galaxy-dev
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
September 2009
- 15 participants
- 140 discussions
details: http://www.bx.psu.edu/hg/galaxy/rev/6555560039d6
changeset: 2702:6555560039d6
user: guru
date: Wed Sep 16 14:55:55 2009 -0400
description:
fastx_clipper tool config problem resolved
1 file(s) affected in this change:
tools/fastx_toolkit/fastx_clipper.xml
diffs (11 lines):
diff -r 86dde83cab76 -r 6555560039d6 tools/fastx_toolkit/fastx_clipper.xml
--- a/tools/fastx_toolkit/fastx_clipper.xml Wed Sep 16 14:06:14 2009 -0400
+++ b/tools/fastx_toolkit/fastx_clipper.xml Wed Sep 16 14:55:55 2009 -0400
@@ -52,7 +52,6 @@
#functional test with param value starting with - fails.
<tests>
<test>
- <!-- Clip a FASTQ file -->
<param name="input" value="fastx_clipper1.fastq" />
<param name="maxmismatches" value="2" />
<param name="minlength" value="15" />
1
0
16 Sep '09
details: http://www.bx.psu.edu/hg/galaxy/rev/86dde83cab76
changeset: 2701:86dde83cab76
user: Greg Von Kuster <greg(a)bx.psu.edu>
date: Wed Sep 16 14:06:14 2009 -0400
description:
Use a grid for admin user management, still needs some polishing, but a good start.
20 file(s) affected in this change:
lib/galaxy/web/controllers/admin.py
lib/galaxy/web/controllers/history.py
lib/galaxy/web/controllers/page.py
lib/galaxy/web/controllers/requests.py
lib/galaxy/web/controllers/requests_admin.py
lib/galaxy/web/framework/helpers/grids.py
templates/admin/dataset_security/deleted_groups.mako
templates/admin/dataset_security/deleted_roles.mako
templates/admin/dataset_security/groups.mako
templates/admin/dataset_security/roles.mako
templates/admin/dataset_security/user.mako
templates/admin/dataset_security/users.mako
templates/admin/user/create.mako
templates/admin/user/deleted_users.mako
templates/admin/user/grid.mako
templates/admin/user/reset_password.mako
templates/admin/user/user.mako
templates/history/grid.mako
test/base/twilltestcase.py
test/functional/test_security_and_libraries.py
diffs (1508 lines):
diff -r c40962280e72 -r 86dde83cab76 lib/galaxy/web/controllers/admin.py
--- a/lib/galaxy/web/controllers/admin.py Wed Sep 16 12:39:57 2009 -0400
+++ b/lib/galaxy/web/controllers/admin.py Wed Sep 16 14:06:14 2009 -0400
@@ -4,10 +4,88 @@
from galaxy.web.base.controller import *
from galaxy.model.orm import *
from galaxy.web.controllers.forms import get_all_forms, get_form_widgets
+from galaxy.web.framework.helpers import time_ago, iff, grids
import logging
log = logging.getLogger( __name__ )
+class UserListGrid( grids.Grid ):
+ class EmailColumn( grids.GridColumn ):
+ def get_value( self, trans, grid, user ):
+ return user.email
+ class UserNameColumn( grids.GridColumn ):
+ def get_value( self, trans, grid, user ):
+ if user.username:
+ return user.username
+ return 'not set'
+ class GroupsColumn( grids.GridColumn ):
+ def get_value( self, trans, grid, user ):
+ if user.groups:
+ return len( user.groups )
+ return 0
+ class RolesColumn( grids.GridColumn ):
+ def get_value( self, trans, grid, user ):
+ if user.roles:
+ return len( user.roles )
+ return 0
+ class ExternalColumn( grids.GridColumn ):
+ def get_value( self, trans, grid, user ):
+ if user.external:
+ return 'yes'
+ return 'no'
+ class LastLoginColumn( grids.GridColumn ):
+ def get_value( self, trans, grid, user ):
+ if user.galaxy_sessions:
+ return self.format( user.galaxy_sessions[ 0 ].update_time )
+ return 'never'
+ # Grid definition
+ title = "Users"
+ model_class = model.User
+ template='/admin/user/grid.mako'
+ columns = [
+ EmailColumn( "Email", link=( lambda item: dict( operation="user", id=item.id ) ), attach_popup=True ),
+ UserNameColumn( "User Name", attach_popup=False ),
+ GroupsColumn( "Groups", attach_popup=False ),
+ RolesColumn( "Roles", attach_popup=False ),
+ ExternalColumn( "External", attach_popup=False ),
+ LastLoginColumn( "Last Login", format=time_ago ),
+ # Valid for filtering but invisible
+ grids.GridColumn( "Deleted", key="deleted", visible=False )
+ ]
+ operations = [
+ grids.GridOperation( "reset_password", condition=( lambda item: not item.deleted ), allow_multiple=True )
+ ]
+ #TODO: enhance to account for trans.app.config.allow_user_deletion here so that we can eliminate these operations if
+ # the setting is False
+ operations.append( grids.GridOperation( "delete", condition=( lambda item: not item.deleted ), allow_multiple=True ) )
+ operations.append( grids.GridOperation( "undelete", condition=( lambda item: item.deleted ), allow_multiple=True ) )
+ operations.append( grids.GridOperation( "purge", condition=( lambda item: item.deleted ), allow_multiple=True ) )
+ standard_filters = [
+ grids.GridColumnFilter( "Active", args=dict( deleted=False ) ),
+ grids.GridColumnFilter( "Deleted", args=dict( deleted=True ) ),
+ grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
+ ]
+ default_filter = dict( deleted=False )
+ def get_current_item( self, trans ):
+ return trans.user
+ def build_initial_query( self, session ):
+ return session.query( self.model_class )
+ def apply_default_filter( self, trans, query, **kwargs ):
+ email_filter = kwargs.get( "email_filter", None )
+ if email_filter:
+ if email_filter == 'all':
+ return query
+ else:
+ return query.filter( or_( trans.app.model.User.table.c.email.like( '%s' % email_filter.lower() + '%' ),
+ trans.app.model.User.table.c.email.like( '%s' % email_filter.upper() + '%' ) ) )
+ elif query.count() > 200:
+ return query.filter( or_( trans.app.model.User.table.c.email.like( 'A%' ),
+ trans.app.model.User.table.c.email.like( 'a%' ) ) )
+ return query
+
class Admin( BaseController ):
+
+ user_list_grid = UserListGrid()
+
@web.expose
@web.require_admin
def index( self, trans, **kwd ):
@@ -438,34 +516,41 @@
# Galaxy User Stuff
@web.expose
@web.require_admin
- def create_new_user( self, trans, **kwd ):
- params = util.Params( kwd )
- msg = util.restore_text( params.get( 'msg', '' ) )
+ def create_new_user( self, trans, **kwargs ):
email = ''
password = ''
confirm = ''
subscribe = False
- messagetype = params.get( 'messagetype', 'done' )
- if 'user_create_button' in kwd:
- if 'email' in kwd:
- email = kwd[ 'email' ]
- if 'password' in kwd:
- password = kwd[ 'password' ]
- if 'confirm' in kwd:
- confirm = kwd[ 'confirm' ]
- if 'subscribe' in kwd:
- subscribe = kwd[ 'subscribe' ]
- messagetype = 'error'
- if len( email ) == 0 or "@" not in email or "." not in email:
- msg = "Please enter a real email address"
+ email_filter = kwargs.get( 'email_filter', 'A' )
+ if 'user_create_button' in kwargs:
+ message = ''
+ status = ''
+ email = kwargs.get( 'email' , None )
+ password = kwargs.get( 'password', None )
+ confirm = kwargs.get( 'confirm', None )
+ subscribe = kwargs.get( 'subscribe', None )
+ if not email:
+ message = 'Enter a valid email address'
+ elif not password:
+ message = 'Enter a valid password'
+ elif not confirm:
+ message = 'Confirm the password'
+ elif len( email ) == 0 or "@" not in email or "." not in email:
+ message = 'Enter a real email address'
elif len( email) > 255:
- msg = "Email address exceeds maximum allowable length"
+ message = 'Email address exceeds maximum allowable length'
elif trans.app.model.User.filter( trans.app.model.User.table.c.email==email ).first():
- msg = "User with that email already exists"
+ message = 'A user with that email already exists'
elif len( password ) < 6:
- msg = "Please use a password of at least 6 characters"
+ message = 'Use a password of at least 6 characters'
elif password != confirm:
- msg = "Passwords do not match"
+ message = 'Passwords do not match'
+ if message:
+ trans.response.send_redirect( web.url_for( controller='admin',
+ action='users',
+ email_filter=email_filter,
+ message=util.sanitize_text( message ),
+ status='error' ) )
else:
user = trans.app.model.User( email=email )
user.set_password_cleartext( password )
@@ -474,20 +559,22 @@
user.flush()
trans.app.security_agent.create_private_user_role( user )
trans.app.security_agent.user_set_default_permissions( user, history=False, dataset=False )
- trans.log_event( "Admin created a new account for user %s" % email )
- msg = 'Created new user account'
- messagetype = 'done'
+ message = 'Created new user account (%s)' % user.email
+ status = 'done'
#subscribe user to email list
if subscribe:
mail = os.popen( "%s -t" % trans.app.config.sendmail_path, 'w' )
mail.write( "To: %s\nFrom: %s\nSubject: Join Mailing List\n\nJoin Mailing list." % ( trans.app.config.mailing_join_addr, email ) )
if mail.close():
- msg + ". However, subscribing to the mailing list has failed."
- messagetype = 'error'
- trans.response.send_redirect( web.url_for( action='users', msg=util.sanitize_text( msg ), messagetype=messagetype ) )
+ message + ". However, subscribing to the mailing list has failed."
+ status = 'error'
+ trans.response.send_redirect( web.url_for( controller='admin',
+ action='users',
+ email_filter=email_filter,
+ message=util.sanitize_text( message ),
+ status=status ) )
return trans.fill_template( '/admin/user/create.mako',
- msg=msg,
- messagetype=messagetype,
+ email_filter=email_filter,
email=email,
password=password,
confirm=confirm,
@@ -495,56 +582,76 @@
@web.expose
@web.require_admin
def reset_user_password( self, trans, **kwd ):
- params = util.Params( kwd )
- msg = util.restore_text( params.get( 'msg', '' ) )
- user_id = int( params.user_id )
- user = trans.app.model.User.filter( trans.app.model.User.table.c.id==user_id ).first()
- password = ''
- confirm = ''
- messagetype = params.get( 'messagetype', 'done' )
+ id = kwd.get( 'id', None )
+ if not id:
+ message = "No user ids received for resetting passwords"
+ trans.response.send_redirect( web.url_for( action='users', message=message, status='error' ) )
+ ids = util.listify( id )
if 'reset_user_password_button' in kwd:
- if 'password' in kwd:
- password = kwd[ 'password' ]
- if 'confirm' in kwd:
- confirm = kwd[ 'confirm' ]
- messagetype = 'error'
- if len( password ) < 6:
- msg = "Please use a password of at least 6 characters"
- elif password != confirm:
- msg = "Passwords do not match"
- else:
- user.set_password_cleartext( password )
- user.flush()
- trans.log_event( "Admin reset password for user %s" % user.email )
- msg = 'Password reset'
- messagetype = 'done'
- trans.response.send_redirect( web.url_for( action='users', msg=util.sanitize_text( msg ), messagetype=messagetype ) )
+ message = ''
+ status = ''
+ for user_id in ids:
+ user = get_user( trans, user_id )
+ password = kwd.get( 'password', None )
+ confirm = kwd.get( 'confirm' , None )
+ if len( password ) < 6:
+ message = "Please use a password of at least 6 characters"
+ status = 'error'
+ break
+ elif password != confirm:
+ message = "Passwords do not match"
+ status = 'error'
+ break
+ else:
+ user.set_password_cleartext( password )
+ user.flush()
+ if not message and not status:
+ message = "Passwords reset for %d users" % len( ids )
+ status = 'done'
+ trans.response.send_redirect( web.url_for( action='users',
+ message=util.sanitize_text( message ),
+ status=status ) )
+ users = [ get_user( trans, user_id ) for user_id in ids ]
+ if len( ids ) > 1:
+ id=','.join( id )
return trans.fill_template( '/admin/user/reset_password.mako',
- msg=msg,
- messagetype=messagetype,
- user=user,
- password=password,
- confirm=confirm )
+ id=id,
+ users=users,
+ password='',
+ confirm='' )
@web.expose
@web.require_admin
def mark_user_deleted( self, trans, **kwd ):
- params = util.Params( kwd )
- msg = util.restore_text( params.get( 'msg', '' ) )
- messagetype = params.get( 'messagetype', 'done' )
- user = trans.app.model.User.get( int( params.user_id ) )
- user.deleted = True
- user.flush()
- msg = "User '%s' has been marked as deleted." % user.email
- trans.response.send_redirect( web.url_for( action='users', msg=util.sanitize_text( msg ), messagetype='done' ) )
+ id = kwd.get( 'id', None )
+ if not id:
+ message = "No user ids received for deleting"
+ trans.response.send_redirect( web.url_for( action='users', message=message, status='error' ) )
+ ids = util.listify( id )
+ for user_id in ids:
+ user = get_user( trans, user_id )
+ user.deleted = True
+ user.flush()
+ message = "Deleted %d users" % len( ids )
+ trans.response.send_redirect( web.url_for( action='users', message=util.sanitize_text( message ), status='done' ) )
@web.expose
@web.require_admin
def undelete_user( self, trans, **kwd ):
- params = util.Params( kwd )
- user = trans.app.model.User.get( int( params.user_id ) )
- user.deleted = False
- user.flush()
- msg = "User '%s' has been marked as not deleted." % user.email
- trans.response.send_redirect( web.url_for( action='users', msg=util.sanitize_text( msg ), messagetype='done' ) )
+ id = kwd.get( 'id', None )
+ if not id:
+ message = "No user ids received for undeleting"
+ trans.response.send_redirect( web.url_for( action='users', message=message, status='error' ) )
+ ids = util.listify( id )
+ count = 0
+ for user_id in ids:
+ user = get_user( trans, user_id )
+ if user.deleted:
+ user.deleted = False
+ user.flush()
+ count += 1
+ message = "Undeleted %d users" % count
+ trans.response.send_redirect( web.url_for( action='users',
+ message=util.sanitize_text( message ),
+ status='done' ) )
@web.expose
@web.require_admin
def purge_user( self, trans, **kwd ):
@@ -559,86 +666,111 @@
# - UserGroupAssociation where user_id == User.id
# - UserRoleAssociation where user_id == User.id EXCEPT FOR THE PRIVATE ROLE
# Purging Histories and Datasets must be handled via the cleanup_datasets.py script
- params = util.Params( kwd )
- user = trans.app.model.User.get( int( params.user_id ) )
- if not user.deleted:
- # We should never reach here, but just in case there is a bug somewhere...
- msg = "User '%s' has not been deleted, so it cannot be purged." % user.email
- trans.response.send_redirect( web.url_for( action='users', msg=util.sanitize_text( msg ), messagetype='error' ) )
- private_role = trans.app.security_agent.get_private_user_role( user )
- # Delete History
- for h in user.active_histories:
- h.refresh()
- for hda in h.active_datasets:
- # Delete HistoryDatasetAssociation
- d = trans.app.model.Dataset.get( hda.dataset_id )
- # Delete Dataset
- if not d.deleted:
- d.deleted = True
- d.flush()
- hda.deleted = True
- hda.flush()
- h.deleted = True
- h.flush()
- # Delete UserGroupAssociations
- for uga in user.groups:
- uga.delete()
- uga.flush()
- # Delete UserRoleAssociations EXCEPT FOR THE PRIVATE ROLE
- for ura in user.roles:
- if ura.role_id != private_role.id:
- ura.delete()
- ura.flush()
- # Purge the user
- user.purged = True
- user.flush()
- msg = "User '%s' has been marked as purged." % user.email
- trans.response.send_redirect( web.url_for( action='deleted_users', msg=util.sanitize_text( msg ), messagetype='done' ) )
+ id = kwd.get( 'id', None )
+ if not id:
+ message = "No user ids received for purging"
+ trans.response.send_redirect( web.url_for( action='users',
+ message=util.sanitize_text( message ),
+ status='error' ) )
+ ids = util.listify( id )
+ for user_id in ids:
+ user = get_user( trans, user_id )
+ if not user.deleted:
+ # We should never reach here, but just in case there is a bug somewhere...
+ message = "User '%s' has not been deleted, so it cannot be purged." % user.email
+ trans.response.send_redirect( web.url_for( action='users',
+ message=util.sanitize_text( message ),
+ status='error' ) )
+ private_role = trans.app.security_agent.get_private_user_role( user )
+ # Delete History
+ for h in user.active_histories:
+ h.refresh()
+ for hda in h.active_datasets:
+ # Delete HistoryDatasetAssociation
+ d = trans.app.model.Dataset.get( hda.dataset_id )
+ # Delete Dataset
+ if not d.deleted:
+ d.deleted = True
+ d.flush()
+ hda.deleted = True
+ hda.flush()
+ h.deleted = True
+ h.flush()
+ # Delete UserGroupAssociations
+ for uga in user.groups:
+ uga.delete()
+ uga.flush()
+ # Delete UserRoleAssociations EXCEPT FOR THE PRIVATE ROLE
+ for ura in user.roles:
+ if ura.role_id != private_role.id:
+ ura.delete()
+ ura.flush()
+ # Purge the user
+ user.purged = True
+ user.flush()
+ message = "Purged %d users" % len( ids )
+ trans.response.send_redirect( web.url_for( controller='admin',
+ action='users',
+ message=util.sanitize_text( message ),
+ status='done' ) )
@web.expose
@web.require_admin
- def deleted_users( self, trans, **kwd ):
- params = util.Params( kwd )
- msg = util.restore_text( params.get( 'msg', '' ) )
- messagetype = params.get( 'messagetype', 'done' )
- users = trans.app.model.User.filter( and_( trans.app.model.User.table.c.deleted==True, trans.app.model.User.table.c.purged==False ) ) \
- .order_by( trans.app.model.User.table.c.email ) \
- .all()
- return trans.fill_template( '/admin/user/deleted_users.mako', users=users, msg=msg, messagetype=messagetype )
- @web.expose
- @web.require_admin
- def users( self, trans, **kwd ):
- params = util.Params( kwd )
- msg = util.restore_text( params.get( 'msg', '' ) )
- messagetype = params.get( 'messagetype', 'done' )
- users = trans.app.model.User.filter( trans.app.model.User.table.c.deleted==False ).order_by( trans.app.model.User.table.c.email ).all()
- return trans.fill_template( '/admin/dataset_security/users.mako',
- users=users,
- allow_user_deletion=trans.app.config.allow_user_deletion,
- msg=msg,
- messagetype=messagetype )
+ def users( self, trans, **kwargs ):
+ if 'operation' in kwargs:
+ operation = kwargs['operation'].lower()
+ if operation == "user":
+ return self.user( trans, **kwargs )
+ if operation == "reset_password":
+ return self.reset_user_password( trans, **kwargs )
+ if operation == "delete":
+ return self.mark_user_deleted( trans, **kwargs )
+ if operation == "undelete":
+ return self.undelete_user( trans, **kwargs )
+ if operation == "purge":
+ return self.purge_user( trans, **kwargs )
+ if operation == "create":
+ return self.create_new_user( trans, **kwargs )
+ # Render the list view
+ return self.user_list_grid( trans, **kwargs )
@web.expose
@web.require_admin
def user( self, trans, **kwd ):
- params = util.Params( kwd )
- msg = util.restore_text( params.get( 'msg', '' ) )
- messagetype = params.get( 'messagetype', 'done' )
- user = trans.app.model.User.get( int( params.user_id ) )
+ user_id = kwd.get( 'id', None )
+ message = ''
+ status = ''
+ if not user_id:
+ message += "Invalid user id (%s) received" % str( user_id )
+ trans.response.send_redirect( web.url_for( controller='admin',
+ action='users',
+ message=util.sanitize_text( message ),
+ status='error' ) )
+ user = get_user( trans, user_id )
private_role = trans.app.security_agent.get_private_user_role( user )
- if params.get( 'user_roles_groups_edit_button', False ):
+ if kwd.get( 'user_roles_groups_edit_button', False ):
# Make sure the user is not dis-associating himself from his private role
- out_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.out_roles ) ]
+ out_roles = kwd.get( 'out_roles', [] )
+ if out_roles:
+ out_roles = [ trans.app.model.Role.get( x ) for x in util.listify( out_roles ) ]
if private_role in out_roles:
- msg += "You cannot eliminate a user's private role association. "
- messagetype = 'error'
- in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.in_roles ) ]
- out_groups = [ trans.app.model.Group.get( x ) for x in util.listify( params.out_groups ) ]
- in_groups = [ trans.app.model.Group.get( x ) for x in util.listify( params.in_groups ) ]
+ message += "You cannot eliminate a user's private role association. "
+ status = 'error'
+ in_roles = kwd.get( 'in_roles', [] )
+ if in_roles:
+ in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( in_roles ) ]
+ out_groups = kwd.get( 'out_groups', [] )
+ if out_groups:
+ out_groups = [ trans.app.model.Group.get( x ) for x in util.listify( out_groups ) ]
+ in_groups = kwd.get( 'in_groups', [] )
+ if in_groups:
+ in_groups = [ trans.app.model.Group.get( x ) for x in util.listify( in_groups ) ]
if in_roles:
trans.app.security_agent.set_entity_user_associations( users=[ user ], roles=in_roles, groups=in_groups )
user.refresh()
- msg += "User '%s' has been updated with %d associated roles and %d associated groups (private roles are not displayed)" % \
+ message += "User '%s' has been updated with %d associated roles and %d associated groups (private roles are not displayed)" % \
( user.email, len( in_roles ), len( in_groups ) )
- trans.response.send_redirect( web.url_for( action='users', msg=util.sanitize_text( msg ), messagetype=messagetype ) )
+ trans.response.send_redirect( web.url_for( action='users',
+ message=util.sanitize_text( message ),
+ status='done' ) )
in_roles = []
out_roles = []
in_groups = []
@@ -653,20 +785,24 @@
# role, which should always be in in_roles. The check above is added as an additional
# precaution, since for a period of time we were including private roles in the form fields.
out_roles.append( ( role.id, role.name ) )
- for group in trans.app.model.Group.filter( trans.app.model.Group.table.c.deleted==False ).order_by( trans.app.model.Group.table.c.name ).all():
+ for group in trans.app.model.Group.filter( trans.app.model.Group.table.c.deleted==False ) \
+ .order_by( trans.app.model.Group.table.c.name ).all():
if group in [ x.group for x in user.groups ]:
in_groups.append( ( group.id, group.name ) )
else:
out_groups.append( ( group.id, group.name ) )
- msg += "User '%s' is currently associated with %d roles and is a member of %d groups" % ( user.email, len( in_roles ), len( in_groups ) )
- return trans.fill_template( '/admin/dataset_security/user.mako',
+ message += "User '%s' is currently associated with %d roles and is a member of %d groups" % \
+ ( user.email, len( in_roles ), len( in_groups ) )
+ if not status:
+ status = 'done'
+ return trans.fill_template( '/admin/user/user.mako',
user=user,
in_roles=in_roles,
out_roles=out_roles,
in_groups=in_groups,
out_groups=out_groups,
- msg=msg,
- messagetype=messagetype )
+ msg=message,
+ messagetype=status )
@web.expose
@web.require_admin
def memdump( self, trans, ids = 'None', sorts = 'None', pages = 'None', new_id = None, new_sort = None, **kwd ):
@@ -749,3 +885,14 @@
else:
last_updated[job.id] = '%s minutes' % int( delta.seconds / 60 )
return trans.fill_template( '/admin/jobs.mako', jobs = jobs, last_updated = last_updated, cutoff = cutoff, msg = msg, messagetype = messagetype )
+
+## ---- Utility methods -------------------------------------------------------
+
+def get_user( trans, id ):
+ """Get a User from the database by id."""
+ # Load user from database
+ id = trans.security.decode_id( id )
+ user = trans.sa_session.query( model.User ).get( id )
+ if not user:
+ err+msg( "User not found" )
+ return user
diff -r c40962280e72 -r 86dde83cab76 lib/galaxy/web/controllers/history.py
--- a/lib/galaxy/web/controllers/history.py Wed Sep 16 12:39:57 2009 -0400
+++ b/lib/galaxy/web/controllers/history.py Wed Sep 16 14:06:14 2009 -0400
@@ -84,7 +84,7 @@
default_filter = dict( deleted=False )
def get_current_item( self, trans ):
return trans.get_history()
- def apply_default_filter( self, trans, query ):
+ def apply_default_filter( self, trans, query, **kwargs ):
return query.filter_by( user=trans.user, purged=False )
class SharedHistoryListGrid( grids.Grid ):
@@ -121,7 +121,7 @@
standard_filters = []
def build_initial_query( self, session ):
return session.query( self.model_class ).join( 'users_shared_with' )
- def apply_default_filter( self, trans, query ):
+ def apply_default_filter( self, trans, query, **kwargs ):
return query.filter( model.HistoryUserShareAssociation.user == trans.user )
class HistoryController( BaseController ):
diff -r c40962280e72 -r 86dde83cab76 lib/galaxy/web/controllers/page.py
--- a/lib/galaxy/web/controllers/page.py Wed Sep 16 12:39:57 2009 -0400
+++ b/lib/galaxy/web/controllers/page.py Wed Sep 16 14:06:14 2009 -0400
@@ -34,7 +34,7 @@
grids.GridOperation( "View", allow_multiple=False, url_args=dict( action='display') ),
grids.GridOperation( "Edit", allow_multiple=False, url_args=dict( action='edit') )
]
- def apply_default_filter( self, trans, query ):
+ def apply_default_filter( self, trans, query, **kwargs ):
return query.filter_by( user=trans.user )
class PageController( BaseController ):
diff -r c40962280e72 -r 86dde83cab76 lib/galaxy/web/controllers/requests.py
--- a/lib/galaxy/web/controllers/requests.py Wed Sep 16 12:39:57 2009 -0400
+++ b/lib/galaxy/web/controllers/requests.py Wed Sep 16 14:06:14 2009 -0400
@@ -51,14 +51,12 @@
return None
def get_request_type(self, trans, request):
return request.type.name
- def apply_default_filter( self, trans, query ):
+ def apply_default_filter( self, trans, query, **kwargs ):
return query.filter_by( user=trans.user )
def number_of_samples(self, trans, request):
return str(len(request.samples))
def get_state(self, trans, request):
return request.state
-
-
class Requests( BaseController ):
request_grid = RequestsListGrid()
@@ -475,10 +473,6 @@
# The folders that should not be displayed may not be a complete list, but it is ultimately passed
# to the calling method to keep from re-checking the same folders when the library / folder
# select lists are rendered.
- #
- # TODO: RC, when you add the folders select list to your request form, take advantage of the hidden_folder_ids
- # so that you do not need to check those same folders yet again when populating the select list.
- #
libraries = odict()
for library in all_libraries:
can_show, hidden_folder_ids = trans.app.security_agent.show_library_item( user, roles, library, actions_to_check )
@@ -721,10 +715,6 @@
# The folders that should not be displayed may not be a complete list, but it is ultimately passed
# to the calling method to keep from re-checking the same folders when the library / folder
# select lists are rendered.
- #
- # TODO: RC, when you add the folders select list to your request form, take advantage of the hidden_folder_ids
- # so that you do not need to check those same folders yet again when populating the select list.
- #
libraries = {}
for library in all_libraries:
can_show, hidden_folder_ids = trans.app.security_agent.show_library_item( user, roles, library, actions_to_check )
diff -r c40962280e72 -r 86dde83cab76 lib/galaxy/web/controllers/requests_admin.py
--- a/lib/galaxy/web/controllers/requests_admin.py Wed Sep 16 12:39:57 2009 -0400
+++ b/lib/galaxy/web/controllers/requests_admin.py Wed Sep 16 14:06:14 2009 -0400
@@ -53,9 +53,6 @@
def get_request_type(self, trans, request):
request_type = trans.app.model.RequestType.get(request.request_type_id)
return request_type.name
-# def apply_default_filter( self, trans, query ):
-# return query.filter(or_(self.model_class.state==self.model_class.states.SUBMITTED,
-# self.model_class.state==self.model_class.states.COMPLETE))
def number_of_samples(self, trans, request):
return str(len(request.samples))
diff -r c40962280e72 -r 86dde83cab76 lib/galaxy/web/framework/helpers/grids.py
--- a/lib/galaxy/web/framework/helpers/grids.py Wed Sep 16 12:39:57 2009 -0400
+++ b/lib/galaxy/web/framework/helpers/grids.py Wed Sep 16 14:06:14 2009 -0400
@@ -35,7 +35,7 @@
session = trans.sa_session
# Build initial query
query = self.build_initial_query( session )
- query = self.apply_default_filter( trans, query )
+ query = self.apply_default_filter( trans, query, **kwargs )
# Maintain sort state in generated urls
extra_url_args = {}
# Process filtering arguments
diff -r c40962280e72 -r 86dde83cab76 templates/admin/dataset_security/deleted_groups.mako
--- a/templates/admin/dataset_security/deleted_groups.mako Wed Sep 16 12:39:57 2009 -0400
+++ b/templates/admin/dataset_security/deleted_groups.mako Wed Sep 16 14:06:14 2009 -0400
@@ -40,7 +40,7 @@
%else:
<table class="manage-table colored" border="0" cellspacing="0" cellpadding="0" width="100%">
<%
- render_quick_find = len( groups ) > 50
+ render_quick_find = len( groups ) > 200
ctr = 0
%>
%if render_quick_find:
diff -r c40962280e72 -r 86dde83cab76 templates/admin/dataset_security/deleted_roles.mako
--- a/templates/admin/dataset_security/deleted_roles.mako Wed Sep 16 12:39:57 2009 -0400
+++ b/templates/admin/dataset_security/deleted_roles.mako Wed Sep 16 14:06:14 2009 -0400
@@ -42,7 +42,7 @@
%else:
<table class="manage-table colored" border="0" cellspacing="0" cellpadding="0" width="100%">
<%
- render_quick_find = len( roles ) > 50
+ render_quick_find = len( roles ) > 200
ctr = 0
%>
%if render_quick_find:
diff -r c40962280e72 -r 86dde83cab76 templates/admin/dataset_security/groups.mako
--- a/templates/admin/dataset_security/groups.mako Wed Sep 16 12:39:57 2009 -0400
+++ b/templates/admin/dataset_security/groups.mako Wed Sep 16 14:06:14 2009 -0400
@@ -46,7 +46,7 @@
%else:
<table class="manage-table colored" border="0" cellspacing="0" cellpadding="0" width="100%">
<%
- render_quick_find = len( groups ) > 50
+ render_quick_find = len( groups ) > 200
ctr = 0
%>
%if render_quick_find:
diff -r c40962280e72 -r 86dde83cab76 templates/admin/dataset_security/roles.mako
--- a/templates/admin/dataset_security/roles.mako Wed Sep 16 12:39:57 2009 -0400
+++ b/templates/admin/dataset_security/roles.mako Wed Sep 16 14:06:14 2009 -0400
@@ -48,7 +48,7 @@
%else:
<table class="manage-table colored" border="0" cellspacing="0" cellpadding="0" width="100%">
<%
- render_quick_find = len( roles ) > 50
+ render_quick_find = len( roles ) > 200
ctr = 0
%>
%if render_quick_find:
diff -r c40962280e72 -r 86dde83cab76 templates/admin/dataset_security/user.mako
--- a/templates/admin/dataset_security/user.mako Wed Sep 16 12:39:57 2009 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-<%inherit file="/base.mako"/>
-<%namespace file="/message.mako" import="render_msg" />
-
-<%def name="javascripts()">
- ${parent.javascripts()}
- <script type="text/javascript">
- $(function(){
- $("input:text:first").focus();
- })
- </script>
-</%def>
-
-<%def name="render_select( name, options )">
- <select name="${name}" id="${name}" style="min-width: 250px; height: 150px;" multiple>
- %for option in options:
- <option value="${option[0]}">${option[1]}</option>
- %endfor
- </select>
-</%def>
-
-<script type="text/javascript">
-$().ready(function() {
- $('#roles_add_button').click(function() {
- return !$('#out_roles option:selected').remove().appendTo('#in_roles');
- });
- $('#roles_remove_button').click(function() {
- return !$('#in_roles option:selected').remove().appendTo('#out_roles');
- });
- $('#groups_add_button').click(function() {
- return !$('#out_groups option:selected').remove().appendTo('#in_groups');
- });
- $('#groups_remove_button').click(function() {
- return !$('#in_groups option:selected').remove().appendTo('#out_groups');
- });
- $('form#associate_user_role_group').submit(function() {
- $('#in_roles option').each(function(i) {
- $(this).attr("selected", "selected");
- });
- $('#in_groups option').each(function(i) {
- $(this).attr("selected", "selected");
- });
- });
-});
-</script>
-
-%if msg:
- ${render_msg( msg, messagetype )}
-%endif
-
-<div class="toolForm">
- <div class="toolFormTitle">User '${user.email}'</div>
- <div class="toolFormBody">
- <form name="associate_user_role_group" id="associate_user_role_group" action="${h.url_for( action='user', user_id=user.id )}" method="post" >
- <div class="form-row">
- <div style="float: left; margin-right: 10px;">
- <label>Roles associated with '${user.email}'</label>
- ${render_select( "in_roles", in_roles )}<br/>
- <input type="submit" id="roles_remove_button" value=">>"/>
- </div>
- <div>
- <label>Roles not associated with '${user.email}'</label>
- ${render_select( "out_roles", out_roles )}<br/>
- <input type="submit" id="roles_add_button" value="<<"/>
- </div>
- </div>
- <div class="form-row">
- <div style="float: left; margin-right: 10px;">
- <label>Groups associated with '${user.email}'</label>
- ${render_select( "in_groups", in_groups )}<br/>
- <input type="submit" id="groups_remove_button" value=">>"/>
- </div>
- <div>
- <label>Groups not associated with '${user.email}'</label>
- ${render_select( "out_groups", out_groups )}<br/>
- <input type="submit" id="groups_add_button" value="<<"/>
- </div>
- </div>
- <div class="form-row">
- <input type="submit" name="user_roles_groups_edit_button" value="Save"/>
- </div>
- </form>
- </div>
-</div>
diff -r c40962280e72 -r 86dde83cab76 templates/admin/dataset_security/users.mako
--- a/templates/admin/dataset_security/users.mako Wed Sep 16 12:39:57 2009 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-<%inherit file="/base.mako"/>
-<%namespace file="/message.mako" import="render_msg" />
-
-## Render a row
-<%def name="render_row( user, ctr, anchored, curr_anchor )">
- %if ctr % 2 == 1:
- <tr class="odd_row">
- %else:
- <tr>
- %endif
- <td>
- <a href="${h.url_for( controller='admin', action='user', user_id=user.id )}">${user.email}</a>
- <a id="user-${user.id}-popup" class="popup-arrow" style="display: none;">▼</a>
- <div popupmenu="user-${user.id}-popup">
- <a class="action-button" href="${h.url_for( action='reset_user_password', user_id=user.id )}">Reset password</a>
- <a class="action-button" href="${h.url_for( controller='admin', action='user', user_id=user.id )}">Change associated groups and roles</a>
- %if allow_user_deletion:
- <a class="action-button" href="${h.url_for( action='mark_user_deleted', user_id=user.id )}">Mark user deleted</a>
- %endif
- </div>
- </td>
- <td>
- ${len( user.groups )}
- </td>
- <td>
- ${len( user.roles )}
- %if not anchored:
- <a name="${curr_anchor}"></a>
- <div style="float: right;"><a href="#TOP">top</a></div>
- %endif
- </td>
- </tr>
-</%def>
-
-<a name="TOP"><h2>Users</h2></a>
-
-<ul class="manage-table-actions">
- <li><a class="action-button" href="${h.url_for( controller='admin', action='create_new_user' )}">Create a new user</a></li>
- %if allow_user_deletion:
- <li><a class="action-button" href="${h.url_for( controller='admin', action='deleted_users' )}">Manage deleted users</a></li>
- %endif
-</ul>
-
-%if msg:
- ${render_msg( msg, messagetype )}
-%endif
-
-%if len( users ) == 0:
- There are no Galaxy users
-%else:
- <table class="manage-table colored" border="0" cellspacing="0" cellpadding="0" width="100%">
- <%
- render_quick_find = len( users ) > 50
- ctr = 0
- %>
- %if render_quick_find:
- <%
- anchors = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
- anchor_loc = 0
- anchored = False
- curr_anchor = 'A'
- %>
- <tr style="background: #EEE">
- <td colspan="3" style="border-bottom: 1px solid #D8B365; text-align: center;">
- Jump to letter:
- %for a in anchors:
- | <a href="#${a}">${a}</a>
- %endfor
- </td>
- </tr>
- %endif
- <tr class="header">
- <td>Email</td>
- <td>Groups</td>
- <td>Roles</td>
- </tr>
- %for ctr, user in enumerate( users ):
- %if render_quick_find and not user.email.upper().startswith( curr_anchor ):
- <% anchored = False %>
- %endif
- %if render_quick_find and user.email.upper().startswith( curr_anchor ):
- %if not anchored:
- ${render_row( user, ctr, anchored, curr_anchor )}
- <% anchored = True %>
- %else:
- ${render_row( user, ctr, anchored, curr_anchor )}
- %endif
- %elif render_quick_find:
- %for anchor in anchors[ anchor_loc: ]:
- %if user.email.upper().startswith( anchor ):
- %if not anchored:
- <% curr_anchor = anchor %>
- ${render_row( user, ctr, anchored, curr_anchor )}
- <% anchored = True %>
- %else:
- ${render_row( user, ctr, anchored, curr_anchor )}
- %endif
- <%
- anchor_loc = anchors.index( anchor )
- break
- %>
- %endif
- %endfor
- %else:
- ${render_row( user, ctr, True, '' )}
- %endif
- %endfor
- </table>
-%endif
diff -r c40962280e72 -r 86dde83cab76 templates/admin/user/create.mako
--- a/templates/admin/user/create.mako Wed Sep 16 12:39:57 2009 -0400
+++ b/templates/admin/user/create.mako Wed Sep 16 14:06:14 2009 -0400
@@ -8,7 +8,7 @@
<div class="toolForm">
<div class="toolFormTitle">Create user account</div>
<div class="toolFormBody">
- <form name="form" action="${h.url_for( controller='admin', action='create_new_user' )}" method="post" >
+ <form name="form" action="${h.url_for( controller='admin', action='create_new_user', email_filter=email_filter )}" method="post" >
<div class="form-row">
<label>Email address:</label>
<div style="float: left; width: 250px; margin-right: 10px;">
diff -r c40962280e72 -r 86dde83cab76 templates/admin/user/deleted_users.mako
--- a/templates/admin/user/deleted_users.mako Wed Sep 16 12:39:57 2009 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-<%inherit file="/base.mako"/>
-<%namespace file="/message.mako" import="render_msg" />
-
-## Render a row
-<%def name="render_row( user, ctr, anchored, curr_anchor )">
- %if ctr % 2 == 1:
- <tr class="odd_row">
- %else:
- <tr>
- %endif
- <td>
- ${user.email}
- <a id="user-${user.id}-popup" class="popup-arrow" style="display: none;">▼</a>
- <div popupmenu="user-${user.id}-popup">
- <a class="action-button" href="${h.url_for( controller="admin", action='undelete_user', user_id=user.id )}">Undelete</a>
- <a class="action-button" confirm="Purging a user will delete all of their histories, datasets, and group and role associations. Click OK to purge the user '${user.email}'" href="${h.url_for( controller="admin", action='purge_user', user_id=user.id )}">Purge</a>
- </div>
- %if not anchored:
- <a name="${curr_anchor}"></a>
- <div style="float: right;"><a href="#TOP">top</a></div>
- %endif
- </td>
- </tr>
-</%def>
-
-<a name="TOP"><h2>Deleted Users</h2></a>
-
-%if msg:
- ${render_msg( msg, messagetype )}
-%endif
-
-%if len( users ) == 0:
- There are no deleted Galaxy users
-%else:
- <table class="manage-table colored" border="0" cellspacing="0" cellpadding="0" width="100%">
- <%
- render_quick_find = len( users ) > 50
- ctr = 0
- %>
- %if render_quick_find:
- <%
- anchors = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
- anchor_loc = 0
- anchored = False
- curr_anchor = 'A'
- %>
- <tr style="background: #EEE">
- <td colspan="3" style="text-align: center; border-bottom: 1px solid #D8B365">
- Jump to letter:
- %for a in anchors:
- | <a href="#${a}">${a}</a>
- %endfor
- </td>
- </tr>
- %endif
- <tr class="header">
- <td>Email</td>
- </tr>
- %for ctr, user in enumerate( users ):
- %if render_quick_find and not user.email.upper().startswith( curr_anchor ):
- <% anchored = False %>
- %endif
- %if render_quick_find and user.email.upper().startswith( curr_anchor ):
- %if not anchored:
- ${render_row( user, ctr, anchored, curr_anchor )}
- <% anchored = True %>
- %else:
- ${render_row( user, ctr, anchored, curr_anchor )}
- %endif
- %elif render_quick_find:
- %for anchor in anchors[ anchor_loc: ]:
- %if user.email.upper().startswith( anchor ):
- %if not anchored:
- <% curr_anchor = anchor %>
- ${render_row( user, ctr, anchored, curr_anchor )}
- <% anchored = True %>
- %else:
- ${render_row( user, ctr, anchored, curr_anchor )}
- %endif
- <%
- anchor_loc = anchors.index( anchor )
- break
- %>
- %endif
- %endfor
- %else:
- ${render_row( user, ctr, True, '' )}
- %endif
- %endfor
- </table>
-%endif
diff -r c40962280e72 -r 86dde83cab76 templates/admin/user/grid.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/admin/user/grid.mako Wed Sep 16 14:06:14 2009 -0400
@@ -0,0 +1,224 @@
+<%inherit file="/base.mako"/>
+<%def name="title()">${grid.title}</%def>
+<% from galaxy import util %>
+
+%if message:
+ <p>
+ <div class="${message_type}message transient-message">${util.restore_text( message )}</div>
+ <div style="clear: both"></div>
+ </p>
+%endif
+
+<%def name="javascripts()">
+ ${parent.javascripts()}
+ ${h.js("jquery.autocomplete", "autocomplete_tagging" )}
+ <script type="text/javascript">
+ ## TODO: generalize and move into galaxy.base.js
+ $(document).ready(function() {
+ $(".grid").each( function() {
+ var grid = this;
+ var checkboxes = $(this).find("input.grid-row-select-checkbox");
+ var update = $(this).find( "span.grid-selected-count" );
+ $(checkboxes).each( function() {
+ $(this).change( function() {
+ var n = $(checkboxes).filter("[checked]").size();
+ update.text( n );
+ });
+ })
+ });
+ });
+ ## Can this be moved into base.mako?
+ %if refresh_frames:
+ %if 'masthead' in refresh_frames:
+ ## Refresh masthead == user changes (backward compatibility)
+ if ( parent.user_changed ) {
+ %if trans.user:
+ parent.user_changed( "${trans.user.email}", ${int( app.config.is_admin_user( trans.user ) )} );
+ %else:
+ parent.user_changed( null, false );
+ %endif
+ }
+ %endif
+ %if 'history' in refresh_frames:
+ if ( parent.frames && parent.frames.galaxy_history ) {
+ parent.frames.galaxy_history.location.href="${h.url_for( controller='root', action='history')}";
+ if ( parent.force_right_panel ) {
+ parent.force_right_panel( 'show' );
+ }
+ }
+ %endif
+ %if 'tools' in refresh_frames:
+ if ( parent.frames && parent.frames.galaxy_tools ) {
+ parent.frames.galaxy_tools.location.href="${h.url_for( controller='root', action='tool_menu')}";
+ if ( parent.force_left_panel ) {
+ parent.force_left_panel( 'show' );
+ }
+ }
+ %endif
+ %endif
+ </script>
+</%def>
+
+<%def name="stylesheets()">
+ ${h.css( "base", "autocomplete_tagging" )}
+ <style>
+ ## Not generic to all grids -- move to base?
+ .count-box {
+ min-width: 1.1em;
+ padding: 5px;
+ border-width: 1px;
+ border-style: solid;
+ text-align: center;
+ display: inline-block;
+ }
+ </style>
+</%def>
+
+%if grid.standard_filters:
+ <div class="grid-header">
+ <h2>${grid.title}</h2>
+ <span class="title">Filter:</span>
+ %for i, filter in enumerate( grid.standard_filters ):
+ %if i > 0:
+ <span>|</span>
+ %endif
+ <span class="filter"><a href="${url( filter.get_url_args() )}">${filter.label}</a></span>
+ %endfor
+ </div>
+%endif
+
+<ul class="manage-table-actions">
+ <li><a class="action-button" href="${h.url_for( controller='admin', action='users', operation='create' )}">Create a new user</a></li>
+</ul>
+
+%if query.count() == 0:
+ No users were returned for the current query. Click the Show all users button or a letter below.
+%endif:
+<%
+ letters = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z', '0']
+%>
+<div class="toolFormBody">
+ <div class="form-row">
+ <a class="action-button" href="${h.url_for( controller='admin', action='users', email_filter='all' )}"><span>Show all users</span></a>
+ <div class="toolParamHelp" style="clear: both;">
+ Default behavior is displaying only users whose email begins with 'a' if there are more than 200 total users
+ </div>
+ </div>
+ <div class="form-row">
+ <label>Show only users whose email starts with:</label>
+ %for letter in letters:
+ | <a href="${h.url_for( controller='admin', action='users', email_filter=letter )}">${letter}</a>
+ %endfor
+ <div style="clear: both"></div>
+ </div>
+ <form name="user_actions" action="${url()}" method="post">
+ <table class="grid">
+ <thead>
+ <tr>
+ <th></th>
+ %for column in grid.columns:
+ %if column.visible:
+ <%
+ href = ""
+ extra = ""
+ if column.sortable:
+ if sort_key == column.key:
+ if sort_order == "asc":
+ href = url( sort=( "-" + column.key ) )
+ extra = "↓"
+ else:
+ href = url( sort=( column.key ) )
+ extra = "↑"
+ else:
+ href = url( sort=column.key )
+ %>
+ <th\
+ %if column.ncells > 1:
+ colspan="${column.ncells}"
+ %endif
+ >
+ %if href:
+ <a href="${href}">${column.label}</a>
+ %else:
+ ${column.label}
+ %endif
+ <span>${extra}</span>
+ </th>
+ %endif
+ %endfor
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ %for i, item in enumerate( query ):
+ <tr \
+ %if current_item == item:
+ class="current" \
+ %endif
+ >
+ ## Item selection column
+ <td style="width: 1.5em;">
+ <input type="checkbox" name="id" value=${trans.security.encode_id( item.id )} class="grid-row-select-checkbox" />
+ </td>
+ ## Data columns
+ %for column in grid.columns:
+ %if column.visible:
+ <%
+ # Link
+ link = column.get_link( trans, grid, item )
+ if link:
+ href = url( **link )
+ else:
+ href = None
+ # Value (coerced to list so we can loop)
+ value = column.get_value( trans, grid, item )
+ if column.ncells == 1:
+ value = [ value ]
+ %>
+ %for cellnum, v in enumerate( value ):
+ <%
+ # Attach popup menu?
+ if column.attach_popup and cellnum == 0:
+ extra = '<a id="grid-%d-popup" class="arrow" style="display: none;"><span>▼</span></a>' % i
+ else:
+ extra = ""
+ %>
+ %if href:
+ <td><div class="menubutton split" style="float: left;"><a class="label" href="${href}">${v}${extra}</a> </td>
+ %else:
+ <td >${v}${extra}</td>
+ %endif
+ %endfor
+ %endif
+ %endfor
+ ## Actions column
+ <td>
+ <div popupmenu="grid-${i}-popup">
+ %for operation in grid.operations:
+ %if operation.allowed( item ):
+ <a class="action-button" href="${url( operation=operation.label, id=item.id )}">${operation.label}</a>
+ %endif
+ %endfor
+ </div>
+ </td>
+ </tr>
+ %endfor
+ </tbody>
+ %if grid.operations:
+ <tfoot>
+ <tr>
+ <td></td>
+ <td colspan="100">
+ For <span class="grid-selected-count"></span> selected users:
+ %for operation in grid.operations:
+ %if operation.allow_multiple:
+ <input type="submit" name="operation" value="${operation.label}" class="action-button">
+ %endif
+ %endfor
+ </td>
+ </tr>
+ </tfoot>
+ %endif
+ </table>
+ </form>
+</div>
diff -r c40962280e72 -r 86dde83cab76 templates/admin/user/reset_password.mako
--- a/templates/admin/user/reset_password.mako Wed Sep 16 12:39:57 2009 -0400
+++ b/templates/admin/user/reset_password.mako Wed Sep 16 14:06:14 2009 -0400
@@ -6,15 +6,17 @@
%endif
<div class="toolForm">
- <div class="toolFormTitle">Reset user password</div>
+ <div class="toolFormTitle">Reset password for users</div>
<div class="toolFormBody">
<form name="form" action="${h.url_for( controller='admin', action='reset_user_password' )}" method="post" >
- <input type="hidden" name="user_id" value="${user.id}" size="40">
- <div class="form-row">
- <label>Email:</label>
- ${user.email}
- <div style="clear: both"></div>
- </div>
+ <input type="hidden" name="id" value="${id}" size="40">
+ %for user in users:
+ <div class="form-row">
+ <label>Email:</label>
+ ${user.email}
+ <div style="clear: both"></div>
+ </div>
+ %endfor
<div class="form-row">
<label>Password:</label>
<div style="float: left; width: 250px; margin-right: 10px;">
diff -r c40962280e72 -r 86dde83cab76 templates/admin/user/user.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/admin/user/user.mako Wed Sep 16 14:06:14 2009 -0400
@@ -0,0 +1,83 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+<%def name="javascripts()">
+ ${parent.javascripts()}
+ <script type="text/javascript">
+ $(function(){
+ $("input:text:first").focus();
+ })
+ </script>
+</%def>
+
+<%def name="render_select( name, options )">
+ <select name="${name}" id="${name}" style="min-width: 250px; height: 150px;" multiple>
+ %for option in options:
+ <option value="${option[0]}">${option[1]}</option>
+ %endfor
+ </select>
+</%def>
+
+<script type="text/javascript">
+$().ready(function() {
+ $('#roles_add_button').click(function() {
+ return !$('#out_roles option:selected').remove().appendTo('#in_roles');
+ });
+ $('#roles_remove_button').click(function() {
+ return !$('#in_roles option:selected').remove().appendTo('#out_roles');
+ });
+ $('#groups_add_button').click(function() {
+ return !$('#out_groups option:selected').remove().appendTo('#in_groups');
+ });
+ $('#groups_remove_button').click(function() {
+ return !$('#in_groups option:selected').remove().appendTo('#out_groups');
+ });
+ $('form#associate_user_role_group').submit(function() {
+ $('#in_roles option').each(function(i) {
+ $(this).attr("selected", "selected");
+ });
+ $('#in_groups option').each(function(i) {
+ $(this).attr("selected", "selected");
+ });
+ });
+});
+</script>
+
+%if msg:
+ ${render_msg( msg, messagetype )}
+%endif
+
+<div class="toolForm">
+ <div class="toolFormTitle">User '${user.email}'</div>
+ <div class="toolFormBody">
+ <form name="associate_user_role_group" id="associate_user_role_group" action="${h.url_for( action='user', id=trans.app.security.encode_id( user.id ) )}" method="post" >
+ <div class="form-row">
+ <div style="float: left; margin-right: 10px;">
+ <label>Roles associated with '${user.email}'</label>
+ ${render_select( "in_roles", in_roles )}<br/>
+ <input type="submit" id="roles_remove_button" value=">>"/>
+ </div>
+ <div>
+ <label>Roles not associated with '${user.email}'</label>
+ ${render_select( "out_roles", out_roles )}<br/>
+ <input type="submit" id="roles_add_button" value="<<"/>
+ </div>
+ </div>
+ <div class="form-row">
+ <div style="float: left; margin-right: 10px;">
+ <label>Groups associated with '${user.email}'</label>
+ ${render_select( "in_groups", in_groups )}<br/>
+ <input type="submit" id="groups_remove_button" value=">>"/>
+ </div>
+ <div>
+ <label>Groups not associated with '${user.email}'</label>
+ ${render_select( "out_groups", out_groups )}<br/>
+ <input type="submit" id="groups_add_button" value="<<"/>
+ </div>
+ </div>
+ <div class="form-row">
+ <input type="submit" name="user_roles_groups_edit_button" value="Save"/>
+ </div>
+ </form>
+ </div>
+</div>
diff -r c40962280e72 -r 86dde83cab76 templates/history/grid.mako
--- a/templates/history/grid.mako Wed Sep 16 12:39:57 2009 -0400
+++ b/templates/history/grid.mako Wed Sep 16 14:06:14 2009 -0400
@@ -179,18 +179,20 @@
</tr>
%endfor
</tbody>
- <tfoot>
- <tr>
- <td></td>
- <td colspan="100">
- For <span class="grid-selected-count"></span> selected histories:
- %for operation in grid.operations:
- %if operation.allow_multiple:
- <input type="submit" name="operation" value="${operation.label}" class="action-button">
- %endif
- %endfor
- </td>
- </tr>
- </tfoot>
+ %if grid.operations:
+ <tfoot>
+ <tr>
+ <td></td>
+ <td colspan="100">
+ For <span class="grid-selected-count"></span> selected histories:
+ %for operation in grid.operations:
+ %if operation.allow_multiple:
+ <input type="submit" name="operation" value="${operation.label}" class="action-button">
+ %endif
+ %endfor
+ </td>
+ </tr>
+ </tfoot>
+ %endif
</table>
</form>
diff -r c40962280e72 -r 86dde83cab76 test/base/twilltestcase.py
--- a/test/base/twilltestcase.py Wed Sep 16 12:39:57 2009 -0400
+++ b/test/base/twilltestcase.py Wed Sep 16 14:06:14 2009 -0400
@@ -779,8 +779,8 @@
def create_new_account_as_admin( self, email='test4(a)bx.psu.edu', password='testuser' ):
"""Create a new account for another user"""
self.home()
- self.visit_url( "%s/admin/create_new_user?email=%s&password=%s&confirm=%s&user_create_button=%s" \
- % ( self.url, email, password, password, 'Create' ) )
+ self.visit_url( "%s/admin/create_new_user?email=%s&password=%s&confirm=%s&user_create_button=Create&subscribe=False" \
+ % ( self.url, email, password, password ) )
try:
self.check_page_for_string( "Created new user account" )
previously_created = False
@@ -790,34 +790,34 @@
previously_created = True
self.home()
return previously_created
- def reset_password_as_admin( self, user_id=4, password='testreset' ):
+ def reset_password_as_admin( self, user_id, password='testreset' ):
"""Reset a user password"""
self.home()
- self.visit_url( "%s/admin/reset_user_password?user_id=%s" % ( self.url, str( user_id ) ) )
+ self.visit_url( "%s/admin/reset_user_password?id=%s" % ( self.url, user_id ) )
tc.fv( "1", "password", password )
tc.fv( "1", "confirm", password )
tc.submit( "reset_user_password_button" )
- self.check_page_for_string( "Password reset" )
+ self.check_page_for_string( "Passwords reset for 1 users" )
self.home()
- def mark_user_deleted( self, user_id=4, email='' ):
+ def mark_user_deleted( self, user_id, email='' ):
"""Mark a user as deleted"""
self.home()
- self.visit_url( "%s/admin/mark_user_deleted?user_id=%s" % ( self.url, str( user_id ) ) )
- check_str = "User '%s' has been marked as deleted." % email
+ self.visit_url( "%s/admin/mark_user_deleted?id=%s" % ( self.url, user_id ) )
+ check_str = "Deleted 1 users"
self.check_page_for_string( check_str )
self.home()
- def undelete_user( self, user_id=4, email='' ):
+ def undelete_user( self, user_id, email='' ):
"""Undelete a user"""
self.home()
- self.visit_url( "%s/admin/undelete_user?user_id=%s" % ( self.url, user_id ) )
- check_str = "User '%s' has been marked as not deleted" % email
+ self.visit_url( "%s/admin/undelete_user?id=%s" % ( self.url, user_id ) )
+ check_str = "Undeleted 1 users"
self.check_page_for_string( check_str )
self.home()
def purge_user( self, user_id, email ):
"""Purge a user account"""
self.home()
- self.visit_url( "%s/admin/purge_user?user_id=%s" % ( self.url, user_id ) )
- check_str = "User '%s' has been marked as purged." % email
+ self.visit_url( "%s/admin/purge_user?id=%s" % ( self.url, user_id ) )
+ check_str = "Purged 1 users"
self.check_page_for_string( check_str )
self.home()
def associate_roles_and_groups_with_user( self, user_id, email,
@@ -825,7 +825,7 @@
in_group_ids=[], out_group_ids=[],
check_str='' ):
self.home()
- url = "%s/admin/user?user_id=%s&user_roles_groups_edit_button=Save" % ( self.url, user_id )
+ url = "%s/admin/user?id=%s&user_roles_groups_edit_button=Save" % ( self.url, user_id )
if in_role_ids:
url += "&in_roles=%s" % ','.join( in_role_ids )
if out_role_ids:
diff -r c40962280e72 -r 86dde83cab76 test/functional/test_security_and_libraries.py
--- a/test/functional/test_security_and_libraries.py Wed Sep 16 12:39:57 2009 -0400
+++ b/test/functional/test_security_and_libraries.py Wed Sep 16 14:06:14 2009 -0400
@@ -70,11 +70,11 @@
raise AssertionError( 'The DefaultHistoryPermission.action for history id %d is "%s", but it should be "%s"' \
% ( latest_history.id, dhp.action, galaxy.model.Dataset.permitted_actions.DATASET_MANAGE_PERMISSIONS.action ) )
self.home()
- self.visit_url( "%s/admin/user?user_id=%s" % ( self.url, admin_user.id ) )
+ self.visit_url( "%s/admin/user?id=%s" % ( self.url, self.security.encode_id( admin_user.id ) ) )
self.check_page_for_string( admin_user.email )
# Try deleting the admin_user's private role
check_str = "You cannot eliminate a user's private role association."
- self.associate_roles_and_groups_with_user( str( admin_user.id ), admin_user.email,
+ self.associate_roles_and_groups_with_user( self.security.encode_id( admin_user.id ), admin_user.email,
out_role_ids=str( admin_user_private_role.id ),
check_str=check_str )
self.logout()
@@ -158,6 +158,7 @@
raise AssertionError( 'DatasetPermissionss "%s" for dataset id %d differ from DefaultHistoryPermissions "%s" for history id %d' \
% ( str( dps ), latest_dataset.id, str( dhps ), latest_history.id ) )
self.logout()
+
def test_015_login_as_regular_user2( self ):
"""Testing logging in as regular user test2(a)bx.psu.edu - tests changing DefaultHistoryPermissions for the current history"""
self.login( email='test2(a)bx.psu.edu' ) # This will not be an admin user
@@ -248,7 +249,7 @@
def test_025_reset_password_as_admin( self ):
"""Testing reseting a user password as admin"""
email = 'test3(a)bx.psu.edu'
- self.reset_password_as_admin( user_id=regular_user3.id, password='testreset' )
+ self.reset_password_as_admin( user_id=self.security.encode_id( regular_user3.id ), password='testreset' )
self.logout()
def test_030_login_after_password_reset( self ):
"""Testing logging in after an admin reset a password - tests DefaultHistoryPermissions for accounts created by an admin"""
@@ -281,17 +282,17 @@
self.logout()
# Reset the password to the default for later tests
self.login( email='test(a)bx.psu.edu' )
- self.reset_password_as_admin( user_id=regular_user3.id, password='testuser' )
+ self.reset_password_as_admin( user_id=self.security.encode_id( regular_user3.id ), password='testuser' )
def test_035_mark_user_deleted( self ):
"""Testing marking a user account as deleted"""
- self.mark_user_deleted( user_id=regular_user3.id, email=regular_user3.email )
+ self.mark_user_deleted( user_id=self.security.encode_id( regular_user3.id ), email=regular_user3.email )
# Deleting a user should not delete any associations
regular_user3.refresh()
if not regular_user3.active_histories:
raise AssertionError( 'HistoryDatasetAssociations for regular_user3 were incorrectly deleted when the user was marked deleted' )
def test_040_undelete_user( self ):
"""Testing undeleting a user account"""
- self.undelete_user( user_id=regular_user3.id, email=regular_user3.email )
+ self.undelete_user( user_id=self.security.encode_id( regular_user3.id ), email=regular_user3.email )
def test_045_create_role( self ):
"""Testing creating new role with 3 members ( and a new group named the same ), then renaming the role"""
name = 'Role One'
@@ -436,7 +437,7 @@
for uga in admin_user.groups:
group_ids.append( str( uga.group_id ) )
check_str = "User '%s' has been updated with %d associated roles and %d associated groups" % ( admin_user.email, len( role_ids ), len( group_ids ) )
- self.associate_roles_and_groups_with_user( str( admin_user.id ), str( admin_user.email ),
+ self.associate_roles_and_groups_with_user( self.security.encode_id( admin_user.id ), str( admin_user.email ),
in_role_ids=role_ids, in_group_ids=group_ids, check_str=check_str )
admin_user.refresh()
# admin_user should now be associated with 4 roles: private, role_one, role_two, role_three
@@ -1610,9 +1611,9 @@
self.home()
def test_250_purge_user( self ):
"""Testing purging a user account"""
- self.mark_user_deleted( user_id=regular_user3.id, email=regular_user3.email )
+ self.mark_user_deleted( user_id=self.security.encode_id( regular_user3.id ), email=regular_user3.email )
regular_user3.refresh()
- self.purge_user( str( regular_user3.id ), regular_user3.email )
+ self.purge_user( self.security.encode_id( regular_user3.id ), regular_user3.email )
regular_user3.refresh()
if not regular_user3.purged:
raise AssertionError( 'User %s was not marked as purged.' % regular_user3.email )
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/79446c87dba7
changeset: 2703:79446c87dba7
user: Nate Coraor <nate(a)bx.psu.edu>
date: Wed Sep 16 15:22:45 2009 -0400
description:
remove numpy egg
2 file(s) affected in this change:
eggs.ini
lib/galaxy/jobs/__init__.py
diffs (39 lines):
diff -r 6555560039d6 -r 79446c87dba7 eggs.ini
--- a/eggs.ini Wed Sep 16 14:55:55 2009 -0400
+++ b/eggs.ini Wed Sep 16 15:22:45 2009 -0400
@@ -23,7 +23,6 @@
python_lzo = 1.08
threadframe = 0.2
guppy = 0.1.8
-numpy = 1.2.1
[eggs:noplatform]
Beaker = 1.4
@@ -63,7 +62,6 @@
; source location, necessary for scrambling
[source]
-numpy = http://downloads.sourceforge.net/numpy/numpy-1.2.1.tar.gz
bx_python = http://bitbucket.org/james_taylor/bx-python/get/4bf1f32e6b76.bz2
Cheetah = http://voxel.dl.sourceforge.net/sourceforge/cheetahtemplate/Cheetah-1.0.tar…
DRMAA_python = http://gridengine.sunsource.net/files/documents/7/36/DRMAA-python-0.2.tar.gz
diff -r 6555560039d6 -r 79446c87dba7 lib/galaxy/jobs/__init__.py
--- a/lib/galaxy/jobs/__init__.py Wed Sep 16 14:55:55 2009 -0400
+++ b/lib/galaxy/jobs/__init__.py Wed Sep 16 15:22:45 2009 -0400
@@ -495,8 +495,14 @@
shutil.move( dataset_path.false_path, dataset_path.real_path )
log.debug( "finish(): Moved %s to %s" % ( dataset_path.false_path, dataset_path.real_path ) )
except ( IOError, OSError ):
- self.fail( "Job %s's output dataset(s) could not be read" % job.id )
- return
+ # this can happen if Galaxy is restarted during the job's
+ # finish method - the false_path file has already moved,
+ # and when the job is recovered, it won't be found.
+ if os.path.exists( dataset_path.real_path ) and os.stat( dataset_path.real_path ).st_size > 0:
+ log.warning( "finish(): %s not found, but %s is not empty, so it will be used instead" % ( dataset_path.false_path, dataset_path.real_path ) )
+ else:
+ self.fail( "Job %s's output dataset(s) could not be read" % job.id )
+ return
job_context = ExpressionContext( dict( stdout = stdout, stderr = stderr ) )
for dataset_assoc in job.output_datasets:
context = self.get_dataset_finish_context( job_context, dataset_assoc.dataset.dataset )
1
0
16 Sep '09
details: http://www.bx.psu.edu/hg/galaxy/rev/1fb29bd2725a
changeset: 2699:1fb29bd2725a
user: Kelly Vincent <kpvincent(a)bx.psu.edu>
date: Wed Sep 16 11:27:50 2009 -0400
description:
tool_conf.xml.sample for added BWA wrapper tool
1 file(s) affected in this change:
tool_conf.xml.sample
diffs (11 lines):
diff -r 14d54c9dbd59 -r 1fb29bd2725a tool_conf.xml.sample
--- a/tool_conf.xml.sample Wed Sep 16 11:14:39 2009 -0400
+++ b/tool_conf.xml.sample Wed Sep 16 11:27:50 2009 -0400
@@ -336,6 +336,7 @@
<tool file="metag_tools/blat_wrapper.xml" />
<tool file="metag_tools/mapping_to_ucsc.xml" />
<tool file="sr_mapping/bowtie_wrapper.xml" />
+ <tool file="sr_mapping/bwa_wrapper.xml" />
</section>
<section name="Tracks" id="tracks">
<tool file="visualization/genetrack.xml" />
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/c40962280e72
changeset: 2700:c40962280e72
user: rc
date: Wed Sep 16 12:39:57 2009 -0400
description:
Forms:
- Added 'type' and 'layout' columns to the form_definition table
- Added types to forms; Request, Sample & Library info template
- Added layouts to sample form definition to support multiple grids while rendering
Requests:
- Added 'folder_id' column to the request table
- Added the Data Library Folder selectbox when creating a new request
- Moved the 4 request_type methods to requests_admin from admin controller
Updated the functional tests
21 file(s) affected in this change:
lib/galaxy/model/__init__.py
lib/galaxy/model/mapping.py
lib/galaxy/model/migrate/versions/0019_request_library_folder.py
lib/galaxy/web/controllers/admin.py
lib/galaxy/web/controllers/forms.py
lib/galaxy/web/controllers/library.py
lib/galaxy/web/controllers/requests.py
lib/galaxy/web/controllers/requests_admin.py
lib/galaxy/web/form_builder.py
templates/admin/forms/edit_form.mako
templates/admin/forms/manage_forms.mako
templates/admin/index.mako
templates/admin/requests/add_states.mako
templates/admin/requests/create_request_type.mako
templates/admin/requests/manage_request_types.mako
templates/admin/requests/show_request.mako
templates/admin/requests/view_request_type.mako
templates/requests/new_request.mako
templates/requests/show_request.mako
test/base/twilltestcase.py
test/functional/test_forms_and_requests.py
diffs (1969 lines):
diff -r 1fb29bd2725a -r c40962280e72 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py Wed Sep 16 11:27:50 2009 -0400
+++ b/lib/galaxy/model/__init__.py Wed Sep 16 12:39:57 2009 -0400
@@ -1005,11 +1005,31 @@
return os.path.abspath( os.path.join( path, "metadata_%d.dat" % self.id ) )
class FormDefinition( object ):
- def __init__(self, name=None, desc=None, fields=[], current_form=None):
+ types = Bunch( REQUEST = 'Sequencing Request Form',
+ SAMPLE = 'Sequencing Sample Form',
+ LIBRARY_INFO_TEMPLATE = 'Library information template' )
+ def __init__(self, name=None, desc=None, fields=[], current_form=None, form_type=None, layout=None):
self.name = name
self.desc = desc
self.fields = fields
self.form_definition_current = current_form
+ self.type = form_type
+ self.layout = layout
+ def fields_of_grid(self, layout_grid_name):
+ fields_dict = {}
+ if not layout_grid_name:
+ for i, f in enumerate(self.fields):
+ fields_dict[i] = f
+ else:
+ layout_index = -1
+ for index, lg_name in enumerate(self.layout):
+ if lg_name == layout_grid_name:
+ layout_index = index
+ break
+ for i, f in enumerate(self.fields):
+ if f['layout'] == str(layout_index):
+ fields_dict[i] = f
+ return fields_dict
class FormDefinitionCurrent( object ):
def __init__(self, form_definition=None):
@@ -1025,13 +1045,14 @@
SUBMITTED = 'Submitted',
COMPLETE = 'Complete')
def __init__(self, name=None, desc=None, request_type=None, user=None,
- form_values=None, library=None, state=False):
+ form_values=None, library=None, folder=None, state=False):
self.name = name
self.desc = desc
self.type = request_type
self.values = form_values
self.user = user
self.library = library
+ self.folder = folder
self.state = state
self.samples_list = []
def add_sample(self, sample_name=None, sample_desc=None, sample_values=None):
diff -r 1fb29bd2725a -r c40962280e72 lib/galaxy/model/mapping.py
--- a/lib/galaxy/model/mapping.py Wed Sep 16 11:27:50 2009 -0400
+++ b/lib/galaxy/model/mapping.py Wed Sep 16 12:39:57 2009 -0400
@@ -465,7 +465,9 @@
Integer,
ForeignKey( "form_definition_current.id", name='for_def_form_def_current_id_fk', use_alter=True ),
index=True ),
- Column( "fields", JSONType() ) )
+ Column( "fields", JSONType() ),
+ Column( "type", TrimmedString( 255 ), index=True ),
+ Column( "layout", JSONType() ), )
RequestType.table = Table('request_type', metadata,
Column( "id", Integer, primary_key=True),
@@ -494,6 +496,7 @@
Column( "request_type_id", Integer, ForeignKey( "request_type.id" ), index=True ),
Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True ),
Column( "library_id", Integer, ForeignKey( "library.id" ), index=True ),
+ Column( "folder_id", Integer, ForeignKey( "library_folder.id" ), index=True ),
Column( "state", TrimmedString( 255 ), index=True ),
Column( "deleted", Boolean, index=True, default=False ) )
@@ -612,8 +615,10 @@
backref="requests" ),
samples=relation( Sample,
primaryjoin=( Request.table.c.id == Sample.table.c.request_id ) ),
+ folder=relation( LibraryFolder,
+ primaryjoin=( Request.table.c.folder_id == LibraryFolder.table.c.id ) ),
library=relation( Library,
- primaryjoin=( Request.table.c.library_id == Library.table.c.id ) ),
+ primaryjoin=( Request.table.c.library_id == Library.table.c.id ) )
) )
assign_mapper( context, RequestType, RequestType.table,
diff -r 1fb29bd2725a -r c40962280e72 lib/galaxy/model/migrate/versions/0019_request_library_folder.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/model/migrate/versions/0019_request_library_folder.py Wed Sep 16 12:39:57 2009 -0400
@@ -0,0 +1,84 @@
+from sqlalchemy import *
+from sqlalchemy.orm import *
+from sqlalchemy.exceptions import *
+from migrate import *
+from migrate.changeset import *
+import datetime
+now = datetime.datetime.utcnow
+import sys, logging
+# Need our custom types, but don't import anything else from model
+from galaxy.model.custom_types import *
+
+log = logging.getLogger( __name__ )
+log.setLevel(logging.DEBUG)
+handler = logging.StreamHandler( sys.stdout )
+format = "%(name)s %(levelname)s %(asctime)s %(message)s"
+formatter = logging.Formatter( format )
+handler.setFormatter( formatter )
+log.addHandler( handler )
+
+metadata = MetaData( migrate_engine )
+db_session = scoped_session( sessionmaker( bind=migrate_engine, autoflush=False, transactional=False ) )
+
+def display_migration_details():
+ print "========================================"
+ print """This script creates a request.folder_id column which is a foreign
+key to the library_folder table. This also adds a 'type' and 'layout' column
+to the form_definition table."""
+ print "========================================"
+
+def upgrade():
+ display_migration_details()
+ # Load existing tables
+ metadata.reflect()
+ # Create the folder_id column
+ try:
+ Request_table = Table( "request", metadata, autoload=True )
+ except NoSuchTableError:
+ Request_table = None
+ log.debug( "Failed loading table request" )
+ if Request_table:
+ try:
+ col = Column( "folder_id", Integer, index=True )
+ col.create( Request_table )
+ assert col is Request_table.c.folder_id
+ except Exception, e:
+ log.debug( "Adding column 'folder_id' to request table failed: %s" % ( str( e ) ) )
+ try:
+ LibraryFolder_table = Table( "library_folder", metadata, autoload=True )
+ except NoSuchTableError:
+ Request_table = None
+ log.debug( "Failed loading table library_folder" )
+ # Add 1 foreign key constraint to the library_folder table
+ if Request_table and LibraryFolder_table:
+ try:
+ cons = ForeignKeyConstraint( [Request_table.c.folder_id],
+ [LibraryFolder_table.c.id],
+ name='request_folder_id_fk' )
+ # Create the constraint
+ cons.create()
+ except Exception, e:
+ log.debug( "Adding foreign key constraint 'request_folder_id_fk' to table 'library_folder' failed: %s" % ( str( e ) ) )
+ # Create the type column in form_definition
+ try:
+ FormDefinition_table = Table( "form_definition", metadata, autoload=True )
+ except NoSuchTableError:
+ FormDefinition_table = None
+ log.debug( "Failed loading table form_definition" )
+ if FormDefinition_table:
+ try:
+ col = Column( "type", TrimmedString( 255 ), index=True )
+ col.create( FormDefinition_table )
+ assert col is FormDefinition_table.c.type
+ except Exception, e:
+ log.debug( "Adding column 'type' to form_definition table failed: %s" % ( str( e ) ) )
+ try:
+ col = Column( "layout", JSONType())
+ col.create( FormDefinition_table )
+ assert col is FormDefinition_table.c.layout
+ except Exception, e:
+ log.debug( "Adding column 'layout' to form_definition table failed: %s" % ( str( e ) ) )
+
+
+def downgrade():
+ pass
diff -r 1fb29bd2725a -r c40962280e72 lib/galaxy/web/controllers/admin.py
--- a/lib/galaxy/web/controllers/admin.py Wed Sep 16 11:27:50 2009 -0400
+++ b/lib/galaxy/web/controllers/admin.py Wed Sep 16 12:39:57 2009 -0400
@@ -749,122 +749,3 @@
else:
last_updated[job.id] = '%s minutes' % int( delta.seconds / 60 )
return trans.fill_template( '/admin/jobs.mako', jobs = jobs, last_updated = last_updated, cutoff = cutoff, msg = msg, messagetype = messagetype )
- @web.expose
- @web.require_admin
- def manage_request_types( self, trans, **kwd ):
- params = util.Params( kwd )
- msg = util.restore_text( params.get( 'msg', '' ) )
- messagetype = params.get( 'messagetype', 'done' )
- show_filter = util.restore_text( params.get( 'show_filter', 'Active' ) )
- forms = get_all_forms(trans, all_versions=True)
- request_types_list = trans.app.model.RequestType.query().all()
- if show_filter == 'All':
- request_types = request_types_list
- elif show_filter == 'Deleted':
- request_types = [rt for rt in request_types_list if rt.deleted]
- else:
- request_types = [rt for rt in request_types_list if not rt.deleted]
- return trans.fill_template( '/admin/requests/manage_request_types.mako',
- request_types=request_types,
- forms=forms,
- show_filter=show_filter,
- msg=msg,
- messagetype=messagetype )
- @web.expose
- @web.require_admin
- def request_type( self, trans, **kwd ):
- params = util.Params( kwd )
- msg = util.restore_text( params.get( 'msg', '' ) )
- messagetype = params.get( 'messagetype', 'done' )
- if params.get( 'create', False ):
- return trans.fill_template( '/admin/requests/create_request_type.mako',
- forms=get_all_forms( trans,
- filter=dict(deleted=False) ),
- msg=msg,
- messagetype=messagetype)
- elif params.get( 'define_states_button', False ):
- return trans.fill_template( '/admin/requests/add_states.mako',
- request_type_name=util.restore_text( params.name ),
- desc=util.restore_text( params.description ),
- num_states=int(util.restore_text( params.num_states )),
- request_form_id=int(util.restore_text( params.request_form_id )),
- sample_form_id=int(util.restore_text( params.sample_form_id )),
- msg=msg,
- messagetype=messagetype)
- elif params.get( 'save_request_type', False ):
- st, msg = self._save_request_type(trans, **kwd)
- if not st:
- return trans.fill_template( '/admin/requests/create_request_type.mako',
- forms=get_all_forms( trans ),
- msg=msg,
- messagetype='error')
- return trans.response.send_redirect( web.url_for( controller='admin',
- action='manage_request_types',
- msg='Request type <b>%s</b> has been created' % st.name,
- messagetype='done') )
- elif params.get('view', False):
- rt = trans.app.model.RequestType.get(int(util.restore_text( params.id )))
- ss_list = trans.app.model.SampleState.filter(trans.app.model.SampleState.table.c.request_type_id == rt.id).all()
- return trans.fill_template( '/admin/requests/view_request_type.mako',
- request_type=rt,
- forms=get_all_forms( trans ),
- states_list=ss_list,
- deleted=False,
- show_deleted=False,
- msg=msg,
- messagetype=messagetype )
- def _save_request_type(self, trans, **kwd):
- params = util.Params( kwd )
- num_states = int( util.restore_text( params.get( 'num_states', 0 ) ))
- proceed = True
- for i in range( num_states ):
- if not util.restore_text( params.get( 'state_name_%i' % i, None ) ):
- proceed = False
- break
- if not proceed:
- msg = "All the state name(s) must be completed."
- return None, msg
- rt = trans.app.model.RequestType()
- rt.name = util.restore_text( params.name )
- rt.desc = util.restore_text( params.description ) or ""
- rt.request_form = trans.app.model.FormDefinition.get(int( params.request_form_id ))
- rt.sample_form = trans.app.model.FormDefinition.get(int( params.sample_form_id ))
- rt.flush()
- # set sample states
- ss_list = trans.app.model.SampleState.filter(trans.app.model.SampleState.table.c.request_type_id == rt.id).all()
- for ss in ss_list:
- ss.delete()
- ss.flush()
- for i in range( num_states ):
- name = util.restore_text( params.get( 'state_name_%i' % i, None ))
- desc = util.restore_text( params.get( 'state_desc_%i' % i, None ))
- ss = trans.app.model.SampleState(name, desc, rt)
- ss.flush()
- msg = "The new request type named '%s' with %s state(s) has been created" % (rt.name, num_states)
- return rt, msg
- @web.expose
- @web.require_admin
- def delete_request_type( self, trans, **kwd ):
- params = util.Params( kwd )
- msg = util.restore_text( params.get( 'msg', '' ) )
- messagetype = params.get( 'messagetype', 'done' )
- rt = trans.app.model.RequestType.get(int(util.restore_text( params.request_type_id )))
- rt.deleted = True
- rt.flush()
- return trans.response.send_redirect( web.url_for( controller='admin',
- action='manage_request_types',
- msg='Request type <b>%s</b> has been deleted' % rt.name,
- messagetype='done') )
- @web.expose
- @web.require_admin
- def undelete_request_type( self, trans, **kwd ):
- params = util.Params( kwd )
- msg = util.restore_text( params.get( 'msg', '' ) )
- messagetype = params.get( 'messagetype', 'done' )
- rt = trans.app.model.RequestType.get(int(util.restore_text( params.request_type_id )))
- rt.deleted = False
- rt.flush()
- return trans.response.send_redirect( web.url_for( controller='admin',
- action='manage_request_types',
- msg='Request type <b>%s</b> has been undeleted' % rt.name,
- messagetype='done') )
diff -r 1fb29bd2725a -r c40962280e72 lib/galaxy/web/controllers/forms.py
--- a/lib/galaxy/web/controllers/forms.py Wed Sep 16 11:27:50 2009 -0400
+++ b/lib/galaxy/web/controllers/forms.py Wed Sep 16 12:39:57 2009 -0400
@@ -31,37 +31,72 @@
show_filter = params.get( 'show_filter', 'Active' )
return self._show_forms_list(trans, msg, messagetype, show_filter)
def _show_forms_list(self, trans, msg, messagetype, show_filter='Active'):
- fdc_list = trans.app.model.FormDefinitionCurrent.query().all()
+ all_forms = trans.app.model.FormDefinitionCurrent.query().all()
if show_filter == 'All':
- forms_list = fdc_list
+ forms_list = all_forms
elif show_filter == 'Deleted':
- forms_list = [form for form in fdc_list if form.deleted]
+ forms_list = [form for form in all_forms if form.deleted]
else:
- forms_list = [form for form in fdc_list if not form.deleted]
+ forms_list = [form for form in all_forms if not form.deleted]
return trans.fill_template( '/admin/forms/manage_forms.mako',
fdc_list=forms_list,
+ all_forms=all_forms,
show_filter=show_filter,
msg=msg,
messagetype=messagetype )
+ def __form_types_widget(self, trans, selected='none'):
+ form_type_selectbox = SelectField( 'form_type_selectbox',
+ refresh_on_change=True,
+ refresh_on_change_values=[trans.app.model.FormDefinition.types.SAMPLE] )
+ if selected == 'none':
+ form_type_selectbox.add_option('Select one', 'none', selected=True)
+ else:
+ form_type_selectbox.add_option('Select one', 'none')
+ for ft in trans.app.model.FormDefinition.types.items():
+ if selected == ft[1]:
+ form_type_selectbox.add_option(ft[1], ft[1], selected=True)
+ else:
+ form_type_selectbox.add_option(ft[1], ft[1])
+ return form_type_selectbox
+
@web.expose
@web.require_admin
def new( self, trans, **kwd ):
params = util.Params( kwd )
msg = util.restore_text( params.get( 'msg', '' ) )
messagetype = params.get( 'messagetype', 'done' )
+ self.__imported_from_file = False
if params.get( 'create_form_button', False ):
fd, msg = self.__save_form( trans, fdc_id=None, **kwd )
+ if not fd:
+ return trans.response.send_redirect( web.url_for( controller='forms',
+ action='new',
+ msg=msg,
+ messagetype='error' ) )
self.__get_saved_form( fd )
- return trans.response.send_redirect( web.url_for( controller='forms',
- action='edit',
- form_id=fd.id,
- show_form=True ) )
+ if self.__imported_from_file:
+ return trans.response.send_redirect( web.url_for( controller='forms',
+ action='edit',
+ show_form=True,
+ form_id=fd.id) )
+ else:
+ return trans.response.send_redirect( web.url_for( controller='forms',
+ action='edit',
+ form_id=fd.id,
+ add_field_button='Add field',
+ num_fields=0,
+ name=fd.name,
+ description=fd.desc,
+ form_type_selectbox=fd.type ) )
self.current_form = {}
self.current_form[ 'name' ] = 'New Form'
self.current_form[ 'desc' ] = ''
+ self.current_form['type'] = 'none'
+ self.current_form[ 'layout' ] = ['Main']
self.current_form[ 'fields' ] = []
inputs = [ ( 'Name', TextField( 'name', 40, self.current_form[ 'name' ] ) ),
( 'Description', TextField( 'description', 40, self.current_form[ 'desc' ] ) ),
+ ( 'Type', self.__form_types_widget(trans, selected=self.current_form['type']) ),
( 'Import from csv file (Optional)', FileField( 'file_data', 40, '' ) ) ]
return trans.fill_template( '/admin/forms/create_form.mako',
inputs=inputs,
@@ -115,12 +150,19 @@
# The following two dicts store the unsaved select box options
self.del_options = {}
self.add_options = {}
- if fd.fields:
- return self.__show( trans=trans, form=fd, msg=msg, messagetype=messagetype, **kwd )
- else:
- # If the form is empty, we'll simulate a click on the add_field_button so the
- # form will be displayed with the field choice, saving a mouse click.
- return self.__show( trans=trans, form=fd, msg=msg, messagetype=messagetype, empty_form=True, **kwd )
+ return self.__show( trans=trans, form=fd, msg=msg, messagetype=messagetype, **kwd )
+ #Add a layout grid
+ elif params.get( 'add_layout_grid', False ):
+ self.__update_current_form( trans, **kwd )
+ self.__add_layout_grid()
+ # show the form again
+ return self.__show( trans=trans, form=fd, msg=msg, messagetype=messagetype, **kwd )
+ # Delete a layout grid
+ elif params.get( 'remove_layout_grid_button', False ):
+ self.__update_current_form( trans, **kwd )
+ index = int( kwd[ 'remove_layout_grid_button' ].split( ' ' )[2] ) - 1
+ self.__remove_layout_grid( index )
+ return self.__show( trans=trans, form=fd, msg=msg, messagetype=messagetype, **kwd )
# Delete a field
elif params.get( 'remove_button', False ):
self.__update_current_form( trans, **kwd )
@@ -163,7 +205,11 @@
elif params.get( 'select_box_options', False ) == 'add':
index = int( kwd[ 'field_index' ] )
self.current_form[ 'fields' ][ index ][ 'selectlist' ].append( '' )
- return self.__show( trans=trans, form=fd, msg=msg, messagetype=messagetype, **kwd )
+ return self.__show( trans=trans, form=fd, msg=msg, messagetype=messagetype, **kwd )
+ def __add_layout_grid(self):
+ self.current_form['layout'].append('')
+ def __remove_layout_grid(self, index):
+ del self.current_form['layout'][index]
def __remove_field(self, index):
del self.current_form['fields'][index]
def __add_field(self):
@@ -175,7 +221,8 @@
'visible': True,
'required': False,
'type': BaseField.form_field_types()[0],
- 'selectlist': [] }
+ 'selectlist': [],
+ 'layout': 'none' }
self.current_form['fields'].append(empty_field)
def __get_field(self, index, **kwd):
params = util.Params( kwd )
@@ -187,6 +234,7 @@
helptext = util.restore_text( params.get( 'field_helptext_%i' % index, '' ) )
required = params.get( 'field_required_%i' % index, False )
field_type = util.restore_text( params.get( 'field_type_%i' % index, '' ) )
+ layout = params.get( 'field_layout_%i' % index, '' )
if field_type == 'SelectField':
selectlist = self.__get_selectbox_options(index, **kwd)
return {'label': name,
@@ -194,12 +242,14 @@
'visible': True,
'required': required,
'type': field_type,
- 'selectlist': selectlist }
+ 'selectlist': selectlist,
+ 'layout': layout }
return {'label': name,
'helptext': helptext,
'visible': True,
'required': required,
- 'type': field_type}
+ 'type': field_type,
+ 'layout': layout}
def __get_selectbox_options(self, index, **kwd):
'''
This method gets all the options entered by the user for field when
@@ -219,6 +269,8 @@
self.current_form = {}
self.current_form['name'] = fd.name
self.current_form['desc'] = fd.desc
+ self.current_form['type'] = fd.type
+ self.current_form['layout'] = list(copy.deepcopy(fd.layout))
self.current_form['fields'] = list(copy.deepcopy(fd.fields))
def __validate_form(self, **kwd):
'''
@@ -230,6 +282,9 @@
# form name
if not util.restore_text( params.name ):
return None, 'Form name must be filled.'
+ # form type
+ if util.restore_text( params.form_type_selectbox ) == 'none':
+ return None, 'Form type must be selected.'
# fields
for i in range( len(self.current_form['fields']) ):
if not util.restore_text(params.get( 'field_name_%i' % i, None )):
@@ -239,6 +294,11 @@
params = util.Params( kwd )
name = util.restore_text( params.name )
desc = util.restore_text( params.description ) or ""
+ form_type = util.restore_text( params.form_type_selectbox )
+ layout = []
+ if form_type == trans.app.model.FormDefinition.types.SAMPLE:
+ for index in range(len(self.current_form[ 'layout' ])):
+ layout.append(params.get( 'grid_layout%i' % index, '' ))
csv_file = params.get( 'file_data', '' )
if csv_file == '':
# set form fields
@@ -247,16 +307,18 @@
fields.append(self.__get_field(i, **kwd))
fields = fields
else:
- fields = self.__import_fields(trans, csv_file)
- return name, desc, fields
+ fields = self.__import_fields(trans, csv_file, form_type)
+ return name, desc, form_type, layout, fields
def __update_current_form(self, trans, **kwd):
- name, desc, fields = self.__get_form(trans, **kwd)
+ name, desc, form_type, layout, fields = self.__get_form(trans, **kwd)
self.current_form = {}
self.current_form['name'] = name
self.current_form['desc'] = desc
+ self.current_form['type'] = form_type
+ self.current_form['layout'] = layout
self.current_form['fields'] = fields
- def __import_fields(self, trans, csv_file):
+ def __import_fields(self, trans, csv_file, form_type):
'''
"company","name of the company", "True", "required", "TextField",,
"due date","turnaround time", "True", "optional", "SelectField","24 hours, 1 week, 1 month"
@@ -265,20 +327,32 @@
fields = []
try:
reader = csv.reader(csv_file.file)
- for row in reader:
- options = row[5].split(',')
- fields.append({'label': row[0],
- 'helptext': row[1],
- 'visible': row[2],
- 'required': row[3],
- 'type': row[4],
- 'selectlist': options})
+ if form_type == trans.app.model.FormDefinition.types.SAMPLE:
+ for row in reader:
+ options = row[5].split(',')
+ fields.append({'label': row[0],
+ 'helptext': row[1],
+ 'visible': row[2],
+ 'required': row[3],
+ 'type': row[4],
+ 'selectlist': options,
+ 'layout':row[6]})
+ else:
+ for row in reader:
+ options = row[5].split(',')
+ fields.append({'label': row[0],
+ 'helptext': row[1],
+ 'visible': row[2],
+ 'required': row[3],
+ 'type': row[4],
+ 'selectlist': options})
except:
return trans.response.send_redirect( web.url_for( controller='forms',
action='new',
status='error',
message='Error in importing <b>%s</b> file' % csv_file,
**kwd))
+ self.__imported_from_file = True
return fields
def __save_form(self, trans, fdc_id=None, **kwd):
@@ -290,7 +364,7 @@
if not flag:
return None, msg
fd = trans.app.model.FormDefinition()
- fd.name, fd.desc, fd.fields = self.__get_form(trans, **kwd)
+ fd.name, fd.desc, fd.type, fd.layout, fd.fields = self.__get_form(trans, **kwd)
if fdc_id: # save changes to the existing form
# change the pointer in the form_definition_current table to point
# to this new record
@@ -306,7 +380,7 @@
return fd, msg
class FieldUI(object):
- def __init__(self, index, field=None, field_type=None):
+ def __init__(self, layout_grids, index, field=None, field_type=None):
'''
This method returns a list of widgets which describes a field. This
includes label, helptext, type, & required/optional
@@ -323,6 +397,11 @@
self.required = SelectField('field_required_'+str(index), display='radio')
self.required.add_option('Required', 'required')
self.required.add_option('Optional', 'optional', selected=True)
+ self.layout_grids = layout_grids
+ if layout_grids:
+ self.layout_selectbox = SelectField('field_layout_'+str(index))
+ for index, grid_name in enumerate(layout_grids):
+ self.layout_selectbox.add_option("%i. %s" %(index+1, grid_name), index)
if field:
self.fill(field, field_type)
def fill(self, field, field_type=None):
@@ -350,6 +429,14 @@
self.required = SelectField('field_required_'+str(self.index), display='radio')
self.required.add_option('Required', 'required', selected=True)
self.required.add_option('Optional', 'optional')
+ # layout
+ if self.layout_grids:
+ self.layout_selectbox = SelectField('field_layout_'+str(self.index))
+ for i, grid_name in enumerate(self.layout_grids):
+ if field['layout'] == str(i):
+ self.layout_selectbox.add_option("%i. %s" %(i+1, grid_name), i, selected=True)
+ else:
+ self.layout_selectbox.add_option("%i. %s" %(i+1, grid_name), i)
def selectbox_ui(self, field):
self.selectbox_options = []
if field['selectlist']:
@@ -358,6 +445,12 @@
TextField('field_'+str(self.index)+'_option_'+str(ctr),
40, option)))
def get(self):
+ if self.layout_grids:
+ return [( 'Label', self.label ),
+ ( 'Help text', self.helptext ),
+ ( 'Type', self.fieldtype, self.selectbox_options),
+ ( '', self.required),
+ ( 'Select the grid layout to place this field', self.layout_selectbox)]
return [( 'Label', self.label ),
( 'Help text', self.helptext ),
( 'Type', self.fieldtype, self.selectbox_options),
@@ -367,31 +460,29 @@
def label(self):
return str(self.index)+'.'+self.label
- def __show( self, trans, form, msg='', messagetype='done', empty_form=False, **kwd ):
+ def __show( self, trans, form, msg='', messagetype='done', **kwd ):
'''
This method displays the form and any of the changes made to it,
The empty_form param allows for this method to simulate clicking
the "add_field_button" on the edit_form.mako page so that the page
is displayed with the first field to be added, saving a mouse click.
'''
- if empty_form:
- # Send params that will simulate a button click on the add_field_button
- # button on edit_form.mako.
- param_dict = { 'form_id' : str( form.id ),
- 'num_fields' : '0',
- 'refresh' : 'true',
- 'name' : form.name,
- 'description' : form.desc,
- 'add_field_button' : 'Add field' }
- self.edit( trans, **param_dict )
params = util.Params( kwd )
# name & description
form_details = [ ( 'Name', TextField( 'name', 40, self.current_form[ 'name' ] ) ),
- ( 'Description', TextField( 'description', 40, self.current_form[ 'desc' ] ) ) ]
+ ( 'Description', TextField( 'description', 40, self.current_form[ 'desc' ] ) ),
+ ( 'Type', self.__form_types_widget(trans, selected=self.current_form['type']) ) ]
+ form_layout = []
+ if self.current_form['type'] == trans.app.model.FormDefinition.types.SAMPLE:
+ for index, lg in enumerate(self.current_form['layout']):
+ form_layout.append( TextField( 'grid_layout%i' % index, 40, lg ))
# fields
field_details = []
for index, field in enumerate( self.current_form[ 'fields' ] ):
- field_ui = self.FieldUI( index, field )
+ if self.current_form['type'] == trans.app.model.FormDefinition.types.SAMPLE:
+ field_ui = self.FieldUI( self.current_form['layout'], index, field )
+ else:
+ field_ui = self.FieldUI( None, index, field )
field_details.append( field_ui.get() )
return trans.fill_template( '/admin/forms/edit_form.mako',
form_details=form_details,
@@ -399,10 +490,12 @@
form=form,
field_types=BaseField.form_field_types(),
msg=msg,
- messagetype=messagetype )
+ messagetype=messagetype,
+ current_form_type=self.current_form['type'],
+ layout_grids=form_layout )
# Common methods for all components that use forms
-def get_all_forms( trans, all_versions=False, filter=None ):
+def get_all_forms( trans, all_versions=False, filter=None, form_type='All' ):
'''
Return all the latest forms from the form_definition_current table
if all_versions is set to True. Otherwise return all the versions
@@ -418,7 +511,11 @@
fdc_list = trans.app.model.FormDefinitionCurrent.query().filter_by(**filter)
else:
fdc_list = trans.app.model.FormDefinitionCurrent.query().all()
- return [ fdc.latest_form for fdc in fdc_list ]
+ if form_type == 'All':
+ return [ fdc.latest_form for fdc in fdc_list ]
+ else:
+ return [ fdc.latest_form for fdc in fdc_list if fdc.latest_form.type == form_type ]
+
def get_form_widgets( trans, form, contents=[], user=None, **kwd ):
diff -r 1fb29bd2725a -r c40962280e72 lib/galaxy/web/controllers/library.py
--- a/lib/galaxy/web/controllers/library.py Wed Sep 16 11:27:50 2009 -0400
+++ b/lib/galaxy/web/controllers/library.py Wed Sep 16 12:39:57 2009 -0400
@@ -1100,7 +1100,8 @@
library_id=library_id,
folder_id=folder_id,
ldda_id=ldda_id,
- forms=get_all_forms( trans, filter=dict(deleted=False) ),
+ forms=get_all_forms( trans, filter=dict(deleted=False),
+ form_type=trans.app.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE ),
msg=msg,
messagetype=messagetype )
@web.expose
diff -r 1fb29bd2725a -r c40962280e72 lib/galaxy/web/controllers/requests.py
--- a/lib/galaxy/web/controllers/requests.py Wed Sep 16 11:27:50 2009 -0400
+++ b/lib/galaxy/web/controllers/requests.py Wed Sep 16 12:39:57 2009 -0400
@@ -148,7 +148,7 @@
request_details.append(dict(label='Date created',
value=request.create_time,
helptext=''))
- # library associated
+ # library associated
if request.library:
value = request.library.name
else:
@@ -156,6 +156,14 @@
request_details.append( dict( label='Data library',
value=value,
helptext='Data library where the resultant dataset will be stored' ) )
+ # folder associated
+ if request.folder:
+ value = request.folder.name
+ else:
+ value = None
+ request_details.append( dict( label='Data library folder',
+ value=value,
+ helptext='Data library folder where the resultant dataset will be stored' ) )
# form fields
for index, field in enumerate(request.type.request_form.fields):
if field['required']:
@@ -230,7 +238,7 @@
return trans.response.send_redirect( web.url_for( controller='requests',
action='list',
status='error',
- message='Error in importing <b>%s</b> samples file' % file_obj.file,
+ message='Error in importing samples file',
**kwd))
elif params.get('add_sample_button', False) == 'Add New':
# save the all (saved+unsaved) sample info in 'current_samples'
@@ -488,7 +496,9 @@
def __library_ui(self, libraries, request=None, **kwd):
params = util.Params( kwd )
lib_id = params.get( 'library_id', 'none' )
- lib_list = SelectField( 'library_id', refresh_on_change=True, refresh_on_change_values=['new'] )
+ lib_id_list = ['new'] + [str(lib.id) for lib in libraries.keys()]
+ lib_list = SelectField( 'library_id', refresh_on_change=True, refresh_on_change_values=lib_id_list )
+ folders = []
if request and lib_id == 'none':
if request.library:
lib_id = str(request.library.id)
@@ -499,23 +509,48 @@
for lib, hidden_folder_ids in libraries.items():
if str(lib.id) == lib_id:
lib_list.add_option(lib.name, lib.id, selected=True)
+ folders.append( lib.root_folder )
+ for f in lib.root_folder.folders:
+ if str(f.id) not in hidden_folder_ids.split(','):
+ folders.append( f )
else:
lib_list.add_option(lib.name, lib.id)
+ lib_list.refresh_on_change_values.append(lib.id)
if lib_id == 'new':
lib_list.add_option('Create a new data library', 'new', selected=True)
else:
lib_list.add_option('Create a new data library', 'new')
- widget = dict(label='Data library',
- widget=lib_list,
- helptext='Data library where the resultant dataset will be stored.')
+ lib_widget = dict(label='Data library',
+ widget=lib_list,
+ helptext='Data library where the resultant dataset will be stored.')
+ if folders:
+ if request:
+ if request.folder:
+ current_fid = request.folder.id
+ else:
+ current_fid = request.library.root_folder.id
+ else:
+ current_fid = params.get( 'folder_id', 'none' )
+ folder_list = SelectField( 'folder_id')
+ for f in folders:
+ if str(f.id) == current_fid:
+ folder_list.add_option(f.name, f.id, selected=True)
+ else:
+ folder_list.add_option(f.name, f.id)
+ folder_widget = dict(label='Folder',
+ widget=folder_list,
+ helptext='Folder of the selected data library where the resultant dataset will be stored.')
if lib_id == 'new':
new_lib = dict(label='Create a new data library',
widget=TextField('new_library_name', 40,
util.restore_text( params.get( 'new_library_name', '' ) )),
helptext='Enter a name here to request a new data library')
- return [widget, new_lib]
+ return [lib_widget, new_lib]
else:
- return [widget]
+ if folders:
+ return [lib_widget, folder_widget]
+ else:
+ return [lib_widget]
def __validate(self, trans, request):
'''
Validates the request entered by the user
@@ -546,6 +581,13 @@
library = trans.app.model.Library.get(int(params.get('library_id', None)))
except:
library = None
+ try:
+ folder = trans.app.model.LibraryFolder.get(int(params.get('folder_id', None)))
+ except:
+ if library:
+ folder = library.root_folder
+ else:
+ folder = None
# fields
values = []
for index, field in enumerate(request_type.request_form.fields):
@@ -577,7 +619,7 @@
if not request:
request = trans.app.model.Request(name, desc, request_type,
trans.user, form_values,
- library=library,
+ library=library, folder=folder,
state=trans.app.model.Request.states.UNSUBMITTED)
request.flush()
else:
@@ -587,6 +629,7 @@
request.user = trans.user
request.values = form_values
request.library = library
+ request.folder = folder
request.state = trans.app.model.Request.states.UNSUBMITTED
request.flush()
return request
diff -r 1fb29bd2725a -r c40962280e72 lib/galaxy/web/controllers/requests_admin.py
--- a/lib/galaxy/web/controllers/requests_admin.py Wed Sep 16 11:27:50 2009 -0400
+++ b/lib/galaxy/web/controllers/requests_admin.py Wed Sep 16 12:39:57 2009 -0400
@@ -8,6 +8,7 @@
from galaxy.web.form_builder import *
from datetime import datetime, timedelta
from galaxy.web.controllers.forms import get_form_widgets
+from galaxy.web.controllers.forms import get_all_forms
log = logging.getLogger( __name__ )
@@ -100,6 +101,7 @@
else:
self.request_grid.default_filter = dict(state=kwargs['show_filter'], deleted=False)
self.request_grid.show_filter = kwargs.get('show_filter', trans.app.model.Request.states.SUBMITTED)
+ self.__update_request_state(trans)
# Render the list view
return self.request_grid( trans, **kwargs )
@web.expose
@@ -553,8 +555,17 @@
else:
value = None
request_details.append(dict(label='Data library',
- value=value,
- helptext='Data library where the resultant dataset will be stored'))
+ value=value,
+ helptext='Data library where the resultant dataset will be stored'))
+ # folder associated
+ if request.folder:
+ value = request.folder.name
+ else:
+ value = None
+ request_details.append( dict( label='Data library folder',
+ value=value,
+ helptext='Data library folder where the resultant dataset will be stored' ) )
+
# form fields
for index, field in enumerate(request.type.request_form.fields):
if field['required']:
@@ -714,26 +725,31 @@
"""
params = util.Params( kwd )
lib_id = params.get( 'library_id', 'none' )
- all_libraries = trans.app.model.Library.filter( trans.app.model.Library.table.c.deleted == False ) \
- .order_by( trans.app.model.Library.name ).all()
- roles = user.all_roles()
- actions_to_check = [ trans.app.security_agent.permitted_actions.LIBRARY_ADD ]
- # The libraries dictionary looks like: { library : '1,2' }, library : '3' }
- # Its keys are the libraries that should be displayed for the current user and whose values are a
- # string of comma-separated folder ids, of the associated folders the should NOT be displayed.
- # The folders that should not be displayed may not be a complete list, but it is ultimately passed
- # to the calling method to keep from re-checking the same folders when the library / folder
- # select lists are rendered.
- #
- # TODO: RC, when you add the folders select list to your request form, take advantage of the hidden_folder_ids
- # so that you do not need to check those same folders yet again when populating the select list.
- #
- libraries = {}
- for library in all_libraries:
- can_show, hidden_folder_ids = trans.app.security_agent.show_library_item( user, roles, library, actions_to_check )
- if can_show:
- libraries[ library ] = hidden_folder_ids
- lib_list = SelectField( 'library_id', refresh_on_change=True, refresh_on_change_values=['new'] )
+ if not user:
+ libraries = {}
+ else:
+ all_libraries = trans.app.model.Library.filter( trans.app.model.Library.table.c.deleted == False ) \
+ .order_by( trans.app.model.Library.name ).all()
+ roles = user.all_roles()
+ actions_to_check = [ trans.app.security_agent.permitted_actions.LIBRARY_ADD ]
+ # The libraries dictionary looks like: { library : '1,2' }, library : '3' }
+ # Its keys are the libraries that should be displayed for the current user and whose values are a
+ # string of comma-separated folder ids, of the associated folders the should NOT be displayed.
+ # The folders that should not be displayed may not be a complete list, but it is ultimately passed
+ # to the calling method to keep from re-checking the same folders when the library / folder
+ # select lists are rendered.
+ #
+ # TODO: RC, when you add the folders select list to your request form, take advantage of the hidden_folder_ids
+ # so that you do not need to check those same folders yet again when populating the select list.
+ #
+ libraries = {}
+ for library in all_libraries:
+ can_show, hidden_folder_ids = trans.app.security_agent.show_library_item( user, roles, library, actions_to_check )
+ if can_show:
+ libraries[ library ] = hidden_folder_ids
+ lib_id_list = ['new'] + [str(lib.id) for lib in libraries.keys()]
+ lib_list = SelectField( 'library_id', refresh_on_change=True, refresh_on_change_values=lib_id_list )
+ folders = []
if request and lib_id == 'none':
if request.library:
lib_id = str(request.library.id)
@@ -744,23 +760,48 @@
for lib, hidden_folder_ids in libraries.items():
if str(lib.id) == lib_id:
lib_list.add_option(lib.name, lib.id, selected=True)
+ folders.append( lib.root_folder )
+ for f in lib.root_folder.folders:
+ if str(f.id) not in hidden_folder_ids.split(','):
+ folders.append( f )
else:
lib_list.add_option(lib.name, lib.id)
+ lib_list.refresh_on_change_values.append(lib.id)
if lib_id == 'new':
lib_list.add_option('Create a new data library', 'new', selected=True)
else:
lib_list.add_option('Create a new data library', 'new')
- widget = dict(label='Data library',
- widget=lib_list,
- helptext='Data library where the resultant dataset will be stored.')
+ lib_widget = dict(label='Data library',
+ widget=lib_list,
+ helptext='Data library where the resultant dataset will be stored.')
+ if folders:
+ if request:
+ if request.folder:
+ current_fid = request.folder.id
+ else:
+ current_fid = request.library.root_folder.id
+ else:
+ current_fid = params.get( 'folder_id', 'none' )
+ folder_list = SelectField( 'folder_id')
+ for f in folders:
+ if str(f.id) == current_fid:
+ folder_list.add_option(f.name, f.id, selected=True)
+ else:
+ folder_list.add_option(f.name, f.id)
+ folder_widget = dict(label='Folder',
+ widget=folder_list,
+ helptext='Folder of the selected data library where the resultant dataset will be stored.')
if lib_id == 'new':
- new_lib = dict(label='Create a new Library',
+ new_lib = dict(label='Create a new data library',
widget=TextField('new_library_name', 40,
util.restore_text( params.get( 'new_library_name', '' ) )),
- helptext='Enter a library name here to request a new library')
- return [widget, new_lib]
+ helptext='Enter a name here to request a new data library')
+ return [lib_widget, new_lib]
else:
- return [widget]
+ if folders:
+ return [lib_widget, folder_widget]
+ else:
+ return [lib_widget]
def __validate(self, trans, request):
'''
Validates the request entered by the user
@@ -795,6 +836,13 @@
library = trans.app.model.Library.get(int(params.get('library_id', None)))
except:
library = None
+ try:
+ folder = trans.app.model.LibraryFolder.get(int(params.get('folder_id', None)))
+ except:
+ if library:
+ folder = library.root_folder
+ else:
+ folder = None
# fields
values = []
for index, field in enumerate(request_type.request_form.fields):
@@ -826,7 +874,7 @@
if not request:
request = trans.app.model.Request(name, desc, request_type,
user, form_values,
- library=library,
+ library=library, folder=folder,
state=trans.app.model.Request.states.UNSUBMITTED)
request.flush()
else:
@@ -836,6 +884,7 @@
request.user = user
request.values = form_values
request.library = library
+ request.folder = folder
request.flush()
return request
@web.expose
@@ -934,6 +983,13 @@
request_id=request.id,
msg='Bar codes has been saved for this request',
messagetype='done'))
+
+ def __update_request_state(self, trans):
+ requests = trans.app.model.Request.query.filter_by(deleted=False,
+ state=trans.app.model.Request.states.SUBMITTED)
+ for request in requests:
+ self.__set_request_state(request)
+
def __set_request_state(self, request):
# check if all the samples of the current request are in the final state
complete = True
@@ -1013,4 +1069,128 @@
return trans.fill_template( '/admin/samples/events.mako',
events_list=events_list,
sample=sample, widgets=widgets, title=title)
-
\ No newline at end of file
+
+ # Request Type Stuff
+ @web.expose
+ @web.require_admin
+ def manage_request_types( self, trans, **kwd ):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ show_filter = util.restore_text( params.get( 'show_filter', 'Active' ) )
+ forms = get_all_forms(trans, all_versions=True)
+ request_types_list = trans.app.model.RequestType.query().all()
+ if show_filter == 'All':
+ request_types = request_types_list
+ elif show_filter == 'Deleted':
+ request_types = [rt for rt in request_types_list if rt.deleted]
+ else:
+ request_types = [rt for rt in request_types_list if not rt.deleted]
+ return trans.fill_template( '/admin/requests/manage_request_types.mako',
+ request_types=request_types,
+ forms=forms,
+ show_filter=show_filter,
+ msg=msg,
+ messagetype=messagetype )
+ @web.expose
+ @web.require_admin
+ def request_type( self, trans, **kwd ):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ if params.get( 'create', False ):
+ return trans.fill_template( '/admin/requests/create_request_type.mako',
+ request_forms=get_all_forms( trans,
+ filter=dict(deleted=False),
+ form_type=trans.app.model.FormDefinition.types.REQUEST ),
+ sample_forms=get_all_forms( trans,
+ filter=dict(deleted=False),
+ form_type=trans.app.model.FormDefinition.types.SAMPLE ),
+ msg=msg,
+ messagetype=messagetype)
+ elif params.get( 'define_states_button', False ):
+ return trans.fill_template( '/admin/requests/add_states.mako',
+ request_type_name=util.restore_text( params.name ),
+ desc=util.restore_text( params.description ),
+ num_states=int(util.restore_text( params.num_states )),
+ request_form_id=int(util.restore_text( params.request_form_id )),
+ sample_form_id=int(util.restore_text( params.sample_form_id )),
+ msg=msg,
+ messagetype=messagetype)
+ elif params.get( 'save_request_type', False ):
+ st, msg = self.__save_request_type(trans, **kwd)
+ if not st:
+ return trans.fill_template( '/admin/requests/create_request_type.mako',
+ forms=get_all_forms( trans ),
+ msg=msg,
+ messagetype='error')
+ return trans.response.send_redirect( web.url_for( controller='requests_admin',
+ action='manage_request_types',
+ msg='Request type <b>%s</b> has been created' % st.name,
+ messagetype='done') )
+ elif params.get('view', False):
+ rt = trans.app.model.RequestType.get(int(util.restore_text( params.id )))
+ ss_list = trans.app.model.SampleState.filter(trans.app.model.SampleState.table.c.request_type_id == rt.id).all()
+ return trans.fill_template( '/admin/requests/view_request_type.mako',
+ request_type=rt,
+ forms=get_all_forms( trans ),
+ states_list=ss_list,
+ deleted=False,
+ show_deleted=False,
+ msg=msg,
+ messagetype=messagetype )
+ def __save_request_type(self, trans, **kwd):
+ params = util.Params( kwd )
+ num_states = int( util.restore_text( params.get( 'num_states', 0 ) ))
+ proceed = True
+ for i in range( num_states ):
+ if not util.restore_text( params.get( 'state_name_%i' % i, None ) ):
+ proceed = False
+ break
+ if not proceed:
+ msg = "All the state name(s) must be completed."
+ return None, msg
+ rt = trans.app.model.RequestType()
+ rt.name = util.restore_text( params.name )
+ rt.desc = util.restore_text( params.description ) or ""
+ rt.request_form = trans.app.model.FormDefinition.get(int( params.request_form_id ))
+ rt.sample_form = trans.app.model.FormDefinition.get(int( params.sample_form_id ))
+ rt.flush()
+ # set sample states
+ ss_list = trans.app.model.SampleState.filter(trans.app.model.SampleState.table.c.request_type_id == rt.id).all()
+ for ss in ss_list:
+ ss.delete()
+ ss.flush()
+ for i in range( num_states ):
+ name = util.restore_text( params.get( 'state_name_%i' % i, None ))
+ desc = util.restore_text( params.get( 'state_desc_%i' % i, None ))
+ ss = trans.app.model.SampleState(name, desc, rt)
+ ss.flush()
+ msg = "The new request type named '%s' with %s state(s) has been created" % (rt.name, num_states)
+ return rt, msg
+ @web.expose
+ @web.require_admin
+ def delete_request_type( self, trans, **kwd ):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ rt = trans.app.model.RequestType.get(int(util.restore_text( params.request_type_id )))
+ rt.deleted = True
+ rt.flush()
+ return trans.response.send_redirect( web.url_for( controller='requests_admin',
+ action='manage_request_types',
+ msg='Request type <b>%s</b> has been deleted' % rt.name,
+ messagetype='done') )
+ @web.expose
+ @web.require_admin
+ def undelete_request_type( self, trans, **kwd ):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ rt = trans.app.model.RequestType.get(int(util.restore_text( params.request_type_id )))
+ rt.deleted = False
+ rt.flush()
+ return trans.response.send_redirect( web.url_for( controller='requests_admin',
+ action='manage_request_types',
+ msg='Request type <b>%s</b> has been undeleted' % rt.name,
+ messagetype='done') )
diff -r 1fb29bd2725a -r c40962280e72 lib/galaxy/web/form_builder.py
--- a/lib/galaxy/web/form_builder.py Wed Sep 16 11:27:50 2009 -0400
+++ b/lib/galaxy/web/form_builder.py Wed Sep 16 12:39:57 2009 -0400
@@ -12,7 +12,7 @@
raise TypeError( "Abstract Method" )
@staticmethod
def form_field_types():
- return ['TextField', 'TextArea', 'SelectField', 'CheckboxField', 'AddressField']
+ return ['TextField', 'NumberField', 'TextArea', 'SelectField', 'CheckboxField', 'AddressField']
class TextField(BaseField):
"""
@@ -29,6 +29,25 @@
self.value = value or ""
def get_html( self, prefix="" ):
return '<input type="text" name="%s%s" size="%d" value="%s">' \
+ % ( prefix, self.name, self.size, escape(str(self.value), quote=True) )
+ def set_size(self, size):
+ self.size = int( size )
+
+class NumberField(BaseField):
+ """
+ A number input box.
+
+ >>> print NumberField( "foo" ).get_html()
+ <input type="int" name="foo" size="10" value="">
+ >>> print NumberField( "bins", size=4, value="12345" ).get_html()
+ <input type="int" name="bins" size="4" value="12345">
+ """
+ def __init__( self, name, size=None, value=None ):
+ self.name = name
+ self.size = int( size or 10 )
+ self.value = value or ""
+ def get_html( self, prefix="" ):
+ return '<input type="int" name="%s%s" size="%d" value="%s">' \
% ( prefix, self.name, self.size, escape(str(self.value), quote=True) )
def set_size(self, size):
self.size = int( size )
diff -r 1fb29bd2725a -r c40962280e72 templates/admin/forms/edit_form.mako
--- a/templates/admin/forms/edit_form.mako Wed Sep 16 11:27:50 2009 -0400
+++ b/templates/admin/forms/edit_form.mako Wed Sep 16 12:39:57 2009 -0400
@@ -69,6 +69,16 @@
</div>
</%def>
+<%def name="render_layout( index, widget )">
+ <div class="repeat-group-item">
+ <div class="form-row">
+ <b> ${index+1}</b>
+ ${widget.get_html()}
+ <input type="submit" name="remove_layout_grid_button" value="Remove grid ${index+1}"/>
+ </div>
+ </div>
+</%def>
+
<div class="toolForm">
<div class="toolFormTitle">Edit form definition "${form.name}"</div>
<form id="edit_form" name="edit_form" action="${h.url_for( controller='forms', action='edit', form_id=form.id, num_fields=len(form.fields) )}" method="post" >
@@ -81,6 +91,18 @@
<div style="clear: both"></div>
</div>
%endfor
+ %if current_form_type == trans.app.model.FormDefinition.types.SAMPLE:
+ <div class="toolFormTitle">Form Layout</div>
+ <div class="form-row">
+ <label>Layout grid names</label>
+ </div>
+ %for index, lg in enumerate(layout_grids):
+ ${render_layout( index, lg )}
+ %endfor
+ <div class="form-row">
+ <input type="submit" name="add_layout_grid" value="Add layout grid"/>
+ </div>
+ %endif
<div class="toolFormTitle">Fields (${len(form.fields)})</div>
%for ctr, field in enumerate(field_details):
${render_field( ctr, field )}
diff -r 1fb29bd2725a -r c40962280e72 templates/admin/forms/manage_forms.mako
--- a/templates/admin/forms/manage_forms.mako Wed Sep 16 11:27:50 2009 -0400
+++ b/templates/admin/forms/manage_forms.mako Wed Sep 16 12:39:57 2009 -0400
@@ -29,6 +29,7 @@
%endif
</td>
<td><i>${form.desc}</i></td>
+ <td>${form.type}</td>
</tr>
</%def>
@@ -41,7 +42,7 @@
</li>
</ul>
-%if not fdc_list:
+%if not all_forms:
There are no forms.
%else:
<div class="grid-header">
@@ -61,6 +62,7 @@
<tr>
<th>Name</th>
<th>Description</th>
+ <th>Type</th>
</tr>
</thead>
<tbody>
diff -r 1fb29bd2725a -r c40962280e72 templates/admin/index.mako
--- a/templates/admin/index.mako Wed Sep 16 11:27:50 2009 -0400
+++ b/templates/admin/index.mako Wed Sep 16 12:39:57 2009 -0400
@@ -118,7 +118,7 @@
</div>
<div class="toolSectionBody">
<div class="toolSectionBg">
- <div class="toolTitle"><a href="${h.url_for( controller='admin', action='manage_request_types' )}" target="galaxy_main">Manage request types</a></div>
+ <div class="toolTitle"><a href="${h.url_for( controller='requests_admin', action='manage_request_types' )}" target="galaxy_main">Manage request types</a></div>
<div class="toolTitle"><a href="${h.url_for( controller='requests_admin', action='list')}" target="galaxy_main">Manage requests</a></div>
</div>
</div>
diff -r 1fb29bd2725a -r c40962280e72 templates/admin/requests/add_states.mako
--- a/templates/admin/requests/add_states.mako Wed Sep 16 11:27:50 2009 -0400
+++ b/templates/admin/requests/add_states.mako Wed Sep 16 12:39:57 2009 -0400
@@ -7,7 +7,7 @@
<div class="toolForm">
<div class="toolFormTitle">Create ${num_states} states for the '${request_type_name}' request type</div>
- <form name="new_form_fields" action="${h.url_for( controller='admin', action='request_type', name=request_type_name, description=desc, num_states=num_states, request_form_id=request_form_id, sample_form_id=sample_form_id)}" method="post" >
+ <form name="new_form_fields" action="${h.url_for( controller='requests_admin', action='request_type', name=request_type_name, description=desc, num_states=num_states, request_form_id=request_form_id, sample_form_id=sample_form_id)}" method="post" >
<div class="toolFormBody">
%for element_count in range( num_states ):
<div class="form-row">
diff -r 1fb29bd2725a -r c40962280e72 templates/admin/requests/create_request_type.mako
--- a/templates/admin/requests/create_request_type.mako Wed Sep 16 11:27:50 2009 -0400
+++ b/templates/admin/requests/create_request_type.mako Wed Sep 16 12:39:57 2009 -0400
@@ -8,11 +8,11 @@
<div class="toolForm">
<div class="toolFormTitle">Create a new request type</div>
- %if not forms:
- Create a form definition first to create a new request type.
+ %if not request_forms or not sample_forms:
+ Create a request & sample form definition first to create a new request type.
%else:
<div class="toolFormBody">
- <form name="create_request_type" action="${h.url_for( controller='admin', action='request_type')}" method="post" >
+ <form name="create_request_type" action="${h.url_for( controller='requests_admin', action='request_type')}" method="post" >
<div class="form-row">
<label>Name:</label>
<div style="float: left; width: 250px; margin-right: 10px;">
@@ -32,7 +32,7 @@
Request Form definition:
</label>
<select name="request_form_id">
- %for form in forms:
+ %for form in request_forms:
<option value="${form.id}">${form.name}</option>
%endfor
</select>
@@ -42,7 +42,7 @@
Sample Form definition:
</label>
<select name="sample_form_id">
- %for form in forms:
+ %for form in sample_forms:
<option value="${form.id}">${form.name}</option>
%endfor
</select>
diff -r 1fb29bd2725a -r c40962280e72 templates/admin/requests/manage_request_types.mako
--- a/templates/admin/requests/manage_request_types.mako Wed Sep 16 11:27:50 2009 -0400
+++ b/templates/admin/requests/manage_request_types.mako Wed Sep 16 12:39:57 2009 -0400
@@ -13,7 +13,7 @@
<ul class="manage-table-actions">
<li>
- <a class="action-button" href="${h.url_for( controller='admin', action='request_type', create=True )}"><span>Create a new request type</span></a>
+ <a class="action-button" href="${h.url_for( controller='requests_admin', action='request_type', create=True )}"><span>Create a new request type</span></a>
</li>
</ul>
@@ -24,9 +24,9 @@
<span>|</span>
%endif
%if show_filter == filter:
- <span class="filter"><a href="${h.url_for( controller='admin', action='manage_request_types', show_filter=filter )}"><b>${filter}</b></a></span>
+ <span class="filter"><a href="${h.url_for( controller='requests_admin', action='manage_request_types', show_filter=filter )}"><b>${filter}</b></a></span>
%else:
- <span class="filter"><a href="${h.url_for( controller='admin', action='manage_request_types', show_filter=filter )}">${filter}</a></span>
+ <span class="filter"><a href="${h.url_for( controller='requests_admin', action='manage_request_types', show_filter=filter )}">${filter}</a></span>
%endif
%endfor
</div>
@@ -46,7 +46,7 @@
%for request_type in request_types:
<tr>
<td>
- <a href="${h.url_for( controller='admin', action='request_type', view='True', id=request_type.id)}">${request_type.name}</a>
+ <a href="${h.url_for( controller='requests_admin', action='request_type', view='True', id=request_type.id)}">${request_type.name}</a>
<a id="request_type-${request_type.id}-popup" class="popup-arrow" style="display: none;">▼</a>
%if request_type.deleted:
<div popupmenu="request_type-${request_type.id}-popup">
diff -r 1fb29bd2725a -r c40962280e72 templates/admin/requests/show_request.mako
--- a/templates/admin/requests/show_request.mako Wed Sep 16 11:27:50 2009 -0400
+++ b/templates/admin/requests/show_request.mako Wed Sep 16 12:39:57 2009 -0400
@@ -26,18 +26,39 @@
%endif
</ul>
-<%def name="render_sample_form( index, sample_name, sample_values )">
- <td>
- <input type="text" name=sample_${index}_name value="${sample_name}" size="10"/>
- <div class="toolParamHelp" style="clear: both;">
- <i>${' (required)' }</i>
- </div>
- </td>
- <td>
- </td>
- %for field_index, field in enumerate(request.type.sample_form.fields):
+
+<%def name="render_sample_form( index, sample_name, sample_values, grid_index, fields_dict )">
+ %if grid_index == 0:
<td>
- <input type="text" name=sample_${index}_field_${field_index} value="${sample_values[field_index]}" size="7"/>
+ <input type="text" name=sample_${index}_name value="${sample_name}" size="10"/>
+ <div class="toolParamHelp" style="clear: both;">
+ <i>${' (required)' }</i>
+ </div>
+ </td>
+ <td>
+ </td>
+ %else:
+ <td>
+ ${sample_name}
+ </td>
+ %endif
+ %for field_index, field in fields_dict.items():
+ <td>
+ %if field['type'] == 'TextField':
+ <input type="text" name="sample_${index}_field_${field_index}" value="${sample_values[field_index]}" size="7"/>
+ %elif field['type'] == 'SelectField':
+ <select name="sample_${index}_field_${field_index}" last_selected_value="2">
+ %for option_index, option in enumerate(field['selectlist']):
+ %if option == sample_values[field_index]:
+ <option value="${option}" selected>${option}</option>
+ %else:
+ <option value="${option}">${option}</option>
+ %endif
+ %endfor
+ </select>
+ %elif field['type'] == 'CheckboxField':
+ <input type="checkbox" name="sample_${index}_field_${field_index}" value="Yes"/>
+ %endif
<div class="toolParamHelp" style="clear: both;">
<i>${'('+field['required']+')' }</i>
</div>
@@ -45,18 +66,20 @@
%endfor
</%def>
-<%def name="render_sample( index, sample )">
+<%def name="render_sample( index, sample, grid_index, fields_dict )">
<td>
${sample.name}
</td>
- <td>
- %if sample.request.unsubmitted():
- Unsubmitted
- %else:
- <a href="${h.url_for( controller='requests_admin', action='show_events', sample_id=sample.id)}">${sample.current_state().name}</a>
- %endif
- </td>
- %for field_index, field in enumerate(request.type.sample_form.fields):
+ %if grid_index == 0:
+ <td>
+ %if sample.request.unsubmitted():
+ Unsubmitted
+ %else:
+ <a href="${h.url_for( controller='requests_admin', action='show_events', sample_id=sample.id)}">${sample.current_state().name}</a>
+ %endif
+ </td>
+ %endif
+ %for field_index, field in fields_dict.items():
<td>
%if sample.values.content[field_index]:
${sample.values.content[field_index]}
@@ -65,7 +88,6 @@
%endif
</td>
%endfor
-
</%def>
<div class="toolForm">
@@ -100,58 +122,81 @@
</div>
</div>
+<%def name="render_grid( grid_index, grid_name, fields_dict )">
+ %if grid_name:
+ <div class="toolFormTitle">${grid_name}</div>
+ %endif
+ <div style="clear: both"></div>
+ <table class="grid">
+ <thead>
+ <tr>
+ <th>No.</th>
+ <th>Sample Name</th>
+ %if grid_index == 0:
+ <th>State</th>
+ %endif
+ %for index, field in fields_dict.items():
+ <th>
+ ${field['label']}
+ <div class="toolParamHelp" style="clear: both;">
+ <i>${field['helptext']}</i>
+ </div>
+ </th>
+ %endfor
+ <th></th>
+ </tr>
+ <thead>
+ <tbody>
+ <%
+ request.refresh()
+ %>
+ %for sample_index, sample in enumerate(current_samples):
+ %if edit_mode:
+ <tr>
+ <td>${sample_index+1}</td>
+ ${render_sample_form( sample_index, sample[0], sample[1], grid_index, fields_dict)}
+ <td>
+ %if request.unsubmitted() and grid_index == 0:
+ <a class="action-button" href="${h.url_for( controller='requests', action='delete_sample', request_id=request.id, sample_id=sample_index)}">
+ <img src="${h.url_for('/static/images/delete_icon.png')}" />
+ <span></span></a>
+ %endif
+ </td>
+ </tr>
+ %else:
+ <tr>
+ <td>${sample_index+1}</td>
+ %if sample_index in range(len(request.samples)):
+ ${render_sample( sample_index, request.samples[sample_index], grid_index, fields_dict )}
+ %else:
+ ${render_sample_form( sample_index, sample[0], sample[1], grid_index, fields_dict)}
+ %endif
+ <td>
+ %if request.unsubmitted() and grid_index == 0:
+ <a class="action-button" href="${h.url_for( controller='requests', action='delete_sample', request_id=request.id, sample_id=sample_index)}">
+ <img src="${h.url_for('/static/images/delete_icon.png')}" />
+ <span></span></a>
+ %endif
+ </td>
+ </tr>
+ %endif
+ %endfor
+ </tbody>
+ </table>
+</%def>
+
<div class="toolForm">
##<div class="toolFormTitle">Samples (${len(request.samples)})</div>
<form id="edit_form" name="edit_form" action="${h.url_for( controller='requests_admin', action='show_request' )}" enctype="multipart/form-data" method="post" >
<div class="form-row">
%if current_samples:
- <table class="grid">
- <thead>
- <tr>
- <th>No.</th>
- <th>Sample Name</th>
- <th>State</th>
- %for field_index, field in enumerate(request.type.sample_form.fields):
- <th>
- ${field['label']}
- <div class="toolParamHelp" style="clear: both;">
- <i>${field['helptext']}</i>
- </div>
- </th>
- %endfor
- <th></th>
- </tr>
- <thead>
- <tbody>
- <%
- request.refresh()
- %>
- %for sample_index, sample in enumerate(current_samples):
- %if edit_mode:
- <tr>
- <td>${sample_index+1}</td>
- ${render_sample_form( sample_index, sample[0], sample[1])}
- </tr>
- %else:
- <tr>
- <td>${sample_index+1}</td>
- %if sample_index in range(len(request.samples)):
- ${render_sample( sample_index, request.samples[sample_index] )}
- %else:
- ${render_sample_form( sample_index, sample[0], sample[1])}
- %endif
- <td>
- %if request.unsubmitted():
- <a class="action-button" href="${h.url_for( controller='requests_admin', action='delete_sample', request_id=request.id, sample_id=sample_index)}">
- <img src="${h.url_for('/static/images/delete_icon.png')}" />
- <span></span></a>
- %endif
- </td>
- </tr>
- %endif
- %endfor
- </tbody>
- </table>
+ %if not request.type.sample_form.layout:
+ ${render_grid( 0, "", request.type.sample_form.fields_of_grid( None ) )}
+ %else:
+ %for grid_index, grid_name in enumerate(request.type.sample_form.layout):
+ ${render_grid( grid_index, grid_name, request.type.sample_form.fields_of_grid( grid_name ) )}
+ %endfor
+ %endif
%else:
<label>There are no samples.</label>
%endif
diff -r 1fb29bd2725a -r c40962280e72 templates/admin/requests/view_request_type.mako
--- a/templates/admin/requests/view_request_type.mako Wed Sep 16 11:27:50 2009 -0400
+++ b/templates/admin/requests/view_request_type.mako Wed Sep 16 12:39:57 2009 -0400
@@ -11,7 +11,7 @@
<div class="toolForm">
<div class="toolFormTitle">View request type details</div>
<div class="toolFormBody">
- <form name="library" action="${h.url_for( controller='admin', action='request_type', save_changes=True, create=False, id=request_type.id, num_states=num_states )}" method="post" >
+ <form name="library">
<div class="form-row">
<label>Name</label>
${request_type.name}
diff -r 1fb29bd2725a -r c40962280e72 templates/requests/new_request.mako
--- a/templates/requests/new_request.mako Wed Sep 16 11:27:50 2009 -0400
+++ b/templates/requests/new_request.mako Wed Sep 16 12:39:57 2009 -0400
@@ -58,9 +58,9 @@
<div class="form-row">
<label>${field['label']}</label>
${field['widget'].get_html()}
- %if field['label'] == 'Data library' and new_library:
- ${new_library.get_html()}
- %endif
+ ##%if field['label'] == 'Data library' and new_library:
+ ## ${new_library.get_html()}
+ ##%endif
<div class="toolParamHelp" style="clear: both;">
${field['helptext']}
</div>
diff -r 1fb29bd2725a -r c40962280e72 templates/requests/show_request.mako
--- a/templates/requests/show_request.mako Wed Sep 16 11:27:50 2009 -0400
+++ b/templates/requests/show_request.mako Wed Sep 16 12:39:57 2009 -0400
@@ -26,18 +26,40 @@
-<%def name="render_sample_form( index, sample_name, sample_values )">
- <td>
- <input type="text" name=sample_${index}_name value="${sample_name}" size="10"/>
- <div class="toolParamHelp" style="clear: both;">
- <i>${' (required)' }</i>
- </div>
- </td>
- <td>
- </td>
- %for field_index, field in enumerate(request.type.sample_form.fields):
+<%def name="render_sample_form( index, sample_name, sample_values, grid_index, fields_dict )">
+ %if grid_index == 0:
<td>
- <input type="text" name=sample_${index}_field_${field_index} value="${sample_values[field_index]}" size="7"/>
+ <input type="text" name=sample_${index}_name value="${sample_name}" size="10"/>
+ <div class="toolParamHelp" style="clear: both;">
+ <i>${' (required)' }</i>
+ </div>
+ </td>
+ <td>
+ </td>
+ %else:
+ <td>
+ ${sample_name}
+ </td>
+ %endif
+ %for field_index, field in fields_dict.items():
+ <td>
+ %if field['type'] == 'TextField':
+ <input type="text" name="sample_${index}_field_${field_index}" value="${sample_values[field_index]}" size="7"/>
+ %elif field['type'] == 'SelectField':
+ <select name="sample_${index}_field_${field_index}" last_selected_value="2">
+ %for option_index, option in enumerate(field['selectlist']):
+ %if option == sample_values[field_index]:
+ <option value="${option}" selected>${option}</option>
+ %else:
+ <option value="${option}">${option}</option>
+ %endif
+ %endfor
+ </select>
+ %elif field['type'] == 'CheckboxField':
+ <input type="checkbox" name="sample_${index}_field_${field_index}" value="Yes"/>
+ %elif field['type'] == 'NumberField':
+ <input type=int name="sample_${index}_field_${field_index}" value="${sample_values[field_index]}" size="7"/>
+ %endif
<div class="toolParamHelp" style="clear: both;">
<i>${'('+field['required']+')' }</i>
</div>
@@ -45,18 +67,20 @@
%endfor
</%def>
-<%def name="render_sample( index, sample )">
+<%def name="render_sample( index, sample, grid_index, fields_dict )">
<td>
${sample.name}
</td>
- <td>
- %if sample.request.unsubmitted():
- Unsubmitted
- %else:
- <a href="${h.url_for( controller='requests', action='show_events', sample_id=sample.id)}">${sample.current_state().name}</a>
- %endif
- </td>
- %for field_index, field in enumerate(request.type.sample_form.fields):
+ %if grid_index == 0:
+ <td>
+ %if sample.request.unsubmitted():
+ Unsubmitted
+ %else:
+ <a href="${h.url_for( controller='requests', action='show_events', sample_id=sample.id)}">${sample.current_state().name}</a>
+ %endif
+ </td>
+ %endif
+ %for field_index, field in fields_dict.items():
<td>
%if sample.values.content[field_index]:
${sample.values.content[field_index]}
@@ -105,65 +129,81 @@
</div>
</div>
+<%def name="render_grid( grid_index, grid_name, fields_dict )">
+ %if grid_name:
+ <div class="toolFormTitle">${grid_name}</div>
+ %endif
+ <div style="clear: both"></div>
+ <table class="grid">
+ <thead>
+ <tr>
+ <th>No.</th>
+ <th>Sample Name</th>
+ %if grid_index == 0:
+ <th>State</th>
+ %endif
+ %for index, field in fields_dict.items():
+ <th>
+ ${field['label']}
+ <div class="toolParamHelp" style="clear: both;">
+ <i>${field['helptext']}</i>
+ </div>
+ </th>
+ %endfor
+ <th></th>
+ </tr>
+ <thead>
+ <tbody>
+ <%
+ request.refresh()
+ %>
+ %for sample_index, sample in enumerate(current_samples):
+ %if edit_mode:
+ <tr>
+ <td>${sample_index+1}</td>
+ ${render_sample_form( sample_index, sample[0], sample[1], grid_index, fields_dict)}
+ <td>
+ %if request.unsubmitted() and grid_index == 0:
+ <a class="action-button" href="${h.url_for( controller='requests', action='delete_sample', request_id=request.id, sample_id=sample_index)}">
+ <img src="${h.url_for('/static/images/delete_icon.png')}" />
+ <span></span></a>
+ %endif
+ </td>
+ </tr>
+ %else:
+ <tr>
+ <td>${sample_index+1}</td>
+ %if sample_index in range(len(request.samples)):
+ ${render_sample( sample_index, request.samples[sample_index], grid_index, fields_dict )}
+ %else:
+ ${render_sample_form( sample_index, sample[0], sample[1], grid_index, fields_dict)}
+ %endif
+ <td>
+ %if request.unsubmitted() and grid_index == 0:
+ <a class="action-button" href="${h.url_for( controller='requests', action='delete_sample', request_id=request.id, sample_id=sample_index)}">
+ <img src="${h.url_for('/static/images/delete_icon.png')}" />
+ <span></span></a>
+ %endif
+ </td>
+ </tr>
+ %endif
+ %endfor
+ </tbody>
+ </table>
+</%def>
+
<div class="toolForm">
##<div class="toolFormTitle">Samples (${len(request.samples)})</div>
<form id="show_request" name="show_request" action="${h.url_for( controller='requests', action='show_request' )}" enctype="multipart/form-data" method="post" >
<div class="form-row">
- %if current_samples:
- <table class="grid">
- <thead>
- <tr>
- <th>No.</th>
- <th>Sample Name</th>
- <th>State</th>
- %for field_index, field in enumerate(request.type.sample_form.fields):
- <th>
- ${field['label']}
- <div class="toolParamHelp" style="clear: both;">
- <i>${field['helptext']}</i>
- </div>
- </th>
- %endfor
- <th></th>
- </tr>
- <thead>
- <tbody>
- <%
- request.refresh()
- %>
- %for sample_index, sample in enumerate(current_samples):
- %if edit_mode:
- <tr>
- <td>${sample_index+1}</td>
- ${render_sample_form( sample_index, sample[0], sample[1])}
- <td>
- %if request.unsubmitted():
- <a class="action-button" href="${h.url_for( controller='requests', action='delete_sample', request_id=request.id, sample_id=sample_index)}">
- <img src="${h.url_for('/static/images/delete_icon.png')}" />
- <span></span></a>
- %endif
- </td>
- </tr>
- %else:
- <tr>
- <td>${sample_index+1}</td>
- %if sample_index in range(len(request.samples)):
- ${render_sample( sample_index, request.samples[sample_index] )}
- %else:
- ${render_sample_form( sample_index, sample[0], sample[1])}
- %endif
- <td>
- %if request.unsubmitted():
- <a class="action-button" href="${h.url_for( controller='requests', action='delete_sample', request_id=request.id, sample_id=sample_index)}">
- <img src="${h.url_for('/static/images/delete_icon.png')}" />
- <span></span></a>
- %endif
- </td>
- </tr>
- %endif
- %endfor
- </tbody>
- </table>
+ %if current_samples:
+ %if not request.type.sample_form.layout:
+ ${render_grid( 0, "", request.type.sample_form.fields_of_grid( None ) )}
+ %else:
+ %for grid_index, grid_name in enumerate(request.type.sample_form.layout):
+ ${render_grid( grid_index, grid_name, request.type.sample_form.fields_of_grid( grid_name ) )}
+ %endfor
+ %endif
%else:
<div class="form-row">
<label>There are no samples.</label>
diff -r 1fb29bd2725a -r c40962280e72 test/base/twilltestcase.py
--- a/test/base/twilltestcase.py Wed Sep 16 11:27:50 2009 -0400
+++ b/test/base/twilltestcase.py Wed Sep 16 12:39:57 2009 -0400
@@ -972,15 +972,13 @@
self.home()
# Form stuff
- def create_form( self, name='Form One', desc='This is Form One', num_fields=1 ):
+ def create_form( self, name, desc, formtype, num_fields=1 ):
"""
Create a new form definition. Testing framework is still limited to only testing
one instance for each repeat. This has to do with the 'flat' nature of defining
test param values. Using same-named parameters down different branches (having
different scope in the tool) cannot be properly tested when they both exist at the
same time.
- TODO: RC: create an edit_form() method that will test the addition of a new field
- of a specified type.
"""
# TODO: RC: enhance this so that all supported field types can be passed in
# and tested. If nothing is passed, all fields are TextField.
@@ -988,7 +986,8 @@
self.visit_url( "%s/forms/new" % self.url )
self.check_page_for_string( 'Create a new form definition' )
tc.fv( "1", "name", name ) # form field 1 is the field named name...
- tc.fv( "1", "description", desc ) # form field 1 is the field named name...
+ tc.fv( "1", "description", desc ) # form field 1 is the field named desc...
+ tc.fv( "1", "form_type_selectbox", formtype )
tc.submit( "create_form_button" )
for index in range( num_fields ):
field_name = 'field_name_%i' % index
@@ -1053,7 +1052,7 @@
# Requests stuff
def create_request_type( self, name, desc, request_form_id, sample_form_id, states ):
self.home()
- self.visit_url( "%s/admin/request_type?create=True" % self.url )
+ self.visit_url( "%s/requests_admin/request_type?create=True" % self.url )
self.check_page_for_string( 'Create a new request type' )
tc.fv( "1", "name", name )
tc.fv( "1", "description", desc )
@@ -1067,13 +1066,14 @@
tc.fv("1", "state_desc_%i" % index, state[1])
tc.submit( "save_request_type" )
self.check_page_for_string( "Request type <b>%s</b> has been created" % name )
- def create_request( self, request_type_id, name, desc, library_id, fields ):
+ def create_request( self, request_type_id, name, desc, library_id, folder_id, fields ):
self.home()
self.visit_url( "%s/requests/new?create=True&select_request_type=%i" % (self.url, request_type_id) )
self.check_page_for_string( 'Add a new request' )
tc.fv( "1", "name", name )
tc.fv( "1", "desc", desc )
tc.fv( "1", "library_id", str(library_id) )
+ #tc.fv( "1", "folder_id", str(folder_id) )
for index, field_value in enumerate(fields):
tc.fv( "1", "field_%i" % index, field_value )
tc.submit( "create_request_button" )
@@ -1088,13 +1088,14 @@
for index, field_value in enumerate(fields):
tc.fv( "1", "field_%i" % index, field_value )
tc.submit( "create_request_button" )
- def edit_request( self, request_id, name, new_name, new_desc, new_library_id, new_fields):
+ def edit_request( self, request_id, name, new_name, new_desc, new_library_id, new_folder_id, new_fields):
self.home()
self.visit_url( "%s/requests/edit?request_id=%i&show=True" % (self.url, request_id) )
self.check_page_for_string( 'Edit request "%s"' % name )
tc.fv( "1", "name", new_name )
tc.fv( "1", "desc", new_desc )
tc.fv( "1", "library_id", str(new_library_id) )
+ tc.fv( "1", "folder_id", str(new_folder_id) )
for index, field_value in enumerate(new_fields):
tc.fv( "1", "field_%i" % index, field_value )
tc.submit( "save_changes_request_button" )
diff -r 1fb29bd2725a -r c40962280e72 test/functional/test_forms_and_requests.py
--- a/test/functional/test_forms_and_requests.py Wed Sep 16 11:27:50 2009 -0400
+++ b/test/functional/test_forms_and_requests.py Wed Sep 16 12:39:57 2009 -0400
@@ -41,14 +41,17 @@
global form_one_name
name = form_one_name
desc = "This is Form One's description"
- self.create_form( name=name, desc=desc )
+ formtype = 'Sequencing Request Form'
+ self.create_form( name=name, desc=desc, formtype=formtype )
self.home()
self.visit_page( 'forms/manage' )
self.check_page_for_string( name )
self.check_page_for_string( desc )
+ self.check_page_for_string( formtype )
# Get the form_definition object for later tests
form_one = galaxy.model.FormDefinition.filter( and_( galaxy.model.FormDefinition.table.c.name==name,
- galaxy.model.FormDefinition.table.c.desc==desc ) ).all()[-1]
+ galaxy.model.FormDefinition.table.c.desc==desc,
+ galaxy.model.FormDefinition.table.c.type==formtype ) ).all()[-1]
assert form_one is not None, 'Problem retrieving form named "%s" from the database' % name
# edit form & add few more fields
new_name = "Request Form (Renamed)"
@@ -86,15 +89,18 @@
global form_two_name
name = form_two_name
desc = "This is Form One's description"
- self.create_form( name=name, desc=desc )
+ formtype = 'Sequencing Sample Form'
+ self.create_form( name=name, desc=desc, formtype=formtype )
self.home()
self.visit_page( 'forms/manage' )
self.check_page_for_string( name )
self.check_page_for_string( desc )
+ self.check_page_for_string( formtype )
def test_020_create_request_type( self ):
"""Testing creating a new requestype"""
request_form = get_latest_form(form_one_name)
sample_form = get_latest_form(form_two_name)
+ print request_form.id, sample_form.id
self.create_request_type(request_type_name, "test request type",
str(request_form.id), str(sample_form.id), sample_states )
global request_type
@@ -147,6 +153,17 @@
# Role one members are: admin_user, regular_user1. Each of these users will be permitted to
# LIBRARY_ADD, LIBRARY_MODIFY, LIBRARY_MANAGE for library items.
self.set_library_permissions( str( library_one.id ), library_one.name, str( regular_user1_private_role.id ), permissions_in, permissions_out )
+ # create a folder in the library
+ root_folder = library_one.root_folder
+ name = "Folder One"
+ self.add_folder( str( library_one.id ), str( root_folder.id ), name=name, description='' )
+ global folder_one
+ folder_one = galaxy.model.LibraryFolder.filter( and_( galaxy.model.LibraryFolder.table.c.parent_id==root_folder.id,
+ galaxy.model.LibraryFolder.table.c.name==name ) ).first()
+ assert folder_one is not None, 'Problem retrieving library folder named "%s" from the database' % name
+ self.home()
+ self.visit_url( '%s/library_admin/browse_library?id=%s' % ( self.url, str( library_one.id ) ) )
+ self.check_page_for_string( name )
# create address
#self.create_address( user_address1 )
#self.check_page_for_string( 'Address <b>%s</b> has been added' % user_address1[ 'short_desc' ] )
@@ -175,7 +192,7 @@
fields = ['field one value', 'field two value', str(user_address.id)]
# create the request
request_name, request_desc = 'Request One', 'Request One Description'
- self.create_request(request_type.id, request_name, request_desc, library_one.id, fields)
+ self.create_request(request_type.id, request_name, request_desc, library_one.id, folder_one.id, fields)
self.check_page_for_string( request_name )
self.check_page_for_string( request_desc )
global request_one
@@ -195,7 +212,7 @@
self.check_page_for_string( field_value )
# edit this request
fields = ['field one value (editted)', 'field two value (editted)', str(user_address.id)]
- self.edit_request(request_one.id, request_one.name, request_one.name+' (Renamed)', request_one.desc+' (Re-described)', library_one.id, fields)
+ self.edit_request(request_one.id, request_one.name, request_one.name+' (Renamed)', request_one.desc+' (Re-described)', library_one.id, folder_one.id, fields)
request_one.refresh()
self.check_page_for_string( request_name+' (Renamed)' )
self.check_page_for_string( request_desc+' (Re-described)' )
1
0
16 Sep '09
details: http://www.bx.psu.edu/hg/galaxy/rev/ba884f1a6b81
changeset: 2692:ba884f1a6b81
user: Dan Blankenberg <dan(a)bx.psu.edu>
date: Tue Sep 15 10:15:42 2009 -0400
description:
Fix maf_utilities compatibility with python 2.4; STRING.startswith() accepting a tuple was introduced in python 2.5.
1 file(s) affected in this change:
lib/galaxy/tools/util/maf_utilities.py
diffs (23 lines):
diff -r 40c5e1853a66 -r ba884f1a6b81 lib/galaxy/tools/util/maf_utilities.py
--- a/lib/galaxy/tools/util/maf_utilities.py Mon Sep 14 17:03:17 2009 -0400
+++ b/lib/galaxy/tools/util/maf_utilities.py Tue Sep 15 10:15:42 2009 -0400
@@ -403,7 +403,7 @@
else:
blocks.append( ( score, idx, offset ) )
- gap_chars_tuple = tuple( GAP_CHARS )
+ #gap_chars_tuple = tuple( GAP_CHARS )
gap_chars_str = ''.join( GAP_CHARS )
#Loop through ordered blocks and layer by increasing score
for block_dict in blocks:
for block in iter_blocks_split_by_species( block_dict[1].get_at_offset( block_dict[2] ) ): #need to handle each occurance of sequence in block seperately
@@ -415,7 +415,8 @@
#we should trim gaps from both sides, since these are not positions in this species genome (sequence)
text = text.rstrip( gap_chars_str )
gap_offset = 0
- while text.startswith( gap_chars_tuple ):
+ while True in [ text.startswith( gap_char ) for gap_char in GAP_CHARS ]: #python2.4 doesn't accept a tuple for .startswith()
+ #while text.startswith( gap_chars_tuple ):
gap_offset += 1
text = text[1:]
if not text:
1
0
16 Sep '09
details: http://www.bx.psu.edu/hg/galaxy/rev/b179523d7d78
changeset: 2693:b179523d7d78
user: anton(a)nekrut-mbp.bx.psu.edu
date: Tue Sep 15 10:30:54 2009 -0400
description:
Modification for input datatype in the splitter:w
1 file(s) affected in this change:
tools/metag_tools/split_paired_reads.xml
diffs (21 lines):
diff -r ba884f1a6b81 -r b179523d7d78 tools/metag_tools/split_paired_reads.xml
--- a/tools/metag_tools/split_paired_reads.xml Tue Sep 15 10:15:42 2009 -0400
+++ b/tools/metag_tools/split_paired_reads.xml Tue Sep 15 10:30:54 2009 -0400
@@ -4,7 +4,7 @@
split_paired_reads.py $input $output1 $output2
</command>
<inputs>
- <param name="input" type="data" format="fastqsolexa" label="Your paired-end file" />
+ <param name="input" type="data" format="fastqsolexa,fastqsanger" label="Your paired-end file" />
</inputs>
<outputs>
<data name="output1" format="fastqsolexa"/>
@@ -20,7 +20,7 @@
**What it does**
-Splits a single fastq datasret representing paired-end run into two datasets (one for each end). This tool works only for datasets where both ends have **the same** length.
+Splits a single fastq dataset representing paired-end run into two datasets (one for each end). This tool works only for datasets where both ends have **the same** length.
-----
1
0
16 Sep '09
details: http://www.bx.psu.edu/hg/galaxy/rev/990231e77b88
changeset: 2694:990231e77b88
user: guru
date: Tue Sep 15 11:28:50 2009 -0400
description:
More modifications to fastx toolkit: added fastqsanger to input format list and changed the ascii offset param to select.
4 file(s) affected in this change:
tools/fastx_toolkit/fasta_nucleotide_changer.xml
tools/fastx_toolkit/fastq_quality_converter.xml
tools/fastx_toolkit/fastq_quality_filter.xml
tools/fastx_toolkit/fastx_quality_statistics.xml
diffs (82 lines):
diff -r b179523d7d78 -r 990231e77b88 tools/fastx_toolkit/fasta_nucleotide_changer.xml
--- a/tools/fastx_toolkit/fasta_nucleotide_changer.xml Tue Sep 15 10:30:54 2009 -0400
+++ b/tools/fastx_toolkit/fasta_nucleotide_changer.xml Tue Sep 15 11:28:50 2009 -0400
@@ -10,21 +10,21 @@
</param>
</inputs>
+ <!--
+ Functional tests with param value starting with - fail.
<tests>
<test>
- <!-- DNA-to-RNA -->
<param name="input" value="fasta_nuc_changer1.fasta" />
<param name="mode" value="-r" />
<output name="output" file="fasta_nuc_change1.out" />
</test>
<test>
- <!-- RNA-to-DNA -->
<param name="input" value="fasta_nuc_changer2.fasta" />
<param name="mode" value="-d" />
<output name="output" file="fasta_nuc_change2.out" />
</test>
</tests>
-
+ -->
<outputs>
<data format="input" name="output" metadata_source="input" />
diff -r b179523d7d78 -r 990231e77b88 tools/fastx_toolkit/fastq_quality_converter.xml
--- a/tools/fastx_toolkit/fastq_quality_converter.xml Tue Sep 15 10:30:54 2009 -0400
+++ b/tools/fastx_toolkit/fastq_quality_converter.xml Tue Sep 15 11:28:50 2009 -0400
@@ -2,15 +2,18 @@
<description>(ASCII-Numeric)</description>
<command>zcat -f $input | fastq_quality_converter $QUAL_FORMAT -o $output -Q $offset</command>
<inputs>
- <param format="fastqsolexa" name="input" type="data" label="Library to convert" />
+ <param format="fastqsolexa,fastqsanger" name="input" type="data" label="Library to convert" />
<param name="QUAL_FORMAT" type="select" label="Desired output format">
<option value="-a">ASCII (letters) quality scores</option>
<option value="-n">Numeric quality scores</option>
</param>
- <param name="offset" size="4" type="integer" value="33" label="FASTQ ASCII offset" />
- </inputs>
+ <param name="offset" type="select" label="FASTQ ASCII offset">
+ <option value="33">33</option>
+ <option value="64">64</option>
+ </param>
+ </inputs>
<tests>
<test>
diff -r b179523d7d78 -r 990231e77b88 tools/fastx_toolkit/fastq_quality_filter.xml
--- a/tools/fastx_toolkit/fastq_quality_filter.xml Tue Sep 15 10:30:54 2009 -0400
+++ b/tools/fastx_toolkit/fastq_quality_filter.xml Tue Sep 15 11:28:50 2009 -0400
@@ -4,7 +4,7 @@
<command>zcat -f '$input' | fastq_quality_filter -q $quality -p $percent -v -o $output</command>
<inputs>
- <param format="fastqsolexa" name="input" type="data" label="Library to filter" />
+ <param format="fastqsolexa,fastqsanger" name="input" type="data" label="Library to filter" />
<param name="quality" size="4" type="integer" value="20">
<label>Quality cut-off value</label>
diff -r b179523d7d78 -r 990231e77b88 tools/fastx_toolkit/fastx_quality_statistics.xml
--- a/tools/fastx_toolkit/fastx_quality_statistics.xml Tue Sep 15 10:30:54 2009 -0400
+++ b/tools/fastx_toolkit/fastx_quality_statistics.xml Tue Sep 15 11:28:50 2009 -0400
@@ -3,8 +3,11 @@
<command>zcat -f $input | fastx_quality_stats -o $output -Q $offset</command>
<inputs>
- <param format="fasta,fastqsolexa" name="input" type="data" label="Library to analyse" />
- <param name="offset" size="4" type="integer" value="33" label="FASTQ ASCII offset" />
+ <param format="fasta,fastqsolexa,fastqsanger" name="input" type="data" label="Library to analyse" />
+ <param name="offset" type="select" label="FASTQ ASCII offset">
+ <option value="33">33</option>
+ <option value="64">64</option>
+ </param>
</inputs>
<tests>
1
0
16 Sep '09
details: http://www.bx.psu.edu/hg/galaxy/rev/b25489f4fb26
changeset: 2695:b25489f4fb26
user: Dan Blankenberg <dan(a)bx.psu.edu>
date: Tue Sep 15 12:04:14 2009 -0400
description:
Add a new tool, Mutate by SNP codon, which will take codon position and sequence information that is joined to SNP data and create a 'mutated codon'.
6 file(s) affected in this change:
test-data/mutate_snp_codon_in.interval
test-data/mutate_snp_codon_out.interval
tool_conf.xml.main
tool_conf.xml.sample
tools/evolution/mutate_snp_codon.py
tools/evolution/mutate_snp_codon.xml
diffs (193 lines):
diff -r 990231e77b88 -r b25489f4fb26 test-data/mutate_snp_codon_in.interval
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/mutate_snp_codon_in.interval Tue Sep 15 12:04:14 2009 -0400
@@ -0,0 +1,6 @@
+chr1 58995 58998 NM_001005484 0 + GAA GAA Glu GAA 1177632 28.96 0 2787607 0.422452662804 585 chr1 58996 58997 rs1638318 0 + A A A/G genomic single by-submitter 0 0 unknown exact 3
+chr1 59289 59292 NM_001005484 0 + TTT TTT Phe TTT 714298 17.57 0 1538990 0.464134269878 585 chr1 59290 59291 rs71245814 0 + T T G/T genomic single unknown 0 0 unknown exact 3
+chr1 59313 59316 NM_001005484 0 + AAG AAG Lys AAG 1295568 31.86 0 2289189 0.565950648898 585 chr1 59315 59316 rs2854682 0 - G G C/T genomic single by-submitter 0 0 unknown exact 3
+chr1 59373 59376 NM_001005484 0 + ACA ACA Thr ACA 614523 15.11 0 2162384 0.284187729839 585 chr1 59373 59374 rs2691305 0 - A A C/T genomic single unknown 0 0 unknown exact 3
+chr1 59412 59415 NM_001005484 0 + GCG GCG Ala GCG 299495 7.37 0 2820741 0.106176001271 585 chr1 59414 59415 rs2531266 0 + G G C/G genomic single by-submitter 0 0 unknown exact 3
+chr1 59412 59415 NM_001005484 0 + GCG GCG Ala GCG 299495 7.37 0 2820741 0.106176001271 585 chr1 59414 59415 rs55874132 0 + G G C/G genomic single unknown 0 0 coding-synon exact 1
diff -r 990231e77b88 -r b25489f4fb26 test-data/mutate_snp_codon_out.interval
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/mutate_snp_codon_out.interval Tue Sep 15 12:04:14 2009 -0400
@@ -0,0 +1,6 @@
+chr1 58995 58998 NM_001005484 0 + GAA GAA Glu GAA 1177632 28.96 0 2787607 0.422452662804 585 chr1 58996 58997 rs1638318 0 + A A A/G genomic single by-submitter 0 0 unknown exact 3 GGA
+chr1 59289 59292 NM_001005484 0 + TTT TTT Phe TTT 714298 17.57 0 1538990 0.464134269878 585 chr1 59290 59291 rs71245814 0 + T T G/T genomic single unknown 0 0 unknown exact 3 TGT
+chr1 59313 59316 NM_001005484 0 + AAG AAG Lys AAG 1295568 31.86 0 2289189 0.565950648898 585 chr1 59315 59316 rs2854682 0 - G G C/T genomic single by-submitter 0 0 unknown exact 3 AAA
+chr1 59373 59376 NM_001005484 0 + ACA ACA Thr ACA 614523 15.11 0 2162384 0.284187729839 585 chr1 59373 59374 rs2691305 0 - A A C/T genomic single unknown 0 0 unknown exact 3 GCA
+chr1 59412 59415 NM_001005484 0 + GCG GCG Ala GCG 299495 7.37 0 2820741 0.106176001271 585 chr1 59414 59415 rs2531266 0 + G G C/G genomic single by-submitter 0 0 unknown exact 3 GCC
+chr1 59412 59415 NM_001005484 0 + GCG GCG Ala GCG 299495 7.37 0 2820741 0.106176001271 585 chr1 59414 59415 rs55874132 0 + G G C/G genomic single unknown 0 0 coding-synon exact 1 GCC
diff -r 990231e77b88 -r b25489f4fb26 tool_conf.xml.main
--- a/tool_conf.xml.main Tue Sep 15 11:28:50 2009 -0400
+++ b/tool_conf.xml.main Tue Sep 15 12:04:14 2009 -0400
@@ -132,10 +132,11 @@
<tool file="regVariation/best_regression_subsets.xml" />
<tool file="regVariation/rcve.xml" />
</section>
- <section name="Evolution: HyPhy" id="hyphy">
+ <section name="Evolution" id="hyphy">
<tool file="hyphy/hyphy_branch_lengths_wrapper.xml" />
<tool file="hyphy/hyphy_nj_tree_wrapper.xml" />
<tool file="hyphy/hyphy_dnds_wrapper.xml" />
+ <tool file="evolution/mutate_snp_codon.xml" />
</section>
<section name="Metagenomic analyses" id="tax_manipulation">
<tool file="taxonomy/gi2taxonomy.xml" />
diff -r 990231e77b88 -r b25489f4fb26 tool_conf.xml.sample
--- a/tool_conf.xml.sample Tue Sep 15 11:28:50 2009 -0400
+++ b/tool_conf.xml.sample Tue Sep 15 12:04:14 2009 -0400
@@ -152,10 +152,11 @@
<tool file="regVariation/best_regression_subsets.xml" />
<tool file="regVariation/rcve.xml" />
</section>
- <section name="Evolution: HyPhy" id="hyphy">
+ <section name="Evolution" id="hyphy">
<tool file="hyphy/hyphy_branch_lengths_wrapper.xml" />
<tool file="hyphy/hyphy_nj_tree_wrapper.xml" />
<tool file="hyphy/hyphy_dnds_wrapper.xml" />
+ <tool file="evolution/mutate_snp_codon.xml" />
</section>
<section name="Metagenomic analyses" id="tax_manipulation">
<tool file="taxonomy/gi2taxonomy.xml" />
diff -r 990231e77b88 -r b25489f4fb26 tools/evolution/mutate_snp_codon.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/evolution/mutate_snp_codon.py Tue Sep 15 12:04:14 2009 -0400
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+"""
+Script to mutate SNP codons.
+Dan Blankenberg
+"""
+
+import sys, string
+
+def strandify( fields, column ):
+ strand = '+'
+ if column >= 0 and column < len( fields ):
+ strand = fields[ column ]
+ if strand not in [ '+', '-' ]:
+ strand = '+'
+ return strand
+
+def main():
+ # parse command line
+ input_file = sys.argv[1]
+ out = open( sys.argv[2], 'wb+' )
+ codon_chrom_col = int( sys.argv[3] ) - 1
+ codon_start_col = int( sys.argv[4] ) - 1
+ codon_end_col = int( sys.argv[5] ) - 1
+ codon_strand_col = int( sys.argv[6] ) - 1
+ codon_seq_col = int( sys.argv[7] ) - 1
+
+ snp_chrom_col = int( sys.argv[8] ) - 1
+ snp_start_col = int( sys.argv[9] ) - 1
+ snp_end_col = int( sys.argv[10] ) - 1
+ snp_strand_col = int( sys.argv[11] ) - 1
+ snp_observed_col = int( sys.argv[12] ) - 1
+
+ max_field_index = max( codon_chrom_col, codon_start_col, codon_end_col, codon_strand_col, codon_seq_col, snp_chrom_col, snp_start_col, snp_end_col, snp_strand_col, snp_observed_col )
+
+ DNA_COMP = string.maketrans( "ACGTacgt", "TGCAtgca" )
+ skipped_lines = 0
+ for line in open( input_file ):
+ line = line.rstrip( '\n\r' )
+ if line and not line.startswith( '#' ):
+ fields = line.split( '\t' )
+ if max_field_index >= len( fields ):
+ skipped_lines += 1
+ continue
+ codon_chrom = fields[codon_chrom_col]
+ codon_start = int( fields[codon_start_col] )
+ codon_end = int( fields[codon_end_col] )
+ codon_strand = strandify( fields, codon_strand_col )
+ codon_seq = fields[codon_seq_col].upper()
+
+ snp_chrom = fields[snp_chrom_col]
+ snp_start = int( fields[snp_start_col] )
+ snp_end = int( fields[snp_end_col] )
+ snp_strand = strandify( fields, snp_strand_col )
+ snp_observed = fields[snp_observed_col].split( '/' )
+
+ for observed in snp_observed:
+ #Extract DNA on neg strand codons will have positions reversed relative to interval positions; i.e. position 0 == position 2
+ offset = snp_start - codon_start
+ if codon_strand == '-':
+ offset = 2 - offset
+ assert offset >= 0 and offset <= 2, ValueError( 'Impossible offset determined: %s' % offset )
+
+ if codon_strand != snp_strand:
+ #if our SNP is on a different strand than our codon, take complement of provided observed SNP base
+ observed = observed.translate( DNA_COMP )
+ snp_codon = [ char for char in codon_seq ]
+ snp_codon[offset] = observed.upper()
+ snp_codon = ''.join( snp_codon )
+
+ if codon_seq != snp_codon: #only output when we actually have a different codon
+ out.write( "%s\t%s\n" % ( line, snp_codon ) )
+
+if __name__ == "__main__": main()
diff -r 990231e77b88 -r b25489f4fb26 tools/evolution/mutate_snp_codon.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/evolution/mutate_snp_codon.xml Tue Sep 15 12:04:14 2009 -0400
@@ -0,0 +1,60 @@
+<tool id="mutate_snp_codon_1" name="Mutate Codons" version="1.0.0">
+ <description>with SNPs</description>
+ <command interpreter="python">mutate_snp_codon.py $input1 $output1 ${input1.metadata.chromCol} ${input1.metadata.startCol} ${input1.metadata.endCol} ${input1.metadata.strandCol} $codon_seq_col $snp_chrom_col $snp_start_col $snp_end_col $snp_strand_col $snp_observed_col</command>
+ <inputs>
+ <param name="input1" type="data" format="interval" label="Interval file with joined SNPs" optional="False" help="The interval metadata for this file should be set for the codon positions."/>
+ <param name="codon_seq_col" label="Codon Sequence column" type="data_column" data_ref="input1" />
+ <param name="snp_chrom_col" label="SNP chromosome column" type="data_column" data_ref="input1" />
+ <param name="snp_start_col" label="SNP start column" type="data_column" data_ref="input1" />
+ <param name="snp_end_col" label="SNP end column" type="data_column" data_ref="input1" />
+ <param name="snp_strand_col" label="SNP strand column" type="data_column" data_ref="input1" />
+ <param name="snp_observed_col" label="SNP observed column" type="data_column" data_ref="input1" />
+ </inputs>
+ <outputs>
+ <data name="output1" format="interval" metadata_source="input1"/>
+ </outputs>
+ <tests>
+ <test>
+ <param name="input1" value="mutate_snp_codon_in.interval"/>
+ <param name="codon_seq_col" value="8"/>
+ <param name="snp_chrom_col" value="17"/>
+ <param name="snp_start_col" value="18"/>
+ <param name="snp_end_col" value="19"/>
+ <param name="snp_strand_col" value="22"/>
+ <param name="snp_observed_col" value="25"/>
+ <output name="output1" file="mutate_snp_codon_out.interval" />
+ </test>
+ </tests>
+ <help>
+This tool takes an interval file as input. This input should contain a set of codon locations and corresponding DNA sequence (such as from the *Extract Genomic DNA* tool) joined to SNP locations with observed values (such as *all fields from selected table* from the snp130 table of hg18 at the UCSC Table browser). This interval file should have the metadata (chromosome, start, end, strand) set for the columns containing the locations of the codons. The user needs to specify the columns containing the sequence for the codon as well as the genomic positions and observed values (values should be split by '/') for the SNP data as tool input; SNPs positions and sequence substitutes must have a length of exactly 1. Only genomic intervals which yield a different sequence string are output. All sequence characters are converted to uppercase during processing.
+
+ For example, using these settings:
+
+ * **metadata** **chromosome**, **start**, **end** and **strand** set to **1**, **2**, **3** and **6**, respectively
+ * **Codon Sequence column** set to **c8**
+ * **SNP chromosome column** set to **c17**
+ * **SNP start column** set to **c18**
+ * **SNP end column** set to **c19**
+ * **SNP strand column** set to **c22**
+ * **SNP observed column** set to **c25**
+
+ with the following input::
+
+ chr1 58995 58998 NM_001005484 0 + GAA GAA Glu GAA 1177632 28.96 0 2787607 0.422452662804 585 chr1 58996 58997 rs1638318 0 + A A A/G genomic single by-submitter 0 0 unknown exact 3
+ chr1 59289 59292 NM_001005484 0 + TTT TTT Phe TTT 714298 17.57 0 1538990 0.464134269878 585 chr1 59290 59291 rs71245814 0 + T T G/T genomic single unknown 0 0 unknown exact 3
+ chr1 59313 59316 NM_001005484 0 + AAG AAG Lys AAG 1295568 31.86 0 2289189 0.565950648898 585 chr1 59315 59316 rs2854682 0 - G G C/T genomic single by-submitter 0 0 unknown exact 3
+ chr1 59373 59376 NM_001005484 0 + ACA ACA Thr ACA 614523 15.11 0 2162384 0.284187729839 585 chr1 59373 59374 rs2691305 0 - A A C/T genomic single unknown 0 0 unknown exact 3
+ chr1 59412 59415 NM_001005484 0 + GCG GCG Ala GCG 299495 7.37 0 2820741 0.106176001271 585 chr1 59414 59415 rs2531266 0 + G G C/G genomic single by-submitter 0 0 unknown exact 3
+ chr1 59412 59415 NM_001005484 0 + GCG GCG Ala GCG 299495 7.37 0 2820741 0.106176001271 585 chr1 59414 59415 rs55874132 0 + G G C/G genomic single unknown 0 0 coding-synon exact 1
+
+
+ will produce::
+
+ chr1 58995 58998 NM_001005484 0 + GAA GAA Glu GAA 1177632 28.96 0 2787607 0.422452662804 585 chr1 58996 58997 rs1638318 0 + A A A/G genomic single by-submitter 0 0 unknown exact 3 GGA
+ chr1 59289 59292 NM_001005484 0 + TTT TTT Phe TTT 714298 17.57 0 1538990 0.464134269878 585 chr1 59290 59291 rs71245814 0 + T T G/T genomic single unknown 0 0 unknown exact 3 TGT
+ chr1 59313 59316 NM_001005484 0 + AAG AAG Lys AAG 1295568 31.86 0 2289189 0.565950648898 585 chr1 59315 59316 rs2854682 0 - G G C/T genomic single by-submitter 0 0 unknown exact 3 AAA
+ chr1 59373 59376 NM_001005484 0 + ACA ACA Thr ACA 614523 15.11 0 2162384 0.284187729839 585 chr1 59373 59374 rs2691305 0 - A A C/T genomic single unknown 0 0 unknown exact 3 GCA
+ chr1 59412 59415 NM_001005484 0 + GCG GCG Ala GCG 299495 7.37 0 2820741 0.106176001271 585 chr1 59414 59415 rs2531266 0 + G G C/G genomic single by-submitter 0 0 unknown exact 3 GCC
+ chr1 59412 59415 NM_001005484 0 + GCG GCG Ala GCG 299495 7.37 0 2820741 0.106176001271 585 chr1 59414 59415 rs55874132 0 + G G C/G genomic single unknown 0 0 coding-synon exact 1 GCC
+ </help>
+</tool>
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/bd160d40ee15
changeset: 2696:bd160d40ee15
user: Nate Coraor <nate(a)bx.psu.edu>
date: Tue Sep 15 12:57:17 2009 -0400
description:
More fixes for cleanup_datasets.py
1 file(s) affected in this change:
scripts/cleanup_datasets/cleanup_datasets.py
diffs (19 lines):
diff -r b25489f4fb26 -r bd160d40ee15 scripts/cleanup_datasets/cleanup_datasets.py
--- a/scripts/cleanup_datasets/cleanup_datasets.py Tue Sep 15 12:04:14 2009 -0400
+++ b/scripts/cleanup_datasets/cleanup_datasets.py Tue Sep 15 12:57:17 2009 -0400
@@ -1,4 +1,6 @@
#!/usr/bin/env python
+
+import os, sys
new_path = [ os.path.join( os.getcwd(), "lib" ) ]
new_path.extend( sys.path[1:] ) # remove scripts/ from the path
@@ -8,7 +10,7 @@
import pkg_resources
pkg_resources.require( "SQLAlchemy >= 0.4" )
-import sys, os, time, ConfigParser, shutil
+import time, ConfigParser, shutil
from datetime import datetime, timedelta
from time import strftime
from optparse import OptionParser
1
0