galaxy-dev
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
January 2010
- 29 participants
- 156 discussions
05 Jan '10
details: http://www.bx.psu.edu/hg/galaxy/rev/77f309c46dd0
changeset: 3201:77f309c46dd0
user: Greg Von Kuster <greg(a)bx.psu.edu>
date: Tue Jan 05 13:01:37 2010 -0500
description:
Add the links for the annotation_profiler tool-data files to buildbot_setup.sh so buildbot will test the tool.
diffstat:
buildbot_setup.sh | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diffs (13 lines):
diff -r 71928a8f9bf9 -r 77f309c46dd0 buildbot_setup.sh
--- a/buildbot_setup.sh Tue Jan 05 10:31:32 2010 -0500
+++ b/buildbot_setup.sh Tue Jan 05 13:01:37 2010 -0500
@@ -14,6 +14,9 @@
LINKS="
/depot/data2/galaxy/alignseq.loc
+/depot/data2/galaxy/annotation_profiler/annotation_profiler.loc
+/depot/data2/galaxy/annotation_profiler/annotation_profiler_options.xml
+/depot/data2/galaxy/annotation_profiler/annotation_profiler_valid_builds.txt
/depot/data2/galaxy/binned_scores.loc
/depot/data2/galaxy/blastdb.loc
/depot/data2/galaxy/bowtie_indices.loc
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/71928a8f9bf9
changeset: 3200:71928a8f9bf9
user: Greg Von Kuster <greg(a)bx.psu.edu>
date: Tue Jan 05 10:31:32 2010 -0500
description:
UI cleanup and fixes:
- only display check boxes on a grid if there are operations to perform
- asynchronous uploads will now properly handle associated library templates
- miscellaneous fixes for issues introduced in the library code merge in change set 3194:4743015d9a57
diffstat:
lib/galaxy/tools/actions/upload_common.py | 31 ++-
lib/galaxy/web/controllers/library_common.py | 38 +++-
templates/admin/requests/show_request.mako | 2 +-
templates/base_panels.mako | 4 +-
templates/grid_base.mako | 4 +-
templates/library/common/browse_library.mako | 100 +++++++-------
templates/library/common/common.mako | 19 +-
templates/library/common/ldda_permissions.mako | 2 +-
templates/library/common/library_dataset_permissions.mako | 2 +-
templates/library/common/library_permissions.mako | 2 +-
templates/library/common/upload.mako | 2 +-
templates/requests/show_request.mako | 2 +-
test/base/twilltestcase.py | 8 +-
test/functional/test_security_and_libraries.py | 4 +-
14 files changed, 119 insertions(+), 101 deletions(-)
diffs (633 lines):
diff -r cadad7fc9284 -r 71928a8f9bf9 lib/galaxy/tools/actions/upload_common.py
--- a/lib/galaxy/tools/actions/upload_common.py Tue Jan 05 09:53:14 2010 -0500
+++ b/lib/galaxy/tools/actions/upload_common.py Tue Jan 05 10:31:32 2010 -0500
@@ -33,7 +33,6 @@
new_files.append( upload_dataset )
params['files'] = new_files
return params
-
def handle_library_params( trans, params, folder_id, replace_dataset=None ):
library_bunch = util.bunch.Bunch()
library_bunch.replace_dataset = replace_dataset
@@ -59,7 +58,6 @@
role = trans.sa_session.query( trans.app.model.Role ).get( role_id )
library_bunch.roles.append( role )
return library_bunch
-
def get_precreated_datasets( trans, params, data_obj, controller='root' ):
"""
Get any precreated datasets (when using asynchronous uploads).
@@ -88,7 +86,6 @@
else:
rval.append( data )
return rval
-
def get_precreated_dataset( precreated_datasets, name ):
"""
Return a dataset matching a name from the list of precreated (via async
@@ -100,13 +97,11 @@
return precreated_datasets.pop( names.index( name ) )
else:
return None
-
def cleanup_unused_precreated_datasets( precreated_datasets ):
for data in precreated_datasets:
log.info( 'Cleaned up unclaimed precreated dataset (%s).' % ( data.id ) )
data.state = data.states.ERROR
data.info = 'No file contents were available.'
-
def new_history_upload( trans, uploaded_dataset, state=None ):
hda = trans.app.model.HistoryDatasetAssociation( name = uploaded_dataset.name,
extension = uploaded_dataset.file_type,
@@ -125,7 +120,6 @@
trans.app.security_agent.set_all_dataset_permissions( hda.dataset, permissions )
trans.sa_session.flush()
return hda
-
def new_library_upload( trans, uploaded_dataset, library_bunch, state=None ):
user, roles = trans.get_user_and_roles()
if not ( trans.app.security_agent.can_add_library_item( user, roles, library_bunch.folder ) \
@@ -183,7 +177,10 @@
ld.library_dataset_dataset_association_id = ldda.id
trans.sa_session.add( ld )
trans.sa_session.flush()
- # Handle template included in the upload form, if any
+ # Handle template included in the upload form, if any. If the upload is not asynchronous ( e.g., URL paste ),
+ # then the template and contents will be included in the library_bunch at this point. If the upload is
+ # asynchronous ( e.g., uploading a file ), then the template and contents will be included in the library_bunch
+ # in the get_uploaded_datasets() method below.
if library_bunch.template and library_bunch.template_field_contents:
# Since information templates are inherited, the template fields can be displayed on the upload form.
# If the user has added field contents, we'll need to create a new form_values and info_association
@@ -203,13 +200,11 @@
trans.sa_session.add( dp )
trans.sa_session.flush()
return ldda
-
def new_upload( trans, uploaded_dataset, library_bunch=None, state=None ):
if library_bunch:
return new_library_upload( trans, uploaded_dataset, library_bunch, state )
else:
return new_history_upload( trans, uploaded_dataset, state )
-
def get_uploaded_datasets( trans, params, precreated_datasets, dataset_upload_inputs, library_bunch=None ):
uploaded_datasets = []
for dataset_upload_input in dataset_upload_inputs:
@@ -226,12 +221,26 @@
if library_bunch:
library_bunch.folder.genome_build = uploaded_dataset.dbkey
trans.sa_session.add( library_bunch.folder )
+ # Handle template included in the upload form, if any. If the upload is asynchronous ( e.g., file upload ),
+ # then the template and contents will be included in the library_bunch at this point. If the upload is
+ # not asynchronous ( e.g., URL paste ), then the template and contents will be included in the library_bunch
+ # in the new_library_upload() method above.
+ if library_bunch.template and library_bunch.template_field_contents:
+ # Since information templates are inherited, the template fields can be displayed on the upload form.
+ # If the user has added field contents, we'll need to create a new form_values and info_association
+ # for the new library_dataset_dataset_association object.
+ # Create a new FormValues object, using the template we previously retrieved
+ form_values = trans.app.model.FormValues( library_bunch.template, library_bunch.template_field_contents )
+ trans.sa_session.add( form_values )
+ trans.sa_session.flush()
+ # Create a new info_association between the current ldda and form_values
+ info_association = trans.app.model.LibraryDatasetDatasetInfoAssociation( data, library_bunch.template, form_values )
+ trans.sa_session.add( info_association )
trans.sa_session.flush()
else:
trans.history.genome_build = uploaded_dataset.dbkey
uploaded_dataset.data = data
return uploaded_datasets
-
def create_paramfile( trans, uploaded_datasets ):
"""
Create the upload tool's JSON "param" file.
@@ -278,7 +287,6 @@
json_file.write( to_json_string( json ) + '\n' )
json_file.close()
return json_file_path
-
def create_job( trans, params, tool, json_file_path, data_list, folder=None ):
"""
Create the upload job.
@@ -314,7 +322,6 @@
trans.app.job_queue.put( job.id, tool )
trans.log_event( "Added job to the job queue, id: %s" % str(job.id), tool_id=job.tool_id )
return dict( [ ( 'output%i' % i, v ) for i, v in enumerate( data_list ) ] )
-
def active_folders( trans, folder ):
# Stolen from galaxy.web.controllers.library_common (importing from which causes a circular issues).
# Much faster way of retrieving all active sub-folders within a given folder than the
diff -r cadad7fc9284 -r 71928a8f9bf9 lib/galaxy/web/controllers/library_common.py
--- a/lib/galaxy/web/controllers/library_common.py Tue Jan 05 09:53:14 2010 -0500
+++ b/lib/galaxy/web/controllers/library_common.py Tue Jan 05 10:31:32 2010 -0500
@@ -102,9 +102,10 @@
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 ). " % \
+ msg = "%d datasets are 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."
+ msg += "Don't navigate away from Galaxy or use the browser's \"stop\" or \"reload\" buttons (on this tab) until the "
+ msg += "message \"This dataset is uploading\" is cleared from the \"Information\" column below for each selected dataset."
messagetype = "info"
return trans.fill_template( '/library/common/browse_library.mako',
cntrller=cntrller,
@@ -645,21 +646,21 @@
**kwd )
if created_outputs:
total_added = len( created_outputs.values() )
+ ldda_id_list = [ str( v.id ) for v in 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 )
+ 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 = "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:
@@ -939,9 +940,9 @@
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 )
+ 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 = "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:
@@ -1132,18 +1133,27 @@
ldda_ids = util.listify( ldda_ids )
if params.do_action == 'add':
history = trans.get_history()
+ total_imported_lddas = 0
+ msg = ''
+ messagetype = 'done'
for ldda_id in ldda_ids:
ldda = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get( trans.security.decode_id( 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 )
+ if ldda.dataset.state in [ 'new', 'upload', 'queued', 'running', 'empty', 'discarded' ]:
+ msg += "Cannot import dataset (%s) since it's state is (%s). " % ( ldda.name, ldda.dataset.state )
+ messagetype = 'error'
+ elif ldda.dataset.state in [ 'ok', 'error' ]:
+ hda = ldda.to_history_dataset_association( target_history=history, add_to_history=True )
+ total_imported_lddas += 1
+ if total_imported_lddas:
+ trans.sa_session.add( history )
+ trans.sa_session.flush()
+ msg += "%i dataset(s) have been imported into your history. " % total_imported_lddas
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' ) )
+ messagetype=messagetype ) )
elif params.do_action == 'manage_permissions':
# We need the folder containing the LibraryDatasetDatasetAssociation(s)
ldda = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get( trans.security.decode_id( ldda_ids[0] ) )
@@ -1197,7 +1207,9 @@
user, roles = trans.get_user_and_roles()
for ldda_id in ldda_ids:
ldda = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get( trans.security.decode_id( ldda_id ) )
- if not ldda or not trans.app.security_agent.can_access_dataset( roles, ldda.dataset ):
+ if not ldda \
+ or not trans.app.security_agent.can_access_dataset( roles, ldda.dataset ) \
+ or ldda.dataset.state in [ 'new', 'upload', 'queued', 'running', 'empty', 'discarded' ]:
continue
path = ""
parent_folder = ldda.library_dataset.folder
diff -r cadad7fc9284 -r 71928a8f9bf9 templates/admin/requests/show_request.mako
--- a/templates/admin/requests/show_request.mako Tue Jan 05 09:53:14 2010 -0500
+++ b/templates/admin/requests/show_request.mako Tue Jan 05 10:31:32 2010 -0500
@@ -122,7 +122,7 @@
%else:
%if rd['label'] == 'Data library':
%if rd['value']:
- <a href="${h.url_for( controller='library_common', action='browse_library', cntrller='library', id=trans.security.encode_id( request.library.id ) )}">${rd['value']}</a>
+ <a href="${h.url_for( controller='library_common', action='browse_library', cntrller='requests_admin', id=trans.security.encode_id( request.library.id ) )}">${rd['value']}</a>
%else:
<i>None</i>
%endif
diff -r cadad7fc9284 -r 71928a8f9bf9 templates/base_panels.mako
--- a/templates/base_panels.mako Tue Jan 05 09:53:14 2010 -0500
+++ b/templates/base_panels.mako Tue Jan 05 10:31:32 2010 -0500
@@ -114,8 +114,8 @@
$(this).ajaxSubmit( { iframe: true } );
if ( $(this).find("input[name='folder_id']").val() != undefined ) {
var library_id = $(this).find("input[name='library_id']").val();
- if ( location.pathname.indexOf( 'library_admin' ) != -1 ) {
- $("iframe#galaxy_main").attr("src","${h.url_for( controller='library_common', action='browse_library' )}?cntrller=library_admin7id=" + library_id + "&created_ldda_ids=" + async_datasets);
+ if ( location.pathname.indexOf( 'admin' ) != -1 ) {
+ $("iframe#galaxy_main").attr("src","${h.url_for( controller='library_common', action='browse_library' )}?cntrller=library_admin&id=" + library_id + "&created_ldda_ids=" + async_datasets);
} else {
$("iframe#galaxy_main").attr("src","${h.url_for( controller='library_common', action='browse_library' )}?cntrller=library&id=" + library_id + "&created_ldda_ids=" + async_datasets);
}
diff -r cadad7fc9284 -r 71928a8f9bf9 templates/grid_base.mako
--- a/templates/grid_base.mako Tue Jan 05 09:53:14 2010 -0500
+++ b/templates/grid_base.mako Tue Jan 05 10:31:32 2010 -0500
@@ -842,7 +842,9 @@
>
## Item selection column
<td style="width: 1.5em;">
- <input type="checkbox" name="id" value=${trans.security.encode_id( item.id )} class="grid-row-select-checkbox" />
+ %if grid.operations:
+ <input type="checkbox" name="id" value=${trans.security.encode_id( item.id )} class="grid-row-select-checkbox" />
+ %endif
</td>
## Data columns
%for column in grid.columns:
diff -r cadad7fc9284 -r 71928a8f9bf9 templates/library/common/browse_library.mako
--- a/templates/library/common/browse_library.mako Tue Jan 05 09:53:14 2010 -0500
+++ b/templates/library/common/browse_library.mako Tue Jan 05 10:31:32 2010 -0500
@@ -15,14 +15,14 @@
</%def>
<%
- if cntrller == 'library':
+ if cntrller in [ 'library', 'requests' ]:
user, roles = trans.get_user_and_roles()
can_add = trans.app.security_agent.can_add_library_item( user, roles, library )
if can_add:
info_association, inherited = library.get_info_association()
can_modify = trans.app.security_agent.can_modify_library_item( user, roles, library )
can_manage = trans.app.security_agent.can_manage_library_item( user, roles, library )
- elif cntrller == 'library_admin':
+ elif cntrller in [ 'library_admin', 'requests_admin' ]:
info_association, inherited = library.get_info_association()
tracked_datasets = {}
@@ -161,7 +161,7 @@
uploaded_by = 'anonymous'
if ldda == library_dataset.library_dataset_dataset_association:
current_version = True
- if cntrller == 'library':
+ if cntrller in [ 'library', 'requests' ]:
can_modify_library_dataset = trans.app.security_agent.can_modify_library_item( user, roles, library_dataset )
can_manage_library_dataset = trans.app.security_agent.can_manage_library_item( user, roles, library_dataset )
else:
@@ -185,22 +185,22 @@
<a href="${h.url_for( controller='library_common', action='ldda_display_info', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), id=trans.security.encode_id( ldda.id ) )}"><b>${ldda.name[:50]}</b></a>
<a id="dataset-${ldda.id}-popup" class="popup-arrow" style="display: none;">▼</a>
<div popupmenu="dataset-${ldda.id}-popup">
- %if cntrller == 'library_admin' or can_modify_library_dataset:
+ %if cntrller in [ 'library_admin', 'requests_admin' ] or can_modify_library_dataset:
<a class="action-button" href="${h.url_for( controller='library_common', action='ldda_edit_info', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), id=trans.security.encode_id( ldda.id ) )}">Edit this dataset's information</a>
%else:
<a class="action-button" href="${h.url_for( controller='library_common', action='ldda_display_info', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), id=trans.security.encode_id( ldda.id ) )}">View this dataset's information</a>
%endif
- %if cntrller == 'library_admin' or can_manage_library_dataset:
+ %if cntrller in [ 'library_admin', 'requests_admin' ] or can_manage_library_dataset:
<a class="action-button" href="${h.url_for( controller='library_common', action='ldda_permissions', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), id=ldda.id, permissions=True )}">Edit this dataset's permissions</a>
%endif
- %if cntrller == 'library_admin' or can_modify_library_dataset:
+ %if cntrller in [ 'library_admin', 'requests_admin' ] or can_modify_library_dataset:
<a class="action-button" href="${h.url_for( controller='library_common', action='upload_library_dataset', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), replace_id=trans.security.encode_id( library_dataset.id ) )}">Upload a new version of this dataset</a>
%endif
%if ldda.has_data:
<a class="action-button" href="${h.url_for( controller='library_common', action='act_on_multiple_datasets', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), ldda_ids=trans.security.encode_id( ldda.id ), do_action='add' )}">Import this dataset into your current history</a>
<a class="action-button" href="${h.url_for( controller='library_common', action='download_dataset_from_folder', cntrller=cntrller, id=trans.security.encode_id( ldda.id ), library_id=trans.security.encode_id( library.id ) )}">Download this dataset</a>
%endif
- %if cntrller == 'library_admin':
+ %if cntrller in [ 'library_admin', 'requests_admin' ]:
%if not library.deleted and not folder.deleted and not library_dataset.deleted:
<a class="action-button" confirm="Click OK to delete dataset '${ldda.name}'." href="${h.url_for( controller='library_admin', action='delete_library_item', library_id=trans.security.encode_id( library.id ), library_item_id=trans.security.encode_id( library_dataset.id ), library_item_type='library_dataset' )}">Delete this dataset</a>
%elif not library.deleted and not folder.deleted and library_dataset.deleted:
@@ -231,11 +231,11 @@
expander = "/static/images/silk/resultset_next.png"
folder_img = "/static/images/silk/folder.png"
if created_ldda_ids:
- created_ldda_ids = [ trans.security.encode_id( ldda_id ) for ldda_id in util.listify( created_ldda_ids ) ]
+ created_ldda_ids = util.listify( created_ldda_ids )
if str( folder.id ) in hidden_folder_ids:
return ""
my_row = None
- if cntrller == 'library':
+ if cntrller in [ 'library', 'requests' ]:
can_access, folder_ids = trans.app.security_agent.check_folder_contents( user, roles, folder )
if not can_access:
can_show, folder_ids = \
@@ -252,7 +252,7 @@
info_association, inherited = folder.get_info_association( restrict=True )
can_modify = trans.app.security_agent.can_modify_library_item( user, roles, folder )
can_manage = trans.app.security_agent.can_manage_library_item( user, roles, folder )
- elif cntrller == 'library_admin':
+ elif cntrller in [ 'library_admin', 'requests_admin' ]:
info_association, inherited = folder.get_info_association( restrict=True )
%>
%if not root_folder:
@@ -272,22 +272,22 @@
%endif
<a id="folder_img-${folder.id}-popup" class="popup-arrow" style="display: none;">▼</a>
<div popupmenu="folder_img-${folder.id}-popup">
- %if cntrller == 'library_admin' or can_add:
+ %if cntrller in [ 'library_admin', 'requests_admin' ] or can_add:
<a class="action-button" href="${h.url_for( controller='library_common', action='upload_library_dataset', cntrller=cntrller, library_id=library_id, folder_id=trans.security.encode_id( folder.id ) )}">Add datasets to this folder</a>
<a class="action-button" href="${h.url_for( controller='library_common', action='create_folder', cntrller=cntrller, parent_id=trans.security.encode_id( folder.id ), library_id=library_id )}">Create a new sub-folder in this folder</a>
%endif
- %if cntrller == 'library_admin' or can_modify:
+ %if cntrller in [ 'library_admin', 'requests_admin' ] or can_modify:
<a class="action-button" href="${h.url_for( controller='library_common', action='folder_info', cntrller=cntrller, id=trans.security.encode_id( folder.id ), library_id=library_id )}">Edit this folder's information</a>
%else:
<a class="action-button" href="${h.url_for( controller='library_common', action='folder_info', cntrller=cntrller, id=trans.security.encode_id( folder.id ), library_id=library_id )}">View this folder's information</a>
%endif
- %if ( cntrller == 'library_admin' or can_add ) and not info_association:
+ %if ( cntrller in [ 'library_admin', 'requests_admin' ] or can_add ) and not info_association:
<a class="action-button" href="${h.url_for( controller='library_common', action='info_template', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), response_action='folder_info', folder_id=trans.security.encode_id( folder.id ) )}">Add an information template to this folder</a>
%endif
- %if cntrller == 'library_admin' or can_manage:
+ %if cntrller in [ 'library_admin', 'requests_admin' ] or can_manage:
<a class="action-button" href="${h.url_for( controller='library_common', action='folder_permissions', cntrller=cntrller, id=trans.security.encode_id( folder.id ), library_id=library_id )}">Edit this folder's permissions</a>
%endif
- %if cntrller == 'library_admin':
+ %if cntrller in [ 'library_admin', 'requests_admin' ]:
%if not folder.deleted:
<a class="action-button" confirm="Click OK to delete the folder '${folder.name}.'" href="${h.url_for( controller='library_admin', action='delete_library_item', library_id=library_id, library_item_id=trans.security.encode_id( folder.id ), library_item_type='folder' )}">Delete this folder and its contents</a>
%elif folder.deleted and not folder.purged:
@@ -311,9 +311,8 @@
%for library_dataset in folder.active_library_datasets:
<%
ldda = library_dataset.library_dataset_dataset_association
- if cntrller == 'library':
- can_access = trans.app.security_agent.can_access_dataset( roles, ldda.dataset )
- selected = created_ldda_ids and ldda.id in created_ldda_ids
+ can_access = trans.app.security_agent.can_access_dataset( roles, ldda.dataset )
+ selected = created_ldda_ids and str( ldda.id ) in created_ldda_ids
%>
%if can_access:
${render_dataset( cntrller, ldda, library_dataset, selected, library, folder, pad, my_row, row_counter )}
@@ -331,7 +330,7 @@
%for ldda in lddas:
<%
library_dataset = ldda.library_dataset
- selected = created_ldda_ids and ldda.id in created_ldda_ids
+ selected = created_ldda_ids and str( ldda.id ) in created_ldda_ids
%>
${render_dataset( cntrller, ldda, library_dataset, selected, library, folder, pad, my_row, row_counter, show_deleted=show_deleted )}
%endfor
@@ -341,21 +340,10 @@
<h2>Data Library “${library.name}”</h2>
<ul class="manage-table-actions">
- %if cntrller == 'library_admin' or can_add:
+ %if not library.deleted and ( cntrller in [ 'library_admin', 'requests_admin' ] or can_add ):
<li><a class="action-button" href="${h.url_for( controller='library_common', action='upload_library_dataset', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( library.root_folder.id ) )}"><span>Add datasets</span></a></li>
<li><a class="action-button" href="${h.url_for( controller='library_common', action='create_folder', cntrller=cntrller, parent_id=trans.security.encode_id( library.root_folder.id ), library_id=trans.security.encode_id( library.id ) )}">Add folder</a></li>
%endif
- %if cntrller == 'library_admin' or can_modify:
- <li><a class="action-button" href="${h.url_for( controller='library_common', action='library_info', cntrller=cntrller, id=trans.security.encode_id( library.id ) )}">Edit information</a></li>
- %else:
- <li><a class="action-button" href="${h.url_for( controller='library_common', action='library_info', cntrller=cntrller, id=trans.security.encode_id( library.id ) )}">View information</a></li>
- %endif
- %if ( cntrller == 'library_admin' or can_add ) and not info_association:
- <li><a class="action-button" href="${h.url_for( controller='library_common', action='info_template', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), response_action='browse_library' )}">Add template</a></li>
- %endif
- %if cntrller == 'library_admin' or can_manage:
- <li><a class="action-button" href="${h.url_for( controller='library_common', action='library_permissions', cntrller=cntrller, id=trans.security.encode_id( library.id ) )}">Edit permissions</a></li>
- %endif
</ul>
%if msg:
@@ -366,34 +354,42 @@
<table cellspacing="0" cellpadding="0" border="0" width="100%" class="grid" id="library-grid">
<thead>
<tr class="libraryTitle">
- %if cntrller == 'library':
- <th style="padding-left: 42px;">${library.name}</th>
- %elif cntrller == 'library_admin':
+ %if cntrller == 'library_admin' or can_add or can_modify or can_manage:
<th style="padding-left: 42px;">
${library.name}
<a id="library-${library.id}-popup" class="popup-arrow" style="display: none;">▼</a>
<div popupmenu="library-${library.id}-popup">
%if not library.deleted:
- <a class="action-button" href="${h.url_for( controller='library_common', action='library_info', cntrller='library_admin', id=trans.security.encode_id( library.id ) )}">Edit information</a>
- ## Editing templates disabled until we determine optimal approach to re-linking library item to new version of form definition
- ##%if library.info_association:
- ## <% form_id = library.info_association[0].template.id %>
- ## <a class="action-button" href="${h.url_for( controller='forms', action='edit', form_id=form_id, show_form=True )}">Edit information template</a>
- %if not library.info_association:
- <a class="action-button" href="${h.url_for( controller='library_common', action='info_template', cntrller='library_admin', library_id=trans.security.encode_id( library.id ), response_action='browse_library' )}">Add template</a>
+ %if cntrller == 'library_admin' or can_modify:
+ <a class="action-button" href="${h.url_for( controller='library_common', action='library_info', cntrller=cntrller, id=trans.security.encode_id( library.id ) )}">Edit information</a>
+ ## Editing templates disabled until we determine optimal approach to re-linking library item to new version of form definition
+ ##%if library.info_association:
+ ## <% form_id = library.info_association[0].template.id %>
+ ## <a class="action-button" href="${h.url_for( controller='forms', action='edit', form_id=form_id, show_form=True )}">Edit information template</a>
%endif
- <a class="action-button" href="${h.url_for( controller='library_common', action='library_permissions', cntrller='library_admin', id=trans.security.encode_id( library.id ) )}">Edit permissions</a>
- <a class="action-button" confirm="Click OK to delete the library named '${library.name}'." href="${h.url_for( controller='library_admin', action='delete_library_item', library_id=trans.security.encode_id( library.id ), library_item_id=trans.security.encode_id( library.id ), library_item_type='library' )}">Delete this data library and its contents</a>
+ %if cntrller == 'library_admin' or can_add:
+ %if not library.info_association:
+ <a class="action-button" href="${h.url_for( controller='library_common', action='info_template', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), response_action='browse_library' )}">Add template</a>
+ %endif
+ %endif
+ %if cntrller == 'library_admin' or can_manage:
+ <a class="action-button" href="${h.url_for( controller='library_common', action='library_permissions', cntrller=cntrller, id=trans.security.encode_id( library.id ) )}">Edit permissions</a>
+ %endif
+ %if cntrller == 'library_admin':
+ <a class="action-button" confirm="Click OK to delete the library named '${library.name}'." href="${h.url_for( controller='library_admin', action='delete_library_item', library_id=trans.security.encode_id( library.id ), library_item_id=trans.security.encode_id( library.id ), library_item_type='library' )}">Delete this data library and its contents</a>
+ %endif
%if show_deleted:
- <a class="action-button" href="${h.url_for( controller='library_common', action='browse_library', cntrller='library_admin', id=trans.security.encode_id( library.id ), show_deleted=False )}">Hide deleted items</a>
+ <a class="action-button" href="${h.url_for( controller='library_common', action='browse_library', cntrller=cntrller, id=trans.security.encode_id( library.id ), show_deleted=False )}">Hide deleted items</a>
%else:
- <a class="action-button" href="${h.url_for( controller='library_common', action='browse_library', cntrller='library_admin', id=trans.security.encode_id( library.id ), show_deleted=True )}">Show deleted items</a>
+ <a class="action-button" href="${h.url_for( controller='library_common', action='browse_library', cntrller=cntrller, id=trans.security.encode_id( library.id ), show_deleted=True )}">Show deleted items</a>
%endif
- %elif not library.purged:
+ %elif cntrller == 'library_admin' and not library.purged:
<a class="action-button" href="${h.url_for( controller='library_admin', action='undelete_library_item', library_id=trans.security.encode_id( library.id ), library_item_id=trans.security.encode_id( library.id ), library_item_type='library' )}">Undelete this data library</a>
%endif
</div>
</th>
+ %else:
+ <th style="padding-left: 42px;">${library.name}</th>
%endif
<th>Information</th>
<th>Uploaded By</th>
@@ -401,12 +397,16 @@
</thead>
</tr>
<% row_counter = RowCounter() %>
- %if cntrller == 'library':
+ %if cntrller in [ 'library', 'requests' ]:
${render_folder( 'library', library.root_folder, 0, created_ldda_ids, trans.security.encode_id( library.id ), hidden_folder_ids, parent=None, row_counter=row_counter, root_folder=True )}
- ${render_actions_on_multiple_items( 'library', default_action=default_action )}
- %elif cntrller == 'library_admin':
+ %if not library.deleted:
+ ${render_actions_on_multiple_items( 'library', default_action=default_action )}
+ %endif
+ %elif cntrller in [ 'library_admin', 'requests_admin' ]:
${render_folder( 'library_admin', library.root_folder, 0, created_ldda_ids, trans.security.encode_id( library.id ), [], parent=None, row_counter=row_counter, root_folder=True, show_deleted=show_deleted )}
- ${render_actions_on_multiple_items( 'library_admin', deleted=library.deleted, show_deleted=show_deleted )}
+ %if not library.deleted and not show_deleted:
+ ${render_actions_on_multiple_items( 'library_admin' )}
+ %endif
%endif
</table>
</form>
diff -r cadad7fc9284 -r 71928a8f9bf9 templates/library/common/common.mako
--- a/templates/library/common/common.mako Tue Jan 05 09:53:14 2010 -0500
+++ b/templates/library/common/common.mako Tue Jan 05 10:31:32 2010 -0500
@@ -59,7 +59,7 @@
%endif
</%def>
-<%def name="render_upload_form( cntrller, upload_option, action, library_id, folder_id, replace_dataset, file_formats, dbkeys, roles, history )">
+<%def name="render_upload_form( cntrller, upload_option, action, library_id, folder_id, replace_dataset, file_formats, dbkeys, widgets, roles, history )">
<% import os, os.path %>
%if upload_option in [ 'upload_file', 'upload_directory', 'upload_paths' ]:
<div class="toolForm" id="upload_library_dataset">
@@ -325,19 +325,16 @@
%endif
</%def>
-<%def name="render_actions_on_multiple_items( cntrller, default_action=None, deleted=False, show_deleted=False )">
+<%def name="render_actions_on_multiple_items( cntrller, default_action=None )">
<tfoot>
<tr>
<td colspan="4" style="padding-left: 42px;">
For selected items:
- %if cntrller=='library_admin' and not deleted and not show_deleted:
- <select name="do_action" id="action_on_selected_items">
+ <select name="do_action" id="action_on_selected_items">
+ %if cntrller=='library_admin':
<option value="manage_permissions">Edit permissions</option>
<option value="delete">Delete</option>
- </select>
- <input type="submit" class="primary-button" name="action_on_datasets_button" id="action_on_datasets_button" value="Go"/>
- %elif cntrller=='library':
- <select name="do_action" id="action_on_selected_items">
+ %elif cntrller=='library':
%if default_action == 'add':
<option value="add" selected>Import into your current history</option>
%else:
@@ -361,9 +358,9 @@
%if 'zip' in comptypes:
<option value="zip">Download as a .zip file</option>
%endif
- </select>
- <input type="submit" class="primary-button" name="action_on_datasets_button" id="action_on_datasets_button" value="Go"/>
- %endif
+ %endif
+ </select>
+ <input type="submit" class="primary-button" name="action_on_datasets_button" id="action_on_datasets_button" value="Go"/>
</td>
</tr>
</tfoot>
diff -r cadad7fc9284 -r 71928a8f9bf9 templates/library/common/ldda_permissions.mako
--- a/templates/library/common/ldda_permissions.mako Tue Jan 05 09:53:14 2010 -0500
+++ b/templates/library/common/ldda_permissions.mako Tue Jan 05 10:31:32 2010 -0500
@@ -62,4 +62,4 @@
%endif
<% ldda_ids = ",".join( [ trans.security.encode_id( d.id ) for d in lddas ] ) %>
-${render_permission_form( lddas[0], name_str, h.url_for( controller='library_common', action='ldda_permissions', library_id=library_id, folder_id=trans.security.encode_id( lddas[0].library_dataset.folder.id ), id=ldda_ids ), roles )}
+${render_permission_form( lddas[0], name_str, h.url_for( controller='library_common', action='ldda_permissions', cntrller=cntrller, library_id=library_id, folder_id=trans.security.encode_id( lddas[0].library_dataset.folder.id ), id=ldda_ids ), roles )}
diff -r cadad7fc9284 -r 71928a8f9bf9 templates/library/common/library_dataset_permissions.mako
--- a/templates/library/common/library_dataset_permissions.mako Tue Jan 05 09:53:14 2010 -0500
+++ b/templates/library/common/library_dataset_permissions.mako Tue Jan 05 10:31:32 2010 -0500
@@ -30,5 +30,5 @@
.filter( trans.app.model.Role.table.c.deleted==False ) \
.order_by( trans.app.model.Role.table.c.name )
%>
- ${render_permission_form( library_dataset, library_dataset.name, h.url_for( controller='library_common', action='library_dataset_permissions', id=trans.security.encode_id( library_dataset.id ), library_id=library_id ), roles )}
+ ${render_permission_form( library_dataset, library_dataset.name, h.url_for( controller='library_common', action='library_dataset_permissions', cntrller=cntrller, id=trans.security.encode_id( library_dataset.id ), library_id=library_id ), roles )}
%endif
diff -r cadad7fc9284 -r 71928a8f9bf9 templates/library/common/library_permissions.mako
--- a/templates/library/common/library_permissions.mako Tue Jan 05 09:53:14 2010 -0500
+++ b/templates/library/common/library_permissions.mako Tue Jan 05 10:31:32 2010 -0500
@@ -24,5 +24,5 @@
.filter( trans.app.model.Role.table.c.deleted==False ) \
.order_by( trans.app.model.Role.table.c.name )
%>
- ${render_permission_form( library, library.name, h.url_for( controller='library_common', action='library_permissions', id=trans.security.encode_id( library.id ), cntrller=cntrller ), roles )}
+ ${render_permission_form( library, library.name, h.url_for( controller='library_common', action='library_permissions', cntrller=cntrller, id=trans.security.encode_id( library.id ), cntrller=cntrller ), roles )}
%endif
diff -r cadad7fc9284 -r 71928a8f9bf9 templates/library/common/upload.mako
--- a/templates/library/common/upload.mako Tue Jan 05 09:53:14 2010 -0500
+++ b/templates/library/common/upload.mako Tue Jan 05 10:31:32 2010 -0500
@@ -53,4 +53,4 @@
${render_msg( msg, messagetype )}
%endif
-${render_upload_form( cntrller, upload_option, action, library_id, folder_id, replace_dataset, file_formats, dbkeys, roles, history )}
+${render_upload_form( cntrller, upload_option, action, library_id, folder_id, replace_dataset, file_formats, dbkeys, widgets, roles, history )}
diff -r cadad7fc9284 -r 71928a8f9bf9 templates/requests/show_request.mako
--- a/templates/requests/show_request.mako Tue Jan 05 09:53:14 2010 -0500
+++ b/templates/requests/show_request.mako Tue Jan 05 10:31:32 2010 -0500
@@ -111,7 +111,7 @@
%else:
%if rd['label'] == 'Data library':
%if rd['value']:
- <a href="${h.url_for( controller='library_common', action='browse_library', cntrller='library', id=trans.security.encode_id( request.library.id ) )}">${rd['value']}</a>
+ <a href="${h.url_for( controller='library_common', action='browse_library', cntrller='requests', id=trans.security.encode_id( request.library.id ) )}">${rd['value']}</a>
%endif
%elif rd['label'] == 'State':
<a href="${h.url_for( controller='requests', action='list', operation='events', id=trans.security.encode_id(request.id) )}">${rd['value']}</a>
diff -r cadad7fc9284 -r 71928a8f9bf9 test/base/twilltestcase.py
--- a/test/base/twilltestcase.py Tue Jan 05 09:53:14 2010 -0500
+++ b/test/base/twilltestcase.py Tue Jan 05 10:31:32 2010 -0500
@@ -1459,9 +1459,9 @@
tc.fv( "1", template_field_name1, template_field_contents1 )
tc.submit( "runtool_btn" )
if root:
- check_str = "Added 1 datasets to the library '%s' ( each is selected )." % folder_name
+ check_str = "Added 1 datasets to the library '%s' (each is selected)." % folder_name
else:
- check_str = "Added 1 datasets to the folder '%s' ( each is selected )." % folder_name
+ check_str = "Added 1 datasets to the folder '%s' (each is selected)." % folder_name
data = self.last_page()
self.library_wait( library_id )
self.home()
@@ -1556,9 +1556,9 @@
self.visit_url( "%s/library_common/add_history_datasets_to_library?cntrller=%s&library_id=%s&folder_id=%s&hda_ids=%s&add_history_datasets_to_library_button=Add+selected+datasets" % \
( self.url, cntrller, library_id, folder_id, hda_id ) )
if root:
- check_str = "Added 1 datasets to the library '%s' ( each is selected )." % folder_name
+ check_str = "Added 1 datasets to the library '%s' (each is selected)." % folder_name
else:
- check_str = "Added 1 datasets to the folder '%s' ( each is selected )." % folder_name
+ check_str = "Added 1 datasets to the folder '%s' (each is selected)." % folder_name
self.check_page_for_string( check_str )
self.home()
def add_dir_of_files_from_admin_view( self, library_id, folder_id, file_type='auto', dbkey='hg18', roles_tuple=[],
diff -r cadad7fc9284 -r 71928a8f9bf9 test/functional/test_security_and_libraries.py
--- a/test/functional/test_security_and_libraries.py Tue Jan 05 09:53:14 2010 -0500
+++ b/test/functional/test_security_and_libraries.py Tue Jan 05 10:31:32 2010 -0500
@@ -1282,7 +1282,7 @@
message = 'This is a test for uploading a directory of files'
template_contents = "%s contents for directory of 3 datasets in %s" % ( form_one_field_label, folder_one.name )
roles_tuple = [ ( str( role_one.id ), role_one.name ) ]
- check_str = "Added 3 datasets to the library '%s' ( each is selected )." % library_one.root_folder.name
+ check_str = "Added 3 datasets to the library '%s' (each is selected)." % library_one.root_folder.name
self.add_dir_of_files_from_admin_view( self.security.encode_id( library_one.id ),
self.security.encode_id( library_one.root_folder.id ),
roles_tuple=roles_tuple,
@@ -1422,7 +1422,7 @@
# Since regular_user1 does not have any sub-directories contained within her configured
# user_library_import_dir, the only option in her server_dir select list will be the
# directory named the same as her email
- check_str_after_submit = "Added 1 datasets to the library '%s' ( each is selected )." % library_one.root_folder.name
+ check_str_after_submit = "Added 1 datasets to the library '%s' (each is selected)." % library_one.root_folder.name
self.add_dir_of_files_from_libraries_view( self.security.encode_id( library_one.id ),
self.security.encode_id( library_one.root_folder.id ),
regular_user1.email,
1
0
05 Jan '10
details: http://www.bx.psu.edu/hg/galaxy/rev/cadad7fc9284
changeset: 3199:cadad7fc9284
user: rc
date: Tue Jan 05 09:53:14 2010 -0500
description:
Fixed update time bug in the request grids
diffstat:
lib/galaxy/web/controllers/requests.py | 27 +++---------------------
lib/galaxy/web/controllers/requests_admin.py | 30 +++++----------------------
2 files changed, 10 insertions(+), 47 deletions(-)
diffs (140 lines):
diff -r e5ae8c367b18 -r cadad7fc9284 lib/galaxy/web/controllers/requests.py
--- a/lib/galaxy/web/controllers/requests.py Mon Jan 04 15:45:41 2010 -0500
+++ b/lib/galaxy/web/controllers/requests.py Tue Jan 05 09:53:14 2010 -0500
@@ -26,14 +26,6 @@
class TypeColumn( grids.TextColumn ):
def get_value(self, trans, grid, request):
return request.type.name
- class LastUpdateColumn( grids.TextColumn ):
- def get_value(self, trans, grid, request):
- delta = datetime.utcnow() - request.update_time
- if delta > timedelta( minutes=60 ):
- last_update = '%s hours' % int( delta.seconds / 60 / 60 )
- else:
- last_update = '%s minutes' % int( delta.seconds / 60 )
- return last_update
class StateColumn( grids.GridColumn ):
def __init__( self, col_name, key, model_class, event_class, filterable, link ):
grids.GridColumn.__init__(self, col_name, key=key, model_class=model_class, filterable=filterable, link=link)
@@ -92,7 +84,7 @@
title = "Sequencing Requests"
template = 'requests/grid.mako'
model_class = model.Request
- default_sort_key = "-create_time"
+ default_sort_key = "create_time"
num_rows_per_page = 50
preserve_state = True
use_paging = True
@@ -111,8 +103,7 @@
SamplesColumn( "Sample(s)",
link=( lambda item: iff( item.deleted, None, dict( operation="show_request", id=item.id ) ) ), ),
TypeColumn( "Type" ),
- LastUpdateColumn( "Last update",
- format=time_ago ),
+ grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
DeletedColumn( "Deleted",
key="deleted",
visible=False,
@@ -234,12 +225,7 @@
events_list = []
all_events = request.events
for event in all_events:
- delta = datetime.utcnow() - event.update_time
- if delta > timedelta( minutes=60 ):
- last_update = '%s hours' % int( delta.seconds / 60 / 60 )
- else:
- last_update = '%s minutes' % int( delta.seconds / 60 )
- events_list.append((event.state, last_update, event.comment))
+ events_list.append((event.state, time_ago(event.update_time), event.comment))
return trans.fill_template( '/requests/events.mako',
events_list=events_list, request=request)
def request_details(self, trans, id):
@@ -983,12 +969,7 @@
events_list = []
all_events = sample.events
for event in all_events:
- delta = datetime.utcnow() - event.update_time
- if delta > timedelta( minutes=60 ):
- last_update = '%s hours' % int( delta.seconds / 60 / 60 )
- else:
- last_update = '%s minutes' % int( delta.seconds / 60 )
- events_list.append((event.state.name, event.state.desc, last_update, event.comment))
+ events_list.append((event.state.name, event.state.desc, time_ago(event.update_time), event.comment))
return trans.fill_template( '/sample/sample_events.mako',
events_list=events_list,
sample_name=sample.name,
diff -r e5ae8c367b18 -r cadad7fc9284 lib/galaxy/web/controllers/requests_admin.py
--- a/lib/galaxy/web/controllers/requests_admin.py Mon Jan 04 15:45:41 2010 -0500
+++ b/lib/galaxy/web/controllers/requests_admin.py Tue Jan 05 09:53:14 2010 -0500
@@ -31,14 +31,6 @@
class TypeColumn( grids.TextColumn ):
def get_value(self, trans, grid, request):
return request.type.name
- class LastUpdateColumn( grids.TextColumn ):
- def get_value(self, trans, grid, request):
- delta = datetime.utcnow() - request.update_time
- if delta > timedelta( minutes=60 ):
- last_update = '%s hours' % int( delta.seconds / 60 / 60 )
- else:
- last_update = '%s minutes' % int( delta.seconds / 60 )
- return last_update
class StateColumn( grids.GridColumn ):
def __init__( self, col_name, key, model_class, event_class, filterable, link ):
grids.GridColumn.__init__(self, col_name, key=key, model_class=model_class, filterable=filterable, link=link)
@@ -101,7 +93,7 @@
title = "Sequencing Requests"
template = "admin/requests/grid.mako"
model_class = model.Request
- default_sort_key = "-create_time"
+ default_sort_key = "-update_time"
num_rows_per_page = 50
preserve_state = True
use_paging = True
@@ -121,8 +113,7 @@
link=( lambda item: iff( item.deleted, None, dict( operation="show_request", id=item.id ) ) ), ),
TypeColumn( "Type",
link=( lambda item: iff( item.deleted, None, dict( operation="view_type", id=item.type.id ) ) ), ),
- LastUpdateColumn( "Last update",
- format=time_ago ),
+ grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
DeletedColumn( "Deleted",
key="deleted",
visible=False,
@@ -232,7 +223,7 @@
# ---- Request Controller ------------------------------------------------------
#
-class Requests( BaseController ):
+class RequestsAdmin( BaseController ):
request_grid = RequestsGrid()
requesttype_grid = RequestTypeGrid()
@@ -528,12 +519,7 @@
events_list = []
all_events = request.events
for event in all_events:
- delta = datetime.utcnow() - event.update_time
- if delta > timedelta( minutes=60 ):
- last_update = '%s hours' % int( delta.seconds / 60 / 60 )
- else:
- last_update = '%s minutes' % int( delta.seconds / 60 )
- events_list.append((event.state, last_update, event.comment))
+ events_list.append((event.state, time_ago(event.update_time), event.comment))
return trans.fill_template( '/admin/requests/events.mako',
events_list=events_list, request=request)
#
@@ -1332,12 +1318,8 @@
events_list = []
all_events = sample.events
for event in all_events:
- delta = datetime.utcnow() - event.update_time
- if delta > timedelta( minutes=60 ):
- last_update = '%s hours' % int( delta.seconds / 60 / 60 )
- else:
- last_update = '%s minutes' % int( delta.seconds / 60 )
- events_list.append((event.state.name, event.state.desc, last_update, event.comment))
+ events_list.append((event.state.name, event.state.desc,
+ time_ago(event.update_time), event.comment))
widgets, title = self.change_state(trans, sample)
return trans.fill_template( '/admin/samples/events.mako',
events_list=events_list,
1
0
05 Jan '10
details: http://www.bx.psu.edu/hg/galaxy/rev/e5ae8c367b18
changeset: 3198:e5ae8c367b18
user: Nate Coraor <nate(a)bx.psu.edu>
date: Mon Jan 04 15:45:41 2010 -0500
description:
Fix a pkg_resources.require bug where certain types of version conflicts would raise an exception and the require would fail.
diffstat:
lib/galaxy/eggs/__init__.py | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diffs (13 lines):
diff -r 0e5788188e23 -r e5ae8c367b18 lib/galaxy/eggs/__init__.py
--- a/lib/galaxy/eggs/__init__.py Mon Jan 04 15:25:47 2010 -0500
+++ b/lib/galaxy/eggs/__init__.py Mon Jan 04 15:45:41 2010 -0500
@@ -526,7 +526,9 @@
raise Exception( "Cannot remove entry: %s" % str(entry) )
r = require( pkg )
if location is not None and not location.endswith( '.egg' ):
+ # re-add the path if it's a non-egg dir, in case more deps live there
working_set.entries.append( location ) # re-add to the set if it's a dir.
+ sys.path.append( location ) # re-add to the set if it's a dir.
return r
except pkg_resources.DistributionNotFound, e:
# the initial require itself is the first dep, but it can have
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/0e5788188e23
changeset: 3197:0e5788188e23
user: jeremy goecks <jeremy.goecks(a)emory.edu>
date: Mon Jan 04 15:25:47 2010 -0500
description:
Pack autocomplete script.
diffstat:
static/scripts/packed/jquery.autocomplete.js | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diffs (8 lines):
diff -r d63ccd7f6d4c -r 0e5788188e23 static/scripts/packed/jquery.autocomplete.js
--- a/static/scripts/packed/jquery.autocomplete.js Mon Jan 04 15:20:29 2010 -0500
+++ b/static/scripts/packed/jquery.autocomplete.js Mon Jan 04 15:25:47 2010 -0500
@@ -1,1 +1,1 @@
-String.prototype.endsWith=function(a){return(this.match(a+"$")==a)};var return_key_pressed_for_autocomplete=false;(function(a){a.fn.extend({autocomplete:function(b,c){var d=typeof b=="string";c=a.extend({},a.Autocompleter.defaults,{url:d?b:null,data:d?null:b,delay:d?a.Autocompleter.defaults.delay:10,max:c&&!c.scroll?10:150},c);c.highlight=c.highlight||function(e){return e};c.formatMatch=c.formatMatch||c.formatItem;return this.each(function(){new a.Autocompleter(this,c)})},result:function(b){return this.bind("result",b)},search:function(b){return this.trigger("search",[b])},flushCache:function(){return this.trigger("flushCache")},setOptions:function(b){return this.trigger("setOptions",[b])},unautocomplete:function(){return this.trigger("unautocomplete")},showAllInCache:function(){return this.trigger("showAllInCache")}});a.Autocompleter=function(l,g){var c={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34,BACKSPACE:8,COLON:16};var b=a(l).attr("autoco
mplete","off").addClass(g.inputClass);var j;var p="";var m=a.Autocompleter.Cache(g);var e=0;var u;var x={mouseDownOnSelect:false};var r=a.Autocompleter.Select(g,l,d,x);var w;a.browser.opera&&a(l.form).bind("submit.autocomplete",function(){if(w){w=false;return false}});b.bind((a.browser.opera?"keypress":"keydown")+".autocomplete",function(y){u=y.keyCode;switch(y.keyCode){case c.UP:y.preventDefault();if(r.visible()){r.prev()}else{t(0,true)}break;case c.DOWN:y.preventDefault();if(r.visible()){r.next()}else{t(0,true)}break;case c.PAGEUP:y.preventDefault();if(r.visible()){r.pageUp()}else{t(0,true)}break;case c.PAGEDOWN:y.preventDefault();if(r.visible()){r.pageDown()}else{t(0,true)}break;case g.multiple&&a.trim(g.multipleSeparator)==","&&c.COMMA:case c.TAB:case c.RETURN:if(y.keyCode==c.RETURN){return_key_pressed_for_autocomplete=false}if(d()){y.preventDefault();w=true;if(y.keyCode==c.RETURN){return_key_pressed_for_autocomplete=true}return false}case c.ESC:r.hide();break;case c.COL
ON:break;default:clearTimeout(j);j=setTimeout(t,g.delay);break}}).focus(function(){e++}).blur(function(){e=0;if(!x.mouseDownOnSelect){r.hide()}return this}).click(function(){if(e++>1&&!r.visible()){t(0,true)}return this}).bind("search",function(){var y=(arguments.length>1)?arguments[1]:null;function z(D,C){var A;if(C&&C.length){for(var B=0;B<C.length;B++){if(C[B].result.toLowerCase()==D.toLowerCase()){A=C[B];break}}}if(typeof y=="function"){y(A)}else{b.trigger("result",A&&[A.data,A.value])}}a.each(h(b.val()),function(A,B){f(B,z,z)});return this}).bind("flushCache",function(){m.flush()}).bind("setOptions",function(){a.extend(g,arguments[1]);if("data" in arguments[1]){m.populate()}}).bind("unautocomplete",function(){r.unbind();b.unbind();a(l.form).unbind(".autocomplete")}).bind("showAllInCache",function(){k("",m.load(""))});function d(){var z=r.selected();if(!z){return false}var y=z.result;p=y;if(g.multiple){var A=h(b.val());if(A.length>1){y=A.slice(0,A.length-1).join(g.multip
leSeparator)+g.multipleSeparator+y}y+=g.multipleSeparator}b.val(y);v();b.trigger("result",[z.data,z.value]);return true}function t(A,z){if(u==c.DEL){r.hide();return}var y=b.val();if(!z&&y==p){return}p=y;y=i(y);if(y.length>=g.minChars){b.addClass(g.loadingClass);if(!g.matchCase){y=y.toLowerCase()}f(y,k,v)}else{n();r.hide()}}function h(z){if(!z){return[""]}var A=z.split(g.multipleSeparator);var y=[];a.each(A,function(B,C){if(a.trim(C)){y[B]=a.trim(C)}});return y}function i(y){if(!g.multiple){return y}var z=h(y);return z[z.length-1]}function q(y,z){if(g.autoFill&&(i(b.val()).toLowerCase()==y.toLowerCase())&&u!=c.BACKSPACE){b.val(b.val()+z.substring(i(p).length));a.Autocompleter.Selection(l,p.length,p.length+z.length)}}function s(){clearTimeout(j);j=setTimeout(v,200)}function v(){var y=r.visible();r.hide();clearTimeout(j);n();if(g.mustMatch){b.search(function(z){if(!z){if(g.multiple){var A=h(b.val()).slice(0,-1);b.val(A.join(g.multipleSeparator)+(A.length?g.multipleSeparator:"")
)}else{b.val("")}}})}if(y){a.Autocompleter.Selection(l,l.value.length,l.value.length)}}function k(z,y){if(y&&y.length&&e){n();r.display(y,z);q(z,y[0].value);r.show()}else{v()}}function f(z,B,y){if(!g.matchCase){z=z.toLowerCase()}var A=m.load(z);if(z.endsWith(":")){A=null}if(A&&A.length){B(z,A)}else{if((typeof g.url=="string")&&(g.url.length>0)){var C={timestamp:+new Date()};a.each(g.extraParams,function(D,E){C[D]=typeof E=="function"?E():E});a.ajax({mode:"abort",port:"autocomplete"+l.name,dataType:g.dataType,url:g.url,data:a.extend({q:i(z),limit:g.max},C),success:function(E){var D=g.parse&&g.parse(E)||o(E);m.add(z,D);B(z,D)}})}else{r.emptyList();y(z)}}}function o(B){var y=[];var A=B.split("\n");for(var z=0;z<A.length;z++){var C=a.trim(A[z]);if(C){C=C.split("|");y[y.length]={data:C,value:C[0],result:g.formatResult&&g.formatResult(C,C[0])||C[0]}}}return y}function n(){b.removeClass(g.loadingClass)}};a.Autocompleter.defaults={inputClass:"ac_input",resultsClass:"ac_results",load
ingClass:"ac_loading",minChars:1,delay:400,matchCase:false,matchSubset:true,matchContains:false,cacheLength:10,max:100,mustMatch:false,extraParams:{},selectFirst:true,formatItem:function(b){return b[0]},formatMatch:null,autoFill:false,width:0,multiple:false,multipleSeparator:", ",highlight:function(c,b){if(b==""){return c}return c.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+b.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"<strong>$1</strong>")},scroll:true,scrollHeight:180};a.Autocompleter.Cache=function(c){var f={};var d=0;function h(l,k){if(!c.matchCase){l=l.toLowerCase()}var j=l.indexOf(k);if(j==-1){return false}return j==0||c.matchContains}function g(j,i){if(d>c.cacheLength){b()}if(!f[j]){d++}f[j]=i}function e(){if(!c.data){return false}var k={},j=0;if(!c.url){c.cacheLength=1}k[""]=[];for(var m=0,l=c.data.length;m<l;m++){var p=c.data[m];p=(typeof p=="string")?[p]:p;var o=c.formatMatch(p,m+1,c.data.length);if(o===false){continue}var
n=o.charAt(0).toLowerCase();if(!k[n]){k[n]=[]}var q={value:o,data:p,result:c.formatResult&&c.formatResult(p)||o};k[n].push(q);if(j++<c.max){k[""].push(q)}}a.each(k,function(r,s){c.cacheLength++;g(r,s)})}setTimeout(e,25);function b(){f={};d=0}return{flush:b,add:g,populate:e,load:function(n){if(!c.cacheLength||!d){return null}if(!c.url&&c.matchContains){var m=[];for(var j in f){if(j.length>0){var o=f[j];a.each(o,function(p,k){if(h(k.value,n)){m.push(k)}})}}return m}else{if(f[n]){return f[n]}else{if(c.matchSubset){for(var l=n.length-1;l>=c.minChars;l--){var o=f[n.substr(0,l)];if(o){var m=[];a.each(o,function(p,k){if((k.data.indexOf("#Header")==0)||(h(k.value,n))){m[m.length]=k}});return m}}}}}return null}}};a.Autocompleter.Select=function(e,j,l,q){var i={ACTIVE:"ac_over"};var k,f=-1,s,m="",t=true,c,p;function o(){if(!t){return}c=a("<div/>").hide().addClass(e.resultsClass).css("position","absolute").appendTo(document.body);p=a("<ul/>").appendTo(c).mouseover(function(u){if(r(u).
nodeName&&r(u).nodeName.toUpperCase()=="LI"){f=a("li",p).removeClass(i.ACTIVE).index(r(u));if(!n(f)){a(r(u)).addClass(i.ACTIVE)}}}).click(function(u){f=a("li",p).index(r(u));if(n(f)){return}a(r(u)).addClass(i.ACTIVE);l();j.focus();return false}).mousedown(function(){q.mouseDownOnSelect=true}).mouseup(function(){q.mouseDownOnSelect=false});if(e.width>0){c.css("width",e.width)}t=false}function r(v){var u=v.target;while(u&&u.tagName!="LI"){u=u.parentNode}if(!u){return[]}return u}function n(u){dataAtPosition=s[u].data;return(dataAtPosition.indexOf("#Header")==0)}function h(u){k.slice(f,f+1).removeClass(i.ACTIVE);var v=false;do{g(u);v=n(f)}while(v);var x=k.slice(f,f+1).addClass(i.ACTIVE);if(e.scroll){var w=0;k.slice(0,f).each(function(){w+=this.offsetHeight});if((w+x[0].offsetHeight-p.scrollTop())>p[0].clientHeight){p.scrollTop(w+x[0].offsetHeight-p.innerHeight())}else{if(w<p.scrollTop()){p.scrollTop(w)}}}}function g(u){f+=u;if(f<0){f=k.size()-1}else{if(f>=k.size()){f=0}}}functio
n b(u){return e.max&&e.max<u?e.max:u}function d(){p.empty();var v=b(s.length);for(var w=0;w<v;w++){if(!s[w]){continue}var x=e.formatItem(s[w].data,w+1,v,s[w].value,m);if(x===false){continue}if(n(w)){if(w!=v-1){var u=a("<li/>").html(s[w].data[1]).addClass("ac_header").appendTo(p)[0]}}else{var u=a("<li/>").html(e.highlight(x,m)).addClass(w%2==0?"ac_even":"ac_odd").appendTo(p)[0]}a.data(u,"ac_data",s[w])}k=p.find("li");if(e.selectFirst){k.slice(0,1).addClass(i.ACTIVE);f=0}if(a.fn.bgiframe){p.bgiframe()}}return{display:function(v,u){o();s=v;m=u;d()},next:function(){h(1)},prev:function(){h(-1)},pageUp:function(){if(f!=0&&f-8<0){h(-f)}else{h(-8)}},pageDown:function(){if(f!=k.size()-1&&f+8>k.size()){h(k.size()-1-f)}else{h(8)}},hide:function(){c&&c.hide();k&&k.removeClass(i.ACTIVE);f=-1},visible:function(){return c&&c.is(":visible")},current:function(){return this.visible()&&(k.filter("."+i.ACTIVE)[0]||e.selectFirst&&k[0])},show:function(){var w=a(j).offset();c.css({width:typeof e.w
idth=="string"||e.width>0?e.width:a(j).width(),top:w.top+j.offsetHeight,left:w.left}).show();if(e.scroll){p.scrollTop(0);p.css({maxHeight:e.scrollHeight,overflow:"auto"});if(a.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var u=0;k.each(function(){u+=this.offsetHeight});var v=u>e.scrollHeight;p.css("height",v?e.scrollHeight:u);if(!v){k.width(p.width()-parseInt(k.css("padding-left"))-parseInt(k.css("padding-right")))}}}},selected:function(){var u=k&&k.filter("."+i.ACTIVE).removeClass(i.ACTIVE);return u&&u.length&&a.data(u[0],"ac_data")},emptyList:function(){p&&p.empty()},unbind:function(){c&&c.remove()}}};a.Autocompleter.Selection=function(d,e,c){if(d.createTextRange){var b=d.createTextRange();b.collapse(true);b.moveStart("character",e);b.moveEnd("character",c);b.select()}else{if(d.setSelectionRange){d.setSelectionRange(e,c)}else{if(d.selectionStart){d.selectionStart=e;d.selectionEnd=c}}}d.focus()}})(jQuery);
\ No newline at end of file
+String.prototype.endsWith=function(a){return(this.match(a+"$")==a)};var return_key_pressed_for_autocomplete=false;(function(a){a.fn.extend({autocomplete:function(b,c){var d=typeof b=="string";c=a.extend({},a.Autocompleter.defaults,{url:d?b:null,data:d?null:b,delay:d?a.Autocompleter.defaults.delay:10,max:c&&!c.scroll?10:150},c);c.highlight=c.highlight||function(e){return e};c.formatMatch=c.formatMatch||c.formatItem;return this.each(function(){new a.Autocompleter(this,c)})},result:function(b){return this.bind("result",b)},search:function(b){return this.trigger("search",[b])},flushCache:function(){return this.trigger("flushCache")},setOptions:function(b){return this.trigger("setOptions",[b])},unautocomplete:function(){return this.trigger("unautocomplete")},showAllInCache:function(){return this.trigger("showAllInCache")}});a.Autocompleter=function(l,g){var c={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34,BACKSPACE:8,COLON:16};var b=a(l).attr("autoco
mplete","off").addClass(g.inputClass);var j;var p="";var m=a.Autocompleter.Cache(g);var e=0;var u;var x={mouseDownOnSelect:false};var r=a.Autocompleter.Select(g,l,d,x);var w;a.browser.opera&&a(l.form).bind("submit.autocomplete",function(){if(w){w=false;return false}});b.bind((a.browser.opera?"keypress":"keydown")+".autocomplete",function(y){u=y.keyCode;switch(y.keyCode){case c.UP:y.preventDefault();if(r.visible()){r.prev()}else{t(0,true)}break;case c.DOWN:y.preventDefault();if(r.visible()){r.next()}else{t(0,true)}break;case c.PAGEUP:y.preventDefault();if(r.visible()){r.pageUp()}else{t(0,true)}break;case c.PAGEDOWN:y.preventDefault();if(r.visible()){r.pageDown()}else{t(0,true)}break;case g.multiple&&a.trim(g.multipleSeparator)==","&&c.COMMA:case c.TAB:case c.RETURN:if(y.keyCode==c.RETURN){return_key_pressed_for_autocomplete=false}if(d()){y.preventDefault();w=true;if(y.keyCode==c.RETURN){return_key_pressed_for_autocomplete=true}return false}case c.ESC:r.hide();break;case c.COL
ON:break;default:clearTimeout(j);j=setTimeout(t,g.delay);break}}).focus(function(){e++}).blur(function(){e=0;if(!x.mouseDownOnSelect){r.hide()}return this}).click(function(){if(e++>1&&!r.visible()){t(0,true)}return this}).bind("search",function(){var y=(arguments.length>1)?arguments[1]:null;function z(D,C){var A;if(C&&C.length){for(var B=0;B<C.length;B++){if(C[B].result.toLowerCase()==D.toLowerCase()){A=C[B];break}}}if(typeof y=="function"){y(A)}else{b.trigger("result",A&&[A.data,A.value])}}a.each(h(b.val()),function(A,B){f(B,z,z)});return this}).bind("flushCache",function(){m.flush()}).bind("setOptions",function(){a.extend(g,arguments[1]);if("data" in arguments[1]){m.populate()}}).bind("unautocomplete",function(){r.unbind();b.unbind();a(l.form).unbind(".autocomplete")}).bind("showAllInCache",function(){k("",m.load(""))});function d(){var z=r.selected();if(!z){return false}var y=z.result;p=y;if(g.multiple){var A=h(b.val());if(A.length>1){y=A.slice(0,A.length-1).join(g.multip
leSeparator)+g.multipleSeparator+y}y+=g.multipleSeparator}b.val(y);v();b.trigger("result",[z.data,z.value]);return true}function t(A,z){if(u==c.DEL){r.hide();return}var y=b.val();if(!z&&y==p){return}p=y;y=i(y);if(y.length>=g.minChars){b.addClass(g.loadingClass);if(!g.matchCase){y=y.toLowerCase()}f(y,k,v)}else{n();r.hide()}}function h(z){if(!z){return[""]}var A=z.split(g.multipleSeparator);var y=[];a.each(A,function(B,C){if(a.trim(C)){y[B]=a.trim(C)}});return y}function i(y){if(!g.multiple){return y}var z=h(y);return z[z.length-1]}function q(y,z){if(g.autoFill&&(i(b.val()).toLowerCase()==y.toLowerCase())&&u!=c.BACKSPACE){b.val(b.val()+z.substring(i(p).length));a.Autocompleter.Selection(l,p.length,p.length+z.length)}}function s(){clearTimeout(j);j=setTimeout(v,200)}function v(){var y=r.visible();r.hide();clearTimeout(j);n();if(g.mustMatch){b.search(function(z){if(!z){if(g.multiple){var A=h(b.val()).slice(0,-1);b.val(A.join(g.multipleSeparator)+(A.length?g.multipleSeparator:"")
)}else{b.val("")}}})}if(y){a.Autocompleter.Selection(l,l.value.length,l.value.length)}}function k(z,y){if(y&&y.length&&e){n();r.display(y,z);q(z,y[0].value);r.show()}else{v()}}function f(z,B,y){if(!g.matchCase){z=z.toLowerCase()}var A=m.load(z);if(z.endsWith(":")){A=null}if(A&&A.length){B(z,A)}else{if((typeof g.url=="string")&&(g.url.length>0)){var C={timestamp:+new Date()};a.each(g.extraParams,function(D,E){C[D]=typeof E=="function"?E():E});a.ajax({mode:"abort",port:"autocomplete"+l.name,dataType:g.dataType,url:g.url,data:a.extend({q:i(z),limit:g.max},C),success:function(E){var D=g.parse&&g.parse(E)||o(E);m.add(z,D);B(z,D)}})}else{r.emptyList();y(z)}}}function o(B){var y=[];var A=B.split("\n");for(var z=0;z<A.length;z++){var C=a.trim(A[z]);if(C){C=C.split("|");y[y.length]={data:C,value:C[0],result:g.formatResult&&g.formatResult(C,C[0])||C[0]}}}return y}function n(){b.removeClass(g.loadingClass)}};a.Autocompleter.defaults={inputClass:"ac_input",resultsClass:"ac_results",load
ingClass:"ac_loading",minChars:1,delay:400,matchCase:false,matchSubset:true,matchContains:false,cacheLength:10,max:100,mustMatch:false,extraParams:{},selectFirst:true,formatItem:function(b){return b[0]},formatMatch:null,autoFill:false,width:0,multiple:false,multipleSeparator:", ",highlight:function(c,b){if(b==""){return c}return c.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+b.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"<strong>$1</strong>")},scroll:true,scrollHeight:180};a.Autocompleter.Cache=function(c){var f={};var d=0;function h(l,k){if(!c.matchCase){l=l.toLowerCase()}var j=l.indexOf(k);if(j==-1){return false}return j==0||c.matchContains}function g(j,i){if(d>c.cacheLength){b()}if(!f[j]){d++}f[j]=i}function e(){if(!c.data){return false}var k={},j=0;if(!c.url){c.cacheLength=1}k[""]=[];for(var m=0,l=c.data.length;m<l;m++){var p=c.data[m];p=(typeof p=="string")?[p]:p;var o=c.formatMatch(p,m+1,c.data.length);if(o===false){continue}var
n=o.charAt(0).toLowerCase();if(!k[n]){k[n]=[]}var q={value:o,data:p,result:c.formatResult&&c.formatResult(p)||o};k[n].push(q);if(j++<c.max){k[""].push(q)}}a.each(k,function(r,s){c.cacheLength++;g(r,s)})}setTimeout(e,25);function b(){f={};d=0}return{flush:b,add:g,populate:e,load:function(n){if(!c.cacheLength||!d){return null}if(!c.url&&c.matchContains){var m=[];for(var j in f){if(j.length>0){var o=f[j];a.each(o,function(p,k){if(h(k.value,n)){m.push(k)}})}}return m}else{if(f[n]){return f[n]}else{if(c.matchSubset){for(var l=n.length-1;l>=c.minChars;l--){var o=f[n.substr(0,l)];if(o){var m=[];a.each(o,function(p,k){if((k.data.indexOf("#Header")==0)||(h(k.value,n))){m[m.length]=k}});return m}}}}}return null}}};a.Autocompleter.Select=function(e,j,l,q){var i={ACTIVE:"ac_over"};var k,f=-1,s,m="",t=true,c,p;function o(){if(!t){return}c=a("<div/>").hide().addClass(e.resultsClass).css("position","absolute").appendTo(document.body);p=a("<ul/>").appendTo(c).mouseover(function(u){if(r(u).
nodeName&&r(u).nodeName.toUpperCase()=="LI"){f=a("li",p).removeClass(i.ACTIVE).index(r(u));if(!n(f)){a(r(u)).addClass(i.ACTIVE)}}}).click(function(u){f=a("li",p).index(r(u));if(n(f)){return}a(r(u)).addClass(i.ACTIVE);l();j.focus();return false}).mousedown(function(){q.mouseDownOnSelect=true}).mouseup(function(){q.mouseDownOnSelect=false});if(e.width>0){c.css("width",e.width)}t=false}function r(v){var u=v.target;while(u&&u.tagName!="LI"){u=u.parentNode}if(!u){return[]}return u}function n(u){dataAtPosition=s[u].data;return(dataAtPosition[0].indexOf("#Header")==0)}function h(u){k.slice(f,f+1).removeClass(i.ACTIVE);var v=false;do{g(u);v=n(f)}while(v);var x=k.slice(f,f+1).addClass(i.ACTIVE);if(e.scroll){var w=0;k.slice(0,f).each(function(){w+=this.offsetHeight});if((w+x[0].offsetHeight-p.scrollTop())>p[0].clientHeight){p.scrollTop(w+x[0].offsetHeight-p.innerHeight())}else{if(w<p.scrollTop()){p.scrollTop(w)}}}}function g(u){f+=u;if(f<0){f=k.size()-1}else{if(f>=k.size()){f=0}}}func
tion b(u){return e.max&&e.max<u?e.max:u}function d(){p.empty();var v=b(s.length);for(var w=0;w<v;w++){if(!s[w]){continue}var x=e.formatItem(s[w].data,w+1,v,s[w].value,m);if(x===false){continue}if(n(w)){if(w!=v-1){var u=a("<li/>").html(s[w].data[1]).addClass("ac_header").appendTo(p)[0]}}else{var u=a("<li/>").html(e.highlight(x,m)).addClass(w%2==0?"ac_even":"ac_odd").appendTo(p)[0]}a.data(u,"ac_data",s[w])}k=p.find("li");if(e.selectFirst){k.slice(0,1).addClass(i.ACTIVE);f=0}if(a.fn.bgiframe){p.bgiframe()}}return{display:function(v,u){o();s=v;m=u;d()},next:function(){h(1)},prev:function(){h(-1)},pageUp:function(){if(f!=0&&f-8<0){h(-f)}else{h(-8)}},pageDown:function(){if(f!=k.size()-1&&f+8>k.size()){h(k.size()-1-f)}else{h(8)}},hide:function(){c&&c.hide();k&&k.removeClass(i.ACTIVE);f=-1},visible:function(){return c&&c.is(":visible")},current:function(){return this.visible()&&(k.filter("."+i.ACTIVE)[0]||e.selectFirst&&k[0])},show:function(){var w=a(j).offset();c.css({width:typeof
e.width=="string"||e.width>0?e.width:a(j).width(),top:w.top+j.offsetHeight,left:w.left}).show();if(e.scroll){p.scrollTop(0);p.css({maxHeight:e.scrollHeight,overflow:"auto"});if(a.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var u=0;k.each(function(){u+=this.offsetHeight});var v=u>e.scrollHeight;p.css("height",v?e.scrollHeight:u);if(!v){k.width(p.width()-parseInt(k.css("padding-left"))-parseInt(k.css("padding-right")))}}}},selected:function(){var u=k&&k.filter("."+i.ACTIVE).removeClass(i.ACTIVE);return u&&u.length&&a.data(u[0],"ac_data")},emptyList:function(){p&&p.empty()},unbind:function(){c&&c.remove()}}};a.Autocompleter.Selection=function(d,e,c){if(d.createTextRange){var b=d.createTextRange();b.collapse(true);b.moveStart("character",e);b.moveEnd("character",c);b.select()}else{if(d.setSelectionRange){d.setSelectionRange(e,c)}else{if(d.selectionStart){d.selectionStart=e;d.selectionEnd=c}}}d.focus()}})(jQuery);
\ No newline at end of file
1
0
05 Jan '10
details: http://www.bx.psu.edu/hg/galaxy/rev/d63ccd7f6d4c
changeset: 3196:d63ccd7f6d4c
user: jeremy goecks <jeremy.goecks(a)emory.edu>
date: Mon Jan 04 15:20:29 2010 -0500
description:
Fix autocomplete IE bug. Fix enables autocomplete to work on IE and hence dbkey select box to work on IE.
diffstat:
static/scripts/jquery.autocomplete.js | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diffs (12 lines):
diff -r ec34b27de1c0 -r d63ccd7f6d4c static/scripts/jquery.autocomplete.js
--- a/static/scripts/jquery.autocomplete.js Mon Jan 04 12:51:34 2010 -0500
+++ b/static/scripts/jquery.autocomplete.js Mon Jan 04 15:20:29 2010 -0500
@@ -655,7 +655,7 @@
function headerAtPosition(position)
{
dataAtPosition = data[position].data;
- return (dataAtPosition.indexOf("#Header") == 0);
+ return (dataAtPosition[0].indexOf("#Header") == 0);
}
function moveSelect(step) {
1
0
05 Jan '10
details: http://www.bx.psu.edu/hg/galaxy/rev/ec34b27de1c0
changeset: 3195:ec34b27de1c0
user: Nate Coraor <nate(a)bx.psu.edu>
date: Mon Jan 04 12:51:34 2010 -0500
description:
python run from virtualenv sets up site.py to pull things from the real python's lib directory, so 'python -S' breaks it. To fix this, have the check_python.py script check for virtualenv and output the arguments that should be used to start python ('python -E' for virtualenv, 'python -ES' for real), then use these arguments anywhere 'python -ES' was used in the past.
diffstat:
manage_db.sh | 2 +-
run.sh | 8 +++++---
run_functional_tests.sh | 10 ++++++----
run_reports.sh | 2 +-
run_unit_tests.sh | 2 +-
scripts/check_python.py | 9 +++++++++
set_metadata.sh | 2 +-
setup.sh | 4 ++--
8 files changed, 26 insertions(+), 13 deletions(-)
diffs (145 lines):
diff -r 4743015d9a57 -r ec34b27de1c0 manage_db.sh
--- a/manage_db.sh Wed Dec 23 20:26:01 2009 -0500
+++ b/manage_db.sh Mon Jan 04 12:51:34 2010 -0500
@@ -6,4 +6,4 @@
#######
cd `dirname $0`
-python -ES ./scripts/manage_db.py $@
+`python ./scripts/check_python.py` ./scripts/manage_db.py $@
diff -r 4743015d9a57 -r ec34b27de1c0 run.sh
--- a/run.sh Wed Dec 23 20:26:01 2009 -0500
+++ b/run.sh Mon Jan 04 12:51:34 2010 -0500
@@ -2,16 +2,18 @@
cd `dirname $0`
+CLEAN_PYTHON=`python ./scripts/check_python.py`
+
# explicitly attempt to fetch eggs before running
FETCH_EGGS=1
for arg in "$@"; do
[ "$arg" = "--stop-daemon" ] && FETCH_EGGS=0; break
done
if [ $FETCH_EGGS -eq 1 ]; then
- python -ES ./scripts/check_eggs.py quiet
+ $CLEAN_PYTHON ./scripts/check_eggs.py quiet
if [ $? -ne 0 ]; then
echo "Some eggs are out of date, attempting to fetch..."
- python -ES ./scripts/fetch_eggs.py
+ $CLEAN_PYTHON ./scripts/fetch_eggs.py
if [ $? -eq 0 ]; then
echo "Fetch successful."
else
@@ -20,4 +22,4 @@
fi
fi
fi
-python -ES ./scripts/paster.py serve universe_wsgi.ini $@
+$CLEAN_PYTHON ./scripts/paster.py serve universe_wsgi.ini $@
diff -r 4743015d9a57 -r ec34b27de1c0 run_functional_tests.sh
--- a/run_functional_tests.sh Wed Dec 23 20:26:01 2009 -0500
+++ b/run_functional_tests.sh Mon Jan 04 12:51:34 2010 -0500
@@ -4,8 +4,10 @@
rm -f run_functional_tests.log
+CLEAN_PYTHON=`python ./scripts/check_python.py`
+
if [ ! $1 ]; then
- python -ES ./scripts/functional_tests.py -v --with-nosehtml --html-report-file run_functional_tests.html --exclude="^get" functional
+ $CLEAN_PYTHON ./scripts/functional_tests.py -v --with-nosehtml --html-report-file run_functional_tests.html --exclude="^get" functional
elif [ $1 = 'help' ]; then
echo "'run_functional_tests.sh' for testing all the tools in functional directory"
echo "'run_functional_tests.sh aaa' for testing one test case of 'aaa' ('aaa' is the file name with path)"
@@ -13,16 +15,16 @@
echo "'run_functional_tests.sh -sid ccc' for testing one section with sid 'ccc' ('ccc' is the string after 'section::')"
echo "'run_functional_tests.sh -list' for listing all the tool ids"
elif [ $1 = '-id' ]; then
- python -ES ./scripts/functional_tests.py -v functional.test_toolbox:TestForTool_$2 --with-nosehtml --html-report-file run_functional_tests.html
+ $CLEAN_PYTHON ./scripts/functional_tests.py -v functional.test_toolbox:TestForTool_$2 --with-nosehtml --html-report-file run_functional_tests.html
elif [ $1 = '-sid' ]; then
- python -ES ./scripts/functional_tests.py --with-nosehtml --html-report-file run_functional_tests.html -v `python tool_list.py $2`
+ $CLEAN_PYTHON ./scripts/functional_tests.py --with-nosehtml --html-report-file run_functional_tests.html -v `python tool_list.py $2`
elif [ $1 = '-list' ]; then
python tool_list.py
echo "==========================================================================================================================================="
echo "'run_functional_tests.sh -id bbb' for testing one tool with id 'bbb' ('bbb' is the tool id)"
echo "'run_functional_tests.sh -sid ccc' for testing one section with sid 'ccc' ('ccc' is the string after 'section::')"
else
- python -ES ./scripts/functional_tests.py -v --with-nosehtml --html-report-file run_functional_tests.html $1
+ $CLEAN_PYTHON ./scripts/functional_tests.py -v --with-nosehtml --html-report-file run_functional_tests.html $1
fi
echo "'run_functional_tests.sh help' for help"
diff -r 4743015d9a57 -r ec34b27de1c0 run_reports.sh
--- a/run_reports.sh Wed Dec 23 20:26:01 2009 -0500
+++ b/run_reports.sh Mon Jan 04 12:51:34 2010 -0500
@@ -2,4 +2,4 @@
cd `dirname $0`
-python -ES ./scripts/paster.py serve reports_wsgi.ini --pid-file=reports_webapp.pid --log-file=reports_webapp.log $@
+`python ./scripts/check_python.py` ./scripts/paster.py serve reports_wsgi.ini --pid-file=reports_webapp.pid --log-file=reports_webapp.log $@
diff -r 4743015d9a57 -r ec34b27de1c0 run_unit_tests.sh
--- a/run_unit_tests.sh Wed Dec 23 20:26:01 2009 -0500
+++ b/run_unit_tests.sh Mon Jan 04 12:51:34 2010 -0500
@@ -2,6 +2,6 @@
## Excluding controllers due to the problematic genetrack dependency
-python -ES ./scripts/nosetests.py -v -w lib \
+`python ./scripts/check_python.py` ./scripts/nosetests.py -v -w lib \
--with-nosehtml --html-report-file run_unit_tests.html \
--with-doctest --exclude=functional --exclude="^get" --exclude=controllers
diff -r 4743015d9a57 -r ec34b27de1c0 scripts/check_python.py
--- a/scripts/check_python.py Wed Dec 23 20:26:01 2009 -0500
+++ b/scripts/check_python.py Mon Jan 04 12:51:34 2010 -0500
@@ -6,6 +6,13 @@
supported version is installed but is not your default, getgalaxy.org
contains instructions on how to force Galaxy to use a different version.""" % sys.version[:3]
+def check_virtualenv():
+ try:
+ assert sys.real_prefix
+ return 'python -E'
+ except:
+ return 'python -ES'
+
def check_python():
try:
assert sys.version_info[:2] >= ( 2, 4 ) and sys.version_info[:2] <= ( 2, 6 )
@@ -16,5 +23,7 @@
if __name__ == '__main__':
try:
check_python()
+ print check_virtualenv()
+ sys.exit( 0 )
except:
sys.exit( 1 )
diff -r 4743015d9a57 -r ec34b27de1c0 set_metadata.sh
--- a/set_metadata.sh Wed Dec 23 20:26:01 2009 -0500
+++ b/set_metadata.sh Mon Jan 04 12:51:34 2010 -0500
@@ -1,4 +1,4 @@
#!/bin/sh
cd `dirname $0`
-python -ES ./scripts/set_metadata.py $@
+`python ./scripts/check_python.py` ./scripts/set_metadata.py $@
diff -r 4743015d9a57 -r ec34b27de1c0 setup.sh
--- a/setup.sh Wed Dec 23 20:26:01 2009 -0500
+++ b/setup.sh Mon Jan 04 12:51:34 2010 -0500
@@ -1,6 +1,6 @@
#!/bin/sh
-python ./scripts/check_python.py
+CLEAN_PYTHON=`python ./scripts/check_python.py`
[ $? -ne 0 ] && exit 1
SAMPLES="
@@ -56,4 +56,4 @@
fi
done
-python ./scripts/fetch_eggs.py
+$CLEAN_PYTHON ./scripts/fetch_eggs.py
1
0
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 ):
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/9f966847abda
changeset: 3193:9f966847abda
user: Kanwei Li <kanwei(a)gmail.com>
date: Tue Dec 22 18:49:34 2009 -0500
description:
Show tooltips in workflows
diffstat:
lib/galaxy/web/controllers/workflow.py | 3 ++-
lib/galaxy/workflow/modules.py | 6 +++++-
static/scripts/galaxy.workflow_editor.canvas.js | 6 ++++--
static/scripts/packed/galaxy.workflow_editor.canvas.js | 2 +-
4 files changed, 12 insertions(+), 5 deletions(-)
diffs (81 lines):
diff -r 828d9f9dcb29 -r 9f966847abda lib/galaxy/web/controllers/workflow.py
--- a/lib/galaxy/web/controllers/workflow.py Tue Dec 22 15:34:50 2009 -0500
+++ b/lib/galaxy/web/controllers/workflow.py Tue Dec 22 18:49:34 2009 -0500
@@ -270,7 +270,7 @@
def get_new_module_info( self, trans, type, **kwargs ):
"""
Get the info for a new instance of a module initialized with default
- paramters (any keyword arguments will be passed along to the module).
+ parameters (any keyword arguments will be passed along to the module).
Result includes data inputs and outputs, html representation
of the initial form, and the initial tool state (with default values).
This is called asynchronously whenever a new node is added.
@@ -282,6 +282,7 @@
'name': module.get_name(),
'tool_id': module.get_tool_id(),
'tool_state': module.get_state(),
+ 'tooltip': module.get_tooltip(),
'data_inputs': module.get_data_inputs(),
'data_outputs': module.get_data_outputs(),
'form_html': module.get_config_form()
diff -r 828d9f9dcb29 -r 9f966847abda lib/galaxy/workflow/modules.py
--- a/lib/galaxy/workflow/modules.py Tue Dec 22 15:34:50 2009 -0500
+++ b/lib/galaxy/workflow/modules.py Tue Dec 22 18:49:34 2009 -0500
@@ -45,6 +45,8 @@
return self.name
def get_tool_id( self ):
return None
+ def get_tooltip( self ):
+ return None
## ---- Configuration time -----------------------------------------------
@@ -201,7 +203,9 @@
return self.state.encode( self.tool, self.trans.app )
def get_errors( self ):
return self.errors
-
+ def get_tooltip( self ):
+ return self.tool.help
+
def get_data_inputs( self ):
data_inputs = []
def callback( input, value, prefixed_name, prefixed_label ):
diff -r 828d9f9dcb29 -r 9f966847abda static/scripts/galaxy.workflow_editor.canvas.js
--- a/static/scripts/galaxy.workflow_editor.canvas.js Tue Dec 22 15:34:50 2009 -0500
+++ b/static/scripts/galaxy.workflow_editor.canvas.js Tue Dec 22 18:49:34 2009 -0500
@@ -271,6 +271,8 @@
this.form_html = data.form_html;
this.tool_state = data.tool_state;
this.tool_errors = data.tool_errors;
+ this.tooltip = data.tooltip ? data.tooltip : ""
+
if ( this.tool_errors ) {
f.addClass( "tool-node-error" );
} else {
@@ -458,7 +460,7 @@
if ( this.active_node != node ) {
this.check_changes_in_active_form();
this.clear_active_node();
- parent.show_form_for_tool( node.form_html, node );
+ parent.show_form_for_tool( node.form_html + node.tooltip, node );
node.make_active();
this.active_node = node;
}
@@ -467,7 +469,7 @@
this.has_changes = true;
if ( this.active_node == node ) {
// Reactive with new form_html
- parent.show_form_for_tool( node.form_html, node );
+ parent.show_form_for_tool( node.form_html + node.tooltip, node );
}
},
layout : function () {
diff -r 828d9f9dcb29 -r 9f966847abda static/scripts/packed/galaxy.workflow_editor.canvas.js
--- a/static/scripts/packed/galaxy.workflow_editor.canvas.js Tue Dec 22 15:34:50 2009 -0500
+++ b/static/scripts/packed/galaxy.workflow_editor.canvas.js Tue Dec 22 18:49:34 2009 -0500
@@ -1,1 +1,1 @@
-function Terminal(a){this.element=a;this.connectors=[]}$.extend(Terminal.prototype,{connect:function(a){this.connectors.push(a);if(this.node){this.node.changed()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.changed()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})}});function OutputTerminal(a,b){Terminal.call(this,a);this.datatype=b}OutputTerminal.prototype=new Terminal();function InputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}InputTerminal.prototype=new Terminal();$.extend(InputTerminal.prototype,{can_accept:function(a){if(this.connectors.length<1){for(var b in this.datatypes){if(a.datatype=="input"){return true}if(issubtype(a.datatype,this.datatypes[b])){return true}}}return false}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a)
{this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;this.handle1.connect(this);this.handle2=a;this.handle2.connect(this)},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},redraw:function(){var d=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}d.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var n=function(c){return $(c).offset().left-d.offset().left};var i=function(c){return $(c).offset().top-d.offset().top};var h=n(this.handle1.element)+5;var g=i(this.handle1.element)+5;var p=n(this.handle2.element)+5;var m=i(this.handle2.element)+5;var f=100;var k=Math.min(h,p);var a=Math.max(h,p);var j=Math.min(g,m);var t=Math.max(g,m);var b=Math.min(Math.max(Math.abs(t-j)/2,100),300);var o=k-f;var s=j-f;var q=a-k+2*f;var l=t-j+2*f;
this.canvas.style.left=o+"px";this.canvas.style.top=s+"px";this.canvas.setAttribute("width",q);this.canvas.setAttribute("height",l);h-=o;g-=s;p-=o;m-=s;var r=this.canvas.getContext("2d");r.lineCap="round";r.strokeStyle=this.outer_color;r.lineWidth=7;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke();r.strokeStyle=this.inner_color;r.lineWidth=5;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke()}});function Node(a){this.element=a;this.input_terminals={};this.output_terminals={};this.tool_errors={}}$.extend(Node.prototype,{enable_input_terminal:function(d,a,b){var c=this;$(d).each(function(){var f=this.terminal=new InputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dropstart",function(g){g.dragProxy.terminal.connectors[0].inner_color="#BBFFBB"}).bind("dropend",function(g){g.dragProxy.terminal.connectors[0].inner_color="#FFFFFF"}).bind("drop",function(g){(new Connector(g.dragTarget.terminal,g.dropTarget.terminal)).redraw()}).bind("hov
er",function(){if(f.connectors.length>0){var g=$("<div class='callout'></div>").css({display:"none"}).appendTo("body").append($("<div class='buttons'></div>").append($("<img src='../images/delete_icon.png' />").click(function(){$.each(f.connectors,function(i,h){h.destroy()});g.remove()}))).bind("mouseleave",function(){$(this).remove()});g.css({top:$(this).offset().top-2,left:$(this).offset().left-g.width(),"padding-right":$(this).width()}).show()}});c.input_terminals[a]=f})},enable_output_terminal:function(d,a,b){var c=this;$(d).each(function(){var g=this;var f=this.terminal=new OutputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dragstart",function(j){var i=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);i.terminal=new OutputTerminal(i);var k=new Connector();k.dragging=true;k.connect(this.terminal,i.terminal);$.dropManage({filter:function(h){return this.terminal.can_accept(f)}}).addClass("input-terminal-active");ret
urn i}).bind("drag",function(i){var h=function(){var k=$(i.dragProxy).offsetParent().offset(),j=i.offsetX-k.left,l=i.offsetY-k.top;$(i.dragProxy).css({left:j,top:l});i.dragProxy.terminal.redraw();canvas_manager.update_viewport_overlay()};h();$("#canvas-container").get(0).scroll_panel.test(i,h)}).bind("dragend",function(h){h.dragProxy.terminal.connectors[0].destroy();$(h.dragProxy).remove();$.dropManage().removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()});c.output_terminals[a]=f})},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b
.appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(g){var d=this.element;if(g.type){this.type=g.type}this.name=g.name;this.form_html=g.form_html;this.tool_state=g.tool_state;this.tool_errors=g.tool_errors;if(this.tool_errors){d.addClass("tool-node-error")}else{d.removeClass("tool-node-error")}var c=this;var a=d.find(".toolFormBody");a.find("div").remove();var h=$("<div class='inputs'></div>").appendTo(a);$.each(g.data_inputs,function(j,b){var f=$("<div class='terminal input-terminal'></div>");c.enable_input_terminal(f,b.name,b.extensions);h.append($("<div class='form-row dataRow input-data-row' name='"+b.name+"'>"+b.label+"</div>").prepend(f))});if((g.data_inputs.length>0)&&(g.data_outputs.length>0)){a.append($("<div class='rule'></div>"))}$.each(g.data_outputs,function(k,b){var j=$("<div class='terminal output-terminal'></div>");c.enable_output_terminal(j,b.name,b.extension);var f=b.name;if(b.extension!="input"){f=f+" ("+b.extensio
n+")"}a.append($("<div class='form-row dataRow'>"+f+"</div>").append(j))});workflow.node_changed(this)},update_field_data:function(f){var c=$(this.element),d=this;this.tool_state=f.tool_state;this.form_html=f.form_html;this.tool_errors=f.tool_errors;if(this.tool_errors){c.addClass("tool-node-error")}else{c.removeClass("tool-node-error")}var g=c.find("div.inputs");var b=$("<div class='inputs'></div>");var a=g.find("div.input-data-row");$.each(f.data_inputs,function(k,h){var j=$("<div class='terminal input-terminal'></div>");d.enable_input_terminal(j,h.name,h.extensions);g.find("div[name="+h.name+"]").each(function(){$(this).find(".input-terminal").each(function(){var i=this.terminal.connectors[0];if(i){j[0].terminal.connectors[0]=i;i.handle2=j[0].terminal}});$(this).remove()});b.append($("<div class='form-row dataRow input-data-row' name='"+h.name+"'>"+h.label+"</div>").prepend(j))});g.replaceWith(b);g.find("div.input-data-row > .terminal").each(function(){this.terminal.destr
oy()});this.changed();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="<div style='color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},changed:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;this.active_form_has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this.nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},to_simple:function(){var a={};$.each(this.nodes,function(b,d){var f={};$.each(d.input_terminals,function(g,h){f[h.name]=null;$.each(h.connecto
rs,function(j,k){f[h.name]={id:k.handle1.node.id,output_name:k.handle1.name}})});var c={id:d.id,type:d.type,tool_id:d.tool_id,tool_state:d.tool_state,tool_errors:d.tool_errors,input_connections:f,position:$(d.element).position()};a[d.id]=c});return{steps:a}},from_simple:function(a){wf=this;var b=0;wf.name=a.name;$.each(a.steps,function(f,d){var c=prebuild_node("tool",d.name,d.tool_id);c.init_field_data(d);if(d.position){c.element.css({top:d.position.top,left:d.position.left})}c.id=d.id;wf.nodes[c.id]=c;b=Math.max(b,parseInt(f))});wf.id_counter=b+1;$.each(a.steps,function(f,d){var c=wf.nodes[f];$.each(d.input_connections,function(h,g){if(g){var i=wf.nodes[g.id];var j=new Connector();j.connect(i.output_terminals[g.output_name],c.input_terminals[h]);j.redraw()}})})},check_changes_in_active_form:function(){if(this.active_form_has_changes){this.has_changes=true;$("#right-content").find("form").submit();this.active_form_has_changes=false}},clear_active_node:function(){if(this.acti
ve_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("<div>No node selected</div>")},activate_node:function(a){if(this.active_node!=a){this.check_changes_in_active_form();this.clear_active_node();parent.show_form_for_tool(a.form_html,a);a.make_active();this.active_node=a}},node_changed:function(a){this.has_changes=true;if(this.active_node==a){parent.show_form_for_tool(a.form_html,a)}},layout:function(){this.check_changes_in_active_form();var i={};var b={};$.each(this.nodes,function(l,k){if(i[l]===undefined){i[l]=0}if(b[l]===undefined){b[l]=[]}});$.each(this.nodes,function(l,k){$.each(k.input_terminals,function(m,n){$.each(n.connectors,function(p,q){var o=q.handle1.node;i[k.id]+=1;b[o.id].push(k.id)})})});node_ids_by_level=[];while(true){level_parents=[];for(var a in i){if(i[a]==0){level_parents.push(a)}}if(level_parents.length==0){break}node_ids_by_level.push(level_parents);for(var f in level_parents){var j=level_parents[f];delete i[j];fo
r(var g in b[j]){i[b[j][g]]-=1}}}if(i.length){return}var d=this.nodes;var h=80;v_pad=30;var c=h;$.each(node_ids_by_level,function(k,l){l.sort(function(p,o){return $(d[p].element).position().top-$(d[o].element).position().top});var m=0;var n=v_pad;$.each(l,function(o,r){var q=d[r];var p=$(q.element);$(p).css({top:n,left:c});m=Math.max(m,$(p).width());n+=$(p).height()+v_pad});c+=m+h});$.each(d,function(k,l){l.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(h,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var i=this.canvas_container.parent();var d=fix_delta(a.xmin,100);var h=fix_delta(a.ymin,100);d=Math.max(d,f.left);h=Math.max(h,f.top);var c=f.left-d;var g=f.top-h;var b=round_
up(a.xmax+100,100)+d;var j=round_up(a.ymax+100,100)+h;b=Math.max(b,-c+i.width());j=Math.max(j,-g+i.height());this.canvas_container.css({left:c,top:g,width:b,height:j});this.canvas_container.children().each(function(){var k=$(this).position();$(this).css("left",k.left+d);$(this).css("top",k.top+h)})}});function fix_delta(a,b){if(a<b||a>3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(l,j,r){var i=$("<div class='toolForm toolFormInCanvas'></div>");var g=new Node(i);g.type=l;if(l=="tool"){g.tool_id=r}var n=$("<div class='toolFormTitle unselectable'>"+j+"</div>");i.append(n);i.css("left",$(window).scrollLeft()+20);i.css("top",$(window).scrollTop()+20);var m=$("<div class='toolFormBody'></div>");var h="<div><img height='16' align='middle' src='../images/loading_small_white_bg.gif'/> loading tool info...</div>";m.append(h);g.form_html=h;i.append(m);var k=$("<div class='buttons' style='float:
right;'></div>");k.append($("<img src='../images/delete_icon.png' />").click(function(b){g.destroy()}).hover(function(){$(this).attr("src","../images/delete_icon_dark.png")},function(){$(this).attr("src","../images/delete_icon.png")}));i.appendTo("#canvas-container");var d=$("#canvas-container").position();var c=$("#canvas-container").parent();var a=i.width();var q=i.height();i.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(q/2)});k.prependTo(n);a+=(k.width()+10);i.css("width",a);$(i).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o){var f=$(this).offsetParent().offset(),b=o.offsetX-f.left,p=o.offsetY-f.top;$(this).css({left:b,top:p});$(this).find(".terminal").each(function(){this.terminal.redraw()})});return g}var ext_to_type=null;var type_to_type
=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}function ScrollPanel(a){this.panel=a}$.extend(ScrollPanel.prototype,{test:function(v,d){clearTimeout(this.timeout);var k=v.pageX,j=v.pageY,l=$(this.panel),c=l.position(),b=l.width(),i=l.height(),w=l.parent(),s=w.width(),a=w.height(),r=w.offset(),p=r.left,m=r.top,A=p+w.width(),u=m+w.height(),B=-(b-(s/2)),z=-(i-(a/2)),g=(s/2),f=(a/2),h=false,q=5,o=23;if(k-q<p){if(c.left<g){var n=Math.min(o,g-c.left);l.css("left",c.left+n);h=true}}else{if(k+q>A){if(c.left>B){var n=Math.min(o,c.left-B);l.css("left",c.left-n);h=true}}else{if(j-q<m){if(c.top<f){var n=Math.min(o,f-c.top);l.css("top",c.top+n);h=true}}else{if(j+q>u){if(c.top>z){var n=Math.min(o,c.top-B);l.css("top",(c.top-n)+"px");h=true}}}}}if(h){d();var l=this;this.timeout=setTimeout(function(){l.test(v,d)},50)}},stop:functi
on(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManager.prototype,{init_drag:function(){var b=this;var a=function(f,g){f=Math.min(f,b.cv.width()/2);f=Math.max(f,-b.cc.width()+b.cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(g){var h=$(this).offset();var f=b.cc.position();c=f.top-h.top;d=f.left-h.left}).bind("drag",function(f){a(f.offsetX+d,f.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("drag",function(k){var j=b.cc.width(),g=b.cc.height(),f=b.oc.width(),h=b.oc.height(),i=$(this).offsetParent().offset(),m=k.offsetX-i.left,l=k.offsetY-i.top;a(-(m/f*
j),-(l/h*g))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g){var i=$(this).offsetParent();var h=i.offset();var f=Math.max(i.width()-(g.offsetX-h.left),i.height()-(g.offsetY-h.top));$(this).css({width:f,height:f});b.draw_overview()});$("#overview-border div").bind("drag",function(f){})},update_viewport_overlay:function(){var b=this.cc,f=this.cv,a=this.oc,c=this.ov,d=b.width(),j=b.height(),i=a.width(),g=a.height(),h=b.position();c.css({left:-(h.left/d*i),top:-(h.top/j*g),width:(f.width()/d*i)-2,height:(f.height()/j*g)-2})},draw_overview:function(){var j=$("#overview-canvas"),m=j.parent().parent().width(),i=j.get(0).getContext("2d"),d=$("#canvas-container").width(),l=$("#canvas-container").height();var g,a,k,f;var h=this.cv.width();var b=this.cv.height();if(d<h&&l<b){k=d/h*m;f=(m-k)/2;g=l/b*m;a=(m-g)/2}else{if(d<l){a=0;g=m;k=Math.ceil(g*d/l);f=(m-k)/2}else{k=m;f=0;g=Math.ceil(k*l/d);a=(m-g)/2}}j.parent
().css({left:f,top:a,width:k,height:g});j.attr("width",k);j.attr("height",g);i.fillStyle="#D2C099";i.strokeStyle="#D8B365";i.lineWidth=1;$.each(workflow.nodes,function(t,q){var s=$(q.element),n=s.position(),c=n.left/d*k,r=n.top/l*g,o=s.width()/d*k,p=s.height()/l*g;i.fillRect(c,r,o,p);i.strokeRect(c,r,o,p)});this.update_viewport_overlay()}});
\ No newline at end of file
+function Terminal(a){this.element=a;this.connectors=[]}$.extend(Terminal.prototype,{connect:function(a){this.connectors.push(a);if(this.node){this.node.changed()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.changed()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})}});function OutputTerminal(a,b){Terminal.call(this,a);this.datatype=b}OutputTerminal.prototype=new Terminal();function InputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}InputTerminal.prototype=new Terminal();$.extend(InputTerminal.prototype,{can_accept:function(a){if(this.connectors.length<1){for(var b in this.datatypes){if(a.datatype=="input"){return true}if(issubtype(a.datatype,this.datatypes[b])){return true}}}return false}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a)
{this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;this.handle1.connect(this);this.handle2=a;this.handle2.connect(this)},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},redraw:function(){var d=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}d.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var n=function(c){return $(c).offset().left-d.offset().left};var i=function(c){return $(c).offset().top-d.offset().top};var h=n(this.handle1.element)+5;var g=i(this.handle1.element)+5;var p=n(this.handle2.element)+5;var m=i(this.handle2.element)+5;var f=100;var k=Math.min(h,p);var a=Math.max(h,p);var j=Math.min(g,m);var t=Math.max(g,m);var b=Math.min(Math.max(Math.abs(t-j)/2,100),300);var o=k-f;var s=j-f;var q=a-k+2*f;var l=t-j+2*f;
this.canvas.style.left=o+"px";this.canvas.style.top=s+"px";this.canvas.setAttribute("width",q);this.canvas.setAttribute("height",l);h-=o;g-=s;p-=o;m-=s;var r=this.canvas.getContext("2d");r.lineCap="round";r.strokeStyle=this.outer_color;r.lineWidth=7;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke();r.strokeStyle=this.inner_color;r.lineWidth=5;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke()}});function Node(a){this.element=a;this.input_terminals={};this.output_terminals={};this.tool_errors={}}$.extend(Node.prototype,{enable_input_terminal:function(d,a,b){var c=this;$(d).each(function(){var f=this.terminal=new InputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dropstart",function(g){g.dragProxy.terminal.connectors[0].inner_color="#BBFFBB"}).bind("dropend",function(g){g.dragProxy.terminal.connectors[0].inner_color="#FFFFFF"}).bind("drop",function(g){(new Connector(g.dragTarget.terminal,g.dropTarget.terminal)).redraw()}).bind("hov
er",function(){if(f.connectors.length>0){var g=$("<div class='callout'></div>").css({display:"none"}).appendTo("body").append($("<div class='buttons'></div>").append($("<img src='../images/delete_icon.png' />").click(function(){$.each(f.connectors,function(i,h){h.destroy()});g.remove()}))).bind("mouseleave",function(){$(this).remove()});g.css({top:$(this).offset().top-2,left:$(this).offset().left-g.width(),"padding-right":$(this).width()}).show()}});c.input_terminals[a]=f})},enable_output_terminal:function(d,a,b){var c=this;$(d).each(function(){var g=this;var f=this.terminal=new OutputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dragstart",function(j){var i=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);i.terminal=new OutputTerminal(i);var k=new Connector();k.dragging=true;k.connect(this.terminal,i.terminal);$.dropManage({filter:function(h){return this.terminal.can_accept(f)}}).addClass("input-terminal-active");ret
urn i}).bind("drag",function(i){var h=function(){var k=$(i.dragProxy).offsetParent().offset(),j=i.offsetX-k.left,l=i.offsetY-k.top;$(i.dragProxy).css({left:j,top:l});i.dragProxy.terminal.redraw();canvas_manager.update_viewport_overlay()};h();$("#canvas-container").get(0).scroll_panel.test(i,h)}).bind("dragend",function(h){h.dragProxy.terminal.connectors[0].destroy();$(h.dragProxy).remove();$.dropManage().removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()});c.output_terminals[a]=f})},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b
.appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(g){var d=this.element;if(g.type){this.type=g.type}this.name=g.name;this.form_html=g.form_html;this.tool_state=g.tool_state;this.tool_errors=g.tool_errors;this.tooltip=g.tooltip?g.tooltip:"";if(this.tool_errors){d.addClass("tool-node-error")}else{d.removeClass("tool-node-error")}var c=this;var a=d.find(".toolFormBody");a.find("div").remove();var h=$("<div class='inputs'></div>").appendTo(a);$.each(g.data_inputs,function(j,b){var f=$("<div class='terminal input-terminal'></div>");c.enable_input_terminal(f,b.name,b.extensions);h.append($("<div class='form-row dataRow input-data-row' name='"+b.name+"'>"+b.label+"</div>").prepend(f))});if((g.data_inputs.length>0)&&(g.data_outputs.length>0)){a.append($("<div class='rule'></div>"))}$.each(g.data_outputs,function(k,b){var j=$("<div class='terminal output-terminal'></div>");c.enable_output_terminal(j,b.name,b.extension);var f=b.name;if(b.ext
ension!="input"){f=f+" ("+b.extension+")"}a.append($("<div class='form-row dataRow'>"+f+"</div>").append(j))});workflow.node_changed(this)},update_field_data:function(f){var c=$(this.element),d=this;this.tool_state=f.tool_state;this.form_html=f.form_html;this.tool_errors=f.tool_errors;if(this.tool_errors){c.addClass("tool-node-error")}else{c.removeClass("tool-node-error")}var g=c.find("div.inputs");var b=$("<div class='inputs'></div>");var a=g.find("div.input-data-row");$.each(f.data_inputs,function(k,h){var j=$("<div class='terminal input-terminal'></div>");d.enable_input_terminal(j,h.name,h.extensions);g.find("div[name="+h.name+"]").each(function(){$(this).find(".input-terminal").each(function(){var i=this.terminal.connectors[0];if(i){j[0].terminal.connectors[0]=i;i.handle2=j[0].terminal}});$(this).remove()});b.append($("<div class='form-row dataRow input-data-row' name='"+h.name+"'>"+h.label+"</div>").prepend(j))});g.replaceWith(b);g.find("div.input-data-row > .terminal")
.each(function(){this.terminal.destroy()});this.changed();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="<div style='color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},changed:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;this.active_form_has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this.nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},to_simple:function(){var a={};$.each(this.nodes,function(b,d){var f={};$.each(d.input_terminals,function(g
,h){f[h.name]=null;$.each(h.connectors,function(j,k){f[h.name]={id:k.handle1.node.id,output_name:k.handle1.name}})});var c={id:d.id,type:d.type,tool_id:d.tool_id,tool_state:d.tool_state,tool_errors:d.tool_errors,input_connections:f,position:$(d.element).position()};a[d.id]=c});return{steps:a}},from_simple:function(a){wf=this;var b=0;wf.name=a.name;$.each(a.steps,function(f,d){var c=prebuild_node("tool",d.name,d.tool_id);c.init_field_data(d);if(d.position){c.element.css({top:d.position.top,left:d.position.left})}c.id=d.id;wf.nodes[c.id]=c;b=Math.max(b,parseInt(f))});wf.id_counter=b+1;$.each(a.steps,function(f,d){var c=wf.nodes[f];$.each(d.input_connections,function(h,g){if(g){var i=wf.nodes[g.id];var j=new Connector();j.connect(i.output_terminals[g.output_name],c.input_terminals[h]);j.redraw()}})})},check_changes_in_active_form:function(){if(this.active_form_has_changes){this.has_changes=true;$("#right-content").find("form").submit();this.active_form_has_changes=false}},clear
_active_node:function(){if(this.active_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("<div>No node selected</div>")},activate_node:function(a){if(this.active_node!=a){this.check_changes_in_active_form();this.clear_active_node();parent.show_form_for_tool(a.form_html+a.tooltip,a);a.make_active();this.active_node=a}},node_changed:function(a){this.has_changes=true;if(this.active_node==a){parent.show_form_for_tool(a.form_html+a.tooltip,a)}},layout:function(){this.check_changes_in_active_form();var i={};var b={};$.each(this.nodes,function(l,k){if(i[l]===undefined){i[l]=0}if(b[l]===undefined){b[l]=[]}});$.each(this.nodes,function(l,k){$.each(k.input_terminals,function(m,n){$.each(n.connectors,function(p,q){var o=q.handle1.node;i[k.id]+=1;b[o.id].push(k.id)})})});node_ids_by_level=[];while(true){level_parents=[];for(var a in i){if(i[a]==0){level_parents.push(a)}}if(level_parents.length==0){break}node_ids_by_level.push(level_parents);for(var f
in level_parents){var j=level_parents[f];delete i[j];for(var g in b[j]){i[b[j][g]]-=1}}}if(i.length){return}var d=this.nodes;var h=80;v_pad=30;var c=h;$.each(node_ids_by_level,function(k,l){l.sort(function(p,o){return $(d[p].element).position().top-$(d[o].element).position().top});var m=0;var n=v_pad;$.each(l,function(o,r){var q=d[r];var p=$(q.element);$(p).css({top:n,left:c});m=Math.max(m,$(p).width());n+=$(p).height()+v_pad});c+=m+h});$.each(d,function(k,l){l.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(h,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var i=this.canvas_container.parent();var d=fix_delta(a.xmin,100);var h=fix_delta(a.ymin,100);d=Math.max(d,f.left);h=Mat
h.max(h,f.top);var c=f.left-d;var g=f.top-h;var b=round_up(a.xmax+100,100)+d;var j=round_up(a.ymax+100,100)+h;b=Math.max(b,-c+i.width());j=Math.max(j,-g+i.height());this.canvas_container.css({left:c,top:g,width:b,height:j});this.canvas_container.children().each(function(){var k=$(this).position();$(this).css("left",k.left+d);$(this).css("top",k.top+h)})}});function fix_delta(a,b){if(a<b||a>3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(l,j,r){var i=$("<div class='toolForm toolFormInCanvas'></div>");var g=new Node(i);g.type=l;if(l=="tool"){g.tool_id=r}var n=$("<div class='toolFormTitle unselectable'>"+j+"</div>");i.append(n);i.css("left",$(window).scrollLeft()+20);i.css("top",$(window).scrollTop()+20);var m=$("<div class='toolFormBody'></div>");var h="<div><img height='16' align='middle' src='../images/loading_small_white_bg.gif'/> loading tool info...</div>";m.append(h);g.form_html=h
;i.append(m);var k=$("<div class='buttons' style='float: right;'></div>");k.append($("<img src='../images/delete_icon.png' />").click(function(b){g.destroy()}).hover(function(){$(this).attr("src","../images/delete_icon_dark.png")},function(){$(this).attr("src","../images/delete_icon.png")}));i.appendTo("#canvas-container");var d=$("#canvas-container").position();var c=$("#canvas-container").parent();var a=i.width();var q=i.height();i.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(q/2)});k.prependTo(n);a+=(k.width()+10);i.css("width",a);$(i).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o){var f=$(this).offsetParent().offset(),b=o.offsetX-f.left,p=o.offsetY-f.top;$(this).css({left:b,top:p});$(this).find(".terminal").each(function(){this.terminal.red
raw()})});return g}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}function ScrollPanel(a){this.panel=a}$.extend(ScrollPanel.prototype,{test:function(v,d){clearTimeout(this.timeout);var k=v.pageX,j=v.pageY,l=$(this.panel),c=l.position(),b=l.width(),i=l.height(),w=l.parent(),s=w.width(),a=w.height(),r=w.offset(),p=r.left,m=r.top,A=p+w.width(),u=m+w.height(),B=-(b-(s/2)),z=-(i-(a/2)),g=(s/2),f=(a/2),h=false,q=5,o=23;if(k-q<p){if(c.left<g){var n=Math.min(o,g-c.left);l.css("left",c.left+n);h=true}}else{if(k+q>A){if(c.left>B){var n=Math.min(o,c.left-B);l.css("left",c.left-n);h=true}}else{if(j-q<m){if(c.top<f){var n=Math.min(o,f-c.top);l.css("top",c.top+n);h=true}}else{if(j+q>u){if(c.top>z){var n=Math.min(o,c.top-B);l.css("top",(c.top-n)+"px");h=true}}}}}if(h){d();var l=this;this.time
out=setTimeout(function(){l.test(v,d)},50)}},stop:function(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManager.prototype,{init_drag:function(){var b=this;var a=function(f,g){f=Math.min(f,b.cv.width()/2);f=Math.max(f,-b.cc.width()+b.cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(g){var h=$(this).offset();var f=b.cc.position();c=f.top-h.top;d=f.left-h.left}).bind("drag",function(f){a(f.offsetX+d,f.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("drag",function(k){var j=b.cc.width(),g=b.cc.height(),f=b.oc.width(),h=b.oc.height(),i=$(this).offsetParent(
).offset(),m=k.offsetX-i.left,l=k.offsetY-i.top;a(-(m/f*j),-(l/h*g))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g){var i=$(this).offsetParent();var h=i.offset();var f=Math.max(i.width()-(g.offsetX-h.left),i.height()-(g.offsetY-h.top));$(this).css({width:f,height:f});b.draw_overview()});$("#overview-border div").bind("drag",function(f){})},update_viewport_overlay:function(){var b=this.cc,f=this.cv,a=this.oc,c=this.ov,d=b.width(),j=b.height(),i=a.width(),g=a.height(),h=b.position();c.css({left:-(h.left/d*i),top:-(h.top/j*g),width:(f.width()/d*i)-2,height:(f.height()/j*g)-2})},draw_overview:function(){var j=$("#overview-canvas"),m=j.parent().parent().width(),i=j.get(0).getContext("2d"),d=$("#canvas-container").width(),l=$("#canvas-container").height();var g,a,k,f;var h=this.cv.width();var b=this.cv.height();if(d<h&&l<b){k=d/h*m;f=(m-k)/2;g=l/b*m;a=(m-g)/2}else{if(d<l){a=0;g=m;k=Math.ceil(g*d/l);f=(m-
k)/2}else{k=m;f=0;g=Math.ceil(k*l/d);a=(m-g)/2}}j.parent().css({left:f,top:a,width:k,height:g});j.attr("width",k);j.attr("height",g);i.fillStyle="#D2C099";i.strokeStyle="#D8B365";i.lineWidth=1;$.each(workflow.nodes,function(t,q){var s=$(q.element),n=s.position(),c=n.left/d*k,r=n.top/l*g,o=s.width()/d*k,p=s.height()/l*g;i.fillRect(c,r,o,p);i.strokeRect(c,r,o,p)});this.update_viewport_overlay()}});
\ No newline at end of file
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/828d9f9dcb29
changeset: 3192:828d9f9dcb29
user: Kanwei Li <kanwei(a)gmail.com>
date: Tue Dec 22 15:34:50 2009 -0500
description:
Code for debugging egg error
diffstat:
lib/galaxy/eggs/__init__.py | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diffs (15 lines):
diff -r e8e73460f0d4 -r 828d9f9dcb29 lib/galaxy/eggs/__init__.py
--- a/lib/galaxy/eggs/__init__.py Mon Dec 21 18:03:50 2009 -0500
+++ b/lib/galaxy/eggs/__init__.py Tue Dec 22 15:34:50 2009 -0500
@@ -520,7 +520,10 @@
location = None
del working_set.by_key[dist.key]
working_set.entry_keys[entry] = []
- sys.path.remove(entry)
+ try:
+ sys.path.remove(entry)
+ except ValueError:
+ raise Exception( "Cannot remove entry: %s" % str(entry) )
r = require( pkg )
if location is not None and not location.endswith( '.egg' ):
working_set.entries.append( location ) # re-add to the set if it's a dir.
1
0