details:
http://www.bx.psu.edu/hg/galaxy/rev/4743015d9a57
changeset: 3194:4743015d9a57
user: Greg Von Kuster <greg(a)bx.psu.edu>
date: Wed Dec 23 20:26:01 2009 -0500
description:
Data library cleanup
- move / merge all duplicate methods from the library_and library_admin controllers into
the library_common controller
- move / merge all duplicate mako templates into the ~/library/common directory
- make the admin view library browser a grid
- all library item ids are now encoded
diffstat:
lib/galaxy/model/__init__.py | 14 +
lib/galaxy/tools/actions/upload_common.py | 2 +-
lib/galaxy/web/controllers/library.py | 944 ----------
lib/galaxy/web/controllers/library_admin.py | 1004 +----------
lib/galaxy/web/controllers/library_common.py | 1119 ++++++++++++-
lib/galaxy/web/controllers/tool_runner.py | 2 +-
templates/admin/library/browse_libraries.mako | 51 -
templates/admin/library/browse_library.mako | 325 ---
templates/admin/library/common.mako | 59 -
templates/admin/library/folder_info.mako | 39 -
templates/admin/library/folder_permissions.mako | 22 -
templates/admin/library/grid.mako | 1 +
templates/admin/library/ldda_edit_info.mako | 135 -
templates/admin/library/ldda_info.mako | 110 -
templates/admin/library/ldda_permissions.mako | 64 -
templates/admin/library/library_dataset_info.mako | 50 -
templates/admin/library/library_dataset_permissions.mako | 28 -
templates/admin/library/library_info.mako | 50 -
templates/admin/library/library_permissions.mako | 21 -
templates/admin/library/new_folder.mako | 44 -
templates/admin/library/new_library.mako | 2 +-
templates/admin/library/upload.mako | 50 -
templates/admin/requests/show_request.mako | 2 +-
templates/base_panels.mako | 4 +-
templates/library/browse_libraries.mako | 2 +-
templates/library/browse_library.mako | 388 ----
templates/library/common.mako | 59 -
templates/library/common/browse_library.mako | 441 +++++
templates/library/common/common.mako | 370 ++++
templates/library/common/folder_info.mako | 56 +
templates/library/common/folder_permissions.mako | 20 +
templates/library/common/ldda_edit_info.mako | 171 +
templates/library/common/ldda_info.mako | 114 +
templates/library/common/ldda_permissions.mako | 65 +
templates/library/common/library_dataset_info.mako | 71 +
templates/library/common/library_dataset_permissions.mako | 34 +
templates/library/common/library_info.mako | 61 +
templates/library/common/library_item_info.mako | 15 +
templates/library/common/library_permissions.mako | 28 +
templates/library/common/new_folder.mako | 44 +
templates/library/common/select_info_template.mako | 44 +
templates/library/common/upload.mako | 56 +
templates/library/folder_info.mako | 53 -
templates/library/folder_permissions.mako | 20 -
templates/library/ldda_edit_info.mako | 168 -
templates/library/ldda_info.mako | 112 -
templates/library/ldda_permissions.mako | 64 -
templates/library/library_dataset_common.mako | 265 ---
templates/library/library_dataset_info.mako | 68 -
templates/library/library_dataset_permissions.mako | 31 -
templates/library/library_info.mako | 64 -
templates/library/library_item_info.mako | 15 -
templates/library/library_permissions.mako | 25 -
templates/library/new_folder.mako | 44 -
templates/library/select_info_template.mako | 44 -
templates/library/upload.mako | 47 -
templates/mobile/manage_library.mako | 16 +-
templates/requests/show_request.mako | 9 +-
test/base/twilltestcase.py | 109 +-
test/functional/test_forms_and_requests.py | 14 +-
test/functional/test_security_and_libraries.py | 416 +++-
61 files changed, 3147 insertions(+), 4618 deletions(-)
diffs (truncated from 9178 to 3000 lines):
diff -r 9f966847abda -r 4743015d9a57 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py Tue Dec 22 18:49:34 2009 -0500
+++ b/lib/galaxy/model/__init__.py Wed Dec 23 20:26:01 2009 -0500
@@ -746,6 +746,13 @@
return template.get_widgets( trans.user, contents=info.content )
return template.get_widgets( trans.user )
return []
+ def get_display_name( self ):
+ # Library name can be either a string or a unicode object. If string,
+ # convert to unicode object assuming 'utf-8' format.
+ name = self.name
+ if isinstance( name, str ):
+ name = unicode( name, 'utf-8' )
+ return name
class LibraryFolder( object ):
def __init__( self, name=None, description=None, item_count=0, order_id=None ):
@@ -811,6 +818,13 @@
def active_datasets( self ):
# This needs to be a list
return [ ld.library_dataset_dataset_association.dataset for ld in self.datasets
if not ld.library_dataset_dataset_association.deleted ]
+ def get_display_name( self ):
+ # Library folder name can be either a string or a unicode object. If string,
+ # convert to unicode object assuming 'utf-8' format.
+ name = self.name
+ if isinstance( name, str ):
+ name = unicode( name, 'utf-8' )
+ return name
class LibraryDataset( object ):
# This class acts as a proxy to the currently selected LDDA
diff -r 9f966847abda -r 4743015d9a57 lib/galaxy/tools/actions/upload_common.py
--- a/lib/galaxy/tools/actions/upload_common.py Tue Dec 22 18:49:34 2009 -0500
+++ b/lib/galaxy/tools/actions/upload_common.py Wed Dec 23 20:26:01 2009 -0500
@@ -41,7 +41,7 @@
# See if we have any template field contents
library_bunch.template_field_contents = []
template_id = params.get( 'template_id', None )
- library_bunch.folder = trans.sa_session.query( trans.app.model.LibraryFolder ).get(
folder_id )
+ library_bunch.folder = trans.sa_session.query( trans.app.model.LibraryFolder ).get(
trans.security.decode_id( folder_id ) )
# We are inheriting the folder's info_association, so we did not
# receive any inherited contents, but we may have redirected here
# after the user entered template contents ( due to errors ).
diff -r 9f966847abda -r 4743015d9a57 lib/galaxy/web/controllers/library.py
--- a/lib/galaxy/web/controllers/library.py Tue Dec 22 18:49:34 2009 -0500
+++ b/lib/galaxy/web/controllers/library.py Wed Dec 23 20:26:01 2009 -0500
@@ -3,50 +3,9 @@
from galaxy.datatypes import sniff
from galaxy import util
from galaxy.util.odict import odict
-from galaxy.util.streamball import StreamBall
-import logging, tempfile, zipfile, tarfile, os, sys
-
-if sys.version_info[:2] < ( 2, 6 ):
- zipfile.BadZipFile = zipfile.error
-if sys.version_info[:2] < ( 2, 5 ):
- zipfile.LargeZipFile = zipfile.error
log = logging.getLogger( __name__ )
-# Test for available compression types
-tmpd = tempfile.mkdtemp()
-comptypes = []
-for comptype in ( 'gz', 'bz2' ):
- tmpf = os.path.join( tmpd, 'compression_test.tar.' + comptype )
- try:
- archive = tarfile.open( tmpf, 'w:' + comptype )
- archive.close()
- comptypes.append( comptype )
- except tarfile.CompressionError:
- log.exception( "Compression error when testing %s compression. This option
will be disabled for library downloads." % comptype )
- try:
- os.unlink( tmpf )
- except OSError:
- pass
-ziptype = '32'
-tmpf = os.path.join( tmpd, 'compression_test.zip' )
-try:
- archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_DEFLATED, True )
- archive.close()
- comptypes.append( 'zip' )
- ziptype = '64'
-except RuntimeError:
- log.exception( "Compression error when testing zip compression. This option will
be disabled for library downloads." )
-except (TypeError, zipfile.LargeZipFile):
- # ZIP64 is only in Python2.5+. Remove TypeError when 2.4 support is dropped
- log.warning( 'Max zip file size is 2GB, ZIP64 not supported' )
- comptypes.append( 'zip' )
-try:
- os.unlink( tmpf )
-except OSError:
- pass
-os.rmdir( tmpd )
-
class Library( BaseController ):
@web.expose
def index( self, trans, **kwd ):
@@ -89,906 +48,3 @@
default_action=params.get( 'default_action',
None ),
msg=msg,
messagetype=messagetype )
- @web.expose
- def browse_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 not library_id:
- # To handle bots
- msg = "You must specify a library id."
- return trans.response.send_redirect( web.url_for(
controller='library',
-
action='browse_libraries',
- default_action=params.get(
'default_action', None ),
- msg=util.sanitize_text( msg
),
- messagetype='error'
) )
- library = trans.sa_session.query( trans.app.model.Library ).get( library_id )
- if not library:
- # To handle bots
- 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 ),
- msg=util.sanitize_text( msg
),
- messagetype='error'
) )
- created_ldda_ids = params.get( 'created_ldda_ids', '' )
- hidden_folder_ids = util.listify( util.restore_text( params.get(
'hidden_folder_ids', '' ) ) )
- if created_ldda_ids and not msg:
- msg = "%d datasets are now uploading in the background to the library
'%s' ( each is selected ). " % ( len( created_ldda_ids.split(',')
), library.name )
- msg += "Do not navigate away from Galaxy or use the browser's
\"stop\" or \"reload\" buttons ( on this tab ) until the upload(s)
change from the \"uploading\" state."
- messagetype = "info"
- return trans.fill_template( '/library/browse_library.mako',
- library=library,
- created_ldda_ids=created_ldda_ids,
- hidden_folder_ids=hidden_folder_ids,
- default_action=params.get( 'default_action',
None ),
- comptypes=comptypes,
- msg=msg,
- messagetype=messagetype )
- @web.expose
- 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'
- elif params.get( 'permissions', False ):
- action = 'permissions'
- else:
- action = 'information'
- 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.sa_session.query( trans.app.model.Library ).get( int( library_id
) )
- if not library:
- 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
),
- messagetype='error'
) )
- if action == 'information':
- # See if we have any associated templates
- widgets = library.get_template_widgets( trans )
- if params.get( 'rename_library_button', False ):
- old_name = library.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/library_info.mako',
- library=library,
- widgets=widgets,
- msg=msg,
- messagetype='error' )
- else:
- library.name = new_name
- library.description = new_description
- # Rename the root_folder
- library.root_folder.name = new_name
- library.root_folder.description = new_description
- trans.sa_session.add_all( ( library, library.root_folder ) )
- trans.sa_session.flush()
- msg = "Library '%s' has been renamed to
'%s'" % ( old_name, new_name )
- return trans.response.send_redirect( web.url_for(
controller='library',
-
action='library',
- obj_id=library.id,
- edit_info=True,
-
msg=util.sanitize_text( msg ),
-
messagetype='done' ) )
- return trans.fill_template( '/library/library_info.mako',
- library=library,
- 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
- permissions = {}
- for k, v in trans.app.model.Library.permitted_actions.items():
- in_roles = [ trans.sa_session.query( 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
- trans.app.security_agent.set_all_library_permissions( library,
permissions )
- trans.sa_session.refresh( library )
- # Copy the permissions to the root folder
- trans.app.security_agent.copy_library_permissions( library,
library.root_folder )
- msg = "Permissions updated for library '%s'" %
library.name
- return trans.response.send_redirect( web.url_for(
controller='library',
-
action='library',
- obj_id=library.id,
- permissions=True,
- msg=util.sanitize_text(
msg ),
-
messagetype='done' ) )
- return trans.fill_template( '/library/library_permissions.mako',
- library=library,
- msg=msg,
- messagetype=messagetype )
- @web.expose
- 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 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.sa_session.query( 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',
- 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 )
- trans.sa_session.add( new_folder )
- trans.sa_session.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',
- 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
- trans.sa_session.add( folder )
- trans.sa_session.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.sa_session.query( 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 )
- trans.sa_session.refresh( folder )
- msg = 'Permissions updated for folder %s' % folder.name
- 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='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' ) )
- return trans.fill_template( '/library/folder_permissions.mako',
- folder=folder,
- library_id=library_id,
- msg=msg,
- messagetype=messagetype )
- @web.expose
- 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' )
- if params.get( 'permissions', False ):
- action = 'permissions'
- else:
- action = 'information'
- library_dataset = trans.sa_session.query( trans.app.model.LibraryDataset ).get(
obj_id )
- if not library_dataset:
- msg = "Invalid library dataset specified, 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'
) )
- user, roles = trans.get_user_and_roles()
- if action == 'information':
- if params.get( 'edit_attributes_button', False ):
- if trans.app.security_agent.can_modify_library_item( user, roles,
library_dataset ):
- if params.get( 'edit_attributes_button', False ):
- old_name = library_dataset.name
- new_name = util.restore_text( params.get( 'name',
'' ) )
- new_info = util.restore_text( params.get( 'info',
'' ) )
- if not new_name:
- msg = 'Enter a valid name'
- messagetype = 'error'
- else:
- library_dataset.name = new_name
- library_dataset.info = new_info
- trans.sa_session.add( library_dataset )
- trans.sa_session.flush()
- msg = "Dataset '%s' has been renamed to
'%s'" % ( old_name, new_name )
- messagetype = 'done'
- else:
- msg = "You are not authorized to change the attributes of this
dataset"
- messagetype = "error"
- return trans.fill_template( '/library/library_dataset_info.mako',
- library_dataset=library_dataset,
- library_id=library_id,
- msg=msg,
- messagetype=messagetype )
- elif action == 'permissions':
- if params.get( 'update_roles_button', False ):
- if trans.app.security_agent.can_manage_library_item( user, roles,
library_dataset ):
- # The user clicked the Save button on the 'Associate With
Roles' form
- permissions = {}
- for k, v in trans.app.model.Library.permitted_actions.items():
- in_roles = [ trans.sa_session.query( 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(
library_dataset, permissions )
- trans.sa_session.refresh( library_dataset )
- # Set the LIBRARY permissions on the
LibraryDatasetDatasetAssociation
- trans.app.security_agent.set_all_library_permissions(
library_dataset.library_dataset_dataset_association, permissions )
- trans.sa_session.refresh(
library_dataset.library_dataset_dataset_association )
- msg = 'Permissions and roles have been updated for library
dataset %s' % library_dataset.name
- messagetype = 'done'
- else:
- msg = "You are not authorized to managed the permissions of this
dataset"
- messagetype = "error"
- return trans.fill_template(
'/library/library_dataset_permissions.mako',
- library_dataset=library_dataset,
- library_id=library_id,
- msg=msg,
- messagetype=messagetype )
- @web.expose
- 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.sa_session.query( 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.sa_session.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_setting_metadata( ldda )
- trans.sa_session.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_setting_metadata( ldda )
- trans.sa_session.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
- trans.sa_session.add( ldda )
- trans.sa_session.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 ):
- 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.sa_session.query( 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.sa_session.query(
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.sa_session.query( 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 )
- trans.sa_session.refresh( ldda.dataset )
- permissions = {}
- for k, v in trans.app.model.Library.permitted_actions.items():
- in_roles = [ trans.sa_session.query( 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 )
- trans.sa_session.refresh( ldda.library_dataset )
- # Set the LIBRARY permissions on the
LibraryDatasetDatasetAssociation
- trans.app.security_agent.set_all_library_permissions( ldda,
permissions )
- trans.sa_session.refresh( ldda )
- 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' )
- dbkey = params.get( 'dbkey', None )
- if isinstance( dbkey, list ):
- last_used_build = dbkey[0]
- else:
- last_used_build = dbkey
- folder = trans.sa_session.query( trans.app.model.LibraryFolder ).get( folder_id
)
- if folder and last_used_build in [ 'None', None, '?' ]:
- last_used_build = folder.genome_build
- replace_id = params.get( 'replace_id', None )
- if replace_id not in [ None, 'None' ]:
- replace_dataset = trans.sa_session.query( trans.app.model.LibraryDataset
).get( replace_id )
- if not last_used_build:
- last_used_build =
replace_dataset.library_dataset_dataset_association.dbkey
- # Don't allow multiple datasets to be uploaded when replacing a dataset
with a new version
- upload_option = 'upload_file'
- else:
- replace_dataset = None
- upload_option = params.get( 'upload_option', 'upload_file' )
- user, roles = trans.get_user_and_roles()
- 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 ):
- # See if we have any inherited templates, but do not inherit contents.
- info_association, inherited = folder.get_info_association( inherited=True
)
- if info_association:
- template_id = str( info_association.template.id )
- widgets = folder.get_template_widgets( trans, get_contents=False )
- else:
- template_id = 'None'
- widgets = []
- created_outputs = trans.webapp.controllers[ 'library_common'
].upload_dataset( trans,
-
controller='library',
-
library_id=library_id,
-
folder_id=folder_id,
-
template_id=template_id,
-
widgets=widgets,
-
replace_dataset=replace_dataset,
-
**kwd )
- if created_outputs:
- ldda_id_list = [ str( v.id ) for v in created_outputs.values() ]
- total_added = len( created_outputs.values() )
- if replace_dataset:
- msg = "Added %d dataset versions to the library dataset
'%s' in the folder '%s'." % ( total_added, replace_dataset.name,
folder.name )
- else:
- if not folder.parent:
- # Libraries have the same name as their root_folder
- msg = "Added %d datasets to the library '%s' (
each is selected ). " % ( total_added, folder.name )
- else:
- msg = "Added %d datasets to the folder '%s' (
each is selected ). " % ( total_added, folder.name )
- # Since permissions on all LibraryDatasetDatasetAssociations must be
the same at this point, we only need
- # to check one of them to see if the current user can manage
permissions on them.
- check_ldda = trans.sa_session.query(
trans.app.model.LibraryDatasetDatasetAssociation ).get( ldda_id_list[0] )
- if trans.app.security_agent.can_manage_library_item( user, roles,
check_ldda ):
- if replace_dataset:
- default_action = ''
- else:
- msg += "Click the Go button at the bottom of this page
to edit the permissions on these datasets if necessary."
- default_action = 'manage_permissions'
- else:
- default_action = 'add'
- trans.response.send_redirect( web.url_for(
controller='library',
-
action='browse_library',
- obj_id=library_id,
-
default_action=default_action,
-
created_ldda_ids=",".join( ldda_id_list ),
- msg=util.sanitize_text(
msg ),
- messagetype='done'
) )
-
- else:
- msg = "Upload failed"
- trans.response.send_redirect( web.url_for(
controller='library',
-
action='browse_library',
- obj_id=library_id,
-
created_ldda_ids=",".join( ldda_id_list ),
- msg=util.sanitize_text(
msg ),
-
messagetype='error' ) )
- # 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.sa_session.query( trans.app.model.Role ) \
- .filter( trans.app.model.Role.table.c.deleted==False ) \
- .order_by( trans.app.model.Role.table.c.name )
- # Send the current history to the form to enable importing datasets from history
to library
- history = trans.get_history()
- trans.sa_session.refresh( history )
- # 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 )
- msg = util.restore_text( params.get( 'msg', '' ) )
- messagetype = params.get( 'messagetype', 'done' )
- try:
- folder = trans.sa_session.query( trans.app.model.LibraryFolder ).get( int(
folder_id ) )
- except:
- msg = "Invalid folder id: %s" % str( folder_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'
) )
- replace_id = params.get( 'replace_id', None )
- if replace_id:
- replace_dataset = trans.sa_session.query( trans.app.model.LibraryDataset
).get( replace_id )
- else:
- replace_dataset = None
- # See if the current history is empty
- history = trans.get_history()
- trans.sa_session.refresh( history )
- if not history.active_datasets:
- msg = 'Your current history is empty'
- return trans.response.send_redirect( web.url_for(
controller='library',
-
action='browse_library',
- obj_id=library_id,
- msg=util.sanitize_text( msg
),
- messagetype='error'
) )
- if params.get( 'add_history_datasets_to_library_button', False ):
- hda_ids = util.listify( hda_ids )
- if hda_ids:
- dataset_names = []
- created_ldda_ids = ''
- for hda_id in hda_ids:
- hda = trans.sa_session.query(
trans.app.model.HistoryDatasetAssociation ).get( hda_id )
- if hda:
- ldda = hda.to_library_dataset_dataset_association(
target_folder=folder, replace_dataset=replace_dataset )
- created_ldda_ids = '%s,%s' % ( created_ldda_ids, str(
ldda.id ) )
- dataset_names.append( ldda.name )
- if not replace_dataset:
- # If replace_dataset is None, the Library level permissions
will be taken from the folder and applied to the new
- # LDDA and LibraryDataset.
- trans.app.security_agent.copy_library_permissions( folder,
ldda )
- trans.app.security_agent.copy_library_permissions( folder,
ldda.library_dataset )
- # Permissions must be the same on the
LibraryDatasetDatasetAssociation and the associated LibraryDataset
- trans.app.security_agent.copy_library_permissions(
ldda.library_dataset, ldda )
- else:
- msg = "The requested HistoryDatasetAssociation id %s is
invalid" % str( hda_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' ) )
- if created_ldda_ids:
- created_ldda_ids = created_ldda_ids.lstrip( ',' )
- ldda_id_list = created_ldda_ids.split( ',' )
- total_added = len( ldda_id_list )
- if replace_dataset:
- msg = "Added %d dataset versions to the library dataset
'%s' in the folder '%s'." % ( total_added, replace_dataset.name,
folder.name )
- else:
- if not folder.parent:
- # Libraries have the same name as their root_folder
- msg = "Added %d datasets to the library '%s' (
each is selected ). " % ( total_added, folder.name )
- else:
- msg = "Added %d datasets to the folder '%s' (
each is selected ). " % ( total_added, folder.name )
- # Since permissions on all LibraryDatasetDatasetAssociations must be
the same at this point, we only need
- # to check one of them to see if the current user can manage
permissions on them.
- check_ldda = trans.sa_session.query(
trans.app.model.LibraryDatasetDatasetAssociation ).get( ldda_id_list[0] )
- user, roles = trans.get_user_and_roles()
- if trans.app.security_agent.can_manage_library_item( user, roles,
check_ldda ):
- if replace_dataset:
- default_action = ''
- else:
- msg += "Click the Go button at the bottom of this page
to edit the permissions on these datasets if necessary."
- default_action = 'manage_permissions'
- else:
- default_action = 'add'
- return trans.response.send_redirect( web.url_for(
controller='library',
-
action='browse_library',
- obj_id=library_id,
-
created_ldda_ids=created_ldda_ids.lstrip( ',' ),
-
default_action=default_action,
-
msg=util.sanitize_text( msg ),
-
messagetype='done' ) )
- else:
- msg = 'Select at least one dataset from the list of active datasets
in your current history'
- messagetype = 'error'
- last_used_build = folder.genome_build
- upload_option = params.get( 'upload_option',
'import_from_history' )
- # 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.sa_session.query( trans.app.model.Role ) \
- .filter(
trans.app.model.Role.table.c.deleted==False ) \
- .order_by( trans.app.model.Role.table.c.name )
- return trans.fill_template( "/library/upload.mako",
- upload_option=upload_option,
- 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=[],
- 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',
- 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 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',
- 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.sa_session.query(
trans.app.model.LibraryDatasetDatasetAssociation ).get( ldda_id )
- hda = ldda.to_history_dataset_association( target_history=history,
add_to_history = True )
- trans.sa_session.add( history )
- trans.sa_session.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.sa_session.query(
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',
- obj_id=library_id,
- msg=util.sanitize_text(
msg ),
-
messagetype='error' ) )
- seen = []
- user, roles = trans.get_user_and_roles()
- for ldda_id in ldda_ids:
- ldda = trans.sa_session.query(
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='browse_library',
- obj_id=library_id,
-
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',
- 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 -r 9f966847abda -r 4743015d9a57 lib/galaxy/web/controllers/library_admin.py
--- a/lib/galaxy/web/controllers/library_admin.py Tue Dec 22 18:49:34 2009 -0500
+++ b/lib/galaxy/web/controllers/library_admin.py Wed Dec 23 20:26:01 2009 -0500
@@ -1,6 +1,7 @@
import sys
from galaxy import util
from galaxy.web.base.controller import *
+from galaxy.web.framework.helpers import time_ago, iff, grids
from galaxy.model.orm import *
# Older py compatibility
try:
@@ -11,199 +12,123 @@
import logging
log = logging.getLogger( __name__ )
+# States for passing messages
+SUCCESS, INFO, WARNING, ERROR = "done", "info", "warning",
"error"
+
+class LibraryListGrid( grids.Grid ):
+ class NameColumn( grids.TextColumn ):
+ def get_value( self, trans, grid, library ):
+ return library.name
+ class DescriptionColumn( grids.TextColumn ):
+ def get_value( self, trans, grid, library ):
+ if library.description:
+ return library.description
+ return ''
+ class StatusColumn( grids.GridColumn ):
+ def get_value( self, trans, grid, library ):
+ if library.purged:
+ return "purged"
+ elif library.deleted:
+ return "deleted"
+ return ""
+ class DeletedColumn( grids.GridColumn ):
+ def get_accepted_filters( self ):
+ """ Returns a list of accepted filters for this column.
"""
+ accepted_filter_labels_and_vals = { "active" : "False",
"deleted" : "True", "all": "All" }
+ accepted_filters = []
+ for label, val in accepted_filter_labels_and_vals.items():
+ args = { self.key: val }
+ accepted_filters.append( grids.GridColumnFilter( label, args) )
+ return accepted_filters
+ # Grid definition
+ title = "Data Libraries"
+ model_class = model.Library
+ template='/admin/library/grid.mako'
+ default_sort_key = "name"
+ columns = [
+ NameColumn( "Library Name",
+ key="name",
+ model_class=model.Library,
+ link=( lambda library: dict( operation="browse",
id=library.id ) ),
+ attach_popup=False,
+ filterable="advanced" ),
+ DescriptionColumn( "Description",
+ key="description",
+ model_class=model.Library,
+ attach_popup=False,
+ filterable="advanced" ),
+ grids.GridColumn( "Created", key="create_time",
format=time_ago ),
+ grids.GridColumn( "Last Updated", key="update_time",
format=time_ago ),
+ StatusColumn( "Status", attach_popup=False ),
+ # Columns that are valid for filtering but are not visible.
+ DeletedColumn( "Deleted", key="deleted", visible=False,
filterable="advanced" )
+ ]
+ columns.append( grids.MulticolFilterColumn( "Search",
+ cols_to_filter=[ columns[0], columns[1]
],
+ key="free-text-search",
+ visible=False,
+ filterable="standard" ) )
+ global_actions = [
+ grids.GridAction( "Create new data library", dict(
controller='library_admin', action='create_library' ) )
+ ]
+ standard_filters = [
+ grids.GridColumnFilter( "Active", args=dict( deleted=False ) ),
+ grids.GridColumnFilter( "Deleted", args=dict( deleted=True,
purged=False ) ),
+ grids.GridColumnFilter( "Purged", args=dict( purged=True ) ),
+ grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
+ ]
+ default_filter = dict( name="All", description="All",
deleted="False", purged="False" )
+ num_rows_per_page = 50
+ preserve_state = False
+ use_paging = True
+ def build_initial_query( self, session ):
+ return session.query( self.model_class )
+
class LibraryAdmin( BaseController ):
+
+ library_list_grid = LibraryListGrid()
+
@web.expose
@web.require_admin
- def browse_libraries( self, trans, **kwd ):
+ def browse_libraries( self, trans, **kwargs ):
+ if 'operation' in kwargs:
+ operation = kwargs['operation'].lower()
+ if operation == "browse":
+ return trans.response.send_redirect( web.url_for(
controller='library_common',
+
action='browse_library',
+
cntrller='library_admin',
+ **kwargs ) )
+ # Render the list view
+ return self.library_list_grid( trans, **kwargs )
+ @web.expose
+ @web.require_admin
+ def create_library( self, trans, **kwd ):
params = util.Params( kwd )
msg = util.restore_text( params.get( 'msg', '' ) )
messagetype = params.get( 'messagetype', 'done' )
- return trans.fill_template( '/admin/library/browse_libraries.mako',
- libraries=trans.sa_session.query(
trans.app.model.Library ) \
- .filter(
trans.app.model.Library.table.c.deleted==False ) \
- .order_by(
trans.app.model.Library.name ),
- deleted=False,
- show_deleted=False,
- msg=msg,
- messagetype=messagetype )
- @web.expose
- @web.require_admin
- def browse_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 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',
+ if params.get( 'new', False ):
+ library = trans.app.model.Library( name = util.restore_text( params.name ),
+ description = util.restore_text(
params.description ) )
+ root_folder = trans.app.model.LibraryFolder( name = util.restore_text(
params.name ), description = "" )
+ library.root_folder = root_folder
+ trans.sa_session.add_all( ( library, root_folder ) )
+ trans.sa_session.flush()
+ msg = "The new library named '%s' has been created" %
library.name
+ return trans.response.send_redirect( web.url_for(
controller='library_common',
+
action='browse_library',
+
cntrller='library_admin',
+
id=trans.security.encode_id( library.id ),
msg=util.sanitize_text( msg
),
- messagetype='error'
) )
- deleted = util.string_as_bool( params.get( 'deleted', False ) )
- show_deleted = util.string_as_bool( params.get( 'show_deleted', False )
)
- library = trans.sa_session.query( trans.app.model.Library ).get( library_id )
- if not library:
- 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
),
- messagetype='error'
) )
- created_ldda_ids = params.get( 'created_ldda_ids', '' )
- if created_ldda_ids and not msg:
- msg = "%d datasets are now uploading in the background to the library
'%s' ( each is selected ). " % ( len( created_ldda_ids.split( ',' )
), library.name )
- msg += "Do not navigate away from Galaxy or use the browser's
\"stop\" or \"reload\" buttons ( on this tab ) until the upload(s)
change from the \"uploading\" state."
- messagetype = "info"
- return trans.fill_template( '/admin/library/browse_library.mako',
- library=library,
- deleted=deleted,
- show_deleted=show_deleted,
- created_ldda_ids=created_ldda_ids,
- msg=msg,
- messagetype=messagetype )
- @web.expose
- @web.require_admin
- 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 ):
- action = 'delete'
- elif params.get( 'permissions', False ):
- action = 'permissions'
- else:
- action = 'information'
- 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.sa_session.query( 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
),
- description = util.restore_text(
params.description ) )
- root_folder = trans.app.model.LibraryFolder( name = util.restore_text(
params.name ), description = "" )
- library.root_folder = root_folder
- trans.sa_session.add_all( ( library, root_folder ) )
- trans.sa_session.flush()
- 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',
- obj_id=library.id,
- msg=util.sanitize_text(
msg ),
-
messagetype='done' ) )
- return trans.fill_template( '/admin/library/new_library.mako',
msg=msg, messagetype=messagetype )
- elif action == 'information':
- # See if we have any associated templates
- widgets = library.get_template_widgets( trans )
- if params.get( 'rename_library_button', False ):
- old_name = library.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(
'/admin/library/library_info.mako',
- library=library,
- widgets=widgets,
- msg=msg,
- messagetype='error' )
- else:
- library.name = new_name
- library.description = new_description
- # Rename the root_folder
- library.root_folder.name = new_name
- library.root_folder.description = new_description
- trans.sa_session.add_all( ( library, library.root_folder ) )
- trans.sa_session.flush()
- 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',
- obj_id=library.id,
- edit_info=True,
-
msg=util.sanitize_text( msg ),
-
messagetype='done' ) )
- return trans.fill_template( '/admin/library/library_info.mako',
- library=library,
- widgets=widgets,
- msg=msg,
- messagetype=messagetype )
- elif action == 'delete':
- def delete_folder( library_folder ):
- trans.sa_session.refresh( library_folder )
- for folder in library_folder.folders:
- delete_folder( folder )
- for library_dataset in library_folder.datasets:
- trans.sa_session.refresh( library_dataset )
- ldda = library_dataset.library_dataset_dataset_association
- if ldda:
- trans.sa_session.refresh( ldda )
- # We don't set ldda.dataset.deleted to True here because the
cleanup_dataset script
- # will eventually remove it from disk. The purge_library method
below sets the dataset
- # to deleted. This allows for the library to be undeleted (
before it is purged ),
- # restoring all of its contents.
- ldda.deleted = True
- trans.sa_session.add( ldda )
- library_dataset.deleted = True
- trans.sa_session.add( library_dataset )
- library_folder.deleted = True
- trans.sa_session.add( library_folder )
- trans.sa_session.flush()
- trans.sa_session.refresh( library )
- delete_folder( library.root_folder )
- library.deleted = True
- trans.sa_session.add( library )
- trans.sa_session.flush()
- msg = "Library '%s' and all of its contents have been marked
deleted" % library.name
- return trans.response.send_redirect( web.url_for(
action='browse_libraries', msg=util.sanitize_text( msg ),
messagetype='done' ) )
- elif action == 'permissions':
- if params.get( 'update_roles_button', False ):
- # The user clicked the Save button on the 'Associate With Roles'
form
- permissions = {}
- for k, v in trans.app.model.Library.permitted_actions.items():
- in_roles = [ trans.sa_session.query( 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
- trans.app.security_agent.set_all_library_permissions( library,
permissions )
- trans.sa_session.refresh( library )
- # Copy the permissions to the root folder
- trans.app.security_agent.copy_library_permissions( library,
library.root_folder )
- msg = "Permissions updated for library '%s'" %
library.name
- return trans.response.send_redirect( web.url_for(
controller='library_admin',
-
action='library',
- obj_id=library.id,
- permissions=True,
- msg=util.sanitize_text(
msg ),
-
messagetype='done' ) )
- return trans.fill_template(
'/admin/library/library_permissions.mako',
- library=library,
- msg=msg,
- messagetype=messagetype )
- @web.expose
- @web.require_admin
- def deleted_libraries( self, trans, **kwd ):
- params = util.Params( kwd )
- msg = util.restore_text( params.get( 'msg', '' ) )
- messagetype = params.get( 'messagetype', 'done' )
- libraries = trans.sa_session.query( trans.app.model.Library ) \
- .filter( and_(
trans.app.model.Library.table.c.deleted==True,
-
trans.app.model.Library.table.c.purged==False ) ) \
- .order_by( trans.app.model.Library.table.c.name )
- return trans.fill_template( '/admin/library/browse_libraries.mako',
- libraries=libraries,
- deleted=True,
- msg=msg,
- messagetype=messagetype,
- show_deleted=True )
+ messagetype='done'
) )
+ return trans.fill_template( '/admin/library/new_library.mako', msg=msg,
messagetype=messagetype )
@web.expose
@web.require_admin
def purge_library( self, trans, **kwd ):
+ # TODO: change this function to purge_library_item, behaving similar to
delete_library_item
+ # assuming we want the ability to purge libraries.
+ # This function is currently only used by the functional tests.
params = util.Params( kwd )
- library = trans.sa_session.query( trans.app.model.Library ).get( int(
params.obj_id ) )
+ library = trans.sa_session.query( trans.app.model.Library ).get(
trans.security.decode_id( params.id ) )
def purge_folder( library_folder ):
for lf in library_folder.folders:
purge_folder( lf )
@@ -232,8 +157,8 @@
msg = "Library '%s' has not been marked deleted, so it cannot be
purged" % ( library.name )
return trans.response.send_redirect( web.url_for(
controller='library_admin',
action='browse_libraries',
- msg=util.sanitize_text( msg
),
- messagetype='error'
) )
+ message=util.sanitize_text(
msg ),
+ status='error' ) )
else:
purge_folder( library.root_folder )
library.purged = True
@@ -241,680 +166,9 @@
trans.sa_session.flush()
msg = "Library '%s' and all of its contents have been purged,
datasets will be removed from disk via the cleanup_datasets script" % library.name
return trans.response.send_redirect( web.url_for(
controller='library_admin',
-
action='deleted_libraries',
- msg=util.sanitize_text( msg
),
- messagetype='done'
) )
- @web.expose
- @web.require_admin
- 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 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.sa_session.query( 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_admin',
-
action='browse_library',
- obj_id=library_id,
- msg=util.sanitize_text( msg
),
- messagetype='error'
) )
- 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 )
- trans.sa_session.add( new_folder )
- trans.sa_session.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_admin',
-
action='browse_library',
- obj_id=library_id,
- msg=util.sanitize_text(
msg ),
-
messagetype='done' ) )
- return trans.fill_template( '/admin/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 ):
- 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(
'/admin/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
- trans.sa_session.add( folder )
- trans.sa_session.flush()
- 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',
- obj_id=folder.id,
-
library_id=library_id,
- edit_info=True,
-
msg=util.sanitize_text( msg ),
-
messagetype='done' ) )
- return trans.fill_template( '/admin/library/folder_info.mako',
- folder=folder,
- library_id=library_id,
- widgets=widgets,
- msg=msg,
- messagetype=messagetype )
- elif action == 'delete':
- folder.deleted = True
- trans.sa_session.add( folder )
- trans.sa_session.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',
- obj_id=library_id,
- msg=util.sanitize_text( msg
),
- messagetype='done'
) )
- elif action =='permissions':
- if params.get( 'update_roles_button', False ):
- # The user clicked the Save button on the 'Associate With Roles'
form
- permissions = {}
- for k, v in trans.app.model.Library.permitted_actions.items():
- in_roles = [ trans.sa_session.query( 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
)
- trans.sa_session.refresh( folder )
- msg = "Permissions updated for folder '%s'" %
folder.name
- return trans.response.send_redirect( web.url_for(
controller='library_admin',
-
action='folder',
- obj_id=folder.id,
- library_id=library_id,
- permissions=True,
- msg=util.sanitize_text(
msg ),
-
messagetype='done' ) )
- return trans.fill_template(
'/admin/library/folder_permissions.mako',
- folder=folder,
- library_id=library_id,
- msg=msg,
- messagetype=messagetype )
- @web.expose
- @web.require_admin
- 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' )
- if params.get( 'permissions', False ):
- action = 'permissions'
- else:
- action = 'information'
- library_dataset = trans.sa_session.query( trans.app.model.LibraryDataset ).get(
obj_id )
- if not library_dataset:
- msg = "Invalid library dataset specified, 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'
) )
- if action == 'information':
- if params.get( 'edit_attributes_button', False ):
- old_name = library_dataset.name
- new_name = util.restore_text( params.get( 'name', '' ) )
- new_info = util.restore_text( params.get( 'info', '' ) )
- if not new_name:
- msg = 'Enter a valid name'
- messagetype = 'error'
- else:
- library_dataset.name = new_name
- library_dataset.info = new_info
- trans.sa_session.add( library_dataset )
- trans.sa_session.flush()
- msg = "Dataset '%s' has been renamed to
'%s'" % ( old_name, new_name )
- messagetype = 'done'
- return trans.fill_template(
'/admin/library/library_dataset_info.mako',
- library_dataset=library_dataset,
- library_id=library_id,
- msg=msg,
- messagetype=messagetype )
- elif action == 'permissions':
- if params.get( 'update_roles_button', False ):
- # The user clicked the Save button on the 'Edit permissions and role
associations' form
- permissions = {}
- for k, v in trans.app.model.Library.permitted_actions.items():
- in_roles = [ trans.sa_session.query( 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( library_dataset,
permissions )
- trans.sa_session.refresh( library_dataset )
- # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation
- trans.app.security_agent.set_all_library_permissions(
library_dataset.library_dataset_dataset_association, permissions )
- trans.sa_session.refresh(
library_dataset.library_dataset_dataset_association )
- msg = 'Permissions and roles have been updated for library dataset
%s' % library_dataset.name
- return trans.fill_template(
'/admin/library/library_dataset_permissions.mako',
- library_dataset=library_dataset,
- library_id=library_id,
- msg=msg,
- messagetype=messagetype )
- @web.expose
- @web.require_admin
- 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.sa_session.query( 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.sa_session.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_setting_metadata( ldda )
- trans.sa_session.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_setting_metadata( ldda )
- trans.sa_session.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
- trans.sa_session.add( ldda )
- trans.sa_session.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 )
- 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.sa_session.query( 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.sa_session.query(
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.sa_session.query( 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 )
- trans.sa_session.refresh( ldda.dataset )
- permissions = {}
- for k, v in trans.app.model.Library.permitted_actions.items():
- in_roles = [ trans.sa_session.query( 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 )
- trans.sa_session.refresh( ldda.library_dataset )
- # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation
- trans.app.security_agent.set_all_library_permissions( ldda, permissions
)
- trans.sa_session.refresh( ldda )
- 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', '?' )
- if isinstance( dbkey, list ):
- last_used_build = dbkey[0]
- else:
- last_used_build = dbkey
- folder = trans.sa_session.query( trans.app.model.LibraryFolder ).get( folder_id
)
- if folder and last_used_build in [ 'None', None, '?' ]:
- last_used_build = folder.genome_build
- replace_id = params.get( 'replace_id', None )
- if replace_id not in [ None, 'None' ]:
- replace_dataset = trans.sa_session.query( trans.app.model.LibraryDataset
).get( int( replace_id ) )
- # The name is separately - by the time the new ldda is created,
- # replace_dataset.name will point to the new ldda, not the one it's
- # replacing.
- replace_dataset_name = replace_dataset.name
- if not last_used_build:
- last_used_build =
replace_dataset.library_dataset_dataset_association.dbkey
- # Don't allow multiple datasets to be uploaded when replacing a dataset
with a new version
- upload_option = 'upload_file'
- else:
- replace_dataset = None
- upload_option = params.get( 'upload_option', 'upload_file' )
- 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 )
- if info_association:
- template_id = str( info_association.template.id )
- widgets = folder.get_template_widgets( trans, get_contents=False )
- else:
- template_id = 'None'
- widgets = []
- created_outputs = trans.webapp.controllers[ 'library_common'
].upload_dataset( trans,
-
controller='library_admin',
-
library_id=library_id,
-
folder_id=folder_id,
-
template_id=template_id,
-
widgets=widgets,
-
replace_dataset=replace_dataset,
-
**kwd )
- if created_outputs:
- total_added = len( created_outputs.values() )
- if replace_dataset:
- msg = "Added %d dataset versions to the library dataset
'%s' in the folder '%s'." % ( total_added, replace_dataset_name,
folder.name )
- else:
- if not folder.parent:
- # Libraries have the same name as their root_folder
- msg = "Added %d datasets to the library '%s' ( each
is selected ). " % ( total_added, folder.name )
- else:
- msg = "Added %d datasets to the folder '%s' ( each
is selected ). " % ( total_added, folder.name )
- msg += "Click the Go button at the bottom of this page to edit
the permissions on these datasets if necessary."
- messagetype='done'
- else:
- msg = "Upload failed"
- messagetype='error'
- trans.response.send_redirect( web.url_for(
controller='library_admin',
- action='browse_library',
- obj_id=library_id,
-
created_ldda_ids=",".join( [ str( v.id ) for v in created_outputs.values() ] ),
- msg=util.sanitize_text( 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.sa_session.query( trans.app.model.Role ) \
- .filter( trans.app.model.Role.table.c.deleted==False ) \
- .order_by( trans.app.model.Role.table.c.name )
- # Send the current history to the form to enable importing datasets from history
to library
- history = trans.get_history()
- trans.sa_session.refresh( history )
- # 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 ):
- params = util.Params( kwd )
- msg = util.restore_text( params.get( 'msg', '' ) )
- messagetype = params.get( 'messagetype', 'done' )
- try:
- folder = trans.sa_session.query( trans.app.model.LibraryFolder ).get( int(
folder_id ) )
- except:
- msg = "Invalid folder id: %s" % str( folder_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'
) )
- replace_id = params.get( 'replace_id', None )
- if replace_id:
- replace_dataset = trans.sa_session.query( trans.app.model.LibraryDataset
).get( replace_id )
- else:
- replace_dataset = None
- # See if the current history is empty
- history = trans.get_history()
- trans.sa_session.refresh( history )
- if not history.active_datasets:
- msg = 'Your current history is empty'
- 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'
) )
- if params.get( 'add_history_datasets_to_library_button', False ):
- hda_ids = util.listify( hda_ids )
- if hda_ids:
- dataset_names = []
- created_ldda_ids = ''
- for hda_id in hda_ids:
- hda = trans.sa_session.query(
trans.app.model.HistoryDatasetAssociation ).get( hda_id )
- if hda:
- ldda = hda.to_library_dataset_dataset_association(
target_folder=folder, replace_dataset=replace_dataset )
- created_ldda_ids = '%s,%s' % ( created_ldda_ids, str(
ldda.id ) )
- dataset_names.append( ldda.name )
- if not replace_dataset:
- # If replace_dataset is None, the Library level permissions
will be taken from the folder and applied to the new
- # LDDA and LibraryDataset.
- trans.app.security_agent.copy_library_permissions( folder,
ldda )
- trans.app.security_agent.copy_library_permissions( folder,
ldda.library_dataset )
- # Permissions must be the same on the
LibraryDatasetDatasetAssociation and the associated LibraryDataset
- trans.app.security_agent.copy_library_permissions(
ldda.library_dataset, ldda )
- else:
- 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',
-
obj_id=library_id,
-
msg=util.sanitize_text( msg ),
-
messagetype='error' ) )
- if created_ldda_ids:
- created_ldda_ids = created_ldda_ids.lstrip( ',' )
- ldda_id_list = created_ldda_ids.split( ',' )
- total_added = len( ldda_id_list )
- if replace_dataset:
- msg = "Added %d dataset versions to the library dataset
'%s' in the folder '%s'." % ( total_added, replace_dataset.name,
folder.name )
- else:
- if not folder.parent:
- # Libraries have the same name as their root_folder
- msg = "Added %d datasets to the library '%s' (
each is selected ). " % ( total_added, folder.name )
- else:
- msg = "Added %d datasets to the folder '%s' (
each is selected ). " % ( total_added, folder.name )
- 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',
- obj_id=library_id,
-
created_ldda_ids=created_ldda_ids,
-
msg=util.sanitize_text( msg ),
-
messagetype='done' ) )
- else:
- msg = 'Select at least one dataset from the list of active datasets
in your current history'
- messagetype = 'error'
- last_used_build = folder.genome_build
- upload_option = params.get( 'upload_option',
'import_from_history' )
- # 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.sa_session.query( trans.app.model.Role ) \
- .filter(
trans.app.model.Role.table.c.deleted==False ) \
- .order_by( trans.app.model.Role.table.c.name )
- return trans.fill_template( "/admin/library/upload.mako",
- upload_option=upload_option,
- 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=[],
- msg=msg,
- messagetype=messagetype )
- @web.expose
- @web.require_admin
- def datasets( self, trans, library_id, **kwd ):
- # This method is used by the select list labeled "Perform action on selected
datasets"
- # on the admin library browser.
- params = util.Params( kwd )
- msg = util.restore_text( params.get( 'msg', '' ) )
- messagetype = params.get( 'messagetype', 'done' )
- if params.get( 'action_on_datasets_button', False ):
- 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',
- obj_id=library_id,
- msg=util.sanitize_text( msg
),
- messagetype='error' )
)
- if params.action == 'manage_permissions':
- # We need the folder containing the LibraryDatasetDatasetAssociation(s)
- ldda = trans.sa_session.query(
trans.app.model.LibraryDatasetDatasetAssociation ).get( int( ldda_ids[0] ) )
- trans.response.send_redirect( web.url_for(
controller='library_admin',
-
action='ldda_manage_permissions',
- library_id=library_id,
-
folder_id=ldda.library_dataset.folder.id,
- obj_id=",".join(
ldda_ids ),
- msg=util.sanitize_text( msg
),
- messagetype=messagetype ) )
- elif params.action == 'delete':
- for ldda_id in ldda_ids:
- ldda = trans.sa_session.query(
trans.app.model.LibraryDatasetDatasetAssociation ).get( ldda_id )
- ldda.deleted = True
- trans.sa_session.add( ldda )
- trans.sa_session.flush()
- msg = "The selected datasets have been removed from this data
library"
- trans.response.send_redirect( web.url_for(
controller='library_admin',
-
action='browse_library',
- obj_id=library_id,
- show_deleted=False,
- msg=util.sanitize_text( msg
),
- messagetype='done' )
)
- else:
- trans.response.send_redirect( web.url_for(
controller='library_admin',
- action='browse_library',
- obj_id=library_id,
- msg=util.sanitize_text( msg ),
- messagetype=messagetype ) )
+
action='browse_libraries',
+ message=util.sanitize_text(
msg ),
+ status='done' ) )
@web.expose
@web.require_admin
def delete_library_item( self, trans, library_id, library_item_id, library_item_type
):
@@ -936,19 +190,21 @@
library_item_desc = 'Dataset'
else:
library_item_desc = library_item_type.capitalize()
- library_item = trans.sa_session.query( library_item_types[ library_item_type
] ).get( int( library_item_id ) )
+ library_item = trans.sa_session.query( library_item_types[ library_item_type
] ).get( trans.security.decode_id( library_item_id ) )
library_item.deleted = True
trans.sa_session.add( library_item )
trans.sa_session.flush()
msg = util.sanitize_text( "%s '%s' has been marked deleted"
% ( library_item_desc, library_item.name ) )
messagetype = 'done'
if library_item_type == 'library':
- return self.browse_libraries( trans, msg=msg, messagetype=messagetype )
+ return self.browse_libraries( trans, message=msg, status=messagetype )
else:
- return self.browse_library( trans,
- obj_id=library_id,
- msg=msg,
- messagetype=messagetype )
+ return trans.response.send_redirect( web.url_for(
controller='library_common',
+
action='browse_library',
+
cntrller='library_admin',
+ 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 ):
@@ -958,26 +214,28 @@
'library_dataset': trans.app.model.LibraryDataset
}
if library_item_type not in library_item_types:
msg = 'Bad library_item_type specified: %s' % str( library_item_type
)
- messagetype = 'error'
+ status = ERROR
else:
if library_item_type == 'library_dataset':
library_item_desc = 'Dataset'
else:
library_item_desc = library_item_type.capitalize()
- library_item = trans.sa_session.query( library_item_types[ library_item_type
] ).get( int( library_item_id ) )
+ library_item = trans.sa_session.query( library_item_types[ library_item_type
] ).get( trans.security.decode_id( library_item_id ) )
if library_item.purged:
msg = '%s %s has been purged, so it cannot be undeleted' % (
library_item_desc, library_item.name )
- messagetype = 'error'
+ status = ERROR
else:
library_item.deleted = False
trans.sa_session.add( library_item )
trans.sa_session.flush()
msg = util.sanitize_text( "%s '%s' has been marked
undeleted" % ( library_item_desc, library_item.name ) )
- messagetype = 'done'
+ status = SUCCESS
if library_item_type == 'library':
- return self.browse_libraries( trans, msg=msg, messagetype=messagetype )
+ return self.browse_libraries( trans, message=msg, status=status )
else:
- return self.browse_library( trans,
- obj_id=library_id,
- msg=msg,
- messagetype=messagetype )
+ return trans.response.send_redirect( web.url_for(
controller='library_common',
+
action='browse_library',
+
cntrller='library_admin',
+ id=library_id,
+ msg=msg,
+ messagetype=status ) )
diff -r 9f966847abda -r 4743015d9a57 lib/galaxy/web/controllers/library_common.py
--- a/lib/galaxy/web/controllers/library_common.py Tue Dec 22 18:49:34 2009 -0500
+++ b/lib/galaxy/web/controllers/library_common.py Wed Dec 23 20:26:01 2009 -0500
@@ -7,9 +7,50 @@
from galaxy.tools.actions import upload_common
from galaxy.web.controllers.forms import get_all_forms
from galaxy.model.orm import *
+from galaxy.util.streamball import StreamBall
+import logging, tempfile, zipfile, tarfile, os, sys
+
+if sys.version_info[:2] < ( 2, 6 ):
+ zipfile.BadZipFile = zipfile.error
+if sys.version_info[:2] < ( 2, 5 ):
+ zipfile.LargeZipFile = zipfile.error
log = logging.getLogger( __name__ )
+# Test for available compression types
+tmpd = tempfile.mkdtemp()
+comptypes = []
+for comptype in ( 'gz', 'bz2' ):
+ tmpf = os.path.join( tmpd, 'compression_test.tar.' + comptype )
+ try:
+ archive = tarfile.open( tmpf, 'w:' + comptype )
+ archive.close()
+ comptypes.append( comptype )
+ except tarfile.CompressionError:
+ log.exception( "Compression error when testing %s compression. This option
will be disabled for library downloads." % comptype )
+ try:
+ os.unlink( tmpf )
+ except OSError:
+ pass
+ziptype = '32'
+tmpf = os.path.join( tmpd, 'compression_test.zip' )
+try:
+ archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_DEFLATED, True )
+ archive.close()
+ comptypes.append( 'zip' )
+ ziptype = '64'
+except RuntimeError:
+ log.exception( "Compression error when testing zip compression. This option will
be disabled for library downloads." )
+except (TypeError, zipfile.LargeZipFile):
+ # ZIP64 is only in Python2.5+. Remove TypeError when 2.4 support is dropped
+ log.warning( 'Max zip file size is 2GB, ZIP64 not supported' )
+ comptypes.append( 'zip' )
+try:
+ os.unlink( tmpf )
+except OSError:
+ pass
+os.rmdir( tmpd )
+
class LibraryCommon( BaseController ):
@web.json
def library_item_updates( self, trans, ids=None, states=None ):
@@ -30,11 +71,661 @@
force_history_refresh = False
rval[id] = {
"state": data.state,
- "html": unicode( trans.fill_template(
"library/library_item_info.mako", ldda=data ), 'utf-8' )
+ "html": unicode( trans.fill_template(
"library/common/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 ):
+ @web.expose
+ def browse_library( self, trans, cntrller, **kwd ):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ library_id = params.get( '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=cntrller,
+
action='browse_libraries',
+ default_action=params.get(
'default_action', None ),
+ msg=util.sanitize_text( msg
),
+ messagetype='error'
) )
+ library = trans.sa_session.query( trans.app.model.Library ).get(
trans.security.decode_id( library_id ) )
+ if not library:
+ # To handle bots
+ msg = "Invalid library id ( %s )." % str( library_id )
+ return trans.response.send_redirect( web.url_for( controller=cntrller,
+
action='browse_libraries',
+ default_action=params.get(
'default_action', None ),
+ msg=util.sanitize_text( msg
),
+ messagetype='error'
) )
+ show_deleted = util.string_as_bool( params.get( 'show_deleted', False )
)
+ created_ldda_ids = params.get( 'created_ldda_ids', '' )
+ hidden_folder_ids = util.listify( params.get( 'hidden_folder_ids',
'' ) )
+ if created_ldda_ids and not msg:
+ msg = "%d datasets are now uploading in the background to the library
'%s' ( each is selected ). " % \
+ ( len( created_ldda_ids.split( ',' ) ), library.name )
+ msg += "Do not navigate away from Galaxy or use the browser's
\"stop\" or \"reload\" buttons ( on this tab ) until the upload(s)
change from the \"uploading\" state."
+ messagetype = "info"
+ return trans.fill_template( '/library/common/browse_library.mako',
+ cntrller=cntrller,
+ library=library,
+ created_ldda_ids=created_ldda_ids,
+ hidden_folder_ids=hidden_folder_ids,
+ default_action=params.get( 'default_action',
None ),
+ show_deleted=show_deleted,
+ comptypes=comptypes,
+ msg=msg,
+ messagetype=messagetype )
+ @web.expose
+ def library_info( self, trans, cntrller, **kwd ):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ library_id = params.get( 'id', None )
+ library = trans.sa_session.query( trans.app.model.Library ).get(
trans.security.decode_id( library_id ) )
+ # See if we have any associated templates
+ widgets = library.get_template_widgets( trans )
+ if params.get( 'rename_library_button', False ):
+ old_name = library.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/common/library_info.mako',
+ cntrller=cntrller,
+ library=library,
+ widgets=widgets,
+ msg=msg,
+ messagetype='error' )
+ else:
+ library.name = new_name
+ library.description = new_description
+ # Rename the root_folder
+ library.root_folder.name = new_name
+ library.root_folder.description = new_description
+ trans.sa_session.add_all( ( library, library.root_folder ) )
+ trans.sa_session.flush()
+ msg = "Library '%s' has been renamed to '%s'" %
( old_name, new_name )
+ return trans.response.send_redirect( web.url_for(
controller='library_common',
+
action='library_info',
+ cntrller=cntrller,
+
id=trans.security.encode_id( library.id ),
+ msg=util.sanitize_text(
msg ),
+
messagetype='done' ) )
+ return trans.fill_template( '/library/common/library_info.mako',
+ cntrller=cntrller,
+ library=library,
+ widgets=widgets,
+ msg=msg,
+ messagetype=messagetype )
+ @web.expose
+ def library_permissions( self, trans, cntrller, **kwd ):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ library_id = params.get( 'id', None )
+ library = trans.sa_session.query( trans.app.model.Library ).get(
trans.security.decode_id( library_id ) )
+ if params.get( 'update_roles_button', False ):
+ # The user clicked the Save button on the 'Associate With Roles'
form
+ permissions = {}
+ for k, v in trans.app.model.Library.permitted_actions.items():
+ in_roles = [ trans.sa_session.query( 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
+ trans.app.security_agent.set_all_library_permissions( library, permissions )
+ trans.sa_session.refresh( library )
+ # Copy the permissions to the root folder
+ trans.app.security_agent.copy_library_permissions( library,
library.root_folder )
+ msg = "Permissions updated for library '%s'" %
library.name
+ return trans.response.send_redirect( web.url_for(
controller='library_common',
+
action='library_permissions',
+ cntrller=cntrller,
+
id=trans.security.encode_id( library.id ),
+ msg=util.sanitize_text( msg
),
+ messagetype='done'
) )
+ return trans.fill_template( '/library/common/library_permissions.mako',
+ cntrller=cntrller,
+ library=library,
+ msg=msg,
+ messagetype=messagetype )
+ @web.expose
+ def create_folder( self, trans, cntrller, parent_id, library_id, **kwd ):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ folder = trans.sa_session.query( trans.app.model.LibraryFolder ).get(
trans.security.decode_id( parent_id ) )
+ if not folder:
+ msg = "Invalid parent folder id (%s) specified" % str( parent_id )
+ return trans.response.send_redirect( web.url_for(
controller='library_common',
+
action='browse_library',
+ cntrller=cntrller,
+ id=library_id,
+ msg=util.sanitize_text( msg
),
+ messagetype='error'
) )
+ 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 )
+ trans.sa_session.add( new_folder )
+ trans.sa_session.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_common',
+
action='browse_library',
+ cntrller=cntrller,
+ id=library_id,
+ msg=util.sanitize_text( msg
),
+ messagetype='done'
) )
+ return trans.fill_template( '/library/common/new_folder.mako',
+ cntrller=cntrller,
+ library_id=library_id,
+ folder=folder,
+ msg=msg,
+ messagetype=messagetype )
+ @web.expose
+ def folder_info( self, trans, cntrller, id, library_id, **kwd ):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ folder = trans.sa_session.query( trans.app.model.LibraryFolder ).get(
trans.security.decode_id( id ) )
+ if cntrller != 'library_admin':
+ user, roles = trans.get_user_and_roles()
+ # See if we have any associated templates
+ widgets = folder.get_template_widgets( trans )
+ if params.get( 'rename_folder_button', False ):
+ if cntrller=='library_admin' or
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/common/folder_info.mako",
+ cntrller=cntrller,
+ folder=folder,
+ library_id=library_id,
+ widgets=widgets,
+ msg=msg,
+ messagetype='error' )
+ else:
+ folder.name = new_name
+ folder.description = new_description
+ trans.sa_session.add( folder )
+ trans.sa_session.flush()
+ msg = "Folder '%s' has been renamed to
'%s'" % ( old_name, new_name )
+ return trans.response.send_redirect( web.url_for(
controller='library_common',
+
action='folder_info',
+ cntrller=cntrller,
+ id=id,
+
library_id=library_id,
+
msg=util.sanitize_text( msg ),
+
messagetype='done' ) )
+ else:
+ msg = "You are not authorized to edit this folder"
+ return trans.fill_template(
"/library/common/folder_info.mako",
+ cntrller=cntrller,
+ folder=folder,
+ library_id=library_id,
+ widgets=widgets,
+ msg=msg,
+ messagetype='error' )
+ return trans.fill_template( '/library/common/folder_info.mako',
+ cntrller=cntrller,
+ folder=folder,
+ library_id=library_id,
+ widgets=widgets,
+ msg=msg,
+ messagetype=messagetype )
+ @web.expose
+ def folder_permissions( self, trans, cntrller, id, library_id, **kwd ):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ folder = trans.sa_session.query( trans.app.model.LibraryFolder ).get( int( id )
)
+ if not folder:
+ msg = "Invalid folder specified, id: %s" % str( id )
+ return trans.response.send_redirect( web.url_for(
controller='library_common',
+
action='browse_library',
+ cntrller=cntrller,
+ id=library_id,
+ msg=util.sanitize_text( msg
),
+ messagetype='error'
) )
+ if cntrller == 'library':
+ user, roles = trans.get_user_and_roles()
+ if params.get( 'update_roles_button', False ):
+ # The user clicked the Save button on the 'Associate With Roles'
form
+ if cntrller == 'library_admin' or
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.sa_session.query( 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
)
+ trans.sa_session.refresh( folder )
+ msg = 'Permissions updated for folder %s' % folder.name
+ return trans.response.send_redirect( web.url_for(
controller='library_common',
+
action='folder_permissions',
+
id=trans.security.encode_id( folder.id ),
+ library_id=library_id,
+ 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_common',
+
action='folder_permissions',
+
id=trans.security.encode_id( folder.id ),
+ library_id=library_id,
+ msg=util.sanitize_text(
msg ),
+
messagetype='error' ) )
+ return trans.fill_template( '/library/common/folder_permissions.mako',
+ cntrller=cntrller,
+ folder=folder,
+ library_id=library_id,
+ msg=msg,
+ messagetype=messagetype )
+ @web.expose
+ def ldda_edit_info( self, trans, cntrller, library_id, folder_id, id, **kwd ):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ ldda = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation
).get( trans.security.decode_id( id ) )
+ if not ldda:
+ msg = "Invalid LibraryDatasetDatasetAssociation specified, id: %s"
% str( id )
+ return trans.response.send_redirect( web.url_for(
controller='library_common',
+
action='browse_library',
+ cntrller=cntrller,
+ id=library_id,
+ msg=util.sanitize_text( msg
),
+ messagetype='error'
) )
+ dbkey = params.get( 'dbkey', '?' )
+ if isinstance( dbkey, list ):
+ dbkey = dbkey[0]
+ if cntrller == 'library':
+ 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 cntrller=='library_admin' or
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.sa_session.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/common/ldda_edit_info.mako",
+ cntrller=cntrller,
+ 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 cntrller=='library_admin' or
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_setting_metadata( ldda )
+ trans.sa_session.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/common/ldda_edit_info.mako",
+ cntrller=cntrller,
+ 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 cntrller=='library_admin' or
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_setting_metadata( ldda )
+ trans.sa_session.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/common/ldda_edit_info.mako",
+ cntrller=cntrller,
+ ldda=ldda,
+ library_id=library_id,
+ file_formats=file_formats,
+ widgets=widgets,
+ msg=msg,
+ messagetype=messagetype )
+ if cntrller=='library_admin' or
trans.app.security_agent.can_modify_library_item( user, roles, 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/common/ldda_edit_info.mako",
+ cntrller=cntrller,
+ ldda=ldda,
+ library_id=library_id,
+ file_formats=file_formats,
+ widgets=widgets,
+ msg=msg,
+ messagetype=messagetype )
+ @web.expose
+ def ldda_display_info( self, trans, cntrller, library_id, folder_id, 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.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation
).get( trans.security.decode_id( id ) )
+ if not ldda:
+ msg = "Invalid LibraryDatasetDatasetAssociation specified, id: %s"
% str( id )
+ return trans.response.send_redirect( web.url_for(
controller='library_common',
+
action='browse_library',
+ cntrller=cntrller,
+ id=library_id,
+ msg=util.sanitize_text( msg
),
+ messagetype='error'
) )
+ library = trans.sa_session.query( trans.app.model.Library ).get(
trans.security.decode_id( library_id ) )
+ # See if we have any associated templates
+ widgets = ldda.get_template_widgets( trans )
+ return trans.fill_template( '/library/common/ldda_info.mako',
+ cntrller=cntrller,
+ ldda=ldda,
+ library=library,
+ show_deleted=show_deleted,
+ widgets=widgets,
+ msg=msg,
+ messagetype=messagetype )
+ @web.expose
+ def ldda_permissions( self, trans, cntrller, library_id, folder_id, id, **kwd ):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ ids = util.listify( id )
+ # Display permission form, permissions will be updated for all lddas
simultaneously.
+ lddas = []
+ for id in [ trans.security.decode_id( id ) for id in ids ]:
+ ldda = trans.sa_session.query(
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_common',
+
action='browse_library',
+ cntrller=cntrller,
+ id=library_id,
+ msg=util.sanitize_text( msg
),
+ messagetype='error' )
)
+ lddas.append( ldda )
+ if params.get( 'update_roles_button', False ):
+ if cntrller=='library_admin' or (
trans.app.security_agent.can_manage_library_item( user, roles, ldda ) and \
+
trans.app.security_agent.can_manage_dataset( roles, ldda.dataset ) ):
+ permissions = {}
+ accessible = False
+ for k, v in trans.app.model.Dataset.permitted_actions.items():
+ in_roles = [ trans.sa_session.query( 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 )
+ trans.sa_session.refresh( ldda.dataset )
+ permissions = {}
+ for k, v in trans.app.model.Library.permitted_actions.items():
+ in_roles = [ trans.sa_session.query( 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 )
+ trans.sa_session.refresh( ldda.library_dataset )
+ # Set the LIBRARY permissions on the
LibraryDatasetDatasetAssociation
+ trans.app.security_agent.set_all_library_permissions( ldda,
permissions )
+ trans.sa_session.refresh( ldda )
+ 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 )
+ else:
+ msg = "You are not authorized to change the permissions of dataset
'%s'" % ldda.name
+ messagetype = 'error'
+ return trans.fill_template(
"/library/common/ldda_permissions.mako",
+ cntrller=cntrller,
+ lddas=lddas,
+ library_id=library_id,
+ msg=msg,
+ messagetype=messagetype )
+ if len( 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_common',
+
action='browse_library',
+ cntrller=cntrller,
+ id=library_id,
+ msg=util.sanitize_text(
msg ),
+
messagetype='error' ) )
+ return trans.fill_template( "/library/common/ldda_permissions.mako",
+ cntrller=cntrller,
+ lddas=lddas,
+ library_id=library_id,
+ msg=msg,
+ messagetype=messagetype )
+ @web.expose
+ def upload_library_dataset( self, trans, cntrller, 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', '?' )
+ if isinstance( dbkey, list ):
+ last_used_build = dbkey[0]
+ else:
+ last_used_build = dbkey
+ folder = trans.sa_session.query( trans.app.model.LibraryFolder ).get(
trans.security.decode_id( folder_id ) )
+ if folder and last_used_build in [ 'None', None, '?' ]:
+ last_used_build = folder.genome_build
+ replace_id = params.get( 'replace_id', None )
+ if replace_id not in [ None, 'None' ]:
+ replace_dataset = trans.sa_session.query( trans.app.model.LibraryDataset
).get( trans.security.decode_id( replace_id ) )
+ # The name is separately - by the time the new ldda is created,
+ # replace_dataset.name will point to the new ldda, not the one it's
+ # replacing.
+ replace_dataset_name = replace_dataset.name
+ if not last_used_build:
+ last_used_build =
replace_dataset.library_dataset_dataset_association.dbkey
+ # Don't allow multiple datasets to be uploaded when replacing a dataset
with a new version
+ upload_option = 'upload_file'
+ else:
+ replace_dataset = None
+ upload_option = params.get( 'upload_option', 'upload_file' )
+ if cntrller == 'library':
+ user, roles = trans.get_user_and_roles()
+ if cntrller == 'library_admin' or \
+ ( 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 ):
+ # See if we have any inherited templates, but do not inherit contents.
+ info_association, inherited = folder.get_info_association( inherited=True
)
+ if info_association:
+ template_id = str( info_association.template.id )
+ widgets = folder.get_template_widgets( trans, get_contents=False )
+ else:
+ template_id = 'None'
+ widgets = []
+ created_outputs = trans.webapp.controllers[ 'library_common'
].upload_dataset( trans,
+
cntrller=cntrller,
+
library_id=library_id,
+
folder_id=folder_id,
+
template_id=template_id,
+
widgets=widgets,
+
replace_dataset=replace_dataset,
+
**kwd )
+ if created_outputs:
+ total_added = len( created_outputs.values() )
+ if replace_dataset:
+ msg = "Added %d dataset versions to the library dataset
'%s' in the folder '%s'." % ( total_added, replace_dataset_name,
folder.name )
+ else:
+ if not folder.parent:
+ # Libraries have the same name as their root_folder
+ msg = "Added %d datasets to the library '%s' (
each is selected ). " % ( total_added, folder.name )
+ else:
+ msg = "Added %d datasets to the folder '%s' (
each is selected ). " % ( total_added, folder.name )
+ if cntrller == 'library_admin':
+ msg += "Click the Go button at the bottom of this page
to edit the permissions on these datasets if necessary."
+ messagetype='done'
+ else:
+ # Since permissions on all LibraryDatasetDatasetAssociations
must be the same at this point, we only need
+ # to check one of them to see if the current user can manage
permissions on them.
+ ldda_id_list = [ str( v.id ) for v in
created_outputs.values() ]
+ check_ldda = trans.sa_session.query(
trans.app.model.LibraryDatasetDatasetAssociation ).get( ldda_id_list[0] )
+ if trans.app.security_agent.can_manage_library_item( user,
roles, check_ldda ):
+ if replace_dataset:
+ default_action = ''
+ else:
+ msg += "Click the Go button at the bottom of
this page to edit the permissions on these datasets if necessary."
+ default_action = 'manage_permissions'
+ else:
+ default_action = 'add'
+ trans.response.send_redirect( web.url_for(
controller='library_common',
+
action='browse_library',
+
cntrller=cntrller,
+ id=library_id,
+
default_action=default_action,
+
created_ldda_ids=",".join( ldda_id_list ),
+
msg=util.sanitize_text( msg ),
+
messagetype='done' ) )
+
+ else:
+ msg = "Upload failed"
+ messagetype='error'
+ trans.response.send_redirect( web.url_for(
controller='library_common',
+
action='browse_library',
+ cntrller=cntrller,
+ id=library_id,
+
created_ldda_ids=",".join( [ str( v.id ) for v in created_outputs.values() ] ),
+ msg=util.sanitize_text( 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.sa_session.query( trans.app.model.Role ) \
+ .filter( trans.app.model.Role.table.c.deleted==False ) \
+ .order_by( trans.app.model.Role.table.c.name )
+ # Send the current history to the form to enable importing datasets from history
to library
+ history = trans.get_history()
+ trans.sa_session.refresh( history )
+ # If we're using nginx upload, override the form action
+ action = web.url_for( controller='library_common',
action='upload_library_dataset', cntrller=cntrller )
+ 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/common/upload.mako',
+ cntrller=cntrller,
+ 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 )
+ def upload_dataset( self, trans, cntrller, 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 ]
@@ -52,7 +743,7 @@
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
+ replace_id = trans.security.encode_id( replace_dataset.id )
else:
replace_id = None
upload_option = params.get( 'upload_option', 'upload_file' )
@@ -60,7 +751,7 @@
if upload_option == 'upload_directory':
if server_dir in [ None, 'None', '' ]:
err_redirect = True
- if controller == 'library_admin':
+ if cntrller == '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 )
@@ -76,7 +767,7 @@
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 )
+ precreated_datasets = upload_common.get_precreated_datasets( trans, tool_params,
trans.app.model.LibraryDatasetDatasetAssociation, controller=cntrller )
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 )
@@ -89,8 +780,9 @@
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,
+ trans.response.send_redirect( web.url_for(
controller='library_common',
action='upload_library_dataset',
+ cntrller=cntrller,
library_id=library_id,
folder_id=folder_id,
replace_id=replace_id,
@@ -182,15 +874,136 @@
return None, err_redirect, msg
return uploaded_datasets, None, None
@web.expose
- def download_dataset_from_folder( self, trans, cntrller, obj_id, library_id=None,
**kwd ):
+ def add_history_datasets_to_library( self, trans, cntrller, library_id, folder_id,
hda_ids='', **kwd ):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ try:
+ folder = trans.sa_session.query( trans.app.model.LibraryFolder ).get(
trans.security.decode_id( folder_id ) )
+ except:
+ msg = "Invalid folder id: %s" % str( folder_id )
+ return trans.response.send_redirect( web.url_for(
controller='library_common',
+
action='browse_library',
+ cntrller=cntrller,
+ id=library_id,
+ msg=util.sanitize_text( msg
),
+ messagetype='error'
) )
+ replace_id = params.get( 'replace_id', None )
+ if replace_id:
+ replace_dataset = trans.sa_session.query( trans.app.model.LibraryDataset
).get( trans.security.decode_id( replace_id ) )
+ else:
+ replace_dataset = None
+ # See if the current history is empty
+ history = trans.get_history()
+ trans.sa_session.refresh( history )
+ if not history.active_datasets:
+ msg = 'Your current history is empty'
+ return trans.response.send_redirect( web.url_for(
controller='library_common',
+
action='browse_library',
+ cntrller=cntrller,
+ id=library_id,
+ msg=util.sanitize_text( msg
),
+ messagetype='error'
) )
+ if params.get( 'add_history_datasets_to_library_button', False ):
+ hda_ids = util.listify( hda_ids )
+ if hda_ids:
+ dataset_names = []
+ created_ldda_ids = ''
+ for hda_id in hda_ids:
+ hda = trans.sa_session.query(
trans.app.model.HistoryDatasetAssociation ).get( trans.security.decode_id( hda_id ) )
+ if hda:
+ ldda = hda.to_library_dataset_dataset_association(
target_folder=folder, replace_dataset=replace_dataset )
+ created_ldda_ids = '%s,%s' % ( created_ldda_ids, str(
ldda.id ) )
+ dataset_names.append( ldda.name )
+ if not replace_dataset:
+ # If replace_dataset is None, the Library level permissions
will be taken from the folder and applied to the new
+ # LDDA and LibraryDataset.
+ trans.app.security_agent.copy_library_permissions( folder,
ldda )
+ trans.app.security_agent.copy_library_permissions( folder,
ldda.library_dataset )
+ # Permissions must be the same on the
LibraryDatasetDatasetAssociation and the associated LibraryDataset
+ trans.app.security_agent.copy_library_permissions(
ldda.library_dataset, ldda )
+ else:
+ msg = "The requested HistoryDatasetAssociation id %s is
invalid" % str( hda_id )
+ return trans.response.send_redirect( web.url_for(
controller='library_common',
+
action='browse_library',
+
cntrller=cntrller,
+ id=library_id,
+
msg=util.sanitize_text( msg ),
+
messagetype='error' ) )
+ if created_ldda_ids:
+ created_ldda_ids = created_ldda_ids.lstrip( ',' )
+ ldda_id_list = created_ldda_ids.split( ',' )
+ total_added = len( ldda_id_list )
+ if replace_dataset:
+ msg = "Added %d dataset versions to the library dataset
'%s' in the folder '%s'." % ( total_added, replace_dataset.name,
folder.name )
+ else:
+ if not folder.parent:
+ # Libraries have the same name as their root_folder
+ msg = "Added %d datasets to the library '%s' (
each is selected ). " % ( total_added, folder.name )
+ else:
+ msg = "Added %d datasets to the folder '%s' (
each is selected ). " % ( total_added, folder.name )
+ if cntrller == 'library_admin':
+ msg += "Click the Go button at the bottom of this page
to edit the permissions on these datasets if necessary."
+ else:
+ # Since permissions on all LibraryDatasetDatasetAssociations
must be the same at this point, we only need
+ # to check one of them to see if the current user can manage
permissions on them.
+ check_ldda = trans.sa_session.query(
trans.app.model.LibraryDatasetDatasetAssociation ).get( trans.security.decode_id(
ldda_id_list[0] ) )
+ user, roles = trans.get_user_and_roles()
+ if trans.app.security_agent.can_manage_library_item( user,
roles, check_ldda ):
+ if replace_dataset:
+ default_action = ''
+ else:
+ msg += "Click the Go button at the bottom of
this page to edit the permissions on these datasets if necessary."
+ default_action = 'manage_permissions'
+ else:
+ default_action = 'add'
+ return trans.response.send_redirect( web.url_for(
controller='library_common',
+
action='browse_library',
+ cntrller=cntrller,
+ id=library_id,
+
created_ldda_ids=created_ldda_ids,
+
msg=util.sanitize_text( msg ),
+
messagetype='done' ) )
+ else:
+ msg = 'Select at least one dataset from the list of active datasets
in your current history'
+ messagetype = 'error'
+ last_used_build = folder.genome_build
+ upload_option = params.get( 'upload_option',
'import_from_history' )
+ # 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.sa_session.query( trans.app.model.Role ) \
+ .filter(
trans.app.model.Role.table.c.deleted==False ) \
+ .order_by( trans.app.model.Role.table.c.name )
+ return trans.fill_template( "/library/common/upload.mako",
+ upload_option=upload_option,
+ 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=[],
+ msg=msg,
+ messagetype=messagetype )
+ @web.expose
+ def download_dataset_from_folder( self, trans, cntrller, id, library_id=None, **kwd
):
"""Catches the dataset id and displays file contents as
directed"""
# id must refer to a LibraryDatasetDatasetAssociation object
- ldda = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation
).get( obj_id )
+ ldda = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation
).get( 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=cntrller,
+ msg = 'Invalid LibraryDatasetDatasetAssociation id %s received for file
downlaod' % str( id )
+ return trans.response.send_redirect( web.url_for(
controller='library_common',
action='browse_library',
- obj_id=library_id,
+ cntrller=cntrller,
+ id=library_id,
msg=util.sanitize_text( msg
),
messagetype='error'
) )
mime = trans.app.datatypes_registry.get_mimetype_by_extension(
ldda.extension.lower() )
@@ -200,38 +1013,263 @@
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 )
+ 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=cntrller,
+ return trans.response.send_redirect( web.url_for(
controller='library_common',
action='browse_library',
- obj_id=library_id,
+ cntrller=cntrller,
+ id=library_id,
msg=util.sanitize_text( msg
),
messagetype='error'
) )
@web.expose
- def info_template( self, trans, cntrller, library_id,
response_action='library', obj_id=None, folder_id=None, ldda_id=None, **kwd ):