galaxy-commits
Threads by month
- ----- 2026 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 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
- 15302 discussions
09 Dec '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/511fbb67b820/
Changeset: 511fbb67b820
User: jmchilton
Date: 2014-12-09 14:17:25+00:00
Summary: Merge next-stable.
Affected #: 44 files
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e .hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -20,4 +20,4 @@
ca45b78adb4152fc6e7395514d46eba6b7d0b838 release_2014.08.11
548ab24667d6206780237bd807f7d857a484c461 latest_2014.08.11
2092948937ac30ef82f71463a235c66d34987088 release_2014.10.06
-acb2548443ae42d39ef200d035ccc0481d6b930c latest_2014.10.06
+782cf1a1f6b56f8a9c0b3e5e9ffd29fd93b16ce3 latest_2014.10.06
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e lib/galaxy/security/validate_user_input.py
--- a/lib/galaxy/security/validate_user_input.py
+++ b/lib/galaxy/security/validate_user_input.py
@@ -1,3 +1,9 @@
+"""
+Utilities for validating inputs related to user objects.
+
+The validate_* methods in this file return simple messages that do not contain
+user inputs - so these methods do not need to be escaped.
+"""
import logging
import re
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -67,6 +67,7 @@
from galaxy.util.template import fill_template
from galaxy.web import url_for
from galaxy.web.form_builder import SelectField
+from galaxy.web.framework.helpers import escape
from galaxy.model.item_attrs import Dictifiable
from galaxy.model import Workflow
from tool_shed.util import common_util
@@ -791,7 +792,7 @@
success = True
# Make sure the tool is actually loaded.
if tool_id not in self.tools_by_id:
- return None, False, "No tool with id %s" % tool_id
+ return None, False, "No tool with id %s" % escape( tool_id )
else:
tool = self.tools_by_id[ tool_id ]
tarball_files = []
@@ -902,7 +903,7 @@
replace the old tool.
"""
if tool_id not in self.tools_by_id:
- message = "No tool with id %s" % tool_id
+ message = "No tool with id %s" % escape( tool_id )
status = 'error'
else:
old_tool = self.tools_by_id[ tool_id ]
@@ -939,7 +940,7 @@
Attempt to remove the tool identified by 'tool_id'.
"""
if tool_id not in self.tools_by_id:
- message = "No tool with id %s" % tool_id
+ message = "No tool with id %s" % escape( tool_id )
status = 'error'
else:
tool = self.tools_by_id[ tool_id ]
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e lib/galaxy/tools/filters/__init__.py
--- a/lib/galaxy/tools/filters/__init__.py
+++ b/lib/galaxy/tools/filters/__init__.py
@@ -1,6 +1,10 @@
+import logging
from galaxy.util import listify
from copy import deepcopy
+log = logging.getLogger( __name__ )
+
+
class FilterFactory( object ):
"""
An instance of this class is responsible for filtering the list
@@ -37,17 +41,21 @@
elif name == 'toolbox_label_filters':
category = "label"
if category:
- self.__init_filters( category, user_filters, filters )
+ validate = getattr( trans.app.config, 'user_%s_filters' % category, [] )
+ self.__init_filters( category, user_filters, filters, validate=validate )
else:
if kwds.get( "trackster", False ):
filters[ "tool" ].append( _has_trackster_conf )
return filters
- def __init_filters( self, key, filters, toolbox_filters ):
+ def __init_filters( self, key, filters, toolbox_filters, validate=None ):
for filter in filters:
- filter_function = self.__build_filter_function( filter )
- toolbox_filters[ key ].append( filter_function )
+ if validate is None or filter in validate or filter in self.default_filters:
+ filter_function = self.__build_filter_function( filter )
+ toolbox_filters[ key ].append( filter_function )
+ else:
+ log.warning( "Refusing to load %s filter '%s' which is not defined in config", key, filter )
return toolbox_filters
def __build_filter_function( self, filter_name ):
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -1664,7 +1664,8 @@
stored.user = trans.user
stored.published = publish
if data[ 'annotation' ]:
- self.add_item_annotation( trans.sa_session, stored.user, stored, data[ 'annotation' ] )
+ annotation = sanitize_html( data[ 'annotation' ], 'utf-8', 'text/html' )
+ self.add_item_annotation( trans.sa_session, stored.user, stored, annotation )
# Persist
trans.sa_session.add( stored )
@@ -2571,6 +2572,8 @@
def set_public_username( self, trans, id, username, **kwargs ):
""" Set user's public username and delegate to sharing() """
user = trans.get_user()
+ # message from validate_publicname does not contain input, no need
+ # to escape.
message = validate_publicname( trans, username, user )
if message:
return trans.fill_template( '/sharing_base.mako', item=self.get_item( trans, id ), message=message, status='error' )
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e lib/galaxy/web/form_builder.py
--- a/lib/galaxy/web/form_builder.py
+++ b/lib/galaxy/web/form_builder.py
@@ -563,7 +563,7 @@
html += '<input name="__switch_default__" type="hidden" value="%s" />' % self.default_field
options = []
for name, delegate_field in self.delegate_fields.items():
- field = dumps( delegate_field.to_dict() )
+ field = escape( dumps( delegate_field.to_dict() ) )
option = " '%s': %s" % ( name, field )
options.append( option )
html += '<script>$(document).ready( function() {\nvar switchOptions = {\n'
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e lib/galaxy/webapps/galaxy/controllers/history.py
--- a/lib/galaxy/webapps/galaxy/controllers/history.py
+++ b/lib/galaxy/webapps/galaxy/controllers/history.py
@@ -718,7 +718,9 @@
for husa in husas:
trans.sa_session.delete( husa )
if not deleted_sharing_relation:
- message = "History '%s' does not seem to be shared with user '%s'" % ( history.name, user.email )
+ history_name = escape( history.name )
+ user_email = escape( user.email )
+ message = "History '%s' does not seem to be shared with user '%s'" % ( history_name, user_email )
return trans.fill_template( '/sharing_base.mako', item=history,
message=message, status='error' )
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e lib/galaxy/webapps/galaxy/controllers/mobile.py
--- a/lib/galaxy/webapps/galaxy/controllers/mobile.py
+++ b/lib/galaxy/webapps/galaxy/controllers/mobile.py
@@ -1,60 +1,71 @@
+from galaxy import web
from galaxy.web.base.controller import *
+
class Mobile( BaseUIController ):
+
@web.expose
def index( self, trans, **kwargs ):
- return trans.fill_template( "mobile/index.mako" )
+ return trans.response.send_redirect( web.url_for(controller='root', action='index' ) )
+ # return trans.fill_template( "mobile/index.mako" )
@web.expose
def history_list( self, trans ):
- return trans.fill_template( "mobile/history/list.mako" )
+ return trans.response.send_redirect( web.url_for(controller='root', action='index' ) )
+ # return trans.fill_template( "mobile/history/list.mako" )
@web.expose
def history_detail( self, trans, id ):
- history = trans.sa_session.query( trans.app.model.History ).get( id )
- assert history.user == trans.user
- return trans.fill_template( "mobile/history/detail.mako", history=history )
+ return trans.response.send_redirect( web.url_for(controller='root', action='index' ) )
+ # history = trans.sa_session.query( trans.app.model.History ).get( id )
+ # assert history.user == trans.user
+ # return trans.fill_template( "mobile/history/detail.mako", history=history )
@web.expose
def dataset_detail( self, trans, id ):
- dataset = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( id )
- assert dataset.history.user == trans.user
- return trans.fill_template( "mobile/dataset/detail.mako", dataset=dataset )
+ return trans.response.send_redirect( web.url_for(controller='root', action='index' ) )
+ # dataset = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( id )
+ # assert dataset.history.user == trans.user
+ # return trans.fill_template( "mobile/dataset/detail.mako", dataset=dataset )
@web.expose
def dataset_peek( self, trans, id ):
- dataset = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( id )
- assert dataset.history.user == trans.user
- return trans.fill_template( "mobile/dataset/peek.mako", dataset=dataset )
+ return trans.response.send_redirect( web.url_for(controller='root', action='index' ) )
+ # dataset = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( id )
+ # assert dataset.history.user == trans.user
+ # return trans.fill_template( "mobile/dataset/peek.mako", dataset=dataset )
@web.expose
def settings( self, trans, email=None, password=None ):
- message = None
- if email is not None and password is not None:
- if email == "":
- self.__logout( trans )
- message = "Logged out"
- else:
- error = self.__login( trans, email, password )
- message = error or "Login changed"
- return trans.fill_template( "mobile/settings.mako", message=message )
+ return trans.response.send_redirect( web.url_for(controller='root', action='index' ) )
+ # message = None
+ # if email is not None and password is not None:
+ # if email == "":
+ # self.__logout( trans )
+ # message = "Logged out"
+ # else:
+ # error = self.__login( trans, email, password )
+ # message = error or "Login changed"
+ # return trans.fill_template( "mobile/settings.mako", message=message )
def __logout( self, trans ):
- trans.log_event( "User logged out" )
- trans.handle_user_logout()
+ return trans.response.send_redirect( web.url_for(controller='root', action='index' ) )
+ # trans.log_event( "User logged out" )
+ # trans.handle_user_logout()
def __login( self, trans, email="", password="" ):
- error = password_error = None
- user = trans.sa_session.query( model.User ).filter_by( email = email ).first()
- if not user:
- error = "No such user (please note that login is case sensitive)"
- elif user.deleted:
- error = "This account has been marked deleted, contact your Galaxy administrator to restore the account."
- elif user.external:
- error = "This account was created for use with an external authentication method, contact your local Galaxy administrator to activate it."
- elif not user.check_password( password ):
- error = "Invalid password"
- else:
- trans.handle_user_login( user )
- trans.log_event( "User logged in" )
- return error
+ return trans.response.send_redirect( web.url_for(controller='root', action='index' ) )
+ # error = password_error = None
+ # user = trans.sa_session.query( model.User ).filter_by( email = email ).first()
+ # if not user:
+ # error = "No such user (please note that login is case sensitive)"
+ # elif user.deleted:
+ # error = "This account has been marked deleted, contact your Galaxy administrator to restore the account."
+ # elif user.external:
+ # error = "This account was created for use with an external authentication method, contact your local Galaxy administrator to activate it."
+ # elif not user.check_password( password ):
+ # error = "Invalid password"
+ # else:
+ # trans.handle_user_login( user )
+ # trans.log_event( "User logged in" )
+ # return error
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e lib/galaxy/webapps/galaxy/controllers/page.py
--- a/lib/galaxy/webapps/galaxy/controllers/page.py
+++ b/lib/galaxy/webapps/galaxy/controllers/page.py
@@ -500,14 +500,14 @@
.first()
if not other:
mtype = "error"
- msg = ( "User '%s' does not exist" % email )
+ msg = ( "User '%s' does not exist" % escape( email ) )
elif other == trans.get_user():
mtype = "error"
msg = ( "You cannot share a page with yourself" )
elif trans.sa_session.query( model.PageUserShareAssociation ) \
.filter_by( user=other, page=page ).count() > 0:
mtype = "error"
- msg = ( "Page already shared with '%s'" % email )
+ msg = ( "Page already shared with '%s'" % escape( email ) )
else:
share = model.PageUserShareAssociation()
share.page = page
@@ -516,7 +516,9 @@
session.add( share )
self.create_item_slug( session, page )
session.flush()
- trans.set_message( "Page '%s' shared with user '%s'" % ( page.title, other.email ) )
+ page_title = escape( page.title )
+ other_email = escape( other.email )
+ trans.set_message( "Page '%s' shared with user '%s'" % ( page_title, other_email ) )
return trans.response.send_redirect( url_for( controller='page', action='sharing', id=id ) )
return trans.fill_template( "/ind_share_base.mako",
message = msg,
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e lib/galaxy/webapps/galaxy/controllers/visualization.py
--- a/lib/galaxy/webapps/galaxy/controllers/visualization.py
+++ b/lib/galaxy/webapps/galaxy/controllers/visualization.py
@@ -535,14 +535,14 @@
.first()
if not other:
mtype = "error"
- msg = ( "User '%s' does not exist" % email )
+ msg = ( "User '%s' does not exist" % escape( email ) )
elif other == trans.get_user():
mtype = "error"
msg = ( "You cannot share a visualization with yourself" )
elif trans.sa_session.query( model.VisualizationUserShareAssociation ) \
.filter_by( user=other, visualization=visualization ).count() > 0:
mtype = "error"
- msg = ( "Visualization already shared with '%s'" % email )
+ msg = ( "Visualization already shared with '%s'" % escape( email ) )
else:
share = model.VisualizationUserShareAssociation()
share.visualization = visualization
@@ -551,7 +551,9 @@
session.add( share )
self.create_item_slug( session, visualization )
session.flush()
- trans.set_message( "Visualization '%s' shared with user '%s'" % ( visualization.title, other.email ) )
+ viz_title = escape( visualization.title )
+ other_email = escape( other.email )
+ trans.set_message( "Visualization '%s' shared with user '%s'" % ( viz_title, other_email ) )
return trans.response.send_redirect( web.url_for(controller='visualization', action='sharing', id=id ) )
return trans.fill_template( "/ind_share_base.mako",
message = msg,
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e lib/galaxy/webapps/galaxy/controllers/workflow.py
--- a/lib/galaxy/webapps/galaxy/controllers/workflow.py
+++ b/lib/galaxy/webapps/galaxy/controllers/workflow.py
@@ -310,14 +310,14 @@
.first()
if not other:
mtype = "error"
- msg = ( "User '%s' does not exist" % email )
+ msg = ( "User '%s' does not exist" % escape( email ) )
elif other == trans.get_user():
mtype = "error"
msg = ( "You cannot share a workflow with yourself" )
elif trans.sa_session.query( model.StoredWorkflowUserShareAssociation ) \
.filter_by( user=other, stored_workflow=stored ).count() > 0:
mtype = "error"
- msg = ( "Workflow already shared with '%s'" % email )
+ msg = ( "Workflow already shared with '%s'" % escape( email ) )
else:
share = model.StoredWorkflowUserShareAssociation()
share.stored_workflow = stored
@@ -325,7 +325,7 @@
session = trans.sa_session
session.add( share )
session.flush()
- trans.set_message( "Workflow '%s' shared with user '%s'" % ( stored.name, other.email ) )
+ trans.set_message( "Workflow '%s' shared with user '%s'" % ( escape( stored.name ), escape( other.email ) ) )
return trans.response.send_redirect( url_for( controller='workflow', action='sharing', id=id ) )
return trans.fill_template( "/ind_share_base.mako",
message=msg,
@@ -415,7 +415,7 @@
stored.latest_workflow.name = san_new_name
trans.sa_session.flush()
# For current workflows grid:
- trans.set_message( "Workflow renamed to '%s'." % new_name )
+ trans.set_message( "Workflow renamed to '%s'." % san_new_name )
return self.list( trans )
# For new workflows grid:
#message = "Workflow renamed to '%s'." % new_name
@@ -535,7 +535,7 @@
session.add( new_stored )
session.flush()
# Display the management page
- trans.set_message( 'Created new workflow with name "%s"' % new_stored.name )
+ trans.set_message( 'Created new workflow with name "%s"' % escape( new_stored.name ) )
return self.list( trans )
@web.expose
@@ -582,7 +582,7 @@
trans.sa_session.add( stored )
trans.sa_session.flush()
# Display the management page
- trans.set_message( "Workflow '%s' deleted" % stored.name )
+ trans.set_message( "Workflow '%s' deleted" % escape( stored.name ) )
return self.list( trans )
@web.expose
@@ -1089,7 +1089,7 @@
message += "Imported, but this workflow contains cycles. "
status = "error"
else:
- message += "Workflow <b>%s</b> imported successfully. " % workflow.name
+ message += "Workflow <b>%s</b> imported successfully. " % escape( workflow.name )
if missing_tool_tups:
if trans.user_is_admin():
# A required tool is not available in the local Galaxy instance.
@@ -1103,7 +1103,7 @@
message += "You can likely install the required tools from one of the Galaxy tool sheds listed below.<br/>"
for missing_tool_tup in missing_tool_tups:
missing_tool_id, missing_tool_name, missing_tool_version = missing_tool_tup
- message += "<b>Tool name</b> %s, <b>id</b> %s, <b>version</b> %s<br/>" % ( missing_tool_name, missing_tool_id, missing_tool_version )
+ message += "<b>Tool name</b> %s, <b>id</b> %s, <b>version</b> %s<br/>" % ( escape( missing_tool_name ), escape( missing_tool_id ), escape( missing_tool_version ) )
message += "<br/>"
for shed_name, shed_url in trans.app.tool_shed_registry.tool_sheds.items():
if shed_url.endswith( '/' ):
@@ -1113,7 +1113,7 @@
url += '&tool_id='
for missing_tool_tup in missing_tool_tups:
missing_tool_id = missing_tool_tup[0]
- url += '%s,' % missing_tool_id
+ url += '%s,' % escape( missing_tool_id )
message += '<a href="%s">%s</a><br/>' % ( url, shed_name )
status = 'error'
if installed_repository_file or tool_shed_url:
@@ -1133,13 +1133,13 @@
pass
if tool_shed_url:
# We've received the textual representation of a workflow from a Galaxy tool shed.
- message = "Workflow <b>%s</b> imported successfully." % workflow.name
+ message = "Workflow <b>%s</b> imported successfully." % escape( workflow.name )
url = '%s/workflow/view_workflow?repository_metadata_id=%s&workflow_name=%s&message=%s' % \
( tool_shed_url, repository_metadata_id, encoding_util.tool_shed_encode( workflow_name ), message )
return trans.response.send_redirect( url )
elif installed_repository_file:
# The workflow was read from a file included with an installed tool shed repository.
- message = "Workflow <b>%s</b> imported successfully." % workflow.name
+ message = "Workflow <b>%s</b> imported successfully." % escape( workflow.name )
if cntrller == 'api':
return status, message
return trans.response.send_redirect( web.url_for( controller='admin_toolshed',
@@ -1184,7 +1184,7 @@
# Index page with message
workflow_id = trans.security.encode_id( stored_workflow.id )
return trans.show_message( 'Workflow "%s" created from current history. You can <a href="%s" target="_parent">edit</a> or <a href="%s">run</a> the workflow.' %
- ( workflow_name, url_for( controller='workflow', action='editor', id=workflow_id ),
+ ( escape( workflow_name ), url_for( controller='workflow', action='editor', id=workflow_id ),
url_for( controller='workflow', action='run', id=workflow_id ) ) )
@web.expose
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e templates/embed_base.mako
--- a/templates/embed_base.mako
+++ b/templates/embed_base.mako
@@ -51,7 +51,7 @@
</div><h4><a class="toggle-embed" href="${display_href}" title="Show or hide ${item_display_name} content">Galaxy ${get_class_display_name( item.__class__ )} | ${get_item_name( item ) | h}</a></h4>
%if hasattr( item, "annotation") and item.annotation:
- <div class="annotation">${item.annotation}</div>
+ <div class="annotation">${item.annotation | h}</div>
%endif
## Use a hidden var to store the ajax URL for getting an item's content.
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e templates/ind_share_base.mako
--- a/templates/ind_share_base.mako
+++ b/templates/ind_share_base.mako
@@ -91,7 +91,7 @@
Email address of user to share with
</label><div style="float: left; width: 250px; margin-right: 10px;">
- <input type="text" name="email" value="${email}" size="40">
+ <input type="text" name="email" value="${email | h}" size="40"></div><div style="clear: both"></div></div>
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e templates/user/dbkeys.mako
--- a/templates/user/dbkeys.mako
+++ b/templates/user/dbkeys.mako
@@ -148,7 +148,7 @@
Processing
% endif
</td>
- <td><form action="dbkeys" method="post"><input type="hidden" name="key" value="${key}" /><input type="submit" name="delete" value="Delete" /></form></td>
+ <td><form action="dbkeys" method="post"><input type="hidden" name="key" value="${key | h}" /><input type="submit" name="delete" value="Delete" /></form></td></tr>
% endfor
</table>
@@ -194,7 +194,7 @@
<div style="clear: both; padding-bottom: 0.5em"></div><select id="fasta_input" name="dataset_id">
%for dataset in fasta_hdas:
- <option value="${trans.security.encode_id( dataset.id )}">${dataset.hid}: ${dataset.name}</option>
+ <option value="${trans.security.encode_id( dataset.id )}">${dataset.hid | h}: ${dataset.name | h}</option>
%endfor
</select><input type="file" id="len_file_input" name="len_file" /></input>
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e templates/user/openid_associate.mako
--- a/templates/user/openid_associate.mako
+++ b/templates/user/openid_associate.mako
@@ -48,13 +48,13 @@
The following OpenIDs will be associated with the account chosen or created below.
<ul>
%for openid in openids:
- <li>${openid.openid}</li>
+ <li>${openid.openid | h}</li>
%endfor
</ul></div>
%else:
<div>
- The OpenID <strong>${openids[0].openid}</strong> will be associated with the account chosen or created.
+ The OpenID <strong>${openids[0].openid | h}</strong> will be associated with the account chosen or created.
</div>
%endif
<br/>
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e templates/user/toolbox_filters.mako
--- a/templates/user/toolbox_filters.mako
+++ b/templates/user/toolbox_filters.mako
@@ -15,7 +15,7 @@
%if tool_filters or section_filters or label_filters:
<div class="toolForm">
- <form name="toolbox_filter" id="toolbox_filter" action="${h.url_for( controller='user', action='edit_toolbox_filters', cntrller=cntrller, user_id=trans.security.encode_id( user.id ) )}" method="post" >
+ <form name="toolbox_filter" id="toolbox_filter" action="${h.url_for( controller='user', action='edit_toolbox_filters', cntrller=cntrller )}" method="post" >
% if tool_filters:
<div class="toolFormTitle">Edit ToolBox filters :: Tools</div><div class="toolFormBody">
@@ -87,5 +87,5 @@
</form></div>
%else:
- ${render_msg( 'No filter available. Contact you system administrator or check your configuration file.', 'info' )}
+ ${render_msg( 'No filters available. Contact your system administrator or check your configuration file.', 'info' )}
%endif
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e templates/user/username.mako
--- a/templates/user/username.mako
+++ b/templates/user/username.mako
@@ -1,4 +1,9 @@
<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+%if message:
+ ${render_msg( message, status )}
+%endif
<% is_admin = cntrller == 'admin' and trans.user_is_admin() %>
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e templates/webapps/galaxy/root/tool_menu.mako
--- a/templates/webapps/galaxy/root/tool_menu.mako
+++ b/templates/webapps/galaxy/root/tool_menu.mako
@@ -82,7 +82,7 @@
%if t.user.stored_workflow_menu_entries:
%for m in t.user.stored_workflow_menu_entries:
<div class="toolTitle">
- <a href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id(m.stored_workflow_id) )}" target="galaxy_main">${ util.unicodify( m.stored_workflow.name ) }</a>
+ <a href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id(m.stored_workflow_id) )}" target="galaxy_main">${ util.unicodify( m.stored_workflow.name ) | h}</a></div>
%endfor
%endif
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e templates/webapps/galaxy/tool_executed.mako
--- a/templates/webapps/galaxy/tool_executed.mako
+++ b/templates/webapps/galaxy/tool_executed.mako
@@ -61,7 +61,7 @@
${jobs_str} been successfully added to the queue - resulting in the following ${datasets_str}:
</p>
%for _, data in out_data:
- <div style="padding: 10px"><b> ${data.hid}: ${data.name}</b></div>
+ <div style="padding: 10px"><b> ${data.hid}: ${data.name | h}</b></div>
%endfor
<p>
@@ -83,7 +83,7 @@
<ul><!-- Styling on this list is a little flat. Consider identing these error messages. -->
%for job_error in job_errors:
- <li><b>${job_error}</b></li>
+ <li><b>${job_error | h}</b></li>
%endfor
</ul></div>
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e templates/webapps/galaxy/visualization/phyloviz.mako
--- a/templates/webapps/galaxy/visualization/phyloviz.mako
+++ b/templates/webapps/galaxy/visualization/phyloviz.mako
@@ -180,7 +180,6 @@
<%def name="center_panel()">
-
<div class="unified-panel-header" unselectable="on"><div class="unified-panel-header-inner"><div style="float:left;" id="title"></div>
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e templates/webapps/galaxy/workflow/configure_menu.mako
--- a/templates/webapps/galaxy/workflow/configure_menu.mako
+++ b/templates/webapps/galaxy/workflow/configure_menu.mako
@@ -1,4 +1,5 @@
<%inherit file="/webapps/galaxy/base_panels.mako"/>
+<%page expression_filter="h"/><%def name="init()"><%
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e templates/webapps/galaxy/workflow/display.mako
--- a/templates/webapps/galaxy/workflow/display.mako
+++ b/templates/webapps/galaxy/workflow/display.mako
@@ -40,7 +40,7 @@
<%def name="row_for_param( param, value, other_values, prefix, step )"><% cls = "form-row" %><div class="${cls}">
- <label>${param.get_label()}</label>
+ <label>${param.get_label() | h}</label><div>
%if isinstance( param, DataToolParameter ) or isinstance( param, DataCollectionToolParameter ):
%if ( prefix + param.name ) in step.input_connections_by_name:
@@ -93,19 +93,19 @@
%><div class="toolForm">
%if tool:
- <div class="toolFormTitle">Step ${int(step.order_index)+1}: ${tool.name}</div>
+ <div class="toolFormTitle">Step ${int(step.order_index)+1}: ${tool.name | h}</div><div class="toolFormBody">
${do_inputs( tool.inputs, step.state.inputs, "", step )}
</div>
%else:
- <div class="toolFormTitle">Step ${int(step.order_index)+1}: Unknown Tool with id '${step.tool_id}'</div>
+ <div class="toolFormTitle">Step ${int(step.order_index)+1}: Unknown Tool with id '${step.tool_id | h}'</div>
%endif
</div>
%else:
## TODO: always input dataset?
<% module = step.module %><div class="toolForm">
- <div class="toolFormTitle">Step ${int(step.order_index)+1}: ${module.name}</div>
+ <div class="toolFormTitle">Step ${int(step.order_index)+1}: ${module.name | h}</div><div class="toolFormBody">
${do_inputs( module.get_runtime_inputs(), step.state.inputs, "", step )}
</div>
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e templates/webapps/galaxy/workflow/list.mako
--- a/templates/webapps/galaxy/workflow/list.mako
+++ b/templates/webapps/galaxy/workflow/list.mako
@@ -94,7 +94,7 @@
<% workflow = association.stored_workflow %><tr><td>
- <a class="menubutton" id="shared-${i}-popup" href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id(workflow.id) )}">${h.to_unicode( workflow.name )}</a>
+ <a class="menubutton" id="shared-${i}-popup" href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id(workflow.id) )}">${h.to_unicode( workflow.name ) | h}</a></td><td>${workflow.user.email}</td><td>${len(workflow.latest_workflow.steps)}</td>
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e templates/webapps/galaxy/workflow/list_for_run.mako
--- a/templates/webapps/galaxy/workflow/list_for_run.mako
+++ b/templates/webapps/galaxy/workflow/list_for_run.mako
@@ -23,7 +23,7 @@
%for i, workflow in enumerate( workflows ):
<tr><td>
- <a href="${h.url_for(controller='workflow', action='run', id=trans.security.encode_id(workflow.id) )}">${h.to_unicode( workflow.name )}</a>
+ <a href="${h.url_for(controller='workflow', action='run', id=trans.security.encode_id(workflow.id) )}">${h.to_unicode( workflow.name ) | h}</a><a id="wf-${i}-popup" class="popup-arrow" style="display: none;">▼</a></td><td>${len(workflow.latest_workflow.steps)}</td>
@@ -51,10 +51,10 @@
<% workflow = association.stored_workflow %><tr><td>
- <a href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id(workflow.id) )}">${workflow.name}</a>
+ <a href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id(workflow.id) )}">${workflow.name | h}</a><a id="shared-${i}-popup" class="popup-arrow" style="display: none;">▼</a></td>
- <td>${workflow.user.email}</td>
+ <td>${workflow.user.email | h}</td><td>${len(workflow.latest_workflow.steps)}</td></tr>
%endfor
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e templates/webapps/galaxy/workflow/missing_tools.mako
--- a/templates/webapps/galaxy/workflow/missing_tools.mako
+++ b/templates/webapps/galaxy/workflow/missing_tools.mako
@@ -1,6 +1,6 @@
<%inherit file="/base.mako"/>
-<h2>Cannot run workflow "${h.to_unicode( workflow.name )}"</h2>
+<h2>Cannot run workflow "${h.to_unicode( workflow.name ) | h}"</h2>
%if workflow.annotation:
<div class="workflow-annotation">${workflow.annotation}</div>
@@ -11,7 +11,7 @@
<strong>This workflow utilizes tools which are unavailable, and cannot be run. Enable the tools listed below, or <a href="${h.url_for(controller='workflow', action='editor', id=trans.security.encode_id(workflow.id) )}" target="_parent">edit the workflow</a> to correct these errors.</strong><br/><ul>
%for i, tool in enumerate( missing_tools ):
- <li>${tool}</li>
+ <li>${tool | h}</li>
%endfor
</ul></div>
\ No newline at end of file
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e templates/webapps/galaxy/workflow/myexp_export.mako
--- a/templates/webapps/galaxy/workflow/myexp_export.mako
+++ b/templates/webapps/galaxy/workflow/myexp_export.mako
@@ -9,7 +9,7 @@
## Generate request.
<?xml version="1.0"?><workflow>
- <title>${workflow_name}</title>
+ <title>${workflow_name | h}</title><description>${workflow_description}</description><type>Galaxy</type><content encoding="base64" type="binary">
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e templates/webapps/galaxy/workflow/rename.mako
--- a/templates/webapps/galaxy/workflow/rename.mako
+++ b/templates/webapps/galaxy/workflow/rename.mako
@@ -15,7 +15,7 @@
%endif
<div class="toolForm">
- <div class="toolFormTitle">Rename workflow '${stored.name}'</div>
+ <div class="toolFormTitle">Rename workflow '${stored.name | h}'</div><div class="toolFormBody"><form action="${h.url_for(controller='workflow', action='rename', id=trans.security.encode_id(stored.id) )}" method="POST"><div class="form-row">
@@ -23,7 +23,7 @@
New name
</label><div style="float: left; width: 250px; margin-right: 10px;">
- <input type="text" name="new_name" value="${stored.name}" size="40">
+ <input type="text" name="new_name" value="${stored.name | h}" size="40"></div><div style="clear: both"></div></div>
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e templates/webapps/galaxy/workflow/run.mako
--- a/templates/webapps/galaxy/workflow/run.mako
+++ b/templates/webapps/galaxy/workflow/run.mako
@@ -372,7 +372,7 @@
<% cls = "form-row" %>
%endif
<div class="${cls}">
- <label>${param.get_label()}</label>
+ <label>${param.get_label() | h}</label><div>
%if isinstance( param, DataToolParameter ) or isinstance( param, DataCollectionToolParameter ):
%if ( prefix + param.name ) in step.input_connections_by_name:
@@ -444,7 +444,7 @@
%else:
<span class="workflow_parameters"><span class="uneditable_field">
- ${param.value_to_display_text( value, app )}
+ ${param.value_to_display_text( value, app ) | h}
</span><span class="editable_field"><span class="editable">
@@ -474,7 +474,7 @@
<span class="action-button" id="hide_all_tool_body">Collapse</span></div>
-<h2>Running workflow "${h.to_unicode( workflow.name )}"</h2>
+<h2>Running workflow "${h.to_unicode( workflow.name ) | h}"</h2>
%if has_upgrade_messages:
<div class="warningmessage">
@@ -574,6 +574,7 @@
<%
pja_ss_all = []
for pja_ss in [ActionBox.get_short_str(pja) for pja in step.post_job_actions]:
+ pja_ss = h.escape( pja_ss )
for rematch in re.findall('\$\{.+?\}', pja_ss):
pja_ss = pja_ss.replace(rematch, '<span style="background-color:%s" class="wfpspan wf_parm__%s pja_wfp">%s</span>' % (wf_parms[rematch[2:-1]], rematch[2:-1], rematch[2:-1]))
pja_ss_all.append(pja_ss)
@@ -586,7 +587,7 @@
%else:
<div class="toolForm"><div class="toolFormTitle">
- <span class='title_ul_text'>Step ${int(step.order_index)+1}: ${module.name}</span>
+ <span class='title_ul_text'>Step ${int(step.order_index)+1}: ${module.name | h}</span>
% if step.annotations:
<div class="step-annotation">${step.annotations[0].annotation}</div>
% endif
diff -r 8d8bce91a289e040d47f9b757aae4051a0501743 -r 511fbb67b820735128ee02e526fb6873beaa961e templates/webapps/galaxy/workflow/run_complete.mako
--- a/templates/webapps/galaxy/workflow/run_complete.mako
+++ b/templates/webapps/galaxy/workflow/run_complete.mako
@@ -1,4 +1,5 @@
<%inherit file="/base.mako"/>
+<%page expression_filter="h"/><div class="donemessagelarge">
%if scheduled:
@@ -7,7 +8,7 @@
<div class="workflow-invocation-complete">
%if invocation['new_history']:
<p>These datasets will appear in a new history:
- <a target='galaxy_history' href="${h.url_for( controller='history', action='list', operation="Switch", id=trans.security.encode_id(invocation['new_history'].id), use_panels=False, show_deleted=False )}">
+ <a target='galaxy_history' href="${h.url_for( controller='history', action='list', operation="Switch", id=trans.security.encode_id(invocation['new_history'].id), use_panels=False, show_deleted=False ) | n}">
'${h.to_unicode(invocation['new_history'].name)}'.
</a></p>
%endif
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
09 Dec '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/ac30ccd5cd1e/
Changeset: ac30ccd5cd1e
Branch: next-stable
User: jmchilton
Date: 2014-12-09 14:14:54+00:00
Summary: Merge stable.
Affected #: 42 files
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac .hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -20,4 +20,4 @@
ca45b78adb4152fc6e7395514d46eba6b7d0b838 release_2014.08.11
548ab24667d6206780237bd807f7d857a484c461 latest_2014.08.11
2092948937ac30ef82f71463a235c66d34987088 release_2014.10.06
-acb2548443ae42d39ef200d035ccc0481d6b930c latest_2014.10.06
+782cf1a1f6b56f8a9c0b3e5e9ffd29fd93b16ce3 latest_2014.10.06
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac lib/galaxy/security/validate_user_input.py
--- a/lib/galaxy/security/validate_user_input.py
+++ b/lib/galaxy/security/validate_user_input.py
@@ -1,3 +1,9 @@
+"""
+Utilities for validating inputs related to user objects.
+
+The validate_* methods in this file return simple messages that do not contain
+user inputs - so these methods do not need to be escaped.
+"""
import logging
import re
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -67,6 +67,7 @@
from galaxy.util.template import fill_template
from galaxy.web import url_for
from galaxy.web.form_builder import SelectField
+from galaxy.web.framework.helpers import escape
from galaxy.model.item_attrs import Dictifiable
from galaxy.model import Workflow
from tool_shed.util import common_util
@@ -791,7 +792,7 @@
success = True
# Make sure the tool is actually loaded.
if tool_id not in self.tools_by_id:
- return None, False, "No tool with id %s" % tool_id
+ return None, False, "No tool with id %s" % escape( tool_id )
else:
tool = self.tools_by_id[ tool_id ]
tarball_files = []
@@ -902,7 +903,7 @@
replace the old tool.
"""
if tool_id not in self.tools_by_id:
- message = "No tool with id %s" % tool_id
+ message = "No tool with id %s" % escape( tool_id )
status = 'error'
else:
old_tool = self.tools_by_id[ tool_id ]
@@ -939,7 +940,7 @@
Attempt to remove the tool identified by 'tool_id'.
"""
if tool_id not in self.tools_by_id:
- message = "No tool with id %s" % tool_id
+ message = "No tool with id %s" % escape( tool_id )
status = 'error'
else:
tool = self.tools_by_id[ tool_id ]
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac lib/galaxy/tools/filters/__init__.py
--- a/lib/galaxy/tools/filters/__init__.py
+++ b/lib/galaxy/tools/filters/__init__.py
@@ -1,6 +1,10 @@
+import logging
from galaxy.util import listify
from copy import deepcopy
+log = logging.getLogger( __name__ )
+
+
class FilterFactory( object ):
"""
An instance of this class is responsible for filtering the list
@@ -37,17 +41,21 @@
elif name == 'toolbox_label_filters':
category = "label"
if category:
- self.__init_filters( category, user_filters, filters )
+ validate = getattr( trans.app.config, 'user_%s_filters' % category, [] )
+ self.__init_filters( category, user_filters, filters, validate=validate )
else:
if kwds.get( "trackster", False ):
filters[ "tool" ].append( _has_trackster_conf )
return filters
- def __init_filters( self, key, filters, toolbox_filters ):
+ def __init_filters( self, key, filters, toolbox_filters, validate=None ):
for filter in filters:
- filter_function = self.__build_filter_function( filter )
- toolbox_filters[ key ].append( filter_function )
+ if validate is None or filter in validate or filter in self.default_filters:
+ filter_function = self.__build_filter_function( filter )
+ toolbox_filters[ key ].append( filter_function )
+ else:
+ log.warning( "Refusing to load %s filter '%s' which is not defined in config", key, filter )
return toolbox_filters
def __build_filter_function( self, filter_name ):
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -1664,7 +1664,8 @@
stored.user = trans.user
stored.published = publish
if data[ 'annotation' ]:
- self.add_item_annotation( trans.sa_session, stored.user, stored, data[ 'annotation' ] )
+ annotation = sanitize_html( data[ 'annotation' ], 'utf-8', 'text/html' )
+ self.add_item_annotation( trans.sa_session, stored.user, stored, annotation )
# Persist
trans.sa_session.add( stored )
@@ -2571,6 +2572,8 @@
def set_public_username( self, trans, id, username, **kwargs ):
""" Set user's public username and delegate to sharing() """
user = trans.get_user()
+ # message from validate_publicname does not contain input, no need
+ # to escape.
message = validate_publicname( trans, username, user )
if message:
return trans.fill_template( '/sharing_base.mako', item=self.get_item( trans, id ), message=message, status='error' )
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac lib/galaxy/web/form_builder.py
--- a/lib/galaxy/web/form_builder.py
+++ b/lib/galaxy/web/form_builder.py
@@ -563,7 +563,7 @@
html += '<input name="__switch_default__" type="hidden" value="%s" />' % self.default_field
options = []
for name, delegate_field in self.delegate_fields.items():
- field = dumps( delegate_field.to_dict() )
+ field = escape( dumps( delegate_field.to_dict() ) )
option = " '%s': %s" % ( name, field )
options.append( option )
html += '<script>$(document).ready( function() {\nvar switchOptions = {\n'
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac lib/galaxy/webapps/galaxy/controllers/history.py
--- a/lib/galaxy/webapps/galaxy/controllers/history.py
+++ b/lib/galaxy/webapps/galaxy/controllers/history.py
@@ -718,7 +718,9 @@
for husa in husas:
trans.sa_session.delete( husa )
if not deleted_sharing_relation:
- message = "History '%s' does not seem to be shared with user '%s'" % ( history.name, user.email )
+ history_name = escape( history.name )
+ user_email = escape( user.email )
+ message = "History '%s' does not seem to be shared with user '%s'" % ( history_name, user_email )
return trans.fill_template( '/sharing_base.mako', item=history,
message=message, status='error' )
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac lib/galaxy/webapps/galaxy/controllers/mobile.py
--- a/lib/galaxy/webapps/galaxy/controllers/mobile.py
+++ b/lib/galaxy/webapps/galaxy/controllers/mobile.py
@@ -1,60 +1,71 @@
+from galaxy import web
from galaxy.web.base.controller import *
+
class Mobile( BaseUIController ):
+
@web.expose
def index( self, trans, **kwargs ):
- return trans.fill_template( "mobile/index.mako" )
+ return trans.response.send_redirect( web.url_for(controller='root', action='index' ) )
+ # return trans.fill_template( "mobile/index.mako" )
@web.expose
def history_list( self, trans ):
- return trans.fill_template( "mobile/history/list.mako" )
+ return trans.response.send_redirect( web.url_for(controller='root', action='index' ) )
+ # return trans.fill_template( "mobile/history/list.mako" )
@web.expose
def history_detail( self, trans, id ):
- history = trans.sa_session.query( trans.app.model.History ).get( id )
- assert history.user == trans.user
- return trans.fill_template( "mobile/history/detail.mako", history=history )
+ return trans.response.send_redirect( web.url_for(controller='root', action='index' ) )
+ # history = trans.sa_session.query( trans.app.model.History ).get( id )
+ # assert history.user == trans.user
+ # return trans.fill_template( "mobile/history/detail.mako", history=history )
@web.expose
def dataset_detail( self, trans, id ):
- dataset = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( id )
- assert dataset.history.user == trans.user
- return trans.fill_template( "mobile/dataset/detail.mako", dataset=dataset )
+ return trans.response.send_redirect( web.url_for(controller='root', action='index' ) )
+ # dataset = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( id )
+ # assert dataset.history.user == trans.user
+ # return trans.fill_template( "mobile/dataset/detail.mako", dataset=dataset )
@web.expose
def dataset_peek( self, trans, id ):
- dataset = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( id )
- assert dataset.history.user == trans.user
- return trans.fill_template( "mobile/dataset/peek.mako", dataset=dataset )
+ return trans.response.send_redirect( web.url_for(controller='root', action='index' ) )
+ # dataset = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( id )
+ # assert dataset.history.user == trans.user
+ # return trans.fill_template( "mobile/dataset/peek.mako", dataset=dataset )
@web.expose
def settings( self, trans, email=None, password=None ):
- message = None
- if email is not None and password is not None:
- if email == "":
- self.__logout( trans )
- message = "Logged out"
- else:
- error = self.__login( trans, email, password )
- message = error or "Login changed"
- return trans.fill_template( "mobile/settings.mako", message=message )
+ return trans.response.send_redirect( web.url_for(controller='root', action='index' ) )
+ # message = None
+ # if email is not None and password is not None:
+ # if email == "":
+ # self.__logout( trans )
+ # message = "Logged out"
+ # else:
+ # error = self.__login( trans, email, password )
+ # message = error or "Login changed"
+ # return trans.fill_template( "mobile/settings.mako", message=message )
def __logout( self, trans ):
- trans.log_event( "User logged out" )
- trans.handle_user_logout()
+ return trans.response.send_redirect( web.url_for(controller='root', action='index' ) )
+ # trans.log_event( "User logged out" )
+ # trans.handle_user_logout()
def __login( self, trans, email="", password="" ):
- error = password_error = None
- user = trans.sa_session.query( model.User ).filter_by( email = email ).first()
- if not user:
- error = "No such user (please note that login is case sensitive)"
- elif user.deleted:
- error = "This account has been marked deleted, contact your Galaxy administrator to restore the account."
- elif user.external:
- error = "This account was created for use with an external authentication method, contact your local Galaxy administrator to activate it."
- elif not user.check_password( password ):
- error = "Invalid password"
- else:
- trans.handle_user_login( user )
- trans.log_event( "User logged in" )
- return error
+ return trans.response.send_redirect( web.url_for(controller='root', action='index' ) )
+ # error = password_error = None
+ # user = trans.sa_session.query( model.User ).filter_by( email = email ).first()
+ # if not user:
+ # error = "No such user (please note that login is case sensitive)"
+ # elif user.deleted:
+ # error = "This account has been marked deleted, contact your Galaxy administrator to restore the account."
+ # elif user.external:
+ # error = "This account was created for use with an external authentication method, contact your local Galaxy administrator to activate it."
+ # elif not user.check_password( password ):
+ # error = "Invalid password"
+ # else:
+ # trans.handle_user_login( user )
+ # trans.log_event( "User logged in" )
+ # return error
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac lib/galaxy/webapps/galaxy/controllers/page.py
--- a/lib/galaxy/webapps/galaxy/controllers/page.py
+++ b/lib/galaxy/webapps/galaxy/controllers/page.py
@@ -500,14 +500,14 @@
.first()
if not other:
mtype = "error"
- msg = ( "User '%s' does not exist" % email )
+ msg = ( "User '%s' does not exist" % escape( email ) )
elif other == trans.get_user():
mtype = "error"
msg = ( "You cannot share a page with yourself" )
elif trans.sa_session.query( model.PageUserShareAssociation ) \
.filter_by( user=other, page=page ).count() > 0:
mtype = "error"
- msg = ( "Page already shared with '%s'" % email )
+ msg = ( "Page already shared with '%s'" % escape( email ) )
else:
share = model.PageUserShareAssociation()
share.page = page
@@ -516,7 +516,9 @@
session.add( share )
self.create_item_slug( session, page )
session.flush()
- trans.set_message( "Page '%s' shared with user '%s'" % ( page.title, other.email ) )
+ page_title = escape( page.title )
+ other_email = escape( other.email )
+ trans.set_message( "Page '%s' shared with user '%s'" % ( page_title, other_email ) )
return trans.response.send_redirect( url_for( controller='page', action='sharing', id=id ) )
return trans.fill_template( "/ind_share_base.mako",
message = msg,
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac lib/galaxy/webapps/galaxy/controllers/visualization.py
--- a/lib/galaxy/webapps/galaxy/controllers/visualization.py
+++ b/lib/galaxy/webapps/galaxy/controllers/visualization.py
@@ -535,14 +535,14 @@
.first()
if not other:
mtype = "error"
- msg = ( "User '%s' does not exist" % email )
+ msg = ( "User '%s' does not exist" % escape( email ) )
elif other == trans.get_user():
mtype = "error"
msg = ( "You cannot share a visualization with yourself" )
elif trans.sa_session.query( model.VisualizationUserShareAssociation ) \
.filter_by( user=other, visualization=visualization ).count() > 0:
mtype = "error"
- msg = ( "Visualization already shared with '%s'" % email )
+ msg = ( "Visualization already shared with '%s'" % escape( email ) )
else:
share = model.VisualizationUserShareAssociation()
share.visualization = visualization
@@ -551,7 +551,9 @@
session.add( share )
self.create_item_slug( session, visualization )
session.flush()
- trans.set_message( "Visualization '%s' shared with user '%s'" % ( visualization.title, other.email ) )
+ viz_title = escape( visualization.title )
+ other_email = escape( other.email )
+ trans.set_message( "Visualization '%s' shared with user '%s'" % ( viz_title, other_email ) )
return trans.response.send_redirect( web.url_for(controller='visualization', action='sharing', id=id ) )
return trans.fill_template( "/ind_share_base.mako",
message = msg,
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac lib/galaxy/webapps/galaxy/controllers/workflow.py
--- a/lib/galaxy/webapps/galaxy/controllers/workflow.py
+++ b/lib/galaxy/webapps/galaxy/controllers/workflow.py
@@ -310,14 +310,14 @@
.first()
if not other:
mtype = "error"
- msg = ( "User '%s' does not exist" % email )
+ msg = ( "User '%s' does not exist" % escape( email ) )
elif other == trans.get_user():
mtype = "error"
msg = ( "You cannot share a workflow with yourself" )
elif trans.sa_session.query( model.StoredWorkflowUserShareAssociation ) \
.filter_by( user=other, stored_workflow=stored ).count() > 0:
mtype = "error"
- msg = ( "Workflow already shared with '%s'" % email )
+ msg = ( "Workflow already shared with '%s'" % escape( email ) )
else:
share = model.StoredWorkflowUserShareAssociation()
share.stored_workflow = stored
@@ -325,7 +325,7 @@
session = trans.sa_session
session.add( share )
session.flush()
- trans.set_message( "Workflow '%s' shared with user '%s'" % ( stored.name, other.email ) )
+ trans.set_message( "Workflow '%s' shared with user '%s'" % ( escape( stored.name ), escape( other.email ) ) )
return trans.response.send_redirect( url_for( controller='workflow', action='sharing', id=id ) )
return trans.fill_template( "/ind_share_base.mako",
message=msg,
@@ -436,7 +436,7 @@
stored.latest_workflow.name = san_new_name
trans.sa_session.flush()
# For current workflows grid:
- trans.set_message( "Workflow renamed to '%s'." % new_name )
+ trans.set_message( "Workflow renamed to '%s'." % san_new_name )
return self.list( trans )
# For new workflows grid:
#message = "Workflow renamed to '%s'." % new_name
@@ -556,7 +556,7 @@
session.add( new_stored )
session.flush()
# Display the management page
- trans.set_message( 'Created new workflow with name "%s"' % new_stored.name )
+ trans.set_message( 'Created new workflow with name "%s"' % escape( new_stored.name ) )
return self.list( trans )
@web.expose
@@ -603,7 +603,7 @@
trans.sa_session.add( stored )
trans.sa_session.flush()
# Display the management page
- trans.set_message( "Workflow '%s' deleted" % stored.name )
+ trans.set_message( "Workflow '%s' deleted" % escape( stored.name ) )
return self.list( trans )
@web.expose
@@ -1110,7 +1110,7 @@
message += "Imported, but this workflow contains cycles. "
status = "error"
else:
- message += "Workflow <b>%s</b> imported successfully. " % workflow.name
+ message += "Workflow <b>%s</b> imported successfully. " % escape( workflow.name )
if missing_tool_tups:
if trans.user_is_admin():
# A required tool is not available in the local Galaxy instance.
@@ -1124,7 +1124,7 @@
message += "You can likely install the required tools from one of the Galaxy tool sheds listed below.<br/>"
for missing_tool_tup in missing_tool_tups:
missing_tool_id, missing_tool_name, missing_tool_version = missing_tool_tup
- message += "<b>Tool name</b> %s, <b>id</b> %s, <b>version</b> %s<br/>" % ( missing_tool_name, missing_tool_id, missing_tool_version )
+ message += "<b>Tool name</b> %s, <b>id</b> %s, <b>version</b> %s<br/>" % ( escape( missing_tool_name ), escape( missing_tool_id ), escape( missing_tool_version ) )
message += "<br/>"
for shed_name, shed_url in trans.app.tool_shed_registry.tool_sheds.items():
if shed_url.endswith( '/' ):
@@ -1134,7 +1134,7 @@
url += '&tool_id='
for missing_tool_tup in missing_tool_tups:
missing_tool_id = missing_tool_tup[0]
- url += '%s,' % missing_tool_id
+ url += '%s,' % escape( missing_tool_id )
message += '<a href="%s">%s</a><br/>' % ( url, shed_name )
status = 'error'
if installed_repository_file or tool_shed_url:
@@ -1154,13 +1154,13 @@
pass
if tool_shed_url:
# We've received the textual representation of a workflow from a Galaxy tool shed.
- message = "Workflow <b>%s</b> imported successfully." % workflow.name
+ message = "Workflow <b>%s</b> imported successfully." % escape( workflow.name )
url = '%s/workflow/view_workflow?repository_metadata_id=%s&workflow_name=%s&message=%s' % \
( tool_shed_url, repository_metadata_id, encoding_util.tool_shed_encode( workflow_name ), message )
return trans.response.send_redirect( url )
elif installed_repository_file:
# The workflow was read from a file included with an installed tool shed repository.
- message = "Workflow <b>%s</b> imported successfully." % workflow.name
+ message = "Workflow <b>%s</b> imported successfully." % escape( workflow.name )
if cntrller == 'api':
return status, message
return trans.response.send_redirect( web.url_for( controller='admin_toolshed',
@@ -1205,7 +1205,7 @@
# Index page with message
workflow_id = trans.security.encode_id( stored_workflow.id )
return trans.show_message( 'Workflow "%s" created from current history. You can <a href="%s" target="_parent">edit</a> or <a href="%s">run</a> the workflow.' %
- ( workflow_name, url_for( controller='workflow', action='editor', id=workflow_id ),
+ ( escape( workflow_name ), url_for( controller='workflow', action='editor', id=workflow_id ),
url_for( controller='workflow', action='run', id=workflow_id ) ) )
@web.expose
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac templates/embed_base.mako
--- a/templates/embed_base.mako
+++ b/templates/embed_base.mako
@@ -51,7 +51,7 @@
</div><h4><a class="toggle-embed" href="${display_href}" title="Show or hide ${item_display_name} content">Galaxy ${get_class_display_name( item.__class__ )} | ${get_item_name( item ) | h}</a></h4>
%if hasattr( item, "annotation") and item.annotation:
- <div class="annotation">${item.annotation}</div>
+ <div class="annotation">${item.annotation | h}</div>
%endif
## Use a hidden var to store the ajax URL for getting an item's content.
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac templates/ind_share_base.mako
--- a/templates/ind_share_base.mako
+++ b/templates/ind_share_base.mako
@@ -91,7 +91,7 @@
Email address of user to share with
</label><div style="float: left; width: 250px; margin-right: 10px;">
- <input type="text" name="email" value="${email}" size="40">
+ <input type="text" name="email" value="${email | h}" size="40"></div><div style="clear: both"></div></div>
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac templates/user/dbkeys.mako
--- a/templates/user/dbkeys.mako
+++ b/templates/user/dbkeys.mako
@@ -148,7 +148,7 @@
Processing
% endif
</td>
- <td><form action="dbkeys" method="post"><input type="hidden" name="key" value="${key}" /><input type="submit" name="delete" value="Delete" /></form></td>
+ <td><form action="dbkeys" method="post"><input type="hidden" name="key" value="${key | h}" /><input type="submit" name="delete" value="Delete" /></form></td></tr>
% endfor
</table>
@@ -194,7 +194,7 @@
<div style="clear: both; padding-bottom: 0.5em"></div><select id="fasta_input" name="dataset_id">
%for dataset in fasta_hdas:
- <option value="${trans.security.encode_id( dataset.id )}">${dataset.hid}: ${dataset.name}</option>
+ <option value="${trans.security.encode_id( dataset.id )}">${dataset.hid | h}: ${dataset.name | h}</option>
%endfor
</select><input type="file" id="len_file_input" name="len_file" /></input>
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac templates/user/openid_associate.mako
--- a/templates/user/openid_associate.mako
+++ b/templates/user/openid_associate.mako
@@ -48,13 +48,13 @@
The following OpenIDs will be associated with the account chosen or created below.
<ul>
%for openid in openids:
- <li>${openid.openid}</li>
+ <li>${openid.openid | h}</li>
%endfor
</ul></div>
%else:
<div>
- The OpenID <strong>${openids[0].openid}</strong> will be associated with the account chosen or created.
+ The OpenID <strong>${openids[0].openid | h}</strong> will be associated with the account chosen or created.
</div>
%endif
<br/>
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac templates/user/toolbox_filters.mako
--- a/templates/user/toolbox_filters.mako
+++ b/templates/user/toolbox_filters.mako
@@ -15,7 +15,7 @@
%if tool_filters or section_filters or label_filters:
<div class="toolForm">
- <form name="toolbox_filter" id="toolbox_filter" action="${h.url_for( controller='user', action='edit_toolbox_filters', cntrller=cntrller, user_id=trans.security.encode_id( user.id ) )}" method="post" >
+ <form name="toolbox_filter" id="toolbox_filter" action="${h.url_for( controller='user', action='edit_toolbox_filters', cntrller=cntrller )}" method="post" >
% if tool_filters:
<div class="toolFormTitle">Edit ToolBox filters :: Tools</div><div class="toolFormBody">
@@ -87,5 +87,5 @@
</form></div>
%else:
- ${render_msg( 'No filter available. Contact you system administrator or check your configuration file.', 'info' )}
+ ${render_msg( 'No filters available. Contact your system administrator or check your configuration file.', 'info' )}
%endif
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac templates/user/username.mako
--- a/templates/user/username.mako
+++ b/templates/user/username.mako
@@ -1,4 +1,9 @@
<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+%if message:
+ ${render_msg( message, status )}
+%endif
<% is_admin = cntrller == 'admin' and trans.user_is_admin() %>
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac templates/webapps/galaxy/root/tool_menu.mako
--- a/templates/webapps/galaxy/root/tool_menu.mako
+++ b/templates/webapps/galaxy/root/tool_menu.mako
@@ -82,7 +82,7 @@
%if t.user.stored_workflow_menu_entries:
%for m in t.user.stored_workflow_menu_entries:
<div class="toolTitle">
- <a href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id(m.stored_workflow_id) )}" target="galaxy_main">${ util.unicodify( m.stored_workflow.name ) }</a>
+ <a href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id(m.stored_workflow_id) )}" target="galaxy_main">${ util.unicodify( m.stored_workflow.name ) | h}</a></div>
%endfor
%endif
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac templates/webapps/galaxy/tool_executed.mako
--- a/templates/webapps/galaxy/tool_executed.mako
+++ b/templates/webapps/galaxy/tool_executed.mako
@@ -61,7 +61,7 @@
${jobs_str} been successfully added to the queue - resulting in the following ${datasets_str}:
</p>
%for _, data in out_data:
- <div style="padding: 10px"><b> ${data.hid}: ${data.name}</b></div>
+ <div style="padding: 10px"><b> ${data.hid}: ${data.name | h}</b></div>
%endfor
<p>
@@ -83,7 +83,7 @@
<ul><!-- Styling on this list is a little flat. Consider identing these error messages. -->
%for job_error in job_errors:
- <li><b>${job_error}</b></li>
+ <li><b>${job_error | h}</b></li>
%endfor
</ul></div>
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac templates/webapps/galaxy/visualization/phyloviz.mako
--- a/templates/webapps/galaxy/visualization/phyloviz.mako
+++ b/templates/webapps/galaxy/visualization/phyloviz.mako
@@ -180,7 +180,6 @@
<%def name="center_panel()">
-
<div class="unified-panel-header" unselectable="on"><div class="unified-panel-header-inner"><div style="float:left;" id="title"></div>
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac templates/webapps/galaxy/workflow/configure_menu.mako
--- a/templates/webapps/galaxy/workflow/configure_menu.mako
+++ b/templates/webapps/galaxy/workflow/configure_menu.mako
@@ -1,4 +1,5 @@
<%inherit file="/webapps/galaxy/base_panels.mako"/>
+<%page expression_filter="h"/><%def name="init()"><%
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac templates/webapps/galaxy/workflow/display.mako
--- a/templates/webapps/galaxy/workflow/display.mako
+++ b/templates/webapps/galaxy/workflow/display.mako
@@ -40,7 +40,7 @@
<%def name="row_for_param( param, value, other_values, prefix, step )"><% cls = "form-row" %><div class="${cls}">
- <label>${param.get_label()}</label>
+ <label>${param.get_label() | h}</label><div>
%if isinstance( param, DataToolParameter ) or isinstance( param, DataCollectionToolParameter ):
%if ( prefix + param.name ) in step.input_connections_by_name:
@@ -93,19 +93,19 @@
%><div class="toolForm">
%if tool:
- <div class="toolFormTitle">Step ${int(step.order_index)+1}: ${tool.name}</div>
+ <div class="toolFormTitle">Step ${int(step.order_index)+1}: ${tool.name | h}</div><div class="toolFormBody">
${do_inputs( tool.inputs, step.state.inputs, "", step )}
</div>
%else:
- <div class="toolFormTitle">Step ${int(step.order_index)+1}: Unknown Tool with id '${step.tool_id}'</div>
+ <div class="toolFormTitle">Step ${int(step.order_index)+1}: Unknown Tool with id '${step.tool_id | h}'</div>
%endif
</div>
%else:
## TODO: always input dataset?
<% module = step.module %><div class="toolForm">
- <div class="toolFormTitle">Step ${int(step.order_index)+1}: ${module.name}</div>
+ <div class="toolFormTitle">Step ${int(step.order_index)+1}: ${module.name | h}</div><div class="toolFormBody">
${do_inputs( module.get_runtime_inputs(), step.state.inputs, "", step )}
</div>
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac templates/webapps/galaxy/workflow/list.mako
--- a/templates/webapps/galaxy/workflow/list.mako
+++ b/templates/webapps/galaxy/workflow/list.mako
@@ -94,7 +94,7 @@
<% workflow = association.stored_workflow %><tr><td>
- <a class="menubutton" id="shared-${i}-popup" href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id(workflow.id) )}">${h.to_unicode( workflow.name )}</a>
+ <a class="menubutton" id="shared-${i}-popup" href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id(workflow.id) )}">${h.to_unicode( workflow.name ) | h}</a></td><td>${workflow.user.email}</td><td>${len(workflow.latest_workflow.steps)}</td>
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac templates/webapps/galaxy/workflow/list_for_run.mako
--- a/templates/webapps/galaxy/workflow/list_for_run.mako
+++ b/templates/webapps/galaxy/workflow/list_for_run.mako
@@ -36,7 +36,7 @@
%for i, workflow in enumerate( workflows ):
<tr><td>
- <a href="${h.url_for(controller='workflow', action='run', id=trans.security.encode_id(workflow.id) )}">${h.to_unicode( workflow.name )}</a>
+ <a href="${h.url_for(controller='workflow', action='run', id=trans.security.encode_id(workflow.id) )}">${h.to_unicode( workflow.name ) | h}</a><a id="wf-${i}-popup" class="popup-arrow" style="display: none;">▼</a></td><td>${len(workflow.latest_workflow.steps)}</td>
@@ -64,10 +64,10 @@
<% workflow = association.stored_workflow %><tr><td>
- <a href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id(workflow.id) )}">${workflow.name}</a>
+ <a href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id(workflow.id) )}">${workflow.name | h}</a><a id="shared-${i}-popup" class="popup-arrow" style="display: none;">▼</a></td>
- <td>${workflow.user.email}</td>
+ <td>${workflow.user.email | h}</td><td>${len(workflow.latest_workflow.steps)}</td></tr>
%endfor
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac templates/webapps/galaxy/workflow/missing_tools.mako
--- a/templates/webapps/galaxy/workflow/missing_tools.mako
+++ b/templates/webapps/galaxy/workflow/missing_tools.mako
@@ -1,6 +1,6 @@
<%inherit file="/base.mako"/>
-<h2>Cannot run workflow "${h.to_unicode( workflow.name )}"</h2>
+<h2>Cannot run workflow "${h.to_unicode( workflow.name ) | h}"</h2>
%if workflow.annotation:
<div class="workflow-annotation">${workflow.annotation}</div>
@@ -11,7 +11,7 @@
<strong>This workflow utilizes tools which are unavailable, and cannot be run. Enable the tools listed below, or <a href="${h.url_for(controller='workflow', action='editor', id=trans.security.encode_id(workflow.id) )}" target="_parent">edit the workflow</a> to correct these errors.</strong><br/><ul>
%for i, tool in enumerate( missing_tools ):
- <li>${tool}</li>
+ <li>${tool | h}</li>
%endfor
</ul></div>
\ No newline at end of file
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac templates/webapps/galaxy/workflow/myexp_export.mako
--- a/templates/webapps/galaxy/workflow/myexp_export.mako
+++ b/templates/webapps/galaxy/workflow/myexp_export.mako
@@ -9,7 +9,7 @@
## Generate request.
<?xml version="1.0"?><workflow>
- <title>${workflow_name}</title>
+ <title>${workflow_name | h}</title><description>${workflow_description}</description><type>Galaxy</type><content encoding="base64" type="binary">
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac templates/webapps/galaxy/workflow/rename.mako
--- a/templates/webapps/galaxy/workflow/rename.mako
+++ b/templates/webapps/galaxy/workflow/rename.mako
@@ -15,7 +15,7 @@
%endif
<div class="toolForm">
- <div class="toolFormTitle">Rename workflow '${stored.name}'</div>
+ <div class="toolFormTitle">Rename workflow '${stored.name | h}'</div><div class="toolFormBody"><form action="${h.url_for(controller='workflow', action='rename', id=trans.security.encode_id(stored.id) )}" method="POST"><div class="form-row">
@@ -23,7 +23,7 @@
New name
</label><div style="float: left; width: 250px; margin-right: 10px;">
- <input type="text" name="new_name" value="${stored.name}" size="40">
+ <input type="text" name="new_name" value="${stored.name | h}" size="40"></div><div style="clear: both"></div></div>
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac templates/webapps/galaxy/workflow/run.mako
--- a/templates/webapps/galaxy/workflow/run.mako
+++ b/templates/webapps/galaxy/workflow/run.mako
@@ -372,7 +372,7 @@
<% cls = "form-row" %>
%endif
<div class="${cls}">
- <label>${param.get_label()}</label>
+ <label>${param.get_label() | h}</label><div>
%if isinstance( param, DataToolParameter ) or isinstance( param, DataCollectionToolParameter ):
%if ( prefix + param.name ) in step.input_connections_by_name:
@@ -444,7 +444,7 @@
%else:
<span class="workflow_parameters"><span class="uneditable_field">
- ${param.value_to_display_text( value, app )}
+ ${param.value_to_display_text( value, app ) | h}
</span><span class="editable_field"><span class="editable">
@@ -474,7 +474,7 @@
<span class="action-button" id="hide_all_tool_body">Collapse</span></div>
-<h2>Running workflow "${h.to_unicode( workflow.name )}"</h2>
+<h2>Running workflow "${h.to_unicode( workflow.name ) | h}"</h2>
%if has_upgrade_messages:
<div class="warningmessage">
@@ -574,6 +574,7 @@
<%
pja_ss_all = []
for pja_ss in [ActionBox.get_short_str(pja) for pja in step.post_job_actions]:
+ pja_ss = h.escape( pja_ss )
for rematch in re.findall('\$\{.+?\}', pja_ss):
pja_ss = pja_ss.replace(rematch, '<span style="background-color:%s" class="wfpspan wf_parm__%s pja_wfp">%s</span>' % (wf_parms[rematch[2:-1]], rematch[2:-1], rematch[2:-1]))
pja_ss_all.append(pja_ss)
@@ -586,7 +587,7 @@
%else:
<div class="toolForm"><div class="toolFormTitle">
- <span class='title_ul_text'>Step ${int(step.order_index)+1}: ${module.name}</span>
+ <span class='title_ul_text'>Step ${int(step.order_index)+1}: ${module.name | h}</span>
% if step.annotations:
<div class="step-annotation">${step.annotations[0].annotation}</div>
% endif
diff -r 49ef0cdbf45acca661900c22869f33cd01536ecf -r ac30ccd5cd1e285390706592a0b005f79456cbac templates/webapps/galaxy/workflow/run_complete.mako
--- a/templates/webapps/galaxy/workflow/run_complete.mako
+++ b/templates/webapps/galaxy/workflow/run_complete.mako
@@ -1,4 +1,5 @@
<%inherit file="/base.mako"/>
+<%page expression_filter="h"/><div class="donemessagelarge">
%if scheduled:
@@ -7,7 +8,7 @@
<div class="workflow-invocation-complete">
%if invocation['new_history']:
<p>These datasets will appear in a new history:
- <a target='galaxy_history' href="${h.url_for( controller='history', action='list', operation="Switch", id=trans.security.encode_id(invocation['new_history'].id), use_panels=False, show_deleted=False )}">
+ <a target='galaxy_history' href="${h.url_for( controller='history', action='list', operation="Switch", id=trans.security.encode_id(invocation['new_history'].id), use_panels=False, show_deleted=False ) | n}">
'${h.to_unicode(invocation['new_history'].name)}'.
</a></p>
%endif
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: natefoo: Update tag latest_2014.10.06 for changeset 782cf1a1f6b5
by commits-noreply@bitbucket.org 09 Dec '14
by commits-noreply@bitbucket.org 09 Dec '14
09 Dec '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/3e3ac0894aba/
Changeset: 3e3ac0894aba
Branch: stable
User: natefoo
Date: 2014-12-09 14:00:15+00:00
Summary: Update tag latest_2014.10.06 for changeset 782cf1a1f6b5
Affected #: 1 file
diff -r 782cf1a1f6b56f8a9c0b3e5e9ffd29fd93b16ce3 -r 3e3ac0894aba44bba95bce6dd6833e639e01f890 .hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -20,4 +20,4 @@
ca45b78adb4152fc6e7395514d46eba6b7d0b838 release_2014.08.11
548ab24667d6206780237bd807f7d857a484c461 latest_2014.08.11
2092948937ac30ef82f71463a235c66d34987088 release_2014.10.06
-8e45b1cefba16727d4d3a7d0dceaaaf1ef400a0c latest_2014.10.06
+782cf1a1f6b56f8a9c0b3e5e9ffd29fd93b16ce3 latest_2014.10.06
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: martenson: show wrapper versions and requirement versions in the toolform header
by commits-noreply@bitbucket.org 08 Dec '14
by commits-noreply@bitbucket.org 08 Dec '14
08 Dec '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/8d8bce91a289/
Changeset: 8d8bce91a289
User: martenson
Date: 2014-12-08 22:07:58+00:00
Summary: show wrapper versions and requirement versions in the toolform header
Affected #: 1 file
diff -r 8e98c3d9b9a8bc3cabff60c67367fbaf5b328320 -r 8d8bce91a289e040d47f9b757aae4051a0501743 templates/webapps/galaxy/tool_form.mako
--- a/templates/webapps/galaxy/tool_form.mako
+++ b/templates/webapps/galaxy/tool_form.mako
@@ -353,10 +353,25 @@
%if tool.has_multiple_pages:
<div class="toolFormTitle">${tool.name} (step ${tool_state.page+1} of ${tool.npages})
%elif not tool_version_select_field:
- <div class="toolFormTitle">${tool.name} (version ${tool.version})
+ <div class="toolFormTitle">${tool.name} (Galaxy tool version ${tool.version})
%else:
<div class="toolFormTitle">${tool.name} ${tool_version_select_field.get_html()}
%endif
+ ## Show information button with underlying requirements and their versions
+ %if tool.requirements:
+ <a href="#" class="icon-btn" title="Underlying versions" tabindex="0" data-toggle="popover" data-placement="bottom" data-content=
+ "
+ %for i, requirement in enumerate( tool.requirements ):
+ ${ requirement.name } v ${ requirement.version } ${ '' if i + 1 == len( tool.requirements ) else ' | ' }
+ %endfor
+ "
+ onclick="$(function () {
+ $( '[ data-toggle=\'popover\' ]' ).popover();
+ $( this ).popover( 'show' );
+ })">
+ <span class="fa fa-info-circle"></span>
+ </a>
+ %endif
<span class="pull-right">
%if trans.app.config.biostar_url:
@@ -442,4 +457,4 @@
<div id="citations"></div>
%endif
-</div>
\ No newline at end of file
+</div>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dannon: Merged in carlfeberhard/carlfeberhard-galaxy-central-stable/stable (pull request #600)
by commits-noreply@bitbucket.org 08 Dec '14
by commits-noreply@bitbucket.org 08 Dec '14
08 Dec '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/782cf1a1f6b5/
Changeset: 782cf1a1f6b5
Branch: stable
User: dannon
Date: 2014-12-08 22:06:25+00:00
Summary: Merged in carlfeberhard/carlfeberhard-galaxy-central-stable/stable (pull request #600)
[STABLE] Fix to 04a072e to use the correct mako method in the masthead.
Affected #: 1 file
diff -r 07404a82972d877b5529fffaeb3e7e05b69a02a3 -r 782cf1a1f6b56f8a9c0b3e5e9ffd29fd93b16ce3 templates/webapps/galaxy/galaxy.masthead.mako
--- a/templates/webapps/galaxy/galaxy.masthead.mako
+++ b/templates/webapps/galaxy/galaxy.masthead.mako
@@ -1,4 +1,4 @@
-<%namespace file="/galaxy_client_app.mako" import="get_user_json" />
+<%namespace file="/galaxy_client_app.mako" import="get_user_dict" />
## masthead head generator
<%def name="load(active_view = None)">
@@ -34,7 +34,7 @@
'requests' : bool(trans.user and (trans.user.requests or trans.app.security_agent.get_accessible_request_types(trans, trans.user))),
'email' : trans.user.email if (trans.user) else "",
'valid' : bool(trans.user != None),
- 'json' : get_user_json()
+ 'json' : get_user_dict()
}
}
%>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/030db20e2f4f/
Changeset: 030db20e2f4f
Branch: stable
User: carlfeberhard
Date: 2014-12-08 21:47:33+00:00
Summary: Fix to 04a072e: use proper mako dict method instead of printing json string
Affected #: 1 file
diff -r 374e94196a14673993540a60d446addc6b1780a0 -r 030db20e2f4f15d63f622ccdd224d65214cb8d7a templates/webapps/galaxy/galaxy.masthead.mako
--- a/templates/webapps/galaxy/galaxy.masthead.mako
+++ b/templates/webapps/galaxy/galaxy.masthead.mako
@@ -1,4 +1,4 @@
-<%namespace file="/galaxy_client_app.mako" import="get_user_json" />
+<%namespace file="/galaxy_client_app.mako" import="get_user_dict" />
## masthead head generator
<%def name="load(active_view = None)">
@@ -34,7 +34,7 @@
'requests' : bool(trans.user and (trans.user.requests or trans.app.security_agent.get_accessible_request_types(trans, trans.user))),
'email' : trans.user.email if (trans.user) else "",
'valid' : bool(trans.user != None),
- 'json' : get_user_json()
+ 'json' : get_user_dict()
}
}
%>
https://bitbucket.org/galaxy/galaxy-central/commits/782cf1a1f6b5/
Changeset: 782cf1a1f6b5
Branch: stable
User: dannon
Date: 2014-12-08 22:06:25+00:00
Summary: Merged in carlfeberhard/carlfeberhard-galaxy-central-stable/stable (pull request #600)
[STABLE] Fix to 04a072e to use the correct mako method in the masthead.
Affected #: 1 file
diff -r 07404a82972d877b5529fffaeb3e7e05b69a02a3 -r 782cf1a1f6b56f8a9c0b3e5e9ffd29fd93b16ce3 templates/webapps/galaxy/galaxy.masthead.mako
--- a/templates/webapps/galaxy/galaxy.masthead.mako
+++ b/templates/webapps/galaxy/galaxy.masthead.mako
@@ -1,4 +1,4 @@
-<%namespace file="/galaxy_client_app.mako" import="get_user_json" />
+<%namespace file="/galaxy_client_app.mako" import="get_user_dict" />
## masthead head generator
<%def name="load(active_view = None)">
@@ -34,7 +34,7 @@
'requests' : bool(trans.user and (trans.user.requests or trans.app.security_agent.get_accessible_request_types(trans, trans.user))),
'email' : trans.user.email if (trans.user) else "",
'valid' : bool(trans.user != None),
- 'json' : get_user_json()
+ 'json' : get_user_dict()
}
}
%>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: carlfeberhard: Client build: modularize mode-button plugin from ui.js; update history/multi-view.js and history/view.mako
by commits-noreply@bitbucket.org 08 Dec '14
by commits-noreply@bitbucket.org 08 Dec '14
08 Dec '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/8e98c3d9b9a8/
Changeset: 8e98c3d9b9a8
User: carlfeberhard
Date: 2014-12-08 21:34:09+00:00
Summary: Client build: modularize mode-button plugin from ui.js; update history/multi-view.js and history/view.mako
Affected #: 10 files
diff -r 0fb0c56af3cf25bb8c3bb366d34c6aedcbb9df14 -r 8e98c3d9b9a8bc3cabff60c67367fbaf5b328320 client/galaxy/scripts/jq-plugins/ui/mode-button.js
--- /dev/null
+++ b/client/galaxy/scripts/jq-plugins/ui/mode-button.js
@@ -0,0 +1,191 @@
+// from: https://raw.githubusercontent.com/umdjs/umd/master/jqueryPlugin.js
+// Uses AMD or browser globals to create a jQuery plugin.
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ //TODO: So...this turns out to be an all or nothing thing. If I load jQuery in the define below, it will
+ // (of course) wipe the old jquery *and all the plugins loaded into it*. So the define below *is still
+ // relying on jquery being loaded globally* in order to preserve plugins.
+ define([], factory);
+ } else {
+ // Browser globals
+ factory(jQuery);
+ }
+
+}(function () {
+
+ /** Multi 'mode' button (or any element really) that changes the html
+ * contents of itself when clicked. Pass in an ordered list of
+ * objects with 'html' and (optional) onclick functions.
+ *
+ * When clicked in a particular node, the onclick function will
+ * be called (with the element as this) and the element will
+ * switch to the next mode, replacing its html content with
+ * that mode's html.
+ *
+ * If there is no next mode, the element will switch back to
+ * the first mode.
+ * @example:
+ * $( '.myElement' ).modeButton({
+ * modes : [
+ * {
+ * mode: 'bler',
+ * html: '<h5>Bler</h5>',
+ * onclick : function(){
+ * $( 'body' ).css( 'background-color', 'red' );
+ * }
+ * },
+ * {
+ * mode: 'bloo',
+ * html: '<h4>Bloo</h4>',
+ * onclick : function(){
+ * $( 'body' ).css( 'background-color', 'blue' );
+ * }
+ * },
+ * {
+ * mode: 'blah',
+ * html: '<h3>Blah</h3>',
+ * onclick : function(){
+ * $( 'body' ).css( 'background-color', 'grey' );
+ * }
+ * },
+ * ]
+ * });
+ * $( '.myElement' ).modeButton( 'callModeFn', 'bler' );
+ */
+ /** constructor */
+ function ModeButton( element, options ){
+ this.currModeIndex = 0;
+ return this._init( element, options );
+ }
+
+ /** html5 data key to store this object inside an element */
+ ModeButton.prototype.DATA_KEY = 'mode-button';
+ /** default options */
+ ModeButton.prototype.defaults = {
+ switchModesOnClick : true
+ };
+
+ // ---- private interface
+ /** set up options, intial mode, and the click handler */
+ ModeButton.prototype._init = function _init( element, options ){
+ //console.debug( 'ModeButton._init:', element, options );
+ options = options || {};
+ this.$element = $( element );
+ this.options = $.extend( true, {}, this.defaults, options );
+ if( !options.modes ){
+ throw new Error( 'ModeButton requires a "modes" array' );
+ }
+
+ var modeButton = this;
+ this.$element.click( function _ModeButtonClick( event ){
+ // call the curr mode fn
+ modeButton.callModeFn();
+ // inc the curr mode index
+ if( modeButton.options.switchModesOnClick ){ modeButton._incModeIndex(); }
+ // set the element html
+ $( this ).html( modeButton.options.modes[ modeButton.currModeIndex ].html );
+ });
+ return this.reset();
+ };
+ /** increment the mode index to the next in the array, looping back to zero if at the last */
+ ModeButton.prototype._incModeIndex = function _incModeIndex(){
+ this.currModeIndex += 1;
+ if( this.currModeIndex >= this.options.modes.length ){
+ this.currModeIndex = 0;
+ }
+ return this;
+ };
+ /** get the mode index in the modes array for the given key (mode name) */
+ ModeButton.prototype._getModeIndex = function _getModeIndex( modeKey ){
+ for( var i=0; i<this.options.modes.length; i+=1 ){
+ if( this.options.modes[ i ].mode === modeKey ){ return i; }
+ }
+ throw new Error( 'mode not found: ' + modeKey );
+ };
+ /** set the current mode to the one with the given index and set button html */
+ ModeButton.prototype._setModeByIndex = function _setModeByIndex( index ){
+ var newMode = this.options.modes[ index ];
+ if( !newMode ){
+ throw new Error( 'mode index not found: ' + index );
+ }
+ this.currModeIndex = index;
+ if( newMode.html ){
+ this.$element.html( newMode.html );
+ }
+ return this;
+ };
+
+ // ---- public interface
+ /** get the current mode object (not just the mode name) */
+ ModeButton.prototype.currentMode = function currentMode(){
+ return this.options.modes[ this.currModeIndex ];
+ };
+ /** return the mode key of the current mode */
+ ModeButton.prototype.current = function current(){
+ // sugar for returning mode name
+ return this.currentMode().mode;
+ };
+ /** get the mode with the given modeKey or the current mode if modeKey is undefined */
+ ModeButton.prototype.getMode = function getMode( modeKey ){
+ if( !modeKey ){ return this.currentMode(); }
+ return this.options.modes[( this._getModeIndex( modeKey ) )];
+ };
+ /** T/F if the button has the given mode */
+ ModeButton.prototype.hasMode = function hasMode( modeKey ){
+ try {
+ return !!this.getMode( modeKey );
+ } catch( err ){}
+ return false;
+ };
+ /** set the current mode to the mode with the given name */
+ ModeButton.prototype.setMode = function setMode( modeKey ){
+ return this._setModeByIndex( this._getModeIndex( modeKey ) );
+ };
+ /** reset to the initial mode */
+ ModeButton.prototype.reset = function reset(){
+ this.currModeIndex = 0;
+ if( this.options.initialMode ){
+ this.currModeIndex = this._getModeIndex( this.options.initialMode );
+ }
+ return this._setModeByIndex( this.currModeIndex );
+ };
+ /** manually call the click handler of the given mode */
+ ModeButton.prototype.callModeFn = function callModeFn( modeKey ){
+ var modeFn = this.getMode( modeKey ).onclick;
+ if( modeFn && $.type( modeFn === 'function' ) ){
+ // call with the element as context (std jquery pattern)
+ return modeFn.call( this.$element.get(0) );
+ }
+ return undefined;
+ };
+
+ // as jq plugin
+ $.fn.modeButton = function $modeButton( options ){
+ if( !this.size() ){ return this; }
+
+ //TODO: does map still work with jq multi selection (i.e. $( '.class-for-many-btns' ).modeButton)?
+ if( $.type( options ) === 'object' ){
+ return this.map( function(){
+ var $this = $( this );
+ $this.data( 'mode-button', new ModeButton( $this, options ) );
+ return this;
+ });
+ }
+
+ var $first = $( this[0] ),
+ button = $first.data( 'mode-button' );
+
+ if( !button ){
+ throw new Error( 'modeButton needs an options object or string name of a function' );
+ }
+
+ if( button && $.type( options ) === 'string' ){
+ var fnName = options;
+ if( button && $.type( button[ fnName ] ) === 'function' ){
+ return button[ fnName ].apply( button, $.makeArray( arguments ).slice( 1 ) );
+ }
+ }
+ return button;
+ };
+
+}));
diff -r 0fb0c56af3cf25bb8c3bb366d34c6aedcbb9df14 -r 8e98c3d9b9a8bc3cabff60c67367fbaf5b328320 client/galaxy/scripts/mvc/history/multi-panel.js
--- a/client/galaxy/scripts/mvc/history/multi-panel.js
+++ b/client/galaxy/scripts/mvc/history/multi-panel.js
@@ -2,7 +2,8 @@
"mvc/history/history-model",
"mvc/history/history-panel-edit",
"mvc/base-mvc",
- "utils/ajax-queue"
+ "utils/ajax-queue",
+ "jq-plugins/ui/mode-button"
], function( HISTORY_MODEL, HPANEL_EDIT, baseMVC, ajaxQueue ){
window.HISTORY_MODEL = HISTORY_MODEL;
//==============================================================================
diff -r 0fb0c56af3cf25bb8c3bb366d34c6aedcbb9df14 -r 8e98c3d9b9a8bc3cabff60c67367fbaf5b328320 client/galaxy/scripts/mvc/ui.js
--- a/client/galaxy/scripts/mvc/ui.js
+++ b/client/galaxy/scripts/mvc/ui.js
@@ -749,184 +749,3 @@
}
});
}());
-
-
-//==============================================================================
-(function(){
- /** Multi 'mode' button (or any element really) that changes the html
- * contents of itself when clicked. Pass in an ordered list of
- * objects with 'html' and (optional) onclick functions.
- *
- * When clicked in a particular node, the onclick function will
- * be called (with the element as this) and the element will
- * switch to the next mode, replacing its html content with
- * that mode's html.
- *
- * If there is no next mode, the element will switch back to
- * the first mode.
- * @example:
- * $( '.myElement' ).modeButton({
- * modes : [
- * {
- * mode: 'bler',
- * html: '<h5>Bler</h5>',
- * onclick : function(){
- * $( 'body' ).css( 'background-color', 'red' );
- * }
- * },
- * {
- * mode: 'bloo',
- * html: '<h4>Bloo</h4>',
- * onclick : function(){
- * $( 'body' ).css( 'background-color', 'blue' );
- * }
- * },
- * {
- * mode: 'blah',
- * html: '<h3>Blah</h3>',
- * onclick : function(){
- * $( 'body' ).css( 'background-color', 'grey' );
- * }
- * },
- * ]
- * });
- * $( '.myElement' ).modeButton( 'callModeFn', 'bler' );
- */
- /** constructor */
- function ModeButton( element, options ){
- this.currModeIndex = 0;
- return this._init( element, options );
- }
-
- /** html5 data key to store this object inside an element */
- ModeButton.prototype.DATA_KEY = 'mode-button';
- /** default options */
- ModeButton.prototype.defaults = {
- switchModesOnClick : true
- };
-
- // ---- private interface
- /** set up options, intial mode, and the click handler */
- ModeButton.prototype._init = function _init( element, options ){
- //console.debug( 'ModeButton._init:', element, options );
- options = options || {};
- this.$element = $( element );
- this.options = jQuery.extend( true, {}, this.defaults, options );
- if( !options.modes ){
- throw new Error( 'ModeButton requires a "modes" array' );
- }
-
- var modeButton = this;
- this.$element.click( function _ModeButtonClick( event ){
- // call the curr mode fn
- modeButton.callModeFn();
- // inc the curr mode index
- if( modeButton.options.switchModesOnClick ){ modeButton._incModeIndex(); }
- // set the element html
- $( this ).html( modeButton.options.modes[ modeButton.currModeIndex ].html );
- });
- return this.reset();
- };
- /** increment the mode index to the next in the array, looping back to zero if at the last */
- ModeButton.prototype._incModeIndex = function _incModeIndex(){
- this.currModeIndex += 1;
- if( this.currModeIndex >= this.options.modes.length ){
- this.currModeIndex = 0;
- }
- return this;
- };
- /** get the mode index in the modes array for the given key (mode name) */
- ModeButton.prototype._getModeIndex = function _getModeIndex( modeKey ){
- for( var i=0; i<this.options.modes.length; i+=1 ){
- if( this.options.modes[ i ].mode === modeKey ){ return i; }
- }
- throw new Error( 'mode not found: ' + modeKey );
- };
- /** set the current mode to the one with the given index and set button html */
- ModeButton.prototype._setModeByIndex = function _setModeByIndex( index ){
- var newMode = this.options.modes[ index ];
- if( !newMode ){
- throw new Error( 'mode index not found: ' + index );
- }
- this.currModeIndex = index;
- if( newMode.html ){
- this.$element.html( newMode.html );
- }
- return this;
- };
-
- // ---- public interface
- /** get the current mode object (not just the mode name) */
- ModeButton.prototype.currentMode = function currentMode(){
- return this.options.modes[ this.currModeIndex ];
- };
- /** return the mode key of the current mode */
- ModeButton.prototype.current = function current(){
- // sugar for returning mode name
- return this.currentMode().mode;
- };
- /** get the mode with the given modeKey or the current mode if modeKey is undefined */
- ModeButton.prototype.getMode = function getMode( modeKey ){
- if( !modeKey ){ return this.currentMode(); }
- return this.options.modes[( this._getModeIndex( modeKey ) )];
- };
- /** T/F if the button has the given mode */
- ModeButton.prototype.hasMode = function hasMode( modeKey ){
- try {
- return !!this.getMode( modeKey );
- } catch( err ){}
- return false;
- };
- /** set the current mode to the mode with the given name */
- ModeButton.prototype.setMode = function setMode( modeKey ){
- return this._setModeByIndex( this._getModeIndex( modeKey ) );
- };
- /** reset to the initial mode */
- ModeButton.prototype.reset = function reset(){
- this.currModeIndex = 0;
- if( this.options.initialMode ){
- this.currModeIndex = this._getModeIndex( this.options.initialMode );
- }
- return this._setModeByIndex( this.currModeIndex );
- };
- /** manually call the click handler of the given mode */
- ModeButton.prototype.callModeFn = function callModeFn( modeKey ){
- var modeFn = this.getMode( modeKey ).onclick;
- if( modeFn && jQuery.type( modeFn === 'function' ) ){
- // call with the element as context (std jquery pattern)
- return modeFn.call( this.$element.get(0) );
- }
- return undefined;
- };
-
- // as jq plugin
- jQuery.fn.extend({
- modeButton : function $modeButton( options ){
- if( !this.size() ){ return this; }
-
- //TODO: does map still work with jq multi selection (i.e. $( '.class-for-many-btns' ).modeButton)?
- if( jQuery.type( options ) === 'object' ){
- return this.map( function(){
- var $this = $( this );
- $this.data( 'mode-button', new ModeButton( $this, options ) );
- return this;
- });
- }
-
- var $first = $( this[0] ),
- button = $first.data( 'mode-button' );
-
- if( !button ){
- throw new Error( 'modeButton needs an options object or string name of a function' );
- }
-
- if( button && jQuery.type( options ) === 'string' ){
- var fnName = options;
- if( button && jQuery.type( button[ fnName ] ) === 'function' ){
- return button[ fnName ].apply( button, jQuery.makeArray( arguments ).slice( 1 ) );
- }
- }
- return button;
- }
- });
-}());
diff -r 0fb0c56af3cf25bb8c3bb366d34c6aedcbb9df14 -r 8e98c3d9b9a8bc3cabff60c67367fbaf5b328320 static/scripts/jq-plugins/ui/mode-button.js
--- /dev/null
+++ b/static/scripts/jq-plugins/ui/mode-button.js
@@ -0,0 +1,191 @@
+// from: https://raw.githubusercontent.com/umdjs/umd/master/jqueryPlugin.js
+// Uses AMD or browser globals to create a jQuery plugin.
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ //TODO: So...this turns out to be an all or nothing thing. If I load jQuery in the define below, it will
+ // (of course) wipe the old jquery *and all the plugins loaded into it*. So the define below *is still
+ // relying on jquery being loaded globally* in order to preserve plugins.
+ define([], factory);
+ } else {
+ // Browser globals
+ factory(jQuery);
+ }
+
+}(function () {
+
+ /** Multi 'mode' button (or any element really) that changes the html
+ * contents of itself when clicked. Pass in an ordered list of
+ * objects with 'html' and (optional) onclick functions.
+ *
+ * When clicked in a particular node, the onclick function will
+ * be called (with the element as this) and the element will
+ * switch to the next mode, replacing its html content with
+ * that mode's html.
+ *
+ * If there is no next mode, the element will switch back to
+ * the first mode.
+ * @example:
+ * $( '.myElement' ).modeButton({
+ * modes : [
+ * {
+ * mode: 'bler',
+ * html: '<h5>Bler</h5>',
+ * onclick : function(){
+ * $( 'body' ).css( 'background-color', 'red' );
+ * }
+ * },
+ * {
+ * mode: 'bloo',
+ * html: '<h4>Bloo</h4>',
+ * onclick : function(){
+ * $( 'body' ).css( 'background-color', 'blue' );
+ * }
+ * },
+ * {
+ * mode: 'blah',
+ * html: '<h3>Blah</h3>',
+ * onclick : function(){
+ * $( 'body' ).css( 'background-color', 'grey' );
+ * }
+ * },
+ * ]
+ * });
+ * $( '.myElement' ).modeButton( 'callModeFn', 'bler' );
+ */
+ /** constructor */
+ function ModeButton( element, options ){
+ this.currModeIndex = 0;
+ return this._init( element, options );
+ }
+
+ /** html5 data key to store this object inside an element */
+ ModeButton.prototype.DATA_KEY = 'mode-button';
+ /** default options */
+ ModeButton.prototype.defaults = {
+ switchModesOnClick : true
+ };
+
+ // ---- private interface
+ /** set up options, intial mode, and the click handler */
+ ModeButton.prototype._init = function _init( element, options ){
+ //console.debug( 'ModeButton._init:', element, options );
+ options = options || {};
+ this.$element = $( element );
+ this.options = $.extend( true, {}, this.defaults, options );
+ if( !options.modes ){
+ throw new Error( 'ModeButton requires a "modes" array' );
+ }
+
+ var modeButton = this;
+ this.$element.click( function _ModeButtonClick( event ){
+ // call the curr mode fn
+ modeButton.callModeFn();
+ // inc the curr mode index
+ if( modeButton.options.switchModesOnClick ){ modeButton._incModeIndex(); }
+ // set the element html
+ $( this ).html( modeButton.options.modes[ modeButton.currModeIndex ].html );
+ });
+ return this.reset();
+ };
+ /** increment the mode index to the next in the array, looping back to zero if at the last */
+ ModeButton.prototype._incModeIndex = function _incModeIndex(){
+ this.currModeIndex += 1;
+ if( this.currModeIndex >= this.options.modes.length ){
+ this.currModeIndex = 0;
+ }
+ return this;
+ };
+ /** get the mode index in the modes array for the given key (mode name) */
+ ModeButton.prototype._getModeIndex = function _getModeIndex( modeKey ){
+ for( var i=0; i<this.options.modes.length; i+=1 ){
+ if( this.options.modes[ i ].mode === modeKey ){ return i; }
+ }
+ throw new Error( 'mode not found: ' + modeKey );
+ };
+ /** set the current mode to the one with the given index and set button html */
+ ModeButton.prototype._setModeByIndex = function _setModeByIndex( index ){
+ var newMode = this.options.modes[ index ];
+ if( !newMode ){
+ throw new Error( 'mode index not found: ' + index );
+ }
+ this.currModeIndex = index;
+ if( newMode.html ){
+ this.$element.html( newMode.html );
+ }
+ return this;
+ };
+
+ // ---- public interface
+ /** get the current mode object (not just the mode name) */
+ ModeButton.prototype.currentMode = function currentMode(){
+ return this.options.modes[ this.currModeIndex ];
+ };
+ /** return the mode key of the current mode */
+ ModeButton.prototype.current = function current(){
+ // sugar for returning mode name
+ return this.currentMode().mode;
+ };
+ /** get the mode with the given modeKey or the current mode if modeKey is undefined */
+ ModeButton.prototype.getMode = function getMode( modeKey ){
+ if( !modeKey ){ return this.currentMode(); }
+ return this.options.modes[( this._getModeIndex( modeKey ) )];
+ };
+ /** T/F if the button has the given mode */
+ ModeButton.prototype.hasMode = function hasMode( modeKey ){
+ try {
+ return !!this.getMode( modeKey );
+ } catch( err ){}
+ return false;
+ };
+ /** set the current mode to the mode with the given name */
+ ModeButton.prototype.setMode = function setMode( modeKey ){
+ return this._setModeByIndex( this._getModeIndex( modeKey ) );
+ };
+ /** reset to the initial mode */
+ ModeButton.prototype.reset = function reset(){
+ this.currModeIndex = 0;
+ if( this.options.initialMode ){
+ this.currModeIndex = this._getModeIndex( this.options.initialMode );
+ }
+ return this._setModeByIndex( this.currModeIndex );
+ };
+ /** manually call the click handler of the given mode */
+ ModeButton.prototype.callModeFn = function callModeFn( modeKey ){
+ var modeFn = this.getMode( modeKey ).onclick;
+ if( modeFn && $.type( modeFn === 'function' ) ){
+ // call with the element as context (std jquery pattern)
+ return modeFn.call( this.$element.get(0) );
+ }
+ return undefined;
+ };
+
+ // as jq plugin
+ $.fn.modeButton = function $modeButton( options ){
+ if( !this.size() ){ return this; }
+
+ //TODO: does map still work with jq multi selection (i.e. $( '.class-for-many-btns' ).modeButton)?
+ if( $.type( options ) === 'object' ){
+ return this.map( function(){
+ var $this = $( this );
+ $this.data( 'mode-button', new ModeButton( $this, options ) );
+ return this;
+ });
+ }
+
+ var $first = $( this[0] ),
+ button = $first.data( 'mode-button' );
+
+ if( !button ){
+ throw new Error( 'modeButton needs an options object or string name of a function' );
+ }
+
+ if( button && $.type( options ) === 'string' ){
+ var fnName = options;
+ if( button && $.type( button[ fnName ] ) === 'function' ){
+ return button[ fnName ].apply( button, $.makeArray( arguments ).slice( 1 ) );
+ }
+ }
+ return button;
+ };
+
+}));
diff -r 0fb0c56af3cf25bb8c3bb366d34c6aedcbb9df14 -r 8e98c3d9b9a8bc3cabff60c67367fbaf5b328320 static/scripts/mvc/history/multi-panel.js
--- a/static/scripts/mvc/history/multi-panel.js
+++ b/static/scripts/mvc/history/multi-panel.js
@@ -2,7 +2,8 @@
"mvc/history/history-model",
"mvc/history/history-panel-edit",
"mvc/base-mvc",
- "utils/ajax-queue"
+ "utils/ajax-queue",
+ "jq-plugins/ui/mode-button"
], function( HISTORY_MODEL, HPANEL_EDIT, baseMVC, ajaxQueue ){
window.HISTORY_MODEL = HISTORY_MODEL;
//==============================================================================
diff -r 0fb0c56af3cf25bb8c3bb366d34c6aedcbb9df14 -r 8e98c3d9b9a8bc3cabff60c67367fbaf5b328320 static/scripts/mvc/ui.js
--- a/static/scripts/mvc/ui.js
+++ b/static/scripts/mvc/ui.js
@@ -749,184 +749,3 @@
}
});
}());
-
-
-//==============================================================================
-(function(){
- /** Multi 'mode' button (or any element really) that changes the html
- * contents of itself when clicked. Pass in an ordered list of
- * objects with 'html' and (optional) onclick functions.
- *
- * When clicked in a particular node, the onclick function will
- * be called (with the element as this) and the element will
- * switch to the next mode, replacing its html content with
- * that mode's html.
- *
- * If there is no next mode, the element will switch back to
- * the first mode.
- * @example:
- * $( '.myElement' ).modeButton({
- * modes : [
- * {
- * mode: 'bler',
- * html: '<h5>Bler</h5>',
- * onclick : function(){
- * $( 'body' ).css( 'background-color', 'red' );
- * }
- * },
- * {
- * mode: 'bloo',
- * html: '<h4>Bloo</h4>',
- * onclick : function(){
- * $( 'body' ).css( 'background-color', 'blue' );
- * }
- * },
- * {
- * mode: 'blah',
- * html: '<h3>Blah</h3>',
- * onclick : function(){
- * $( 'body' ).css( 'background-color', 'grey' );
- * }
- * },
- * ]
- * });
- * $( '.myElement' ).modeButton( 'callModeFn', 'bler' );
- */
- /** constructor */
- function ModeButton( element, options ){
- this.currModeIndex = 0;
- return this._init( element, options );
- }
-
- /** html5 data key to store this object inside an element */
- ModeButton.prototype.DATA_KEY = 'mode-button';
- /** default options */
- ModeButton.prototype.defaults = {
- switchModesOnClick : true
- };
-
- // ---- private interface
- /** set up options, intial mode, and the click handler */
- ModeButton.prototype._init = function _init( element, options ){
- //console.debug( 'ModeButton._init:', element, options );
- options = options || {};
- this.$element = $( element );
- this.options = jQuery.extend( true, {}, this.defaults, options );
- if( !options.modes ){
- throw new Error( 'ModeButton requires a "modes" array' );
- }
-
- var modeButton = this;
- this.$element.click( function _ModeButtonClick( event ){
- // call the curr mode fn
- modeButton.callModeFn();
- // inc the curr mode index
- if( modeButton.options.switchModesOnClick ){ modeButton._incModeIndex(); }
- // set the element html
- $( this ).html( modeButton.options.modes[ modeButton.currModeIndex ].html );
- });
- return this.reset();
- };
- /** increment the mode index to the next in the array, looping back to zero if at the last */
- ModeButton.prototype._incModeIndex = function _incModeIndex(){
- this.currModeIndex += 1;
- if( this.currModeIndex >= this.options.modes.length ){
- this.currModeIndex = 0;
- }
- return this;
- };
- /** get the mode index in the modes array for the given key (mode name) */
- ModeButton.prototype._getModeIndex = function _getModeIndex( modeKey ){
- for( var i=0; i<this.options.modes.length; i+=1 ){
- if( this.options.modes[ i ].mode === modeKey ){ return i; }
- }
- throw new Error( 'mode not found: ' + modeKey );
- };
- /** set the current mode to the one with the given index and set button html */
- ModeButton.prototype._setModeByIndex = function _setModeByIndex( index ){
- var newMode = this.options.modes[ index ];
- if( !newMode ){
- throw new Error( 'mode index not found: ' + index );
- }
- this.currModeIndex = index;
- if( newMode.html ){
- this.$element.html( newMode.html );
- }
- return this;
- };
-
- // ---- public interface
- /** get the current mode object (not just the mode name) */
- ModeButton.prototype.currentMode = function currentMode(){
- return this.options.modes[ this.currModeIndex ];
- };
- /** return the mode key of the current mode */
- ModeButton.prototype.current = function current(){
- // sugar for returning mode name
- return this.currentMode().mode;
- };
- /** get the mode with the given modeKey or the current mode if modeKey is undefined */
- ModeButton.prototype.getMode = function getMode( modeKey ){
- if( !modeKey ){ return this.currentMode(); }
- return this.options.modes[( this._getModeIndex( modeKey ) )];
- };
- /** T/F if the button has the given mode */
- ModeButton.prototype.hasMode = function hasMode( modeKey ){
- try {
- return !!this.getMode( modeKey );
- } catch( err ){}
- return false;
- };
- /** set the current mode to the mode with the given name */
- ModeButton.prototype.setMode = function setMode( modeKey ){
- return this._setModeByIndex( this._getModeIndex( modeKey ) );
- };
- /** reset to the initial mode */
- ModeButton.prototype.reset = function reset(){
- this.currModeIndex = 0;
- if( this.options.initialMode ){
- this.currModeIndex = this._getModeIndex( this.options.initialMode );
- }
- return this._setModeByIndex( this.currModeIndex );
- };
- /** manually call the click handler of the given mode */
- ModeButton.prototype.callModeFn = function callModeFn( modeKey ){
- var modeFn = this.getMode( modeKey ).onclick;
- if( modeFn && jQuery.type( modeFn === 'function' ) ){
- // call with the element as context (std jquery pattern)
- return modeFn.call( this.$element.get(0) );
- }
- return undefined;
- };
-
- // as jq plugin
- jQuery.fn.extend({
- modeButton : function $modeButton( options ){
- if( !this.size() ){ return this; }
-
- //TODO: does map still work with jq multi selection (i.e. $( '.class-for-many-btns' ).modeButton)?
- if( jQuery.type( options ) === 'object' ){
- return this.map( function(){
- var $this = $( this );
- $this.data( 'mode-button', new ModeButton( $this, options ) );
- return this;
- });
- }
-
- var $first = $( this[0] ),
- button = $first.data( 'mode-button' );
-
- if( !button ){
- throw new Error( 'modeButton needs an options object or string name of a function' );
- }
-
- if( button && jQuery.type( options ) === 'string' ){
- var fnName = options;
- if( button && jQuery.type( button[ fnName ] ) === 'function' ){
- return button[ fnName ].apply( button, jQuery.makeArray( arguments ).slice( 1 ) );
- }
- }
- return button;
- }
- });
-}());
diff -r 0fb0c56af3cf25bb8c3bb366d34c6aedcbb9df14 -r 8e98c3d9b9a8bc3cabff60c67367fbaf5b328320 static/scripts/packed/jq-plugins/ui/mode-button.js
--- /dev/null
+++ b/static/scripts/packed/jq-plugins/ui/mode-button.js
@@ -0,0 +1,1 @@
+(function(a){if(typeof define==="function"&&define.amd){define([],a)}else{a(jQuery)}}(function(){function c(o,n){this.currModeIndex=0;return this._init(o,n)}c.prototype.DATA_KEY="mode-button";c.prototype.defaults={switchModesOnClick:true};c.prototype._init=function j(o,n){n=n||{};this.$element=$(o);this.options=$.extend(true,{},this.defaults,n);if(!n.modes){throw new Error('ModeButton requires a "modes" array')}var q=this;this.$element.click(function p(r){q.callModeFn();if(q.options.switchModesOnClick){q._incModeIndex()}$(this).html(q.options.modes[q.currModeIndex].html)});return this.reset()};c.prototype._incModeIndex=function l(){this.currModeIndex+=1;if(this.currModeIndex>=this.options.modes.length){this.currModeIndex=0}return this};c.prototype._getModeIndex=function f(n){for(var o=0;o<this.options.modes.length;o+=1){if(this.options.modes[o].mode===n){return o}}throw new Error("mode not found: "+n)};c.prototype._setModeByIndex=function m(n){var o=this.options.modes[n];if(!o){throw new Error("mode index not found: "+n)}this.currModeIndex=n;if(o.html){this.$element.html(o.html)}return this};c.prototype.currentMode=function d(){return this.options.modes[this.currModeIndex]};c.prototype.current=function i(){return this.currentMode().mode};c.prototype.getMode=function g(n){if(!n){return this.currentMode()}return this.options.modes[(this._getModeIndex(n))]};c.prototype.hasMode=function b(n){try{return !!this.getMode(n)}catch(o){}return false};c.prototype.setMode=function a(n){return this._setModeByIndex(this._getModeIndex(n))};c.prototype.reset=function h(){this.currModeIndex=0;if(this.options.initialMode){this.currModeIndex=this._getModeIndex(this.options.initialMode)}return this._setModeByIndex(this.currModeIndex)};c.prototype.callModeFn=function e(n){var o=this.getMode(n).onclick;if(o&&$.type(o==="function")){return o.call(this.$element.get(0))}return undefined};$.fn.modeButton=function k(n){if(!this.size()){return this}if($.type(n)==="object"){return this.map(function(){var r=$(this);r.data("mode-button",new c(r,n));return this})}var p=$(this[0]),o=p.data("mode-button");if(!o){throw new Error("modeButton needs an options object or string name of a function")}if(o&&$.type(n)==="string"){var q=n;if(o&&$.type(o[q])==="function"){return o[q].apply(o,$.makeArray(arguments).slice(1))}}return o}}));
\ No newline at end of file
diff -r 0fb0c56af3cf25bb8c3bb366d34c6aedcbb9df14 -r 8e98c3d9b9a8bc3cabff60c67367fbaf5b328320 static/scripts/packed/mvc/history/multi-panel.js
--- a/static/scripts/packed/mvc/history/multi-panel.js
+++ b/static/scripts/packed/mvc/history/multi-panel.js
@@ -1,1 +1,1 @@
-define(["mvc/history/history-model","mvc/history/history-panel-edit","mvc/base-mvc","utils/ajax-queue"],function(d,l,z,a){window.HISTORY_MODEL=d;function g(H,E){E=E||{};if(!(Galaxy&&Galaxy.modal)){return H.copy()}var F=H.get("name"),C="Copy of '"+F+"'";function D(J){if(!J){if(!Galaxy.modal.$("#invalid-title").size()){var I=$("<p/>").attr("id","invalid-title").css({color:"red","margin-top":"8px"}).addClass("bg-danger").text(_l("Please enter a valid history title"));Galaxy.modal.$(".modal-body").append(I)}return false}return J}function G(I){var J=$('<p><span class="fa fa-spinner fa-spin"></span> Copying history...</p>').css("margin-top","8px");Galaxy.modal.$(".modal-body").append(J);H.copy(true,I).fail(function(){alert(_l("History could not be copied. Please contact a Galaxy administrator"))}).always(function(){Galaxy.modal.hide()})}Galaxy.modal.show(_.extend({title:_l("Copying history")+' "'+F+'"',body:$(['<label for="copy-modal-title">',_l("Enter a title for the copied history"),":","</label><br />",'<input id="copy-modal-title" class="form-control" style="width: 100%" value="',C,'" />'].join("")),buttons:{Cancel:function(){Galaxy.modal.hide()},Copy:function(){var I=Galaxy.modal.$("#copy-modal-title").val();if(!D(I)){return}G(I)}}},E));$("#copy-modal-title").focus().select()}var B=Backbone.View.extend(z.LoggableMixin).extend({tagName:"div",className:"history-column flex-column flex-row-container",id:function q(){if(!this.model){return""}return"history-column-"+this.model.get("id")},initialize:function c(C){C=C||{};this.panel=C.panel||this.createPanel(C);this.setUpListeners()},createPanel:function u(D){D=_.extend({model:this.model,dragItems:true},D);var C=new l.HistoryPanelEdit(D);C._renderEmptyMessage=this.__patch_renderEmptyMessage;return C},__patch_renderEmptyMessage:function(E){var D=this,F=_.chain(this.model.get("state_ids")).values().flatten().value().length,C=D.$emptyMessage(E);if(!_.isEmpty(D.hdaViews)){C.hide()}else{if(F&&!this.model.contents.length){C.empty().append($('<span class="fa fa-spinner fa-spin"></span><i>loading datasets...</i>')).show()}else{if(D.searchFor){C.text(D.noneFoundMsg).show()}else{C.text(D.emptyMsg).show()}}}return C},setUpListeners:function f(){var C=this;this.once("rendered",function(){C.trigger("rendered:initial",C)});this.setUpPanelListeners()},setUpPanelListeners:function k(){var C=this;this.listenTo(this.panel,{rendered:function(){C.trigger("rendered",C)}},this)},inView:function(C,D){var F=this.$el.offset().left,E=F+this.$el.width();if(E<C){return false}if(F>D){return false}return true},$panel:function e(){return this.$(".history-panel")},render:function A(D){D=(D!==undefined)?(D):("fast");var C=this.model?this.model.toJSON():{};this.$el.html(this.template(C));this.renderPanel(D);this.setUpBehaviors();return this},setUpBehaviors:function v(){},template:function w(D){D=D||{};var C=['<div class="panel-controls clear flex-row">',this.controlsLeftTemplate(),'<div class="pull-right">','<button class="delete-history btn btn-default">',D.deleted?_l("Undelete"):_l("Delete"),"</button>",'<button class="copy-history btn btn-default">',_l("Copy"),"</button>","</div>","</div>",'<div class="inner flex-row flex-column-container">','<div id="history-',D.id,'" class="history-column history-panel flex-column"></div>',"</div>"].join("");return $(C)},controlsLeftTemplate:function(){return(this.currentHistory)?['<div class="pull-left">','<button class="create-new btn btn-default">',_l("Create new"),"</button> ","</div>"].join(""):['<div class="pull-left">','<button class="switch-to btn btn-default">',_l("Switch to"),"</button>","</div>"].join("")},renderPanel:function h(C){C=(C!==undefined)?(C):("fast");this.panel.setElement(this.$panel()).render(C);return this},events:{"click .switch-to.btn":function(){this.model.setAsCurrent()},"click .delete-history.btn":function(){var C=this,D;if(this.model.get("deleted")){D=this.model.undelete()}else{D=this.model._delete()}D.fail(function(G,E,F){alert(_l("Could not delete the history")+":\n"+F)}).done(function(E){C.render()})},"click .copy-history.btn":"copy"},copy:function s(){g(this.model)},toString:function(){return"HistoryPanelColumn("+(this.panel?this.panel:"")+")"}});var m=Backbone.View.extend(z.LoggableMixin).extend({initialize:function c(C){C=C||{};this.log(this+".init",C);if(!C.currentHistoryId){throw new Error(this+" requires a currentHistoryId in the options")}this.currentHistoryId=C.currentHistoryId;this.options={columnWidth:312,borderWidth:1,columnGap:8,headerHeight:29,footerHeight:0,controlsHeight:20};this.order=C.order||"update";this.hdaQueue=new a.NamedAjaxQueue([],false);this.collection=null;this.setCollection(C.histories||[]);this.columnMap={};this.createColumns(C.columnOptions);this.setUpListeners()},setUpListeners:function f(){},setCollection:function y(D){var C=this;C.stopListening(C.collection);C.collection=D;C.sortCollection(C.order,{silent:true});C.setUpCollectionListeners();C.trigger("new-collection",C);return C},setUpCollectionListeners:function(){var C=this,D=C.collection;C.listenTo(D,{add:C.addAsCurrentColumn,"set-as-current":C.setCurrentHistory,"change:deleted":C.handleDeletedHistory,sort:function(){C.renderColumns(0)}})},setCurrentHistory:function p(D){var C=this.columnMap[this.currentHistoryId];if(C){C.currentHistory=false;C.$el.height("")}this.currentHistoryId=D.id;var E=this.columnMap[this.currentHistoryId];E.currentHistory=true;this.sortCollection();multipanel._recalcFirstColumnHeight();return E},handleDeletedHistory:function b(D){if(D.get("deleted")){this.log("handleDeletedHistory",this.collection.includeDeleted,D);var C=this;column=C.columnMap[D.id];if(!column){return}if(column.model.id===this.currentHistoryId){}else{if(!C.collection.includeDeleted){C.removeColumn(column)}}}},sortCollection:function(C,D){C=C||this.order;var E=this.currentHistoryId;switch(C){case"name":this.collection.comparator=function(F){return[F.id!==E,F.get("name").toLowerCase()]};break;case"size":this.collection.comparator=function(F){return[F.id!==E,F.get("size")]};break;default:this.collection.comparator=function(F){return[F.id!==E,Date(F.get("update_time"))]}}this.collection.sort(D);return this.collection},setOrder:function(C){if(["update","name","size"].indexOf(C)===-1){C="update"}this.order=C;this.sortCollection();return this},create:function(C){return this.collection.create({current:true})},createColumns:function r(D){D=D||{};var C=this;this.columnMap={};C.collection.each(function(E,F){var G=C.createColumn(E,D);C.columnMap[E.id]=G})},createColumn:function t(E,C){C=_.extend({},C,{model:E});var D=new B(C);if(E.id===this.currentHistoryId){D.currentHistory=true}this.setUpColumnListeners(D);return D},sortedFilteredColumns:function(C){C=C||this.filters;if(!C||!C.length){return this.sortedColumns()}var D=this;return D.sortedColumns().filter(function(G,F){var E=G.currentHistory||_.every(C.map(function(H){return H.call(G)}));return E})},sortedColumns:function(){var D=this;var C=this.collection.map(function(F,E){return D.columnMap[F.id]});return C},addColumn:function o(E,C){C=C!==undefined?C:true;var D=this.createColumn(E);this.columnMap[E.id]=D;if(C){this.renderColumns()}return D},addAsCurrentColumn:function o(E){var D=this,C=this.addColumn(E,false);this.setCurrentHistory(E);C.once("rendered",function(){D.queueHdaFetch(C)});return C},removeColumn:function x(E,D){D=D!==undefined?D:true;this.log("removeColumn",E);if(!E){return}var F=this,C=this.options.columnWidth+this.options.columnGap;E.$el.fadeOut("fast",function(){if(D){$(this).remove();F.$(".middle").width(F.$(".middle").width()-C);F.checkColumnsInView();F._recalcFirstColumnHeight()}F.stopListening(E.panel);F.stopListening(E);delete F.columnMap[E.model.id];E.remove()})},setUpColumnListeners:function n(C){var D=this;D.listenTo(C,{"in-view":D.queueHdaFetch});D.listenTo(C.panel,{"view:draggable:dragstart":function(H,F,E,G){D._dropData=JSON.parse(H.dataTransfer.getData("text"));D.currentColumnDropTargetOn()},"view:draggable:dragend":function(H,F,E,G){D._dropData=null;D.currentColumnDropTargetOff()},"droptarget:drop":function(G,H,F){var I=D._dropData.filter(function(J){return(_.isObject(J)&&J.id&&J.model_class==="HistoryDatasetAssociation")});D._dropData=null;var E=new a.NamedAjaxQueue();I.forEach(function(J){E.add({name:"copy-"+J.id,fn:function(){return F.model.contents.copy(J.id)}})});E.start();E.done(function(J){F.model.fetch()})}})},columnMapLength:function(){return Object.keys(this.columnMap).length},render:function A(D){D=D!==undefined?D:this.fxSpeed;var C=this;C.log(C+".render");C.$el.html(C.template(C.options));C.renderColumns(D);C.setUpBehaviors();C.trigger("rendered",C);return C},template:function w(C){C=C||{};var D=[];if(this.options.headerHeight){D=D.concat(['<div class="loading-overlay flex-row"><div class="loading-overlay-message">loading...</div></div>','<div class="header flex-column-container">','<div class="header-control header-control-left flex-column">','<button class="done btn btn-default">',_l("Done"),"</button>",'<button class="include-deleted btn btn-default"></button>','<div class="order btn-group">','<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">',_l("Order histories by")+'... <span class="caret"></span>',"</button>",'<ul class="dropdown-menu" role="menu">','<li><a href="javascript:void(0);" class="order-update">',_l("Time of last update"),"</a></li>",'<li><a href="javascript:void(0);" class="order-name">',_l("Name"),"</a></li>",'<li><a href="javascript:void(0);" class="order-size">',_l("Size"),"</a></li>","</ul>","</div>",'<div id="search-histories" class="header-search"></div>',"</div>",'<div class="header-control header-control-center flex-column">','<div class="header-info">',"</div>","</div>",'<div class="header-control header-control-right flex-column">','<div id="search-datasets" class="header-search"></div>','<button id="toggle-deleted" class="btn btn-default">',_l("Include deleted datasets"),"</button>",'<button id="toggle-hidden" class="btn btn-default">',_l("Include hidden datasets"),"</button>","</div>","</div>"])}D=D.concat(['<div class="outer-middle flex-row flex-row-container">','<div class="middle flex-column-container flex-row"></div>',"</div>",'<div class="footer flex-column-container">',"</div>"]);return $(D.join(""))},renderColumns:function j(F){F=F!==undefined?F:this.fxSpeed;var E=this,C=E.sortedFilteredColumns();E.$(".middle").width(C.length*(this.options.columnWidth+this.options.columnGap)+this.options.columnGap+16);var D=E.$(".middle");D.empty();C.forEach(function(H,G){H.$el.appendTo(D);H.delegateEvents();E.renderColumn(H,F)});if(this.searchFor&&C.length<=1){}else{E.checkColumnsInView();this._recalcFirstColumnHeight()}return C},renderColumn:function(C,D){D=D!==undefined?D:this.fxSpeed;return C.render(D)},queueHdaFetch:function i(E){if(E.model.contents.length===0&&!E.model.get("empty")){var C={},D=_.values(E.panel.storage.get("expandedIds")).join();if(D){C.dataset_details=D}this.hdaQueue.add({name:E.model.id,fn:function(){var F=E.model.contents.fetch({data:C,silent:true});return F.done(function(G){E.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},queueHdaFetchDetails:function(C){if((C.model.contents.length===0&&!C.model.get("empty"))||(!C.model.contents.haveDetails())){this.hdaQueue.add({name:C.model.id,fn:function(){var D=C.model.contents.fetch({data:{details:"all"},silent:true});return D.done(function(E){C.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},renderInfo:function(C){this.$(".header .header-info").text(C)},events:{"click .done.btn":function(){window.location="/"},"click .create-new.btn":"create","click .order .order-update":function(C){this.setOrder("update")},"click .order .order-name":function(C){this.setOrder("name")},"click .order .order-size":function(C){this.setOrder("size")}},includeDeletedHistories:function(){window.location+=(/\?/.test(window.location.toString()))?("&"):("?")+"include_deleted_histories=True"},excludeDeletedHistories:function(){window.location=window.location.toString().replace(/[&\?]include_deleted_histories=True/g,"")},setUpBehaviors:function(){var D=this;D.$(".include-deleted").modeButton({initialMode:this.collection.includeDeleted?"exclude":"include",switchModesOnClick:false,modes:[{mode:"include",html:_l("Include deleted histories"),onclick:_.bind(D.includeDeletedHistories,D)},{mode:"exclude",html:_l("Exclude deleted histories"),onclick:_.bind(D.excludeDeletedHistories,D)}]});D.$("#search-histories").searchInput({name:"search-histories",placeholder:_l("search histories"),onsearch:function(E){D.searchFor=E;D.filters=[function(){return this.model.matchesAll(D.searchFor)}];D.renderColumns(0)},onclear:function(E){D.searchFor=null;D.filters=[];D.renderColumns(0)}});D.$("#search-datasets").searchInput({name:"search-datasets",placeholder:_l("search all datasets"),onfirstsearch:function(E){D.hdaQueue.clear();D.$("#search-datasets").searchInput("toggle-loading");D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E);D.queueHdaFetchDetails(F)});D.hdaQueue.progress(function(F){D.renderInfo([_l("searching"),(F.curr+1),_l("of"),F.total].join(" "))});D.hdaQueue.deferred.done(function(){D.renderInfo("");D.$("#search-datasets").searchInput("toggle-loading")})},onsearch:function(E){D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E)})},onclear:function(E){D.searchFor=null;D.sortedFilteredColumns().forEach(function(F){F.panel.clearSearch()})}});D.$("#toggle-deleted").modeButton({initialMode:"include",modes:[{mode:"exclude",html:_l("Exclude deleted datasets")},{mode:"include",html:_l("Include deleted datasets")}]}).click(function(){var E=$(this).modeButton("getMode").mode==="exclude";D.sortedFilteredColumns().forEach(function(G,F){_.delay(function(){G.panel.toggleShowDeleted(E,false)},F*200)})});D.$("#toggle-hidden").modeButton({initialMode:"include",modes:[{mode:"exclude",html:_l("Exclude hidden datasets")},{mode:"include",html:_l("Include hidden datasets")}]}).click(function(){var E=$(this).modeButton("getMode").mode==="exclude";D.sortedFilteredColumns().forEach(function(G,F){_.delay(function(){G.panel.toggleShowHidden(E,false)},F*200)})});$(window).resize(function(){D._recalcFirstColumnHeight()});var C=_.debounce(_.bind(this.checkColumnsInView,this),100);this.$(".middle").parent().scroll(C)},_recalcFirstColumnHeight:function(){var C=this.$(".history-column").first(),E=this.$(".middle").height(),D=C.find(".panel-controls").height();C.height(E).find(".inner").height(E-D)},_viewport:function(){var C=this.$(".middle").parent().offset().left;return{left:C,right:C+this.$(".middle").parent().width()}},columnsInView:function(){var C=this._viewport();return this.sortedFilteredColumns().filter(function(D){return D.currentHistory||D.inView(C.left,C.right)})},checkColumnsInView:function(){this.columnsInView().forEach(function(C){C.trigger("in-view",C)})},currentColumnDropTargetOn:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=function(D){};C.panel.dropTargetOn()},currentColumnDropTargetOff:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=l.HistoryPanelEdit.prototype.dataDrop;C.panel.dropTargetOff()},toString:function(){return"MultiPanelColumns("+(this.columns?this.columns.length:0)+")"}});return{MultiPanelColumns:m}});
\ No newline at end of file
+define(["mvc/history/history-model","mvc/history/history-panel-edit","mvc/base-mvc","utils/ajax-queue","jq-plugins/ui/mode-button"],function(d,l,z,a){window.HISTORY_MODEL=d;function g(H,E){E=E||{};if(!(Galaxy&&Galaxy.modal)){return H.copy()}var F=H.get("name"),C="Copy of '"+F+"'";function D(J){if(!J){if(!Galaxy.modal.$("#invalid-title").size()){var I=$("<p/>").attr("id","invalid-title").css({color:"red","margin-top":"8px"}).addClass("bg-danger").text(_l("Please enter a valid history title"));Galaxy.modal.$(".modal-body").append(I)}return false}return J}function G(I){var J=$('<p><span class="fa fa-spinner fa-spin"></span> Copying history...</p>').css("margin-top","8px");Galaxy.modal.$(".modal-body").append(J);H.copy(true,I).fail(function(){alert(_l("History could not be copied. Please contact a Galaxy administrator"))}).always(function(){Galaxy.modal.hide()})}Galaxy.modal.show(_.extend({title:_l("Copying history")+' "'+F+'"',body:$(['<label for="copy-modal-title">',_l("Enter a title for the copied history"),":","</label><br />",'<input id="copy-modal-title" class="form-control" style="width: 100%" value="',C,'" />'].join("")),buttons:{Cancel:function(){Galaxy.modal.hide()},Copy:function(){var I=Galaxy.modal.$("#copy-modal-title").val();if(!D(I)){return}G(I)}}},E));$("#copy-modal-title").focus().select()}var B=Backbone.View.extend(z.LoggableMixin).extend({tagName:"div",className:"history-column flex-column flex-row-container",id:function q(){if(!this.model){return""}return"history-column-"+this.model.get("id")},initialize:function c(C){C=C||{};this.panel=C.panel||this.createPanel(C);this.setUpListeners()},createPanel:function u(D){D=_.extend({model:this.model,dragItems:true},D);var C=new l.HistoryPanelEdit(D);C._renderEmptyMessage=this.__patch_renderEmptyMessage;return C},__patch_renderEmptyMessage:function(E){var D=this,F=_.chain(this.model.get("state_ids")).values().flatten().value().length,C=D.$emptyMessage(E);if(!_.isEmpty(D.hdaViews)){C.hide()}else{if(F&&!this.model.contents.length){C.empty().append($('<span class="fa fa-spinner fa-spin"></span><i>loading datasets...</i>')).show()}else{if(D.searchFor){C.text(D.noneFoundMsg).show()}else{C.text(D.emptyMsg).show()}}}return C},setUpListeners:function f(){var C=this;this.once("rendered",function(){C.trigger("rendered:initial",C)});this.setUpPanelListeners()},setUpPanelListeners:function k(){var C=this;this.listenTo(this.panel,{rendered:function(){C.trigger("rendered",C)}},this)},inView:function(C,D){var F=this.$el.offset().left,E=F+this.$el.width();if(E<C){return false}if(F>D){return false}return true},$panel:function e(){return this.$(".history-panel")},render:function A(D){D=(D!==undefined)?(D):("fast");var C=this.model?this.model.toJSON():{};this.$el.html(this.template(C));this.renderPanel(D);this.setUpBehaviors();return this},setUpBehaviors:function v(){},template:function w(D){D=D||{};var C=['<div class="panel-controls clear flex-row">',this.controlsLeftTemplate(),'<div class="pull-right">','<button class="delete-history btn btn-default">',D.deleted?_l("Undelete"):_l("Delete"),"</button>",'<button class="copy-history btn btn-default">',_l("Copy"),"</button>","</div>","</div>",'<div class="inner flex-row flex-column-container">','<div id="history-',D.id,'" class="history-column history-panel flex-column"></div>',"</div>"].join("");return $(C)},controlsLeftTemplate:function(){return(this.currentHistory)?['<div class="pull-left">','<button class="create-new btn btn-default">',_l("Create new"),"</button> ","</div>"].join(""):['<div class="pull-left">','<button class="switch-to btn btn-default">',_l("Switch to"),"</button>","</div>"].join("")},renderPanel:function h(C){C=(C!==undefined)?(C):("fast");this.panel.setElement(this.$panel()).render(C);return this},events:{"click .switch-to.btn":function(){this.model.setAsCurrent()},"click .delete-history.btn":function(){var C=this,D;if(this.model.get("deleted")){D=this.model.undelete()}else{D=this.model._delete()}D.fail(function(G,E,F){alert(_l("Could not delete the history")+":\n"+F)}).done(function(E){C.render()})},"click .copy-history.btn":"copy"},copy:function s(){g(this.model)},toString:function(){return"HistoryPanelColumn("+(this.panel?this.panel:"")+")"}});var m=Backbone.View.extend(z.LoggableMixin).extend({initialize:function c(C){C=C||{};this.log(this+".init",C);if(!C.currentHistoryId){throw new Error(this+" requires a currentHistoryId in the options")}this.currentHistoryId=C.currentHistoryId;this.options={columnWidth:312,borderWidth:1,columnGap:8,headerHeight:29,footerHeight:0,controlsHeight:20};this.order=C.order||"update";this.hdaQueue=new a.NamedAjaxQueue([],false);this.collection=null;this.setCollection(C.histories||[]);this.columnMap={};this.createColumns(C.columnOptions);this.setUpListeners()},setUpListeners:function f(){},setCollection:function y(D){var C=this;C.stopListening(C.collection);C.collection=D;C.sortCollection(C.order,{silent:true});C.setUpCollectionListeners();C.trigger("new-collection",C);return C},setUpCollectionListeners:function(){var C=this,D=C.collection;C.listenTo(D,{add:C.addAsCurrentColumn,"set-as-current":C.setCurrentHistory,"change:deleted":C.handleDeletedHistory,sort:function(){C.renderColumns(0)}})},setCurrentHistory:function p(D){var C=this.columnMap[this.currentHistoryId];if(C){C.currentHistory=false;C.$el.height("")}this.currentHistoryId=D.id;var E=this.columnMap[this.currentHistoryId];E.currentHistory=true;this.sortCollection();multipanel._recalcFirstColumnHeight();return E},handleDeletedHistory:function b(D){if(D.get("deleted")){this.log("handleDeletedHistory",this.collection.includeDeleted,D);var C=this;column=C.columnMap[D.id];if(!column){return}if(column.model.id===this.currentHistoryId){}else{if(!C.collection.includeDeleted){C.removeColumn(column)}}}},sortCollection:function(C,D){C=C||this.order;var E=this.currentHistoryId;switch(C){case"name":this.collection.comparator=function(F){return[F.id!==E,F.get("name").toLowerCase()]};break;case"size":this.collection.comparator=function(F){return[F.id!==E,F.get("size")]};break;default:this.collection.comparator=function(F){return[F.id!==E,Date(F.get("update_time"))]}}this.collection.sort(D);return this.collection},setOrder:function(C){if(["update","name","size"].indexOf(C)===-1){C="update"}this.order=C;this.sortCollection();return this},create:function(C){return this.collection.create({current:true})},createColumns:function r(D){D=D||{};var C=this;this.columnMap={};C.collection.each(function(E,F){var G=C.createColumn(E,D);C.columnMap[E.id]=G})},createColumn:function t(E,C){C=_.extend({},C,{model:E});var D=new B(C);if(E.id===this.currentHistoryId){D.currentHistory=true}this.setUpColumnListeners(D);return D},sortedFilteredColumns:function(C){C=C||this.filters;if(!C||!C.length){return this.sortedColumns()}var D=this;return D.sortedColumns().filter(function(G,F){var E=G.currentHistory||_.every(C.map(function(H){return H.call(G)}));return E})},sortedColumns:function(){var D=this;var C=this.collection.map(function(F,E){return D.columnMap[F.id]});return C},addColumn:function o(E,C){C=C!==undefined?C:true;var D=this.createColumn(E);this.columnMap[E.id]=D;if(C){this.renderColumns()}return D},addAsCurrentColumn:function o(E){var D=this,C=this.addColumn(E,false);this.setCurrentHistory(E);C.once("rendered",function(){D.queueHdaFetch(C)});return C},removeColumn:function x(E,D){D=D!==undefined?D:true;this.log("removeColumn",E);if(!E){return}var F=this,C=this.options.columnWidth+this.options.columnGap;E.$el.fadeOut("fast",function(){if(D){$(this).remove();F.$(".middle").width(F.$(".middle").width()-C);F.checkColumnsInView();F._recalcFirstColumnHeight()}F.stopListening(E.panel);F.stopListening(E);delete F.columnMap[E.model.id];E.remove()})},setUpColumnListeners:function n(C){var D=this;D.listenTo(C,{"in-view":D.queueHdaFetch});D.listenTo(C.panel,{"view:draggable:dragstart":function(H,F,E,G){D._dropData=JSON.parse(H.dataTransfer.getData("text"));D.currentColumnDropTargetOn()},"view:draggable:dragend":function(H,F,E,G){D._dropData=null;D.currentColumnDropTargetOff()},"droptarget:drop":function(G,H,F){var I=D._dropData.filter(function(J){return(_.isObject(J)&&J.id&&J.model_class==="HistoryDatasetAssociation")});D._dropData=null;var E=new a.NamedAjaxQueue();I.forEach(function(J){E.add({name:"copy-"+J.id,fn:function(){return F.model.contents.copy(J.id)}})});E.start();E.done(function(J){F.model.fetch()})}})},columnMapLength:function(){return Object.keys(this.columnMap).length},render:function A(D){D=D!==undefined?D:this.fxSpeed;var C=this;C.log(C+".render");C.$el.html(C.template(C.options));C.renderColumns(D);C.setUpBehaviors();C.trigger("rendered",C);return C},template:function w(C){C=C||{};var D=[];if(this.options.headerHeight){D=D.concat(['<div class="loading-overlay flex-row"><div class="loading-overlay-message">loading...</div></div>','<div class="header flex-column-container">','<div class="header-control header-control-left flex-column">','<button class="done btn btn-default">',_l("Done"),"</button>",'<button class="include-deleted btn btn-default"></button>','<div class="order btn-group">','<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">',_l("Order histories by")+'... <span class="caret"></span>',"</button>",'<ul class="dropdown-menu" role="menu">','<li><a href="javascript:void(0);" class="order-update">',_l("Time of last update"),"</a></li>",'<li><a href="javascript:void(0);" class="order-name">',_l("Name"),"</a></li>",'<li><a href="javascript:void(0);" class="order-size">',_l("Size"),"</a></li>","</ul>","</div>",'<div id="search-histories" class="header-search"></div>',"</div>",'<div class="header-control header-control-center flex-column">','<div class="header-info">',"</div>","</div>",'<div class="header-control header-control-right flex-column">','<div id="search-datasets" class="header-search"></div>','<button id="toggle-deleted" class="btn btn-default">',_l("Include deleted datasets"),"</button>",'<button id="toggle-hidden" class="btn btn-default">',_l("Include hidden datasets"),"</button>","</div>","</div>"])}D=D.concat(['<div class="outer-middle flex-row flex-row-container">','<div class="middle flex-column-container flex-row"></div>',"</div>",'<div class="footer flex-column-container">',"</div>"]);return $(D.join(""))},renderColumns:function j(F){F=F!==undefined?F:this.fxSpeed;var E=this,C=E.sortedFilteredColumns();E.$(".middle").width(C.length*(this.options.columnWidth+this.options.columnGap)+this.options.columnGap+16);var D=E.$(".middle");D.empty();C.forEach(function(H,G){H.$el.appendTo(D);H.delegateEvents();E.renderColumn(H,F)});if(this.searchFor&&C.length<=1){}else{E.checkColumnsInView();this._recalcFirstColumnHeight()}return C},renderColumn:function(C,D){D=D!==undefined?D:this.fxSpeed;return C.render(D)},queueHdaFetch:function i(E){if(E.model.contents.length===0&&!E.model.get("empty")){var C={},D=_.values(E.panel.storage.get("expandedIds")).join();if(D){C.dataset_details=D}this.hdaQueue.add({name:E.model.id,fn:function(){var F=E.model.contents.fetch({data:C,silent:true});return F.done(function(G){E.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},queueHdaFetchDetails:function(C){if((C.model.contents.length===0&&!C.model.get("empty"))||(!C.model.contents.haveDetails())){this.hdaQueue.add({name:C.model.id,fn:function(){var D=C.model.contents.fetch({data:{details:"all"},silent:true});return D.done(function(E){C.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},renderInfo:function(C){this.$(".header .header-info").text(C)},events:{"click .done.btn":function(){window.location="/"},"click .create-new.btn":"create","click .order .order-update":function(C){this.setOrder("update")},"click .order .order-name":function(C){this.setOrder("name")},"click .order .order-size":function(C){this.setOrder("size")}},includeDeletedHistories:function(){window.location+=(/\?/.test(window.location.toString()))?("&"):("?")+"include_deleted_histories=True"},excludeDeletedHistories:function(){window.location=window.location.toString().replace(/[&\?]include_deleted_histories=True/g,"")},setUpBehaviors:function(){var D=this;D.$(".include-deleted").modeButton({initialMode:this.collection.includeDeleted?"exclude":"include",switchModesOnClick:false,modes:[{mode:"include",html:_l("Include deleted histories"),onclick:_.bind(D.includeDeletedHistories,D)},{mode:"exclude",html:_l("Exclude deleted histories"),onclick:_.bind(D.excludeDeletedHistories,D)}]});D.$("#search-histories").searchInput({name:"search-histories",placeholder:_l("search histories"),onsearch:function(E){D.searchFor=E;D.filters=[function(){return this.model.matchesAll(D.searchFor)}];D.renderColumns(0)},onclear:function(E){D.searchFor=null;D.filters=[];D.renderColumns(0)}});D.$("#search-datasets").searchInput({name:"search-datasets",placeholder:_l("search all datasets"),onfirstsearch:function(E){D.hdaQueue.clear();D.$("#search-datasets").searchInput("toggle-loading");D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E);D.queueHdaFetchDetails(F)});D.hdaQueue.progress(function(F){D.renderInfo([_l("searching"),(F.curr+1),_l("of"),F.total].join(" "))});D.hdaQueue.deferred.done(function(){D.renderInfo("");D.$("#search-datasets").searchInput("toggle-loading")})},onsearch:function(E){D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E)})},onclear:function(E){D.searchFor=null;D.sortedFilteredColumns().forEach(function(F){F.panel.clearSearch()})}});D.$("#toggle-deleted").modeButton({initialMode:"include",modes:[{mode:"exclude",html:_l("Exclude deleted datasets")},{mode:"include",html:_l("Include deleted datasets")}]}).click(function(){var E=$(this).modeButton("getMode").mode==="exclude";D.sortedFilteredColumns().forEach(function(G,F){_.delay(function(){G.panel.toggleShowDeleted(E,false)},F*200)})});D.$("#toggle-hidden").modeButton({initialMode:"include",modes:[{mode:"exclude",html:_l("Exclude hidden datasets")},{mode:"include",html:_l("Include hidden datasets")}]}).click(function(){var E=$(this).modeButton("getMode").mode==="exclude";D.sortedFilteredColumns().forEach(function(G,F){_.delay(function(){G.panel.toggleShowHidden(E,false)},F*200)})});$(window).resize(function(){D._recalcFirstColumnHeight()});var C=_.debounce(_.bind(this.checkColumnsInView,this),100);this.$(".middle").parent().scroll(C)},_recalcFirstColumnHeight:function(){var C=this.$(".history-column").first(),E=this.$(".middle").height(),D=C.find(".panel-controls").height();C.height(E).find(".inner").height(E-D)},_viewport:function(){var C=this.$(".middle").parent().offset().left;return{left:C,right:C+this.$(".middle").parent().width()}},columnsInView:function(){var C=this._viewport();return this.sortedFilteredColumns().filter(function(D){return D.currentHistory||D.inView(C.left,C.right)})},checkColumnsInView:function(){this.columnsInView().forEach(function(C){C.trigger("in-view",C)})},currentColumnDropTargetOn:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=function(D){};C.panel.dropTargetOn()},currentColumnDropTargetOff:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=l.HistoryPanelEdit.prototype.dataDrop;C.panel.dropTargetOff()},toString:function(){return"MultiPanelColumns("+(this.columns?this.columns.length:0)+")"}});return{MultiPanelColumns:m}});
\ No newline at end of file
diff -r 0fb0c56af3cf25bb8c3bb366d34c6aedcbb9df14 -r 8e98c3d9b9a8bc3cabff60c67367fbaf5b328320 static/scripts/packed/mvc/ui.js
--- a/static/scripts/packed/mvc/ui.js
+++ b/static/scripts/packed/mvc/ui.js
@@ -1,1 +1,1 @@
-var IconButton=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,is_menu_button:true,id:null,href:null,target:null,enabled:true,visible:true,tooltip_config:{}}});var IconButtonView=Backbone.View.extend({initialize:function(){this.model.attributes.tooltip_config={placement:"bottom"};this.model.bind("change",this.render,this)},render:function(){this.$el.tooltip("hide");var a=this.template(this.model.toJSON());a.tooltip(this.model.get("tooltip_config"));this.$el.replaceWith(a);this.setElement(a);return this},events:{click:"click"},click:function(a){if(_.isFunction(this.model.get("on_click"))){this.model.get("on_click")(a);return false}return true},template:function(b){var a='title="'+b.title+'" class="icon-button';if(b.is_menu_button){a+=" menu-button"}a+=" "+b.icon_class;if(!b.enabled){a+="_disabled"}a+='"';if(b.id){a+=' id="'+b.id+'"'}a+=' href="'+b.href+'"';if(b.target){a+=' target="'+b.target+'"'}if(!b.visible){a+=' style="display: none;"'}if(b.enabled){a="<a "+a+"/>"}else{a="<span "+a+"/>"}return $(a)}});var IconButtonCollection=Backbone.Collection.extend({model:IconButton});var IconButtonMenuView=Backbone.View.extend({tagName:"div",initialize:function(){this.render()},render:function(){var a=this;this.collection.each(function(d){var b=$("<a/>").attr("href","javascript:void(0)").attr("title",d.attributes.title).addClass("icon-button menu-button").addClass(d.attributes.icon_class).appendTo(a.$el).click(d.attributes.on_click);if(d.attributes.tooltip_config){b.tooltip(d.attributes.tooltip_config)}var c=d.get("options");if(c){make_popupmenu(b,c)}});return this}});var create_icon_buttons_menu=function(b,a){if(!a){a={}}var c=new IconButtonCollection(_.map(b,function(d){return new IconButton(_.extend(d,a))}));return new IconButtonMenuView({collection:c})};var Grid=Backbone.Collection.extend({});var GridView=Backbone.View.extend({});var PopupMenu=Backbone.View.extend({initialize:function(b,a){this.$button=b;if(!this.$button.size()){this.$button=$("<div/>")}this.options=a||[];var c=this;this.$button.click(function(d){$(".popmenu-wrapper").remove();c._renderAndShow(d);return false})},_renderAndShow:function(a){this.render();this.$el.appendTo("body").css(this._getShownPosition(a)).show();this._setUpCloseBehavior()},render:function(){this.$el.addClass("popmenu-wrapper").hide().css({position:"absolute"}).html(this.template(this.$button.attr("id"),this.options));if(this.options.length){var a=this;this.$el.find("li").each(function(c,b){var d=a.options[c];if(d.func){$(this).children("a.popupmenu-option").click(function(e){d.func.call(a,e,d)})}})}return this},template:function(b,a){return['<ul id="',b,'-menu" class="dropdown-menu">',this._templateOptions(a),"</ul>"].join("")},_templateOptions:function(a){if(!a.length){return"<li>(no options)</li>"}return _.map(a,function(d){if(d.divider){return'<li class="divider"></li>'}else{if(d.header){return['<li class="head"><a href="javascript:void(0);">',d.html,"</a></li>"].join("")}}var c=d.href||"javascript:void(0);",e=(d.target)?(' target="'+d.target+'"'):(""),b=(d.checked)?('<span class="fa fa-check"></span>'):("");return['<li><a class="popupmenu-option" href="',c,'"',e,">",b,d.html,"</a></li>"].join("")}).join("")},_getShownPosition:function(b){var c=this.$el.width();var a=b.pageX-c/2;a=Math.min(a,$(document).scrollLeft()+$(window).width()-c-5);a=Math.max(a,$(document).scrollLeft()+5);return{top:b.pageY,left:a}},_setUpCloseBehavior:function(){var c=this;function a(e){$(document).off("click.close_popup");if(window.parent!==window){try{$(window.parent.document).off("click.close_popup")}catch(d){}}else{try{$("iframe#galaxy_main").contents().off("click.close_popup")}catch(d){}}c.remove()}$("html").one("click.close_popup",a);if(window.parent!==window){try{$(window.parent.document).find("html").one("click.close_popup",a)}catch(b){}}else{try{$("iframe#galaxy_main").contents().one("click.close_popup",a)}catch(b){}}},addItem:function(b,a){a=(a>=0)?a:this.options.length;this.options.splice(a,0,b);return this},removeItem:function(a){if(a>=0){this.options.splice(a,1)}return this},findIndexByHtml:function(b){for(var a=0;a<this.options.length;a++){if(_.has(this.options[a],"html")&&(this.options[a].html===b)){return a}}return null},findItemByHtml:function(a){return this.options[(this.findIndexByHtml(a))]},toString:function(){return"PopupMenu"}});PopupMenu.create=function _create(b,a){return new PopupMenu(b,a)};PopupMenu.make_popupmenu=function(b,c){var a=[];_.each(c,function(f,d){var e={html:d};if(f===null){e.header=true}else{if(jQuery.type(f)==="function"){e.func=f}}a.push(e)});return new PopupMenu($(b),a)};PopupMenu.convertLinksToOptions=function(c,a){c=$(c);a=a||"a";var b=[];c.find(a).each(function(g,e){var f={},d=$(g);f.html=d.text();if(d.attr("href")){var j=d.attr("href"),k=d.attr("target"),h=d.attr("confirm");f.func=function(){if((h)&&(!confirm(h))){return}switch(k){case"_parent":window.parent.location=j;break;case"_top":window.top.location=j;break;default:window.location=j}}}b.push(f)});return b};PopupMenu.fromExistingDom=function(d,c,a){d=$(d);c=$(c);var b=PopupMenu.convertLinksToOptions(c,a);c.remove();return new PopupMenu(d,b)};PopupMenu.make_popup_menus=function(c,b,d){c=c||document;b=b||"div[popupmenu]";d=d||function(e,f){return"#"+e.attr("popupmenu")};var a=[];$(c).find(b).each(function(){var e=$(this),f=$(c).find(d(e,c));a.push(PopupMenu.fromDom(f,e));f.addClass("popup")});return a};var faIconButton=function(a){a=a||{};a.tooltipConfig=a.tooltipConfig||{placement:"bottom"};a.classes=["icon-btn"].concat(a.classes||[]);if(a.disabled){a.classes.push("disabled")}var b=['<a class="',a.classes.join(" "),'"',((a.title)?(' title="'+a.title+'"'):("")),((!a.disabled&&a.target)?(' target="'+a.target+'"'):("")),' href="',((!a.disabled&&a.href)?(a.href):("javascript:void(0);")),'">','<span class="fa ',a.faIcon,'"></span>',"</a>"].join("");var c=$(b).tooltip(a.tooltipConfig);if(_.isFunction(a.onclick)){c.click(a.onclick)}return c};function LoadingIndicator(a,c){var b=this;c=jQuery.extend({cover:false},c||{});function d(){var e=['<div class="loading-indicator">','<div class="loading-indicator-text">','<span class="fa fa-spinner fa-spin fa-lg"></span>','<span class="loading-indicator-message">loading...</span>',"</div>","</div>"].join("\n");var g=$(e).hide().css(c.css||{position:"fixed"}),f=g.children(".loading-indicator-text");if(c.cover){g.css({"z-index":2,top:a.css("top"),bottom:a.css("bottom"),left:a.css("left"),right:a.css("right"),opacity:0.5,"background-color":"white","text-align":"center"});f=g.children(".loading-indicator-text").css({"margin-top":"20px"})}else{f=g.children(".loading-indicator-text").css({margin:"12px 0px 0px 10px",opacity:"0.85",color:"grey"});f.children(".loading-indicator-message").css({margin:"0px 8px 0px 0px","font-style":"italic"})}return g}b.show=function(f,e,g){f=f||"loading...";e=e||"fast";a.parent().find(".loading-indicator").remove();b.$indicator=d().insertBefore(a);b.message(f);b.$indicator.fadeIn(e,g);return b};b.message=function(e){b.$indicator.find("i").text(e)};b.hide=function(e,f){e=e||"fast";if(b.$indicator&&b.$indicator.size()){b.$indicator.fadeOut(e,function(){b.$indicator.remove();if(f){f()}})}else{if(f){f()}}return b};return b}(function(){var b=window._l||function(d){return d};function a(k,q){var e=27,n=13,d=$(k),f=true,h={initialVal:"",name:"search",placeholder:"search",classes:"",onclear:function(){},onfirstsearch:null,onsearch:function(r){},minSearchLen:0,escWillClear:true,oninit:function(){}};function j(r){var s=$(this).parent().children("input");s.focus().val("").trigger("clear:searchInput");q.onclear()}function p(s,r){$(this).trigger("search:searchInput",r);if(typeof q.onfirstsearch==="function"&&f){f=false;q.onfirstsearch(r)}else{q.onsearch(r)}}function g(){return['<input type="text" name="',q.name,'" placeholder="',q.placeholder,'" ','class="search-query ',q.classes,'" ',"/>"].join("")}function m(){return $(g()).focus(function(r){$(this).select()}).keyup(function(s){s.preventDefault();s.stopPropagation();if(!$(this).val()){$(this).blur()}if(s.which===e&&q.escWillClear){j.call(this,s)}else{var r=$(this).val();if((s.which===n)||(q.minSearchLen&&r.length>=q.minSearchLen)){p.call(this,s,r)}else{if(!r.length){j.call(this,s)}}}}).on("change",function(r){p.call(this,r,$(this).val())}).val(q.initialVal)}function l(){return $(['<span class="search-clear fa fa-times-circle" ','title="',b("clear search (esc)"),'"></span>'].join("")).tooltip({placement:"bottom"}).click(function(r){j.call(this,r)})}function o(){return $(['<span class="search-loading fa fa-spinner fa-spin" ','title="',b("loading..."),'"></span>'].join("")).hide().tooltip({placement:"bottom"})}function i(){d.find(".search-loading").toggle();d.find(".search-clear").toggle()}if(jQuery.type(q)==="string"){if(q==="toggle-loading"){i()}return d}if(jQuery.type(q)==="object"){q=jQuery.extend(true,{},h,q)}return d.addClass("search-input").prepend([m(),l(),o()])}jQuery.fn.extend({searchInput:function c(d){return this.each(function(){return a(this,d)})}})}());(function(){function c(o,n){this.currModeIndex=0;return this._init(o,n)}c.prototype.DATA_KEY="mode-button";c.prototype.defaults={switchModesOnClick:true};c.prototype._init=function j(o,n){n=n||{};this.$element=$(o);this.options=jQuery.extend(true,{},this.defaults,n);if(!n.modes){throw new Error('ModeButton requires a "modes" array')}var q=this;this.$element.click(function p(r){q.callModeFn();if(q.options.switchModesOnClick){q._incModeIndex()}$(this).html(q.options.modes[q.currModeIndex].html)});return this.reset()};c.prototype._incModeIndex=function l(){this.currModeIndex+=1;if(this.currModeIndex>=this.options.modes.length){this.currModeIndex=0}return this};c.prototype._getModeIndex=function f(n){for(var o=0;o<this.options.modes.length;o+=1){if(this.options.modes[o].mode===n){return o}}throw new Error("mode not found: "+n)};c.prototype._setModeByIndex=function m(n){var o=this.options.modes[n];if(!o){throw new Error("mode index not found: "+n)}this.currModeIndex=n;if(o.html){this.$element.html(o.html)}return this};c.prototype.currentMode=function d(){return this.options.modes[this.currModeIndex]};c.prototype.current=function i(){return this.currentMode().mode};c.prototype.getMode=function g(n){if(!n){return this.currentMode()}return this.options.modes[(this._getModeIndex(n))]};c.prototype.hasMode=function b(n){try{return !!this.getMode(n)}catch(o){}return false};c.prototype.setMode=function a(n){return this._setModeByIndex(this._getModeIndex(n))};c.prototype.reset=function h(){this.currModeIndex=0;if(this.options.initialMode){this.currModeIndex=this._getModeIndex(this.options.initialMode)}return this._setModeByIndex(this.currModeIndex)};c.prototype.callModeFn=function e(n){var o=this.getMode(n).onclick;if(o&&jQuery.type(o==="function")){return o.call(this.$element.get(0))}return undefined};jQuery.fn.extend({modeButton:function k(n){if(!this.size()){return this}if(jQuery.type(n)==="object"){return this.map(function(){var r=$(this);r.data("mode-button",new c(r,n));return this})}var p=$(this[0]),o=p.data("mode-button");if(!o){throw new Error("modeButton needs an options object or string name of a function")}if(o&&jQuery.type(n)==="string"){var q=n;if(o&&jQuery.type(o[q])==="function"){return o[q].apply(o,jQuery.makeArray(arguments).slice(1))}}return o}})}());
\ No newline at end of file
+var IconButton=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,is_menu_button:true,id:null,href:null,target:null,enabled:true,visible:true,tooltip_config:{}}});var IconButtonView=Backbone.View.extend({initialize:function(){this.model.attributes.tooltip_config={placement:"bottom"};this.model.bind("change",this.render,this)},render:function(){this.$el.tooltip("hide");var a=this.template(this.model.toJSON());a.tooltip(this.model.get("tooltip_config"));this.$el.replaceWith(a);this.setElement(a);return this},events:{click:"click"},click:function(a){if(_.isFunction(this.model.get("on_click"))){this.model.get("on_click")(a);return false}return true},template:function(b){var a='title="'+b.title+'" class="icon-button';if(b.is_menu_button){a+=" menu-button"}a+=" "+b.icon_class;if(!b.enabled){a+="_disabled"}a+='"';if(b.id){a+=' id="'+b.id+'"'}a+=' href="'+b.href+'"';if(b.target){a+=' target="'+b.target+'"'}if(!b.visible){a+=' style="display: none;"'}if(b.enabled){a="<a "+a+"/>"}else{a="<span "+a+"/>"}return $(a)}});var IconButtonCollection=Backbone.Collection.extend({model:IconButton});var IconButtonMenuView=Backbone.View.extend({tagName:"div",initialize:function(){this.render()},render:function(){var a=this;this.collection.each(function(d){var b=$("<a/>").attr("href","javascript:void(0)").attr("title",d.attributes.title).addClass("icon-button menu-button").addClass(d.attributes.icon_class).appendTo(a.$el).click(d.attributes.on_click);if(d.attributes.tooltip_config){b.tooltip(d.attributes.tooltip_config)}var c=d.get("options");if(c){make_popupmenu(b,c)}});return this}});var create_icon_buttons_menu=function(b,a){if(!a){a={}}var c=new IconButtonCollection(_.map(b,function(d){return new IconButton(_.extend(d,a))}));return new IconButtonMenuView({collection:c})};var Grid=Backbone.Collection.extend({});var GridView=Backbone.View.extend({});var PopupMenu=Backbone.View.extend({initialize:function(b,a){this.$button=b;if(!this.$button.size()){this.$button=$("<div/>")}this.options=a||[];var c=this;this.$button.click(function(d){$(".popmenu-wrapper").remove();c._renderAndShow(d);return false})},_renderAndShow:function(a){this.render();this.$el.appendTo("body").css(this._getShownPosition(a)).show();this._setUpCloseBehavior()},render:function(){this.$el.addClass("popmenu-wrapper").hide().css({position:"absolute"}).html(this.template(this.$button.attr("id"),this.options));if(this.options.length){var a=this;this.$el.find("li").each(function(c,b){var d=a.options[c];if(d.func){$(this).children("a.popupmenu-option").click(function(e){d.func.call(a,e,d)})}})}return this},template:function(b,a){return['<ul id="',b,'-menu" class="dropdown-menu">',this._templateOptions(a),"</ul>"].join("")},_templateOptions:function(a){if(!a.length){return"<li>(no options)</li>"}return _.map(a,function(d){if(d.divider){return'<li class="divider"></li>'}else{if(d.header){return['<li class="head"><a href="javascript:void(0);">',d.html,"</a></li>"].join("")}}var c=d.href||"javascript:void(0);",e=(d.target)?(' target="'+d.target+'"'):(""),b=(d.checked)?('<span class="fa fa-check"></span>'):("");return['<li><a class="popupmenu-option" href="',c,'"',e,">",b,d.html,"</a></li>"].join("")}).join("")},_getShownPosition:function(b){var c=this.$el.width();var a=b.pageX-c/2;a=Math.min(a,$(document).scrollLeft()+$(window).width()-c-5);a=Math.max(a,$(document).scrollLeft()+5);return{top:b.pageY,left:a}},_setUpCloseBehavior:function(){var c=this;function a(e){$(document).off("click.close_popup");if(window.parent!==window){try{$(window.parent.document).off("click.close_popup")}catch(d){}}else{try{$("iframe#galaxy_main").contents().off("click.close_popup")}catch(d){}}c.remove()}$("html").one("click.close_popup",a);if(window.parent!==window){try{$(window.parent.document).find("html").one("click.close_popup",a)}catch(b){}}else{try{$("iframe#galaxy_main").contents().one("click.close_popup",a)}catch(b){}}},addItem:function(b,a){a=(a>=0)?a:this.options.length;this.options.splice(a,0,b);return this},removeItem:function(a){if(a>=0){this.options.splice(a,1)}return this},findIndexByHtml:function(b){for(var a=0;a<this.options.length;a++){if(_.has(this.options[a],"html")&&(this.options[a].html===b)){return a}}return null},findItemByHtml:function(a){return this.options[(this.findIndexByHtml(a))]},toString:function(){return"PopupMenu"}});PopupMenu.create=function _create(b,a){return new PopupMenu(b,a)};PopupMenu.make_popupmenu=function(b,c){var a=[];_.each(c,function(f,d){var e={html:d};if(f===null){e.header=true}else{if(jQuery.type(f)==="function"){e.func=f}}a.push(e)});return new PopupMenu($(b),a)};PopupMenu.convertLinksToOptions=function(c,a){c=$(c);a=a||"a";var b=[];c.find(a).each(function(g,e){var f={},d=$(g);f.html=d.text();if(d.attr("href")){var j=d.attr("href"),k=d.attr("target"),h=d.attr("confirm");f.func=function(){if((h)&&(!confirm(h))){return}switch(k){case"_parent":window.parent.location=j;break;case"_top":window.top.location=j;break;default:window.location=j}}}b.push(f)});return b};PopupMenu.fromExistingDom=function(d,c,a){d=$(d);c=$(c);var b=PopupMenu.convertLinksToOptions(c,a);c.remove();return new PopupMenu(d,b)};PopupMenu.make_popup_menus=function(c,b,d){c=c||document;b=b||"div[popupmenu]";d=d||function(e,f){return"#"+e.attr("popupmenu")};var a=[];$(c).find(b).each(function(){var e=$(this),f=$(c).find(d(e,c));a.push(PopupMenu.fromDom(f,e));f.addClass("popup")});return a};var faIconButton=function(a){a=a||{};a.tooltipConfig=a.tooltipConfig||{placement:"bottom"};a.classes=["icon-btn"].concat(a.classes||[]);if(a.disabled){a.classes.push("disabled")}var b=['<a class="',a.classes.join(" "),'"',((a.title)?(' title="'+a.title+'"'):("")),((!a.disabled&&a.target)?(' target="'+a.target+'"'):("")),' href="',((!a.disabled&&a.href)?(a.href):("javascript:void(0);")),'">','<span class="fa ',a.faIcon,'"></span>',"</a>"].join("");var c=$(b).tooltip(a.tooltipConfig);if(_.isFunction(a.onclick)){c.click(a.onclick)}return c};function LoadingIndicator(a,c){var b=this;c=jQuery.extend({cover:false},c||{});function d(){var e=['<div class="loading-indicator">','<div class="loading-indicator-text">','<span class="fa fa-spinner fa-spin fa-lg"></span>','<span class="loading-indicator-message">loading...</span>',"</div>","</div>"].join("\n");var g=$(e).hide().css(c.css||{position:"fixed"}),f=g.children(".loading-indicator-text");if(c.cover){g.css({"z-index":2,top:a.css("top"),bottom:a.css("bottom"),left:a.css("left"),right:a.css("right"),opacity:0.5,"background-color":"white","text-align":"center"});f=g.children(".loading-indicator-text").css({"margin-top":"20px"})}else{f=g.children(".loading-indicator-text").css({margin:"12px 0px 0px 10px",opacity:"0.85",color:"grey"});f.children(".loading-indicator-message").css({margin:"0px 8px 0px 0px","font-style":"italic"})}return g}b.show=function(f,e,g){f=f||"loading...";e=e||"fast";a.parent().find(".loading-indicator").remove();b.$indicator=d().insertBefore(a);b.message(f);b.$indicator.fadeIn(e,g);return b};b.message=function(e){b.$indicator.find("i").text(e)};b.hide=function(e,f){e=e||"fast";if(b.$indicator&&b.$indicator.size()){b.$indicator.fadeOut(e,function(){b.$indicator.remove();if(f){f()}})}else{if(f){f()}}return b};return b}(function(){var b=window._l||function(d){return d};function a(k,q){var e=27,n=13,d=$(k),f=true,h={initialVal:"",name:"search",placeholder:"search",classes:"",onclear:function(){},onfirstsearch:null,onsearch:function(r){},minSearchLen:0,escWillClear:true,oninit:function(){}};function j(r){var s=$(this).parent().children("input");s.focus().val("").trigger("clear:searchInput");q.onclear()}function p(s,r){$(this).trigger("search:searchInput",r);if(typeof q.onfirstsearch==="function"&&f){f=false;q.onfirstsearch(r)}else{q.onsearch(r)}}function g(){return['<input type="text" name="',q.name,'" placeholder="',q.placeholder,'" ','class="search-query ',q.classes,'" ',"/>"].join("")}function m(){return $(g()).focus(function(r){$(this).select()}).keyup(function(s){s.preventDefault();s.stopPropagation();if(!$(this).val()){$(this).blur()}if(s.which===e&&q.escWillClear){j.call(this,s)}else{var r=$(this).val();if((s.which===n)||(q.minSearchLen&&r.length>=q.minSearchLen)){p.call(this,s,r)}else{if(!r.length){j.call(this,s)}}}}).on("change",function(r){p.call(this,r,$(this).val())}).val(q.initialVal)}function l(){return $(['<span class="search-clear fa fa-times-circle" ','title="',b("clear search (esc)"),'"></span>'].join("")).tooltip({placement:"bottom"}).click(function(r){j.call(this,r)})}function o(){return $(['<span class="search-loading fa fa-spinner fa-spin" ','title="',b("loading..."),'"></span>'].join("")).hide().tooltip({placement:"bottom"})}function i(){d.find(".search-loading").toggle();d.find(".search-clear").toggle()}if(jQuery.type(q)==="string"){if(q==="toggle-loading"){i()}return d}if(jQuery.type(q)==="object"){q=jQuery.extend(true,{},h,q)}return d.addClass("search-input").prepend([m(),l(),o()])}jQuery.fn.extend({searchInput:function c(d){return this.each(function(){return a(this,d)})}})}());
\ No newline at end of file
diff -r 0fb0c56af3cf25bb8c3bb366d34c6aedcbb9df14 -r 8e98c3d9b9a8bc3cabff60c67367fbaf5b328320 templates/webapps/galaxy/history/view.mako
--- a/templates/webapps/galaxy/history/view.mako
+++ b/templates/webapps/galaxy/history/view.mako
@@ -65,8 +65,7 @@
## ----------------------------------------------------------------------------
<%def name="javascripts()">
-${parent.javascripts()}
-
+ ${parent.javascripts()}
</%def>
## ----------------------------------------------------------------------------
@@ -144,7 +143,7 @@
window.location = "${ switch_to_url }";
}
});
-
+
$( '#import' ).modeButton({
switchModesOnClick : false,
initialMode : "${ 'with_deleted' if show_deleted else 'without_deleted' }",
@@ -175,8 +174,16 @@
({ location: 'mvc/history/history-panel', className: 'HistoryPanel' });
require.config({
- baseUrl : "${h.url_for( '/static/scripts' )}"
- })([ 'mvc/user/user-model', panelToUse.location, 'utils/localization' ], function( user, panelMod, _l ){
+ baseUrl : "${h.url_for( '/static/scripts' )}",
+ paths : {
+ 'jquery' : 'libs/jquery/jquery'
+ }
+ })([
+ 'mvc/user/user-model',
+ panelToUse.location,
+ 'utils/localization',
+ 'jq-plugins/ui/mode-button'
+ ], function( user, panelMod, _l ){
$(function(){
setUpBehaviors();
if( hasMasthead ){
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/39b03ce9d101/
Changeset: 39b03ce9d101
User: guerler
Date: 2014-12-08 20:34:11+00:00
Summary: Security fixes for assigned templates
Affected #: 4 files
diff -r 864fdca5b06e6f15040298a316746448d09cdb40 -r 39b03ce9d101f7177c51342172ba9bab540ee257 templates/webapps/galaxy/tracks/history_datasets_select_grid.mako
--- a/templates/webapps/galaxy/tracks/history_datasets_select_grid.mako
+++ b/templates/webapps/galaxy/tracks/history_datasets_select_grid.mako
@@ -1,5 +1,5 @@
<%inherit file="/tracks/history_select_grid.mako"/><%def name="title()">
- <h2>History '${grid.get_current_item( trans, **kwargs ).name}'</h2>
+ <h2>History '${grid.get_current_item( trans, **kwargs ).name | h}'</h2></%def>
diff -r 864fdca5b06e6f15040298a316746448d09cdb40 -r 39b03ce9d101f7177c51342172ba9bab540ee257 templates/webapps/galaxy/tracks/index.mako
--- a/templates/webapps/galaxy/tracks/index.mako
+++ /dev/null
@@ -1,38 +0,0 @@
-<form id="form" method="POST">
- <div class="form-row">
- <label for="dbkey">Browser name:</label>
- <div class="form-row-input">
- <input type="text" name="title" id="title" value="Unnamed Browser"></input>
- </div>
- <div style="clear: both;"></div>
- </div>
- <div class="form-row">
- <label for="dbkey">Reference genome build (dbkey): </label>
- <div class="form-row-input">
- <select name="dbkey" id="dbkey" refresh_on_change="true">
- %for tmp_dbkey in dbkey_set:
- <option value="${tmp_dbkey}"
- %if tmp_dbkey == dbkey:
- selected="selected"
- %endif
- >${tmp_dbkey}</option>
- %endfor
- </select>
- </div>
- <div style="clear: both;"></div>
- </div>
- <div class="form-row">
- <label for="dataset_ids">Datasets to visualize: (${", ".join(available_tracks)} files are supported)</label>
- %for dataset_id, (dataset_ext, dataset_name) in datasets.iteritems():
- <div>
- <input type="checkbox" id="${dataset_id}" name="dataset_ids" value="${dataset_id}" />
- <label style="display:inline; font-weight: normal" for="${dataset_id}">[${dataset_ext}] ${dataset_name}</label>
- </div>
- %endfor
-
- <div style="clear: both;"></div>
- </div>
- <div class="form-row">
- <input type="submit" name="browse" value="Browse"/>
- </div>
-</form>
diff -r 864fdca5b06e6f15040298a316746448d09cdb40 -r 39b03ce9d101f7177c51342172ba9bab540ee257 templates/webapps/galaxy/tracks/library_datasets_select_grid.mako
--- a/templates/webapps/galaxy/tracks/library_datasets_select_grid.mako
+++ b/templates/webapps/galaxy/tracks/library_datasets_select_grid.mako
@@ -2,7 +2,7 @@
<%namespace file='/library/common/browse_library.mako' import="render_content, grid_javascripts" /><%def name="title()">
- <h2>History '${grid.get_current_item( trans, **kwargs ).name}'</h2>
+ <h2>History '${grid.get_current_item( trans, **kwargs ).name | h}'</h2></%def>
${select_header()}
diff -r 864fdca5b06e6f15040298a316746448d09cdb40 -r 39b03ce9d101f7177c51342172ba9bab540ee257 templates/webapps/galaxy/visualization/phyloviz.mako
--- a/templates/webapps/galaxy/visualization/phyloviz.mako
+++ b/templates/webapps/galaxy/visualization/phyloviz.mako
@@ -196,7 +196,7 @@
<p>Select a tree to view:
<select id="phylovizNexSelector">
% for tree, index in data["trees"]:
- <option value="${index}">${tree}</option>
+ <option value="${index | h}">${tree | h}</option>
% endfor
</select></p>
https://bitbucket.org/galaxy/galaxy-central/commits/0fb0c56af3cf/
Changeset: 0fb0c56af3cf
User: guerler
Date: 2014-12-08 20:38:01+00:00
Summary: Parameters: Handle missing context
Affected #: 1 file
diff -r 39b03ce9d101f7177c51342172ba9bab540ee257 -r 0fb0c56af3cf25bb8c3bb366d34c6aedcbb9df14 lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -767,7 +767,10 @@
if self.options:
return self.options.get_options( trans, other_values )
elif self.dynamic_options:
- return eval( self.dynamic_options, self.tool.code_namespace, other_values )
+ try:
+ return eval( self.dynamic_options, self.tool.code_namespace, other_values )
+ except Exception:
+ return []
else:
return self.static_options
@@ -779,7 +782,10 @@
if self.options:
return map( _get_UnvalidatedValue_value, set( v for _, v, _ in self.options.get_options( trans, other_values ) ) )
elif self.dynamic_options:
- return set( v for _, v, _ in eval( self.dynamic_options, self.tool.code_namespace, other_values ) )
+ try:
+ return set( v for _, v, _ in eval( self.dynamic_options, self.tool.code_namespace, other_values ) )
+ except Exception:
+ return set()
else:
return self.legal_values
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/4806dfc74e0e/
Changeset: 4806dfc74e0e
Branch: next-stable
User: guerler
Date: 2014-12-08 20:34:11+00:00
Summary: Security fixes for assigned templates
Affected #: 4 files
diff -r 0317c3ec09d99ac40a9217a4725c6a2fe89c3de8 -r 4806dfc74e0e3d903ad40ee33dacec67ed516daa templates/webapps/galaxy/tracks/history_datasets_select_grid.mako
--- a/templates/webapps/galaxy/tracks/history_datasets_select_grid.mako
+++ b/templates/webapps/galaxy/tracks/history_datasets_select_grid.mako
@@ -1,5 +1,5 @@
<%inherit file="/tracks/history_select_grid.mako"/><%def name="title()">
- <h2>History '${grid.get_current_item( trans, **kwargs ).name}'</h2>
+ <h2>History '${grid.get_current_item( trans, **kwargs ).name | h}'</h2></%def>
diff -r 0317c3ec09d99ac40a9217a4725c6a2fe89c3de8 -r 4806dfc74e0e3d903ad40ee33dacec67ed516daa templates/webapps/galaxy/tracks/index.mako
--- a/templates/webapps/galaxy/tracks/index.mako
+++ /dev/null
@@ -1,38 +0,0 @@
-<form id="form" method="POST">
- <div class="form-row">
- <label for="dbkey">Browser name:</label>
- <div class="form-row-input">
- <input type="text" name="title" id="title" value="Unnamed Browser"></input>
- </div>
- <div style="clear: both;"></div>
- </div>
- <div class="form-row">
- <label for="dbkey">Reference genome build (dbkey): </label>
- <div class="form-row-input">
- <select name="dbkey" id="dbkey" refresh_on_change="true">
- %for tmp_dbkey in dbkey_set:
- <option value="${tmp_dbkey}"
- %if tmp_dbkey == dbkey:
- selected="selected"
- %endif
- >${tmp_dbkey}</option>
- %endfor
- </select>
- </div>
- <div style="clear: both;"></div>
- </div>
- <div class="form-row">
- <label for="dataset_ids">Datasets to visualize: (${", ".join(available_tracks)} files are supported)</label>
- %for dataset_id, (dataset_ext, dataset_name) in datasets.iteritems():
- <div>
- <input type="checkbox" id="${dataset_id}" name="dataset_ids" value="${dataset_id}" />
- <label style="display:inline; font-weight: normal" for="${dataset_id}">[${dataset_ext}] ${dataset_name}</label>
- </div>
- %endfor
-
- <div style="clear: both;"></div>
- </div>
- <div class="form-row">
- <input type="submit" name="browse" value="Browse"/>
- </div>
-</form>
diff -r 0317c3ec09d99ac40a9217a4725c6a2fe89c3de8 -r 4806dfc74e0e3d903ad40ee33dacec67ed516daa templates/webapps/galaxy/tracks/library_datasets_select_grid.mako
--- a/templates/webapps/galaxy/tracks/library_datasets_select_grid.mako
+++ b/templates/webapps/galaxy/tracks/library_datasets_select_grid.mako
@@ -2,7 +2,7 @@
<%namespace file='/library/common/browse_library.mako' import="render_content, grid_javascripts" /><%def name="title()">
- <h2>History '${grid.get_current_item( trans, **kwargs ).name}'</h2>
+ <h2>History '${grid.get_current_item( trans, **kwargs ).name | h}'</h2></%def>
${select_header()}
diff -r 0317c3ec09d99ac40a9217a4725c6a2fe89c3de8 -r 4806dfc74e0e3d903ad40ee33dacec67ed516daa templates/webapps/galaxy/visualization/phyloviz.mako
--- a/templates/webapps/galaxy/visualization/phyloviz.mako
+++ b/templates/webapps/galaxy/visualization/phyloviz.mako
@@ -196,7 +196,7 @@
<p>Select a tree to view:
<select id="phylovizNexSelector">
% for tree, index in data["trees"]:
- <option value="${index}">${tree}</option>
+ <option value="${index | h}">${tree | h}</option>
% endfor
</select></p>
https://bitbucket.org/galaxy/galaxy-central/commits/49ef0cdbf45a/
Changeset: 49ef0cdbf45a
Branch: next-stable
User: guerler
Date: 2014-12-08 20:38:01+00:00
Summary: Parameters: Handle missing context
Affected #: 1 file
diff -r 4806dfc74e0e3d903ad40ee33dacec67ed516daa -r 49ef0cdbf45acca661900c22869f33cd01536ecf lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -767,7 +767,10 @@
if self.options:
return self.options.get_options( trans, other_values )
elif self.dynamic_options:
- return eval( self.dynamic_options, self.tool.code_namespace, other_values )
+ try:
+ return eval( self.dynamic_options, self.tool.code_namespace, other_values )
+ except Exception:
+ return []
else:
return self.static_options
@@ -779,7 +782,10 @@
if self.options:
return map( _get_UnvalidatedValue_value, set( v for _, v, _ in self.options.get_options( trans, other_values ) ) )
elif self.dynamic_options:
- return set( v for _, v, _ in eval( self.dynamic_options, self.tool.code_namespace, other_values ) )
+ try:
+ return set( v for _, v, _ in eval( self.dynamic_options, self.tool.code_namespace, other_values ) )
+ except Exception:
+ return set()
else:
return self.legal_values
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dannon: Merged in dan/galaxy-central-prs/stable (pull request #597)
by commits-noreply@bitbucket.org 08 Dec '14
by commits-noreply@bitbucket.org 08 Dec '14
08 Dec '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/07404a82972d/
Changeset: 07404a82972d
Branch: stable
User: dannon
Date: 2014-12-08 20:22:53+00:00
Summary: Merged in dan/galaxy-central-prs/stable (pull request #597)
[STABLE] HTML escape user-settable values in Data Libraries. Update tests to reflect that e.g. quotes are now html escaped within pages. Eliminate the unnecessary use of Params() object for these controllers.
Affected #: 17 files
diff -r 704efd2f5e06b9f6e63246d2324874cf7f28d83a -r 07404a82972d877b5529fffaeb3e7e05b69a02a3 lib/galaxy/webapps/galaxy/controllers/library.py
--- a/lib/galaxy/webapps/galaxy/controllers/library.py
+++ b/lib/galaxy/webapps/galaxy/controllers/library.py
@@ -3,7 +3,7 @@
from galaxy import web
from galaxy.model.orm import and_, not_, or_
from galaxy.web.base.controller import BaseUIController
-from galaxy.web.framework.helpers import grids
+from galaxy.web.framework.helpers import escape, grids
from library_common import get_comptypes, lucene_search, whoosh_search
@@ -79,7 +79,6 @@
@web.expose
def list( self, trans, **kwd ):
- params = util.Params( kwd )
# define app configuration for generic mako template
app = {
'jscript' : "galaxy.library"
@@ -89,10 +88,9 @@
@web.expose
def index( self, trans, **kwd ):
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- default_action = params.get( 'default_action', None )
+ message = escape( kwd.get( 'message', '' ) )
+ status = escape( kwd.get( 'status', 'done' ) )
+ default_action = kwd.get( 'default_action', None )
return trans.fill_template( "/library/index.mako",
default_action=default_action,
message=message,
diff -r 704efd2f5e06b9f6e63246d2324874cf7f28d83a -r 07404a82972d877b5529fffaeb3e7e05b69a02a3 lib/galaxy/webapps/galaxy/controllers/library_admin.py
--- a/lib/galaxy/webapps/galaxy/controllers/library_admin.py
+++ b/lib/galaxy/webapps/galaxy/controllers/library_admin.py
@@ -5,7 +5,7 @@
from galaxy import web
from galaxy.web.base.controller import BaseUIController
-from galaxy.web.framework.helpers import grids, time_ago
+from galaxy.web.framework.helpers import escape, grids, time_ago
from library_common import get_comptypes, lucene_search, whoosh_search
# from galaxy.model.orm import *
@@ -141,20 +141,19 @@
lddas=lddas,
show_deleted=show_deleted,
use_panels=use_panels,
- message=message,
- status=status )
+ message=escape( message ),
+ status=escape( status ) )
# Render the list view
return self.library_list_grid( trans, **kwd )
@web.expose
@web.require_admin
def create_library( self, trans, **kwd ):
- params = galaxy.util.Params( kwd )
- message = galaxy.util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- if params.get( 'create_library_button', False ):
- name = galaxy.util.restore_text( params.get( 'name', 'No name' ) )
- description = galaxy.util.restore_text( params.get( 'description', '' ) )
- synopsis = galaxy.util.restore_text( params.get( 'synopsis', '' ) )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ if kwd.get( 'create_library_button', False ):
+ name = kwd.get( 'name', 'No name' )
+ description = kwd.get( 'description', '' )
+ synopsis = kwd.get( 'synopsis', '' )
if synopsis in [ 'None', None ]:
synopsis = ''
library = trans.app.model.Library( name=name, description=description, synopsis=synopsis )
@@ -167,9 +166,9 @@
action='browse_library',
cntrller='library_admin',
id=trans.security.encode_id( library.id ),
- message=galaxy.util.sanitize_text( message ),
+ message=message,
status='done' ) )
- return trans.fill_template( '/admin/library/new_library.mako', message=message, status=status )
+ return trans.fill_template( '/admin/library/new_library.mako', message=escape( message ), status=escape( status ) )
@web.expose
@web.require_admin
def delete_library( self, trans, id, **kwd ):
@@ -196,8 +195,7 @@
# 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 = galaxy.util.Params( kwd )
- library = trans.sa_session.query( trans.app.model.Library ).get( trans.security.decode_id( params.id ) )
+ library = trans.sa_session.query( trans.app.model.Library ).get( trans.security.decode_id( kwd.get( 'id' ) ) )
def purge_folder( library_folder ):
for lf in library_folder.folders:
purge_folder( lf )
@@ -226,7 +224,7 @@
message = "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',
- message=galaxy.util.sanitize_text( message ),
+ message=message,
status='error' ) )
else:
purge_folder( library.root_folder )
@@ -236,5 +234,5 @@
message = "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='browse_libraries',
- message=galaxy.util.sanitize_text( message ),
+ message=message,
status='done' ) )
diff -r 704efd2f5e06b9f6e63246d2324874cf7f28d83a -r 07404a82972d877b5529fffaeb3e7e05b69a02a3 lib/galaxy/webapps/galaxy/controllers/library_common.py
--- a/lib/galaxy/webapps/galaxy/controllers/library_common.py
+++ b/lib/galaxy/webapps/galaxy/controllers/library_common.py
@@ -20,6 +20,7 @@
from galaxy.util.streamball import StreamBall
from galaxy.web.base.controller import BaseUIController, UsesFormDefinitionsMixin, UsesExtendedMetadataMixin, UsesLibraryMixinItems
from galaxy.web.form_builder import AddressField, CheckboxField, SelectField, build_select_field
+from galaxy.web.framework.helpers import escape
from galaxy.model.orm import and_, eagerload_all
# Whoosh is compatible with Python 2.5+ Try to import Whoosh and set flag to indicate whether tool search is enabled.
@@ -92,14 +93,13 @@
@web.expose
def browse_library( self, trans, cntrller='library', **kwd ):
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
# If use_panels is True, the library is being accessed via an external link
# which did not originate from within the Galaxy instance, and the library will
# be displayed correctly with the mast head.
- use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
- library_id = params.get( 'id', None )
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
+ library_id = kwd.get( 'id', None )
if not library_id:
# To handle bots
message = "You must specify a library id."
@@ -116,9 +116,9 @@
message = "Invalid library id ( %s ) specified." % str( library_id )
status = 'error'
else:
- 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', '' ) )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
+ created_ldda_ids = kwd.get( 'created_ldda_ids', '' )
+ hidden_folder_ids = util.listify( kwd.get( 'hidden_folder_ids', '' ) )
if created_ldda_ids and not message:
message = "%d datasets are uploading in the background to the library '%s' (each is selected). " % \
( len( created_ldda_ids.split( ',' ) ), library.name )
@@ -137,8 +137,8 @@
show_deleted=show_deleted,
comptypes=comptypes,
current_user_roles=current_user_roles,
- message=message,
- status=status )
+ message=escape( message ),
+ status=escape( status ) )
else:
return trans.fill_template( 'library/common/browse_library.mako',
cntrller=cntrller,
@@ -149,44 +149,43 @@
show_deleted=show_deleted,
comptypes=comptypes,
current_user_roles=current_user_roles,
- message=message,
- status=status )
+ message=escape( message ),
+ status=escape( status ) )
except Exception, e:
message = 'Error attempting to display contents of library (%s): %s.' % ( str( library.name ), str( e ) )
status = 'error'
- default_action = params.get( 'default_action', None )
+ default_action = kwd.get( 'default_action', None )
return trans.response.send_redirect( web.url_for( use_panels=use_panels,
controller=cntrller,
action='browse_libraries',
default_action=default_action,
- message=util.sanitize_text( message ),
+ message=message,
status=status ) )
@web.expose
def library_info( self, trans, cntrller, **kwd ):
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
- show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
is_admin = trans.user_is_admin() and cntrller == 'library_admin'
current_user_roles = trans.get_current_user_roles()
- library_id = params.get( 'id', None )
+ library_id = kwd.get( 'id', None )
try:
library = trans.sa_session.query( trans.app.model.Library ).get( trans.security.decode_id( library_id ) )
except:
library = None
self._check_access( trans, cntrller, is_admin, library, current_user_roles, use_panels, library_id, show_deleted )
- if params.get( 'library_info_button', False ):
+ if kwd.get( 'library_info_button', False ):
self._check_modify( trans, cntrller, is_admin, library, current_user_roles, use_panels, library_id, show_deleted )
old_name = library.name
- new_name = util.restore_text( params.get( 'name', 'No name' ) )
+ new_name = kwd.get( 'name', 'No name' )
if not new_name:
message = 'Enter a valid name'
status='error'
else:
- new_description = util.restore_text( params.get( 'description', '' ) )
- new_synopsis = util.restore_text( params.get( 'synopsis', '' ) )
+ new_description = kwd.get( 'description', '' )
+ new_synopsis = kwd.get( 'synopsis', '' )
if new_synopsis in [ None, 'None' ]:
new_synopsis = ''
library.name = new_name
@@ -204,7 +203,7 @@
use_panels=use_panels,
id=trans.security.encode_id( library.id ),
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status='done' ) )
# See if we have any associated templates
info_association, inherited = library.get_info_association()
@@ -220,29 +219,28 @@
show_deleted=show_deleted,
info_association=info_association,
inherited=inherited,
- message=message,
- status=status )
+ message=escape( message ),
+ status=escape( status ) )
@web.expose
def library_permissions( self, trans, cntrller, **kwd ):
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
- show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
is_admin = trans.user_is_admin() and cntrller == 'library_admin'
current_user_roles = trans.get_current_user_roles()
- library_id = params.get( 'id', None )
+ library_id = kwd.get( 'id', None )
try:
library = trans.sa_session.query( trans.app.model.Library ).get( trans.security.decode_id( library_id ) )
except:
library = None
self._check_access( trans, cntrller, is_admin, library, current_user_roles, use_panels, library_id, show_deleted )
self._check_manage( trans, cntrller, is_admin, library, current_user_roles, use_panels, library_id, show_deleted )
- if params.get( 'update_roles_button', False ):
+ if kwd.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', [] ) ) ]
+ 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( trans, library, permissions )
trans.sa_session.refresh( library )
@@ -255,7 +253,7 @@
use_panels=use_panels,
id=trans.security.encode_id( library.id ),
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status='done' ) )
roles = trans.app.security_agent.get_legitimate_roles( trans, library, cntrller )
all_roles = trans.app.security_agent.get_all_roles( trans, cntrller )
@@ -267,15 +265,14 @@
roles=roles,
all_roles=all_roles,
show_deleted=show_deleted,
- message=message,
- status=status )
+ message=escape( message ),
+ status=escape( status ) )
@web.expose
def create_folder( self, trans, cntrller, parent_id, library_id, **kwd ):
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
- use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
is_admin = trans.user_is_admin() and cntrller in ( 'library_admin', 'api' )
current_user_roles = trans.get_current_user_roles()
try:
@@ -288,9 +285,9 @@
parent_library = parent_folder.parent_library
self._check_access( trans, cntrller, is_admin, parent_folder, current_user_roles, use_panels, library_id, show_deleted )
self._check_add( trans, cntrller, is_admin, parent_folder, current_user_roles, use_panels, library_id, show_deleted )
- if params.get( 'new_folder_button', False ) or cntrller == 'api':
- new_folder = trans.app.model.LibraryFolder( name=util.restore_text( params.name ),
- description=util.restore_text( params.description ) )
+ if kwd.get( 'new_folder_button', False ) or cntrller == 'api':
+ new_folder = trans.app.model.LibraryFolder( name=kwd.get( 'name', '' ),
+ description=kwd.get( 'description', '' ) )
# We are associating the last used genome build with folders, so we will always
# initialize a new folder with the first dbkey in genome builds list which is currently
# ? unspecified (?)
@@ -322,7 +319,7 @@
show_deleted=show_deleted,
info_association=info_association,
inherited=inherited,
- message=message,
+ message=escape( message ),
status='done' )
# If not inheritable info_association, redirect to the library.
message = "The new folder named '%s' has been added to the data library." % new_folder.name
@@ -334,7 +331,7 @@
use_panels=use_panels,
id=library_id,
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status='done' ) )
# We do not render any template widgets on creation pages since saving the info_association
# cannot occur before the associated item is saved.
@@ -344,15 +341,14 @@
library_id=library_id,
folder=parent_folder,
show_deleted=show_deleted,
- message=message,
- status=status )
+ message=escape( message ),
+ status=escape( status ) )
@web.expose
def folder_info( self, trans, cntrller, id, library_id, **kwd ):
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
- use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
is_admin = trans.user_is_admin() and cntrller == 'library_admin'
current_user_roles = trans.get_current_user_roles()
try:
@@ -360,11 +356,11 @@
except:
folder = None
self._check_access( trans, cntrller, is_admin, folder, current_user_roles, use_panels, library_id, show_deleted )
- if params.get( 'rename_folder_button', False ):
+ if kwd.get( 'rename_folder_button', False ):
self._check_modify( trans, cntrller, is_admin, folder, current_user_roles, use_panels, library_id, show_deleted )
old_name = folder.name
- new_name = util.restore_text( params.name )
- new_description = util.restore_text( params.description )
+ new_name = kwd.get( 'name', '' )
+ new_description = kwd.get( 'description', '' )
if not new_name:
message = 'Enter a valid name'
status='error'
@@ -381,7 +377,7 @@
id=id,
library_id=library_id,
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status='done' ) )
# See if we have any associated templates
widgets = []
@@ -401,15 +397,14 @@
show_deleted=show_deleted,
info_association=info_association,
inherited=inherited,
- message=message,
- status=status )
+ message=escape( message ),
+ status=escape( status ) )
@web.expose
def folder_permissions( self, trans, cntrller, id, library_id, **kwd ):
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
- use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
is_admin = trans.user_is_admin() and cntrller == 'library_admin'
current_user_roles = trans.get_current_user_roles()
try:
@@ -418,14 +413,14 @@
folder = None
self._check_access( trans, cntrller, is_admin, folder, current_user_roles, use_panels, library_id, show_deleted )
self._check_manage( trans, cntrller, is_admin, folder, current_user_roles, use_panels, library_id, show_deleted )
- if params.get( 'update_roles_button', False ):
+ if kwd.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():
if k != 'LIBRARY_ACCESS':
# LIBRARY_ACCESS is a special permission set only at the library level
# and it is not inherited.
- in_roles = [ trans.sa_session.query( trans.app.model.Role ).get( int( x ) ) for x in util.listify( params.get( k + '_in', [] ) ) ]
+ in_roles = [ trans.sa_session.query( trans.app.model.Role ).get( int( 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( trans, folder, permissions )
trans.sa_session.refresh( folder )
@@ -437,7 +432,7 @@
id=trans.security.encode_id( folder.id ),
library_id=library_id,
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status='done' ) )
# If the library is public all roles are legitimate, but if the library
# is restricted, only those roles associated with the LIBRARY_ACCESS
@@ -451,15 +446,14 @@
current_user_roles=current_user_roles,
roles=roles,
show_deleted=show_deleted,
- message=message,
- status=status )
+ message=escape( message ),
+ status=escape( status ) )
@web.expose
def ldda_edit_info( self, trans, cntrller, library_id, folder_id, id, **kwd ):
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
- use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
is_admin = trans.user_is_admin() and cntrller == 'library_admin'
current_user_roles = trans.get_current_user_roles()
try:
@@ -468,7 +462,7 @@
ldda = None
self._check_access( trans, cntrller, is_admin, ldda, current_user_roles, use_panels, library_id, show_deleted )
self._check_modify( trans, cntrller, is_admin, ldda, current_user_roles, use_panels, library_id, show_deleted )
- dbkey = params.get( 'dbkey', '?' )
+ dbkey = kwd.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 ]
@@ -492,26 +486,26 @@
info_association, inherited = ldda.get_info_association()
if info_association and ( not( inherited ) or info_association.inheritable ):
widgets = ldda.get_template_widgets( trans )
- if params.get( 'change', False ):
+ if kwd.get( 'change', False ):
# The user clicked the Save button on the 'Change data type' form
if __ok_to_edit_metadata( ldda.id ):
- 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 )
+ if ldda.datatype.allow_datatype_change and trans.app.datatypes_registry.get_datatype_by_extension( kwd.get( 'datatype' ) ).allow_datatype_change:
+ trans.app.datatypes_registry.change_datatype( ldda, kwd.get( 'datatype' ) )
trans.sa_session.flush()
message = "Data type changed for library dataset '%s'." % ldda.name
status = 'done'
else:
- message = "You are unable to change datatypes in this manner. Changing %s to %s is not allowed." % ( ldda.extension, params.datatype )
+ message = "You are unable to change datatypes in this manner. Changing %s to %s is not allowed." % ( ldda.extension, kwd.get( 'datatype' ) )
status = 'error'
else:
message = "This dataset is currently being used as input or output. You cannot change datatype until the jobs have completed or you have canceled them."
status = "error"
- elif params.get( 'save', False ):
+ elif kwd.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', '' ) )
+ new_name = kwd.get( 'name', '' )
+ new_info = kwd.get( 'info', '' )
+ new_message = kwd.get( 'message', '' )
if not new_name:
message = 'Enter a valid name'
status = 'error'
@@ -524,12 +518,12 @@
for name, spec in ldda.datatype.metadata_spec.items():
if spec.get("readonly"):
continue
- optional = params.get( "is_" + name, None )
+ optional = kwd.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 ) ) )
+ setattr( ldda.metadata, name, spec.unwrap( kwd.get( name, None ) ) )
ldda.metadata.dbkey = dbkey
ldda.datatype.after_setting_metadata( ldda )
message = "Attributes updated for library dataset '%s'." % ldda.name
@@ -538,7 +532,7 @@
message = "Attributes updated, but metadata could not be changed because this dataset is currently being used as input or output. You must cancel or wait for these jobs to complete before changing metadata."
status = 'warning'
trans.sa_session.flush()
- elif params.get( 'detect', False ):
+ elif kwd.get( 'detect', False ):
# The user clicked the Auto-detect button on the 'Edit Attributes' form
if __ok_to_edit_metadata( ldda.id ):
for name, spec in ldda.datatype.metadata_spec.items():
@@ -553,8 +547,8 @@
message = "This dataset is currently being used as input or output. You cannot change metadata until the jobs have completed or you have canceled them."
status = 'error'
trans.sa_session.flush()
- elif params.get( 'change_extended_metadata', False):
- em_string = util.restore_text( params.get("extended_metadata", "") )
+ elif kwd.get( 'change_extended_metadata', False):
+ em_string = kwd.get("extended_metadata", "" )
if len(em_string):
payload = None
try:
@@ -604,16 +598,15 @@
show_deleted=show_deleted,
info_association=info_association,
inherited=inherited,
- message=message,
- status=status )
+ message=escape( message ),
+ status=escape( status ) )
@web.expose
def ldda_info( self, trans, cntrller, library_id, folder_id, id, **kwd ):
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
- show_associated_hdas_and_lddas = util.string_as_bool( params.get( 'show_associated_hdas_and_lddas', False ) )
- use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
+ show_associated_hdas_and_lddas = util.string_as_bool( kwd.get( 'show_associated_hdas_and_lddas', False ) )
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
is_admin = trans.user_is_admin() and cntrller == 'library_admin'
current_user_roles = trans.get_current_user_roles()
ldda = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get( trans.security.decode_id( id ) )
@@ -653,15 +646,14 @@
current_user_roles=current_user_roles,
info_association=info_association,
inherited=inherited,
- message=message,
- status=status )
+ message=escape( message ),
+ status=escape( status ) )
@web.expose
def ldda_permissions( self, trans, cntrller, library_id, folder_id, id, **kwd ):
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
- use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
ids = util.listify( id )
lddas = []
libraries = []
@@ -685,7 +677,7 @@
id=library_id,
cntrller=cntrller,
use_panels=use_panels,
- message=util.sanitize_text( message ),
+ message=message,
status='error' ) )
# If access to the dataset is restricted, then use the roles associated with the DATASET_ACCESS permission to
# determine the legitimate roles. If the dataset is public, see if access to the library is restricted. If
@@ -698,7 +690,7 @@
roles = trans.app.security_agent.get_legitimate_roles( trans, library, cntrller )
else:
roles = trans.app.security_agent.get_legitimate_roles( trans, ldda.dataset, cntrller )
- if params.get( 'update_roles_button', False ):
+ if kwd.get( 'update_roles_button', False ):
# Dataset permissions
access_action = trans.app.security_agent.get_action( trans.app.security_agent.permitted_actions.DATASET_ACCESS.action )
manage_permissions_action = trans.app.security_agent.get_action( trans.app.security_agent.permitted_actions.DATASET_MANAGE_PERMISSIONS.action )
@@ -755,8 +747,8 @@
library_id=library_id,
roles=roles,
show_deleted=show_deleted,
- message=message,
- status=status )
+ message=escape( message ),
+ status=escape( status ) )
if len( ids ) > 1:
# Ensure that the permissions across all library items are identical, otherwise we can't update them together.
check_list = []
@@ -781,7 +773,7 @@
use_panels=use_panels,
id=library_id,
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status='error' ) )
# Display permission form, permissions will be updated for all lddas simultaneously.
return trans.fill_template( "/library/common/ldda_permissions.mako",
@@ -791,31 +783,30 @@
library_id=library_id,
roles=roles,
show_deleted=show_deleted,
- message=message,
- status=status )
+ message=escape( message ),
+ status=escape( status ) )
@web.expose
def upload_library_dataset( self, trans, cntrller, library_id, folder_id, **kwd ):
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- ldda_message = util.restore_text( params.get( 'ldda_message', '' ) )
- deleted = util.string_as_bool( params.get( 'deleted', False ) )
- show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
- use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
- replace_id = params.get( 'replace_id', None )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ ldda_message = kwd.get( 'ldda_message', '' )
+ deleted = util.string_as_bool( kwd.get( 'deleted', False ) )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
+ replace_id = kwd.get( 'replace_id', None )
replace_dataset = None
- upload_option = params.get( 'upload_option', 'upload_file' )
- if params.get( 'files_0|space_to_tab', False ):
- space_to_tab = params.get( 'files_0|space_to_tab', '' )
+ upload_option = kwd.get( 'upload_option', 'upload_file' )
+ if kwd.get( 'files_0|space_to_tab', False ):
+ space_to_tab = kwd.get( 'files_0|space_to_tab', '' )
else:
- space_to_tab = params.get( 'space_to_tab', '' )
- link_data_only = params.get( 'link_data_only', 'copy_files' )
- dbkey = params.get( 'dbkey', '?' )
+ space_to_tab = kwd.get( 'space_to_tab', '' )
+ link_data_only = kwd.get( 'link_data_only', 'copy_files' )
+ dbkey = kwd.get( 'dbkey', '?' )
if isinstance( dbkey, list ):
last_used_build = dbkey[0]
else:
last_used_build = dbkey
- roles = params.get( 'roles', '' )
+ roles = kwd.get( 'roles', '' )
is_admin = trans.user_is_admin() and cntrller in ( 'library_admin', 'api' )
current_user_roles = trans.get_current_user_roles()
widgets = []
@@ -844,7 +835,7 @@
library = folder.parent_library
if folder and last_used_build in [ 'None', None, '?' ]:
last_used_build = folder.genome_build
- if params.get( 'runtool_btn', False ) or params.get( 'ajax_upload', False ) or cntrller == 'api':
+ if kwd.get( 'runtool_btn', False ) or kwd.get( 'ajax_upload', False ) or cntrller == 'api':
error = False
if upload_option == 'upload_paths' and not trans.app.config.allow_library_path_paste:
error = True
@@ -869,7 +860,7 @@
replace_id=replace_id,
upload_option=upload_option,
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status='error' ) )
else:
# See if we have any inherited templates.
@@ -883,7 +874,7 @@
for index, widget_dict in enumerate( widgets ):
widget = widget_dict[ 'widget' ]
if isinstance( widget, AddressField ):
- value = util.restore_text( params.get( widget.name, '' ) )
+ value = kwd.get( widget.name, '' )
if value == 'new':
if self.field_param_values_ok( widget.name, 'AddressField', **kwd ):
# Save the new address
@@ -966,7 +957,7 @@
default_action=default_action,
created_ldda_ids=created_ldda_ids,
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status='done' ) )
else:
created_ldda_ids = ''
@@ -981,7 +972,7 @@
id=library_id,
created_ldda_ids=created_ldda_ids,
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status=status ) )
# Note: if the upload form was submitted due to refresh_on_change for a form field, we cannot re-populate
# the field for the selected file ( files_0|file_data ) if the user selected one. This is because the value
@@ -1040,8 +1031,8 @@
link_data_only=link_data_only,
show_deleted=show_deleted,
ldda_message=ldda_message,
- message=message,
- status=status )
+ message=escape( message ),
+ status=escape( status ) )
def upload_dataset( self, trans, cntrller, library_id, folder_id, replace_dataset=None, **kwd ):
# Set up the traditional tool state/params
tool_id = 'upload1'
@@ -1054,16 +1045,15 @@
if input.type == "upload_dataset":
dataset_upload_inputs.append( input )
# Library-specific params
- params = util.Params( kwd ) # is this filetoolparam safe?
- show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- server_dir = util.restore_text( params.get( 'server_dir', '' ) )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ server_dir = kwd.get( 'server_dir', '' )
if replace_dataset not in [ None, 'None' ]:
replace_id = trans.security.encode_id( replace_dataset.id )
else:
replace_id = None
- upload_option = params.get( 'upload_option', 'upload_file' )
+ upload_option = kwd.get( 'upload_option', 'upload_file' )
response_code = 200
if upload_option == 'upload_directory':
if server_dir in [ None, 'None', '' ]:
@@ -1092,7 +1082,7 @@
try:
# FIXME: instead of passing params here ( which have been processed by util.Params(), the original kwd
# should be passed so that complex objects that may have been included in the initial request remain.
- library_bunch = upload_common.handle_library_params( trans, params, folder_id, replace_dataset )
+ library_bunch = upload_common.handle_library_params( trans, kwd, folder_id, replace_dataset )
except:
response_code = 500
message = "Unable to parse upload parameters, please report this error."
@@ -1103,9 +1093,9 @@
tool_params = upload_common.persist_uploads( tool_params )
uploaded_datasets = upload_common.get_uploaded_datasets( trans, cntrller, tool_params, precreated_datasets, dataset_upload_inputs, library_bunch=library_bunch )
elif upload_option == 'upload_directory':
- uploaded_datasets, response_code, message = self.get_server_dir_uploaded_datasets( trans, cntrller, params, full_dir, import_dir_desc, library_bunch, response_code, message )
+ uploaded_datasets, response_code, message = self.get_server_dir_uploaded_datasets( trans, cntrller, kwd, full_dir, import_dir_desc, library_bunch, response_code, message )
elif upload_option == 'upload_paths':
- uploaded_datasets, response_code, message = self.get_path_paste_uploaded_datasets( trans, cntrller, params, library_bunch, response_code, message )
+ uploaded_datasets, response_code, message = self.get_path_paste_uploaded_datasets( trans, cntrller, kwd, library_bunch, response_code, message )
upload_common.cleanup_unused_precreated_datasets( precreated_datasets )
if upload_option == 'upload_file' and not uploaded_datasets:
response_code = 400
@@ -1121,7 +1111,7 @@
replace_id=replace_id,
upload_option=upload_option,
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status='error' ) )
json_file_path = upload_common.create_paramfile( trans, uploaded_datasets )
data_list = [ ud.data for ud in uploaded_datasets ]
@@ -1135,7 +1125,7 @@
def make_library_uploaded_dataset( self, trans, cntrller, params, name, path, type, library_bunch, in_folder=None ):
link_data_only = params.get( 'link_data_only', 'copy_files' )
uuid_str = params.get( 'uuid', None )
- file_type = params.file_type
+ file_type = params.get( 'file_type' )
library_bunch.replace_dataset = None # not valid for these types of upload
uploaded_dataset = util.bunch.Bunch()
new_name = name
@@ -1151,8 +1141,8 @@
uploaded_dataset.type = type
uploaded_dataset.ext = None
uploaded_dataset.file_type = file_type
- uploaded_dataset.dbkey = params.dbkey
- uploaded_dataset.space_to_tab = params.space_to_tab
+ uploaded_dataset.dbkey = params.get( 'dbkey' )
+ uploaded_dataset.space_to_tab = params.get( 'space_to_tab' )
if in_folder:
uploaded_dataset.in_folder = in_folder
uploaded_dataset.data = upload_common.new_upload( trans, cntrller, uploaded_dataset, library_bunch )
@@ -1247,7 +1237,7 @@
files_and_folders.append((file_path, file, in_folder))
return files_and_folders
def _paths_list(self, params):
- return [ (l.strip(), os.path.abspath(l.strip())) for l in params.filesystem_paths.splitlines() if l.strip() ]
+ return [ (l.strip(), os.path.abspath(l.strip())) for l in params.get( 'filesystem_paths', '' ).splitlines() if l.strip() ]
def _check_path_paste_params(self, params):
if params.get( 'filesystem_paths', '' ) == '':
@@ -1259,33 +1249,32 @@
if not os.path.exists( path ):
bad_paths.append( path )
if bad_paths:
- message = "Invalid paths:<br><ul><li>%s</li></ul>" % "</li><li>".join( bad_paths )
+ message = 'Invalid paths: "%s".' % '", "'.join( bad_paths )
response_code = 400
return None, response_code, message
return None
@web.expose
def add_history_datasets_to_library( self, trans, cntrller, library_id, folder_id, hda_ids='', **kwd ):
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- ldda_message = util.restore_text( params.get( 'ldda_message', '' ) )
- show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
- use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
- replace_id = params.get( 'replace_id', None )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ ldda_message = kwd.get( 'ldda_message', '' )
+ show_deleted = kwd.get( 'show_deleted', False )
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
+ replace_id = kwd.get( 'replace_id', None )
replace_dataset = None
- upload_option = params.get( 'upload_option', 'import_from_history' )
- if params.get( 'files_0|space_to_tab', False ):
- space_to_tab = params.get( 'files_0|space_to_tab', '' )
+ upload_option = kwd.get( 'upload_option', 'import_from_history' )
+ if kwd.get( 'files_0|space_to_tab', False ):
+ space_to_tab = kwd.get( 'files_0|space_to_tab', '' )
else:
- space_to_tab = params.get( 'space_to_tab', '' )
- link_data_only = params.get( 'link_data_only', 'copy_files' )
- dbkey = params.get( 'dbkey', '?' )
+ space_to_tab = kwd.get( 'space_to_tab', '' )
+ link_data_only = kwd.get( 'link_data_only', 'copy_files' )
+ dbkey = kwd.get( 'dbkey', '?' )
if isinstance( dbkey, list ):
last_used_build = dbkey[0]
else:
last_used_build = dbkey
- roles = params.get( 'roles', '' )
+ roles = kwd.get( 'roles', '' )
is_admin = trans.user_is_admin() and cntrller in ( 'library_admin', 'api' )
current_user_roles = trans.get_current_user_roles()
widgets = []
@@ -1323,9 +1312,9 @@
cntrller=cntrller,
id=library_id,
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status='error' ) )
- if params.get( 'add_history_datasets_to_library_button', False ):
+ if kwd.get( 'add_history_datasets_to_library_button', False ):
hda_ids = util.listify( hda_ids )
if hda_ids:
dataset_names = []
@@ -1354,7 +1343,7 @@
trans.app.security_agent.copy_library_permissions( trans, folder, ldda )
trans.app.security_agent.copy_library_permissions( trans, folder, ldda.library_dataset )
else:
- library_bunch = upload_common.handle_library_params( trans, params, folder_id, replace_dataset )
+ library_bunch = upload_common.handle_library_params( trans, kwd, folder_id, replace_dataset )
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
@@ -1422,12 +1411,12 @@
id=library_id,
created_ldda_ids=created_ldda_ids,
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status='done' ) )
else:
message = 'Select at least one dataset from the list of active datasets in your current history'
status = 'error'
- upload_option = params.get( 'upload_option', 'import_from_history' )
+ upload_option = kwd.get( 'upload_option', 'import_from_history' )
widgets = self._get_populated_widgets( folder )
# Send list of data formats to the upload form so the "extension" select list can be populated dynamically
file_formats = trans.app.datatypes_registry.upload_file_formats
@@ -1461,8 +1450,8 @@
link_data_only=link_data_only,
show_deleted=show_deleted,
ldda_message=ldda_message,
- message=message,
- status=status )
+ message=escape( message ),
+ status=escape( status ) )
def _build_roles_select_list( self, trans, cntrller, library, selected_role_ids=[] ):
# Get the list of legitimate roles to display on the upload form. If the library is public,
# all active roles are legitimate. If the library is restricted by the LIBRARY_ACCESS permission, only
@@ -1521,8 +1510,7 @@
def download_dataset_from_folder( self, trans, cntrller, id, library_id=None, **kwd ):
"""Catches the dataset id and displays file contents as directed"""
show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
- params = util.Params( kwd )
- use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
is_admin = trans.user_is_admin() and cntrller == 'library_admin'
current_user_roles = trans.get_current_user_roles()
try:
@@ -1555,15 +1543,14 @@
use_panels=use_panels,
id=library_id,
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status='error' ) )
@web.expose
def library_dataset_info( self, trans, cntrller, id, library_id, **kwd ):
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
- use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
is_admin = trans.user_is_admin() and cntrller == 'library_admin'
current_user_roles = trans.get_current_user_roles()
try:
@@ -1571,11 +1558,11 @@
except:
library_dataset = None
self._check_access( trans, cntrller, is_admin, library_dataset, current_user_roles, use_panels, library_id, show_deleted )
- if params.get( 'edit_attributes_button', False ):
+ if kwd.get( 'edit_attributes_button', False ):
self._check_modify( trans, cntrller, is_admin, library_dataset, current_user_roles, use_panels, library_id, show_deleted )
old_name = library_dataset.name
- new_name = util.restore_text( params.get( 'name', '' ) )
- new_info = util.restore_text( params.get( 'info', '' ) )
+ new_name = kwd.get( 'name', '' )
+ new_info = kwd.get( 'info', '' )
if not new_name:
message = 'Enter a valid name'
status = 'error'
@@ -1604,15 +1591,14 @@
widgets=widgets,
widget_fields_have_contents=widget_fields_have_contents,
show_deleted=show_deleted,
- message=message,
- status=status )
+ message=escape( message ),
+ status=escape( status ) )
@web.expose
def library_dataset_permissions( self, trans, cntrller, id, library_id, **kwd ):
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
- use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
is_admin = trans.user_is_admin() and cntrller == 'library_admin'
current_user_roles = trans.get_current_user_roles()
try:
@@ -1621,7 +1607,7 @@
library_dataset = None
self._check_access( trans, cntrller, is_admin, library_dataset, current_user_roles, use_panels, library_id, show_deleted )
self._check_manage( trans, cntrller, is_admin, library_dataset, current_user_roles, use_panels, library_id, show_deleted )
- if params.get( 'update_roles_button', False ):
+ if kwd.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():
@@ -1652,22 +1638,21 @@
roles=roles,
current_user_roles=current_user_roles,
show_deleted=show_deleted,
- message=message,
- status=status )
+ message=escape( message ),
+ status=escape( status ) )
@web.expose
def make_library_item_public( self, trans, cntrller, library_id, item_type, id, **kwd ):
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
- use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
current_user_roles = trans.get_current_user_roles()
is_admin = trans.user_is_admin() and cntrller == 'library_admin'
if item_type == 'library':
library = trans.sa_session.query( trans.model.Library ).get( trans.security.decode_id( id ) )
self._check_access( trans, cntrller, is_admin, library, current_user_roles, use_panels, library_id, show_deleted )
self._check_manage( trans, cntrller, is_admin, library, current_user_roles, use_panels, library_id, show_deleted )
- contents = util.string_as_bool( params.get( 'contents', 'False' ) )
+ contents = util.string_as_bool( kwd.get( 'contents', 'False' ) )
trans.app.security_agent.make_library_public( library, contents=contents )
if contents:
message = "The data library (%s) and all its contents have been made publicly accessible." % library.name
@@ -1694,7 +1679,7 @@
use_panels=use_panels,
id=library_id,
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status=status ) )
@web.expose
def act_on_multiple_datasets( self, trans, cntrller, library_id=None, ldda_ids='', **kwd ):
@@ -1718,12 +1703,11 @@
rval += '%s %i %s%s %s\r\n' % ( crc, size, self.url_base, quoted_fname, relpath )
return rval
# Perform an action on a list of library datasets.
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
- use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
- action = params.get( 'do_action', None )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
+ action = kwd.get( 'do_action', None )
lddas = []
error = False
is_admin = trans.user_is_admin() and cntrller == 'library_admin'
@@ -1738,7 +1722,7 @@
else:
if action in [ 'import_to_current_history', 'import_to_histories' ]:
new_kwd = {}
- if action == 'import_to_current_history':
+ if current_history is not None and action == 'import_to_current_history':
encoded_current_history_id = trans.security.encode_id( current_history.id )
selected_history_id = encoded_current_history_id
new_kwd[ 'do_action' ] = action
@@ -1809,7 +1793,7 @@
folder_id=folder_id,
id=",".join( encoded_ldda_ids ),
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status=status ) )
else:
message = "You are not authorized to manage permissions on any of the selected datasets."
@@ -1970,11 +1954,11 @@
use_panels=use_panels,
id=library_id,
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status=status ) )
else:
# We arrived here from the library_dataset_search_results page, so redirect there.
- search_term = params.get( 'search_term', '' )
+ search_term = kwd.get( 'search_term', '' )
comptypes = get_comptypes( trans )
return trans.fill_template( '/library/common/library_dataset_search_results.mako',
cntrller=cntrller,
@@ -1984,8 +1968,8 @@
lddas=lddas,
show_deleted=show_deleted,
use_panels=use_panels,
- message=message,
- status=status )
+ message=escape( message ),
+ status=escape( status ) )
@web.expose
def import_datasets_to_histories( self, trans, cntrller, library_id='', folder_id='', ldda_ids='', target_history_id='', target_history_ids='', new_history_name='', **kwd ):
@@ -1995,12 +1979,11 @@
# - a select list option for acting on multiple selected datasets within a library
# ( ldda_ids is a comma separated string of ldda ids )
# - a menu option for a library dataset search result set ( ldda_ids is a comma separated string of ldda ids )
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
- use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
- action = params.get( 'do_action', None )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
+ action = kwd.get( 'do_action', None )
user = trans.get_user()
current_history = trans.get_history()
if library_id:
@@ -2019,7 +2002,7 @@
target_history_ids = set( [ trans.security.decode_id( target_history_id ) for target_history_id in target_history_ids if target_history_id ] )
elif target_history_id:
target_history_ids = [ trans.security.decode_id( target_history_id ) ]
- if params.get( 'import_datasets_to_histories_button', False ):
+ if kwd.get( 'import_datasets_to_histories_button', False ):
invalid_datasets = 0
if not ldda_ids or not ( target_history_ids or new_history_name ):
message = "You must provide one or more source library datasets and one or more target histories."
@@ -2083,11 +2066,13 @@
# to the lddas in order for the menu optin to be available.
ldda = trans.sa_session.query( trans.model.LibraryDatasetDatasetAssociation ).get( ldda_id )
source_lddas.append( ldda )
+ if current_history is None:
+ current_history = trans.get_history( create=True )
if current_history is not None:
target_histories = [ current_history ]
else:
target_histories = []
- message = 'You must have a history before you can import datasets. You can do this by <a href="%s" target="_top">loading the analysis interface</a>.' % url_for(controller='root')
+ message = 'You must have a history before you can import datasets. You can do this by loading the analysis interface.'
status = 'error'
if user:
target_histories = user.active_histories
@@ -2097,7 +2082,7 @@
action='browse_library',
cntrller=cntrller,
id=library_id,
- message=util.sanitize_text( message ),
+ message=message,
status=status ) )
return trans.fill_template( "/library/common/import_datasets_to_histories.mako",
cntrller=cntrller,
@@ -2111,15 +2096,14 @@
new_history_name=new_history_name,
show_deleted=show_deleted,
use_panels=use_panels,
- message=message,
- status=status )
+ message=escape( message ),
+ status=escape( status ) )
@web.expose
def manage_template_inheritance( self, trans, cntrller, item_type, library_id, folder_id=None, ldda_id=None, **kwd ):
- params = util.Params( kwd )
- show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
- use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
is_admin = ( trans.user_is_admin() and cntrller == 'library_admin' )
current_user_roles = trans.get_current_user_roles()
try:
@@ -2138,7 +2122,7 @@
cntrller=cntrller,
id=library_id,
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status='error' ) )
info_association, inherited = item.get_info_association( restrict=True )
if info_association:
@@ -2157,7 +2141,7 @@
folder_id=folder_id,
id=id,
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status='done' ) )
@web.expose
def move_library_item( self, trans, cntrller, item_type, item_id, source_library_id='', make_target_current=True, **kwd ):
@@ -2168,11 +2152,10 @@
# 'ldda' and item_id is a comma separated string of ldda ids )
# - a menu option for a library dataset search result set ( item_type is 'ldda' and item_id is a
# comma separated string of ldda ids )
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
- use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
make_target_current = util.string_as_bool( make_target_current )
is_admin = trans.user_is_admin() and cntrller == 'library_admin'
user = trans.get_user()
@@ -2186,14 +2169,14 @@
else:
# Request sent from the library_dataset_search_results page.
source_library = None
- target_library_id = params.get( 'target_library_id', '' )
+ target_library_id = kwd.get( 'target_library_id', '' )
if target_library_id not in [ '', 'none', None ]:
target_library = trans.sa_session.query( trans.model.Library ).get( trans.security.decode_id( target_library_id ) )
elif make_target_current:
target_library = source_library
else:
target_library = None
- target_folder_id = params.get( 'target_folder_id', '' )
+ target_folder_id = kwd.get( 'target_folder_id', '' )
if target_folder_id not in [ '', 'none', None ]:
target_folder = trans.sa_session.query( trans.model.LibraryFolder ).get( trans.security.decode_id( target_folder_id ) )
if target_library is None:
@@ -2208,7 +2191,7 @@
elif item_type == 'folder':
move_folder_id = item_id
move_folder = trans.sa_session.query( trans.model.LibraryFolder ).get( trans.security.decode_id( move_folder_id ) )
- if params.get( 'move_library_item_button', False ):
+ if kwd.get( 'move_library_item_button', False ):
if not ( move_ldda_ids or move_folder_id ) or target_folder_id in [ '', 'none', None ]:
message = "You must select a source folder or one or more source datasets, and a target folder."
status = 'error'
@@ -2372,8 +2355,8 @@
target_folder_id_select_field=target_folder_id_select_field,
show_deleted=show_deleted,
use_panels=use_panels,
- message=message,
- status=status )
+ message=escape( message ),
+ status=escape( status ) )
@web.expose
def delete_library_item( self, trans, cntrller, library_id, item_id, item_type, **kwd ):
# This action will handle deleting all types of library items. State is saved for libraries and
@@ -2541,7 +2524,7 @@
action='browse_libraries',
cntrller=cntrller,
use_panels=use_panels,
- message=util.sanitize_text( message ),
+ message=message,
status='error' ) )
return trans.response.send_redirect( web.url_for( controller='library_common',
action='browse_library',
@@ -2549,7 +2532,7 @@
use_panels=use_panels,
id=library_id,
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status='error' ) )
def _check_add( self, trans, cntrller, is_admin, item, current_user_roles, use_panels, library_id, show_deleted ):
# Deny access if the user is not an admin and does not have the LIBRARY_ADD permission.
@@ -2564,7 +2547,7 @@
use_panels=use_panels,
id=library_id,
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status='error' ) )
def _check_manage( self, trans, cntrller, is_admin, item, current_user_roles, use_panels, library_id, show_deleted ):
if isinstance( item, trans.model.LibraryDataset ):
@@ -2580,7 +2563,7 @@
id=library_id,
cntrller=cntrller,
use_panels=use_panels,
- message=util.sanitize_text( message ),
+ message=message,
status='error' ) )
# Deny access if the user is not an admin and does not have the LIBRARY_MANAGE permission.
if not ( is_admin or trans.app.security_agent.can_manage_library_item( current_user_roles, item ) ):
@@ -2592,7 +2575,7 @@
id=library_id,
cntrller=cntrller,
use_panels=use_panels,
- message=util.sanitize_text( message ),
+ message=message,
status='error' ) )
def _check_modify( self, trans, cntrller, is_admin, item, current_user_roles, use_panels, library_id, show_deleted ):
# Deny modification if the user is not an admin and does not have the LIBRARY_MODIFY permission.
@@ -2606,7 +2589,7 @@
id=library_id,
use_panels=use_panels,
show_deleted=show_deleted,
- message=util.sanitize_text( message ),
+ message=message,
status='error' ) )
# ---- Utility methods -------------------------------------------------------
@@ -2740,9 +2723,8 @@
return map( operator.getitem, intermed, ( -1, ) * len( intermed ) )
def lucene_search( trans, cntrller, search_term, search_url, **kwd ):
"""Return display of results from a full-text lucene search of data libraries."""
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
full_url = "%s/find?%s" % ( search_url, urllib.urlencode( { "kwd" : search_term } ) )
response = urllib2.urlopen( full_url )
ldda_ids = util.json.loads( response.read() )[ "ids" ]
@@ -2751,9 +2733,8 @@
return status, message, get_sorted_accessible_library_items( trans, cntrller, lddas, 'name' )
def whoosh_search( trans, cntrller, search_term, **kwd ):
"""Return display of results from a full-text whoosh search of data libraries."""
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
ok = True
if whoosh_search_enabled:
whoosh_index_dir = trans.app.config.whoosh_index_dir
diff -r 704efd2f5e06b9f6e63246d2324874cf7f28d83a -r 07404a82972d877b5529fffaeb3e7e05b69a02a3 templates/webapps/galaxy/library/common/browse_library.mako
--- a/templates/webapps/galaxy/library/common/browse_library.mako
+++ b/templates/webapps/galaxy/library/common/browse_library.mako
@@ -236,29 +236,29 @@
%if current_version and ( not ldda.library_dataset.deleted or show_deleted ):
<tr class="datasetRow"
%if parent is not None:
- parent="${parent}"
+ parent="${parent | h}"
%endif
- id="libraryItem-${ldda.id}">
+ id="libraryItem-${ldda.id | h}"><td style="padding-left: ${pad+20}px;">
- <input style="float: left;" type="checkbox" name="ldda_ids" id="${trans.security.encode_id( ldda.id )}" value="${trans.security.encode_id( ldda.id )}"
+ <input style="float: left;" type="checkbox" name="ldda_ids" id="${trans.security.encode_id( ldda.id ) | h}" value="${trans.security.encode_id( ldda.id ) | h}"
%if selected:
checked="checked"
%endif
/>
%if simple:
- <label for="${trans.security.encode_id( ldda.id )}">${ util.unicodify( ldda.name )}</label>
+ <label for="${trans.security.encode_id( ldda.id ) | h}">${ util.unicodify( ldda.name ) | h}</label>
%else:
- <div style="float: left; margin-left: 1px;" class="menubutton split popup" id="dataset-${ldda.id}-popup">
+ <div style="float: left; margin-left: 1px;" class="menubutton split popup" id="dataset-${ldda.id | h}-popup"><a class="view-info" href="${h.url_for( controller='library_common', action='ldda_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 ), use_panels=use_panels, show_deleted=show_deleted )}">
%if ldda.library_dataset.deleted:
- <div class="libraryItem-error">${util.unicodify( ldda.name )}</div>
+ <div class="libraryItem-error">${util.unicodify( ldda.name ) | h}</div>
%else:
- ${util.unicodify( ldda.name )}
+ ${util.unicodify( ldda.name ) | h}
%endif
</a></div>
%if not library.deleted:
- <div popupmenu="dataset-${ldda.id}-popup">
+ <div popupmenu="dataset-${ldda.id | h}-popup">
%if not branch_deleted( folder ) and not ldda.library_dataset.deleted and can_modify:
<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 ), use_panels=use_panels, show_deleted=show_deleted )}">Edit information</a><a class="action-button" href="${h.url_for( controller='library_common', action='move_library_item', cntrller=cntrller, item_type='ldda', item_id=trans.security.encode_id( ldda.id ), source_library_id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Move this dataset</a>
@@ -287,7 +287,7 @@
%endif
%if can_modify:
%if not library.deleted and not branch_deleted( folder ) and not ldda.library_dataset.deleted:
- <a class="action-button" confirm="Click OK to delete dataset '${util.unicodify( ldda.name )}'." href="${h.url_for( controller='library_common', action='delete_library_item', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), item_id=trans.security.encode_id( library_dataset.id ), item_type='library_dataset', show_deleted=show_deleted )}">Delete this dataset</a>
+ <a class="action-button" confirm="Click OK to delete dataset '${util.unicodify( ldda.name ) | h}'." href="${h.url_for( controller='library_common', action='delete_library_item', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), item_id=trans.security.encode_id( library_dataset.id ), item_type='library_dataset', show_deleted=show_deleted )}">Delete this dataset</a>
%elif not library.deleted and not branch_deleted( folder ) and not ldda.library_dataset.purged and ldda.library_dataset.deleted:
<a class="action-button" href="${h.url_for( controller='library_common', action='undelete_library_item', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), item_id=trans.security.encode_id( library_dataset.id ), item_type='library_dataset', show_deleted=show_deleted )}">Undelete this dataset</a>
%endif
@@ -298,10 +298,10 @@
</td>
% if not simple:
<td id="libraryItemInfo">${render_library_item_info( ldda )}</td>
- <td>${ldda.extension}</td>
+ <td>${ldda.extension | h}</td>
% endif
- <td>${ldda.create_time.strftime( trans.app.config.pretty_datetime_format )}</td>
- <td>${ldda.get_size( nice_size=True )}</td>
+ <td>${ldda.create_time.strftime( trans.app.config.pretty_datetime_format ) | h}</td>
+ <td>${ldda.get_size( nice_size=True ) | h}</td></tr><%
my_row = row_counter.count
@@ -355,28 +355,28 @@
%>
%if not root_folder and ( not folder.deleted or show_deleted ):
<% encoded_id = trans.security.encode_id( folder.id ) %>
- <tr id="folder-${encoded_id}" class="folderRow libraryOrFolderRow"
+ <tr id="folder-${encoded_id | h}" class="folderRow libraryOrFolderRow"
%if parent is not None:
- parent="${parent}"
+ parent="${parent | h}"
style="display: none;"
%endif
>
- <td style="padding-left: ${folder_pad}px;">
+ <td style="padding-left: ${folder_pad | h}px;"><input type="checkbox" class="folderCheckbox"/>
- <span class="expandLink folder-${encoded_id}-click">
- <div style="float: left; margin-left: 2px;" class="menubutton split popup" id="folder_img-${folder.id}-popup">
- <a class="folder-${encoded_id}-click" href="javascript:void(0);">
+ <span class="expandLink folder-${encoded_id | h}-click">
+ <div style="float: left; margin-left: 2px;" class="menubutton split popup" id="folder_img-${folder.id | h}-popup">
+ <a class="folder-${encoded_id | h}-click" href="javascript:void(0);"><span class="rowIcon"></span>
%if folder.deleted:
- <div class="libraryItem-error">${folder.name}</div>
+ <div class="libraryItem-error">${folder.name | h}</div>
%else:
- ${folder.name}
+ ${folder.name | h}
%endif
</a></div></span>
%if not library.deleted:
- <div popupmenu="folder_img-${folder.id}-popup">
+ <div popupmenu="folder_img-${folder.id | h}-popup">
%if not branch_deleted( folder ) and can_add:
<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 ), use_panels=use_panels, show_deleted=show_deleted )}">Add datasets</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=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Add sub-folder</a>
@@ -407,7 +407,7 @@
%endif
%if can_modify:
%if not library.deleted and not folder.deleted:
- <a class="action-button" confirm="Click OK to delete the folder '${folder.name}.'" href="${h.url_for( controller='library_common', action='delete_library_item', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), item_id=trans.security.encode_id( folder.id ), item_type='folder', show_deleted=show_deleted )}">Delete this folder</a>
+ <a class="action-button" confirm="Click OK to delete the folder '${folder.name | h}.'" href="${h.url_for( controller='library_common', action='delete_library_item', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), item_id=trans.security.encode_id( folder.id ), item_type='folder', show_deleted=show_deleted )}">Delete this folder</a>
%elif not library.deleted and folder.deleted and not folder.purged:
<a class="action-button" href="${h.url_for( controller='library_common', action='undelete_library_item', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), item_id=trans.security.encode_id( folder.id ), item_type='folder', show_deleted=show_deleted )}">Undelete this folder</a>
%endif
@@ -416,7 +416,7 @@
%endif
<td>
%if folder.description:
- ${folder.description}
+ ${folder.description | h}
%endif
<td colspan="3"></td></tr>
@@ -504,7 +504,7 @@
return str( self.count )
%>
- <h2>Data Library “${library.name}”</h2>
+ <h2>Data Library “${library.name | h}”</h2><ul class="manage-table-actions">
%if not library.deleted and ( is_admin or can_add ):
@@ -517,7 +517,7 @@
%if not library.deleted:
%if 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 ), use_panels=use_panels, show_deleted=show_deleted )}">Edit information</a>
- <a class="action-button" confirm="Click OK to delete the library named '${library.name}'." href="${h.url_for( controller='library_common', action='delete_library_item', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), item_id=trans.security.encode_id( library.id ), item_type='library' )}">Delete this data library</a>
+ <a class="action-button" confirm="Click OK to delete the library named '${library.name | h}'." href="${h.url_for( controller='library_common', action='delete_library_item', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), item_id=trans.security.encode_id( library.id ), item_type='library' )}">Delete this data library</a>
%if show_deleted:
<a class="action-button" href="${h.url_for( controller='library_common', action='browse_library', cntrller=cntrller, id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=False )}">Hide deleted items</a>
%else:
@@ -555,7 +555,7 @@
%if library.synopsis not in [ '', 'None', None ]:
<div class="libraryItemBody">
- ${library.synopsis}
+ ${library.synopsis | h}
</div>
%endif
@@ -610,6 +610,6 @@
${render_compression_types_help( comptypes )}
%endif
%if not has_accessible_folders:
- The data library '${library.name}' does not contain any datasets that you can access.
+ The data library '${library.name | h}' does not contain any datasets that you can access.
%endif
</%def>
diff -r 704efd2f5e06b9f6e63246d2324874cf7f28d83a -r 07404a82972d877b5529fffaeb3e7e05b69a02a3 templates/webapps/galaxy/library/common/browse_library_opt.mako
--- a/templates/webapps/galaxy/library/common/browse_library_opt.mako
+++ b/templates/webapps/galaxy/library/common/browse_library_opt.mako
@@ -228,29 +228,29 @@
%if current_version and ( not ldda.library_dataset.deleted or show_deleted ):
<tr class="datasetRow"
%if parent is not None:
- parent="${parent}"
+ parent="${parent | h}"
%endif
- id="libraryItem-${ldda.id}">
+ id="libraryItem-${ldda.id | h}"><td style="padding-left: ${pad+20}px;">
- <input style="float: left;" type="checkbox" name="ldda_ids" id="${trans.security.encode_id( ldda.id )}" value="${trans.security.encode_id( ldda.id )}"
+ <input style="float: left;" type="checkbox" name="ldda_ids" id="${trans.security.encode_id( ldda.id ) | h}" value="${trans.security.encode_id( ldda.id ) | h}"
%if selected:
checked="checked"
%endif
/>
%if simple:
- <label for="${trans.security.encode_id( ldda.id )}">${ util.unicodify( ldda.name )}</label>
+ <label for="${trans.security.encode_id( ldda.id ) | h}">${ util.unicodify( ldda.name ) | h}</label>
%else:
- <div style="float: left; margin-left: 1px;" class="menubutton split popup" id="dataset-${ldda.id}-popup">
+ <div style="float: left; margin-left: 1px;" class="menubutton split popup" id="dataset-${ldda.id | h}-popup"><a class="view-info" href="${h.url_for( controller='library_common', action='ldda_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 ), use_panels=use_panels, show_deleted=show_deleted )}">
%if ldda.library_dataset.deleted:
- <div class="libraryItem-error">${util.unicodify( ldda.name )}</div>
+ <div class="libraryItem-error">${util.unicodify( ldda.name ) | h}</div>
%else:
- ${util.unicodify( ldda.name )}
+ ${util.unicodify( ldda.name ) | h}
%endif
</a></div>
%if not library.deleted:
- <div popupmenu="dataset-${ldda.id}-popup">
+ <div popupmenu="dataset-${ldda.id | h}-popup">
%if not branch_deleted( folder ) and not ldda.library_dataset.deleted and can_modify:
<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 ), use_panels=use_panels, show_deleted=show_deleted )}">Edit information</a><a class="action-button" href="${h.url_for( controller='library_common', action='move_library_item', cntrller=cntrller, item_type='ldda', item_id=trans.security.encode_id( ldda.id ), source_library_id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Move this dataset</a>
@@ -279,7 +279,7 @@
%endif
%if can_modify:
%if not library.deleted and not branch_deleted( folder ) and not ldda.library_dataset.deleted:
- <a class="action-button" confirm="Click OK to delete dataset '${util.unicodify( ldda.name )}'." href="${h.url_for( controller='library_common', action='delete_library_item', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), item_id=trans.security.encode_id( library_dataset.id ), item_type='library_dataset', show_deleted=show_deleted )}">Delete this dataset</a>
+ <a class="action-button" confirm="Click OK to delete dataset '${util.unicodify( ldda.name ) | h}'." href="${h.url_for( controller='library_common', action='delete_library_item', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), item_id=trans.security.encode_id( library_dataset.id ), item_type='library_dataset', show_deleted=show_deleted )}">Delete this dataset</a>
%elif not library.deleted and not branch_deleted( folder ) and not ldda.library_dataset.purged and ldda.library_dataset.deleted:
<a class="action-button" href="${h.url_for( controller='library_common', action='undelete_library_item', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), item_id=trans.security.encode_id( library_dataset.id ), item_type='library_dataset', show_deleted=show_deleted )}">Undelete this dataset</a>
%endif
@@ -290,10 +290,10 @@
</td>
% if not simple:
<td id="libraryItemInfo">${render_library_item_info( ldda )}</td>
- <td>${ldda.extension}</td>
+ <td>${ldda.extension | h}</td>
% endif
- <td>${ldda.create_time.strftime( "%Y-%m-%d" )}</td>
- <td>${ldda.get_size( nice_size=True )}</td>
+ <td>${ldda.create_time.strftime( "%Y-%m-%d" ) | h}</td>
+ <td>${ldda.get_size( nice_size=True ) | h}</td></tr><%
my_row = row_counter.count
@@ -362,28 +362,28 @@
%>
%if not root_folder and ( not folder.deleted or show_deleted ):
<% encoded_id = trans.security.encode_id( folder.id ) %>
- <tr id="folder-${encoded_id}" class="folderRow libraryOrFolderRow"
+ <tr id="folder-${encoded_id | h}" class="folderRow libraryOrFolderRow"
%if parent is not None:
- parent="${parent}"
+ parent="${parent | h}"
style="display: none;"
%endif
>
- <td style="padding-left: ${folder_pad}px;">
+ <td style="padding-left: ${folder_pad | h}px;"><input type="checkbox" class="folderCheckbox"/>
- <span class="expandLink folder-${encoded_id}-click">
- <div style="float: left; margin-left: 2px;" class="menubutton split popup" id="folder_img-${folder.id}-popup">
- <a class="folder-${encoded_id}-click" href="javascript:void(0);">
+ <span class="expandLink folder-${encoded_id | h}-click">
+ <div style="float: left; margin-left: 2px;" class="menubutton split popup" id="folder_img-${folder.id | h}-popup">
+ <a class="folder-${encoded_id | h}-click" href="javascript:void(0);"><span class="rowIcon"></span>
%if folder.deleted:
- <div class="libraryItem-error">${folder.name}</div>
+ <div class="libraryItem-error">${folder.name | h}</div>
%else:
- ${folder.name}
+ ${folder.name | h}
%endif
</a></div></span>
%if not library.deleted:
- <div popupmenu="folder_img-${folder.id}-popup">
+ <div popupmenu="folder_img-${folder.id | h}-popup">
%if not branch_deleted( folder ) and can_add:
<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 ), use_panels=use_panels, show_deleted=show_deleted )}">Add datasets</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=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Add sub-folder</a>
@@ -414,7 +414,7 @@
%endif
%if can_modify:
%if not library.deleted and not folder.deleted:
- <a class="action-button" confirm="Click OK to delete the folder '${folder.name}.'" href="${h.url_for( controller='library_common', action='delete_library_item', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), item_id=trans.security.encode_id( folder.id ), item_type='folder', show_deleted=show_deleted )}">Delete this folder</a>
+ <a class="action-button" confirm="Click OK to delete the folder '${folder.name | h}.'" href="${h.url_for( controller='library_common', action='delete_library_item', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), item_id=trans.security.encode_id( folder.id ), item_type='folder', show_deleted=show_deleted )}">Delete this folder</a>
%elif not library.deleted and folder.deleted and not folder.purged:
<a class="action-button" href="${h.url_for( controller='library_common', action='undelete_library_item', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), item_id=trans.security.encode_id( folder.id ), item_type='folder', show_deleted=show_deleted )}">Undelete this folder</a>
%endif
@@ -423,7 +423,7 @@
%endif
<td>
%if folder.description:
- ${folder.description}
+ ${folder.description | h}
%endif
<td colspan="3"></td></tr>
@@ -515,12 +515,12 @@
<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 ), use_panels=use_panels, show_deleted=show_deleted )}">Add folder</a></li>
%endif
%if ( ( not library.deleted ) and ( can_modify or can_manage ) ) or ( can_modify and not library.purged ) or ( library.purged ):
- <li><a class="action-button" id="library-${library.id}-popup" class="menubutton">Library Actions</a></li>
- <div popupmenu="library-${library.id}-popup">
+ <li><a class="action-button" id="library-${library.id | h}-popup" class="menubutton">Library Actions</a></li>
+ <div popupmenu="library-${library.id | h}-popup">
%if not library.deleted:
%if 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 ), use_panels=use_panels, show_deleted=show_deleted )}">Edit information</a>
- <a class="action-button" confirm="Click OK to delete the library named '${library.name}'." href="${h.url_for( controller='library_common', action='delete_library_item', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), item_id=trans.security.encode_id( library.id ), item_type='library' )}">Delete this data library</a>
+ <a class="action-button" confirm="Click OK to delete the library named '${library.name | h}'." href="${h.url_for( controller='library_common', action='delete_library_item', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), item_id=trans.security.encode_id( library.id ), item_type='library' )}">Delete this data library</a>
%if show_deleted:
<a class="action-button" href="${h.url_for( controller='library_common', action='browse_library', cntrller=cntrller, id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=False )}">Hide deleted items</a>
%else:
@@ -558,7 +558,7 @@
%if library.synopsis not in [ '', 'None', None ]:
<div class="libraryItemBody">
- ${library.synopsis}
+ ${library.synopsis | h}
</div>
%endif
@@ -616,6 +616,6 @@
${render_compression_types_help( comptypes )}
%endif
%if not has_accessible_folders:
- The data library '${library.name}' does not contain any datasets that you can access.
+ The data library '${library.name | h}' does not contain any datasets that you can access.
%endif
</%def>
diff -r 704efd2f5e06b9f6e63246d2324874cf7f28d83a -r 07404a82972d877b5529fffaeb3e7e05b69a02a3 templates/webapps/galaxy/library/common/common.mako
--- a/templates/webapps/galaxy/library/common/common.mako
+++ b/templates/webapps/galaxy/library/common/common.mako
@@ -88,19 +88,19 @@
else:
tool_form_title = 'Upload files'
%>
- <div class="toolFormTitle">${tool_form_title}</div>
+ <div class="toolFormTitle">${tool_form_title | h}</div><div class="toolFormBody"><form name="upload_library_dataset" id="upload_library_dataset" action="${action}" enctype="multipart/form-data" method="post"><input type="hidden" name="tool_id" value="upload1"/><input type="hidden" name="tool_state" value="None"/>
- <input type="hidden" name="cntrller" value="${cntrller}"/>
- <input type="hidden" name="library_id" value="${library_id}"/>
- <input type="hidden" name="folder_id" value="${folder_id}"/>
- <input type="hidden" name="show_deleted" value="${show_deleted}"/>
+ <input type="hidden" name="cntrller" value="${cntrller | h}"/>
+ <input type="hidden" name="library_id" value="${library_id | h}"/>
+ <input type="hidden" name="folder_id" value="${folder_id | h}"/>
+ <input type="hidden" name="show_deleted" value="${show_deleted | h}"/>
%if replace_dataset not in [ None, 'None' ]:
- <input type="hidden" name="replace_id" value="${trans.security.encode_id( replace_dataset.id )}"/>
+ <input type="hidden" name="replace_id" value="${trans.security.encode_id( replace_dataset.id ) | h}"/><div class="form-row">
- You are currently selecting a new file to replace '<a href="${h.url_for( controller='library_common', action='ldda_info', cntrller=cntrller, library_id=library_id, folder_id=folder_id, id=trans.security.encode_id( replace_dataset.library_dataset_dataset_association.id ) )}">${util.unicodify( replace_dataset.name )}</a>'.
+ You are currently selecting a new file to replace '<a href="${h.url_for( controller='library_common', action='ldda_info', cntrller=cntrller, library_id=library_id, folder_id=folder_id, id=trans.security.encode_id( replace_dataset.library_dataset_dataset_association.id ) )}">${util.unicodify( replace_dataset.name ) | h}</a>'.
<div style="clear: both"></div></div>
%endif
@@ -120,7 +120,7 @@
<select name="file_type"><option value="auto" selected>Auto-detect</option>
%for file_format in file_formats:
- <option value="${file_format}">${file_format}</option>
+ <option value="${file_format | h}">${file_format | h}</option>
%endfor
</select></div>
@@ -176,23 +176,23 @@
%for entry in os.listdir( import_dir ):
## Do not include entries that are not directories
%if os.path.isdir( os.path.join( import_dir, entry ) ):
- <option>${entry}</option>
+ <option>${entry | h}</option>
%endif
%endfor
%else:
%if ( trans.user_is_admin() and cntrller == 'library_admin' ):
- <option>${import_dir}</option>
+ <option>${import_dir | h}</option>
%else:
- <option>${trans.user.email}</option>
+ <option>${trans.user.email | h}</option>
%endif
%endif
</select></div><div class="toolParamHelp" style="clear: both;">
%if contains_directories:
- Upload all files in a sub-directory of <strong>${import_dir}</strong> on the Galaxy server.
+ Upload all files in a sub-directory of <strong>${import_dir | h}</strong> on the Galaxy server.
%else:
- Upload all files in <strong>${import_dir}</strong> on the Galaxy server.
+ Upload all files in <strong>${import_dir | h}</strong> on the Galaxy server.
%endif
</div><div style="clear: both"></div>
@@ -282,9 +282,9 @@
%>
%for dbkey in dbkeys:
%if dbkey[1] == default_selected:
- <option value="${dbkey[1]}" selected>${dbkey[0]}</option>
+ <option value="${dbkey[1] | h}" selected>${dbkey[0] | h}</option>
%else:
- <option value="${dbkey[1]}">${dbkey[0]}</option>
+ <option value="${dbkey[1] | h}">${dbkey[0] | h}</option>
%endif
%endfor
</select>
@@ -295,7 +295,7 @@
<label>Message:</label><div class="form-row-input">
%if ldda_message:
- <textarea name="ldda_message" rows="3" cols="35">${ldda_message}</textarea>
+ <textarea name="ldda_message" rows="3" cols="35">${ldda_message | h}</textarea>
%else:
<textarea name="ldda_message" rows="3" cols="35"></textarea>
%endif
@@ -320,13 +320,13 @@
%if widgets:
%for i, field in enumerate( widgets ):
<div class="form-row">
- <label>${field[ 'label' ]}</label>
+ <label>${field[ 'label' ] | h}</label><div class="form-row-input">
${field[ 'widget' ].get_html()}
</div><div class="toolParamHelp" style="clear: both;">
%if field[ 'helptext' ]:
- ${field[ 'helptext' ]}<br/>
+ ${field[ 'helptext' ] | h}<br/>
%endif
*Inherited template field
</div>
@@ -342,14 +342,14 @@
</div>
%elif upload_option == 'import_from_history':
<div class="toolForm">
- <div class="toolFormTitle">Active datasets in your current history (${ util.unicodify( history.name )})</div>
+ <div class="toolFormTitle">Active datasets in your current history (${ util.unicodify( history.name ) | h})</div><div class="toolFormBody">
%if history and history.active_datasets:
<form name="add_history_datasets_to_library" action="${h.url_for( controller='library_common', action='add_history_datasets_to_library', cntrller=cntrller, library_id=library_id )}" enctype="multipart/form-data" method="post">
- <input type="hidden" name="folder_id" value="${folder_id}"/>
- <input type="hidden" name="show_deleted" value="${show_deleted}"/>
+ <input type="hidden" name="folder_id" value="${folder_id | h}"/>
+ <input type="hidden" name="show_deleted" value="${show_deleted | h}"/><input type="hidden" name="upload_option" value="import_from_history"/>
- <input type="hidden" name="ldda_message" value="${ldda_message}"/>
+ <input type="hidden" name="ldda_message" value="${ldda_message | h}"/><%
role_ids_selected = ''
if roles_select_list:
@@ -357,32 +357,32 @@
if selected:
role_ids_selected = ','.join( selected )
%>
- <input type="hidden" name="roles" value="${role_ids_selected}"/>
+ <input type="hidden" name="roles" value="${role_ids_selected | h}"/>
%if replace_dataset not in [ None, 'None' ]:
- <input type="hidden" name="replace_id" value="${trans.security.encode_id( replace_dataset.id )}"/>
+ <input type="hidden" name="replace_id" value="${trans.security.encode_id( replace_dataset.id ) | h}"/><div class="form-row">
- You are currently selecting a new file to replace '<a href="${h.url_for( controller='library_common', action='ldda_info', cntrller=cntrller, library_id=library_id, folder_id=folder_id, id=trans.security.encode_id( replace_dataset.library_dataset_dataset_association.id ) )}">${ util.unicodify( replace_dataset.name )}</a>'.
+ You are currently selecting a new file to replace '<a href="${h.url_for( controller='library_common', action='ldda_info', cntrller=cntrller, library_id=library_id, folder_id=folder_id, id=trans.security.encode_id( replace_dataset.library_dataset_dataset_association.id ) )}">${ util.unicodify( replace_dataset.name ) | h}</a>'.
<div style="clear: both"></div></div>
%endif
%for hda in history.visible_datasets:
<% encoded_id = trans.security.encode_id( hda.id ) %><div class="form-row">
- <input name="hda_ids" id="hist_${encoded_id}" value="${encoded_id}" type="checkbox"/>
- <label for="hist_${encoded_id}" style="display: inline;font-weight:normal;">${hda.hid}: ${ util.unicodify( hda.name )}</label>
+ <input name="hda_ids" id="hist_${encoded_id | h}" value="${encoded_id | h}" type="checkbox"/>
+ <label for="hist_${encoded_id | h}" style="display: inline;font-weight:normal;">${hda.hid | h}: ${ util.unicodify( hda.name ) | h}</label></div>
%endfor
%if widgets:
- <input type="hidden" name="template_id" value="${template_id}"/>
+ <input type="hidden" name="template_id" value="${template_id | h}"/>
%for i, field in enumerate( widgets ):
<div class="form-row">
- <label>${field[ 'label' ]}</label>
+ <label>${field[ 'label' ] | h}</label><div class="form-row-input">
${field[ 'widget' ].get_html()}
</div><div class="toolParamHelp" style="clear: both;">
%if field[ 'helptext' ]:
- ${field[ 'helptext' ]}<br/>
+ ${field[ 'helptext' ] | h}<br/>
%endif
*Inherited template field
</div>
diff -r 704efd2f5e06b9f6e63246d2324874cf7f28d83a -r 07404a82972d877b5529fffaeb3e7e05b69a02a3 templates/webapps/galaxy/library/common/import_datasets_to_histories.mako
--- a/templates/webapps/galaxy/library/common/import_datasets_to_histories.mako
+++ b/templates/webapps/galaxy/library/common/import_datasets_to_histories.mako
@@ -34,8 +34,8 @@
checked = " checked='checked'"
%><div class="form-row">
- <input type="checkbox" name="ldda_ids" id="dataset_${encoded_id}" value="${encoded_id}" ${checked}/>
- <label for="dataset_${encoded_id}" style="display: inline;font-weight:normal;">${util.unicodify( source_ldda.name )}</label>
+ <input type="checkbox" name="ldda_ids" id="dataset_${encoded_id | h}" value="${encoded_id | h}" ${checked}/>
+ <label for="dataset_${encoded_id | h}" style="display: inline;font-weight:normal;">${util.unicodify( source_ldda.name ) | h}</label></div>
%endfor
%else:
@@ -61,7 +61,7 @@
else:
current_history_text = ""
%>
- <option value="${encoded_id}"${selected_text}>${i + 1}: ${h.truncate( util.unicodify( target_history.name ), 30 )}${current_history_text}</option>
+ <option value="${encoded_id | h}"${selected_text}>${i + 1}: ${h.truncate( util.unicodify( target_history.name ), 30 ) | h}${current_history_text | h}</option>
%endfor
</select><br/><br/>
@@ -77,8 +77,8 @@
current_history_text = ""
%><div class="form-row">
- <input type="checkbox" name="target_history_ids" id="target_history_${encoded_id}" value="${encoded_id}"/>
- <label for="target_history_${encoded_id}" style="display: inline; font-weight:normal;">${i + 1}: ${util.unicodify( target_history.name )}${current_history_text}</label>
+ <input type="checkbox" name="target_history_ids" id="target_history_${encoded_id | h}" value="${encoded_id | h}"/>
+ <label for="target_history_${encoded_id | h}" style="display: inline; font-weight:normal;">${i + 1}: ${util.unicodify( target_history.name ) | h}${current_history_text | h}</label></div>
%endfor
</div>
diff -r 704efd2f5e06b9f6e63246d2324874cf7f28d83a -r 07404a82972d877b5529fffaeb3e7e05b69a02a3 templates/webapps/galaxy/library/common/ldda_edit_info.mako
--- a/templates/webapps/galaxy/library/common/ldda_edit_info.mako
+++ b/templates/webapps/galaxy/library/common/ldda_edit_info.mako
@@ -34,9 +34,9 @@
<select name="datatype">
%for ext in file_formats:
%if ldda.ext == ext:
- <option value="${ext}" selected="yes">${ext}</option>
+ <option value="${ext | h}" selected="yes">${ext | h}</option>
%else:
- <option value="${ext}">${ext}</option>
+ <option value="${ext | h}">${ext | h}</option>
%endif
%endfor
</select>
@@ -44,24 +44,24 @@
%if ( trans.user_is_admin() and cntrller=='library_admin' ) or trans.app.security_agent.can_modify_library_item( current_user_roles, ldda.library_dataset ):
<div class="toolForm">
- <div class="toolFormTitle">Edit attributes of ${util.unicodify( ldda.name )}</div>
+ <div class="toolFormTitle">Edit attributes of ${util.unicodify( ldda.name ) | h}</div><div class="toolFormBody"><form name="edit_attributes" action="${h.url_for( controller='library_common', action='ldda_edit_info', cntrller=cntrller, library_id=library_id, folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), use_panels=use_panels, show_deleted=show_deleted, )}" method="post">
- <input type="hidden" name="id" value="${trans.security.encode_id( ldda.id )}"/>
+ <input type="hidden" name="id" value="${trans.security.encode_id( ldda.id ) | h}"/><div class="form-row"><label>Name:</label>
- <input type="text" name="name" value="${util.unicodify( ldda.name )}" size="40"/>
+ <input type="text" name="name" value="${util.unicodify( ldda.name ) | h}" size="40"/><div style="clear: both"></div></div><div class="form-row"><label>Info:</label>
- <input type="text" name="info" value="${util.unicodify( ldda.info )}" size="40"/>
+ <input type="text" name="info" value="${util.unicodify( ldda.info ) | h}" size="40"/><div style="clear: both"></div></div><div class="form-row"><label>Message:</label>
%if ldda.message:
- <textarea name="message" rows="3" cols="35">${ldda.message}</textarea>
+ <textarea name="message" rows="3" cols="35">${ldda.message | h}</textarea>
%else:
<textarea name="message" rows="3" cols="35"></textarea>
%endif
@@ -73,7 +73,7 @@
%for name, spec in ldda.metadata.spec.items():
%if spec.visible:
<div class="form-row">
- <label>${spec.desc}:</label>
+ <label>${spec.desc | h}:</label>
${ldda.metadata.get_html_by_name( name, trans=trans )}
<div style="clear: both"></div></div>
@@ -85,7 +85,7 @@
</form><form name="auto_detect" action="${h.url_for( controller='library_common', action='ldda_edit_info', cntrller=cntrller, library_id=library_id, folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), use_panels=use_panels, show_deleted=show_deleted, )}" method="post"><div class="form-row">
- <input type="hidden" name="id" value="${trans.security.encode_id( ldda.id )}"/>
+ <input type="hidden" name="id" value="${trans.security.encode_id( ldda.id ) | h}"/><input type="submit" name="detect" value="Auto-detect"/><div class="toolParamHelp" style="clear: both;">
This will inspect the dataset and attempt to correct the above column values if they are not accurate.
@@ -101,7 +101,7 @@
%if ldda.datatype.allow_datatype_change:
<form name="change_datatype" action="${h.url_for( controller='library_common', action='ldda_edit_info', cntrller=cntrller, library_id=library_id, folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), use_panels=use_panels, show_deleted=show_deleted, )}" method="post"><div class="form-row">
- <input type="hidden" name="id" value="${trans.security.encode_id( ldda.id )}"/>
+ <input type="hidden" name="id" value="${trans.security.encode_id( ldda.id ) | h}"/><label>New Type:</label>
${datatype( ldda, file_formats )}
<div class="toolParamHelp" style="clear: both;">
@@ -129,10 +129,10 @@
<div class="form-row"><label>Extended Metadata:</label></div>
- <input type="hidden" name="id" value="${trans.security.encode_id( ldda.id )}"/>
+ <input type="hidden" name="id" value="${trans.security.encode_id( ldda.id ) | h}"/><div class="form-row">
%if ldda.extended_metadata:
- <textarea name="extended_metadata" rows="15" cols="35">${util.pretty_print_json(ldda.extended_metadata.data)}</textarea>
+ <textarea name="extended_metadata" rows="15" cols="35">${util.pretty_print_json(ldda.extended_metadata.data) | h}</textarea>
%else:
<textarea name="extended_metadata" rows="15" cols="35"></textarea>
%endif
@@ -147,28 +147,28 @@
<p/>
%else:
<div class="toolForm">
- <div class="toolFormTitle">View information about ${util.unicodify( ldda.name )}</div>
+ <div class="toolFormTitle">View information about ${util.unicodify( ldda.name ) | h}</div><div class="toolFormBody"><div class="form-row"><label>Name:</label>
- ${util.unicodify( ldda.name )}
+ ${util.unicodify( ldda.name ) | h}
<div style="clear: both"></div></div><div class="form-row"><label>Info:</label>
- ${util.unicodify( ldda.info )}
+ ${util.unicodify( ldda.info ) | h}
<div style="clear: both"></div></div><div class="form-row"><label>Data Format:</label>
- ${ldda.ext}
+ ${ldda.ext | h}
<div style="clear: both"></div></div>
%for name, spec in ldda.metadata.spec.items():
%if spec.visible:
<div class="form-row">
- <label>${spec.desc}:</label>
- ${ldda.metadata.get( name )}
+ <label>${spec.desc | h}:</label>
+ ${ldda.metadata.get( name ) | h}
<div style="clear: both"></div></div>
%endif
This diff is so big that we needed to truncate the remainder.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0