diff --git a/lib/galaxy/web/controllers/library.py b/lib/galaxy/web/controllers/library.py index de0442d6725..60b30d95f2d 100644 --- a/lib/galaxy/web/controllers/library.py +++ b/lib/galaxy/web/controllers/library.py @@ -3,7 +3,6 @@ from galaxy.model.orm import * from galaxy.datatypes import sniff from galaxy import util from galaxy.util.odict import odict -from galaxy.web.controllers.forms import get_all_forms from galaxy.util.streamball import StreamBall import logging, tempfile, zipfile, tarfile, os, sys @@ -94,8 +93,8 @@ class Library( BaseController ): params = util.Params( kwd ) msg = util.restore_text( params.get( 'msg', '' ) ) messagetype = params.get( 'messagetype', 'done' ) - id = params.get( 'id', None ) - if not id: + library_id = params.get( 'obj_id', None ) + if not library_id: # To handle bots msg = "You must specify a library id." return trans.response.send_redirect( web.url_for( controller='library', @@ -103,10 +102,10 @@ class Library( BaseController ): default_action=params.get( 'default_action', None ), msg=util.sanitize_text( msg ), messagetype='error' ) ) - library = library=trans.app.model.Library.get( id ) + library = library=trans.app.model.Library.get( library_id ) if not library: # To handle bots - msg = "Invalid library id ( %s )." + msg = "Invalid library id ( %s )." % str( library_id ) return trans.response.send_redirect( web.url_for( controller='library', action='browse_libraries', default_action=params.get( 'default_action', None ), @@ -126,10 +125,11 @@ class Library( BaseController ): msg=msg, messagetype=messagetype ) @web.expose - def library( self, trans, id=None, **kwd ): + def library( self, trans, **kwd ): params = util.Params( kwd ) msg = util.restore_text( params.get( 'msg', '' ) ) messagetype = params.get( 'messagetype', 'done' ) + library_id = params.get( 'obj_id', None ) # TODO: eventually we'll want the ability for users to create libraries if params.get( 'delete', False ): action = 'delete' @@ -137,15 +137,15 @@ class Library( BaseController ): action = 'permissions' else: action = 'information' - if not id: + if not library_id: msg = "You must specify a library." return trans.response.send_redirect( web.url_for( controller='library', action='browse_libraries', msg=util.sanitize_text( msg ), messagetype='error' ) ) - library = trans.app.model.Library.get( int( id ) ) + library = trans.app.model.Library.get( int( library_id ) ) if not library: - msg = "Invalid library id ( %s ) specified." % str( id ) + msg = "Invalid library id ( %s ) specified." % str( obj_id ) return trans.response.send_redirect( web.url_for( controller='library', action='browse_libraries', msg=util.sanitize_text( msg ), @@ -175,7 +175,7 @@ class Library( BaseController ): msg = "Library '%s' has been renamed to '%s'" % ( old_name, new_name ) return trans.response.send_redirect( web.url_for( controller='library', action='library', - id=id, + obj_id=library.id, edit_info=True, msg=util.sanitize_text( msg ), messagetype='done' ) ) @@ -198,7 +198,7 @@ class Library( BaseController ): msg = "Permissions updated for library '%s'" % library.name return trans.response.send_redirect( web.url_for( controller='library', action='library', - id=id, + obj_id=library.id, permissions=True, msg=util.sanitize_text( msg ), messagetype='done' ) ) @@ -207,157 +207,127 @@ class Library( BaseController ): msg=msg, messagetype=messagetype ) @web.expose - def datasets( self, trans, library_id, ldda_ids='', **kwd ): - # This method is used by the select list labeled "Perform action on selected datasets" - # on the analysis library browser. - if not ldda_ids: - msg = "You must select at least one dataset" - return trans.response.send_redirect( web.url_for( controller='library', - action='browse_library', - id=library_id, - msg=util.sanitize_text( msg ), - messagetype='error' ) ) - ldda_ids = util.listify( ldda_ids ) + def folder( self, trans, obj_id, library_id, **kwd ): params = util.Params( kwd ) msg = util.restore_text( params.get( 'msg', '' ) ) messagetype = params.get( 'messagetype', 'done' ) - if not params.do_action: - msg = "You must select an action to perform on selected datasets" + if params.get( 'new', False ): + action = 'new' + elif params.get( 'delete', False ): + action = 'delete' + elif params.get( 'permissions', False ): + action = 'permissions' + else: + # 'information' will be the default + action = 'information' + folder = trans.app.model.LibraryFolder.get( int( obj_id ) ) + if not folder: + msg = "Invalid folder specified, id: %s" % str( obj_id ) return trans.response.send_redirect( web.url_for( controller='library', action='browse_library', - id=library_id, + obj_id=library_id, msg=util.sanitize_text( msg ), messagetype='error' ) ) - if params.do_action == 'add': - history = trans.get_history() - for ldda_id in ldda_ids: - ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( ldda_id ) - hda = ldda.to_history_dataset_association( target_history=history, add_to_history = True ) - history.flush() - msg = "%i dataset(s) have been imported into your history" % len( ldda_ids ) - return trans.response.send_redirect( web.url_for( controller='library', - action='browse_library', - id=library_id, - msg=util.sanitize_text( msg ), - messagetype='done' ) ) - elif params.do_action == 'manage_permissions': - # We need the folder containing the LibraryDatasetDatasetAssociation(s) - ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( ldda_ids[0] ) - trans.response.send_redirect( web.url_for( controller='library', - action='library_dataset_dataset_association', - library_id=library_id, - folder_id=ldda.library_dataset.folder.id, - id=','.join( ldda_ids ), - permissions=True, - msg=util.sanitize_text( msg ), - messagetype=messagetype ) ) - else: - try: - if params.do_action == 'zip': - # Can't use mkstemp - the file must not exist first - tmpd = tempfile.mkdtemp() - tmpf = os.path.join( tmpd, 'library_download.' + params.do_action ) - if ziptype == '64': - archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_DEFLATED, True ) - else: - archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_DEFLATED ) - archive.add = lambda x, y: archive.write( x, y.encode('CP437') ) - elif params.do_action == 'tgz': - archive = util.streamball.StreamBall( 'w|gz' ) - elif params.do_action == 'tbz': - archive = util.streamball.StreamBall( 'w|bz2' ) - except (OSError, zipfile.BadZipFile): - log.exception( "Unable to create archive for download" ) - msg = "Unable to create archive for download, please report this error" + user, roles = trans.get_user_and_roles() + if action == 'new': + if params.new == 'submitted': + new_folder = trans.app.model.LibraryFolder( name=util.restore_text( params.name ), + description=util.restore_text( params.description ) ) + # We are associating the last used genome build with folders, so we will always + # initialize a new folder with the first dbkey in util.dbnames which is currently + # ? unspecified (?) + new_folder.genome_build = util.dbnames.default_value + folder.add_folder( new_folder ) + new_folder.flush() + # New folders default to having the same permissions as their parent folder + trans.app.security_agent.copy_library_permissions( folder, new_folder ) + msg = "New folder named '%s' has been added to the library" % new_folder.name return trans.response.send_redirect( web.url_for( controller='library', action='browse_library', - id=library_id, + obj_id=library_id, msg=util.sanitize_text( msg ), - messagetype='error' ) ) - seen = [] - user, roles = trans.get_user_and_roles() - for id in ldda_ids: - ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id ) - if not ldda or not trans.app.security_agent.can_access_dataset( roles, ldda.dataset ): - continue - path = "" - parent_folder = ldda.library_dataset.folder - while parent_folder is not None: - # Exclude the now-hidden "root folder" - if parent_folder.parent is None: - path = os.path.join( parent_folder.library_root[0].name, path ) - break - path = os.path.join( parent_folder.name, path ) - parent_folder = parent_folder.parent - path += ldda.name - while path in seen: - path += '_' - seen.append( path ) - try: - archive.add( ldda.dataset.file_name, path ) - except IOError: - log.exception( "Unable to write to temporary library download archive" ) - msg = "Unable to create archive for download, please report this error" + messagetype='done' ) ) + return trans.fill_template( '/library/new_folder.mako', + library_id=library_id, + folder=folder, + msg=msg, + messagetype=messagetype ) + elif action == 'information': + # See if we have any associated templates + widgets = folder.get_template_widgets( trans ) + if params.get( 'rename_folder_button', False ): + if trans.app.security_agent.can_modify_library_item( user, roles, folder ): + old_name = folder.name + new_name = util.restore_text( params.name ) + new_description = util.restore_text( params.description ) + if not new_name: + msg = 'Enter a valid name' + return trans.fill_template( "/library/folder_info.mako", + folder=folder, + library_id=library_id, + widgets=widgets, + msg=msg, + messagetype='error' ) + else: + folder.name = new_name + folder.description = new_description + folder.flush() + msg = "Folder '%s' has been renamed to '%s'" % ( old_name, new_name ) + return trans.response.send_redirect( web.url_for( controller='library', + action='folder', + obj_id=folder.id, + library_id=library_id, + rename=True, + msg=util.sanitize_text( msg ), + messagetype='done' ) ) + else: + msg = "You are not authorized to edit this folder" + return trans.fill_template( "/library/folder_info.mako", + folder=folder, + library_id=library_id, + widgets=widgets, + msg=msg, + messagetype='error' ) + return trans.fill_template( '/library/folder_info.mako', + folder=folder, + library_id=library_id, + widgets=widgets, + msg=msg, + messagetype=messagetype ) + elif action == 'permissions': + if params.get( 'update_roles_button', False ): + # The user clicked the Save button on the 'Associate With Roles' form + if trans.app.security_agent.can_manage_library_item( user, roles, folder ): + permissions = {} + for k, v in trans.app.model.Library.permitted_actions.items(): + in_roles = [ trans.app.model.Role.get( int( x ) ) for x in util.listify( params.get( k + '_in', [] ) ) ] + permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles + trans.app.security_agent.set_all_library_permissions( folder, permissions ) + folder.refresh() + msg = 'Permissions updated for folder %s' % folder.name return trans.response.send_redirect( web.url_for( controller='library', - action='browse_library', - id=library_id, + action='folder', + obj_id=folder.id, + library_id=library_id, + permissions=True, + msg=util.sanitize_text( msg ), + messagetype='done' ) ) + else: + msg = "You are not authorized to manage permissions on this folder" + return trans.response.send_redirect( web.url_for( controller='library', + action='folder', + obj_id=folder.id, + library_id=library_id, + permissions=True, msg=util.sanitize_text( msg ), messagetype='error' ) ) - if params.do_action == 'zip': - archive.close() - tmpfh = open( tmpf ) - # clean up now - try: - os.unlink( tmpf ) - os.rmdir( tmpd ) - except OSError: - log.exception( "Unable to remove temporary library download archive and directory" ) - msg = "Unable to create archive for download, please report this error" - return trans.response.send_redirect( web.url_for( controller='library', - action='browse_library', - id=library_id, - msg=util.sanitize_text( msg ), - messagetype='error' ) ) - trans.response.set_content_type( "application/x-zip-compressed" ) - trans.response.headers[ "Content-Disposition" ] = "attachment; filename=GalaxyLibraryFiles.%s" % params.do_action - return tmpfh - else: - trans.response.set_content_type( "application/x-tar" ) - trans.response.headers[ "Content-Disposition" ] = "attachment; filename=GalaxyLibraryFiles.%s" % params.do_action - archive.wsgi_status = trans.response.wsgi_status() - archive.wsgi_headeritems = trans.response.wsgi_headeritems() - return archive.stream + return trans.fill_template( '/library/folder_permissions.mako', + folder=folder, + library_id=library_id, + msg=msg, + messagetype=messagetype ) @web.expose - def download_dataset_from_folder(self, trans, id, library_id=None, **kwd): - """Catches the dataset id and displays file contents as directed""" - # id must refer to a LibraryDatasetDatasetAssociation object - ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id ) - if not ldda.dataset: - msg = 'Invalid LibraryDatasetDatasetAssociation id %s received for file downlaod' % str( id ) - return trans.response.send_redirect( web.url_for( controller='library', - action='browse_library', - id=library_id, - msg=msg, - messagetype='error' ) ) - mime = trans.app.datatypes_registry.get_mimetype_by_extension( ldda.extension.lower() ) - trans.response.set_content_type( mime ) - fStat = os.stat( ldda.file_name ) - trans.response.headers[ 'Content-Length' ] = int( fStat.st_size ) - valid_chars = '.,^_-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' - fname = ldda.name - fname = ''.join( c in valid_chars and c or '_' for c in fname )[ 0:150 ] - trans.response.headers[ "Content-Disposition" ] = "attachment; filename=GalaxyLibraryDataset-%s-[%s]" % ( str( id ), fname ) - try: - return open( ldda.file_name ) - except: - msg = 'This dataset contains no content' - return trans.response.send_redirect( web.url_for( controller='library', - action='browse_library', - id=library_id, - msg=msg, - messagetype='error' ) ) - @web.expose - def library_dataset( self, trans, id, library_id, **kwd ): + def library_dataset( self, trans, obj_id, library_id, **kwd ): params = util.Params( kwd ) msg = util.restore_text( params.get( 'msg', '' ) ) messagetype = params.get( 'messagetype', 'done' ) @@ -365,12 +335,12 @@ class Library( BaseController ): action = 'permissions' else: action = 'information' - library_dataset = trans.app.model.LibraryDataset.get( id ) + library_dataset = trans.app.model.LibraryDataset.get( obj_id ) if not library_dataset: - msg = "Invalid library dataset specified, id: %s" %str( id ) + msg = "Invalid library dataset specified, id: %s" %str( obj_id ) return trans.response.send_redirect( web.url_for( controller='library', action='browse_library', - id=library_id, + obj_id=library_id, msg=util.sanitize_text( msg ), messagetype='error' ) ) user, roles = trans.get_user_and_roles() @@ -424,7 +394,248 @@ class Library( BaseController ): msg=msg, messagetype=messagetype ) @web.expose - def library_dataset_dataset_association( self, trans, library_id, folder_id, id=None, **kwd ): + def ldda_edit_info( self, trans, library_id, folder_id, obj_id, **kwd ): + params = util.Params( kwd ) + msg = util.restore_text( params.get( 'msg', '' ) ) + messagetype = params.get( 'messagetype', 'done' ) + ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( obj_id ) + if not ldda: + msg = "Invalid LibraryDatasetDatasetAssociation specified, obj_id: %s" % str( obj_id ) + return trans.response.send_redirect( web.url_for( controller='library', + action='browse_library', + obj_id=library_id, + msg=util.sanitize_text( msg ), + messagetype='error' ) ) + dbkey = params.get( 'dbkey', '?' ) + if isinstance( dbkey, list ): + dbkey = dbkey[0] + user, roles = trans.get_user_and_roles() + file_formats = [ dtype_name for dtype_name, dtype_value in trans.app.datatypes_registry.datatypes_by_extension.iteritems() if dtype_value.allow_datatype_change ] + file_formats.sort() + # See if we have any associated templates + widgets = ldda.get_template_widgets( trans ) + if params.get( 'change', False ): + # The user clicked the Save button on the 'Change data type' form + if trans.app.security_agent.can_modify_library_item( user, roles, ldda ): + if ldda.datatype.allow_datatype_change and trans.app.datatypes_registry.get_datatype_by_extension( params.datatype ).allow_datatype_change: + trans.app.datatypes_registry.change_datatype( ldda, params.datatype ) + trans.app.model.flush() + msg = "Data type changed for library dataset '%s'" % ldda.name + messagetype = 'done' + else: + msg = "You are unable to change datatypes in this manner. Changing %s to %s is not allowed." % ( ldda.extension, params.datatype ) + messagetype = 'error' + else: + msg = "You are not authorized to change the data type of dataset '%s'" % ldda.name + messagetype = 'error' + return trans.fill_template( "/library/ldda_edit_info.mako", + ldda=ldda, + library_id=library_id, + file_formats=file_formats, + widgets=widgets, + msg=msg, + messagetype=messagetype ) + elif params.get( 'save', False ): + # The user clicked the Save button on the 'Edit Attributes' form + if trans.app.security_agent.can_modify_library_item( user, roles, ldda ): + old_name = ldda.name + new_name = util.restore_text( params.get( 'name', '' ) ) + new_info = util.restore_text( params.get( 'info', '' ) ) + new_message = util.restore_text( params.get( 'message', '' ) ) + if not new_name: + msg = 'Enter a valid name' + messagetype = 'error' + else: + ldda.name = new_name + ldda.info = new_info + ldda.message = new_message + # The following for loop will save all metadata_spec items + for name, spec in ldda.datatype.metadata_spec.items(): + if spec.get("readonly"): + continue + optional = params.get( "is_" + name, None ) + if optional and optional == 'true': + # optional element... == 'true' actually means it is NOT checked (and therefore ommitted) + setattr( ldda.metadata, name, None ) + else: + setattr( ldda.metadata, name, spec.unwrap( params.get ( name, None ) ) ) + ldda.metadata.dbkey = dbkey + ldda.datatype.after_edit( ldda ) + trans.app.model.flush() + msg = 'Attributes updated for library dataset %s' % ldda.name + messagetype = 'done' + else: + msg = "you are not authorized to edit the attributes of dataset '%s'" % ldda.name + messagetype = 'error' + return trans.fill_template( "/library/ldda_edit_info.mako", + ldda=ldda, + library_id=library_id, + file_formats=file_formats, + widgets=widgets, + msg=msg, + messagetype=messagetype ) + elif params.get( 'detect', False ): + # The user clicked the Auto-detect button on the 'Edit Attributes' form + if trans.app.security_agent.can_modify_library_item( user, roles, ldda ): + for name, spec in ldda.datatype.metadata_spec.items(): + # We need to be careful about the attributes we are resetting + if name not in [ 'name', 'info', 'dbkey' ]: + if spec.get( 'default' ): + setattr( ldda.metadata, name, spec.unwrap( spec.get( 'default' ) ) ) + ldda.datatype.set_meta( ldda ) + ldda.datatype.after_edit( ldda ) + trans.app.model.flush() + msg = 'Attributes updated for library dataset %s' % ldda.name + messagetype = 'done' + else: + msg = "you are not authorized to edit the attributes of dataset '%s'" % ldda.name + messagetype = 'error' + return trans.fill_template( "/library/ldda_edit_info.mako", + ldda=ldda, + library_id=library_id, + file_formats=file_formats, + widgets=widgets, + msg=msg, + messagetype=messagetype ) + elif params.get( 'delete', False ): + if trans.app.security_agent.can_modify_library_item( user, roles, folder ): + ldda.deleted = True + ldda.flush() + msg = 'Dataset %s has been removed from this data library' % ldda.name + messagetype = 'done' + else: + msg = "you are not authorized to delete dataset '%s'" % ldda.name + messagetype = 'error' + return trans.fill_template( "/library/ldda_edit_info.mako", + ldda=ldda, + library_id=library_id, + file_formats=file_formats, + widgets=widgets, + msg=msg, + messagetype=messagetype ) + if trans.app.security_agent.can_modify_library_item( user, roles, ldda ): + ldda.datatype.before_edit( ldda ) + if "dbkey" in ldda.datatype.metadata_spec and not ldda.metadata.dbkey: + # Copy dbkey into metadata, for backwards compatability + # This looks like it does nothing, but getting the dbkey + # returns the metadata dbkey unless it is None, in which + # case it resorts to the old dbkey. Setting the dbkey + # sets it properly in the metadata + ldda.metadata.dbkey = ldda.dbkey + return trans.fill_template( "/library/ldda_edit_info.mako", + ldda=ldda, + library_id=library_id, + file_formats=file_formats, + widgets=widgets, + msg=msg, + messagetype=messagetype ) + @web.expose + def ldda_display_info( self, trans, library_id, folder_id, obj_id, **kwd ): + params = util.Params( kwd ) + msg = util.restore_text( params.get( 'msg', '' ) ) + messagetype = params.get( 'messagetype', 'done' ) + ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( obj_id ) + if not ldda: + msg = "Invalid LibraryDatasetDatasetAssociation specified, id: %s" % str( obj_id ) + return trans.response.send_redirect( web.url_for( controller='admin', + action='browse_library', + obj_id=library_id, + msg=util.sanitize_text( msg ), + messagetype='error' ) ) + # See if we have any associated templates + widgets = ldda.get_template_widgets( trans ) + return trans.fill_template( '/library/ldda_info.mako', + ldda=ldda, + library_id=library_id, + widgets=widgets, + msg=msg, + messagetype=messagetype ) + @web.expose + def ldda_manage_permissions( self, trans, library_id, folder_id, obj_id, **kwd ): + params = util.Params( kwd ) + msg = util.restore_text( params.get( 'msg', '' ) ) + messagetype = params.get( 'messagetype', 'done' ) + obj_ids = util.listify( obj_id ) + # Display permission form, permissions will be updated for all lddas simultaneously. + lddas = [] + for obj_id in [ int( obj_id ) for obj_id in obj_ids ]: + ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( obj_id ) + if ldda is None: + msg = 'You specified an invalid LibraryDatasetDatasetAssociation id: %s' %str( obj_id ) + trans.response.send_redirect( web.url_for( controller='library', + action='browse_library', + obj_id=library_id, + msg=util.sanitize_text( msg ), + messagetype='error' ) ) + lddas.append( ldda ) + if params.get( 'update_roles_button', False ): + if trans.app.security_agent.can_manage_library_item( user, roles, ldda ) and \ + trans.app.security_agent.can_manage_dataset( roles, ldda.dataset ): + permissions = {} + for k, v in trans.app.model.Dataset.permitted_actions.items(): + in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.get( k + '_in', [] ) ) ] + permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles + for ldda in lddas: + # Set the DATASET permissions on the Dataset + trans.app.security_agent.set_all_dataset_permissions( ldda.dataset, permissions ) + ldda.dataset.refresh() + permissions = {} + for k, v in trans.app.model.Library.permitted_actions.items(): + in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ] + permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles + for ldda in lddas: + # Set the LIBRARY permissions on the LibraryDataset + # NOTE: the LibraryDataset and LibraryDatasetDatasetAssociation will be set with the same permissions + trans.app.security_agent.set_all_library_permissions( ldda.library_dataset, permissions ) + ldda.library_dataset.refresh() + # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation + trans.app.security_agent.set_all_library_permissions( ldda, permissions ) + ldda.refresh() + msg = 'Permissions and roles have been updated on %d datasets' % len( lddas ) + messagetype = 'done' + else: + msg = "You are not authorized to change the permissions of dataset '%s'" % ldda.name + messagetype = 'error' + return trans.fill_template( "/library/ldda_permissions.mako", + ldda=lddas, + library_id=library_id, + msg=msg, + messagetype=messagetype ) + if trans.app.security_agent.can_manage_library_item( user, roles, ldda ) and \ + trans.app.security_agent.can_manage_dataset( roles, ldda.dataset ): + # Ensure that the permissions across all library items are identical, otherwise we can't update them together. + check_list = [] + for ldda in lddas: + permissions = [] + # Check the library level permissions - the permissions on the LibraryDatasetDatasetAssociation + # will always be the same as the permissions on the associated LibraryDataset, so we only need to + # check one Library object + for library_permission in trans.app.security_agent.get_library_dataset_permissions( ldda.library_dataset ): + if library_permission.action not in permissions: + permissions.append( library_permission.action ) + for dataset_permission in trans.app.security_agent.get_dataset_permissions( ldda.dataset ): + if dataset_permission.action not in permissions: + permissions.append( dataset_permission.action ) + permissions.sort() + if not check_list: + check_list = permissions + if permissions != check_list: + msg = 'The datasets you selected do not have identical permissions, so they can not be updated together' + trans.response.send_redirect( web.url_for( controller='library', + action='browse_library', + obj_id=library_id, + msg=util.sanitize_text( msg ), + messagetype='error' ) ) + else: + msg = "You are not authorized to change the permissions of dataset '%s'" % ldda.name + messagetype = 'error' + return trans.fill_template( "/library/ldda_permissions.mako", + ldda=lddas, + library_id=library_id, + msg=msg, + messagetype=messagetype ) + @web.expose + def upload_library_dataset( self, trans, library_id, folder_id, **kwd ): params = util.Params( kwd ) msg = util.restore_text( params.get( 'msg', '' ) ) messagetype = params.get( 'messagetype', 'done' ) @@ -444,279 +655,6 @@ class Library( BaseController ): else: replace_dataset = None user, roles = trans.get_user_and_roles() - # Let's not overwrite the imported datatypes module with the variable datatypes? - # The built-in 'id' is overwritten in lots of places as well - ldatatypes = [ dtype_name for dtype_name, dtype_value in trans.app.datatypes_registry.datatypes_by_extension.iteritems() if dtype_value.allow_datatype_change ] - ldatatypes.sort() - if id: - if params.get( 'permissions', False ): - action = 'permissions' - elif params.get( 'edit_info', False ): - action = 'edit_info' - else: - action = 'info' - if id.count( ',' ): - ids = id.split( ',' ) - id = None - else: - ids = None - else: - ids = None - if id: - # ldda_id specified, display attributes form - ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id ) - if not ldda: - msg = "Invalid LibraryDatasetDatasetAssociation specified, id: %s" % str( id ) - return trans.response.send_redirect( web.url_for( controller='library', - action='browse_library', - id=library_id, - msg=util.sanitize_text( msg ), - messagetype='error' ) ) - # See if we have any associated templates - widgets = ldda.get_template_widgets( trans ) - if action == 'permissions': - if params.get( 'update_roles_button', False ): - # The user clicked the Save button on the 'Associate With Roles' form - if trans.app.security_agent.can_manage_library_item( user, roles, ldda ) and \ - trans.app.security_agent.can_manage_dataset( roles, ldda.dataset ): - permissions = {} - for k, v in trans.app.model.Dataset.permitted_actions.items(): - in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.get( k + '_in', [] ) ) ] - permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles - # Set the DATASET permissions on the Dataset - trans.app.security_agent.set_all_dataset_permissions( ldda.dataset, permissions ) - ldda.dataset.refresh() - permissions = {} - for k, v in trans.app.model.Library.permitted_actions.items(): - in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ] - permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles - # Set the LIBRARY permissions on the LibraryDataset - # NOTE: the LibraryDataset and LibraryDatasetDatasetAssociation will be set with the same permissions - trans.app.security_agent.set_all_library_permissions( ldda.library_dataset, permissions ) - ldda.library_dataset.refresh() - # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation - trans.app.security_agent.set_all_library_permissions( ldda, permissions ) - ldda.refresh() - msg = "Permissions updated for dataset '%s'" % ldda.name - messagetype = 'done' - else: - msg = "You are not authorized to change the permissions of dataset '%s'" % ldda.name - messagetype = 'error' - return trans.fill_template( '/library/ldda_permissions.mako', - ldda=ldda, - library_id=library_id, - msg=msg, - messagetype=messagetype ) - elif action == 'info': - return trans.fill_template( '/library/ldda_info.mako', - ldda=ldda, - library_id=library_id, - widgets=widgets, - msg=msg, - messagetype=messagetype ) - elif action == 'edit_info': - if params.get( 'change', False ): - # The user clicked the Save button on the 'Change data type' form - if trans.app.security_agent.can_modify_library_item( user, roles, ldda ): - if ldda.datatype.allow_datatype_change and trans.app.datatypes_registry.get_datatype_by_extension( params.datatype ).allow_datatype_change: - trans.app.datatypes_registry.change_datatype( ldda, params.datatype ) - trans.app.model.flush() - msg = "Data type changed for library dataset '%s'" % ldda.name - messagetype = 'done' - else: - msg = "You are unable to change datatypes in this manner. Changing %s to %s is not allowed." % ( ldda.extension, params.datatype ) - messagetype = 'error' - else: - msg = "You are not authorized to change the data type of dataset '%s'" % ldda.name - messagetype = 'error' - return trans.fill_template( "/library/ldda_edit_info.mako", - ldda=ldda, - library_id=library_id, - datatypes=ldatatypes, - widgets=widgets, - msg=msg, - messagetype=messagetype ) - elif params.get( 'save', False ): - # The user clicked the Save button on the 'Edit Attributes' form - if trans.app.security_agent.can_modify_library_item( user, roles, ldda ): - old_name = ldda.name - new_name = util.restore_text( params.get( 'name', '' ) ) - new_info = util.restore_text( params.get( 'info', '' ) ) - new_message = util.restore_text( params.get( 'message', '' ) ) - if not new_name: - msg = 'Enter a valid name' - messagetype = 'error' - else: - ldda.name = new_name - ldda.info = new_info - ldda.message = new_message - # The following for loop will save all metadata_spec items - for name, spec in ldda.datatype.metadata_spec.items(): - if spec.get("readonly"): - continue - optional = params.get( "is_" + name, None ) - if optional and optional == 'true': - # optional element... == 'true' actually means it is NOT checked (and therefore ommitted) - setattr( ldda.metadata, name, None ) - else: - setattr( ldda.metadata, name, spec.unwrap( params.get ( name, None ) ) ) - ldda.metadata.dbkey = dbkey - ldda.datatype.after_edit( ldda ) - trans.app.model.flush() - msg = 'Attributes updated for library dataset %s' % ldda.name - messagetype = 'done' - else: - msg = "you are not authorized to edit the attributes of dataset '%s'" % ldda.name - messagetype = 'error' - return trans.fill_template( "/library/ldda_edit_info.mako", - ldda=ldda, - library_id=library_id, - datatypes=ldatatypes, - widgets=widgets, - msg=msg, - messagetype=messagetype ) - elif params.get( 'detect', False ): - # The user clicked the Auto-detect button on the 'Edit Attributes' form - if trans.app.security_agent.can_modify_library_item( user, roles, ldda ): - for name, spec in ldda.datatype.metadata_spec.items(): - # We need to be careful about the attributes we are resetting - if name not in [ 'name', 'info', 'dbkey' ]: - if spec.get( 'default' ): - setattr( ldda.metadata, name, spec.unwrap( spec.get( 'default' ) ) ) - ldda.datatype.set_meta( ldda ) - ldda.datatype.after_edit( ldda ) - trans.app.model.flush() - msg = 'Attributes updated for library dataset %s' % ldda.name - messagetype = 'done' - else: - msg = "you are not authorized to edit the attributes of dataset '%s'" % ldda.name - messagetype = 'error' - return trans.fill_template( "/library/ldda_edit_info.mako", - ldda=ldda, - library_id=library_id, - datatypes=ldatatypes, - widgets=widgets, - msg=msg, - messagetype=messagetype ) - elif params.get( 'delete', False ): - if trans.app.security_agent.can_modify_library_item( user, roles, folder ): - ldda.deleted = True - ldda.flush() - msg = 'Dataset %s has been removed from this library' % ldda.name - messagetype = 'done' - else: - msg = "you are not authorized to delete dataset '%s'" % ldda.name - messagetype = 'error' - return trans.fill_template( "/library/ldda_edit_info.mako", - ldda=ldda, - library_id=library_id, - datatypes=ldatatypes, - widgets=widgets, - msg=msg, - messagetype=messagetype ) - if trans.app.security_agent.can_modify_library_item( user, roles, ldda ): - ldda.datatype.before_edit( ldda ) - if "dbkey" in ldda.datatype.metadata_spec and not ldda.metadata.dbkey: - # Copy dbkey into metadata, for backwards compatability - # This looks like it does nothing, but getting the dbkey - # returns the metadata dbkey unless it is None, in which - # case it resorts to the old dbkey. Setting the dbkey - # sets it properly in the metadata - ldda.metadata.dbkey = ldda.dbkey - return trans.fill_template( "/library/ldda_edit_info.mako", - ldda=ldda, - library_id=library_id, - datatypes=ldatatypes, - widgets=widgets, - msg=msg, - messagetype=messagetype ) - elif ids: - # Multiple ids specified, display permission form, permissions will be updated for all simultaneously. - lddas = [] - for id in [ int( id ) for id in ids ]: - ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id ) - if ldda is None: - msg = 'You specified an invalid LibraryDatasetDatasetAssociation id: %s' %str( id ) - trans.response.send_redirect( web.url_for( controller='library', - action='browse_library', - id=library_id, - msg=util.sanitize_text( msg ), - messagetype='error' ) ) - lddas.append( ldda ) - if len( lddas ) < 2: - msg = 'You must specify at least two datasets on which to modify permissions, ids you sent: %s' % str( ids ) - trans.response.send_redirect( web.url_for( controller='library', - action='browse_library', - id=library_id, - msg=util.sanitize_text( msg ), - messagetype='error' ) ) - if action == 'permissions': - if params.get( 'update_roles_button', False ): - if trans.app.security_agent.can_manage_library_item( user, roles, ldda ) and \ - trans.app.security_agent.can_manage_dataset( roles, ldda.dataset ): - permissions = {} - for k, v in trans.app.model.Dataset.permitted_actions.items(): - in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.get( k + '_in', [] ) ) ] - permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles - for ldda in lddas: - # Set the DATASET permissions on the Dataset - trans.app.security_agent.set_all_dataset_permissions( ldda.dataset, permissions ) - ldda.dataset.refresh() - permissions = {} - for k, v in trans.app.model.Library.permitted_actions.items(): - in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ] - permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles - for ldda in lddas: - # Set the LIBRARY permissions on the LibraryDataset - # NOTE: the LibraryDataset and LibraryDatasetDatasetAssociation will be set with the same permissions - trans.app.security_agent.set_all_library_permissions( ldda.library_dataset, permissions ) - ldda.library_dataset.refresh() - # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation - trans.app.security_agent.set_all_library_permissions( ldda, permissions ) - ldda.refresh() - msg = 'Permissions and roles have been updated on %d datasets' % len( lddas ) - messagetype = 'done' - else: - msg = "You are not authorized to change the permissions of dataset '%s'" % ldda.name - messagetype = 'error' - return trans.fill_template( "/library/ldda_permissions.mako", - ldda=lddas, - library_id=library_id, - msg=msg, - messagetype=messagetype ) - if trans.app.security_agent.can_manage_library_item( user, roles, ldda ) and \ - trans.app.security_agent.can_manage_dataset( roles, ldda.dataset ): - # Ensure that the permissions across all library items are identical, otherwise we can't update them together. - check_list = [] - for ldda in lddas: - permissions = [] - # Check the library level permissions - the permissions on the LibraryDatasetDatasetAssociation - # will always be the same as the permissions on the associated LibraryDataset, so we only need to - # check one Library object - for library_permission in trans.app.security_agent.get_library_dataset_permissions( ldda.library_dataset ): - if library_permission.action not in permissions: - permissions.append( library_permission.action ) - for dataset_permission in trans.app.security_agent.get_dataset_permissions( ldda.dataset ): - if dataset_permission.action not in permissions: - permissions.append( dataset_permission.action ) - permissions.sort() - if not check_list: - check_list = permissions - if permissions != check_list: - msg = 'The datasets you selected do not have identical permissions, so they can not be updated together' - trans.response.send_redirect( web.url_for( controller='library', - action='browse_library', - id=library_id, - msg=util.sanitize_text( msg ), - messagetype='error' ) ) - else: - msg = "You are not authorized to change the permissions of dataset '%s'" % ldda.name - messagetype = 'error' - return trans.fill_template( "/library/ldda_permissions.mako", - ldda=lddas, - library_id=library_id, - msg=msg, - messagetype=messagetype ) if trans.app.security_agent.can_add_library_item( user, roles, folder ) or \ ( replace_dataset and trans.app.security_agent.can_modify_library_item( user, roles, replace_dataset ) ): if params.get( 'runtool_btn', False ) or params.get( 'ajax_upload', False ): @@ -729,7 +667,7 @@ class Library( BaseController ): template_id = 'None' widgets = [] upload_option = params.get( 'upload_option', 'upload_file' ) - created_outputs = trans.webapp.controllers[ 'library_dataset' ].upload_dataset( trans, + created_outputs = trans.webapp.controllers[ 'library_common' ].upload_dataset( trans, controller='library', library_id=library_id, folder_id=folder_id, @@ -761,7 +699,7 @@ class Library( BaseController ): default_action = 'add' trans.response.send_redirect( web.url_for( controller='library', action='browse_library', - id=library_id, + obj_id=library_id, default_action=default_action, created_ldda_ids=",".join( ldda_id_list ), msg=util.sanitize_text( msg ), @@ -771,45 +709,44 @@ class Library( BaseController ): msg = "Upload failed" trans.response.send_redirect( web.url_for( controller='library', action='browse_library', - id=library_id, + obj_id=library_id, created_ldda_ids=",".join( ldda_id_list ), msg=util.sanitize_text( msg ), messagetype='error' ) ) - if not id or replace_dataset: - # See if we have any inherited templates, but do not inherit contents. - widgets = folder.get_template_widgets( trans, get_contents=False ) - upload_option = params.get( 'upload_option', 'upload_file' ) - # No dataset(s) specified, so display the upload form. Send list of data formats to the form - # so the "extension" select list can be populated dynamically - file_formats = trans.app.datatypes_registry.upload_file_formats - # Send list of genome builds to the form so the "dbkey" select list can be populated dynamically - def get_dbkey_options( last_used_build ): - for dbkey, build_name in util.dbnames: - yield build_name, dbkey, ( dbkey==last_used_build ) - dbkeys = get_dbkey_options( last_used_build ) - # Send list of roles to the form so the dataset can be associated with 1 or more of them. - roles = trans.app.model.Role.filter( trans.app.model.Role.table.c.deleted==False ).order_by( trans.app.model.Role.c.name ).all() - # Send the current history to the form to enable importing datasets from history to library - history = trans.get_history() - history.refresh() - # If we're using nginx upload, override the form action - action = web.url_for( controller='library', action='library_dataset_dataset_association' ) - if upload_option == 'upload_file' and trans.app.config.nginx_upload_path: - action = web.url_for( trans.app.config.nginx_upload_path ) + '?nginx_redir=' + action - return trans.fill_template( '/library/upload.mako', - upload_option=upload_option, - action=action, - library_id=library_id, - folder_id=folder_id, - replace_dataset=replace_dataset, - file_formats=file_formats, - dbkeys=dbkeys, - last_used_build=last_used_build, - roles=roles, - history=history, - widgets=widgets, - msg=msg, - messagetype=messagetype ) + # See if we have any inherited templates, but do not inherit contents. + widgets = folder.get_template_widgets( trans, get_contents=False ) + upload_option = params.get( 'upload_option', 'upload_file' ) + # No dataset(s) specified, so display the upload form. Send list of data formats to the form + # so the "extension" select list can be populated dynamically + file_formats = trans.app.datatypes_registry.upload_file_formats + # Send list of genome builds to the form so the "dbkey" select list can be populated dynamically + def get_dbkey_options( last_used_build ): + for dbkey, build_name in util.dbnames: + yield build_name, dbkey, ( dbkey==last_used_build ) + dbkeys = get_dbkey_options( last_used_build ) + # Send list of roles to the form so the dataset can be associated with 1 or more of them. + roles = trans.app.model.Role.filter( trans.app.model.Role.table.c.deleted==False ).order_by( trans.app.model.Role.c.name ).all() + # Send the current history to the form to enable importing datasets from history to library + history = trans.get_history() + history.refresh() + # If we're using nginx upload, override the form action + action = web.url_for( controller='library', action='upload_library_dataset' ) + if upload_option == 'upload_file' and trans.app.config.nginx_upload_path: + action = web.url_for( trans.app.config.nginx_upload_path ) + '?nginx_redir=' + action + return trans.fill_template( '/library/upload.mako', + upload_option=upload_option, + action=action, + library_id=library_id, + folder_id=folder_id, + replace_dataset=replace_dataset, + file_formats=file_formats, + dbkeys=dbkeys, + last_used_build=last_used_build, + roles=roles, + history=history, + widgets=widgets, + msg=msg, + messagetype=messagetype ) @web.expose def add_history_datasets_to_library( self, trans, library_id, folder_id, hda_ids='', **kwd ): params = util.Params( kwd ) @@ -821,7 +758,7 @@ class Library( BaseController ): msg = "Invalid folder id: %s" % str( folder_id ) return trans.response.send_redirect( web.url_for( controller='library', action='browse_library', - id=library_id, + obj_id=library_id, msg=util.sanitize_text( msg ), messagetype='error' ) ) replace_id = params.get( 'replace_id', None ) @@ -836,7 +773,7 @@ class Library( BaseController ): msg = 'Your current history is empty' return trans.response.send_redirect( web.url_for( controller='library', action='browse_library', - id=library_id, + obj_id=library_id, msg=util.sanitize_text( msg ), messagetype='error' ) ) if params.get( 'add_history_datasets_to_library_button', False ): @@ -861,7 +798,7 @@ class Library( BaseController ): msg = "The requested HistoryDatasetAssociation id %s is invalid" % str( hda_id ) return trans.response.send_redirect( web.url_for( controller='library', action='browse_library', - id=library_id, + obj_id=library_id, msg=util.sanitize_text( msg ), messagetype='error' ) ) if created_ldda_ids: @@ -890,7 +827,7 @@ class Library( BaseController ): default_action = 'add' return trans.response.send_redirect( web.url_for( controller='library', action='browse_library', - id=library_id, + obj_id=library_id, created_ldda_ids=created_ldda_ids.lstrip( ',' ), default_action=default_action, msg=util.sanitize_text( msg ), @@ -923,264 +860,152 @@ class Library( BaseController ): msg=msg, messagetype=messagetype ) @web.expose - def folder( self, trans, id, library_id, **kwd ): + def download_dataset_from_folder(self, trans, obj_id, library_id=None, **kwd): + """Catches the dataset id and displays file contents as directed""" + # id must refer to a LibraryDatasetDatasetAssociation object + ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( obj_id ) + if not ldda.dataset: + msg = 'Invalid LibraryDatasetDatasetAssociation id %s received for file downlaod' % str( obj_id ) + return trans.response.send_redirect( web.url_for( controller='library', + action='browse_library', + obj_id=library_id, + msg=msg, + messagetype='error' ) ) + mime = trans.app.datatypes_registry.get_mimetype_by_extension( ldda.extension.lower() ) + trans.response.set_content_type( mime ) + fStat = os.stat( ldda.file_name ) + trans.response.headers[ 'Content-Length' ] = int( fStat.st_size ) + valid_chars = '.,^_-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' + fname = ldda.name + fname = ''.join( c in valid_chars and c or '_' for c in fname )[ 0:150 ] + trans.response.headers[ "Content-Disposition" ] = "attachment; filename=GalaxyLibraryDataset-%s-[%s]" % ( str( obj_id ), fname ) + try: + return open( ldda.file_name ) + except: + msg = 'This dataset contains no content' + return trans.response.send_redirect( web.url_for( controller='library', + action='browse_library', + obj_id=library_id, + msg=msg, + messagetype='error' ) ) + @web.expose + def datasets( self, trans, library_id, ldda_ids='', **kwd ): + # This method is used by the select list labeled "Perform action on selected datasets" + # on the analysis library browser. + if not ldda_ids: + msg = "You must select at least one dataset" + return trans.response.send_redirect( web.url_for( controller='library', + action='browse_library', + obj_id=library_id, + msg=util.sanitize_text( msg ), + messagetype='error' ) ) + ldda_ids = util.listify( ldda_ids ) params = util.Params( kwd ) msg = util.restore_text( params.get( 'msg', '' ) ) messagetype = params.get( 'messagetype', 'done' ) - if params.get( 'new', False ): - action = 'new' - elif params.get( 'delete', False ): - action = 'delete' - elif params.get( 'permissions', False ): - action = 'permissions' - else: - # 'information' will be the default - action = 'information' - folder = trans.app.model.LibraryFolder.get( int( id ) ) - if not folder: - msg = "Invalid folder specified, id: %s" % str( id ) + if not params.do_action: + msg = "You must select an action to perform on selected datasets" return trans.response.send_redirect( web.url_for( controller='library', action='browse_library', - id=library_id, + obj_id=library_id, msg=util.sanitize_text( msg ), messagetype='error' ) ) - user, roles = trans.get_user_and_roles() - if action == 'new': - if params.new == 'submitted': - new_folder = trans.app.model.LibraryFolder( name=util.restore_text( params.name ), - description=util.restore_text( params.description ) ) - # We are associating the last used genome build with folders, so we will always - # initialize a new folder with the first dbkey in util.dbnames which is currently - # ? unspecified (?) - new_folder.genome_build = util.dbnames.default_value - folder.add_folder( new_folder ) - new_folder.flush() - # New folders default to having the same permissions as their parent folder - trans.app.security_agent.copy_library_permissions( folder, new_folder ) - msg = "New folder named '%s' has been added to the library" % new_folder.name + if params.do_action == 'add': + history = trans.get_history() + for ldda_id in ldda_ids: + ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( ldda_id ) + hda = ldda.to_history_dataset_association( target_history=history, add_to_history = True ) + history.flush() + msg = "%i dataset(s) have been imported into your history" % len( ldda_ids ) + return trans.response.send_redirect( web.url_for( controller='library', + action='browse_library', + obj_id=library_id, + msg=util.sanitize_text( msg ), + messagetype='done' ) ) + elif params.do_action == 'manage_permissions': + # We need the folder containing the LibraryDatasetDatasetAssociation(s) + ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( ldda_ids[0] ) + trans.response.send_redirect( web.url_for( controller='library', + action='upload_library_dataset', + library_id=library_id, + folder_id=ldda.library_dataset.folder.id, + obj_id=','.join( ldda_ids ), + permissions=True, + msg=util.sanitize_text( msg ), + messagetype=messagetype ) ) + else: + try: + if params.do_action == 'zip': + # Can't use mkstemp - the file must not exist first + tmpd = tempfile.mkdtemp() + tmpf = os.path.join( tmpd, 'library_download.' + params.do_action ) + if ziptype == '64': + archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_DEFLATED, True ) + else: + archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_DEFLATED ) + archive.add = lambda x, y: archive.write( x, y.encode('CP437') ) + elif params.do_action == 'tgz': + archive = util.streamball.StreamBall( 'w|gz' ) + elif params.do_action == 'tbz': + archive = util.streamball.StreamBall( 'w|bz2' ) + except (OSError, zipfile.BadZipFile): + log.exception( "Unable to create archive for download" ) + msg = "Unable to create archive for download, please report this error" return trans.response.send_redirect( web.url_for( controller='library', action='browse_library', - id=library_id, + obj_id=library_id, msg=util.sanitize_text( msg ), - messagetype='done' ) ) - return trans.fill_template( '/library/new_folder.mako', - library_id=library_id, - folder=folder, - msg=msg, - messagetype=messagetype ) - elif action == 'information': - # See if we have any associated templates - widgets = folder.get_template_widgets( trans ) - if params.get( 'rename_folder_button', False ): - if trans.app.security_agent.can_modify_library_item( user, roles, folder ): - old_name = folder.name - new_name = util.restore_text( params.name ) - new_description = util.restore_text( params.description ) - if not new_name: - msg = 'Enter a valid name' - return trans.fill_template( "/library/folder_info.mako", - folder=folder, - library_id=library_id, - widgets=widgets, - msg=msg, - messagetype='error' ) - else: - folder.name = new_name - folder.description = new_description - folder.flush() - msg = "Folder '%s' has been renamed to '%s'" % ( old_name, new_name ) - return trans.response.send_redirect( web.url_for( controller='library', - action='folder', - id=id, - library_id=library_id, - rename=True, - msg=util.sanitize_text( msg ), - messagetype='done' ) ) - else: - msg = "You are not authorized to edit this folder" - return trans.fill_template( "/library/folder_info.mako", - folder=folder, - library_id=library_id, - widgets=widgets, - msg=msg, - messagetype='error' ) - return trans.fill_template( '/library/folder_info.mako', - folder=folder, - library_id=library_id, - widgets=widgets, - msg=msg, - messagetype=messagetype ) - elif action == 'permissions': - if params.get( 'update_roles_button', False ): - # The user clicked the Save button on the 'Associate With Roles' form - if trans.app.security_agent.can_manage_library_item( user, roles, folder ): - permissions = {} - for k, v in trans.app.model.Library.permitted_actions.items(): - in_roles = [ trans.app.model.Role.get( int( x ) ) for x in util.listify( params.get( k + '_in', [] ) ) ] - permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles - trans.app.security_agent.set_all_library_permissions( folder, permissions ) - folder.refresh() - msg = 'Permissions updated for folder %s' % folder.name + messagetype='error' ) ) + seen = [] + user, roles = trans.get_user_and_roles() + for ldda_id in ldda_ids: + ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( ldda_id ) + if not ldda or not trans.app.security_agent.can_access_dataset( roles, ldda.dataset ): + continue + path = "" + parent_folder = ldda.library_dataset.folder + while parent_folder is not None: + # Exclude the now-hidden "root folder" + if parent_folder.parent is None: + path = os.path.join( parent_folder.library_root[0].name, path ) + break + path = os.path.join( parent_folder.name, path ) + parent_folder = parent_folder.parent + path += ldda.name + while path in seen: + path += '_' + seen.append( path ) + try: + archive.add( ldda.dataset.file_name, path ) + except IOError: + log.exception( "Unable to write to temporary library download archive" ) + msg = "Unable to create archive for download, please report this error" return trans.response.send_redirect( web.url_for( controller='library', - action='folder', - id=id, - library_id=library_id, - permissions=True, - msg=util.sanitize_text( msg ), - messagetype='done' ) ) - else: - msg = "You are not authorized to manage permissions on this folder" - return trans.response.send_redirect( web.url_for( controller='library', - action='folder', - id=id, - library_id=library_id, - permissions=True, + action='browse_library', + obj_id=library_id, msg=util.sanitize_text( msg ), messagetype='error' ) ) - return trans.fill_template( '/library/folder_permissions.mako', - folder=folder, - library_id=library_id, - msg=msg, - messagetype=messagetype ) - @web.expose - def info_template( self, trans, library_id, id=None, folder_id=None, ldda_id=None, **kwd ): - params = util.Params( kwd ) - msg = util.restore_text( params.get( 'msg', '' ) ) - messagetype = params.get( 'messagetype', 'done' ) - if id: - library_item = trans.app.model.FormDefinition.get( int( id ) ) - library_item_desc = 'information template' - response_action = 'info_template' - response_id = id - elif folder_id: - library_item = trans.app.model.LibraryFolder.get( int( folder_id ) ) - library_item_desc = 'folder' - response_action = 'folder' - response_id = folder_id - elif ldda_id: - library_item = trans.app.model.LibraryDatasetDatasetAssociation.get( int( ldda_id ) ) - library_item_desc = 'library dataset' - response_action = 'library_dataset_dataset_association' - response_id = ldda_id - else: - library_item = trans.app.model.Library.get( int( library_id ) ) - library_item_desc = 'library' - response_action = 'browse_library' - response_id = library_id - forms = get_all_forms( trans, - filter=dict( deleted=False ), - form_type=trans.app.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE ) - if not forms: - msg = "There are no forms on which to base the template, so create a form and " - msg += "try again to add the information template to the %s." % library_item_desc - trans.response.send_redirect( web.url_for( controller='forms', - action='new', - new=True, - msg=msg, - messagetype='done' ) ) - if params.get( 'add', False ): - if params.get( 'add_info_template_button', False ): - form = trans.app.model.FormDefinition.get( int( kwd[ 'form_id' ] ) ) - #fields = list( copy.deepcopy( form.fields ) ) - form_values = trans.app.model.FormValues( form, [] ) - form_values.flush() - if folder_id: - assoc = trans.app.model.LibraryFolderInfoAssociation( library_item, form, form_values ) - elif ldda_id: - assoc = trans.app.model.LibraryDatasetDatasetInfoAssociation( library_item, form, form_values ) - else: - assoc = trans.app.model.LibraryInfoAssociation( library_item, form, form_values ) - assoc.flush() - msg = 'An information template based on the form "%s" has been added to this %s.' % ( form.name, library_item_desc ) - trans.response.send_redirect( web.url_for( controller='library', - action=response_action, - id=response_id, - msg=msg, - message_type='done' ) ) - return trans.fill_template( '/admin/library/select_info_template.mako', - library_item_name=library_item.name, - library_item_desc=library_item_desc, - library_id=library_id, - folder_id=folder_id, - ldda_id=ldda_id, - forms=forms, - msg=msg, - messagetype=messagetype ) - @web.expose - def edit_template_info( self, trans, library_id, num_widgets, library_item_id=None, library_item_type=None, **kwd ): - params = util.Params( kwd ) - msg = util.restore_text( params.get( 'msg', '' ) ) - messagetype = params.get( 'messagetype', 'done' ) - folder_id = None - if library_item_type == 'library': - library_item = trans.app.model.Library.get( library_item_id ) - elif library_item_type == 'library_dataset': - library_item = trans.app.model.LibraryDataset.get( library_item_id ) - elif library_item_type == 'folder': - library_item = trans.app.model.LibraryFolder.get( library_item_id ) - elif library_item_type == 'library_dataset_dataset_association': - library_item = trans.app.model.LibraryDatasetDatasetAssociation.get( library_item_id ) - # This response_action method requires a folder_id - folder_id = library_item.library_dataset.folder.id - else: - msg = "Invalid library item type ( %s ) specified, id ( %s )" % ( str( library_item_type ), str( library_item_id ) ) - return trans.response.send_redirect( web.url_for( controller='library', - action='browse_library', - id=library_id, - msg=util.sanitize_text( msg ), - messagetype='error' ) ) - # Save updated template field contents - field_values = [] - for index in range( int( num_widgets ) ): - field_values.append( util.restore_text( params.get( 'field_%i' % ( index ), '' ) ) ) - info = library_item.info_association[0].info - form_values = trans.app.model.FormValues.get( info.id ) - form_values.content = field_values - form_values.flush() - msg = 'The information has been updated.' - return trans.response.send_redirect( web.url_for( controller='library', - action=library_item_type, - id=library_item.id, - library_id=library_id, - folder_id=folder_id, - edit_info=True, - msg=util.sanitize_text( msg ), - messagetype='done' ) ) - -# ---- Utility methods ------------------------------------------------------- - -def active_folders( trans, folder ): - # Much faster way of retrieving all active sub-folders within a given folder than the - # performance of the mapper. This query also eagerloads the permissions on each folder. - return trans.sa_session.query( trans.app.model.LibraryFolder ) \ - .filter_by( parent=folder, deleted=False ) \ - .options( eagerload_all( "actions" ) ) \ - .order_by( trans.app.model.LibraryFolder.table.c.name ) \ - .all() -def activatable_folders( trans, folder ): - return trans.sa_session.query( trans.app.model.LibraryFolder ) \ - .filter_by( parent=folder, purged=False ) \ - .options( eagerload_all( "actions" ) ) \ - .order_by( trans.app.model.LibraryFolder.table.c.name ) \ - .all() -def active_folders_and_lddas( trans, folder ): - folders = active_folders( trans, folder ) - # This query is much faster than the folder.active_library_datasets property - lddas = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ) \ - .filter_by( deleted=False ) \ - .join( "library_dataset" ) \ - .filter( trans.app.model.LibraryDataset.table.c.folder_id==folder.id ) \ - .order_by( trans.app.model.LibraryDatasetDatasetAssociation.table.c.name ) \ - .all() - return folders, lddas -def activatable_folders_and_lddas( trans, folder ): - folders = activatable_folders( trans, folder ) - # This query is much faster than the folder.activatable_library_datasets property - lddas = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ) \ - .join( "library_dataset" ) \ - .filter( trans.app.model.LibraryDataset.table.c.folder_id==folder.id ) \ - .join( "dataset" ) \ - .filter( trans.app.model.Dataset.table.c.deleted==False ) \ - .order_by( trans.app.model.LibraryDatasetDatasetAssociation.table.c.name ) \ - .all() - return folders, lddas + if params.do_action == 'zip': + archive.close() + tmpfh = open( tmpf ) + # clean up now + try: + os.unlink( tmpf ) + os.rmdir( tmpd ) + except OSError: + log.exception( "Unable to remove temporary library download archive and directory" ) + msg = "Unable to create archive for download, please report this error" + return trans.response.send_redirect( web.url_for( controller='library', + action='browse_library', + obj_id=library_id, + msg=util.sanitize_text( msg ), + messagetype='error' ) ) + trans.response.set_content_type( "application/x-zip-compressed" ) + trans.response.headers[ "Content-Disposition" ] = "attachment; filename=GalaxyLibraryFiles.%s" % params.do_action + return tmpfh + else: + trans.response.set_content_type( "application/x-tar" ) + trans.response.headers[ "Content-Disposition" ] = "attachment; filename=GalaxyLibraryFiles.%s" % params.do_action + archive.wsgi_status = trans.response.wsgi_status() + archive.wsgi_headeritems = trans.response.wsgi_headeritems() + return archive.stream diff --git a/lib/galaxy/web/controllers/library_admin.py b/lib/galaxy/web/controllers/library_admin.py index ca1fbd7193d..86f651172a3 100644 --- a/lib/galaxy/web/controllers/library_admin.py +++ b/lib/galaxy/web/controllers/library_admin.py @@ -2,7 +2,6 @@ import sys from galaxy import util from galaxy.web.base.controller import * from galaxy.model.orm import * -from galaxy.web.controllers.forms import get_all_forms # Older py compatibility try: set() @@ -32,18 +31,19 @@ class LibraryAdmin( BaseController ): params = util.Params( kwd ) msg = util.restore_text( params.get( 'msg', '' ) ) messagetype = params.get( 'messagetype', 'done' ) - id = params.get( 'id', None ) - deleted = util.string_as_bool( params.get( 'deleted', False ) ) - show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) ) - if not id: + library_id = params.get( 'obj_id', None ) + if not library_id: + # To handle bots msg = "You must specify a library id." return trans.response.send_redirect( web.url_for( controller='library_admin', action='browse_libraries', msg=util.sanitize_text( msg ), messagetype='error' ) ) - library = library=trans.app.model.Library.get( id ) + deleted = util.string_as_bool( params.get( 'deleted', False ) ) + show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) ) + library = library=trans.app.model.Library.get( library_id ) if not library: - msg = "Invalid library id ( %s )." + msg = "Invalid library id ( %s )." % str( library_id ) return trans.response.send_redirect( web.url_for( controller='library_admin', action='browse_libraries', msg=util.sanitize_text( msg ), @@ -55,17 +55,17 @@ class LibraryAdmin( BaseController ): return trans.fill_template( '/admin/library/browse_library.mako', library=library, deleted=deleted, + show_deleted=show_deleted, created_ldda_ids=created_ldda_ids, - forms=get_all_forms( trans, filter=dict(deleted=False) ), msg=msg, - messagetype=messagetype, - show_deleted=show_deleted ) + messagetype=messagetype ) @web.expose @web.require_admin - def library( self, trans, id=None, **kwd ): + def library( self, trans, **kwd ): params = util.Params( kwd ) msg = util.restore_text( params.get( 'msg', '' ) ) messagetype = params.get( 'messagetype', 'done' ) + library_id = params.get( 'obj_id', None ) if params.get( 'new', False ): action = 'new' elif params.get( 'delete', False ): @@ -74,14 +74,14 @@ class LibraryAdmin( BaseController ): action = 'permissions' else: action = 'information' - if not id and not action == 'new': + if not library_id and not action == 'new': msg = "You must specify a library to %s." % action return trans.response.send_redirect( web.url_for( controller='library_admin', action='browse_libraries', msg=util.sanitize_text( msg ), messagetype='error' ) ) if not action == 'new': - library = trans.app.model.Library.get( int( id ) ) + library = trans.app.model.Library.get( int( library_id ) ) if action == 'new': if params.new == 'submitted': library = trans.app.model.Library( name = util.restore_text( params.name ), @@ -93,7 +93,7 @@ class LibraryAdmin( BaseController ): msg = "The new library named '%s' has been created" % library.name return trans.response.send_redirect( web.url_for( controller='library_admin', action='browse_library', - id=library.id, + obj_id=library.id, msg=util.sanitize_text( msg ), messagetype='done' ) ) return trans.fill_template( '/admin/library/new_library.mako', msg=msg, messagetype=messagetype ) @@ -122,7 +122,7 @@ class LibraryAdmin( BaseController ): msg = "Library '%s' has been renamed to '%s'" % ( old_name, new_name ) return trans.response.send_redirect( web.url_for( controller='library_admin', action='library', - id=id, + obj_id=library.id, edit_info=True, msg=util.sanitize_text( msg ), messagetype='done' ) ) @@ -171,7 +171,7 @@ class LibraryAdmin( BaseController ): msg = "Permissions updated for library '%s'" % library.name return trans.response.send_redirect( web.url_for( controller='library_admin', action='library', - id=id, + obj_id=library.id, permissions=True, msg=util.sanitize_text( msg ), messagetype='done' ) ) @@ -198,7 +198,7 @@ class LibraryAdmin( BaseController ): @web.require_admin def purge_library( self, trans, **kwd ): params = util.Params( kwd ) - library = trans.app.model.Library.get( int( params.id ) ) + library = trans.app.model.Library.get( int( params.obj_id ) ) def purge_folder( library_folder ): for lf in library_folder.folders: purge_folder( lf ) @@ -240,7 +240,7 @@ class LibraryAdmin( BaseController ): messagetype='done' ) ) @web.expose @web.require_admin - def folder( self, trans, id, library_id, **kwd ): + def folder( self, trans, obj_id, library_id, **kwd ): params = util.Params( kwd ) msg = util.restore_text( params.get( 'msg', '' ) ) messagetype = params.get( 'messagetype', 'done' ) @@ -253,12 +253,12 @@ class LibraryAdmin( BaseController ): else: # 'information' will be the default action = 'information' - folder = trans.app.model.LibraryFolder.get( int( id ) ) + folder = trans.app.model.LibraryFolder.get( int( obj_id ) ) if not folder: - msg = "Invalid folder specified, id: %s" % str( id ) + msg = "Invalid folder specified, id: %s" % str( obj_id ) return trans.response.send_redirect( web.url_for( controller='library_admin', action='browse_library', - id=library_id, + obj_id=library_id, msg=util.sanitize_text( msg ), messagetype='error' ) ) if action == 'new': @@ -276,7 +276,7 @@ class LibraryAdmin( BaseController ): msg = "New folder named '%s' has been added to the library" % new_folder.name return trans.response.send_redirect( web.url_for( controller='library_admin', action='browse_library', - id=library_id, + obj_id=library_id, msg=util.sanitize_text( msg ), messagetype='done' ) ) return trans.fill_template( '/admin/library/new_folder.mako', @@ -306,7 +306,7 @@ class LibraryAdmin( BaseController ): msg = "Folder '%s' has been renamed to '%s'" % ( old_name, new_name ) return trans.response.send_redirect( web.url_for( controller='library_admin', action='folder', - id=id, + obj_id=folder.id, library_id=library_id, edit_info=True, msg=util.sanitize_text( msg ), @@ -322,7 +322,7 @@ class LibraryAdmin( BaseController ): folder.flush() msg = "Folder '%s' and all of its contents have been marked deleted" % folder.name return trans.response.send_redirect( web.url_for( action='browse_library', - id=library_id, + obj_id=library_id, msg=util.sanitize_text( msg ), messagetype='done' ) ) elif action =='permissions': @@ -337,7 +337,7 @@ class LibraryAdmin( BaseController ): msg = "Permissions updated for folder '%s'" % folder.name return trans.response.send_redirect( web.url_for( controller='library_admin', action='folder', - id=id, + obj_id=folder.id, library_id=library_id, permissions=True, msg=util.sanitize_text( msg ), @@ -349,7 +349,7 @@ class LibraryAdmin( BaseController ): messagetype=messagetype ) @web.expose @web.require_admin - def library_dataset( self, trans, id, library_id, **kwd ): + def library_dataset( self, trans, obj_id, library_id, **kwd ): params = util.Params( kwd ) msg = util.restore_text( params.get( 'msg', '' ) ) messagetype = params.get( 'messagetype', 'done' ) @@ -357,12 +357,12 @@ class LibraryAdmin( BaseController ): action = 'permissions' else: action = 'information' - library_dataset = trans.app.model.LibraryDataset.get( id ) + library_dataset = trans.app.model.LibraryDataset.get( obj_id ) if not library_dataset: - msg = "Invalid library dataset specified, id: %s" %str( id ) + msg = "Invalid library dataset specified, id: %s" %str( obj_id ) return trans.response.send_redirect( web.url_for( controller='library_admin', action='browse_library', - id=library_id, + obj_id=library_id, msg=util.sanitize_text( msg ), messagetype='error' ) ) if action == 'information': @@ -406,13 +406,261 @@ class LibraryAdmin( BaseController ): messagetype=messagetype ) @web.expose @web.require_admin - def library_dataset_dataset_association( self, trans, library_id, folder_id, id=None, **kwd ): + def ldda_edit_info( self, trans, library_id, folder_id, obj_id, **kwd ): + params = util.Params( kwd ) + msg = util.restore_text( params.get( 'msg', '' ) ) + messagetype = params.get( 'messagetype', 'done' ) + ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( obj_id ) + if not ldda: + msg = "Invalid LibraryDatasetDatasetAssociation specified, obj_id: %s" % str( obj_id ) + return trans.response.send_redirect( web.url_for( controller='library_admin', + action='browse_library', + obj_id=library_id, + msg=util.sanitize_text( msg ), + messagetype='error' ) ) + dbkey = params.get( 'dbkey', '?' ) + if isinstance( dbkey, list ): + dbkey = dbkey[0] + file_formats = [ dtype_name for dtype_name, dtype_value in trans.app.datatypes_registry.datatypes_by_extension.iteritems() if dtype_value.allow_datatype_change ] + file_formats.sort() + # See if we have any associated templates + widgets = ldda.get_template_widgets( trans ) + if params.get( 'change', False ): + # The user clicked the Save button on the 'Change data type' form + if ldda.datatype.allow_datatype_change and trans.app.datatypes_registry.get_datatype_by_extension( params.datatype ).allow_datatype_change: + trans.app.datatypes_registry.change_datatype( ldda, params.datatype ) + trans.app.model.flush() + msg = "Data type changed for library dataset '%s'" % ldda.name + return trans.fill_template( "/admin/library/ldda_edit_info.mako", + ldda=ldda, + library_id=library_id, + file_formats=file_formats, + widgets=widgets, + msg=msg, + messagetype=messagetype ) + else: + return trans.show_error_message( "You are unable to change datatypes in this manner. Changing %s to %s is not allowed." % \ + ( ldda.extension, params.datatype ) ) + elif params.get( 'save', False ): + # The user clicked the Save button on the 'Edit Attributes' form + old_name = ldda.name + new_name = util.restore_text( params.get( 'name', '' ) ) + new_info = util.restore_text( params.get( 'info', '' ) ) + new_message = util.restore_text( params.get( 'message', '' ) ) + if not new_name: + msg = 'Enter a valid name' + messagetype = 'error' + else: + ldda.name = new_name + ldda.info = new_info + ldda.message = new_message + # The following for loop will save all metadata_spec items + for name, spec in ldda.datatype.metadata_spec.items(): + if spec.get("readonly"): + continue + optional = params.get( "is_" + name, None ) + if optional and optional == 'true': + # optional element... == 'true' actually means it is NOT checked (and therefore ommitted) + setattr( ldda.metadata, name, None ) + else: + setattr( ldda.metadata, name, spec.unwrap( params.get ( name, None ) ) ) + ldda.metadata.dbkey = dbkey + ldda.datatype.after_edit( ldda ) + trans.app.model.flush() + msg = 'Attributes updated for library dataset %s' % ldda.name + messagetype = 'done' + return trans.fill_template( "/admin/library/ldda_edit_info.mako", + ldda=ldda, + library_id=library_id, + file_formats=file_formats, + widgets=widgets, + msg=msg, + messagetype=messagetype ) + elif params.get( 'detect', False ): + # The user clicked the Auto-detect button on the 'Edit Attributes' form + for name, spec in ldda.datatype.metadata_spec.items(): + # We need to be careful about the attributes we are resetting + if name not in [ 'name', 'info', 'dbkey' ]: + if spec.get( 'default' ): + setattr( ldda.metadata, name, spec.unwrap( spec.get( 'default' ) ) ) + ldda.datatype.set_meta( ldda ) + ldda.datatype.after_edit( ldda ) + trans.app.model.flush() + msg = 'Attributes updated for library dataset %s' % ldda.name + return trans.fill_template( "/admin/library/ldda_edit_info.mako", + ldda=ldda, + library_id=library_id, + file_formats=file_formats, + widgets=widgets, + msg=msg, + messagetype=messagetype ) + elif params.get( 'delete', False ): + ldda.deleted = True + ldda.flush() + msg = 'Dataset %s has been removed from this data library' % ldda.name + return trans.fill_template( "/admin/library/ldda_edit_info.mako", + ldda=ldda, + library_id=library_id, + file_formats=file_formats, + widgets=widgets, + msg=msg, + messagetype=messagetype ) + ldda.datatype.before_edit( ldda ) + if "dbkey" in ldda.datatype.metadata_spec and not ldda.metadata.dbkey: + # Copy dbkey into metadata, for backwards compatability + # This looks like it does nothing, but getting the dbkey + # returns the metadata dbkey unless it is None, in which + # case it resorts to the old dbkey. Setting the dbkey + # sets it properly in the metadata + ldda.metadata.dbkey = ldda.dbkey + return trans.fill_template( "/admin/library/ldda_edit_info.mako", + ldda=ldda, + library_id=library_id, + file_formats=file_formats, + widgets=widgets, + msg=msg, + messagetype=messagetype ) + @web.expose + @web.require_admin + def ldda_display_info( self, trans, library_id, folder_id, obj_id, **kwd ): + params = util.Params( kwd ) + msg = util.restore_text( params.get( 'msg', '' ) ) + messagetype = params.get( 'messagetype', 'done' ) + show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) ) + ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( obj_id ) + if not ldda: + msg = "Invalid LibraryDatasetDatasetAssociation specified, obj_id: %s" % str( obj_id ) + return trans.response.send_redirect( web.url_for( controller='library_admin', + action='browse_library', + obj_id=library_id, + msg=util.sanitize_text( msg ), + messagetype='error' ) ) + # See if we have any associated templates + widgets = ldda.get_template_widgets( trans ) + return trans.fill_template( '/admin/library/ldda_info.mako', + ldda=ldda, + library_id=library_id, + show_deleted=show_deleted, + widgets=widgets, + msg=msg, + messagetype=messagetype ) + @web.expose + @web.require_admin + def ldda_manage_permissions( self, trans, library_id, folder_id, obj_id, **kwd ): + params = util.Params( kwd ) + msg = util.restore_text( params.get( 'msg', '' ) ) + messagetype = params.get( 'messagetype', 'done' ) + obj_ids = util.listify( obj_id ) + # Display permission form, permissions will be updated for all lddas simultaneously. + lddas = [] + for obj_id in [ int( obj_id ) for obj_id in obj_ids ]: + ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( obj_id ) + if ldda is None: + msg = 'You specified an invalid LibraryDatasetDatasetAssociation obj_id: %s' %str( obj_id ) + trans.response.send_redirect( web.url_for( controller='library_admin', + action='browse_library', + obj_id=library_id, + msg=util.sanitize_text( msg ), + messagetype='error' ) ) + lddas.append( ldda ) + if params.get( 'update_roles_button', False ): + permissions = {} + accessible = False + for k, v in trans.app.model.Dataset.permitted_actions.items(): + in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.get( k + '_in', [] ) ) ] + # At least 1 user must have every role associated with this dataset, or the dataset is inaccessible + if v == trans.app.security_agent.permitted_actions.DATASET_ACCESS: + if len( in_roles ) > 1: + # Get the set of all users that are being associated with the dataset + in_roles_set = set() + for role in in_roles: + in_roles_set.add( role ) + users_set = set() + for role in in_roles: + for ura in role.users: + users_set.add( ura.user ) + # Make sure that at least 1 user has every role being associated with the dataset + for user in users_set: + user_roles_set = set() + for ura in user.roles: + user_roles_set.add( ura.role ) + if in_roles_set.issubset( user_roles_set ): + accessible = True + break + else: + accessible = True + if not accessible and v == trans.app.security_agent.permitted_actions.DATASET_ACCESS: + # Don't set the permissions for DATASET_ACCESS if inaccessbile, but set all other permissions + # TODO: keep access permissions as they originally were, rather than automatically making public + permissions[ trans.app.security_agent.get_action( v.action ) ] = [] + else: + permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles + for ldda in lddas: + # Set the DATASET permissions on the Dataset + trans.app.security_agent.set_all_dataset_permissions( ldda.dataset, permissions ) + ldda.dataset.refresh() + permissions = {} + for k, v in trans.app.model.Library.permitted_actions.items(): + in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ] + permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles + for ldda in lddas: + # Set the LIBRARY permissions on the LibraryDataset + # NOTE: the LibraryDataset and LibraryDatasetDatasetAssociation will be set with the same permissions + trans.app.security_agent.set_all_library_permissions( ldda.library_dataset, permissions ) + ldda.library_dataset.refresh() + # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation + trans.app.security_agent.set_all_library_permissions( ldda, permissions ) + ldda.refresh() + if not accessible: + msg = "At least 1 user must have every role associated with accessing these %d datasets. " % len( lddas ) + msg += "The roles you attempted to associate for access would make these datasets inaccessible by everyone, " + msg += "so access permissions were not set. All other permissions were updated for the datasets." + messagetype = 'error' + else: + msg = "Permissions have been updated on %d datasets" % len( lddas ) + return trans.fill_template( "/admin/library/ldda_permissions.mako", + lddas=lddas, + library_id=library_id, + msg=msg, + messagetype=messagetype ) + if len( obj_ids ) > 1: + # Ensure that the permissions across all library items are identical, otherwise we can't update them together. + check_list = [] + for ldda in lddas: + permissions = [] + # Check the library level permissions - the permissions on the LibraryDatasetDatasetAssociation + # will always be the same as the permissions on the associated LibraryDataset, so we only need to + # check one Library object + for library_permission in trans.app.security_agent.get_library_dataset_permissions( ldda.library_dataset ): + if library_permission.action not in permissions: + permissions.append( library_permission.action ) + for dataset_permission in trans.app.security_agent.get_dataset_permissions( ldda.dataset ): + if dataset_permission.action not in permissions: + permissions.append( dataset_permission.action ) + permissions.sort() + if not check_list: + check_list = permissions + if permissions != check_list: + msg = 'The datasets you selected do not have identical permissions, so they can not be updated together' + trans.response.send_redirect( web.url_for( controller='library_admin', + action='browse_library', + obj_id=library_id, + msg=util.sanitize_text( msg ), + messagetype='error' ) ) + return trans.fill_template( "/admin/library/ldda_permissions.mako", + lddas=lddas, + library_id=library_id, + msg=msg, + messagetype=messagetype ) + @web.expose + @web.require_admin + def upload_library_dataset( self, trans, library_id, folder_id, **kwd ): params = util.Params( kwd ) msg = util.restore_text( params.get( 'msg', '' ) ) messagetype = params.get( 'messagetype', 'done' ) deleted = util.string_as_bool( params.get( 'deleted', False ) ) show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) ) - dbkey = params.get( 'dbkey', None ) + dbkey = params.get( 'dbkey', '?' ) if isinstance( dbkey, list ): last_used_build = dbkey[0] else: @@ -427,10 +675,6 @@ class LibraryAdmin( BaseController ): last_used_build = replace_dataset.library_dataset_dataset_association.dbkey else: replace_dataset = None - # Let's not overwrite the imported datatypes module with the variable datatypes? - # The built-in 'id' is overwritten in lots of places as well - ldatatypes = [ dtype_name for dtype_name, dtype_value in trans.app.datatypes_registry.datatypes_by_extension.iteritems() if dtype_value.allow_datatype_change ] - ldatatypes.sort() if params.get( 'runtool_btn', False ) or params.get( 'ajax_upload', False ): # See if we have any inherited templates, but do not inherit contents. info_association, inherited = folder.get_info_association( inherited=True ) @@ -441,7 +685,7 @@ class LibraryAdmin( BaseController ): template_id = 'None' widgets = [] upload_option = params.get( 'upload_option', 'upload_file' ) - created_outputs = trans.webapp.controllers[ 'library_dataset' ].upload_dataset( trans, + created_outputs = trans.webapp.controllers[ 'library_common' ].upload_dataset( trans, controller='library_admin', library_id=library_id, folder_id=folder_id, @@ -466,345 +710,44 @@ class LibraryAdmin( BaseController ): messagetype='error' trans.response.send_redirect( web.url_for( controller='library_admin', action='browse_library', - id=library_id, + obj_id=library_id, created_ldda_ids=",".join( [ str( v.id ) for v in created_outputs.values() ] ), msg=util.sanitize_text( msg ), messagetype=messagetype ) ) - elif not id or replace_dataset: - # See if we have any inherited templates, but do not inherit contents. - widgets = folder.get_template_widgets( trans, get_contents=False ) - upload_option = params.get( 'upload_option', 'upload_file' ) - # No dataset(s) specified, so display the upload form. Send list of data formats to the form - # so the "extension" select list can be populated dynamically - file_formats = trans.app.datatypes_registry.upload_file_formats - # Send list of genome builds to the form so the "dbkey" select list can be populated dynamically - def get_dbkey_options( last_used_build ): - for dbkey, build_name in util.dbnames: - yield build_name, dbkey, ( dbkey==last_used_build ) - dbkeys = get_dbkey_options( last_used_build ) - # Send list of roles to the form so the dataset can be associated with 1 or more of them. - roles = trans.app.model.Role.filter( trans.app.model.Role.table.c.deleted==False ).order_by( trans.app.model.Role.c.name ).all() - # Send the current history to the form to enable importing datasets from history to library - history = trans.get_history() - history.refresh() - # If we're using nginx upload, override the form action - action = web.url_for( controller='library_admin', action='library_dataset_dataset_association' ) - if upload_option == 'upload_file' and trans.app.config.nginx_upload_path: - action = web.url_for( trans.app.config.nginx_upload_path ) + '?nginx_redir=' + action - return trans.fill_template( '/admin/library/upload.mako', - upload_option=upload_option, - action=action, - library_id=library_id, - folder_id=folder_id, - replace_dataset=replace_dataset, - file_formats=file_formats, - dbkeys=dbkeys, - last_used_build=last_used_build, - roles=roles, - history=history, - widgets=widgets, - msg=msg, - messagetype=messagetype ) - else: - if params.get( 'permissions', False ): - action = 'permissions' - elif params.get( 'edit_info', False ): - action = 'edit_info' - else: - action = 'info' - if id.count( ',' ): - ids = id.split( ',' ) - id = None - else: - ids = None - if id: - # ldda_id specified, display attributes form - ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id ) - if not ldda: - msg = "Invalid LibraryDatasetDatasetAssociation specified, id: %s" % str( id ) - return trans.response.send_redirect( web.url_for( controller='library_admin', - action='browse_library', - id=library_id, - msg=util.sanitize_text( msg ), - messagetype='error' ) ) - # See if we have any associated templates - widgets = ldda.get_template_widgets( trans ) - if action == 'permissions': - if params.get( 'update_roles_button', False ): - permissions = {} - accessible = False - for k, v in trans.app.model.Dataset.permitted_actions.items(): - # TODO: need to handle case where a user has the DATASET_MANAGE_PERMISSIONS permission, but not - # the DATASET_ACCESS permission, making the former useless. Need to display a warning message. - in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.get( k + '_in', [] ) ) ] - # At least 1 user must have every role associated with this dataset, or the dataset is inaccessible - if v == trans.app.security_agent.permitted_actions.DATASET_ACCESS: - if len( in_roles ) > 1: - # Get the set of all users that are being associated with the dataset - in_roles_set = set() - for role in in_roles: - in_roles_set.add( role ) - users_set = set() - for role in in_roles: - for ura in role.users: - users_set.add( ura.user ) - # Make sure that at least 1 user has every role being associated with the dataset - for user in users_set: - user_roles_set = set() - for ura in user.roles: - user_roles_set.add( ura.role ) - if in_roles_set.issubset( user_roles_set ): - accessible = True - break - else: - accessible = True - if not accessible and v == trans.app.security_agent.permitted_actions.DATASET_ACCESS: - # Don't set the permissions for DATASET_ACCESS if inaccessbile, but set all other permissions - # TODO: keep access permissions as they originally were, rather than automatically making public - permissions[ trans.app.security_agent.get_action( v.action ) ] = [] - else: - permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles - # Set the DATASET permissions on the Dataset - trans.app.security_agent.set_all_dataset_permissions( ldda.dataset, permissions ) - ldda.dataset.refresh() - permissions = {} - for k, v in trans.app.model.Library.permitted_actions.items(): - in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ] - permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles - # Set the LIBRARY permissions on the LibraryDataset - # NOTE: the LibraryDataset and LibraryDatasetDatasetAssociation will be set with the same permissions - trans.app.security_agent.set_all_library_permissions( ldda.library_dataset, permissions ) - ldda.library_dataset.refresh() - # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation - trans.app.security_agent.set_all_library_permissions( ldda, permissions ) - ldda.refresh() - if not accessible: - msg = "At least 1 user must have every role associated with accessing dataset '%s'. " % ldda.name - msg += "The roles you attempted to associate for access would make this dataset inaccessible by everyone, " - msg += "so access permissions were not set. All other permissions were updated for the dataset." - messagetype = 'error' - else: - msg = "Permissions updated for dataset '%s'" % ldda.name - return trans.fill_template( '/admin/library/ldda_permissions.mako', - ldda=ldda, - library_id=library_id, - msg=msg, - messagetype=messagetype ) - elif action == 'info': - return trans.fill_template( '/admin/library/ldda_info.mako', - ldda=ldda, - library_id=library_id, - deleted=deleted, - show_deleted=show_deleted, - widgets=widgets, - msg=msg, - messagetype=messagetype ) - elif action == 'edit_info': - if params.get( 'change', False ): - # The user clicked the Save button on the 'Change data type' form - if ldda.datatype.allow_datatype_change and trans.app.datatypes_registry.get_datatype_by_extension( params.datatype ).allow_datatype_change: - trans.app.datatypes_registry.change_datatype( ldda, params.datatype ) - trans.app.model.flush() - msg = "Data type changed for library dataset '%s'" % ldda.name - return trans.fill_template( "/admin/library/ldda_edit_info.mako", - ldda=ldda, - library_id=library_id, - datatypes=ldatatypes, - widgets=widgets, - msg=msg, - messagetype=messagetype ) - else: - return trans.show_error_message( "You are unable to change datatypes in this manner. Changing %s to %s is not allowed." % ( ldda.extension, params.datatype ) ) - elif params.get( 'save', False ): - # The user clicked the Save button on the 'Edit Attributes' form - old_name = ldda.name - new_name = util.restore_text( params.get( 'name', '' ) ) - new_info = util.restore_text( params.get( 'info', '' ) ) - new_message = util.restore_text( params.get( 'message', '' ) ) - if not new_name: - msg = 'Enter a valid name' - messagetype = 'error' - else: - ldda.name = new_name - ldda.info = new_info - ldda.message = new_message - # The following for loop will save all metadata_spec items - for name, spec in ldda.datatype.metadata_spec.items(): - if spec.get("readonly"): - continue - optional = params.get( "is_" + name, None ) - if optional and optional == 'true': - # optional element... == 'true' actually means it is NOT checked (and therefore ommitted) - setattr( ldda.metadata, name, None ) - else: - setattr( ldda.metadata, name, spec.unwrap( params.get ( name, None ) ) ) - ldda.metadata.dbkey = dbkey - ldda.datatype.after_edit( ldda ) - trans.app.model.flush() - msg = 'Attributes updated for library dataset %s' % ldda.name - messagetype = 'done' - return trans.fill_template( "/admin/library/ldda_edit_info.mako", - ldda=ldda, - library_id=library_id, - datatypes=ldatatypes, - widgets=widgets, - msg=msg, - messagetype=messagetype ) - elif params.get( 'detect', False ): - # The user clicked the Auto-detect button on the 'Edit Attributes' form - for name, spec in ldda.datatype.metadata_spec.items(): - # We need to be careful about the attributes we are resetting - if name not in [ 'name', 'info', 'dbkey' ]: - if spec.get( 'default' ): - setattr( ldda.metadata, name, spec.unwrap( spec.get( 'default' ) ) ) - ldda.datatype.set_meta( ldda ) - ldda.datatype.after_edit( ldda ) - trans.app.model.flush() - msg = 'Attributes updated for library dataset %s' % ldda.name - return trans.fill_template( "/admin/library/ldda_edit_info.mako", - ldda=ldda, - library_id=library_id, - datatypes=ldatatypes, - widgets=widgets, - msg=msg, - messagetype=messagetype ) - elif params.get( 'delete', False ): - ldda.deleted = True - ldda.flush() - msg = 'Dataset %s has been removed from this library' % ldda.name - return trans.fill_template( "/admin/library/ldda_edit_info.mako", - ldda=ldda, - library_id=library_id, - datatypes=ldatatypes, - widgets=widgets, - msg=msg, - messagetype=messagetype ) - ldda.datatype.before_edit( ldda ) - if "dbkey" in ldda.datatype.metadata_spec and not ldda.metadata.dbkey: - # Copy dbkey into metadata, for backwards compatability - # This looks like it does nothing, but getting the dbkey - # returns the metadata dbkey unless it is None, in which - # case it resorts to the old dbkey. Setting the dbkey - # sets it properly in the metadata - ldda.metadata.dbkey = ldda.dbkey - return trans.fill_template( "/admin/library/ldda_edit_info.mako", - ldda=ldda, - library_id=library_id, - datatypes=ldatatypes, - widgets=widgets, - msg=msg, - messagetype=messagetype ) - elif ids: - # Multiple ids specfied, display permission form, permissions will be updated for all simultaneously. - lddas = [] - for id in [ int( id ) for id in ids ]: - ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id ) - if ldda is None: - msg = 'You specified an invalid LibraryDatasetDatasetAssociation id: %s' %str( id ) - trans.response.send_redirect( web.url_for( controller='library_admin', - action='browse_library', - id=library_id, - msg=util.sanitize_text( msg ), - messagetype='error' ) ) - lddas.append( ldda ) - if len( lddas ) < 2: - msg = 'You must specify at least two datasets on which to modify permissions, ids you sent: %s' % str( ids ) - trans.response.send_redirect( web.url_for( controller='library_admin', - action='browse_library', - id=library_id, - msg=util.sanitize_text( msg ), - messagetype='error' ) ) - if action == 'permissions': - if params.get( 'update_roles_button', False ): - permissions = {} - accessible = False - for k, v in trans.app.model.Dataset.permitted_actions.items(): - # TODO: need to handle case where a user has the DATASET_MANAGE_PERMISSIONS permission, but not - # the DATASET_ACCESS permission, making the former useless. Need to display a warning message. - in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.get( k + '_in', [] ) ) ] - # At least 1 user must have every role associated with this dataset, or the dataset is inaccessible - if v == trans.app.security_agent.permitted_actions.DATASET_ACCESS: - if len( in_roles ) > 1: - # Get the set of all users that are being associated with the dataset - in_roles_set = set() - for role in in_roles: - in_roles_set.add( role ) - users_set = set() - for role in in_roles: - for ura in role.users: - users_set.add( ura.user ) - # Make sure that at least 1 user has every role being associated with the dataset - for user in users_set: - user_roles_set = set() - for ura in user.roles: - user_roles_set.add( ura.role ) - if in_roles_set.issubset( user_roles_set ): - accessible = True - break - else: - accessible = True - if not accessible and v == trans.app.security_agent.permitted_actions.DATASET_ACCESS: - # Don't set the permissions for DATASET_ACCESS if inaccessbile, but set all other permissions - # TODO: keep access permissions as they originally were, rather than automatically making public - permissions[ trans.app.security_agent.get_action( v.action ) ] = [] - else: - permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles - for ldda in lddas: - # Set the DATASET permissions on the Dataset - trans.app.security_agent.set_all_dataset_permissions( ldda.dataset, permissions ) - ldda.dataset.refresh() - permissions = {} - for k, v in trans.app.model.Library.permitted_actions.items(): - in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ] - permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles - for ldda in lddas: - # Set the LIBRARY permissions on the LibraryDataset - # NOTE: the LibraryDataset and LibraryDatasetDatasetAssociation will be set with the same permissions - trans.app.security_agent.set_all_library_permissions( ldda.library_dataset, permissions ) - ldda.library_dataset.refresh() - # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation - trans.app.security_agent.set_all_library_permissions( ldda, permissions ) - ldda.refresh() - if not accessible: - msg = "At least 1 user must have every role associated with accessing these %d datasets. " % len( lddas ) - msg += "The roles you attempted to associate for access would make these datasets inaccessible by everyone, " - msg += "so access permissions were not set. All other permissions were updated for the datasets." - messagetype = 'error' - else: - msg = "Permissions have been updated on %d datasets" % len( lddas ) - return trans.fill_template( "/admin/library/ldda_permissions.mako", - ldda=lddas, - library_id=library_id, - msg=msg, - messagetype=messagetype ) - # Ensure that the permissions across all library items are identical, otherwise we can't update them together. - check_list = [] - for ldda in lddas: - permissions = [] - # Check the library level permissions - the permissions on the LibraryDatasetDatasetAssociation - # will always be the same as the permissions on the associated LibraryDataset, so we only need to - # check one Library object - for library_permission in trans.app.security_agent.get_library_dataset_permissions( ldda.library_dataset ): - if library_permission.action not in permissions: - permissions.append( library_permission.action ) - for dataset_permission in trans.app.security_agent.get_dataset_permissions( ldda.dataset ): - if dataset_permission.action not in permissions: - permissions.append( dataset_permission.action ) - permissions.sort() - if not check_list: - check_list = permissions - if permissions != check_list: - msg = 'The datasets you selected do not have identical permissions, so they can not be updated together' - trans.response.send_redirect( web.url_for( controller='library_admin', - action='browse_library', - id=library_id, - msg=util.sanitize_text( msg ), - messagetype='error' ) ) - return trans.fill_template( "/admin/library/ldda_permissions.mako", - ldda=lddas, - library_id=library_id, - msg=msg, - messagetype=messagetype ) + # See if we have any inherited templates, but do not inherit contents. + widgets = folder.get_template_widgets( trans, get_contents=False ) + upload_option = params.get( 'upload_option', 'upload_file' ) + # No dataset(s) specified, so display the upload form. Send list of data formats to the form + # so the "extension" select list can be populated dynamically + file_formats = trans.app.datatypes_registry.upload_file_formats + # Send list of genome builds to the form so the "dbkey" select list can be populated dynamically + def get_dbkey_options( last_used_build ): + for dbkey, build_name in util.dbnames: + yield build_name, dbkey, ( dbkey==last_used_build ) + dbkeys = get_dbkey_options( last_used_build ) + # Send list of roles to the form so the dataset can be associated with 1 or more of them. + roles = trans.app.model.Role.filter( trans.app.model.Role.table.c.deleted==False ).order_by( trans.app.model.Role.c.name ).all() + # Send the current history to the form to enable importing datasets from history to library + history = trans.get_history() + history.refresh() + # If we're using nginx upload, override the form action + action = web.url_for( controller='library_admin', action='upload_library_dataset' ) + if upload_option == 'upload_file' and trans.app.config.nginx_upload_path: + action = web.url_for( trans.app.config.nginx_upload_path ) + '?nginx_redir=' + action + return trans.fill_template( '/admin/library/upload.mako', + upload_option=upload_option, + action=action, + library_id=library_id, + folder_id=folder_id, + replace_dataset=replace_dataset, + file_formats=file_formats, + dbkeys=dbkeys, + last_used_build=last_used_build, + roles=roles, + history=history, + widgets=widgets, + msg=msg, + messagetype=messagetype ) @web.expose @web.require_admin def add_history_datasets_to_library( self, trans, library_id, folder_id, hda_ids='', **kwd ): @@ -817,7 +760,7 @@ class LibraryAdmin( BaseController ): msg = "Invalid folder id: %s" % str( folder_id ) return trans.response.send_redirect( web.url_for( controller='library_admin', action='browse_library', - id=library_id, + obj_id=library_id, msg=util.sanitize_text( msg ), messagetype='error' ) ) replace_id = params.get( 'replace_id', None ) @@ -832,7 +775,7 @@ class LibraryAdmin( BaseController ): msg = 'Your current history is empty' return trans.response.send_redirect( web.url_for( controller='library_admin', action='browse_library', - id=library_id, + obj_id=library_id, msg=util.sanitize_text( msg ), messagetype='error' ) ) if params.get( 'add_history_datasets_to_library_button', False ): @@ -857,7 +800,7 @@ class LibraryAdmin( BaseController ): msg = "The requested HistoryDatasetAssociation id %s is invalid" % str( hda_id ) return trans.response.send_redirect( web.url_for( controller='library_admin', action='browse_library', - id=library_id, + obj_id=library_id, msg=util.sanitize_text( msg ), messagetype='error' ) ) if created_ldda_ids: @@ -875,7 +818,7 @@ class LibraryAdmin( BaseController ): msg += "Click the Go button at the bottom of this page to edit the permissions on these datasets if necessary." return trans.response.send_redirect( web.url_for( controller='library_admin', action='browse_library', - id=library_id, + obj_id=library_id, created_ldda_ids=created_ldda_ids, msg=util.sanitize_text( msg ), messagetype='done' ) ) @@ -908,146 +851,15 @@ class LibraryAdmin( BaseController ): messagetype=messagetype ) @web.expose @web.require_admin - def info_template( self, trans, library_id, id=None, folder_id=None, ldda_id=None, **kwd ): - params = util.Params( kwd ) - msg = util.restore_text( params.get( 'msg', '' ) ) - messagetype = params.get( 'messagetype', 'done' ) - if id: - library_item = trans.app.model.FormDefinition.get( int( id ) ) - library_item_desc = 'information template' - response_action = 'info_template' - response_id = id - elif folder_id: - library_item = trans.app.model.LibraryFolder.get( int( folder_id ) ) - library_item_desc = 'folder' - response_action = 'folder' - response_id = folder_id - elif ldda_id: - library_item = trans.app.model.LibraryDatasetDatasetAssociation.get( int( ldda_id ) ) - library_item_desc = 'library dataset' - response_action = 'library_dataset_dataset_association' - response_id = ldda_id - else: - library_item = trans.app.model.Library.get( int( library_id ) ) - library_item_desc = 'library' - response_action = 'browse_library' - response_id = library_id - forms = get_all_forms( trans, - filter=dict( deleted=False ), - form_type=trans.app.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE ) - if not forms: - msg = "There are no forms on which to base the template, so create a form and " - msg += "try again to add the information template to the %s." % library_item_desc - trans.response.send_redirect( web.url_for( controller='forms', - action='new', - new=True, - msg=msg, - messagetype='done' ) ) - if params.get( 'add', False ): - if params.get( 'add_info_template_button', False ): - form = trans.app.model.FormDefinition.get( int( kwd[ 'form_id' ] ) ) - #fields = list( copy.deepcopy( form.fields ) ) - form_values = trans.app.model.FormValues( form, [] ) - form_values.flush() - if folder_id: - assoc = trans.app.model.LibraryFolderInfoAssociation( library_item, form, form_values ) - elif ldda_id: - assoc = trans.app.model.LibraryDatasetDatasetInfoAssociation( library_item, form, form_values ) - else: - assoc = trans.app.model.LibraryInfoAssociation( library_item, form, form_values ) - assoc.flush() - msg = 'An information template based on the form "%s" has been added to this %s.' % ( form.name, library_item_desc ) - trans.response.send_redirect( web.url_for( controller='library_admin', - action=response_action, - id=response_id, - msg=msg, - message_type='done' ) ) - return trans.fill_template( '/admin/library/select_info_template.mako', - library_item_name=library_item.name, - library_item_desc=library_item_desc, - library_id=library_id, - folder_id=folder_id, - ldda_id=ldda_id, - forms=forms, - msg=msg, - messagetype=messagetype ) - @web.expose - @web.require_admin - def edit_template_info( self, trans, library_id, num_widgets, library_item_id=None, library_item_type=None, **kwd ): - params = util.Params( kwd ) - msg = util.restore_text( params.get( 'msg', '' ) ) - messagetype = params.get( 'messagetype', 'done' ) - folder_id = None - if library_item_type == 'library': - library_item = trans.app.model.Library.get( library_item_id ) - elif library_item_type == 'library_dataset': - library_item = trans.app.model.LibraryDataset.get( library_item_id ) - elif library_item_type == 'folder': - library_item = trans.app.model.LibraryFolder.get( library_item_id ) - elif library_item_type == 'library_dataset_dataset_association': - library_item = trans.app.model.LibraryDatasetDatasetAssociation.get( library_item_id ) - # This response_action method requires a folder_id - folder_id = library_item.library_dataset.folder.id - else: - msg = "Invalid library item type ( %s ) specified, id ( %s )" % ( str( library_item_type ), str( library_item_id ) ) - return trans.response.send_redirect( web.url_for( controller='library_admin', - action='browse_library', - id=library_id, - msg=util.sanitize_text( msg ), - messagetype='error' ) ) - # Save updated template field contents - field_contents = [] - for index in range( int( num_widgets ) ): - field_contents.append( util.restore_text( params.get( 'field_%i' % ( index ), '' ) ) ) - if field_contents: - # Since information templates are inherited, the template fields can be displayed on the information - # page for a folder or library dataset when it has no info_association object. If the user has added - # field contents on an inherited template via a parent's info_association, we'll need to create a new - # form_values and info_association for the current object. The value for the returned inherited variable - # is not applicable at this level. - info_association, inherited = library_item.get_info_association( restrict=True ) - if info_association: - template = info_association.template - info = info_association.info - form_values = trans.app.model.FormValues.get( info.id ) - # Update existing content only if it has changed - if form_values.content != field_contents: - form_values.content = field_contents - form_values.flush() - else: - # Inherit the next available info_association so we can get the template - info_association, inherited = library_item.get_info_association() - template = info_association.template - # Create a new FormValues object - form_values = trans.app.model.FormValues( template, field_contents ) - form_values.flush() - # Create a new info_association between the current library item and form_values - if library_item_type == 'folder': - info_association = trans.app.model.LibraryFolderInfoAssociation( library_item, template, form_values ) - info_association.flush() - elif library_item_type == 'library_dataset_dataset_association': - info_association = trans.app.model.LibraryDatasetDatasetInfoAssociation( library_item, template, form_values ) - info_association.flush() - msg = 'The information has been updated.' - return trans.response.send_redirect( web.url_for( controller='library_admin', - action=library_item_type, - id=library_item.id, - library_id=library_id, - folder_id=folder_id, - edit_info=True, - msg=util.sanitize_text( msg ), - messagetype='done' ) ) - @web.expose - @web.require_admin - def download_dataset_from_folder(self, trans, id, library_id=None, **kwd): + def download_dataset_from_folder(self, trans, obj_id, library_id=None, **kwd): """Catches the dataset id and displays file contents as directed""" # id must refer to a LibraryDatasetDatasetAssociation object - ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id ) + ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( obj_id ) if not ldda.dataset: - msg = 'Invalid LibraryDatasetDatasetAssociation id %s received for file downlaod' % str( id ) + msg = 'Invalid LibraryDatasetDatasetAssociation id %s received for file downlaod' % str( obj_id ) return trans.response.send_redirect( web.url_for( controller='library_admin', action='browse_library', - id=library_id, + obj_id=library_id, msg=util.sanitize_text( msg ), messagetype='error' ) ) mime = trans.app.datatypes_registry.get_mimetype_by_extension( ldda.extension.lower() ) @@ -1057,14 +869,14 @@ class LibraryAdmin( BaseController ): valid_chars = '.,^_-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' fname = ldda.name fname = ''.join( c in valid_chars and c or '_' for c in fname )[ 0:150 ] - trans.response.headers[ "Content-Disposition" ] = "attachment; filename=GalaxyLibraryDataset-%s-[%s]" % ( str( id ), fname ) + trans.response.headers[ "Content-Disposition" ] = "attachment; filename=GalaxyLibraryDataset-%s-[%s]" % ( str( obj_id ), fname ) try: return open( ldda.file_name ) except: msg = 'This dataset contains no content' return trans.response.send_redirect( web.url_for( controller='library_admin', action='browse_library', - id=library_id, + obj_id=library_id, msg=util.sanitize_text( msg ), messagetype='error' ) ) @web.expose @@ -1076,48 +888,40 @@ class LibraryAdmin( BaseController ): msg = util.restore_text( params.get( 'msg', '' ) ) messagetype = params.get( 'messagetype', 'done' ) if params.get( 'action_on_datasets_button', False ): - if not params.ldda_ids: + ldda_ids = util.listify( params.get( 'ldda_ids', None ) ) + if not ldda_ids: msg = "At least one dataset must be selected for %s" % params.action trans.response.send_redirect( web.url_for( controller='library_admin', action='browse_library', - id=library_id, + obj_id=library_id, msg=util.sanitize_text( msg ), messagetype='error' ) ) - ldda_ids = util.listify( params.ldda_ids ) - if params.action == 'edit': + if params.action == 'manage_permissions': # We need the folder containing the LibraryDatasetDatasetAssociation(s) - ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( ldda_ids[0] ) + ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( int( ldda_ids[0] ) ) trans.response.send_redirect( web.url_for( controller='library_admin', - action='library_dataset_dataset_association', + action='ldda_manage_permissions', library_id=library_id, folder_id=ldda.library_dataset.folder.id, - id=",".join( ldda_ids ), - permissions=True, + obj_id=",".join( ldda_ids ), msg=util.sanitize_text( msg ), messagetype=messagetype ) ) elif params.action == 'delete': - for id in ldda_ids: - ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id ) + for ldda_id in ldda_ids: + ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( ldda_id ) ldda.deleted = True ldda.flush() - msg = "The selected datasets have been removed from this library" + msg = "The selected datasets have been removed from this data library" trans.response.send_redirect( web.url_for( controller='library_admin', action='browse_library', - id=library_id, + obj_id=library_id, show_deleted=False, msg=util.sanitize_text( msg ), messagetype='done' ) ) - else: - msg = "Action %s is not yet implemented" % str( params.action ) - trans.response.send_redirect( web.url_for( controller='library_admin', - action='browse_library', - id=library_id, - msg=util.sanitize_text( msg ), - messagetype='error' ) ) else: trans.response.send_redirect( web.url_for( controller='library_admin', action='browse_library', - id=library_id, + obj_id=library_id, msg=util.sanitize_text( msg ), messagetype=messagetype ) ) @web.expose @@ -1149,7 +953,10 @@ class LibraryAdmin( BaseController ): if library_item_type == 'library': return self.browse_libraries( trans, msg=msg, messagetype=messagetype ) else: - return self.browse_library( trans, id=library_id , msg=msg, messagetype=messagetype ) + return self.browse_library( trans, + obj_id=library_id, + msg=msg, + messagetype=messagetype ) @web.expose @web.require_admin def undelete_library_item( self, trans, library_id, library_item_id, library_item_type ): @@ -1177,4 +984,7 @@ class LibraryAdmin( BaseController ): if library_item_type == 'library': return self.browse_libraries( trans, msg=msg, messagetype=messagetype ) else: - return self.browse_library( trans, id=library_id , msg=msg, messagetype=messagetype ) + return self.browse_library( trans, + obj_id=library_id, + msg=msg, + messagetype=messagetype ) diff --git a/lib/galaxy/web/controllers/library_common.py b/lib/galaxy/web/controllers/library_common.py new file mode 100644 index 00000000000..aa9e56322bd --- /dev/null +++ b/lib/galaxy/web/controllers/library_common.py @@ -0,0 +1,300 @@ +import os, os.path, shutil, urllib, StringIO, re, gzip, tempfile, shutil, zipfile +from galaxy.web.base.controller import * +from galaxy import util, jobs +from galaxy.datatypes import sniff +from galaxy.security import RBACAgent +from galaxy.util.json import to_json_string +from galaxy.tools.actions import upload_common +from galaxy.web.controllers.forms import get_all_forms +from galaxy.model.orm import * + +log = logging.getLogger( __name__ ) + +class LibraryCommon( BaseController ): + @web.json + def library_item_updates( self, trans, ids=None, states=None ): + # Avoid caching + trans.response.headers['Pragma'] = 'no-cache' + trans.response.headers['Expires'] = '0' + # Create new HTML for any that have changed + rval = {} + if ids is not None and states is not None: + ids = map( int, ids.split( "," ) ) + states = states.split( "," ) + for id, state in zip( ids, states ): + data = self.app.model.LibraryDatasetDatasetAssociation.get( id ) + if data.state != state: + job_ldda = data + while job_ldda.copied_from_library_dataset_dataset_association: + job_ldda = job_ldda.copied_from_library_dataset_dataset_association + force_history_refresh = False + rval[id] = { + "state": data.state, + "html": unicode( trans.fill_template( "library/library_item_info.mako", ldda=data ), 'utf-8' ) + #"force_history_refresh": force_history_refresh + } + return rval + def upload_dataset( self, trans, controller, library_id, folder_id, replace_dataset=None, **kwd ): + # Set up the traditional tool state/params + tool_id = 'upload1' + tool = trans.app.toolbox.tools_by_id[ tool_id ] + state = tool.new_state( trans ) + errors = tool.update_state( trans, tool.inputs_by_page[0], state.inputs, kwd, changed_dependencies={} ) + tool_params = state.inputs + dataset_upload_inputs = [] + for input_name, input in tool.inputs.iteritems(): + if input.type == "upload_dataset": + dataset_upload_inputs.append( input ) + # Library-specific params + params = util.Params( kwd ) # is this filetoolparam safe? + library_bunch = upload_common.handle_library_params( trans, params, folder_id, replace_dataset ) + msg = util.restore_text( params.get( 'msg', '' ) ) + messagetype = params.get( 'messagetype', 'done' ) + server_dir = util.restore_text( params.get( 'server_dir', '' ) ) + if replace_dataset not in [ None, 'None' ]: + replace_id = replace_dataset.id + else: + replace_id = None + upload_option = params.get( 'upload_option', 'upload_file' ) + err_redirect = False + if upload_option == 'upload_directory': + if server_dir in [ None, 'None', '' ]: + err_redirect = True + if controller == 'library_admin': + import_dir = trans.app.config.library_import_dir + import_dir_desc = 'library_import_dir' + full_dir = os.path.join( import_dir, server_dir ) + else: + import_dir = trans.app.config.user_library_import_dir + import_dir_desc = 'user_library_import_dir' + if server_dir == trans.user.email: + full_dir = os.path.join( import_dir, server_dir ) + else: + full_dir = os.path.join( import_dir, trans.user.email, server_dir ) + if import_dir: + msg = 'Select a directory' + else: + msg = '"%s" is not defined in the Galaxy configuration file' % import_dir_desc + # Proceed with (mostly) regular upload processing + precreated_datasets = upload_common.get_precreated_datasets( trans, tool_params, trans.app.model.LibraryDatasetDatasetAssociation, controller=controller ) + if upload_option == 'upload_file': + tool_params = upload_common.persist_uploads( tool_params ) + uploaded_datasets = upload_common.get_uploaded_datasets( trans, tool_params, precreated_datasets, dataset_upload_inputs, library_bunch=library_bunch ) + elif upload_option == 'upload_directory': + uploaded_datasets = self.get_server_dir_uploaded_datasets( trans, params, full_dir, import_dir_desc, library_bunch, err_redirect, msg ) + upload_common.cleanup_unused_precreated_datasets( precreated_datasets ) + if upload_option == 'upload_file' and not uploaded_datasets: + msg = 'Select a file, enter a URL or enter text' + err_redirect = True + if err_redirect: + trans.response.send_redirect( web.url_for( controller=controller, + action='upload_library_dataset', + library_id=library_id, + folder_id=folder_id, + replace_id=replace_id, + upload_option=upload_option, + msg=util.sanitize_text( msg ), + messagetype='error' ) ) + json_file_path = upload_common.create_paramfile( uploaded_datasets ) + data_list = [ ud.data for ud in uploaded_datasets ] + return upload_common.create_job( trans, tool_params, tool, json_file_path, data_list, folder=library_bunch.folder ) + def get_server_dir_uploaded_datasets( self, trans, params, full_dir, import_dir_desc, library_bunch, err_redirect, msg ): + files = [] + try: + for entry in os.listdir( full_dir ): + # Only import regular files + if os.path.isfile( os.path.join( full_dir, entry ) ): + files.append( entry ) + except Exception, e: + msg = "Unable to get file list for configured %s, error: %s" % ( import_dir_desc, str( e ) ) + err_redirect = True + return None + if not files: + msg = "The directory '%s' contains no valid files" % full_dir + err_redirect = True + return None + uploaded_datasets = [] + for file in files: + library_bunch.replace_dataset = None + uploaded_dataset = util.bunch.Bunch() + uploaded_dataset.path = os.path.join( full_dir, file ) + if not os.path.isfile( uploaded_dataset.path ): + continue + uploaded_dataset.type = 'server_dir' + uploaded_dataset.name = file + uploaded_dataset.ext = None + uploaded_dataset.file_type = params.file_type + uploaded_dataset.dbkey = params.dbkey + uploaded_dataset.space_to_tab = params.space_to_tab + uploaded_dataset.data = upload_common.new_upload( trans, uploaded_dataset, library_bunch ) + uploaded_datasets.append( uploaded_dataset ) + return uploaded_datasets + @web.expose + def info_template( self, trans, cntrller, library_id, response_action='library', obj_id=None, folder_id=None, ldda_id=None, **kwd ): + # Only adding a new templAte to a library or folder is currently allowed. Editing an existing template is + # a future enhancement. The response_action param is the name of the method to which this method will redirect + # if a new template is being added to a library or folder. + params = util.Params( kwd ) + msg = util.restore_text( params.get( 'msg', '' ) ) + messagetype = params.get( 'messagetype', 'done' ) + if obj_id: + library_item = trans.app.model.FormDefinition.get( int( obj_id ) ) + library_item_desc = 'information template' + response_id = obj_id + elif folder_id: + library_item = trans.app.model.LibraryFolder.get( int( folder_id ) ) + library_item_desc = 'folder' + response_id = folder_id + elif ldda_id: + library_item = trans.app.model.LibraryDatasetDatasetAssociation.get( int( ldda_id ) ) + library_item_desc = 'library dataset' + response_id = ldda_id + else: + library_item = trans.app.model.Library.get( int( library_id ) ) + library_item_desc = 'library' + response_id = library_id + forms = get_all_forms( trans, + filter=dict( deleted=False ), + form_type=trans.app.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE ) + if not forms: + msg = "There are no forms on which to base the template, so create a form and " + msg += "try again to add the information template to the %s." % library_item_desc + trans.response.send_redirect( web.url_for( controller='forms', + action='new', + new=True, + msg=msg, + messagetype='done' ) ) + if params.get( 'add_info_template_button', False ): + form = trans.app.model.FormDefinition.get( int( kwd[ 'form_id' ] ) ) + #fields = list( copy.deepcopy( form.fields ) ) + form_values = trans.app.model.FormValues( form, [] ) + form_values.flush() + if folder_id: + assoc = trans.app.model.LibraryFolderInfoAssociation( library_item, form, form_values ) + elif ldda_id: + assoc = trans.app.model.LibraryDatasetDatasetInfoAssociation( library_item, form, form_values ) + else: + assoc = trans.app.model.LibraryInfoAssociation( library_item, form, form_values ) + assoc.flush() + msg = 'An information template based on the form "%s" has been added to this %s.' % ( form.name, library_item_desc ) + trans.response.send_redirect( web.url_for( controller=cntrller, + action=response_action, + obj_id=response_id, + msg=msg, + message_type='done' ) ) + # TODO: handle this better + if cntrller == 'library_admin': + tmplt = '/admin/library/select_info_template.mako' + else: + tmplt = '/ibrary/select_info_template.mako' + return trans.fill_template( tmplt, + library_item_name=library_item.name, + library_item_desc=library_item_desc, + library_id=library_id, + folder_id=folder_id, + ldda_id=ldda_id, + forms=forms, + msg=msg, + messagetype=messagetype ) + @web.expose + def edit_template_info( self, trans, cntrller, library_id, response_action, num_widgets, library_item_id=None, library_item_type=None, **kwd ): + params = util.Params( kwd ) + msg = util.restore_text( params.get( 'msg', '' ) ) + messagetype = params.get( 'messagetype', 'done' ) + folder_id = None + if library_item_type == 'library': + library_item = trans.app.model.Library.get( library_item_id ) + elif library_item_type == 'library_dataset': + library_item = trans.app.model.LibraryDataset.get( library_item_id ) + elif library_item_type == 'folder': + library_item = trans.app.model.LibraryFolder.get( library_item_id ) + elif library_item_type == 'library_dataset_dataset_association': + library_item = trans.app.model.LibraryDatasetDatasetAssociation.get( library_item_id ) + # This response_action method requires a folder_id + folder_id = library_item.library_dataset.folder.id + else: + msg = "Invalid library item type ( %s ) specified, id ( %s )" % ( str( library_item_type ), str( library_item_id ) ) + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='browse_library', + obj_id=library_id, + msg=util.sanitize_text( msg ), + messagetype='error' ) ) + # Save updated template field contents + field_contents = [] + for index in range( int( num_widgets ) ): + field_contents.append( util.restore_text( params.get( 'field_%i' % ( index ), '' ) ) ) + if field_contents: + # Since information templates are inherited, the template fields can be displayed on the information + # page for a folder or library dataset when it has no info_association object. If the user has added + # field contents on an inherited template via a parent's info_association, we'll need to create a new + # form_values and info_association for the current object. The value for the returned inherited variable + # is not applicable at this level. + info_association, inherited = library_item.get_info_association( restrict=True ) + if info_association: + template = info_association.template + info = info_association.info + form_values = trans.app.model.FormValues.get( info.id ) + # Update existing content only if it has changed + if form_values.content != field_contents: + form_values.content = field_contents + form_values.flush() + else: + # Inherit the next available info_association so we can get the template + info_association, inherited = library_item.get_info_association() + template = info_association.template + # Create a new FormValues object + form_values = trans.app.model.FormValues( template, field_contents ) + form_values.flush() + # Create a new info_association between the current library item and form_values + if library_item_type == 'folder': + info_association = trans.app.model.LibraryFolderInfoAssociation( library_item, template, form_values ) + info_association.flush() + elif library_item_type == 'library_dataset_dataset_association': + info_association = trans.app.model.LibraryDatasetDatasetInfoAssociation( library_item, template, form_values ) + info_association.flush() + msg = 'The information has been updated.' + return trans.response.send_redirect( web.url_for( controller=cntrller, + action=response_action, + library_id=library_id, + folder_id=folder_id, + obj_id=library_item.id, + msg=util.sanitize_text( msg ), + messagetype='done' ) ) + +# ---- Utility methods ------------------------------------------------------- + +def active_folders( trans, folder ): + # Much faster way of retrieving all active sub-folders within a given folder than the + # performance of the mapper. This query also eagerloads the permissions on each folder. + return trans.sa_session.query( trans.app.model.LibraryFolder ) \ + .filter_by( parent=folder, deleted=False ) \ + .options( eagerload_all( "actions" ) ) \ + .order_by( trans.app.model.LibraryFolder.table.c.name ) \ + .all() +def activatable_folders( trans, folder ): + return trans.sa_session.query( trans.app.model.LibraryFolder ) \ + .filter_by( parent=folder, purged=False ) \ + .options( eagerload_all( "actions" ) ) \ + .order_by( trans.app.model.LibraryFolder.table.c.name ) \ + .all() +def active_folders_and_lddas( trans, folder ): + folders = active_folders( trans, folder ) + # This query is much faster than the folder.active_library_datasets property + lddas = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ) \ + .filter_by( deleted=False ) \ + .join( "library_dataset" ) \ + .filter( trans.app.model.LibraryDataset.table.c.folder_id==folder.id ) \ + .order_by( trans.app.model.LibraryDatasetDatasetAssociation.table.c.name ) \ + .all() + return folders, lddas +def activatable_folders_and_lddas( trans, folder ): + folders = activatable_folders( trans, folder ) + # This query is much faster than the folder.activatable_library_datasets property + lddas = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ) \ + .join( "library_dataset" ) \ + .filter( trans.app.model.LibraryDataset.table.c.folder_id==folder.id ) \ + .join( "dataset" ) \ + .filter( trans.app.model.Dataset.table.c.deleted==False ) \ + .order_by( trans.app.model.LibraryDatasetDatasetAssociation.table.c.name ) \ + .all() + return folders, lddas diff --git a/lib/galaxy/web/controllers/library_dataset.py b/lib/galaxy/web/controllers/library_dataset.py deleted file mode 100644 index 58969890f34..00000000000 --- a/lib/galaxy/web/controllers/library_dataset.py +++ /dev/null @@ -1,129 +0,0 @@ -import os, os.path, shutil, urllib, StringIO, re, gzip, tempfile, shutil, zipfile -from galaxy.web.base.controller import * -from galaxy import util, jobs -from galaxy.datatypes import sniff -from galaxy.security import RBACAgent -from galaxy.util.json import to_json_string -from galaxy.tools.actions import upload_common - -log = logging.getLogger( __name__ ) - -class UploadLibraryDataset( BaseController ): - @web.json - def library_item_updates( self, trans, ids=None, states=None ): - # Avoid caching - trans.response.headers['Pragma'] = 'no-cache' - trans.response.headers['Expires'] = '0' - # Create new HTML for any that have changed - rval = {} - if ids is not None and states is not None: - ids = map( int, ids.split( "," ) ) - states = states.split( "," ) - for id, state in zip( ids, states ): - data = self.app.model.LibraryDatasetDatasetAssociation.get( id ) - if data.state != state: - job_ldda = data - while job_ldda.copied_from_library_dataset_dataset_association: - job_ldda = job_ldda.copied_from_library_dataset_dataset_association - force_history_refresh = False - rval[id] = { - "state": data.state, - "html": unicode( trans.fill_template( "library/library_item_info.mako", ldda=data ), 'utf-8' ) - #"force_history_refresh": force_history_refresh - } - return rval - def upload_dataset( self, trans, controller, library_id, folder_id, replace_dataset=None, **kwd ): - # Set up the traditional tool state/params - tool_id = 'upload1' - tool = trans.app.toolbox.tools_by_id[ tool_id ] - state = tool.new_state( trans ) - errors = tool.update_state( trans, tool.inputs_by_page[0], state.inputs, kwd, changed_dependencies={} ) - tool_params = state.inputs - dataset_upload_inputs = [] - for input_name, input in tool.inputs.iteritems(): - if input.type == "upload_dataset": - dataset_upload_inputs.append( input ) - # Library-specific params - params = util.Params( kwd ) # is this filetoolparam safe? - library_bunch = upload_common.handle_library_params( trans, params, folder_id, replace_dataset ) - msg = util.restore_text( params.get( 'msg', '' ) ) - messagetype = params.get( 'messagetype', 'done' ) - server_dir = util.restore_text( params.get( 'server_dir', '' ) ) - if replace_dataset not in [ None, 'None' ]: - replace_id = replace_dataset.id - else: - replace_id = None - upload_option = params.get( 'upload_option', 'upload_file' ) - err_redirect = False - if upload_option == 'upload_directory': - if server_dir in [ None, 'None', '' ]: - err_redirect = True - if controller == 'library_admin': - import_dir = trans.app.config.library_import_dir - import_dir_desc = 'library_import_dir' - full_dir = os.path.join( import_dir, server_dir ) - else: - import_dir = trans.app.config.user_library_import_dir - import_dir_desc = 'user_library_import_dir' - if server_dir == trans.user.email: - full_dir = os.path.join( import_dir, server_dir ) - else: - full_dir = os.path.join( import_dir, trans.user.email, server_dir ) - if import_dir: - msg = 'Select a directory' - else: - msg = '"%s" is not defined in the Galaxy configuration file' % import_dir_desc - # Proceed with (mostly) regular upload processing - precreated_datasets = upload_common.get_precreated_datasets( trans, tool_params, trans.app.model.LibraryDatasetDatasetAssociation, controller=controller ) - if upload_option == 'upload_file': - tool_params = upload_common.persist_uploads( tool_params ) - uploaded_datasets = upload_common.get_uploaded_datasets( trans, tool_params, precreated_datasets, dataset_upload_inputs, library_bunch=library_bunch ) - elif upload_option == 'upload_directory': - uploaded_datasets = self.get_server_dir_uploaded_datasets( trans, params, full_dir, import_dir_desc, library_bunch, err_redirect, msg ) - upload_common.cleanup_unused_precreated_datasets( precreated_datasets ) - if upload_option == 'upload_file' and not uploaded_datasets: - msg = 'Select a file, enter a URL or enter text' - err_redirect = True - if err_redirect: - trans.response.send_redirect( web.url_for( controller=controller, - action='library_dataset_dataset_association', - library_id=library_id, - folder_id=folder_id, - replace_id=replace_id, - upload_option=upload_option, - msg=util.sanitize_text( msg ), - messagetype='error' ) ) - json_file_path = upload_common.create_paramfile( uploaded_datasets ) - data_list = [ ud.data for ud in uploaded_datasets ] - return upload_common.create_job( trans, tool_params, tool, json_file_path, data_list, folder=library_bunch.folder ) - def get_server_dir_uploaded_datasets( self, trans, params, full_dir, import_dir_desc, library_bunch, err_redirect, msg ): - files = [] - try: - for entry in os.listdir( full_dir ): - # Only import regular files - if os.path.isfile( os.path.join( full_dir, entry ) ): - files.append( entry ) - except Exception, e: - msg = "Unable to get file list for configured %s, error: %s" % ( import_dir_desc, str( e ) ) - err_redirect = True - return None - if not files: - msg = "The directory '%s' contains no valid files" % full_dir - err_redirect = True - return None - uploaded_datasets = [] - for file in files: - library_bunch.replace_dataset = None - uploaded_dataset = util.bunch.Bunch() - uploaded_dataset.path = os.path.join( full_dir, file ) - if not os.path.isfile( uploaded_dataset.path ): - continue - uploaded_dataset.type = 'server_dir' - uploaded_dataset.name = file - uploaded_dataset.ext = None - uploaded_dataset.file_type = params.file_type - uploaded_dataset.dbkey = params.dbkey - uploaded_dataset.space_to_tab = params.space_to_tab - uploaded_dataset.data = upload_common.new_upload( trans, uploaded_dataset, library_bunch ) - uploaded_datasets.append( uploaded_dataset ) - return uploaded_datasets diff --git a/templates/admin/center.mako b/templates/admin/center.mako index 47a9e544ae8..29fcd42bf3f 100644 --- a/templates/admin/center.mako +++ b/templates/admin/center.mako @@ -37,7 +37,7 @@ users (a library item is one of: a data library, a library folder, a library dataset).

diff --git a/templates/admin/library/browse_libraries.mako b/templates/admin/library/browse_libraries.mako index afbced1a4d6..4cef22358f0 100644 --- a/templates/admin/library/browse_libraries.mako +++ b/templates/admin/library/browse_libraries.mako @@ -42,7 +42,7 @@ %for library in libraries: - ${library.name} + ${library.name} ${library.description} %endfor diff --git a/templates/admin/library/browse_library.mako b/templates/admin/library/browse_library.mako index cd9561182d4..c7c33e7548b 100644 --- a/templates/admin/library/browse_library.mako +++ b/templates/admin/library/browse_library.mako @@ -4,7 +4,7 @@ <% from time import strftime from galaxy import util - from galaxy.web.controllers.library import active_folders_and_lddas, activatable_folders_and_lddas + from galaxy.web.controllers.library_common import active_folders_and_lddas, activatable_folders_and_lddas %> <%def name="stylesheets()"> @@ -128,18 +128,16 @@ %endif - ${ldda.name[:50]} + ${ldda.name[:50]} %if not library.deleted and not folder.deleted and not library_dataset.deleted:
- Edit this dataset's information - ## We're disabling the ability to add templates at the LDDA and LibraryDataset level, but will leave this here for possible future use - ##Add an information template to this dataset - Edit this dataset's permissions - Upload a new version of this dataset + Edit this dataset's information + Edit this dataset's permissions + Upload a new version of this dataset %if ldda.has_data: - Download this dataset + Download this dataset %endif Delete this dataset
@@ -186,18 +184,18 @@ %endif %if not folder.deleted:
- Add datasets to this folder - Create a new sub-folder in this folder - Edit this folder's information + Add datasets to this folder + Create a new sub-folder in this folder + Edit this folder's information ## Editing templates disabled until we determine optimal approach to re-linking library item to new version of form definition ##%if folder.info_association: ## <% form_id = folder.info_association[0].template.id %> ## Edit this folder's information template ##%else: %if not folder.info_association: - Add an information template to this folder + Add an information template to this folder %endif - Edit this folder's permissions + Edit this folder's permissions Delete this folder and its contents
%elif not deleted and folder.deleted and not folder.purged: @@ -246,10 +244,10 @@ @@ -274,21 +272,21 @@
%if not deleted: - Edit this data library's information + Edit this data library's information ## Editing templates disabled until we determine optimal approach to re-linking library item to new version of form definition ##%if library.info_association: ## <% form_id = library.info_association[0].template.id %> ## Edit this data library's information template ##%else: %if not library.info_association: - Add an information template to this data library + Add an information template to this data library %endif - Edit this data library's permissions + Edit this data library's permissions Delete this data library and its contents %if show_deleted: - Hide deleted data library items + Hide deleted data library items %else: - Show deleted data library items + Show deleted data library items %endif %elif not library.purged: Undelete this data library @@ -310,7 +308,7 @@

Perform action on selected datasets: diff --git a/templates/admin/library/common.mako b/templates/admin/library/common.mako index c8f0c4b5834..71acb1662bb 100644 --- a/templates/admin/library/common.mako +++ b/templates/admin/library/common.mako @@ -1,5 +1,5 @@ -<%def name="render_template_info( library_item, library_id, widgets, editable=True )"> +<%def name="render_template_info( library_item, library_id, response_action, widgets, editable=True )"> <% library_item_type = 'unknown type' library_item_desc = '' @@ -22,7 +22,7 @@

Other information about ${library_item_desc} ${library_item.name}
%if editable: -
+ %for i, field in enumerate( widgets ): diff --git a/templates/admin/library/folder_info.mako b/templates/admin/library/folder_info.mako index 7c9dbf8fb92..f8a0f9b1079 100644 --- a/templates/admin/library/folder_info.mako +++ b/templates/admin/library/folder_info.mako @@ -5,7 +5,7 @@

@@ -16,7 +16,7 @@
Edit folder name and description
- +
@@ -35,5 +35,5 @@
%if widgets: - ${render_template_info( folder, library_id, widgets )} + ${render_template_info( folder, library_id, 'folder', widgets )} %endif diff --git a/templates/admin/library/folder_permissions.mako b/templates/admin/library/folder_permissions.mako index 5c252d61ff1..da97560cb9b 100644 --- a/templates/admin/library/folder_permissions.mako +++ b/templates/admin/library/folder_permissions.mako @@ -5,7 +5,7 @@

@@ -17,4 +17,4 @@ roles = trans.app.model.Role.filter( trans.app.model.Role.table.c.deleted==False ).order_by( trans.app.model.Role.table.c.name ).all() %> -${render_permission_form( folder, folder.name, h.url_for( controller='library_admin', action='folder', id=folder.id, library_id=library_id, permissions=True ), roles )} +${render_permission_form( folder, folder.name, h.url_for( controller='library_admin', action='folder', obj_id=folder.id, library_id=library_id, permissions=True ), roles )} diff --git a/templates/admin/library/ldda_edit_info.mako b/templates/admin/library/ldda_edit_info.mako index 1ca9e78bd4a..2f223349056 100644 --- a/templates/admin/library/ldda_edit_info.mako +++ b/templates/admin/library/ldda_edit_info.mako @@ -12,7 +12,7 @@ @@ -20,9 +20,9 @@ ${render_msg( msg, messagetype )} %endif -<%def name="datatype( ldda, datatypes )"> +<%def name="datatype( ldda, file_formats )"> + +
@@ -73,9 +73,9 @@
-
+
- +
This will inspect the dataset and attempt to correct the above column values if they are not accurate. @@ -89,11 +89,11 @@
Change data type of ${ldda.name}
%if ldda.datatype.allow_datatype_change: - - + +
- ${datatype( ldda, datatypes )} + ${datatype( ldda, file_formats )}
This will change the datatype of the existing dataset but not modify its contents. Use this if Galaxy @@ -114,5 +114,5 @@
%if widgets: - ${render_template_info( ldda, library_id, widgets )} + ${render_template_info( ldda, library_id, 'ldda_edit_info', widgets )} %endif diff --git a/templates/admin/library/ldda_info.mako b/templates/admin/library/ldda_info.mako index 2e9916d3247..d1a9402404d 100644 --- a/templates/admin/library/ldda_info.mako +++ b/templates/admin/library/ldda_info.mako @@ -20,7 +20,7 @@ @@ -41,18 +41,16 @@ %if not library.deleted and not ldda.library_dataset.folder.deleted and not ldda.deleted:
- Edit this dataset's information - ## We're disabling the ability to add templates at the LDDA and LibraryDataset level, but will leave this here for possible future use - ##Add an information template to this dataset - Edit this dataset's permissions + Edit this dataset's information + Edit this dataset's permissions %if current_version: - Upload a new version of this dataset + Upload a new version of this dataset %endif %if ldda.has_data: - Download this dataset + Download this dataset %endif - %if not library.deleted and not ldda.library_dataset.folder.deleted and not ldda.deleted: - Delete this dataset + %if not library.deleted and not ldda.library_dataset.folder.deleted and not ldda.library_dataset.deleted: + Delete this dataset %endif
%endif @@ -96,7 +94,7 @@ %endif
%if widgets: - ${render_template_info( ldda, library.id, widgets, editable=False )} + ${render_template_info( ldda, library.id, 'ldda_display_info', widgets, editable=False )} %endif %if current_version: <% expired_lddas = [ e_ldda for e_ldda in ldda.library_dataset.expired_datasets ] %> @@ -104,7 +102,7 @@
Expired versions of ${ldda.name}
%for expired_ldda in expired_lddas: %endfor %endif diff --git a/templates/admin/library/ldda_permissions.mako b/templates/admin/library/ldda_permissions.mako index e20fb451a8d..a0a6315afdc 100644 --- a/templates/admin/library/ldda_permissions.mako +++ b/templates/admin/library/ldda_permissions.mako @@ -5,17 +5,17 @@ <% roles = trans.app.model.Role.filter( trans.app.model.Role.table.c.deleted==False ).order_by( trans.app.model.Role.table.c.name ).all() - lddas = util.listify( ldda ) if len( lddas ) > 1: name_str = '%d selected datasets' % len( lddas ) else: + ldda = lddas[0] name_str = ldda.name %>

@@ -35,7 +35,7 @@
@@ -59,4 +59,4 @@ %endif <% ldda_ids = ",".join( [ str( d.id ) for d in lddas ] ) %> -${render_permission_form( lddas[0], name_str, h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=lddas[0].library_dataset.folder.id, id=ldda_ids, permissions=True ), roles )} +${render_permission_form( lddas[0], name_str, h.url_for( controller='library_admin', action='ldda_manage_permissions', library_id=library_id, folder_id=lddas[0].library_dataset.folder.id, obj_id=ldda_ids ), roles )} diff --git a/templates/admin/library/library_dataset_info.mako b/templates/admin/library/library_dataset_info.mako index 93361064335..9b59b71231a 100644 --- a/templates/admin/library/library_dataset_info.mako +++ b/templates/admin/library/library_dataset_info.mako @@ -11,7 +11,7 @@ @@ -23,7 +23,7 @@
Edit attributes of ${library_dataset.name}
- +
@@ -46,5 +46,5 @@
%if widgets: - ${render_template_info( library_dataset, library.id, widgets )} + ${render_template_info( library_dataset, library.id, '', widgets )} %endif diff --git a/templates/admin/library/library_dataset_permissions.mako b/templates/admin/library/library_dataset_permissions.mako index 730340624d6..ee7c5d62e1a 100644 --- a/templates/admin/library/library_dataset_permissions.mako +++ b/templates/admin/library/library_dataset_permissions.mako @@ -11,7 +11,7 @@ @@ -23,4 +23,4 @@ roles = trans.app.model.Role.filter( trans.app.model.Role.table.c.deleted==False ).order_by( trans.app.model.Role.table.c.name ).all() %> -${render_permission_form( library_dataset, library_dataset.name, h.url_for( controller='library_admin', action='library_dataset', id=library_dataset.id, library_id=library_id, permissions=True ), roles )} +${render_permission_form( library_dataset, library_dataset.name, h.url_for( controller='library_admin', action='library_dataset', obj_id=library_dataset.id, library_id=library_id, permissions=True ), roles )} diff --git a/templates/admin/library/library_info.mako b/templates/admin/library/library_info.mako index 2c383f00919..9a1a685f81a 100644 --- a/templates/admin/library/library_info.mako +++ b/templates/admin/library/library_info.mako @@ -5,7 +5,7 @@

@@ -16,7 +16,7 @@
Change library name and description
- +
@@ -44,5 +44,5 @@ %> %if widgets: - ${render_template_info( library, library.id, widgets )} + ${render_template_info( library, library.id, 'library', widgets )} %endif diff --git a/templates/admin/library/library_permissions.mako b/templates/admin/library/library_permissions.mako index 4d8ee05289e..7867128873b 100644 --- a/templates/admin/library/library_permissions.mako +++ b/templates/admin/library/library_permissions.mako @@ -5,7 +5,7 @@

@@ -16,4 +16,4 @@ <% roles = trans.app.model.Role.filter( trans.app.model.Role.table.c.deleted==False ).order_by( trans.app.model.Role.table.c.name ).all() %> -${render_permission_form( library, library.name, h.url_for( conroller='admin', action='library', id=library.id, permissions=True ), roles )} +${render_permission_form( library, library.name, h.url_for( conroller='admin', action='library', obj_id=library.id, permissions=True ), roles )} diff --git a/templates/admin/library/new_folder.mako b/templates/admin/library/new_folder.mako index 4b7d16cbf31..ecea33ae191 100644 --- a/templates/admin/library/new_folder.mako +++ b/templates/admin/library/new_folder.mako @@ -4,7 +4,7 @@
@@ -15,7 +15,7 @@
Create a new folder
- +
diff --git a/templates/admin/library/select_info_template.mako b/templates/admin/library/select_info_template.mako index 3eee9701a10..a153916a4e5 100644 --- a/templates/admin/library/select_info_template.mako +++ b/templates/admin/library/select_info_template.mako @@ -4,7 +4,7 @@

@@ -14,16 +14,19 @@
Select a form on which to base the template for the ${library_item_desc} '${library_item_name}'
- +
%if library_dataset_id: + %elif folder_id: + %elif ldda_id: + %endif %endif - ${ldda.name[:60]} + ${ldda.name[:50]} @@ -237,19 +237,19 @@ class RowCounter( object ):
@@ -287,22 +287,22 @@ class RowCounter( object ): diff --git a/templates/library/common.mako b/templates/library/common.mako index df9f29b3286..a5e9cba81dc 100644 --- a/templates/library/common.mako +++ b/templates/library/common.mako @@ -1,4 +1,4 @@ -<%def name="render_template_info( library_item, library_id, widgets, editable=True )"> +<%def name="render_template_info( library_item, library_id, response_action, widgets, editable=True )"> <% library_item_type = 'unknown type' library_item_desc = '' @@ -22,7 +22,7 @@
Other information about ${library_item_desc} ${library_item.name}
%if editable and trans.app.security_agent.can_modify_library_item( user, roles, library_item ): - + %for i, field in enumerate( widgets ): diff --git a/templates/library/folder_info.mako b/templates/library/folder_info.mako index 657362d0d92..b3a8f66110a 100644 --- a/templates/library/folder_info.mako +++ b/templates/library/folder_info.mako @@ -7,7 +7,7 @@

@@ -19,7 +19,7 @@
Edit folder name and description
%if trans.app.security_agent.can_modify_library_item( user, roles, folder ): - +
@@ -49,5 +49,5 @@
%if widgets: - ${render_template_info( folder, library_id, widgets )} + ${render_template_info( folder, library_id, 'folder', widgets )} %endif diff --git a/templates/library/folder_permissions.mako b/templates/library/folder_permissions.mako index e2e9252f5d0..8167ad1facc 100644 --- a/templates/library/folder_permissions.mako +++ b/templates/library/folder_permissions.mako @@ -7,7 +7,7 @@

@@ -16,5 +16,5 @@ %endif %if trans.app.security_agent.can_manage_library_item( user, roles, folder ): - ${render_permission_form( folder, folder.name, h.url_for( controller='library', action='folder', id=folder.id, library_id=library_id, permissions=True ), trans.user.all_roles() )} + ${render_permission_form( folder, folder.name, h.url_for( controller='library', action='folder', obj_id=folder.id, library_id=library_id, permissions=True ), trans.user.all_roles() )} %endif diff --git a/templates/library/ldda_edit_info.mako b/templates/library/ldda_edit_info.mako index 709073f16b5..306df2fd5d5 100644 --- a/templates/library/ldda_edit_info.mako +++ b/templates/library/ldda_edit_info.mako @@ -14,7 +14,7 @@ @@ -22,9 +22,9 @@ ${render_msg( msg, messagetype )} %endif -<%def name="datatype( ldda, datatypes )"> +<%def name="datatype( ldda, file_formats )"> + +
@@ -75,7 +75,7 @@
-
+
@@ -91,11 +91,11 @@
Change data type
%if ldda.datatype.allow_datatype_change: - +
- ${datatype( ldda, datatypes )} + ${datatype( ldda, file_formats )}
This will change the datatype of the existing dataset but not modify its contents. Use this if Galaxy @@ -147,5 +147,5 @@
%endif %if widgets: - ${render_template_info( ldda, library_id, widgets )} + ${render_template_info( ldda, library_id, 'ldda_edit_info', widgets )} %endif diff --git a/templates/library/ldda_info.mako b/templates/library/ldda_info.mako index f2bc511aaa1..6c2f64b883a 100644 --- a/templates/library/ldda_info.mako +++ b/templates/library/ldda_info.mako @@ -20,7 +20,7 @@ @@ -41,19 +41,19 @@
%if trans.app.security_agent.can_modify_library_item( user, roles, ldda.library_dataset ): - Edit this dataset's information + Edit this dataset's information %else: - View this dataset's information + View this dataset's information %endif %if trans.app.security_agent.can_manage_dataset( roles, ldda.dataset ) and trans.app.security_agent.can_manage_library_item( user, roles, ldda.library_dataset ): - Edit this dataset's permissions + Edit this dataset's permissions %endif %if current_version and trans.app.security_agent.can_modify_library_item( user, roles, ldda.library_dataset ): - Upload a new version of this dataset + Upload a new version of this dataset %endif %if ldda.has_data: Import this dataset into your current history - Download this dataset + Download this dataset %endif
@@ -96,7 +96,7 @@ %endif
%if widgets: - ${render_template_info( ldda, library_id, widgets, editable=False )} + ${render_template_info( ldda, library_id, 'ldda_display_info', widgets, editable=False )} %endif %if current_version: <% expired_lddas = [ e_ldda for e_ldda in ldda.library_dataset.expired_datasets ] %> @@ -104,7 +104,7 @@
Expired versions of ${ldda.name}
%for expired_ldda in expired_lddas: %endfor %endif diff --git a/templates/library/ldda_permissions.mako b/templates/library/ldda_permissions.mako index 10f2ce53d94..d14ae30bbf7 100644 --- a/templates/library/ldda_permissions.mako +++ b/templates/library/ldda_permissions.mako @@ -15,7 +15,7 @@

@@ -35,7 +35,7 @@
@@ -59,4 +59,4 @@ %endif <% ldda_ids = ",".join( [ str( d.id ) for d in lddas ] ) %> -${render_permission_form( lddas[0], name_str, h.url_for( controller='library', action='library_dataset_dataset_association', library_id=library_id, folder_id=lddas[0].library_dataset.folder.id, id=ldda_ids, permissions=True ), roles )} +${render_permission_form( lddas[0], name_str, h.url_for( controller='library', action='ldda_manage_permissions', library_id=library_id, folder_id=lddas[0].library_dataset.folder.id, obj_id=ldda_ids ), roles )} diff --git a/templates/library/library_dataset_common.mako b/templates/library/library_dataset_common.mako index 5e12404a771..acad9355441 100644 --- a/templates/library/library_dataset_common.mako +++ b/templates/library/library_dataset_common.mako @@ -17,7 +17,7 @@ %if replace_dataset not in [ None, 'None' ]:
- You are currently selecting a new file to replace '${replace_dataset.name}'. + You are currently selecting a new file to replace '${replace_dataset.name}'.
%endif @@ -194,7 +194,7 @@ %if replace_dataset not in [ None, 'None' ]:
- You are currently selecting a new file to replace '${replace_dataset.name}'. + You are currently selecting a new file to replace '${replace_dataset.name}'.
%endif diff --git a/templates/library/library_dataset_info.mako b/templates/library/library_dataset_info.mako index c2b5269b4c8..5501c74c644 100644 --- a/templates/library/library_dataset_info.mako +++ b/templates/library/library_dataset_info.mako @@ -13,7 +13,7 @@ @@ -25,7 +25,7 @@
Edit attributes of ${library_dataset.name}
- +
@@ -64,5 +64,5 @@ %endif %if widgets: - ${render_template_info( library_dataset, library_id, widgets )} + ${render_template_info( library_dataset, library_id, '', widgets )} %endif diff --git a/templates/library/library_dataset_permissions.mako b/templates/library/library_dataset_permissions.mako index c952d5b116d..a8d029cbf8e 100644 --- a/templates/library/library_dataset_permissions.mako +++ b/templates/library/library_dataset_permissions.mako @@ -13,7 +13,7 @@ @@ -25,5 +25,5 @@ <% roles = trans.app.model.Role.filter( trans.app.model.Role.table.c.deleted==False ).order_by( trans.app.model.Role.table.c.name ).all() %> - ${render_permission_form( library_dataset, library_dataset.name, h.url_for( controller='library', action='library_dataset', id=library_dataset.id, library_id=library_id, permissions=True ), roles )} + ${render_permission_form( library_dataset, library_dataset.name, h.url_for( controller='library', action='library_dataset', obj_id=library_dataset.id, library_id=library_id, permissions=True ), roles )} %endif diff --git a/templates/library/library_info.mako b/templates/library/library_info.mako index 91cbdf38d42..28bb9a58f4e 100644 --- a/templates/library/library_info.mako +++ b/templates/library/library_info.mako @@ -7,7 +7,7 @@

@@ -36,7 +36,7 @@
- +
@@ -60,5 +60,5 @@ %endif %if widgets: - ${render_template_info( library, library.id, widgets )} + ${render_template_info( library, library.id, 'library', widgets )} %endif diff --git a/templates/library/library_permissions.mako b/templates/library/library_permissions.mako index 7953c2551cf..eb634028520 100644 --- a/templates/library/library_permissions.mako +++ b/templates/library/library_permissions.mako @@ -7,7 +7,7 @@

@@ -19,5 +19,5 @@ <% roles = trans.app.model.Role.filter( trans.app.model.Role.table.c.deleted==False ).order_by( trans.app.model.Role.table.c.name ).all() %> - ${render_permission_form( library, library.name, h.url_for( controller='library', action='library', id=library.id, permissions=True ), roles )} + ${render_permission_form( library, library.name, h.url_for( controller='library', action='library', obj_id=library.id, permissions=True ), roles )} %endif diff --git a/templates/library/new_folder.mako b/templates/library/new_folder.mako index bdeb1a6c38f..453fb93ab47 100644 --- a/templates/library/new_folder.mako +++ b/templates/library/new_folder.mako @@ -4,7 +4,7 @@
@@ -15,7 +15,7 @@
Create a new folder
- +
diff --git a/templates/library/select_info_template.mako b/templates/library/select_info_template.mako index 29261553678..b64500e8ca7 100644 --- a/templates/library/select_info_template.mako +++ b/templates/library/select_info_template.mako @@ -4,7 +4,7 @@

@@ -14,16 +14,19 @@
Select a form on which to base the template for the ${library_item_desc} '${library_item_name}'
- +
%if library_dataset_id: + %elif folder_id: + %elif ldda_id: + %endif +
@@ -51,7 +51,7 @@
- ${render_template_info( library, library.id )} + ${render_template_info( library, library.id, 'library' )}
%endif @@ -63,5 +63,5 @@ %endif %if widgets: - ${render_template_info( library, library_id, widgets )} + ${render_template_info( library, library_id, 'library', widgets )} %endif diff --git a/templates/requests/show_request.mako b/templates/requests/show_request.mako index 81bf046f807..6505296f327 100644 --- a/templates/requests/show_request.mako +++ b/templates/requests/show_request.mako @@ -104,7 +104,7 @@ %else: %if rd['label'] == 'Data library': %if rd['value']: - ${rd['value']} + ${rd['value']} %else: None %endif diff --git a/test/base/twilltestcase.py b/test/base/twilltestcase.py index d9ba29e6f83..fe0d8f9cc68 100644 --- a/test/base/twilltestcase.py +++ b/test/base/twilltestcase.py @@ -1145,7 +1145,7 @@ class TwillTestCase( unittest.TestCase ): tc.submit( "create_library_button" ) self.home() def set_library_permissions( self, library_id, library_name, role_id, permissions_in, permissions_out ): - url = "library_admin/library?id=%s&permissions=True&update_roles_button=Save" % ( library_id ) + url = "library_admin/library?obj_id=%s&permissions=True&update_roles_button=Save" % ( library_id ) for po in permissions_out: key = '%s_out' % po url ="%s&%s=%s" % ( url, key, str( role_id ) ) @@ -1160,44 +1160,44 @@ class TwillTestCase( unittest.TestCase ): def rename_library( self, library_id, old_name, name='Library One Renamed', description='This is Library One Re-described' ): """Rename a library""" self.home() - self.visit_url( "%s/library_admin/library?information=True&id=%s" % ( self.url, library_id ) ) + self.visit_url( "%s/library_admin/library?obj_id=%s&information=True" % ( self.url, library_id ) ) self.check_page_for_string( 'Change library name and description' ) # Since twill barfs on the form submisson, we ar forced to simulate it - url = "%s/library_admin/library?information=True&id=%s&rename_library_button=Save&description=%s&name=%s" % \ + url = "%s/library_admin/library?obj_id=%s&information=True&rename_library_button=Save&description=%s&name=%s" % \ ( self.url, library_id, description.replace( ' ', '+' ), name.replace( ' ', '+' ) ) self.home() self.visit_url( url ) check_str = "Library '%s' has been renamed to '%s'" % ( old_name, name ) self.check_page_for_string( check_str ) self.home() - def add_library_info_template( self, library_id, library_name, form_id, form_name ): + def add_library_info_template( self, cntrller, library_id, library_name, form_id, form_name ): """Add a new info template to a library""" self.home() - url = "%s/library_admin/info_template?library_id=%s&add=True" % ( self.url, library_id ) + url = "%s/library_common/info_template?cntrller=%s&library_id=%s&response_action='browse_library'" % ( self.url, cntrller, library_id ) self.visit_url( url ) self.check_page_for_string ( "Select a form on which to base the template" ) tc.fv( '1', 'library_id', library_id ) tc.submit( 'add_info_template_button' ) - self.check_page_for_string = 'An information template based on the form "%s" has been added to this library.' % form_name + self.check_page_for_string = 'An information template based on the form "%s" has been added to this data library.' % form_name self.home() def edit_library_info( self, library_id, library_name, ele_1_field_name, ele_1_contents, ele_2_field_name, ele_2_contents ): """Add information to a library using an existing template with 2 elements""" self.home() - self.visit_url( "%s/library_admin/library?information=True&id=%s" % ( self.url, library_id ) ) + self.visit_url( "%s/library_admin/library?obj_id=%s&information=True" % ( self.url, library_id ) ) check_str = 'Other information about library %s' % library_name self.check_page_for_string( check_str ) tc.fv( '2', ele_1_field_name, ele_1_contents ) tc.fv( '2', ele_2_field_name, ele_2_contents ) tc.submit( 'create_new_info_button' ) self.home() - def edit_library_info_template( self, library_id, id, name, ele_name_1, name_1, + def edit_library_info_template( self, library_id, obj_id, name, ele_name_1, name_1, ele_desc_1, desc_1, ele_name_2, name_2, ele_desc_2, desc_2 ): """Edit an existing library info template""" self.home() - url = "%s/library_admin/info_template?library_id=%s&id=%s&edit_template=True" % ( self.url, library_id, id ) + url = "%s/library_admin/edit_info_template?library_id=%s&obj_id=%s&response_action='browse_library'" % ( self.url, library_id, obj_id ) self.visit_url( url ) self.check_page_for_string ( 'Edit template' ) - tc.fv( '1', 'id', id ) + tc.fv( '1', 'obj_id', obj_id ) tc.fv( '1', 'set_num_fields', '0' ) tc.fv( '1', 'name', name ) tc.fv( '1', ele_name_1, name_1 ) @@ -1208,12 +1208,12 @@ class TwillTestCase( unittest.TestCase ): check_str = "Information template '%s' has been updated" % name self.check_page_for_string( check_str ) self.home() - def add_folder_info_template( self, library_id, library_name, folder_id, folder_name, num_fields='2', + def add_folder_info_template( self, cntrller, library_id, library_name, folder_id, folder_name, num_fields='2', name='Folder Template 1', ele_name_0='Fu', ele_help_0='', ele_name_1='Bar', ele_help_1='' ): """Add a new info template to a folder""" self.home() - url = "%s/library_admin/info_template?library_id=%s&folder_id=%s&new_template=True&num_fields=2&create_info_template_button=Go" % \ - ( self.url, library_id, folder_id ) + url = "%s/library_admin/info_template?cntrller=%s&library_id=%s&response_action='folder'&create_info_template_button=Go" % \ + ( self.url, cntrller, library_id, folder_id ) self.home() self.visit_url( url ) check_str = "Create a new information template for folder '%s'" % folder_name @@ -1231,7 +1231,7 @@ class TwillTestCase( unittest.TestCase ): def add_folder( self, library_id, folder_id, name='Folder One', description='This is Folder One' ): """Create a new folder""" self.home() - self.visit_url( "%s/library_admin/folder?library_id=%s&id=%s&new=True" % ( self.url, library_id, folder_id ) ) + self.visit_url( "%s/library_admin/folder?library_id=%s&obj_id=%s&new=True" % ( self.url, library_id, folder_id ) ) self.check_page_for_string( 'Create a new folder' ) tc.fv( "1", "name", name ) # form field 1 is the field named name... tc.fv( "1", "description", description ) # form field 2 is the field named description... @@ -1240,10 +1240,10 @@ class TwillTestCase( unittest.TestCase ): def rename_folder( self, library_id, folder_id, old_name, name='Folder One Renamed', description='This is Folder One Re-described' ): """Rename a Folder""" self.home() - self.visit_url( "%s/library_admin/folder?library_id=%s&manage=True&id=%s" % ( self.url, library_id, folder_id ) ) + self.visit_url( "%s/library_admin/folder?library_id=%s&manage=True&obj_id=%s" % ( self.url, library_id, folder_id ) ) self.check_page_for_string( 'Edit folder name and description' ) # Since twill barfs on the form submisson, we ar forced to simulate it - url = "%s/library_admin/folder?library_id=%s&manage=True&id=%s&rename_folder_button=Save&description=%s&name=%s" % \ + url = "%s/library_admin/folder?library_id=%s&manage=True&obj_id=%s&rename_folder_button=Save&description=%s&name=%s" % \ ( self.url, library_id, folder_id, description.replace( ' ', '+' ), name.replace( ' ', '+' ) ) self.home() self.visit_url( url ) @@ -1255,7 +1255,7 @@ class TwillTestCase( unittest.TestCase ): """Add a dataset to a folder""" filename = self.get_filename( filename ) self.home() - self.visit_url( "%s/library_admin/library_dataset_dataset_association?upload_option=upload_file&library_id=%s&folder_id=%s&message=%s" % \ + self.visit_url( "%s/library_admin/upload_library_dataset?upload_option=upload_file&library_id=%s&folder_id=%s&message=%s" % \ ( self.url, library_id, folder_id, message ) ) self.check_page_for_string( 'Upload files' ) tc.fv( "1", "folder_id", folder_id ) @@ -1277,7 +1277,7 @@ class TwillTestCase( unittest.TestCase ): self.library_wait( library_id ) self.home() def set_library_dataset_permissions( self, library_id, folder_id, ldda_id, ldda_name, role_id, permissions_in, permissions_out ): - url = "library_admin/library_dataset_dataset_association?library_id=%s&folder_id=%s&&id=%s&permissions=True&update_roles_button=Save" % \ + url = "library_admin/ldda_manage_permissions?library_id=%s&folder_id=%s&obj_id=%s&update_roles_button=Save" % \ ( library_id, folder_id, ldda_id ) #role_ids = util.listify( role_ids ) #for role_id in role_ids: @@ -1289,7 +1289,7 @@ class TwillTestCase( unittest.TestCase ): url ="%s&%s=%s" % ( url, key, str( role_id ) ) self.home() self.visit_url( "%s/%s" % ( self.url, url ) ) - check_str = "Permissions updated for dataset '%s'" % ldda_name + check_str = "Permissions have been updated on 1 datasets" self.check_page_for_string( check_str ) self.home() def edit_ldda_template_element_info( self, library_id, folder_id, ldda_id, ldda_name, ele_1_field_name, @@ -1297,7 +1297,7 @@ class TwillTestCase( unittest.TestCase ): ele_3_field_name='', ele_3_contents='', ele_3_help='' ): """Edit library_dataset_dataset_association template element information""" self.home() - self.visit_url( "%s/library_admin/library_dataset_dataset_association?edit_info=True&library_id=%s&folder_id=%s&id=%s" % \ + self.visit_url( "%s/library_admin/ldda_edit_info?library_id=%s&folder_id=%s&obj_id=%s" % \ ( self.url, library_id, folder_id, ldda_id ) ) check_str = 'Edit attributes of %s' % ldda_name self.check_page_for_string( check_str ) @@ -1329,7 +1329,7 @@ class TwillTestCase( unittest.TestCase ): def edit_ldda_attribute_info( self, library_id, folder_id, ldda_id, ldda_name, new_ldda_name ): """Edit library_dataset_dataset_association attribute information""" self.home() - self.visit_url( "%s/library_admin/library_dataset_dataset_association?edit_info=True&library_id=%s&folder_id=%s&id=%s" % \ + self.visit_url( "%s/library_admin/ldda_edit_info?library_id=%s&folder_id=%s&obj_id=%s" % \ ( self.url, library_id, folder_id, ldda_id ) ) check_str = 'Edit attributes of %s' % ldda_name self.check_page_for_string( check_str ) @@ -1345,7 +1345,7 @@ class TwillTestCase( unittest.TestCase ): """Upload new version(s) of a dataset""" self.home() filename = self.get_filename( filename ) - self.visit_url( "%s/library_admin/library_dataset_dataset_association?upload_option=upload_file&library_id=%s&folder_id=%s&replace_id=%s&message=%s" % \ + self.visit_url( "%s/library_admin/upload_library_dataset?upload_option=upload_file&library_id=%s&folder_id=%s&replace_id=%s&message=%s" % \ ( self.url, library_id, folder_id, library_dataset_id, message ) ) self.check_page_for_string( 'Upload files' ) self.check_page_for_string( 'You are currently selecting a new file to replace' ) @@ -1378,7 +1378,7 @@ class TwillTestCase( unittest.TestCase ): """Add a directory of datasets to a folder""" # roles is a list of tuples: [ ( role_id, role_description ) ] self.home() - self.visit_url( "%s/library_admin/library_dataset_dataset_association?upload_option=upload_directory&library_id=%s&folder_id=%s" % ( self.url, library_id, folder_id ) ) + self.visit_url( "%s/library_admin/upload_library_dataset?upload_option=upload_directory&library_id=%s&folder_id=%s" % ( self.url, library_id, folder_id ) ) self.check_page_for_string( 'Upload a directory of files' ) tc.fv( "1", "folder_id", folder_id ) tc.fv( "1", "file_type", file_type ) @@ -1400,7 +1400,7 @@ class TwillTestCase( unittest.TestCase ): """Add a directory of datasets to a folder""" # roles is a list of tuples: [ ( role_id, role_description ) ] self.home() - self.visit_url( "%s/library/library_dataset_dataset_association?upload_option=upload_directory&library_id=%s&folder_id=%s" % \ + self.visit_url( "%s/library/upload_library_dataset?upload_option=upload_directory&library_id=%s&folder_id=%s" % \ ( self.url, library_id, folder_id ) ) self.check_page_for_string( 'Upload a directory of files' ) tc.fv( "1", "folder_id", folder_id ) @@ -1445,7 +1445,7 @@ class TwillTestCase( unittest.TestCase ): def purge_library( self, library_id, library_name ): """Purge a library""" self.home() - self.visit_url( "%s/library_admin/purge_library?id=%s" % ( self.url, library_id ) ) + self.visit_url( "%s/library_admin/purge_library?obj_id=%s" % ( self.url, library_id ) ) check_str = "Library '%s' and all of its contents have been purged" % library_name self.check_page_for_string( check_str ) self.home() @@ -1456,7 +1456,7 @@ class TwillTestCase( unittest.TestCase ): self.home() while count < maxiter: count += 1 - self.visit_url( "%s/%s/browse_library?id=%s" % ( self.url, controller, library_id ) ) + self.visit_url( "%s/%s/browse_library?obj_id=%s" % ( self.url, controller, library_id ) ) page = tc.browser.get_html() if page.find( '' ) > -1: time.sleep( sleep_amount ) diff --git a/test/functional/test_forms_and_requests.py b/test/functional/test_forms_and_requests.py index 86b5792329c..37e731f2e8c 100644 --- a/test/functional/test_forms_and_requests.py +++ b/test/functional/test_forms_and_requests.py @@ -162,7 +162,7 @@ class TestFormsAndRequests( TwillTestCase ): 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.visit_url( '%s/library_admin/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) self.check_page_for_string( name ) # create address #self.create_address( user_address1 ) diff --git a/test/functional/test_security_and_libraries.py b/test/functional/test_security_and_libraries.py index c7e4879c570..23e95f525f7 100644 --- a/test/functional/test_security_and_libraries.py +++ b/test/functional/test_security_and_libraries.py @@ -30,7 +30,7 @@ class TestSecurityAndLibraries( TwillTestCase ): self.check_page_for_string( not_logged_in_security_msg ) self.visit_url( "%s/library_admin/library" % self.url ) self.check_page_for_string( not_logged_in_security_msg ) - self.visit_url( "%s/library_admin/folder?id=1&new=True" % self.url ) + self.visit_url( "%s/library_admin/folder?obj_id=1&new=True" % self.url ) self.check_page_for_string( not_logged_in_security_msg ) def test_005_login_as_admin_user( self ): """Testing logging in as an admin user test@bx.psu.edu - tests initial settings for DefaultUserPermissions and DefaultHistoryPermissions""" @@ -494,7 +494,8 @@ class TestSecurityAndLibraries( TwillTestCase ): assert form_one is not None, 'Problem retrieving form named (%s) from the database' % form_name # Add a new information template to the library template_name = 'Library Template 1' - self.add_library_info_template( str( library_one.id ), + self.add_library_info_template( 'library_admin', + str( library_one.id ), library_one.name, str( form_one.id ), form_one.name ) @@ -510,14 +511,13 @@ class TestSecurityAndLibraries( TwillTestCase ): global form_one_field_name form_one_field_name = 'field_0' contents = '%s library contents' % form_one_field_label - self.visit_url( '%s/library_admin/library?id=%s&information=True' % ( self.url, str( library_one.id ) ) ) + self.visit_url( '%s/library_admin/library?obj_id=%s&information=True' % ( self.url, str( library_one.id ) ) ) # There are 2 forms on this page and the template is the 2nd form tc.fv( '2', form_one_field_name, contents ) tc.submit( 'edit_info_button' ) # For some reason, the following check: # self.check_page_for_string ( 'The information has been updated.' ) # ...throws the following exception - I have not idea why! - # self.check_page_for_string ( 'The information has been updated.' ) # TypeError: 'str' object is not callable # The work-around is to not make ANY self.check_page_for_string() calls until the next method def test_080_edit_template_contents_admin_view( self ): @@ -525,7 +525,7 @@ class TestSecurityAndLibraries( TwillTestCase ): # First make sure the templlate contents from the previous method were correctly saved contents = '%s library contents' % form_one_field_label contents_edited = contents + ' edited' - self.visit_url( '%s/library_admin/library?id=%s&information=True' % ( self.url, str( library_one.id ) ) ) + self.visit_url( '%s/library_admin/library?obj_id=%s&information=True' % ( self.url, str( library_one.id ) ) ) self.check_page_for_string( contents ) # Edit the contents and then save them tc.fv( '2', form_one_field_name, contents_edited ) @@ -554,7 +554,7 @@ class TestSecurityAndLibraries( TwillTestCase ): .order_by( desc( galaxy.model.LibraryDatasetDatasetAssociation.table.c.create_time ) ).first() assert ldda_one is not None, 'Problem retrieving LibraryDatasetDatasetAssociation ldda_one from the database' self.home() - self.visit_url( '%s/library_admin/browse_library?id=%s' % ( self.url, str( library_one.id ) ) ) + self.visit_url( '%s/library_admin/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) self.check_page_for_string( "1.bed" ) self.check_page_for_string( message ) self.check_page_for_string( admin_user.email ) @@ -576,14 +576,14 @@ class TestSecurityAndLibraries( TwillTestCase ): % ( ldda_one.dataset.id, dp.action ) ) # Make sure the library template contents were correctly saved self.home() - self.visit_url( "%s/library_admin/library_dataset_dataset_association?edit_info=True&library_id=%s&folder_id=%s&id=%s" % \ + self.visit_url( "%s/library_admin/ldda_edit_info?library_id=%s&folder_id=%s&obj_id=%s" % \ ( self.url, str( library_one.id ), str( library_one.root_folder.id ), str( ldda_one.id ) ) ) self.check_page_for_string( template_contents ) # Make sure other users can access the dataset from the Libraries view self.logout() self.login( email=regular_user2.email ) self.home() - self.visit_url( '%s/library/browse_library?id=%s' % ( self.url, str( library_one.id ) ) ) + self.visit_url( '%s/library/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) self.check_page_for_string( "1.bed" ) self.logout() self.login( email=admin_user.email ) @@ -600,11 +600,11 @@ class TestSecurityAndLibraries( TwillTestCase ): galaxy.model.LibraryFolder.table.c.description==description ) ).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.visit_url( '%s/library_admin/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) self.check_page_for_string( name ) self.check_page_for_string( description ) self.home() - self.visit_url( '%s/library_admin/folder?id=%s&library_id=%s&information=True' % ( self.url, str( folder_one.id ), str( library_one.id ) ) ) + self.visit_url( '%s/library_admin/folder?obj_id=%s&library_id=%s&information=True' % ( self.url, str( folder_one.id ), str( library_one.id ) ) ) # Make sure the template was inherited self.check_page_for_string( form_one_field_name ) # Make sure the template contents were NOT inherited @@ -632,11 +632,11 @@ class TestSecurityAndLibraries( TwillTestCase ): galaxy.model.LibraryFolder.table.c.description==description ) ).first() assert subfolder_one is not None, 'Problem retrieving library folder named "Folder Ones Subfolder" from the database' self.home() - self.visit_url( '%s/library_admin/browse_library?id=%s' % ( self.url, str( library_one.id ) ) ) + self.visit_url( '%s/library_admin/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) self.check_page_for_string( name ) self.check_page_for_string( description ) self.home() - self.visit_url( '%s/library_admin/folder?id=%s&library_id=%s&information=True' % ( self.url, str( subfolder_one.id ), str( library_one.id ) ) ) + self.visit_url( '%s/library_admin/folder?obj_id=%s&library_id=%s&information=True' % ( self.url, str( subfolder_one.id ), str( library_one.id ) ) ) # Make sure the template was inherited self.check_page_for_string( form_one_field_name ) # Make sure the template contents were NOT inherited @@ -665,11 +665,11 @@ class TestSecurityAndLibraries( TwillTestCase ): galaxy.model.LibraryFolder.table.c.description==description ) ).first() assert folder_two 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.visit_url( '%s/library_admin/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) self.check_page_for_string( name ) self.check_page_for_string( description ) self.home() - self.visit_url( '%s/library_admin/folder?id=%s&library_id=%s&information=True' % ( self.url, str( subfolder_one.id ), str( library_one.id ) ) ) + self.visit_url( '%s/library_admin/folder?obj_id=%s&library_id=%s&information=True' % ( self.url, str( subfolder_one.id ), str( library_one.id ) ) ) # Make sure the template was inherited self.check_page_for_string( form_one_field_name ) # Make sure the template contents were NOT inherited @@ -701,13 +701,13 @@ class TestSecurityAndLibraries( TwillTestCase ): .order_by( desc( galaxy.model.LibraryDatasetDatasetAssociation.table.c.create_time ) ).first() assert ldda_two is not None, 'Problem retrieving LibraryDatasetDatasetAssociation ldda_two from the database' self.home() - self.visit_url( '%s/library_admin/browse_library?id=%s' % ( self.url, str( library_one.id ) ) ) + self.visit_url( '%s/library_admin/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) self.check_page_for_string( "2.bed" ) self.check_page_for_string( message ) self.check_page_for_string( admin_user.email ) # Make sure the library template contents were correctly saved self.home() - self.visit_url( "%s/library_admin/library_dataset_dataset_association?edit_info=True&library_id=%s&folder_id=%s&id=%s" % \ + self.visit_url( "%s/library_admin/ldda_edit_info?library_id=%s&folder_id=%s&obj_id=%s" % \ ( self.url, str( library_one.id ), str( folder_two.id ), str( ldda_two.id ) ) ) self.check_page_for_string( template_contents ) def test_110_add_2nd_public_dataset_to_root_folders_2nd_subfolder( self ): @@ -732,13 +732,13 @@ class TestSecurityAndLibraries( TwillTestCase ): .order_by( desc( galaxy.model.LibraryDatasetDatasetAssociation.table.c.create_time ) ).first() assert ldda_three is not None, 'Problem retrieving LibraryDatasetDatasetAssociation ldda_three from the database' self.home() - self.visit_url( '%s/library_admin/browse_library?id=%s' % ( self.url, str( library_one.id ) ) ) + self.visit_url( '%s/library_admin/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) self.check_page_for_string( "3.bed" ) self.check_page_for_string( message ) self.check_page_for_string( admin_user.email ) # Make sure the library template contents were correctly saved self.home() - self.visit_url( "%s/library_admin/library_dataset_dataset_association?edit_info=True&library_id=%s&folder_id=%s&id=%s" % \ + self.visit_url( "%s/library_admin/ldda_edit_info?library_id=%s&folder_id=%s&obj_id=%s" % \ ( self.url, str( library_one.id ), str( folder_two.id ), str( ldda_three.id ) ) ) self.check_page_for_string( template_contents ) def test_115_add_dataset_with_private_role_restriction_to_folder( self ): @@ -775,21 +775,21 @@ class TestSecurityAndLibraries( TwillTestCase ): .order_by( desc( galaxy.model.LibraryDatasetDatasetAssociation.table.c.create_time ) ).first() assert ldda_four is not None, 'Problem retrieving LibraryDatasetDatasetAssociation ldda_four from the database' self.home() - self.visit_url( '%s/library_admin/browse_library?id=%s' % ( self.url, str( library_one.id ) ) ) + self.visit_url( '%s/library_admin/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) self.check_page_for_string( "4.bed" ) self.check_page_for_string( message ) self.check_page_for_string( admin_user.email ) self.home() # Make sure the library template contents were correctly saved self.home() - self.visit_url( "%s/library_admin/library_dataset_dataset_association?edit_info=True&library_id=%s&folder_id=%s&id=%s" % \ + self.visit_url( "%s/library_admin/ldda_edit_info?library_id=%s&folder_id=%s&obj_id=%s" % \ ( self.url, str( library_one.id ), str( folder_one.id ), str( ldda_four.id ) ) ) self.check_page_for_string( template_contents ) def test_120_accessing_dataset_with_private_role_restriction( self ): """Testing accessing a dataset with a private role restriction""" # admin_user should not be able to see 2.bed from the analysis view's access libraries self.home() - self.visit_url( '%s/library/browse_library?id=%s' % ( self.url, str( library_one.id ) ) ) + self.visit_url( '%s/library/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) try: self.check_page_for_string( folder_one.name ) raise AssertionError( '%s can see library folder %s when it contains only datasets restricted by role %s' \ @@ -807,7 +807,7 @@ class TestSecurityAndLibraries( TwillTestCase ): # since it was associated with regular_user1's private role self.login( email='test1@bx.psu.edu' ) self.home() - self.visit_url( '%s/library/browse_library?id=%s' % ( self.url, str( library_one.id ) ) ) + self.visit_url( '%s/library/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) self.check_page_for_string( folder_one.name ) self.check_page_for_string( '4.bed' ) self.logout() @@ -854,7 +854,7 @@ class TestSecurityAndLibraries( TwillTestCase ): role_ids, permissions_in, permissions_out ) # admin_user should now be able to see 4.bed from the analysis view's access libraries self.home() - self.visit_url( '%s/library/browse_library?id=%s' % ( self.url, str( library_one.id ) ) ) + self.visit_url( '%s/library/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) self.check_page_for_string( ldda_four.name ) self.home() def test_130_add_dataset_with_role_associated_with_group_and_users( self ): @@ -882,28 +882,28 @@ class TestSecurityAndLibraries( TwillTestCase ): .order_by( desc( galaxy.model.LibraryDatasetDatasetAssociation.table.c.create_time ) ).first() assert ldda_five is not None, 'Problem retrieving LibraryDatasetDatasetAssociation ldda_five from the database' self.home() - self.visit_url( '%s/library_admin/browse_library?id=%s' % ( self.url, str( library_one.id ) ) ) + self.visit_url( '%s/library_admin/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) self.check_page_for_string( "5.bed" ) self.check_page_for_string( message ) self.check_page_for_string( admin_user.email ) self.home() # Make sure the library template contents were correctly saved self.home() - self.visit_url( "%s/library_admin/library_dataset_dataset_association?edit_info=True&library_id=%s&folder_id=%s&id=%s" % \ + self.visit_url( "%s/library_admin/ldda_edit_info?library_id=%s&folder_id=%s&obj_id=%s" % \ ( self.url, str( library_one.id ), str( folder_one.id ), str( ldda_five.id ) ) ) self.check_page_for_string( template_contents ) def test_135_accessing_dataset_with_role_associated_with_group_and_users( self ): """Testing accessing a dataset with a role that is associated with a group and users""" # admin_user should be able to see 5.bed since she is associated with role_two self.home() - self.visit_url( '%s/library/browse_library?id=%s' % ( self.url, str( library_one.id ) ) ) + self.visit_url( '%s/library/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) self.check_page_for_string( "5.bed" ) self.check_page_for_string( admin_user.email ) self.logout() # regular_user1 should be able to see 5.bed since she is associated with group_two self.login( email = 'test1@bx.psu.edu' ) self.home() - self.visit_url( '%s/library/browse_library?id=%s' % ( self.url, str( library_one.id ) ) ) + self.visit_url( '%s/library/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) self.check_page_for_string( folder_one.name ) self.check_page_for_string( '5.bed' ) self.check_page_for_string( admin_user.email ) @@ -920,7 +920,7 @@ class TestSecurityAndLibraries( TwillTestCase ): # LIBRARY_MANAGE = Role One # Role One aassociations: test@bx.psu.edu, test1@bx.psu.edu, test3@bx.psu.edu self.home() - self.visit_url( '%s/library/library_dataset_dataset_association?edit_info=True&library_id=%s&folder_id=%s&id=%s' \ + self.visit_url( '%s/library/ldda_edit_info?library_id=%s&folder_id=%s&obj_id=%s' \ % ( self.url, str( library_one.id ), str( folder_one.id ), str( ldda_five.id ) ) ) self.check_page_for_string( '5.bed' ) self.check_page_for_string( 'This is the latest version of this library dataset' ) @@ -937,7 +937,7 @@ class TestSecurityAndLibraries( TwillTestCase ): # regular_user2 should not be able to see 5.bed self.login( email = 'test2@bx.psu.edu' ) self.home() - self.visit_url( '%s/library/browse_library?id=%s' % ( self.url, str( library_one.id ) ) ) + self.visit_url( '%s/library/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) try: self.check_page_for_string( folder_one.name ) raise AssertionError( '%s can see library folder %s when it contains only datasets restricted by role %s' \ @@ -954,7 +954,7 @@ class TestSecurityAndLibraries( TwillTestCase ): # can access ) since she has Role One, and Role One has all library permissions ( see above ). self.login( email = 'test3@bx.psu.edu' ) self.home() - self.visit_url( '%s/library/browse_library?id=%s' % ( self.url, str( library_one.id ) ) ) + self.visit_url( '%s/library/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) self.check_page_for_string( folder_one.name ) # regular_user3 should not be able to see 5.bed since users must have every role associated # with the dataset in order to access it, and regular_user3 isnot associated with Role Two @@ -989,7 +989,7 @@ class TestSecurityAndLibraries( TwillTestCase ): assert ldda_six is not None, 'Problem retrieving LibraryDatasetDatasetAssociation ldda_six from the database' self.home() # Make sure the correct template was inherited - self.visit_url( '%s/library/library_dataset_dataset_association?edit_info=True&library_id=%s&folder_id=%s&id=%s' \ + self.visit_url( '%s/library/ldda_edit_info?library_id=%s&folder_id=%s&obj_id=%s' \ % ( self.url, str( library_one.id ), str( subfolder_one.id ), str( ldda_six.id ) ) ) self.check_page_for_string( form_one_field_name ) # Make sure the template contents were NOT inherited @@ -1005,11 +1005,11 @@ class TestSecurityAndLibraries( TwillTestCase ): self.edit_ldda_attribute_info( str( library_one.id ), str( subfolder_one.id ), str( ldda_six.id ), ldda_six.name, new_ldda_name ) self.home() ldda_six.refresh() - self.visit_url( '%s/library_admin/browse_library?id=%s' % ( self.url, str( library_one.id ) ) ) + self.visit_url( '%s/library_admin/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) self.check_page_for_string( ldda_six.name ) self.home() # Make sure the template contents were NOT inherited - self.visit_url( '%s/library/library_dataset_dataset_association?edit_info=True&library_id=%s&folder_id=%s&id=%s' \ + self.visit_url( '%s/library/ldda_edit_info?library_id=%s&folder_id=%s&obj_id=%s' \ % ( self.url, str( library_one.id ), str( subfolder_one.id ), str( ldda_six.id ) ) ) self.check_page_for_string( form_one_field_name ) contents = "%s contents for Folder One's Subfolder" % form_one_field_label @@ -1019,7 +1019,7 @@ class TestSecurityAndLibraries( TwillTestCase ): except: pass def test_150_uploading_new_dataset_version( self ): - """Testing uploading a new version of a dataset""" + """Testing uploading a new version of a library dataset""" message = 'Testing uploading a new version of a dataset' # The form_one template should be inherited to the library dataset upload form. template_contents = "%s contents for %s new version of 6.bed" % ( form_one_field_label, folder_one.name ) @@ -1039,7 +1039,7 @@ class TestSecurityAndLibraries( TwillTestCase ): .order_by( desc( galaxy.model.LibraryDatasetDatasetAssociation.table.c.create_time ) ).first() assert ldda_six_version_two is not None, 'Problem retrieving LibraryDatasetDatasetAssociation ldda_six_version_two from the database' self.home() - self.visit_url( "%s/library_admin/library_dataset_dataset_association?edit_info=True&library_id=%s&folder_id=%s&id=%s" % \ + self.visit_url( "%s/library_admin/ldda_edit_info?library_id=%s&folder_id=%s&obj_id=%s" % \ ( self.url, str( library_one.id ), str( subfolder_one.id ), str( ldda_six_version_two.id ) ) ) self.check_page_for_string( 'This is the latest version of this library dataset' ) # Make sure the correct template was inherited @@ -1069,21 +1069,19 @@ class TestSecurityAndLibraries( TwillTestCase ): raise AssertionError( 'ldda.dataset "%s" actions "%s" != ldda.dataset "%s" actions "%s"' \ % ( ldda_six.name, str( ldda_six.dataset.actions ), ldda_six_version_two.name, str( ldda_six_version_two.dataset.actions ) ) ) # Check the previous version - self.visit_url( "%s/library_admin/library_dataset_dataset_association?info=True&library_id=%s&folder_id=%s&id=%s" % \ + self.visit_url( "%s/library_admin/ldda_display_info?library_id=%s&folder_id=%s&obj_id=%s" % \ ( self.url, str( library_one.id ), str( subfolder_one.id ), str( ldda_six.id ) ) ) self.check_page_for_string( 'This is an expired version of this library dataset' ) self.home() # Make sure ldda_six is no longer displayed in the library - self.visit_url( '%s/library_admin/browse_library?id=%s' % ( self.url, str( library_one.id ) ) ) + self.visit_url( '%s/library_admin/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) try: self.check_page_for_string( ldda_six.name ) raise AssertionError, "Old version of library dataset %s is displayed in library" % ldda_six.name except: pass self.home() - def test_155_uploading_new_dataset_versions( self ): - """Testing uploading new versions of a dataset using a directory of files""" - message = 'Testing uploading new versions of a dataset using a directory of files' + message = 'Testing uploading a new version of a library dataset' # The form_one template should be inherited to the library dataset upload form. template_contents = "%s contents for %s 5th new version of 6.bed" % ( form_one_field_label, folder_one.name ) ldda_six_version_two.refresh() @@ -1103,7 +1101,7 @@ class TestSecurityAndLibraries( TwillTestCase ): .order_by( desc( galaxy.model.LibraryDatasetDatasetAssociation.table.c.create_time ) ).first() assert ldda_six_version_five is not None, 'Problem retrieving LibraryDatasetDatasetAssociation ldda_six_version_five from the database' self.home() - self.visit_url( "%s/library_admin/library_dataset_dataset_association?edit_info=True&library_id=%s&folder_id=%s&id=%s" % \ + self.visit_url( "%s/library_admin/ldda_edit_info?library_id=%s&folder_id=%s&obj_id=%s" % \ ( self.url, str( library_one.id ), str( subfolder_one.id ), str( ldda_six_version_five.id ) ) ) self.check_page_for_string( 'This is the latest version of this library dataset' ) # Make sure the correct template was inherited @@ -1120,13 +1118,13 @@ class TestSecurityAndLibraries( TwillTestCase ): tc.submit( 'edit_info_button' ) self.check_page_for_string( 'The information has been updated.' ) self.check_page_for_string( template_contents ) - self.visit_url( "%s/library_admin/library_dataset_dataset_association?info=True&library_id=%s&folder_id=%s&id=%s" % \ + self.visit_url( "%s/library_admin/ldda_display_info?library_id=%s&folder_id=%s&obj_id=%s" % \ ( self.url, str( library_one.id ), str( subfolder_one.id ), str( ldda_six_version_five.id ) ) ) check_str = 'Expired versions of %s' % ldda_six_version_five.name self.check_page_for_string( check_str ) self.check_page_for_string( ldda_six.name ) self.home() - # Make sure th permissions are the same + # Make sure the permissions are the same ldda_six.refresh() if len( ldda_six.actions ) != len( ldda_six_version_five.actions ): raise AssertionError( 'ldda "%s" actions "%s" != ldda "%s" actions "%s"' \ @@ -1139,11 +1137,11 @@ class TestSecurityAndLibraries( TwillTestCase ): raise AssertionError( 'ldda.dataset "%s" actions "%s" != ldda.dataset "%s" actions "%s"' \ % ( ldda_six.name, str( ldda_six.dataset.actions ), ldda_six_version_five.name, str( ldda_six_version_five.dataset.actions ) ) ) # Check the previous version - self.visit_url( "%s/library_admin/library_dataset_dataset_association?info=True&library_id=%s&folder_id=%s&id=%s" % \ + self.visit_url( "%s/library_admin/ldda_display_info?library_id=%s&folder_id=%s&obj_id=%s" % \ ( self.url, str( library_one.id ), str( subfolder_one.id ), str( ldda_six_version_two.id ) ) ) self.check_page_for_string( 'This is an expired version of this library dataset' ) self.home() - def test_160_upload_directory_of_files_from_admin_view( self ): + def test_155_upload_directory_of_files_from_admin_view( self ): """Testing uploading a directory of files to a root folder from the Admin view""" message = 'This is a test for uploading a directory of files' template_contents = "%s contents for directory of 3 datasets in %s" % ( form_one_field_label, folder_one.name ) @@ -1156,11 +1154,11 @@ class TestSecurityAndLibraries( TwillTestCase ): template_field_name1=form_one_field_name, template_field_contents1=template_contents ) self.home() - self.visit_page( 'library_admin/browse_library?id=%s' % ( str( library_one.id ) ) ) + self.visit_page( 'library_admin/browse_library?obj_id=%s' % ( str( library_one.id ) ) ) self.check_page_for_string( admin_user.email ) self.check_page_for_string( message ) self.home() - def test_165_change_permissions_on_datasets_uploaded_from_library_dir( self ): + def test_160_change_permissions_on_datasets_uploaded_from_library_dir( self ): """Testing changing the permissions on datasets uploaded from a directory""" # It would be nice if twill functioned such that the above test resulted in a # form with the uploaded datasets selected, but it does not ( they're not checked ), @@ -1176,7 +1174,7 @@ class TestSecurityAndLibraries( TwillTestCase ): def build_url( permissions, role ): # We'll bypass the library_admin/datasets method and directly call the library_admin/dataset method, setting # access, manage permissions, and edit metadata permissions to role_one - url = '/library_admin/library_dataset_dataset_association?permissions=True&id=%s&library_id=%s&folder_id=%s&update_roles_button=Save' % ( ldda_ids, str( library_one.id ), str( folder_one.id ) ) + url = '/library_admin/ldda_manage_permissions?obj_id=%s&library_id=%s&folder_id=%s&update_roles_button=Save' % ( ldda_ids, str( library_one.id ), str( folder_one.id ) ) for p in permissions: url += '&%s_in=%s' % ( p, str( role.id ) ) return url @@ -1213,7 +1211,7 @@ class TestSecurityAndLibraries( TwillTestCase ): # access to any of the 3 datasets, so she will not see folder_one on the libraries page self.login( email='test2@bx.psu.edu' ) self.home() - self.visit_url( '%s/library/browse_library?id=%s' % ( self.url, str( library_one.id ) ) ) + self.visit_url( '%s/library/browse_library?obj_id=%s' % ( self.url, str( library_one.id ) ) ) try: self.check_page_for_string( folder_one.name ) raise AssertionError( '%s can access folder %s even though all contained datasets should be restricted from access by her' \ @@ -1268,7 +1266,7 @@ class TestSecurityAndLibraries( TwillTestCase ): pass check_edit_page2( latest_3_lddas ) self.home() - def test_170_upload_directory_of_files_from_libraries_view( self ): + def test_165_upload_directory_of_files_from_libraries_view( self ): """Testing uploading a directory of files to a root folder from the Data Libraries view""" # admin_user will not have the option sto upload a directory of files from the # Libraries view since a sub-directory named the same as their email is not contained @@ -1287,7 +1285,7 @@ class TestSecurityAndLibraries( TwillTestCase ): check_str_after_submit=check_str_after_submit, message=message.replace( '+', ' ' ) ) self.home() - self.visit_page( 'library/browse_library?id=%s' % ( str( library_one.id ) ) ) + self.visit_page( 'library/browse_library?obj_id=%s' % ( str( library_one.id ) ) ) self.check_page_for_string( regular_user1.email ) self.check_page_for_string( message ) self.logout() @@ -1302,14 +1300,14 @@ class TestSecurityAndLibraries( TwillTestCase ): check_str_after_submit=check_str_after_submit, message=message.replace( '+', ' ' ) ) self.home() - self.visit_page( 'library/browse_library?id=%s' % ( str( library_one.id ) ) ) + self.visit_page( 'library/browse_library?obj_id=%s' % ( str( library_one.id ) ) ) self.check_page_for_string( regular_user3.email ) self.check_page_for_string( message ) self.home() self.logout() self.login( email=admin_user.email ) - def test_175_mark_group_deleted( self ): + def test_170_mark_group_deleted( self ): """Testing marking a group as deleted""" self.home() self.visit_url( '%s/admin/groups' % self.url ) @@ -1323,13 +1321,13 @@ class TestSecurityAndLibraries( TwillTestCase ): raise AssertionError( '%s incorrectly lost all members when it was marked as deleted.' % group_two.name ) if not group_two.roles: raise AssertionError( '%s incorrectly lost all role associations when it was marked as deleted.' % group_two.name ) - def test_180_undelete_group( self ): + def test_175_undelete_group( self ): """Testing undeleting a deleted group""" self.undelete_group( str( group_two.id ), group_two.name ) group_two.refresh() if group_two.deleted: raise AssertionError( '%s was not correctly marked as not deleted.' % group_two.name ) - def test_185_mark_role_deleted( self ): + def test_180_mark_role_deleted( self ): """Testing marking a role as deleted""" self.home() self.visit_url( '%s/admin/roles' % self.url ) @@ -1343,15 +1341,15 @@ class TestSecurityAndLibraries( TwillTestCase ): raise AssertionError( '%s incorrectly lost all user associations when it was marked as deleted.' % role_two.name ) if not role_two.groups: raise AssertionError( '%s incorrectly lost all group associations when it was marked as deleted.' % role_two.name ) - def test_190_undelete_role( self ): + def test_185_undelete_role( self ): """Testing undeleting a deleted role""" self.undelete_role( str( role_two.id ), role_two.name ) - def test_195_mark_dataset_deleted( self ): + def test_190_mark_dataset_deleted( self ): """Testing marking a library dataset as deleted""" self.home() self.delete_library_item( str( library_one.id ), str( ldda_two.library_dataset.id ), ldda_two.name, library_item_type='library_dataset' ) self.home() - self.visit_page( 'library_admin/browse_library?id=%s' % ( str( library_one.id ) ) ) + self.visit_page( 'library_admin/browse_library?obj_id=%s' % ( str( library_one.id ) ) ) try: # 2.bed was only contained in the library in 1 place, so it should no longer display self.check_page_for_string( ldda_two.name ) @@ -1359,40 +1357,40 @@ class TestSecurityAndLibraries( TwillTestCase ): except: pass self.home() - def test_200_display_deleted_dataset( self ): + def test_195_display_deleted_dataset( self ): """Testing displaying deleted dataset""" self.home() - self.visit_url( "%s/library_admin/browse_library?id=%s&show_deleted=True" % ( self.url, str( library_one.id ) ) ) + self.visit_url( "%s/library_admin/browse_library?obj_id=%s&show_deleted=True" % ( self.url, str( library_one.id ) ) ) self.check_page_for_string( ldda_two.name ) self.home() - def test_205_hide_deleted_dataset( self ): + def test_200_hide_deleted_dataset( self ): """Testing hiding deleted dataset""" self.home() - self.visit_url( "%s/library_admin/browse_library?id=%s&show_deleted=False" % ( self.url, str( library_one.id ) ) ) + self.visit_url( "%s/library_admin/browse_library?obj_id=%s&show_deleted=False" % ( self.url, str( library_one.id ) ) ) try: self.check_page_for_string( ldda_two.name ) raise AssertionError( "Dataset '%s' is incorrectly displayed in the library after it has been deleted." % ldda_two.name ) except: pass self.home() - def test_210_mark_folder_deleted( self ): + def test_205_mark_folder_deleted( self ): """Testing marking a library folder as deleted""" self.home() self.delete_library_item( str( library_one.id ), str( folder_two.id ), folder_two.name, library_item_type='folder' ) self.home() - self.visit_page( 'library_admin/browse_library?id=%s' % ( str( library_one.id ) ) ) + self.visit_page( 'library_admin/browse_library?obj_id=%s' % ( str( library_one.id ) ) ) try: self.check_page_for_string( folder_two.name ) raise AssertionError( "Folder '%s' is incorrectly displayed in the library after it has been deleted." % folder_two.name ) except: pass self.home() - def test_215_mark_folder_undeleted( self ): + def test_210_mark_folder_undeleted( self ): """Testing marking a library folder as undeleted""" self.home() self.undelete_library_item( str( library_one.id ), str( folder_two.id ), folder_two.name, library_item_type='folder' ) self.home() - self.visit_page( 'library_admin/browse_library?id=%s' % ( str( library_one.id ) ) ) + self.visit_page( 'library_admin/browse_library?obj_id=%s' % ( str( library_one.id ) ) ) self.check_page_for_string( folder_two.name ) try: # 2.bed was deleted before the folder was deleted, so state should have been saved. In order @@ -1402,7 +1400,7 @@ class TestSecurityAndLibraries( TwillTestCase ): except: pass self.home() - def test_220_mark_library_deleted( self ): + def test_215_mark_library_deleted( self ): """Testing marking a library as deleted""" self.home() # First mark folder_two as deleted to further test state saving when we undelete the library @@ -1412,12 +1410,12 @@ class TestSecurityAndLibraries( TwillTestCase ): self.visit_page( 'library_admin/deleted_libraries' ) self.check_page_for_string( library_one.name ) self.home() - def test_225_mark_library_undeleted( self ): + def test_220_mark_library_undeleted( self ): """Testing marking a library as undeleted""" self.home() self.undelete_library_item( str( library_one.id ), str( library_one.id ), library_one.name, library_item_type='library' ) self.home() - self.visit_page( 'library_admin/browse_library?id=%s' % ( str( library_one.id ) ) ) + self.visit_page( 'library_admin/browse_library?obj_id=%s' % ( str( library_one.id ) ) ) self.check_page_for_string( library_one.name ) try: # folder_two was marked deleted before the library was deleted, so it should not be displayed @@ -1426,7 +1424,7 @@ class TestSecurityAndLibraries( TwillTestCase ): except: pass self.home() - def test_230_purge_user( self ): + def test_225_purge_user( self ): """Testing purging a user account""" self.mark_user_deleted( user_id=self.security.encode_id( regular_user3.id ), email=regular_user3.email ) regular_user3.refresh() @@ -1458,7 +1456,7 @@ class TestSecurityAndLibraries( TwillTestCase ): role = galaxy.model.Role.get( ura.role_id ) if role.type != 'private': raise AssertionError( 'UserRoleAssociations for user %s are not related with the private role.' % regular_user3.email ) - def test_235_manually_unpurge_user( self ): + def test_230_manually_unpurge_user( self ): """Testing manually un-purging a user account""" # Reset the user for later test runs. The user's private Role and DefaultUserPermissions for that role # should have been preserved, so all we need to do is reset purged and deleted. @@ -1466,7 +1464,7 @@ class TestSecurityAndLibraries( TwillTestCase ): regular_user3.purged = False regular_user3.deleted = False regular_user3.flush() - def test_240_purge_group( self ): + def test_235_purge_group( self ): """Testing purging a group""" group_id = str( group_two.id ) self.mark_group_deleted( group_id, group_two.name ) @@ -1481,7 +1479,7 @@ class TestSecurityAndLibraries( TwillTestCase ): raise AssertionError( "Purging the group did not delete the GroupRoleAssociations for group_id '%s'" % group_id ) # Undelete the group for later test runs self.undelete_group( group_id, group_two.name ) - def test_245_purge_role( self ): + def test_240_purge_role( self ): """Testing purging a role""" role_id = str( role_two.id ) self.mark_role_deleted( role_id, role_two.name ) @@ -1506,14 +1504,14 @@ class TestSecurityAndLibraries( TwillTestCase ): dp = galaxy.model.DatasetPermissions.filter( galaxy.model.DatasetPermissions.table.c.role_id == role_id ).all() if dp: raise AssertionError( "Purging the role did not delete the DatasetPermissionss for role_id '%s'" % role_id ) - def test_250_manually_unpurge_role( self ): + def test_245_manually_unpurge_role( self ): """Testing manually un-purging a role""" # Manually unpurge, then undelete the role for later test runs # TODO: If we decide to implement the GUI feature for un-purging a role, replace this with a method call role_two.purged = False role_two.flush() self.undelete_role( str( role_two.id ), role_two.name ) - def test_255_purge_library( self ): + def test_250_purge_library( self ): """Testing purging a library""" self.home() self.delete_library_item( str( library_one.id ), str( library_one.id ), library_one.name, library_item_type='library' ) @@ -1549,7 +1547,7 @@ class TestSecurityAndLibraries( TwillTestCase ): raise AssertionError( 'The library_dataset id %s named "%s" has not been marked as deleted.' % \ ( str( library_dataset.id ), library_dataset.name ) ) check_folder( library_one.root_folder ) - def test_260_no_library_template( self ): + def test_255_no_library_template( self ): """Test library features when library has no template""" name = "Library Two" description = "This is Library Two" @@ -1575,7 +1573,7 @@ class TestSecurityAndLibraries( TwillTestCase ): .order_by( desc( galaxy.model.LibraryDatasetDatasetAssociation.table.c.create_time ) ).first() assert ldda_seven is not None, 'Problem retrieving LibraryDatasetDatasetAssociation ldda_seven from the database' self.home() - self.visit_url( '%s/library_admin/browse_library?id=%s' % ( self.url, str( library_two.id ) ) ) + self.visit_url( '%s/library_admin/browse_library?obj_id=%s' % ( self.url, str( library_two.id ) ) ) self.check_page_for_string( "7.bed" ) self.check_page_for_string( admin_user.email ) # TODO: add a functional test to cover adding a library dataset via url_paste here... @@ -1585,6 +1583,23 @@ class TestSecurityAndLibraries( TwillTestCase ): self.delete_library_item( str( library_two.id ), str( library_two.id ), library_two.name, library_item_type='library' ) self.purge_library( str( library_two.id ), library_two.name ) self.home() + def test_260_library_permissions( self ): + """Test library permissions""" + name = "Library Three" + description = "This is Library Three" + # Create a library, adding no template + self.create_library( name=name, description=description ) + self.visit_page( 'library_admin/browse_libraries' ) + self.check_page_for_string( name ) + self.check_page_for_string( description ) + library_three = galaxy.model.Library.filter( and_( galaxy.model.Library.table.c.name==name, + galaxy.model.Library.table.c.description==description, + galaxy.model.Library.table.c.deleted==False ) ).first() + assert library_three is not None, 'Problem retrieving library named "%s" from the database' % name + # TODO: add tests here... + self.home() + self.delete_library_item( str( library_three.id ), str( library_three.id ), library_three.name, library_item_type='library' ) + self.purge_library( str( library_three.id ), library_three.name ) def test_265_reset_data_for_later_test_runs( self ): """Reseting data to enable later test runs to pass""" ##################