galaxy-commits
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
June 2014
- 1 participants
- 233 discussions
commit/galaxy-central: greg: Fix import in the Tool Shed's common_install_util module.
by commits-noreply@bitbucket.org 03 Jun '14
by commits-noreply@bitbucket.org 03 Jun '14
03 Jun '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/72dea09e14ab/
Changeset: 72dea09e14ab
User: greg
Date: 2014-06-03 22:34:59
Summary: Fix import in the Tool Shed's common_install_util module.
Affected #: 1 file
diff -r 465b390ffeeda37663b92de91c1fa50a46743292 -r 72dea09e14ab6e87e7537b23f8c9af2cd6f50c6b lib/tool_shed/util/common_install_util.py
--- a/lib/tool_shed/util/common_install_util.py
+++ b/lib/tool_shed/util/common_install_util.py
@@ -18,7 +18,6 @@
from tool_shed.util import xml_util
from tool_shed.galaxy_install.install_manager import InstallManager
-from tool_shed.galaxy_install.tool_dependencies.recipe.recipe_manager import StepManager
from tool_shed.galaxy_install.tool_dependencies.recipe.recipe_manager import TagManager
log = logging.getLogger( __name__ )
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: davebgx: Merge in set_environment bugfix from stable.
by commits-noreply@bitbucket.org 03 Jun '14
by commits-noreply@bitbucket.org 03 Jun '14
03 Jun '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/465b390ffeed/
Changeset: 465b390ffeed
User: davebgx
Date: 2014-06-03 22:09:03
Summary: Merge in set_environment bugfix from stable.
Affected #: 6 files
diff -r beef22110c25635ed18a3c24f9d94442a4a4cc9c -r 465b390ffeeda37663b92de91c1fa50a46743292 lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
--- a/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
+++ b/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
@@ -465,11 +465,11 @@
tool_dependencies_config = hg_util.get_config_from_disk( rt_util.TOOL_DEPENDENCY_DEFINITION_FILENAME,
tool_shed_repository.repo_path( trans.app ) )
installed_tool_dependencies = \
- common_install_util.install_specified_packages( app=trans.app,
- tool_shed_repository=tool_shed_repository,
- tool_dependencies_config=tool_dependencies_config,
- tool_dependencies=tool_dependencies,
- from_tool_migration_manager=False )
+ common_install_util.install_specified_tool_dependencies( app=trans.app,
+ tool_shed_repository=tool_shed_repository,
+ tool_dependencies_config=tool_dependencies_config,
+ tool_dependencies=tool_dependencies,
+ from_tool_migration_manager=False )
for installed_tool_dependency in installed_tool_dependencies:
if installed_tool_dependency.status == trans.app.install_model.ToolDependency.installation_status.ERROR:
text = util.unicodify( installed_tool_dependency.error_message )
diff -r beef22110c25635ed18a3c24f9d94442a4a4cc9c -r 465b390ffeeda37663b92de91c1fa50a46743292 lib/tool_shed/galaxy_install/install_manager.py
--- a/lib/tool_shed/galaxy_install/install_manager.py
+++ b/lib/tool_shed/galaxy_install/install_manager.py
@@ -187,7 +187,6 @@
a partial or full list of ToolDependency records associated with the tool_shed_repository.
"""
tag_manager = TagManager()
- sa_session = app.install_model.context
# The value of package_name should match the value of the "package" type in the tool config's
# <requirements> tag set, but it's not required.
package_name = elem.get( 'name', None )
diff -r beef22110c25635ed18a3c24f9d94442a4a4cc9c -r 465b390ffeeda37663b92de91c1fa50a46743292 lib/tool_shed/galaxy_install/tool_dependencies/recipe/recipe_manager.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/recipe/recipe_manager.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/recipe/recipe_manager.py
@@ -97,7 +97,8 @@
return tool_dependency, proceed_with_install, action_elem_tuples
def load_tag_handlers( self ):
- tag_handlers = dict( install=tag_handler.Install(),
+ tag_handlers = dict( environment_variable=tag_handler.SetEnvironment(),
+ install=tag_handler.Install(),
package=tag_handler.Package(),
readme=tag_handler.ReadMe(),
repository=tag_handler.Repository(),
diff -r beef22110c25635ed18a3c24f9d94442a4a4cc9c -r 465b390ffeeda37663b92de91c1fa50a46743292 lib/tool_shed/galaxy_install/tool_dependencies/recipe/tag_handler.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/recipe/tag_handler.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/recipe/tag_handler.py
@@ -446,9 +446,12 @@
def process_tag_set( self, app, tool_shed_repository, tool_dependency, package_elem, package_name, package_version,
from_tool_migration_manager=False, tool_dependency_db_records=None ):
+ # We need to handle two tag sets for package_elem here, this:
# <set_environment version="1.0">
# <environment_variable name="R_SCRIPT_PATH"action="set_to">$REPOSITORY_INSTALL_DIR</environment_variable>
# </set_environment>
+ # or this:
+ # <environment_variable name="R_SCRIPT_PATH"action="set_to">$REPOSITORY_INSTALL_DIR</environment_variable>
action_elem_tuples = []
proceed_with_install = False
if tool_dependency_db_records is None:
@@ -479,6 +482,9 @@
<set_environment version="1.0"><environment_variable name="R_SCRIPT_PATH" action="set_to">$REPOSITORY_INSTALL_DIR</environment_variable></set_environment>
+
+ This method must also handle the sub-element tag::
+ <environment_variable name="R_SCRIPT_PATH" action="set_to">$REPOSITORY_INSTALL_DIR</environment_variable>
"""
# TODO: Add support for a repository dependency definition within this tool dependency type's tag set. This should look something like
# the following. See the implementation of support for this in the tool dependency package type's method above.
@@ -495,11 +501,19 @@
tool_dependencies = []
env_var_version = elem.get( 'version', '1.0' )
tool_shed_repository_install_dir = os.path.abspath( tool_shed_repository.repo_files_directory( app ) )
- for env_var_elem in elem:
- # Althoug we're in a loop here, this method will always return only a single ToolDependency or None.
+ if elem.tag == 'environment_variable':
+ # <environment_variable name="R_SCRIPT_PATH" action="set_to">$REPOSITORY_INSTALL_DIR</environment_variable>
+ elems = [ elem ]
+ else:
+ # <set_environment version="1.0">
+ # <environment_variable name="R_SCRIPT_PATH" action="set_to">$REPOSITORY_INSTALL_DIR</environment_variable>
+ # </set_environment>
+ elems = [ env_var_elem for env_var_elem in elem ]
+ for env_var_elem in elems:
env_var_name = env_var_elem.get( 'name', None )
- # The value of env_var_name must match the text value of at least 1 <requirement> tag in the tool config's <requirements> tag set whose
- # "type" attribute is "set_environment" (e.g., <requirement type="set_environment">R_SCRIPT_PATH</requirement>).
+ # The value of env_var_name must match the text value of at least 1 <requirement> tag in the
+ # tool config's <requirements> tag set whose "type" attribute is "set_environment" (e.g.,
+ # <requirement type="set_environment">R_SCRIPT_PATH</requirement>).
env_var_action = env_var_elem.get( 'action', None )
if env_var_name and env_var_action:
# Tool dependencies of type "set_environmnet" always have the version attribute set to None.
diff -r beef22110c25635ed18a3c24f9d94442a4a4cc9c -r 465b390ffeeda37663b92de91c1fa50a46743292 lib/tool_shed/galaxy_install/tool_migration_manager.py
--- a/lib/tool_shed/galaxy_install/tool_migration_manager.py
+++ b/lib/tool_shed/galaxy_install/tool_migration_manager.py
@@ -447,11 +447,11 @@
# Get the tool_dependencies.xml file from disk.
tool_dependencies_config = hg_util.get_config_from_disk( 'tool_dependencies.xml', repo_install_dir )
installed_tool_dependencies = \
- common_install_util.install_specified_packages( app=self.app,
- tool_shed_repository=tool_shed_repository,
- tool_dependencies_config=tool_dependencies_config,
- tool_dependencies=tool_dependencies,
- from_tool_migration_manager=True )
+ common_install_util.install_specified_tool_dependencies( app=self.app,
+ tool_shed_repository=tool_shed_repository,
+ tool_dependencies_config=tool_dependencies_config,
+ tool_dependencies=tool_dependencies,
+ from_tool_migration_manager=True )
for installed_tool_dependency in installed_tool_dependencies:
if installed_tool_dependency.status == self.app.install_model.ToolDependency.installation_status.ERROR:
print '\nThe ToolMigrationManager returned the following error while installing tool dependency ', installed_tool_dependency.name, ':'
diff -r beef22110c25635ed18a3c24f9d94442a4a4cc9c -r 465b390ffeeda37663b92de91c1fa50a46743292 lib/tool_shed/util/common_install_util.py
--- a/lib/tool_shed/util/common_install_util.py
+++ b/lib/tool_shed/util/common_install_util.py
@@ -18,6 +18,7 @@
from tool_shed.util import xml_util
from tool_shed.galaxy_install.install_manager import InstallManager
+from tool_shed.galaxy_install.tool_dependencies.recipe.recipe_manager import StepManager
from tool_shed.galaxy_install.tool_dependencies.recipe.recipe_manager import TagManager
log = logging.getLogger( __name__ )
@@ -483,7 +484,8 @@
all_required_repo_info_dict[ 'all_repo_info_dicts' ] = all_repo_info_dicts
return all_required_repo_info_dict
-def install_specified_packages( app, tool_shed_repository, tool_dependencies_config, tool_dependencies, from_tool_migration_manager=False ):
+def install_specified_tool_dependencies( app, tool_shed_repository, tool_dependencies_config, tool_dependencies,
+ from_tool_migration_manager=False ):
"""
Follow the recipe in the received tool_dependencies_config to install specified packages for
repository tools. The received list of tool_dependencies are the database records for those
@@ -502,28 +504,46 @@
log.debug( "The received tool_dependencies.xml file is likely invalid: %s" % str( error_message ) )
return installed_packages
root = tree.getroot()
+ elems = []
for elem in root:
- package_name = elem.get( 'name', None )
- package_version = elem.get( 'version', None )
- if package_name and package_version:
- # elem is a package tag set.
- attr_tup = ( package_name, package_version, 'package' )
+ if elem.tag == 'set_environment':
+ version = elem.get( 'version', '1.0' )
+ if version != '1.0':
+ raise Exception( 'The <set_environment> tag must have a version attribute with value 1.0' )
+ for sub_elem in elem:
+ elems.append( sub_elem )
+ else:
+ elems.append( elem )
+ for elem in elems:
+ name = elem.get( 'name', None )
+ version = elem.get( 'version', None )
+ type = elem.get( 'type', None )
+ if type is None:
+ if elem.tag in [ 'environment_variable', 'set_environment' ]:
+ type = 'set_environment'
+ else:
+ type = 'package'
+ if ( name and type == 'set_environment' ) or ( name and version ):
+ # elem is a package set_environment tag set.
+ attr_tup = ( name, version, type )
try:
index = attr_tups_of_dependencies_for_install.index( attr_tup )
except Exception, e:
index = None
if index is not None:
tool_dependency = tool_dependencies[ index ]
+ # If the tool_dependency.type is 'set_environment', then the call to process_tag_set() will
+ # handle everything - no additional installation is necessary.
tool_dependency, proceed_with_install, action_elem_tuples = \
tag_manager.process_tag_set( app,
tool_shed_repository,
tool_dependency,
elem,
- package_name,
- package_version,
+ name,
+ version,
from_tool_migration_manager=from_tool_migration_manager,
tool_dependency_db_records=tool_dependencies )
- if proceed_with_install:
+ if ( tool_dependency.type == 'package' and proceed_with_install ):
try:
tool_dependency = install_manager.install_package( app,
elem,
@@ -531,8 +551,8 @@
tool_dependencies=tool_dependencies,
from_tool_migration_manager=from_tool_migration_manager )
except Exception, e:
- error_message = "Error installing tool dependency package %s version %s: %s" % \
- ( str( package_name ), str( package_version ), str( e ) )
+ error_message = "Error installing tool dependency %s version %s: %s" % \
+ ( str( name ), str( version ), str( e ) )
log.exception( error_message )
if tool_dependency:
# Since there was an installation error, update the tool dependency status to Error. The
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: greg: Fix for installing tool dependencies with type set_environment.
by commits-noreply@bitbucket.org 03 Jun '14
by commits-noreply@bitbucket.org 03 Jun '14
03 Jun '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/96fdb9168f28/
Changeset: 96fdb9168f28
Branch: stable
User: greg
Date: 2014-06-03 21:34:53
Summary: Fix for installing tool dependencies with type set_environment.
Affected #: 6 files
diff -r 75efcf77476543a1f5fae8e4c7ece4b551e2eea9 -r 96fdb9168f28b2ffa463195d084c9278efb2465a lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
--- a/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
+++ b/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
@@ -471,11 +471,11 @@
tool_dependencies_config = suc.get_config_from_disk( suc.TOOL_DEPENDENCY_DEFINITION_FILENAME,
tool_shed_repository.repo_path( trans.app ) )
installed_tool_dependencies = \
- common_install_util.install_specified_packages( app=trans.app,
- tool_shed_repository=tool_shed_repository,
- tool_dependencies_config=tool_dependencies_config,
- tool_dependencies=tool_dependencies,
- from_tool_migration_manager=False )
+ common_install_util.install_specified_tool_dependencies( app=trans.app,
+ tool_shed_repository=tool_shed_repository,
+ tool_dependencies_config=tool_dependencies_config,
+ tool_dependencies=tool_dependencies,
+ from_tool_migration_manager=False )
for installed_tool_dependency in installed_tool_dependencies:
if installed_tool_dependency.status == trans.app.install_model.ToolDependency.installation_status.ERROR:
text = util.unicodify( installed_tool_dependency.error_message )
diff -r 75efcf77476543a1f5fae8e4c7ece4b551e2eea9 -r 96fdb9168f28b2ffa463195d084c9278efb2465a lib/tool_shed/galaxy_install/install_manager.py
--- a/lib/tool_shed/galaxy_install/install_manager.py
+++ b/lib/tool_shed/galaxy_install/install_manager.py
@@ -182,7 +182,6 @@
a partial or full list of ToolDependency records associated with the tool_shed_repository.
"""
tag_manager = TagManager()
- sa_session = app.install_model.context
# The value of package_name should match the value of the "package" type in the tool config's
# <requirements> tag set, but it's not required.
package_name = elem.get( 'name', None )
diff -r 75efcf77476543a1f5fae8e4c7ece4b551e2eea9 -r 96fdb9168f28b2ffa463195d084c9278efb2465a lib/tool_shed/galaxy_install/tool_dependencies/recipe/recipe_manager.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/recipe/recipe_manager.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/recipe/recipe_manager.py
@@ -97,7 +97,8 @@
return tool_dependency, proceed_with_install, action_elem_tuples
def load_tag_handlers( self ):
- tag_handlers = dict( install=tag_handler.Install(),
+ tag_handlers = dict( environment_variable=tag_handler.SetEnvironment(),
+ install=tag_handler.Install(),
package=tag_handler.Package(),
readme=tag_handler.ReadMe(),
repository=tag_handler.Repository(),
diff -r 75efcf77476543a1f5fae8e4c7ece4b551e2eea9 -r 96fdb9168f28b2ffa463195d084c9278efb2465a lib/tool_shed/galaxy_install/tool_dependencies/recipe/tag_handler.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/recipe/tag_handler.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/recipe/tag_handler.py
@@ -437,9 +437,12 @@
def process_tag_set( self, app, tool_shed_repository, tool_dependency, package_elem, package_name, package_version,
from_tool_migration_manager=False, tool_dependency_db_records=None ):
+ # We need to handle two tag sets for package_elem here, this:
# <set_environment version="1.0">
# <environment_variable name="R_SCRIPT_PATH"action="set_to">$REPOSITORY_INSTALL_DIR</environment_variable>
# </set_environment>
+ # or this:
+ # <environment_variable name="R_SCRIPT_PATH"action="set_to">$REPOSITORY_INSTALL_DIR</environment_variable>
action_elem_tuples = []
proceed_with_install = False
if tool_dependency_db_records is None:
@@ -470,6 +473,9 @@
<set_environment version="1.0"><environment_variable name="R_SCRIPT_PATH" action="set_to">$REPOSITORY_INSTALL_DIR</environment_variable></set_environment>
+
+ This method must also handle the sub-element tag::
+ <environment_variable name="R_SCRIPT_PATH" action="set_to">$REPOSITORY_INSTALL_DIR</environment_variable>
"""
# TODO: Add support for a repository dependency definition within this tool dependency type's tag set. This should look something like
# the following. See the implementation of support for this in the tool dependency package type's method above.
@@ -485,11 +491,19 @@
tool_dependencies = []
env_var_version = elem.get( 'version', '1.0' )
tool_shed_repository_install_dir = os.path.abspath( tool_shed_repository.repo_files_directory( app ) )
- for env_var_elem in elem:
- # Althoug we're in a loop here, this method will always return only a single ToolDependency or None.
+ if elem.tag == 'environment_variable':
+ # <environment_variable name="R_SCRIPT_PATH" action="set_to">$REPOSITORY_INSTALL_DIR</environment_variable>
+ elems = [ elem ]
+ else:
+ # <set_environment version="1.0">
+ # <environment_variable name="R_SCRIPT_PATH" action="set_to">$REPOSITORY_INSTALL_DIR</environment_variable>
+ # </set_environment>
+ elems = [ env_var_elem for env_var_elem in elem ]
+ for env_var_elem in elems:
env_var_name = env_var_elem.get( 'name', None )
- # The value of env_var_name must match the text value of at least 1 <requirement> tag in the tool config's <requirements> tag set whose
- # "type" attribute is "set_environment" (e.g., <requirement type="set_environment">R_SCRIPT_PATH</requirement>).
+ # The value of env_var_name must match the text value of at least 1 <requirement> tag in the
+ # tool config's <requirements> tag set whose "type" attribute is "set_environment" (e.g.,
+ # <requirement type="set_environment">R_SCRIPT_PATH</requirement>).
env_var_action = env_var_elem.get( 'action', None )
if env_var_name and env_var_action:
# Tool dependencies of type "set_environmnet" always have the version attribute set to None.
diff -r 75efcf77476543a1f5fae8e4c7ece4b551e2eea9 -r 96fdb9168f28b2ffa463195d084c9278efb2465a lib/tool_shed/galaxy_install/tool_migration_manager.py
--- a/lib/tool_shed/galaxy_install/tool_migration_manager.py
+++ b/lib/tool_shed/galaxy_install/tool_migration_manager.py
@@ -446,11 +446,11 @@
# Get the tool_dependencies.xml file from disk.
tool_dependencies_config = suc.get_config_from_disk( 'tool_dependencies.xml', repo_install_dir )
installed_tool_dependencies = \
- common_install_util.install_specified_packages( app=self.app,
- tool_shed_repository=tool_shed_repository,
- tool_dependencies_config=tool_dependencies_config,
- tool_dependencies=tool_dependencies,
- from_tool_migration_manager=True )
+ common_install_util.install_specified_tool_dependencies( app=self.app,
+ tool_shed_repository=tool_shed_repository,
+ tool_dependencies_config=tool_dependencies_config,
+ tool_dependencies=tool_dependencies,
+ from_tool_migration_manager=True )
for installed_tool_dependency in installed_tool_dependencies:
if installed_tool_dependency.status == self.app.install_model.ToolDependency.installation_status.ERROR:
print '\nThe ToolMigrationManager returned the following error while installing tool dependency ', installed_tool_dependency.name, ':'
diff -r 75efcf77476543a1f5fae8e4c7ece4b551e2eea9 -r 96fdb9168f28b2ffa463195d084c9278efb2465a lib/tool_shed/util/common_install_util.py
--- a/lib/tool_shed/util/common_install_util.py
+++ b/lib/tool_shed/util/common_install_util.py
@@ -18,6 +18,7 @@
from tool_shed.util import xml_util
from tool_shed.galaxy_install.install_manager import InstallManager
+from tool_shed.galaxy_install.tool_dependencies.recipe.recipe_manager import StepManager
from tool_shed.galaxy_install.tool_dependencies.recipe.recipe_manager import TagManager
log = logging.getLogger( __name__ )
@@ -483,7 +484,8 @@
all_required_repo_info_dict[ 'all_repo_info_dicts' ] = all_repo_info_dicts
return all_required_repo_info_dict
-def install_specified_packages( app, tool_shed_repository, tool_dependencies_config, tool_dependencies, from_tool_migration_manager=False ):
+def install_specified_tool_dependencies( app, tool_shed_repository, tool_dependencies_config, tool_dependencies,
+ from_tool_migration_manager=False ):
"""
Follow the recipe in the received tool_dependencies_config to install specified packages for
repository tools. The received list of tool_dependencies are the database records for those
@@ -502,28 +504,46 @@
log.debug( "The received tool_dependencies.xml file is likely invalid: %s" % str( error_message ) )
return installed_packages
root = tree.getroot()
+ elems = []
for elem in root:
- package_name = elem.get( 'name', None )
- package_version = elem.get( 'version', None )
- if package_name and package_version:
- # elem is a package tag set.
- attr_tup = ( package_name, package_version, 'package' )
+ if elem.tag == 'set_environment':
+ version = elem.get( 'version', '1.0' )
+ if version != '1.0':
+ raise Exception( 'The <set_environment> tag must have a version attribute with value 1.0' )
+ for sub_elem in elem:
+ elems.append( sub_elem )
+ else:
+ elems.append( elem )
+ for elem in elems:
+ name = elem.get( 'name', None )
+ version = elem.get( 'version', None )
+ type = elem.get( 'type', None )
+ if type is None:
+ if elem.tag in [ 'environment_variable', 'set_environment' ]:
+ type = 'set_environment'
+ else:
+ type = 'package'
+ if ( name and type == 'set_environment' ) or ( name and version ):
+ # elem is a package set_environment tag set.
+ attr_tup = ( name, version, type )
try:
index = attr_tups_of_dependencies_for_install.index( attr_tup )
except Exception, e:
index = None
if index is not None:
tool_dependency = tool_dependencies[ index ]
+ # If the tool_dependency.type is 'set_environment', then the call to process_tag_set() will
+ # handle everything - no additional installation is necessary.
tool_dependency, proceed_with_install, action_elem_tuples = \
tag_manager.process_tag_set( app,
tool_shed_repository,
tool_dependency,
elem,
- package_name,
- package_version,
+ name,
+ version,
from_tool_migration_manager=from_tool_migration_manager,
tool_dependency_db_records=tool_dependencies )
- if proceed_with_install:
+ if ( tool_dependency.type == 'package' and proceed_with_install ):
try:
tool_dependency = install_manager.install_package( app,
elem,
@@ -531,8 +551,8 @@
tool_dependencies=tool_dependencies,
from_tool_migration_manager=from_tool_migration_manager )
except Exception, e:
- error_message = "Error installing tool dependency package %s version %s: %s" % \
- ( str( package_name ), str( package_version ), str( e ) )
+ error_message = "Error installing tool dependency %s version %s: %s" % \
+ ( str( name ), str( version ), str( e ) )
log.exception( error_message )
if tool_dependency:
# Since there was an installation error, update the tool dependency status to Error. The
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: greg: Pes-8 fixes for the Tool Shed's repository_registry module.
by commits-noreply@bitbucket.org 03 Jun '14
by commits-noreply@bitbucket.org 03 Jun '14
03 Jun '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/beef22110c25/
Changeset: beef22110c25
User: greg
Date: 2014-06-03 21:19:54
Summary: Pes-8 fixes for the Tool Shed's repository_registry module.
Affected #: 1 file
diff -r da344cf4304429522fd5a214e3fc91697ca682b3 -r beef22110c25635ed18a3c24f9d94442a4a4cc9c lib/tool_shed/repository_registry.py
--- a/lib/tool_shed/repository_registry.py
+++ b/lib/tool_shed/repository_registry.py
@@ -55,7 +55,7 @@
self.certified_level_one_viewable_repositories_and_suites_by_category[ category_name ] = 0
if category_name not in self.certified_level_one_viewable_suites_by_category:
self.certified_level_one_viewable_suites_by_category[ category_name ] = 0
-
+
def add_entry( self, repository ):
try:
if repository:
@@ -156,7 +156,7 @@
model.RepositoryMetadata.table.c.changeset_revision,
latest_installable_changeset_revision ) )
return clause_list
-
+
def get_certified_level_one_tuple( self, repository ):
"""
Return True if the latest installable changeset_revision of the received repository is level one certified.
@@ -333,7 +333,7 @@
del self.certified_level_one_viewable_repositories_and_suites_by_category[ catgeory_name ]
if catgeory_name in self.certified_level_one_viewable_suites_by_category:
del self.certified_level_one_viewable_suites_by_category[ catgeory_name ]
-
+
def remove_entry( self, repository ):
try:
if repository:
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: greg: Fix debug typo in the Tool Shed's step handler.
by commits-noreply@bitbucket.org 03 Jun '14
by commits-noreply@bitbucket.org 03 Jun '14
03 Jun '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/da344cf43044/
Changeset: da344cf43044
User: greg
Date: 2014-06-03 19:56:51
Summary: Fix debug typo in the Tool Shed's step handler.
Affected #: 1 file
diff -r d80f43f448db62f5444726220b74d1814f6804a7 -r da344cf4304429522fd5a214e3fc91697ca682b3 lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
@@ -1040,7 +1040,7 @@
filtered_actions = actions[ 1: ]
env_shell_file_paths = action_dict.get( 'env_shell_file_paths', None )
if env_shell_file_paths is None:
- log.debug( 'Missing Rerl environment, make sure your specified Rerl installation exists.' )
+ log.debug( 'Missing Perl environment, make sure your specified Rerl installation exists.' )
if initial_download:
return tool_dependency, filtered_actions, dir
return tool_dependency, None, None
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: greg: Fix documentation in the Tool Shed API users controller.
by commits-noreply@bitbucket.org 03 Jun '14
by commits-noreply@bitbucket.org 03 Jun '14
03 Jun '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/d80f43f448db/
Changeset: d80f43f448db
User: greg
Date: 2014-06-03 19:53:12
Summary: Fix documentation in the Tool Shed API users controller.
Affected #: 1 file
diff -r 13ab3f66d332126c72b23290f7d458223795ffce -r d80f43f448db62f5444726220b74d1814f6804a7 lib/galaxy/webapps/tool_shed/api/users.py
--- a/lib/galaxy/webapps/tool_shed/api/users.py
+++ b/lib/galaxy/webapps/tool_shed/api/users.py
@@ -24,6 +24,8 @@
: param key: the current Galaxy admin user's API key
The following parameters are included in the payload.
+ :param email (required): the email address of the user
+ :param password (required): the password of the user
:param username (required): the public username of the user
"""
user_dict = dict( message = '',
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/31b2924315d0/
Changeset: 31b2924315d0
User: jmchilton
Date: 2014-06-03 19:48:18
Summary: Mechanism to define site-specific parameters to aid defining job destinations.
This is based on work by Hector del Risco at the University of Florida.
Various tool-style parameters can be defined in job_resource_params_conf.xml (see sample) and these define the pool of all possible resource parameters that can be injected into a tool. These can be groupped together and assigned to tools in job_conf.xml (see documented changes to job_conf.xml.sample_advanced).
A conditional is then injected into each tool that gives the end-user the ability to select these parameters. The values of these parameters (as a dict) can then be obtained by dynamic job destination that define a 'resource_params' argument.
Lots here still needs to be tested/verified - can workflows exported from Galaxies without resource parameters (or different ones, be reused in Galaxies with resource parameters) (I think yes?)? can workflows exported with resource parameters be used in other Galaxies (I think yes?), how best to present UI while running workflows? (maybe nothing needs to be changed), should exported job parameter data be swept clean (say when exporting a workflow for instance).
A great extension to this would be to support conditional when defining parameters.
Finally, the Galaxy team will make a reasonable effort to support this syntax for job_conf.xml, job_resource_params_conf.xml, and internal interface for job parameters for sometime once this changeset has reached -stable but until these interfaces may change.
Affected #: 8 files
diff -r 1d1d881508b121df607d9096386effdbe072427e -r 31b2924315d0b48fa7648ab4bfd04ef754829f71 job_conf.xml.sample_advanced
--- a/job_conf.xml.sample_advanced
+++ b/job_conf.xml.sample_advanced
@@ -240,6 +240,15 @@
<param id="request_cpus">8</param></destination></destinations>
+ <resources default="default">
+ <!-- Group different parameters defined in job_resource_params_conf.xml
+ together and assign these groups ids. Tool section below can map
+ tools to different groups. This is experimental functionality!
+ -->
+ <group id="default"></group>
+ <group id="memoryonly">memory</group>
+ <group id="all">processors,memory,time,project</group>
+ </resources><tools><!-- Tools can be configured to use specific destinations or handlers,
identified by either the "id" or "tags" attribute. If assigned to
@@ -250,6 +259,9 @@
<param id="source">trackster</param></tool><tool id="bar" destination="dynamic"/>
+ <!-- Next example defines resource group to insert into tool interface
+ and pass to dynamic destination (as resource_params argument). -->
+ <tool id="longbar" destination="dynamic" resources="all" /><tool id="baz" handler="special_handlers" destination="bigmem"/></tools><limits>
diff -r 1d1d881508b121df607d9096386effdbe072427e -r 31b2924315d0b48fa7648ab4bfd04ef754829f71 job_resource_params_conf.xml.sample
--- /dev/null
+++ b/job_resource_params_conf.xml.sample
@@ -0,0 +1,6 @@
+<parameters>
+ <param label="Processors" name="processors" type="integer" size="2" min="1" max="64" value="" help="Number of processing cores, 'ppn' value (1-64). Leave blank to use default value." />
+ <param label="Memory" name="memory" type="integer" size="3" min="1" max="256" value="" help="Memory size in gigabytes, 'pmem' value (1-256). Leave blank to use default value." />
+ <param label="Time" name="time" type="integer" size="3" min="1" max="744" value="" help="Maximum job time in hours, 'walltime' value (1-744). Leave blank to use default value." />
+ <param label="Project" name="project" type="text" value="" help="Project to assign resource allocation to. Leave blank to use default value." />
+</parameters>
diff -r 1d1d881508b121df607d9096386effdbe072427e -r 31b2924315d0b48fa7648ab4bfd04ef754829f71 lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -152,6 +152,7 @@
self.dependency_resolvers_config_file = resolve_path( kwargs.get( 'dependency_resolvers_config_file', 'dependency_resolvers_conf.xml' ), self.root )
self.job_metrics_config_file = resolve_path( kwargs.get( 'job_metrics_config_file', 'job_metrics_conf.xml' ), self.root )
self.job_config_file = resolve_path( kwargs.get( 'job_config_file', 'job_conf.xml' ), self.root )
+ self.job_resource_params_file = resolve_path( kwargs.get( 'job_resource_params_file', 'job_resource_params_conf.xml' ), self.root )
self.local_job_queue_workers = int( kwargs.get( "local_job_queue_workers", "5" ) )
self.cluster_job_queue_workers = int( kwargs.get( "cluster_job_queue_workers", "3" ) )
self.job_queue_cleanup_interval = int( kwargs.get("job_queue_cleanup_interval", "5") )
diff -r 1d1d881508b121df607d9096386effdbe072427e -r 31b2924315d0b48fa7648ab4bfd04ef754829f71 lib/galaxy/jobs/__init__.py
--- a/lib/galaxy/jobs/__init__.py
+++ b/lib/galaxy/jobs/__init__.py
@@ -79,6 +79,9 @@
self['params'] = dict()
super(JobToolConfiguration, self).__init__(**kwds)
+ def get_resource_group( self ):
+ return self.get( "resources", None )
+
class JobConfiguration( object ):
"""A parser and interface to advanced job management features.
@@ -99,8 +102,12 @@
self.destination_tags = {}
self.default_destination_id = None
self.tools = {}
+ self.resource_groups = {}
+ self.default_resource_group = None
+ self.resource_parameters = {}
self.limits = Bunch()
+ self.__parse_resource_parameters()
# Initialize the config
try:
tree = util.parse_xml(self.app.config.job_config_file)
@@ -190,6 +197,16 @@
# Determine the default destination
self.default_destination_id = self.__get_default(destinations, self.destinations.keys())
+ # Parse resources...
+ resources = root.find('resources')
+ if resources is not None:
+ self.default_resource_group = resources.get( "default", None )
+ for group in self.__findall_with_required(resources, 'group'):
+ id = group.get('id')
+ fields_str = group.get('fields', None) or group.text or ''
+ fields = [ f for f in fields_str.split(",") if f ]
+ self.resource_groups[ id ] = fields
+
# Parse tool mappings
tools = root.find('tools')
if tools is not None:
@@ -297,6 +314,49 @@
log.debug('Done loading job configuration')
+ def get_tool_resource_parameters( self, tool_id ):
+ """ Given a tool id, return XML elements describing parameters to
+ insert into job resources.
+
+ :tool id: A tool ID (a string)
+
+ :returns: List of parameter elements.
+ """
+ fields = []
+
+ if not tool_id:
+ return fields
+
+ # TODO: Only works with exact matches, should handle different kinds of ids
+ # the way destination lookup does.
+ resource_group = None
+ if tool_id in self.tools:
+ resource_group = self.tools[ tool_id ][ 0 ].get_resource_group()
+ resource_group = resource_group or self.default_resource_group
+
+ if resource_group and resource_group in self.resource_groups:
+ fields_names = self.resource_groups[ resource_group ]
+ fields = [ self.resource_parameters[ n ] for n in fields_names ]
+
+ return fields
+
+ def __parse_resource_parameters( self ):
+ if not os.path.exists( self.app.config.job_resource_params_file ):
+ return
+
+ resource_definitions = util.parse_xml( self.app.config.job_resource_params_file )
+ resource_definitions_root = resource_definitions.getroot()
+ # TODO: Also handling conditionals would be awesome!
+ for parameter_elem in resource_definitions_root.findall( "param" ):
+ name = parameter_elem.get( "name" )
+ # Considered prepending __job_resource_param__ here and then
+ # stripping it off when making it available to dynamic job
+ # destination. Not needed because resource parameters are wrapped
+ # in a conditional.
+ ## expanded_name = "__job_resource_param__%s" % name
+ ## parameter_elem.set( "name", expanded_name )
+ self.resource_parameters[ name ] = parameter_elem
+
def __get_default(self, parent, names):
"""Returns the default attribute set in a parent tag like <handlers> or <destinations>, or return the ID of the child, if there is no explicit default and only one child.
diff -r 1d1d881508b121df607d9096386effdbe072427e -r 31b2924315d0b48fa7648ab4bfd04ef754829f71 lib/galaxy/jobs/mapper.py
--- a/lib/galaxy/jobs/mapper.py
+++ b/lib/galaxy/jobs/mapper.py
@@ -71,7 +71,7 @@
actual_args[ possible_arg_name ] = possible_args[ possible_arg_name ]
# Don't hit the DB to load the job object if not needed
- if "job" in function_arg_names or "user" in function_arg_names or "user_email" in function_arg_names:
+ if "job" in function_arg_names or "user" in function_arg_names or "user_email" in function_arg_names or "resource_params" in function_arg_names:
job = self.job_wrapper.get_job()
history = job.history
user = history and history.user
@@ -86,6 +86,24 @@
if "user_email" in function_arg_names:
actual_args[ "user_email" ] = user_email
+ if "resource_params" in function_arg_names:
+ # Find the dymically inserted resource parameters and give them
+ # to rule.
+ app = self.job_wrapper.app
+ param_values = job.get_param_values( app, ignore_errors=True )
+ resource_params = {}
+ try:
+ resource_params_raw = param_values[ "__job_resource" ]
+ if resource_params_raw[ "__job_resource__select" ].lower() in [ "1", "yes", "true" ]:
+ for key, value in resource_params_raw.iteritems():
+ #if key.startswith( "__job_resource_param__" ):
+ # resource_key = key[ len( "__job_resource_param__" ): ]
+ # resource_params[ resource_key ] = value
+ resource_params[ key ] = value
+ except KeyError:
+ pass
+ actual_args[ "resource_params" ] = resource_params
+
return expand_function( **actual_args )
def __convert_url_to_destination( self, url ):
diff -r 1d1d881508b121df607d9096386effdbe072427e -r 31b2924315d0b48fa7648ab4bfd04ef754829f71 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -86,6 +86,16 @@
WORKFLOW_PARAMETER_REGULAR_EXPRESSION = re.compile( '''\$\{.+?\}''' )
+JOB_RESOURCE_CONDITIONAL_XML = """<conditional name="__job_resource">
+ <param name="__job_resource__select" type="select" label="Job Resource Parameters">
+ <option value="no">Use default job resource parameters</option>
+ <option value="yes">Specify job resource parameters</option>
+ </param>
+ <when value="no"></when>
+ <when value="yes">
+ </when>
+</conditional>"""
+
class ToolNotFoundException( Exception ):
pass
@@ -678,6 +688,24 @@
elif root.get( 'tool_type', None ) is not None:
ToolClass = tool_types.get( root.get( 'tool_type' ) )
else:
+ # Normal tool - only insert dynamic resource parameters for these
+ # tools.
+ if hasattr( self.app, "job_config" ): # toolshed may not have job_config?
+ tool_id = root.get( 'id' ) if root else None
+ parameters = self.app.job_config.get_tool_resource_parameters( tool_id )
+ if parameters:
+ inputs = root.find('inputs')
+ # If tool has not inputs, create some so we can insert conditional
+ if not inputs:
+ inputs = ElementTree.fromstring( "<inputs></inputs>")
+ root.append( inputs )
+ # Insert a conditional allowing user to specify resource parameters.
+ conditional_element = ElementTree.fromstring( JOB_RESOURCE_CONDITIONAL_XML )
+ when_yes_elem = conditional_element.findall( "when" )[ 1 ]
+ for parameter in parameters:
+ when_yes_elem.append( parameter )
+ inputs.append( conditional_element )
+
ToolClass = Tool
return ToolClass( config_file, root, self.app, guid=guid, repository_id=repository_id, **kwds )
diff -r 1d1d881508b121df607d9096386effdbe072427e -r 31b2924315d0b48fa7648ab4bfd04ef754829f71 test/unit/jobs/test_job_configuration.py
--- a/test/unit/jobs/test_job_configuration.py
+++ b/test/unit/jobs/test_job_configuration.py
@@ -20,6 +20,7 @@
self.config = bunch.Bunch(
job_config_file=os.path.join( self.temp_directory, "job_conf.xml" ),
use_tasked_jobs=False,
+ job_resource_params_file="/tmp/fake_absent_path",
)
self.__write_config_from( SIMPLE_JOB_CONF )
self.app = bunch.Bunch( config=self.config, job_metrics=MockJobMetrics() )
diff -r 1d1d881508b121df607d9096386effdbe072427e -r 31b2924315d0b48fa7648ab4bfd04ef754829f71 universe_wsgi.ini.sample
--- a/universe_wsgi.ini.sample
+++ b/universe_wsgi.ini.sample
@@ -807,6 +807,12 @@
# individually. This only affects cluster jobs, not local jobs.
#environment_setup_file = None
+
+# Optional file containing job resource data entry fields definition.
+# These fields will be presented to users in the tool forms and allow them to
+# overwrite default job resources such as number of processors, memory, and walltime.
+#job_resource_params_file = job_resource_params_conf.xml
+
# If using job concurrency limits (configured in job_config_file), several
# extra database queries must be performed to determine the number of jobs a
# user has dispatched to a given destination. By default, these queries will
https://bitbucket.org/galaxy/galaxy-central/commits/13ab3f66d332/
Changeset: 13ab3f66d332
User: jmchilton
Date: 2014-06-03 19:48:18
Summary: Fix unit tests for 46a487e.
Affected #: 1 file
diff -r 31b2924315d0b48fa7648ab4bfd04ef754829f71 -r 13ab3f66d332126c72b23290f7d458223795ffce test/unit/jobs/test_job_configuration.py
--- a/test/unit/jobs/test_job_configuration.py
+++ b/test/unit/jobs/test_job_configuration.py
@@ -100,16 +100,17 @@
assert limits.walltime is None
assert limits.walltime_delta is None
assert limits.output_size is None
- assert limits.concurrent_jobs == {}
+ assert limits.destination_user_concurrent_jobs == {}
+ assert limits.destination_total_concurrent_jobs == {}
def test_limit_overrides( self ):
self.__with_advanced_config()
limits = self.job_config.limits
assert limits.registered_user_concurrent_jobs == 2
assert limits.anonymous_user_concurrent_jobs == 1
- assert limits.concurrent_jobs[ "local" ] == 1
- assert limits.concurrent_jobs[ "mycluster" ] == 2
- assert limits.concurrent_jobs[ "longjobs" ] == 1
+ assert limits.destination_user_concurrent_jobs[ "local" ] == 1
+ assert limits.destination_user_concurrent_jobs[ "mycluster" ] == 2
+ assert limits.destination_user_concurrent_jobs[ "longjobs" ] == 1
assert limits.walltime_delta == datetime.timedelta( 0, 0, 0, 0, 0, 24 )
def test_env_parsing( self ):
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: History panel: allow multi-select with shift key to select range of datasets
by commits-noreply@bitbucket.org 03 Jun '14
by commits-noreply@bitbucket.org 03 Jun '14
03 Jun '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/1d1d881508b1/
Changeset: 1d1d881508b1
User: carlfeberhard
Date: 2014-06-03 17:20:15
Summary: History panel: allow multi-select with shift key to select range of datasets
Affected #: 10 files
diff -r 46a487e7d5476429cb71885adcbcfb9746ce725a -r 1d1d881508b121df607d9096386effdbe072427e static/scripts/mvc/collection/dataset-collection-base.js
--- a/static/scripts/mvc/collection/dataset-collection-base.js
+++ b/static/scripts/mvc/collection/dataset-collection-base.js
@@ -39,41 +39,39 @@
templateSkeleton : function (){
return [
'<div class="dataset hda">',
- ' <div class="dataset-warnings">',
- '<% if ( deleted ) { %>',
- ' <div class="dataset-deleted-msg warningmessagesmall"><strong>',
- ' This dataset has been deleted.', // Localize?
- ' </div>',
- '<% } %>',
- '<% if ( ! visible ) { %>',
- ' <div class="dataset-hidden-msg warningmessagesmall"><strong>',
- ' This dataset has been hidden.', // Localize?
- ' </div>',
- '<% } %>',
- ' </div>',
- ' <div class="dataset-selector"><span class="fa fa-2x fa-square-o"></span></div>',
- ' <div class="dataset-primary-actions"></div>',
- ' <div class="dataset-title-bar clear" tabindex="0">',
- ' <span class="dataset-state-icon state-icon"></span>',
- ' <div class="dataset-title">',
- ' <span class="hda-hid"><%= hid %></span>',
- ' <span class="dataset-name"><%= name %></span>',
- ' </div>',
- ' </div>',
- ' <div class="dataset-body"></div>',
- '</div>',
+ '<div class="dataset-warnings">',
+ '<% if ( deleted ) { %>',
+ '<div class="dataset-deleted-msg warningmessagesmall"><strong>',
+ _l( 'This dataset has been deleted.' ),
+ '</div>',
+ '<% } %>',
+ '<% if ( ! visible ) { %>',
+ '<div class="dataset-hidden-msg warningmessagesmall"><strong>',
+ _l( 'This dataset has been hidden.' ),
+ '</div>',
+ '<% } %>',
+ '</div>',
+ '<div class="dataset-selector"><span class="fa fa-2x fa-square-o"></span></div>',
+ '<div class="dataset-primary-actions"></div>',
+ '<div class="dataset-title-bar clear" tabindex="0">',
+ '<span class="dataset-state-icon state-icon"></span>',
+ '<div class="dataset-title">',
+ '<span class="hda-hid"><%= hid %></span> ',
+ '<span class="dataset-name"><%= name %></span>',
+ '</div>',
+ '</div>',
+ '<div class="dataset-body"></div>',
+ '</div>'
].join( '' );
},
templateBody : function() {
return [
'<div class="dataset-body">',
- ' <div class="dataset-summary">',
- ' A dataset collection.',
- ' </div>',
-
+ '<div class="dataset-summary">',
+ 'A dataset collection.',
+ '</div>'
].join( '' );
-
},
_buildNewRender : function(){
@@ -170,8 +168,7 @@
*/
_render_body_ok : function(){
// most common state renderer and the most complicated
- var view = this,
- $body = $( _.template(this.templateBody(), this.model.toJSON() ) )
+ var $body = $( _.template( this.templateBody(), this.model.toJSON() ) );
// return shortened form if del'd (no display apps or peek?)
if( this.model.get( 'deleted' ) ){
@@ -188,4 +185,4 @@
DatasetCollectionBaseView : DatasetCollectionBaseView
};
-});
\ No newline at end of file
+});
diff -r 46a487e7d5476429cb71885adcbcfb9746ce725a -r 1d1d881508b121df607d9096386effdbe072427e static/scripts/mvc/collection/dataset-collection-edit.js
--- a/static/scripts/mvc/collection/dataset-collection-edit.js
+++ b/static/scripts/mvc/collection/dataset-collection-edit.js
@@ -57,7 +57,7 @@
}
deleteBtnData.faIcon = 'fa-times';
return faIconButton( deleteBtnData );
- },
+ }
});
@@ -66,4 +66,4 @@
DatasetCollectionEditView : DatasetCollectionEditView
};
-});
\ No newline at end of file
+});
diff -r 46a487e7d5476429cb71885adcbcfb9746ce725a -r 1d1d881508b121df607d9096386effdbe072427e static/scripts/mvc/dataset/hda-base.js
--- a/static/scripts/mvc/dataset/hda-base.js
+++ b/static/scripts/mvc/dataset/hda-base.js
@@ -47,7 +47,7 @@
}
if( this.draggable ){ this.draggableOn(); }
next();
- });
+ });
},
/** Show or hide the body/details of history content.
@@ -117,7 +117,7 @@
this.$el.find( '.dataset-selector span' )
.removeClass( 'fa-square-o' ).addClass( 'fa-check-square-o' );
if( !this.selected ){
- this.trigger( 'selected', this );
+ this.trigger( 'selected', this, event );
this.selected = true;
}
return false;
@@ -130,7 +130,7 @@
this.$el.find( '.dataset-selector span' )
.removeClass( 'fa-check-square-o' ).addClass( 'fa-square-o' );
if( this.selected ){
- this.trigger( 'de-selected', this );
+ this.trigger( 'de-selected', this, event );
this.selected = false;
}
return false;
@@ -142,7 +142,7 @@
} else {
this.select( event );
}
- },
+ }
});
diff -r 46a487e7d5476429cb71885adcbcfb9746ce725a -r 1d1d881508b121df607d9096386effdbe072427e static/scripts/mvc/history/history-panel.js
--- a/static/scripts/mvc/history/history-panel.js
+++ b/static/scripts/mvc/history/history-panel.js
@@ -45,6 +45,8 @@
// ---- set up instance vars
/** selected hda ids */
this.selectedHdaIds = [];
+ /** last selected hda */
+ this.lastSelectedViewId = null;
/** editor for tags - sub-view */
this.tagsEditor = null;
@@ -275,7 +277,7 @@
historyContentType = hda.get( 'history_content_type' ),
hdaView = null;
- if( historyContentType == "dataset" ) {
+ if( historyContentType === "dataset" ) {
hdaView = new this.HDAViewClass({
model : hda,
linkTarget : this.linkTarget,
@@ -288,7 +290,7 @@
tagsEditorShown : ( this.tagsEditor && !this.tagsEditor.hidden ),
annotationEditorShown : ( this.annotationEditor && !this.annotationEditor.hidden )
});
- } else if ( historyContentType == "dataset_collection" ) {
+ } else if ( historyContentType === "dataset_collection" ) {
hdaView = new datasetCollectionEdit.DatasetCollectionEditView({
model : hda,
linkTarget : this.linkTarget,
@@ -311,12 +313,33 @@
readonlyPanel.ReadOnlyHistoryPanel.prototype._setUpHdaListeners.call( this, hdaView );
// maintain a list of hdas that are selected
- hdaView.on( 'selected', function( hdaView ){
- var id = hdaView.model.get( 'id' );
- historyView.selectedHdaIds = _.union( historyView.selectedHdaIds, [ id ] );
+ hdaView.on( 'selected', function( hdaView, event ){
+ if( !event ){ return; }
+ //console.debug( 'selected', event );
+ var selectedIds = [];
+ //console.debug( historyView.lastSelectedViewId, historyView.hdaViews[ historyView.lastSelectedViewId ] );
+
+ // shift will select a range, but not set lastSelectedViewId
+ if( ( event.shiftKey )
+ && ( historyView.lastSelectedViewId && _.has( historyView.hdaViews, historyView.lastSelectedViewId ) ) ){
+ var lastSelectedView = historyView.hdaViews[ historyView.lastSelectedViewId ];
+ selectedIds = historyView.selectDatasetRange( hdaView, lastSelectedView )
+ .map( function( view ){ return view.model.id; });
+
+ // only
+ } else {
+ var id = hdaView.model.get( 'id' );
+ historyView.lastSelectedViewId = id;
+ //console.debug( 'lastSelectedViewId:', historyView.lastSelectedViewId );
+ selectedIds = [ id ];
+ }
+ //console.debug( 'selectedIds:', selectedIds );
+ historyView.selectedHdaIds = _.union( historyView.selectedHdaIds, selectedIds );
+ //TODO: might want to use getSelectedHdaViews instead managing these lists with ops
//console.debug( 'selected', historyView.selectedHdaIds );
});
- hdaView.on( 'de-selected', function( hdaView ){
+ hdaView.on( 'de-selected', function( hdaView, event ){
+ //console.debug( 'de-selected', event );
var id = hdaView.model.get( 'id' );
historyView.selectedHdaIds = _.without( historyView.selectedHdaIds, id );
//console.debug( 'de-selected', historyView.selectedHdaIds );
@@ -386,6 +409,7 @@
view.showSelector();
});
this.selectedHdaIds = [];
+ this.lastSelectedViewId = null;
},
/** hide selectors on all visible hdas and associated controls */
@@ -397,6 +421,7 @@
view.hideSelector();
});
this.selectedHdaIds = [];
+ this.lastSelectedViewId = null;
},
/** show or hide selectors on all visible hdas and associated controls */
@@ -417,11 +442,21 @@
/** deselect all visible hdas */
deselectAllDatasets : function( event ){
+ this.lastSelectedViewId = null;
_.each( this.hdaViews, function( view ){
view.deselect( event );
});
},
+ /** select a range of datasets between A and B */
+ selectDatasetRange : function( viewA, viewB ){
+ var range = this.hdaViewRange( viewA, viewB );
+ _.each( range, function( view ){
+ view.select();
+ });
+ return range;
+ },
+
/** return an array of all currently selected hdas */
getSelectedHdaViews : function(){
return _.filter( this.hdaViews, function( v ){
diff -r 46a487e7d5476429cb71885adcbcfb9746ce725a -r 1d1d881508b121df607d9096386effdbe072427e static/scripts/mvc/history/readonly-history-panel.js
--- a/static/scripts/mvc/history/readonly-history-panel.js
+++ b/static/scripts/mvc/history/readonly-history-panel.js
@@ -613,7 +613,7 @@
var hdaId = hda.get( 'id' ),
historyContentType = hda.get( "history_content_type" ),
hdaView = null;
- if( historyContentType == "dataset" ) {
+ if( historyContentType === "dataset" ){
hdaView = new this.HDAViewClass({
model : hda,
linkTarget : this.linkTarget,
@@ -717,6 +717,38 @@
// return ( model )?( this.hdaViews[ model.id ] ):( undefined );
//},
+ hdaViewRange : function( viewA, viewB ){
+ //console.debug( 'a: ', viewA, viewA.model );
+ //console.debug( 'b: ', viewB, viewB.model );
+ if( viewA === viewB ){ return [ viewA ]; }
+ //TODO: would probably be better if we cache'd the views as an ordered list (as well as a map)
+ var panel = this,
+ withinSet = false,
+ set = [];
+ this.model.hdas.getVisible(
+ this.storage.get( 'show_deleted' ),
+ this.storage.get( 'show_hidden' ),
+ this.filters
+ ).each( function( hda ){
+ //console.debug( 'checking: ', hda.get( 'name' ) );
+ if( withinSet ){
+ //console.debug( '\t\t adding: ', hda.get( 'name' ) );
+ set.push( panel.hdaViews[ hda.id ] );
+ if( hda === viewA.model || hda === viewB.model ){
+ //console.debug( '\t found last: ', hda.get( 'name' ) );
+ withinSet = false;
+ }
+ } else {
+ if( hda === viewA.model || hda === viewB.model ){
+ //console.debug( 'found first: ', hda.get( 'name' ) );
+ withinSet = true;
+ set.push( panel.hdaViews[ hda.id ] );
+ }
+ }
+ });
+ return set;
+ },
+
// ------------------------------------------------------------------------ panel events
/** event map */
events : {
diff -r 46a487e7d5476429cb71885adcbcfb9746ce725a -r 1d1d881508b121df607d9096386effdbe072427e static/scripts/packed/mvc/collection/dataset-collection-base.js
--- a/static/scripts/packed/mvc/collection/dataset-collection-base.js
+++ b/static/scripts/packed/mvc/collection/dataset-collection-base.js
@@ -1,1 +1,1 @@
-define(["mvc/dataset/hda-model","mvc/dataset/hda-base"],function(b,a){var c=a.HistoryContentBaseView.extend({className:"dataset hda history-panel-hda",id:function(){return"hdca-"+this.model.get("id")},initialize:function(d){if(d.logger){this.logger=this.model.logger=d.logger}this.log(this+".initialize:",d);this.selectable=d.selectable||false;this.selected=d.selected||false;this.expanded=d.expanded||false},render:function(e){var d=this._buildNewRender();this._queueNewRender(d,e);return this},templateSkeleton:function(){return['<div class="dataset hda">',' <div class="dataset-warnings">',"<% if ( deleted ) { %>",' <div class="dataset-deleted-msg warningmessagesmall"><strong>'," This dataset has been deleted."," </div>","<% } %>","<% if ( ! visible ) { %>",' <div class="dataset-hidden-msg warningmessagesmall"><strong>'," This dataset has been hidden."," </div>","<% } %>"," </div>",' <div class="dataset-selector"><span class="fa fa-2x fa-square-o"></span></div>',' <div class="dataset-primary-actions"></div>',' <div class="dataset-title-bar clear" tabindex="0">',' <span class="dataset-state-icon state-icon"></span>',' <div class="dataset-title">',' <span class="hda-hid"><%= hid %></span>',' <span class="dataset-name"><%= name %></span>'," </div>"," </div>",' <div class="dataset-body"></div>',"</div>",].join("")},templateBody:function(){return['<div class="dataset-body">',' <div class="dataset-summary">'," A dataset collection."," </div>",].join("")},_buildNewRender:function(){var d=$(_.template(this.templateSkeleton(),this.model.toJSON()));d.find(".dataset-primary-actions").append(this._render_titleButtons());d.children(".dataset-body").replaceWith(this._render_body());this._setUpBehaviors(d);return d},_render_titleButtons:function(){return[]},_render_body:function(){var e=$('<div>Error: unknown state "'+this.model.get("state")+'".</div>'),d=this["_render_body_"+this.model.get("state")];if(_.isFunction(d)){e=d.call(this)}this._setUpBehaviors(e);if(this.expanded){e.show()}return e},_setUpBehaviors:function(d){d=d||this.$el;make_popup_menus(d);d.find("[title]").tooltip({placement:"bottom"})},events:{"click .dataset-title-bar":"toggleBodyVisibility","keydown .dataset-title-bar":"toggleBodyVisibility","click .dataset-selector":"toggleSelect"},expandBody:function(){var d=this;function e(){d.$el.children(".dataset-body").replaceWith(d._render_body());d.$el.children(".dataset-body").slideDown(d.fxSpeed,function(){d.expanded=true;d.trigger("body-expanded",d.model.get("id"))})}e()},collapseBody:function(){var d=this;this.$el.children(".dataset-body").slideUp(d.fxSpeed,function(){d.expanded=false;d.trigger("body-collapsed",d.model.get("id"))})},_render_body_ok:function(){var d=this,e=$(_.template(this.templateBody(),this.model.toJSON()));if(this.model.get("deleted")){return e}return e}});return{DatasetCollectionBaseView:c}});
\ No newline at end of file
+define(["mvc/dataset/hda-model","mvc/dataset/hda-base"],function(b,a){var c=a.HistoryContentBaseView.extend({className:"dataset hda history-panel-hda",id:function(){return"hdca-"+this.model.get("id")},initialize:function(d){if(d.logger){this.logger=this.model.logger=d.logger}this.log(this+".initialize:",d);this.selectable=d.selectable||false;this.selected=d.selected||false;this.expanded=d.expanded||false},render:function(e){var d=this._buildNewRender();this._queueNewRender(d,e);return this},templateSkeleton:function(){return['<div class="dataset hda">','<div class="dataset-warnings">',"<% if ( deleted ) { %>",'<div class="dataset-deleted-msg warningmessagesmall"><strong>',_l("This dataset has been deleted."),"</div>","<% } %>","<% if ( ! visible ) { %>",'<div class="dataset-hidden-msg warningmessagesmall"><strong>',_l("This dataset has been hidden."),"</div>","<% } %>","</div>",'<div class="dataset-selector"><span class="fa fa-2x fa-square-o"></span></div>','<div class="dataset-primary-actions"></div>','<div class="dataset-title-bar clear" tabindex="0">','<span class="dataset-state-icon state-icon"></span>','<div class="dataset-title">','<span class="hda-hid"><%= hid %></span> ','<span class="dataset-name"><%= name %></span>',"</div>","</div>",'<div class="dataset-body"></div>',"</div>"].join("")},templateBody:function(){return['<div class="dataset-body">','<div class="dataset-summary">',"A dataset collection.","</div>"].join("")},_buildNewRender:function(){var d=$(_.template(this.templateSkeleton(),this.model.toJSON()));d.find(".dataset-primary-actions").append(this._render_titleButtons());d.children(".dataset-body").replaceWith(this._render_body());this._setUpBehaviors(d);return d},_render_titleButtons:function(){return[]},_render_body:function(){var e=$('<div>Error: unknown state "'+this.model.get("state")+'".</div>'),d=this["_render_body_"+this.model.get("state")];if(_.isFunction(d)){e=d.call(this)}this._setUpBehaviors(e);if(this.expanded){e.show()}return e},_setUpBehaviors:function(d){d=d||this.$el;make_popup_menus(d);d.find("[title]").tooltip({placement:"bottom"})},events:{"click .dataset-title-bar":"toggleBodyVisibility","keydown .dataset-title-bar":"toggleBodyVisibility","click .dataset-selector":"toggleSelect"},expandBody:function(){var d=this;function e(){d.$el.children(".dataset-body").replaceWith(d._render_body());d.$el.children(".dataset-body").slideDown(d.fxSpeed,function(){d.expanded=true;d.trigger("body-expanded",d.model.get("id"))})}e()},collapseBody:function(){var d=this;this.$el.children(".dataset-body").slideUp(d.fxSpeed,function(){d.expanded=false;d.trigger("body-collapsed",d.model.get("id"))})},_render_body_ok:function(){var d=$(_.template(this.templateBody(),this.model.toJSON()));if(this.model.get("deleted")){return d}return d}});return{DatasetCollectionBaseView:c}});
\ No newline at end of file
diff -r 46a487e7d5476429cb71885adcbcfb9746ce725a -r 1d1d881508b121df607d9096386effdbe072427e static/scripts/packed/mvc/collection/dataset-collection-edit.js
--- a/static/scripts/packed/mvc/collection/dataset-collection-edit.js
+++ b/static/scripts/packed/mvc/collection/dataset-collection-edit.js
@@ -1,1 +1,1 @@
-define(["mvc/dataset/hda-model","mvc/collection/dataset-collection-base",],function(b,c){var a=c.DatasetCollectionBaseView.extend({initialize:function(d){c.DatasetCollectionBaseView.prototype.initialize.call(this,d)},_render_titleButtons:function(){return c.DatasetCollectionBaseView.prototype._render_titleButtons.call(this).concat([this._render_deleteButton()])},_render_deleteButton:function(){if((this.model.get("state")===b.HistoryDatasetAssociation.STATES.NEW)||(this.model.get("state")===b.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){return null}var d=this,e={title:_l("Delete"),classes:"dataset-delete",onclick:function(){d.$el.find(".icon-btn.dataset-delete").trigger("mouseout");d.model["delete"]()}};if(this.model.get("deleted")){e={title:_l("Dataset collection is already deleted"),disabled:true}}e.faIcon="fa-times";return faIconButton(e)},});return{DatasetCollectionEditView:a}});
\ No newline at end of file
+define(["mvc/dataset/hda-model","mvc/collection/dataset-collection-base",],function(b,c){var a=c.DatasetCollectionBaseView.extend({initialize:function(d){c.DatasetCollectionBaseView.prototype.initialize.call(this,d)},_render_titleButtons:function(){return c.DatasetCollectionBaseView.prototype._render_titleButtons.call(this).concat([this._render_deleteButton()])},_render_deleteButton:function(){if((this.model.get("state")===b.HistoryDatasetAssociation.STATES.NEW)||(this.model.get("state")===b.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){return null}var d=this,e={title:_l("Delete"),classes:"dataset-delete",onclick:function(){d.$el.find(".icon-btn.dataset-delete").trigger("mouseout");d.model["delete"]()}};if(this.model.get("deleted")){e={title:_l("Dataset collection is already deleted"),disabled:true}}e.faIcon="fa-times";return faIconButton(e)}});return{DatasetCollectionEditView:a}});
\ No newline at end of file
diff -r 46a487e7d5476429cb71885adcbcfb9746ce725a -r 1d1d881508b121df607d9096386effdbe072427e static/scripts/packed/mvc/dataset/hda-base.js
--- a/static/scripts/packed/mvc/dataset/hda-base.js
+++ b/static/scripts/packed/mvc/dataset/hda-base.js
@@ -1,1 +1,1 @@
-define(["mvc/dataset/hda-model","mvc/base-mvc","mvc/data","utils/localization"],function(e,b,g,d){var h=Backbone.View.extend(b.LoggableMixin).extend({tagName:"div",fxSpeed:"fast",_queueNewRender:function(j,k){k=(k===undefined)?(true):(k);var i=this;if(k){$(i).queue(function(l){this.$el.fadeOut(i.fxSpeed,l)})}$(i).queue(function(l){this.$el.empty().attr("class",i.className).addClass("state-"+i.model.get("state")).append(j.children());if(this.selectable){this.showSelector(0)}l()});if(k){$(i).queue(function(l){this.$el.fadeIn(i.fxSpeed,l)})}$(i).queue(function(l){this.trigger("rendered",i);if(this.model.inReadyState()){this.trigger("rendered:ready",i)}if(this.draggable){this.draggableOn()}l()})},toggleBodyVisibility:function(l,j){var i=32,k=13;if(l&&(l.type==="keydown")&&!(l.keyCode===i||l.keyCode===k)){return true}var m=this.$el.find(".dataset-body");j=(j===undefined)?(!m.is(":visible")):(j);if(j){this.expandBody()}else{this.collapseBody()}return false},showSelector:function(){if(this.selected){this.select(null,true)}this.selectable=true;this.trigger("selectable",true,this);this.$(".dataset-primary-actions").hide();this.$(".dataset-selector").show()},hideSelector:function(){this.selectable=false;this.trigger("selectable",false,this);this.$(".dataset-selector").hide();this.$(".dataset-primary-actions").show()},toggleSelector:function(){if(!this.$el.find(".dataset-selector").is(":visible")){this.showSelector()}else{this.hideSelector()}},select:function(i){this.$el.find(".dataset-selector span").removeClass("fa-square-o").addClass("fa-check-square-o");if(!this.selected){this.trigger("selected",this);this.selected=true}return false},deselect:function(i){this.$el.find(".dataset-selector span").removeClass("fa-check-square-o").addClass("fa-square-o");if(this.selected){this.trigger("de-selected",this);this.selected=false}return false},toggleSelect:function(i){if(this.selected){this.deselect(i)}else{this.select(i)}},});var c=h.extend({className:"dataset hda history-panel-hda",id:function(){return"hda-"+this.model.get("id")},initialize:function(i){if(i.logger){this.logger=this.model.logger=i.logger}this.log(this+".initialize:",i);this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton];this.linkTarget=i.linkTarget||"_blank";this.selectable=i.selectable||false;this.selected=i.selected||false;this.expanded=i.expanded||false;this.draggable=i.draggable||false;this._setUpListeners()},_setUpListeners:function(){this.model.on("change",function(j,i){if(this.model.changedAttributes().state&&this.model.inReadyState()&&this.expanded&&!this.model.hasDetails()){this.model.fetch()}else{this.render()}},this)},render:function(j){this.$el.find("[title]").tooltip("destroy");this.urls=this.model.urls();var i=this._buildNewRender();this._queueNewRender(i,j);return this},_buildNewRender:function(){var i=$(c.templates.skeleton(this.model.toJSON()));i.find(".dataset-primary-actions").append(this._render_titleButtons());i.children(".dataset-body").replaceWith(this._render_body());this._setUpBehaviors(i);return i},_setUpBehaviors:function(i){i=i||this.$el;make_popup_menus(i);i.find("[title]").tooltip({placement:"bottom"})},_render_titleButtons:function(){return[this._render_displayButton()]},_render_displayButton:function(){if((this.model.get("state")===e.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(this.model.get("state")===e.HistoryDatasetAssociation.STATES.DISCARDED)||(!this.model.get("accessible"))){return null}var j={target:this.linkTarget,classes:"dataset-display"};if(this.model.get("purged")){j.disabled=true;j.title=d("Cannot display datasets removed from disk")}else{if(this.model.get("state")===e.HistoryDatasetAssociation.STATES.UPLOAD){j.disabled=true;j.title=d("This dataset must finish uploading before it can be viewed")}else{if(this.model.get("state")===e.HistoryDatasetAssociation.STATES.NEW){j.disabled=true;j.title=d("This dataset is not yet viewable")}else{j.title=d("View data");j.href=this.urls.display;var i=this;j.onclick=function(k){if(Galaxy.frame&&Galaxy.frame.active){Galaxy.frame.add({title:"Data Viewer: "+i.model.get("name"),type:"other",content:function(l){var m=new g.TabularDataset({id:i.model.id});$.when(m.fetch()).then(function(){g.createTabularDatasetChunkedView({model:m,parent_elt:l,embedded:true,height:"100%"})})}});k.preventDefault()}}}}}j.faIcon="fa-eye";return faIconButton(j)},_render_downloadButton:function(){if(this.model.get("purged")||!this.model.hasData()){return null}var j=this.urls,k=this.model.get("meta_files");if(_.isEmpty(k)){return $(['<a href="'+j.download+'" title="'+d("Download")+'" ','class="icon-btn dataset-download-btn">','<span class="fa fa-floppy-o"></span>',"</a>"].join(""))}var l="dataset-"+this.model.get("id")+"-popup",i=['<div popupmenu="'+l+'">','<a href="'+j.download+'">',d("Download dataset"),"</a>","<a>"+d("Additional files")+"</a>",_.map(k,function(m){return['<a class="action-button" href="',j.meta_download+m.file_type,'">',d("Download")," ",m.file_type,"</a>"].join("")}).join("\n"),"</div>",'<div class="icon-btn-group">','<a href="'+j.download+'" title="'+d("Download")+'" ','class="icon-btn dataset-download-btn">','<span class="fa fa-floppy-o"></span>','</a><a class="icon-btn popup" id="'+l+'">','<span class="fa fa-caret-down"></span>',"</a>","</div>"].join("\n");return $(i)},_render_showParamsButton:function(){return faIconButton({title:d("View details"),classes:"dataset-params-btn",href:this.urls.show_params,target:this.linkTarget,faIcon:"fa-info-circle"})},_render_body:function(){var j=$('<div>Error: unknown dataset state "'+this.model.get("state")+'".</div>'),i=this["_render_body_"+this.model.get("state")];if(_.isFunction(i)){j=i.call(this)}this._setUpBehaviors(j);if(this.expanded){j.show()}return j},_render_stateBodyHelper:function(i,l){l=l||[];var j=this,k=$(c.templates.body(_.extend(this.model.toJSON(),{body:i})));k.find(".dataset-actions .left").append(_.map(l,function(m){return m.call(j)}));return k},_render_body_new:function(){return this._render_stateBodyHelper("<div>"+d("This is a new dataset and not all of its data are available yet")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_noPermission:function(){return this._render_stateBodyHelper("<div>"+d("You do not have permission to view this dataset")+"</div>")},_render_body_discarded:function(){return this._render_stateBodyHelper("<div>"+d("The job creating this dataset was cancelled before completion")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_queued:function(){return this._render_stateBodyHelper("<div>"+d("This job is waiting to run")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_upload:function(){return this._render_stateBodyHelper("<div>"+d("This dataset is currently uploading")+"</div>")},_render_body_setting_metadata:function(){return this._render_stateBodyHelper("<div>"+d("Metadata is being auto-detected")+"</div>")},_render_body_running:function(){return this._render_stateBodyHelper("<div>"+d("This job is currently running")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_paused:function(){return this._render_stateBodyHelper("<div>"+d('This job is paused. Use the "Resume Paused Jobs" in the history menu to resume')+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_error:function(){var i=['<span class="help-text">',d("An error occurred with this dataset"),":</span>",'<div class="job-error-text">',$.trim(this.model.get("misc_info")),"</div>"].join("");if(!this.model.get("purged")){i="<div>"+this.model.get("misc_blurb")+"</div>"+i}return this._render_stateBodyHelper(i,[this._render_downloadButton].concat(this.defaultPrimaryActionButtonRenderers))},_render_body_empty:function(){return this._render_stateBodyHelper("<div>"+d("No data")+": <i>"+this.model.get("misc_blurb")+"</i></div>",this.defaultPrimaryActionButtonRenderers)},_render_body_failed_metadata:function(){var i=$('<div class="warningmessagesmall"></div>').append($("<strong/>").text(d("An error occurred setting the metadata for this dataset"))),j=this._render_body_ok();j.prepend(i);return j},_render_body_ok:function(){var i=this,k=$(c.templates.body(this.model.toJSON())),j=[this._render_downloadButton].concat(this.defaultPrimaryActionButtonRenderers);k.find(".dataset-actions .left").append(_.map(j,function(l){return l.call(i)}));if(this.model.isDeletedOrPurged()){return k}return k},events:{"click .dataset-title-bar":"toggleBodyVisibility","keydown .dataset-title-bar":"toggleBodyVisibility","click .dataset-selector":"toggleSelect"},expandBody:function(){var i=this;function j(){i.$el.children(".dataset-body").replaceWith(i._render_body());i.$el.children(".dataset-body").slideDown(i.fxSpeed,function(){i.expanded=true;i.trigger("body-expanded",i.model.get("id"))})}if(this.model.inReadyState()&&!this.model.hasDetails()){this.model.fetch({silent:true}).always(function(k){i.urls=i.model.urls();j()})}else{j()}},collapseBody:function(){var i=this;this.$el.children(".dataset-body").slideUp(i.fxSpeed,function(){i.expanded=false;i.trigger("body-collapsed",i.model.get("id"))})},draggableOn:function(){this.draggable=true;this.dragStartHandler=_.bind(this._dragStartHandler,this);this.dragEndHandler=_.bind(this._dragEndHandler,this);var i=this.$el.find(".dataset-title-bar").attr("draggable",true).get(0);i.addEventListener("dragstart",this.dragStartHandler,false);i.addEventListener("dragend",this.dragEndHandler,false)},draggableOff:function(){this.draggable=false;var i=this.$el.find(".dataset-title-bar").attr("draggable",false).get(0);i.removeEventListener("dragstart",this.dragStartHandler,false);i.removeEventListener("dragend",this.dragEndHandler,false)},toggleDraggable:function(){if(this.draggable){this.draggableOff()}else{this.draggableOn()}},_dragStartHandler:function(i){this.trigger("dragstart",this);i.dataTransfer.effectAllowed="move";i.dataTransfer.setData("text",JSON.stringify(this.model.toJSON()));return false},_dragEndHandler:function(i){this.trigger("dragend",this);return false},remove:function(j){var i=this;this.$el.fadeOut(i.fxSpeed,function(){i.$el.remove();i.off();if(j){j()}})},toString:function(){var i=(this.model)?(this.model+""):("(no model)");return"HDABaseView("+i+")"}});var a=_.template(['<div class="dataset hda">','<div class="dataset-warnings">',"<% if( hda.error ){ %>",'<div class="errormessagesmall">',d("There was an error getting the data for this dataset"),":<%- hda.error %>","</div>","<% } %>","<% if( hda.deleted ){ %>","<% if( hda.purged ){ %>",'<div class="dataset-purged-msg warningmessagesmall"><strong>',d("This dataset has been deleted and removed from disk")+".","</strong></div>","<% } else { %>",'<div class="dataset-deleted-msg warningmessagesmall"><strong>',d("This dataset has been deleted")+".","</strong></div>","<% } %>","<% } %>","<% if( !hda.visible ){ %>",'<div class="dataset-hidden-msg warningmessagesmall"><strong>',d("This dataset has been hidden")+".","</strong></div>","<% } %>","</div>",'<div class="dataset-selector">','<span class="fa fa-2x fa-square-o"></span>',"</div>",'<div class="dataset-primary-actions"></div>','<div class="dataset-title-bar clear" tabindex="0">','<span class="dataset-state-icon state-icon"></span>','<div class="dataset-title">','<span class="hda-hid"><%- hda.hid %></span> ','<span class="dataset-name"><%- hda.name %></span>',"</div>","</div>",'<div class="dataset-body"></div>',"</div>"].join(""));var f=_.template(['<div class="dataset-body">',"<% if( hda.body ){ %>",'<div class="dataset-summary">',"<%= hda.body %>","</div>",'<div class="dataset-actions clear">','<div class="left"></div>','<div class="right"></div>',"</div>","<% } else { %>",'<div class="dataset-summary">',"<% if( hda.misc_blurb ){ %>",'<div class="dataset-blurb">','<span class="value"><%- hda.misc_blurb %></span>',"</div>","<% } %>","<% if( hda.data_type ){ %>",'<div class="dataset-datatype">','<label class="prompt">',d("format"),"</label>",'<span class="value"><%- hda.data_type %></span>',"</div>","<% } %>","<% if( hda.metadata_dbkey ){ %>",'<div class="dataset-dbkey">','<label class="prompt">',d("database"),"</label>",'<span class="value">',"<%- hda.metadata_dbkey %>","</span>","</div>","<% } %>","<% if( hda.misc_info ){ %>",'<div class="dataset-info">','<span class="value"><%- hda.misc_info %></span>',"</div>","<% } %>","</div>",'<div class="dataset-actions clear">','<div class="left"></div>','<div class="right"></div>',"</div>","<% if( !hda.deleted ){ %>",'<div class="tags-display"></div>','<div class="annotation-display"></div>','<div class="dataset-display-applications">',"<% _.each( hda.display_apps, function( app ){ %>",'<div class="display-application">','<span class="display-application-location"><%- app.label %></span> ','<span class="display-application-links">',"<% _.each( app.links, function( link ){ %>",'<a target="<%= link.target %>" href="<%= link.href %>">',"<% print( _l( link.text ) ); %>","</a> ","<% }); %>","</span>","</div>","<% }); %>","<% _.each( hda.display_types, function( app ){ %>",'<div class="display-application">','<span class="display-application-location"><%- app.label %></span> ','<span class="display-application-links">',"<% _.each( app.links, function( link ){ %>",'<a target="<%= link.target %>" href="<%= link.href %>">',"<% print( _l( link.text ) ); %>","</a> ","<% }); %>","</span>","</div>","<% }); %>","</div>",'<div class="dataset-peek">',"<% if( hda.peek ){ %>",'<pre class="peek"><%= hda.peek %></pre>',"<% } %>","</div>","<% } %>","<% } %>","</div>"].join(""));c.templates={skeleton:function(i){return a({_l:d,hda:i})},body:function(i){return f({_l:d,hda:i})}};return{HistoryContentBaseView:h,HDABaseView:c}});
\ No newline at end of file
+define(["mvc/dataset/hda-model","mvc/base-mvc","mvc/data","utils/localization"],function(e,b,g,d){var h=Backbone.View.extend(b.LoggableMixin).extend({tagName:"div",fxSpeed:"fast",_queueNewRender:function(j,k){k=(k===undefined)?(true):(k);var i=this;if(k){$(i).queue(function(l){this.$el.fadeOut(i.fxSpeed,l)})}$(i).queue(function(l){this.$el.empty().attr("class",i.className).addClass("state-"+i.model.get("state")).append(j.children());if(this.selectable){this.showSelector(0)}l()});if(k){$(i).queue(function(l){this.$el.fadeIn(i.fxSpeed,l)})}$(i).queue(function(l){this.trigger("rendered",i);if(this.model.inReadyState()){this.trigger("rendered:ready",i)}if(this.draggable){this.draggableOn()}l()})},toggleBodyVisibility:function(l,j){var i=32,k=13;if(l&&(l.type==="keydown")&&!(l.keyCode===i||l.keyCode===k)){return true}var m=this.$el.find(".dataset-body");j=(j===undefined)?(!m.is(":visible")):(j);if(j){this.expandBody()}else{this.collapseBody()}return false},showSelector:function(){if(this.selected){this.select(null,true)}this.selectable=true;this.trigger("selectable",true,this);this.$(".dataset-primary-actions").hide();this.$(".dataset-selector").show()},hideSelector:function(){this.selectable=false;this.trigger("selectable",false,this);this.$(".dataset-selector").hide();this.$(".dataset-primary-actions").show()},toggleSelector:function(){if(!this.$el.find(".dataset-selector").is(":visible")){this.showSelector()}else{this.hideSelector()}},select:function(i){this.$el.find(".dataset-selector span").removeClass("fa-square-o").addClass("fa-check-square-o");if(!this.selected){this.trigger("selected",this,i);this.selected=true}return false},deselect:function(i){this.$el.find(".dataset-selector span").removeClass("fa-check-square-o").addClass("fa-square-o");if(this.selected){this.trigger("de-selected",this,i);this.selected=false}return false},toggleSelect:function(i){if(this.selected){this.deselect(i)}else{this.select(i)}}});var c=h.extend({className:"dataset hda history-panel-hda",id:function(){return"hda-"+this.model.get("id")},initialize:function(i){if(i.logger){this.logger=this.model.logger=i.logger}this.log(this+".initialize:",i);this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton];this.linkTarget=i.linkTarget||"_blank";this.selectable=i.selectable||false;this.selected=i.selected||false;this.expanded=i.expanded||false;this.draggable=i.draggable||false;this._setUpListeners()},_setUpListeners:function(){this.model.on("change",function(j,i){if(this.model.changedAttributes().state&&this.model.inReadyState()&&this.expanded&&!this.model.hasDetails()){this.model.fetch()}else{this.render()}},this)},render:function(j){this.$el.find("[title]").tooltip("destroy");this.urls=this.model.urls();var i=this._buildNewRender();this._queueNewRender(i,j);return this},_buildNewRender:function(){var i=$(c.templates.skeleton(this.model.toJSON()));i.find(".dataset-primary-actions").append(this._render_titleButtons());i.children(".dataset-body").replaceWith(this._render_body());this._setUpBehaviors(i);return i},_setUpBehaviors:function(i){i=i||this.$el;make_popup_menus(i);i.find("[title]").tooltip({placement:"bottom"})},_render_titleButtons:function(){return[this._render_displayButton()]},_render_displayButton:function(){if((this.model.get("state")===e.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(this.model.get("state")===e.HistoryDatasetAssociation.STATES.DISCARDED)||(!this.model.get("accessible"))){return null}var j={target:this.linkTarget,classes:"dataset-display"};if(this.model.get("purged")){j.disabled=true;j.title=d("Cannot display datasets removed from disk")}else{if(this.model.get("state")===e.HistoryDatasetAssociation.STATES.UPLOAD){j.disabled=true;j.title=d("This dataset must finish uploading before it can be viewed")}else{if(this.model.get("state")===e.HistoryDatasetAssociation.STATES.NEW){j.disabled=true;j.title=d("This dataset is not yet viewable")}else{j.title=d("View data");j.href=this.urls.display;var i=this;j.onclick=function(k){if(Galaxy.frame&&Galaxy.frame.active){Galaxy.frame.add({title:"Data Viewer: "+i.model.get("name"),type:"other",content:function(l){var m=new g.TabularDataset({id:i.model.id});$.when(m.fetch()).then(function(){g.createTabularDatasetChunkedView({model:m,parent_elt:l,embedded:true,height:"100%"})})}});k.preventDefault()}}}}}j.faIcon="fa-eye";return faIconButton(j)},_render_downloadButton:function(){if(this.model.get("purged")||!this.model.hasData()){return null}var j=this.urls,k=this.model.get("meta_files");if(_.isEmpty(k)){return $(['<a href="'+j.download+'" title="'+d("Download")+'" ','class="icon-btn dataset-download-btn">','<span class="fa fa-floppy-o"></span>',"</a>"].join(""))}var l="dataset-"+this.model.get("id")+"-popup",i=['<div popupmenu="'+l+'">','<a href="'+j.download+'">',d("Download dataset"),"</a>","<a>"+d("Additional files")+"</a>",_.map(k,function(m){return['<a class="action-button" href="',j.meta_download+m.file_type,'">',d("Download")," ",m.file_type,"</a>"].join("")}).join("\n"),"</div>",'<div class="icon-btn-group">','<a href="'+j.download+'" title="'+d("Download")+'" ','class="icon-btn dataset-download-btn">','<span class="fa fa-floppy-o"></span>','</a><a class="icon-btn popup" id="'+l+'">','<span class="fa fa-caret-down"></span>',"</a>","</div>"].join("\n");return $(i)},_render_showParamsButton:function(){return faIconButton({title:d("View details"),classes:"dataset-params-btn",href:this.urls.show_params,target:this.linkTarget,faIcon:"fa-info-circle"})},_render_body:function(){var j=$('<div>Error: unknown dataset state "'+this.model.get("state")+'".</div>'),i=this["_render_body_"+this.model.get("state")];if(_.isFunction(i)){j=i.call(this)}this._setUpBehaviors(j);if(this.expanded){j.show()}return j},_render_stateBodyHelper:function(i,l){l=l||[];var j=this,k=$(c.templates.body(_.extend(this.model.toJSON(),{body:i})));k.find(".dataset-actions .left").append(_.map(l,function(m){return m.call(j)}));return k},_render_body_new:function(){return this._render_stateBodyHelper("<div>"+d("This is a new dataset and not all of its data are available yet")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_noPermission:function(){return this._render_stateBodyHelper("<div>"+d("You do not have permission to view this dataset")+"</div>")},_render_body_discarded:function(){return this._render_stateBodyHelper("<div>"+d("The job creating this dataset was cancelled before completion")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_queued:function(){return this._render_stateBodyHelper("<div>"+d("This job is waiting to run")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_upload:function(){return this._render_stateBodyHelper("<div>"+d("This dataset is currently uploading")+"</div>")},_render_body_setting_metadata:function(){return this._render_stateBodyHelper("<div>"+d("Metadata is being auto-detected")+"</div>")},_render_body_running:function(){return this._render_stateBodyHelper("<div>"+d("This job is currently running")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_paused:function(){return this._render_stateBodyHelper("<div>"+d('This job is paused. Use the "Resume Paused Jobs" in the history menu to resume')+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_error:function(){var i=['<span class="help-text">',d("An error occurred with this dataset"),":</span>",'<div class="job-error-text">',$.trim(this.model.get("misc_info")),"</div>"].join("");if(!this.model.get("purged")){i="<div>"+this.model.get("misc_blurb")+"</div>"+i}return this._render_stateBodyHelper(i,[this._render_downloadButton].concat(this.defaultPrimaryActionButtonRenderers))},_render_body_empty:function(){return this._render_stateBodyHelper("<div>"+d("No data")+": <i>"+this.model.get("misc_blurb")+"</i></div>",this.defaultPrimaryActionButtonRenderers)},_render_body_failed_metadata:function(){var i=$('<div class="warningmessagesmall"></div>').append($("<strong/>").text(d("An error occurred setting the metadata for this dataset"))),j=this._render_body_ok();j.prepend(i);return j},_render_body_ok:function(){var i=this,k=$(c.templates.body(this.model.toJSON())),j=[this._render_downloadButton].concat(this.defaultPrimaryActionButtonRenderers);k.find(".dataset-actions .left").append(_.map(j,function(l){return l.call(i)}));if(this.model.isDeletedOrPurged()){return k}return k},events:{"click .dataset-title-bar":"toggleBodyVisibility","keydown .dataset-title-bar":"toggleBodyVisibility","click .dataset-selector":"toggleSelect"},expandBody:function(){var i=this;function j(){i.$el.children(".dataset-body").replaceWith(i._render_body());i.$el.children(".dataset-body").slideDown(i.fxSpeed,function(){i.expanded=true;i.trigger("body-expanded",i.model.get("id"))})}if(this.model.inReadyState()&&!this.model.hasDetails()){this.model.fetch({silent:true}).always(function(k){i.urls=i.model.urls();j()})}else{j()}},collapseBody:function(){var i=this;this.$el.children(".dataset-body").slideUp(i.fxSpeed,function(){i.expanded=false;i.trigger("body-collapsed",i.model.get("id"))})},draggableOn:function(){this.draggable=true;this.dragStartHandler=_.bind(this._dragStartHandler,this);this.dragEndHandler=_.bind(this._dragEndHandler,this);var i=this.$el.find(".dataset-title-bar").attr("draggable",true).get(0);i.addEventListener("dragstart",this.dragStartHandler,false);i.addEventListener("dragend",this.dragEndHandler,false)},draggableOff:function(){this.draggable=false;var i=this.$el.find(".dataset-title-bar").attr("draggable",false).get(0);i.removeEventListener("dragstart",this.dragStartHandler,false);i.removeEventListener("dragend",this.dragEndHandler,false)},toggleDraggable:function(){if(this.draggable){this.draggableOff()}else{this.draggableOn()}},_dragStartHandler:function(i){this.trigger("dragstart",this);i.dataTransfer.effectAllowed="move";i.dataTransfer.setData("text",JSON.stringify(this.model.toJSON()));return false},_dragEndHandler:function(i){this.trigger("dragend",this);return false},remove:function(j){var i=this;this.$el.fadeOut(i.fxSpeed,function(){i.$el.remove();i.off();if(j){j()}})},toString:function(){var i=(this.model)?(this.model+""):("(no model)");return"HDABaseView("+i+")"}});var a=_.template(['<div class="dataset hda">','<div class="dataset-warnings">',"<% if( hda.error ){ %>",'<div class="errormessagesmall">',d("There was an error getting the data for this dataset"),":<%- hda.error %>","</div>","<% } %>","<% if( hda.deleted ){ %>","<% if( hda.purged ){ %>",'<div class="dataset-purged-msg warningmessagesmall"><strong>',d("This dataset has been deleted and removed from disk")+".","</strong></div>","<% } else { %>",'<div class="dataset-deleted-msg warningmessagesmall"><strong>',d("This dataset has been deleted")+".","</strong></div>","<% } %>","<% } %>","<% if( !hda.visible ){ %>",'<div class="dataset-hidden-msg warningmessagesmall"><strong>',d("This dataset has been hidden")+".","</strong></div>","<% } %>","</div>",'<div class="dataset-selector">','<span class="fa fa-2x fa-square-o"></span>',"</div>",'<div class="dataset-primary-actions"></div>','<div class="dataset-title-bar clear" tabindex="0">','<span class="dataset-state-icon state-icon"></span>','<div class="dataset-title">','<span class="hda-hid"><%- hda.hid %></span> ','<span class="dataset-name"><%- hda.name %></span>',"</div>","</div>",'<div class="dataset-body"></div>',"</div>"].join(""));var f=_.template(['<div class="dataset-body">',"<% if( hda.body ){ %>",'<div class="dataset-summary">',"<%= hda.body %>","</div>",'<div class="dataset-actions clear">','<div class="left"></div>','<div class="right"></div>',"</div>","<% } else { %>",'<div class="dataset-summary">',"<% if( hda.misc_blurb ){ %>",'<div class="dataset-blurb">','<span class="value"><%- hda.misc_blurb %></span>',"</div>","<% } %>","<% if( hda.data_type ){ %>",'<div class="dataset-datatype">','<label class="prompt">',d("format"),"</label>",'<span class="value"><%- hda.data_type %></span>',"</div>","<% } %>","<% if( hda.metadata_dbkey ){ %>",'<div class="dataset-dbkey">','<label class="prompt">',d("database"),"</label>",'<span class="value">',"<%- hda.metadata_dbkey %>","</span>","</div>","<% } %>","<% if( hda.misc_info ){ %>",'<div class="dataset-info">','<span class="value"><%- hda.misc_info %></span>',"</div>","<% } %>","</div>",'<div class="dataset-actions clear">','<div class="left"></div>','<div class="right"></div>',"</div>","<% if( !hda.deleted ){ %>",'<div class="tags-display"></div>','<div class="annotation-display"></div>','<div class="dataset-display-applications">',"<% _.each( hda.display_apps, function( app ){ %>",'<div class="display-application">','<span class="display-application-location"><%- app.label %></span> ','<span class="display-application-links">',"<% _.each( app.links, function( link ){ %>",'<a target="<%= link.target %>" href="<%= link.href %>">',"<% print( _l( link.text ) ); %>","</a> ","<% }); %>","</span>","</div>","<% }); %>","<% _.each( hda.display_types, function( app ){ %>",'<div class="display-application">','<span class="display-application-location"><%- app.label %></span> ','<span class="display-application-links">',"<% _.each( app.links, function( link ){ %>",'<a target="<%= link.target %>" href="<%= link.href %>">',"<% print( _l( link.text ) ); %>","</a> ","<% }); %>","</span>","</div>","<% }); %>","</div>",'<div class="dataset-peek">',"<% if( hda.peek ){ %>",'<pre class="peek"><%= hda.peek %></pre>',"<% } %>","</div>","<% } %>","<% } %>","</div>"].join(""));c.templates={skeleton:function(i){return a({_l:d,hda:i})},body:function(i){return f({_l:d,hda:i})}};return{HistoryContentBaseView:h,HDABaseView:c}});
\ No newline at end of file
diff -r 46a487e7d5476429cb71885adcbcfb9746ce725a -r 1d1d881508b121df607d9096386effdbe072427e static/scripts/packed/mvc/history/history-panel.js
--- a/static/scripts/packed/mvc/history/history-panel.js
+++ b/static/scripts/packed/mvc/history/history-panel.js
@@ -1,1 +1,1 @@
-define(["mvc/dataset/hda-model","mvc/dataset/hda-edit","mvc/collection/dataset-collection-edit","mvc/history/readonly-history-panel","mvc/tags","mvc/annotations","utils/localization"],function(f,b,h,d,a,c,e){var g=d.ReadOnlyHistoryPanel.extend({HDAViewClass:b.HDAEditView,initialize:function(i){i=i||{};this.selectedHdaIds=[];this.tagsEditor=null;this.annotationEditor=null;this.purgeAllowed=i.purgeAllowed||false;this.selecting=i.selecting||false;this.annotationEditorShown=i.annotationEditorShown||false;this.tagsEditorShown=i.tagsEditorShown||false;d.ReadOnlyHistoryPanel.prototype.initialize.call(this,i)},_setUpModelEventHandlers:function(){d.ReadOnlyHistoryPanel.prototype._setUpModelEventHandlers.call(this);this.model.on("change:nice_size",this.updateHistoryDiskSize,this);this.model.hdas.on("change:deleted",this._handleHdaDeletionChange,this);this.model.hdas.on("change:visible",this._handleHdaVisibleChange,this);this.model.hdas.on("change:purged",function(i){this.model.fetch()},this)},renderModel:function(){var i=$("<div/>");i.append(g.templates.historyPanel(this.model.toJSON()));this.$emptyMessage(i).text(this.emptyMsg);if(Galaxy&&Galaxy.currUser&&Galaxy.currUser.id&&Galaxy.currUser.id===this.model.get("user_id")){this._renderTags(i);this._renderAnnotation(i)}i.find(".history-secondary-actions").prepend(this._renderSelectButton());i.find(".history-dataset-actions").toggle(this.selecting);i.find(".history-secondary-actions").prepend(this._renderSearchButton());this._setUpBehaviours(i);this.renderHdas(i);return i},_renderTags:function(i){var j=this;this.tagsEditor=new a.TagsEditor({model:this.model,el:i.find(".history-controls .tags-display"),onshowFirstTime:function(){this.render()},onshow:function(){j.toggleHDATagEditors(true,j.fxSpeed)},onhide:function(){j.toggleHDATagEditors(false,j.fxSpeed)},$activator:faIconButton({title:e("Edit history tags"),classes:"history-tag-btn",faIcon:"fa-tags"}).appendTo(i.find(".history-secondary-actions"))})},_renderAnnotation:function(i){var j=this;this.annotationEditor=new c.AnnotationEditor({model:this.model,el:i.find(".history-controls .annotation-display"),onshowFirstTime:function(){this.render()},onshow:function(){j.toggleHDAAnnotationEditors(true,j.fxSpeed)},onhide:function(){j.toggleHDAAnnotationEditors(false,j.fxSpeed)},$activator:faIconButton({title:e("Edit history annotation"),classes:"history-annotate-btn",faIcon:"fa-comment"}).appendTo(i.find(".history-secondary-actions"))})},_renderSelectButton:function(i){return faIconButton({title:e("Operations on multiple datasets"),classes:"history-select-btn",faIcon:"fa-check-square-o"})},_setUpBehaviours:function(i){i=i||this.$el;d.ReadOnlyHistoryPanel.prototype._setUpBehaviours.call(this,i);if(!this.model){return}this._setUpDatasetActionsPopup(i);if((!Galaxy.currUser||Galaxy.currUser.isAnonymous())||(Galaxy.currUser.id!==this.model.get("user_id"))){return}var j=this;i.find(".history-name").attr("title",e("Click to rename history")).tooltip({placement:"bottom"}).make_text_editable({on_finish:function(k){var l=j.model.get("name");if(k&&k!==l){j.$el.find(".history-name").text(k);j.model.save({name:k}).fail(function(){j.$el.find(".history-name").text(j.model.previous("name"))})}else{j.$el.find(".history-name").text(l)}}})},_setUpDatasetActionsPopup:function(i){var j=this,k=[{html:e("Hide datasets"),func:function(){var l=f.HistoryDatasetAssociation.prototype.hide;j.getSelectedHdaCollection().ajaxQueue(l)}},{html:e("Unhide datasets"),func:function(){var l=f.HistoryDatasetAssociation.prototype.unhide;j.getSelectedHdaCollection().ajaxQueue(l)}},{html:e("Delete datasets"),func:function(){var l=f.HistoryDatasetAssociation.prototype["delete"];j.getSelectedHdaCollection().ajaxQueue(l)}},{html:e("Undelete datasets"),func:function(){var l=f.HistoryDatasetAssociation.prototype.undelete;j.getSelectedHdaCollection().ajaxQueue(l)}}];if(j.purgeAllowed){k.push({html:e("Permanently delete datasets"),func:function(){if(confirm(e("This will permanently remove the data in your datasets. Are you sure?"))){var l=f.HistoryDatasetAssociation.prototype.purge;j.getSelectedHdaCollection().ajaxQueue(l)}}})}k.push({html:e("Build Dataset List (Experimental)"),func:function(){j.getSelectedHdaCollection().promoteToHistoryDatasetCollection(j.model,"list")}});k.push({html:e("Build Dataset Pair (Experimental)"),func:function(){j.getSelectedHdaCollection().promoteToHistoryDatasetCollection(j.model,"paired")}});return new PopupMenu(i.find(".history-dataset-action-popup-btn"),k)},_handleHdaDeletionChange:function(i){if(i.get("deleted")&&!this.storage.get("show_deleted")){this.removeHdaView(this.hdaViews[i.id])}},_handleHdaVisibleChange:function(i){if(i.hidden()&&!this.storage.get("show_hidden")){this.removeHdaView(this.hdaViews[i.id])}},_createContentView:function(j){var i=j.get("id"),l=j.get("history_content_type"),k=null;if(l=="dataset"){k=new this.HDAViewClass({model:j,linkTarget:this.linkTarget,expanded:this.storage.get("expandedHdas")[i],selectable:this.selecting,purgeAllowed:this.purgeAllowed,hasUser:this.model.ownedByCurrUser(),logger:this.logger,tagsEditorShown:(this.tagsEditor&&!this.tagsEditor.hidden),annotationEditorShown:(this.annotationEditor&&!this.annotationEditor.hidden)})}else{if(l=="dataset_collection"){k=new h.DatasetCollectionEditView({model:j,linkTarget:this.linkTarget,expanded:this.storage.get("expandedHdas")[i],hasUser:this.model.ownedByCurrUser(),logger:this.logger})}}this._setUpHdaListeners(k);return k},_setUpHdaListeners:function(j){var i=this;d.ReadOnlyHistoryPanel.prototype._setUpHdaListeners.call(this,j);j.on("selected",function(k){var l=k.model.get("id");i.selectedHdaIds=_.union(i.selectedHdaIds,[l])});j.on("de-selected",function(k){var l=k.model.get("id");i.selectedHdaIds=_.without(i.selectedHdaIds,l)})},toggleHDATagEditors:function(i){var j=arguments;_.each(this.hdaViews,function(k){if(k.tagsEditor){k.tagsEditor.toggle.apply(k.tagsEditor,j)}})},toggleHDAAnnotationEditors:function(i){var j=arguments;_.each(this.hdaViews,function(k){if(k.annotationEditor){k.annotationEditor.toggle.apply(k.annotationEditor,j)}})},removeHdaView:function(j){if(!j){return}var i=this;j.$el.fadeOut(i.fxSpeed,function(){j.off();j.remove();delete i.hdaViews[j.model.id];if(_.isEmpty(i.hdaViews)){i.trigger("empty-history",i);i._renderEmptyMsg()}})},events:_.extend(_.clone(d.ReadOnlyHistoryPanel.prototype.events),{"click .history-select-btn":"toggleSelectors","click .history-select-all-datasets-btn":"selectAllDatasets","click .history-deselect-all-datasets-btn":"deselectAllDatasets"}),updateHistoryDiskSize:function(){this.$el.find(".history-size").text(this.model.get("nice_size"))},showSelectors:function(i){i=(i!==undefined)?(i):(this.fxSpeed);this.selecting=true;this.$(".history-dataset-actions").slideDown(i);_.each(this.hdaViews,function(j){j.showSelector()});this.selectedHdaIds=[]},hideSelectors:function(i){i=(i!==undefined)?(i):(this.fxSpeed);this.selecting=false;this.$(".history-dataset-actions").slideUp(i);_.each(this.hdaViews,function(j){j.hideSelector()});this.selectedHdaIds=[]},toggleSelectors:function(){if(!this.selecting){this.showSelectors()}else{this.hideSelectors()}},selectAllDatasets:function(i){_.each(this.hdaViews,function(j){j.select(i)})},deselectAllDatasets:function(i){_.each(this.hdaViews,function(j){j.deselect(i)})},getSelectedHdaViews:function(){return _.filter(this.hdaViews,function(i){return i.selected})},getSelectedHdaCollection:function(){return new f.HDACollection(_.map(this.getSelectedHdaViews(),function(i){return i.model}),{historyId:this.model.id})},toString:function(){return"HistoryPanel("+((this.model)?(this.model.get("name")):(""))+")"}});return{HistoryPanel:g}});
\ No newline at end of file
+define(["mvc/dataset/hda-model","mvc/dataset/hda-edit","mvc/collection/dataset-collection-edit","mvc/history/readonly-history-panel","mvc/tags","mvc/annotations","utils/localization"],function(f,b,h,d,a,c,e){var g=d.ReadOnlyHistoryPanel.extend({HDAViewClass:b.HDAEditView,initialize:function(i){i=i||{};this.selectedHdaIds=[];this.lastSelectedViewId=null;this.tagsEditor=null;this.annotationEditor=null;this.purgeAllowed=i.purgeAllowed||false;this.selecting=i.selecting||false;this.annotationEditorShown=i.annotationEditorShown||false;this.tagsEditorShown=i.tagsEditorShown||false;d.ReadOnlyHistoryPanel.prototype.initialize.call(this,i)},_setUpModelEventHandlers:function(){d.ReadOnlyHistoryPanel.prototype._setUpModelEventHandlers.call(this);this.model.on("change:nice_size",this.updateHistoryDiskSize,this);this.model.hdas.on("change:deleted",this._handleHdaDeletionChange,this);this.model.hdas.on("change:visible",this._handleHdaVisibleChange,this);this.model.hdas.on("change:purged",function(i){this.model.fetch()},this)},renderModel:function(){var i=$("<div/>");i.append(g.templates.historyPanel(this.model.toJSON()));this.$emptyMessage(i).text(this.emptyMsg);if(Galaxy&&Galaxy.currUser&&Galaxy.currUser.id&&Galaxy.currUser.id===this.model.get("user_id")){this._renderTags(i);this._renderAnnotation(i)}i.find(".history-secondary-actions").prepend(this._renderSelectButton());i.find(".history-dataset-actions").toggle(this.selecting);i.find(".history-secondary-actions").prepend(this._renderSearchButton());this._setUpBehaviours(i);this.renderHdas(i);return i},_renderTags:function(i){var j=this;this.tagsEditor=new a.TagsEditor({model:this.model,el:i.find(".history-controls .tags-display"),onshowFirstTime:function(){this.render()},onshow:function(){j.toggleHDATagEditors(true,j.fxSpeed)},onhide:function(){j.toggleHDATagEditors(false,j.fxSpeed)},$activator:faIconButton({title:e("Edit history tags"),classes:"history-tag-btn",faIcon:"fa-tags"}).appendTo(i.find(".history-secondary-actions"))})},_renderAnnotation:function(i){var j=this;this.annotationEditor=new c.AnnotationEditor({model:this.model,el:i.find(".history-controls .annotation-display"),onshowFirstTime:function(){this.render()},onshow:function(){j.toggleHDAAnnotationEditors(true,j.fxSpeed)},onhide:function(){j.toggleHDAAnnotationEditors(false,j.fxSpeed)},$activator:faIconButton({title:e("Edit history annotation"),classes:"history-annotate-btn",faIcon:"fa-comment"}).appendTo(i.find(".history-secondary-actions"))})},_renderSelectButton:function(i){return faIconButton({title:e("Operations on multiple datasets"),classes:"history-select-btn",faIcon:"fa-check-square-o"})},_setUpBehaviours:function(i){i=i||this.$el;d.ReadOnlyHistoryPanel.prototype._setUpBehaviours.call(this,i);if(!this.model){return}this._setUpDatasetActionsPopup(i);if((!Galaxy.currUser||Galaxy.currUser.isAnonymous())||(Galaxy.currUser.id!==this.model.get("user_id"))){return}var j=this;i.find(".history-name").attr("title",e("Click to rename history")).tooltip({placement:"bottom"}).make_text_editable({on_finish:function(k){var l=j.model.get("name");if(k&&k!==l){j.$el.find(".history-name").text(k);j.model.save({name:k}).fail(function(){j.$el.find(".history-name").text(j.model.previous("name"))})}else{j.$el.find(".history-name").text(l)}}})},_setUpDatasetActionsPopup:function(i){var j=this,k=[{html:e("Hide datasets"),func:function(){var l=f.HistoryDatasetAssociation.prototype.hide;j.getSelectedHdaCollection().ajaxQueue(l)}},{html:e("Unhide datasets"),func:function(){var l=f.HistoryDatasetAssociation.prototype.unhide;j.getSelectedHdaCollection().ajaxQueue(l)}},{html:e("Delete datasets"),func:function(){var l=f.HistoryDatasetAssociation.prototype["delete"];j.getSelectedHdaCollection().ajaxQueue(l)}},{html:e("Undelete datasets"),func:function(){var l=f.HistoryDatasetAssociation.prototype.undelete;j.getSelectedHdaCollection().ajaxQueue(l)}}];if(j.purgeAllowed){k.push({html:e("Permanently delete datasets"),func:function(){if(confirm(e("This will permanently remove the data in your datasets. Are you sure?"))){var l=f.HistoryDatasetAssociation.prototype.purge;j.getSelectedHdaCollection().ajaxQueue(l)}}})}k.push({html:e("Build Dataset List (Experimental)"),func:function(){j.getSelectedHdaCollection().promoteToHistoryDatasetCollection(j.model,"list")}});k.push({html:e("Build Dataset Pair (Experimental)"),func:function(){j.getSelectedHdaCollection().promoteToHistoryDatasetCollection(j.model,"paired")}});return new PopupMenu(i.find(".history-dataset-action-popup-btn"),k)},_handleHdaDeletionChange:function(i){if(i.get("deleted")&&!this.storage.get("show_deleted")){this.removeHdaView(this.hdaViews[i.id])}},_handleHdaVisibleChange:function(i){if(i.hidden()&&!this.storage.get("show_hidden")){this.removeHdaView(this.hdaViews[i.id])}},_createContentView:function(j){var i=j.get("id"),l=j.get("history_content_type"),k=null;if(l==="dataset"){k=new this.HDAViewClass({model:j,linkTarget:this.linkTarget,expanded:this.storage.get("expandedHdas")[i],selectable:this.selecting,purgeAllowed:this.purgeAllowed,hasUser:this.model.ownedByCurrUser(),logger:this.logger,tagsEditorShown:(this.tagsEditor&&!this.tagsEditor.hidden),annotationEditorShown:(this.annotationEditor&&!this.annotationEditor.hidden)})}else{if(l==="dataset_collection"){k=new h.DatasetCollectionEditView({model:j,linkTarget:this.linkTarget,expanded:this.storage.get("expandedHdas")[i],hasUser:this.model.ownedByCurrUser(),logger:this.logger})}}this._setUpHdaListeners(k);return k},_setUpHdaListeners:function(j){var i=this;d.ReadOnlyHistoryPanel.prototype._setUpHdaListeners.call(this,j);j.on("selected",function(m,l){if(!l){return}var k=[];if((l.shiftKey)&&(i.lastSelectedViewId&&_.has(i.hdaViews,i.lastSelectedViewId))){var o=i.hdaViews[i.lastSelectedViewId];k=i.selectDatasetRange(m,o).map(function(p){return p.model.id})}else{var n=m.model.get("id");i.lastSelectedViewId=n;k=[n]}i.selectedHdaIds=_.union(i.selectedHdaIds,k)});j.on("de-selected",function(l,k){var m=l.model.get("id");i.selectedHdaIds=_.without(i.selectedHdaIds,m)})},toggleHDATagEditors:function(i){var j=arguments;_.each(this.hdaViews,function(k){if(k.tagsEditor){k.tagsEditor.toggle.apply(k.tagsEditor,j)}})},toggleHDAAnnotationEditors:function(i){var j=arguments;_.each(this.hdaViews,function(k){if(k.annotationEditor){k.annotationEditor.toggle.apply(k.annotationEditor,j)}})},removeHdaView:function(j){if(!j){return}var i=this;j.$el.fadeOut(i.fxSpeed,function(){j.off();j.remove();delete i.hdaViews[j.model.id];if(_.isEmpty(i.hdaViews)){i.trigger("empty-history",i);i._renderEmptyMsg()}})},events:_.extend(_.clone(d.ReadOnlyHistoryPanel.prototype.events),{"click .history-select-btn":"toggleSelectors","click .history-select-all-datasets-btn":"selectAllDatasets","click .history-deselect-all-datasets-btn":"deselectAllDatasets"}),updateHistoryDiskSize:function(){this.$el.find(".history-size").text(this.model.get("nice_size"))},showSelectors:function(i){i=(i!==undefined)?(i):(this.fxSpeed);this.selecting=true;this.$(".history-dataset-actions").slideDown(i);_.each(this.hdaViews,function(j){j.showSelector()});this.selectedHdaIds=[];this.lastSelectedViewId=null},hideSelectors:function(i){i=(i!==undefined)?(i):(this.fxSpeed);this.selecting=false;this.$(".history-dataset-actions").slideUp(i);_.each(this.hdaViews,function(j){j.hideSelector()});this.selectedHdaIds=[];this.lastSelectedViewId=null},toggleSelectors:function(){if(!this.selecting){this.showSelectors()}else{this.hideSelectors()}},selectAllDatasets:function(i){_.each(this.hdaViews,function(j){j.select(i)})},deselectAllDatasets:function(i){this.lastSelectedViewId=null;_.each(this.hdaViews,function(j){j.deselect(i)})},selectDatasetRange:function(k,j){var i=this.hdaViewRange(k,j);_.each(i,function(l){l.select()});return i},getSelectedHdaViews:function(){return _.filter(this.hdaViews,function(i){return i.selected})},getSelectedHdaCollection:function(){return new f.HDACollection(_.map(this.getSelectedHdaViews(),function(i){return i.model}),{historyId:this.model.id})},toString:function(){return"HistoryPanel("+((this.model)?(this.model.get("name")):(""))+")"}});return{HistoryPanel:g}});
\ No newline at end of file
diff -r 46a487e7d5476429cb71885adcbcfb9746ce725a -r 1d1d881508b121df607d9096386effdbe072427e static/scripts/packed/mvc/history/readonly-history-panel.js
--- a/static/scripts/packed/mvc/history/readonly-history-panel.js
+++ b/static/scripts/packed/mvc/history/readonly-history-panel.js
@@ -1,1 +1,1 @@
-define(["mvc/history/history-model","mvc/collection/dataset-collection-base","mvc/dataset/hda-base","mvc/user/user-model","mvc/base-mvc","utils/localization"],function(g,k,b,a,f,d){var i=f.SessionStorageModel.extend({defaults:{expandedHdas:{},show_deleted:false,show_hidden:false},addExpandedHda:function(n){var m="expandedHdas";this.save(m,_.extend(this.get(m),_.object([n],[true])))},removeExpandedHda:function(n){var m="expandedHdas";this.save(m,_.omit(this.get(m),n))},toString:function(){return"HistoryPrefs("+this.id+")"}});i.storageKeyPrefix="history:";i.historyStorageKey=function e(m){if(!m){throw new Error("HistoryPrefs.historyStorageKey needs valid id: "+m)}return(i.storageKeyPrefix+m)};i.get=function c(m){return new i({id:i.historyStorageKey(m)})};i.clearAll=function h(n){for(var m in sessionStorage){if(m.indexOf(i.storageKeyPrefix)===0){sessionStorage.removeItem(m)}}};var j=Backbone.View.extend(f.LoggableMixin).extend({HDAViewClass:b.HDABaseView,tagName:"div",className:"history-panel",fxSpeed:"fast",emptyMsg:d("This history is empty"),noneFoundMsg:d("No matching datasets found"),initialize:function(m){m=m||{};if(m.logger){this.logger=m.logger}this.log(this+".initialize:",m);this.linkTarget=m.linkTarget||"_blank";this.fxSpeed=_.has(m,"fxSpeed")?(m.fxSpeed):(this.fxSpeed);this.filters=[];this.searchFor="";this.findContainerFn=m.findContainerFn;this.hdaViews={};this.indicator=new LoadingIndicator(this.$el);this._setUpListeners();var n=_.pick(m,"initiallyExpanded","show_deleted","show_hidden");this.setModel(this.model,n,false);if(m.onready){m.onready.call(this)}},_setUpListeners:function(){this.on("error",function(n,q,m,p,o){this.errorHandler(n,q,m,p,o)});this.on("loading-history",function(){this._showLoadingIndicator("loading history...",40)});this.on("loading-done",function(){this._hideLoadingIndicator(40);if(_.isEmpty(this.hdaViews)){this.trigger("empty-history",this)}});this.once("rendered",function(){this.trigger("rendered:initial",this);return false});if(this.logger){this.on("all",function(m){this.log(this+"",arguments)},this)}return this},errorHandler:function(o,r,n,q,p){console.error(o,r,n,q,p);if(r&&r.status===0&&r.readyState===0){}else{if(r&&r.status===502){}else{var m=this._parseErrorMessage(o,r,n,q,p);if(!this.$messages().is(":visible")){this.once("rendered",function(){this.displayMessage("error",m.message,m.details)})}else{this.displayMessage("error",m.message,m.details)}}}},_parseErrorMessage:function(p,t,o,s,r){var n=Galaxy.currUser,m={message:this._bePolite(s),details:{user:(n instanceof a.User)?(n.toJSON()):(n+""),source:(p instanceof Backbone.Model)?(p.toJSON()):(p+""),xhr:t,options:(t)?(_.omit(o,"xhr")):(o)}};_.extend(m.details,r||{});if(t&&_.isFunction(t.getAllResponseHeaders)){var q=t.getAllResponseHeaders();q=_.compact(q.split("\n"));q=_.map(q,function(u){return u.split(": ")});m.details.xhr.responseHeaders=_.object(q)}return m},_bePolite:function(m){m=m||d("An error occurred while getting updates from the server");return m+". "+d("Please contact a Galaxy administrator if the problem persists")+"."},loadHistoryWithHDADetails:function(o,n,m,q){var p=function(r){return _.keys(i.get(r.id).get("expandedHdas"))};return this.loadHistory(o,n,m,q,p)},loadHistory:function(p,o,n,s,q){var m=this;o=o||{};m.trigger("loading-history",m);var r=g.History.getHistoryData(p,{historyFn:n,hdaFn:s,hdaDetailIds:o.initiallyExpanded||q});return m._loadHistoryFromXHR(r,o).fail(function(v,t,u){m.trigger("error",m,v,o,d("An error was encountered while "+t),{historyId:p,history:u||{}})}).always(function(){m.trigger("loading-done",m)})},_loadHistoryFromXHR:function(o,n){var m=this;o.then(function(p,q){m.JSONToModel(p,q,n)});o.fail(function(q,p){m.render()});return o},JSONToModel:function(p,m,n){this.log("JSONToModel:",p,m,n);n=n||{};var o=new g.History(p,m,n);this.setModel(o);return this},setModel:function(n,m,o){m=m||{};o=(o!==undefined)?(o):(true);this.log("setModel:",n,m,o);this.freeModel();this.selectedHdaIds=[];if(n){this.model=n;if(this.logger){this.model.logger=this.logger}this._setUpWebStorage(m.initiallyExpanded,m.show_deleted,m.show_hidden);this._setUpModelEventHandlers();this.trigger("new-model",this)}if(o){this.render()}return this},freeModel:function(){if(this.model){this.model.clearUpdateTimeout();this.stopListening(this.model);this.stopListening(this.model.hdas)}this.freeHdaViews();return this},freeHdaViews:function(){this.hdaViews={};return this},_setUpWebStorage:function(n,m,o){this.storage=new i({id:i.historyStorageKey(this.model.get("id"))});if(_.isObject(n)){this.storage.set("exandedHdas",n)}if(_.isBoolean(m)){this.storage.set("show_deleted",m)}if(_.isBoolean(o)){this.storage.set("show_hidden",o)}this.trigger("new-storage",this.storage,this);this.log(this+" (init'd) storage:",this.storage.get());return this},_setUpModelEventHandlers:function(){this.model.hdas.on("add",this.addContentView,this);this.model.on("error error:hdas",function(n,p,m,o){this.errorHandler(n,p,m,o)},this);return this},render:function(o,p){this.log("render:",o,p);o=(o===undefined)?(this.fxSpeed):(o);var m=this,n;if(this.model){n=this.renderModel()}else{n=this.renderWithoutModel()}$(m).queue("fx",[function(q){if(o&&m.$el.is(":visible")){m.$el.fadeOut(o,q)}else{q()}},function(q){m.$el.empty();if(n){m.$el.append(n.children())}q()},function(q){if(o&&!m.$el.is(":visible")){m.$el.fadeIn(o,q)}else{q()}},function(q){if(p){p.call(this)}m.trigger("rendered",this);q()}]);return this},renderWithoutModel:function(){var m=$("<div/>"),n=$("<div/>").addClass("message-container").css({margin:"4px"});return m.append(n)},renderModel:function(){var m=$("<div/>");m.append(j.templates.historyPanel(this.model.toJSON()));this.$emptyMessage(m).text(this.emptyMsg);m.find(".history-secondary-actions").prepend(this._renderSearchButton());this._setUpBehaviours(m);this.renderHdas(m);return m},_renderEmptyMsg:function(o){var n=this,m=n.$emptyMessage(o);if(!_.isEmpty(n.hdaViews)){m.hide()}else{if(n.searchFor){m.text(n.noneFoundMsg).show()}else{m.text(n.emptyMsg).show()}}return this},_renderSearchButton:function(m){return faIconButton({title:d("Search datasets"),classes:"history-search-btn",faIcon:"fa-search"})},_setUpBehaviours:function(m){m=m||this.$el;m.find("[title]").tooltip({placement:"bottom"});this._setUpSearchInput(m.find(".history-search-controls .history-search-input"));return this},$container:function(){return(this.findContainerFn)?(this.findContainerFn.call(this)):(this.$el.parent())},$datasetsList:function(m){return(m||this.$el).find(".datasets-list")},$messages:function(m){return(m||this.$el).find(".message-container")},$emptyMessage:function(m){return(m||this.$el).find(".empty-history-message")},renderHdas:function(n){n=n||this.$el;var m=this,p={},o=this.model.hdas.getVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"),this.filters);this.$datasetsList(n).empty();if(o.length){o.each(function(r){var q=r.get("id"),s=m._createContentView(r);p[q]=s;if(_.contains(m.selectedHdaIds,q)){s.selected=true}m.attachContentView(s.render(),n)})}this.hdaViews=p;this._renderEmptyMsg(n);return this.hdaViews},_createContentView:function(n){var m=n.get("id"),p=n.get("history_content_type"),o=null;if(p=="dataset"){o=new this.HDAViewClass({model:n,linkTarget:this.linkTarget,expanded:this.storage.get("expandedHdas")[m],hasUser:this.model.ownedByCurrUser(),logger:this.logger})}else{o=new k.DatasetCollectionBaseView({model:n,linkTarget:this.linkTarget,expanded:this.storage.get("expandedHdas")[m],hasUser:this.model.ownedByCurrUser(),logger:this.logger})}this._setUpHdaListeners(o);return o},_setUpHdaListeners:function(n){var m=this;n.on("error",function(p,r,o,q){m.errorHandler(p,r,o,q)});n.on("body-expanded",function(o){m.storage.addExpandedHda(o)});n.on("body-collapsed",function(o){m.storage.removeExpandedHda(o)});return this},attachContentView:function(o,n){n=n||this.$el;var m=this.$datasetsList(n);m.prepend(o.$el);return this},addContentView:function(p){this.log("add."+this,p);var n=this;if(!p.isVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"))){return n}$({}).queue([function o(r){var q=n.$emptyMessage();if(q.is(":visible")){q.fadeOut(n.fxSpeed,r)}else{r()}},function m(q){var r=n._createContentView(p);n.hdaViews[p.id]=r;r.render().$el.hide();n.scrollToTop();n.attachContentView(r);r.$el.slideDown(n.fxSpeed)}]);return n},refreshContents:function(n,m){if(this.model){return this.model.refresh(n,m)}return $.when()},events:{"click .message-container":"clearMessages","click .history-search-btn":"toggleSearchControls"},collapseAllHdaBodies:function(){_.each(this.hdaViews,function(m){m.toggleBodyVisibility(null,false)});this.storage.set("expandedHdas",{});return this},toggleShowDeleted:function(m){m=(m!==undefined)?(m):(!this.storage.get("show_deleted"));this.storage.set("show_deleted",m);this.renderHdas();return this.storage.get("show_deleted")},toggleShowHidden:function(m){m=(m!==undefined)?(m):(!this.storage.get("show_hidden"));this.storage.set("show_hidden",m);this.renderHdas();return this.storage.get("show_hidden")},_setUpSearchInput:function(n){var o=this,p=".history-search-input";function m(q){if(o.model.hdas.haveDetails()){o.searchHdas(q);return}o.$el.find(p).searchInput("toggle-loading");o.model.hdas.fetchAllDetails({silent:true}).always(function(){o.$el.find(p).searchInput("toggle-loading")}).done(function(){o.searchHdas(q)})}n.searchInput({initialVal:o.searchFor,name:"history-search",placeholder:"search datasets",classes:"history-search",onfirstsearch:m,onsearch:_.bind(this.searchHdas,this),onclear:_.bind(this.clearHdaSearch,this)});return n},toggleSearchControls:function(o,m){var n=this.$el.find(".history-search-controls"),p=(jQuery.type(o)==="number")?(o):(this.fxSpeed);m=(m!==undefined)?(m):(!n.is(":visible"));if(m){n.slideDown(p,function(){$(this).find("input").focus()})}else{n.slideUp(p)}return m},searchHdas:function(m){var n=this;this.searchFor=m;this.filters=[function(o){return o.matchesAll(n.searchFor)}];this.trigger("search:searching",m,this);this.renderHdas();return this},clearHdaSearch:function(m){this.searchFor="";this.filters=[];this.trigger("search:clear",this);this.renderHdas();return this},_showLoadingIndicator:function(n,m,o){m=(m!==undefined)?(m):(this.fxSpeed);if(!this.indicator){this.indicator=new LoadingIndicator(this.$el,this.$el.parent())}if(!this.$el.is(":visible")){this.indicator.show(0,o)}else{this.$el.fadeOut(m);this.indicator.show(n,m,o)}},_hideLoadingIndicator:function(m,n){m=(m!==undefined)?(m):(this.fxSpeed);if(this.indicator){this.indicator.hide(m,n)}},displayMessage:function(r,s,q){var o=this;this.scrollToTop();var p=this.$messages(),m=$("<div/>").addClass(r+"message").html(s);if(!_.isEmpty(q)){var n=$('<a href="javascript:void(0)">Details</a>').click(function(){Galaxy.modal.show(o._messageToModalOptions(r,s,q));return false});m.append(" ",n)}return p.html(m)},_messageToModalOptions:function(q,s,p){var m=this,r=$("<div/>"),o={title:"Details"};function n(t){t=_.omit(t,_.functions(t));return["<table>",_.map(t,function(v,u){v=(_.isObject(v))?(n(v)):(v);return'<tr><td style="vertical-align: top; color: grey">'+u+'</td><td style="padding-left: 8px">'+v+"</td></tr>"}).join(""),"</table>"].join("")}if(_.isObject(p)){o.body=r.append(n(p))}else{o.body=r.html(p)}o.buttons={Ok:function(){Galaxy.modal.hide();m.clearMessages()}};return o},clearMessages:function(){this.$messages().empty();return this},scrollPosition:function(){return this.$container().scrollTop()},scrollTo:function(m){this.$container().scrollTop(m);return this},scrollToTop:function(){this.$container().scrollTop(0);return this},scrollToId:function(n){if((!n)||(!this.hdaViews[n])){return this}var m=this.hdaViews[n];this.scrollTo(m.el.offsetTop);return this},scrollToHid:function(m){var n=this.model.hdas.getByHid(m);if(!n){return this}return this.scrollToId(n.id)},toString:function(){return"ReadOnlyHistoryPanel("+((this.model)?(this.model.get("name")):(""))+")"}});var l=['<div class="history-controls">','<div class="history-search-controls">','<div class="history-search-input"></div>',"</div>",'<div class="history-title">',"<% if( history.name ){ %>",'<div class="history-name"><%= history.name %></div>',"<% } %>","</div>",'<div class="history-subtitle clear">',"<% if( history.nice_size ){ %>",'<div class="history-size"><%= history.nice_size %></div>',"<% } %>",'<div class="history-secondary-actions"></div>',"</div>","<% if( history.deleted ){ %>",'<div class="warningmessagesmall"><strong>',d("You are currently viewing a deleted history!"),"</strong></div>","<% } %>",'<div class="message-container">',"<% if( history.message ){ %>",'<div class="<%= history.status %>message"><%= history.message %></div>',"<% } %>","</div>",'<div class="quota-message errormessage">',d("You are over your disk quota"),". ",d("Tool execution is on hold until your disk usage drops below your allocated quota"),".","</div>",'<div class="tags-display"></div>','<div class="annotation-display"></div>','<div class="history-dataset-actions">','<div class="btn-group">','<button class="history-select-all-datasets-btn btn btn-default"','data-mode="select">',d("All"),"</button>",'<button class="history-deselect-all-datasets-btn btn btn-default"','data-mode="select">',d("None"),"</button>","</div>",'<button class="history-dataset-action-popup-btn btn btn-default">',d("For all selected"),"...</button>","</div>","</div>",'<div class="datasets-list"></div>','<div class="empty-history-message infomessagesmall">',d("This history is empty"),"</div>"].join("");j.templates={historyPanel:function(m){return _.template(l,m,{variable:"history"})}};return{ReadOnlyHistoryPanel:j}});
\ No newline at end of file
+define(["mvc/history/history-model","mvc/collection/dataset-collection-base","mvc/dataset/hda-base","mvc/user/user-model","mvc/base-mvc","utils/localization"],function(g,k,b,a,f,d){var i=f.SessionStorageModel.extend({defaults:{expandedHdas:{},show_deleted:false,show_hidden:false},addExpandedHda:function(n){var m="expandedHdas";this.save(m,_.extend(this.get(m),_.object([n],[true])))},removeExpandedHda:function(n){var m="expandedHdas";this.save(m,_.omit(this.get(m),n))},toString:function(){return"HistoryPrefs("+this.id+")"}});i.storageKeyPrefix="history:";i.historyStorageKey=function e(m){if(!m){throw new Error("HistoryPrefs.historyStorageKey needs valid id: "+m)}return(i.storageKeyPrefix+m)};i.get=function c(m){return new i({id:i.historyStorageKey(m)})};i.clearAll=function h(n){for(var m in sessionStorage){if(m.indexOf(i.storageKeyPrefix)===0){sessionStorage.removeItem(m)}}};var j=Backbone.View.extend(f.LoggableMixin).extend({HDAViewClass:b.HDABaseView,tagName:"div",className:"history-panel",fxSpeed:"fast",emptyMsg:d("This history is empty"),noneFoundMsg:d("No matching datasets found"),initialize:function(m){m=m||{};if(m.logger){this.logger=m.logger}this.log(this+".initialize:",m);this.linkTarget=m.linkTarget||"_blank";this.fxSpeed=_.has(m,"fxSpeed")?(m.fxSpeed):(this.fxSpeed);this.filters=[];this.searchFor="";this.findContainerFn=m.findContainerFn;this.hdaViews={};this.indicator=new LoadingIndicator(this.$el);this._setUpListeners();var n=_.pick(m,"initiallyExpanded","show_deleted","show_hidden");this.setModel(this.model,n,false);if(m.onready){m.onready.call(this)}},_setUpListeners:function(){this.on("error",function(n,q,m,p,o){this.errorHandler(n,q,m,p,o)});this.on("loading-history",function(){this._showLoadingIndicator("loading history...",40)});this.on("loading-done",function(){this._hideLoadingIndicator(40);if(_.isEmpty(this.hdaViews)){this.trigger("empty-history",this)}});this.once("rendered",function(){this.trigger("rendered:initial",this);return false});if(this.logger){this.on("all",function(m){this.log(this+"",arguments)},this)}return this},errorHandler:function(o,r,n,q,p){console.error(o,r,n,q,p);if(r&&r.status===0&&r.readyState===0){}else{if(r&&r.status===502){}else{var m=this._parseErrorMessage(o,r,n,q,p);if(!this.$messages().is(":visible")){this.once("rendered",function(){this.displayMessage("error",m.message,m.details)})}else{this.displayMessage("error",m.message,m.details)}}}},_parseErrorMessage:function(p,t,o,s,r){var n=Galaxy.currUser,m={message:this._bePolite(s),details:{user:(n instanceof a.User)?(n.toJSON()):(n+""),source:(p instanceof Backbone.Model)?(p.toJSON()):(p+""),xhr:t,options:(t)?(_.omit(o,"xhr")):(o)}};_.extend(m.details,r||{});if(t&&_.isFunction(t.getAllResponseHeaders)){var q=t.getAllResponseHeaders();q=_.compact(q.split("\n"));q=_.map(q,function(u){return u.split(": ")});m.details.xhr.responseHeaders=_.object(q)}return m},_bePolite:function(m){m=m||d("An error occurred while getting updates from the server");return m+". "+d("Please contact a Galaxy administrator if the problem persists")+"."},loadHistoryWithHDADetails:function(o,n,m,q){var p=function(r){return _.keys(i.get(r.id).get("expandedHdas"))};return this.loadHistory(o,n,m,q,p)},loadHistory:function(p,o,n,s,q){var m=this;o=o||{};m.trigger("loading-history",m);var r=g.History.getHistoryData(p,{historyFn:n,hdaFn:s,hdaDetailIds:o.initiallyExpanded||q});return m._loadHistoryFromXHR(r,o).fail(function(v,t,u){m.trigger("error",m,v,o,d("An error was encountered while "+t),{historyId:p,history:u||{}})}).always(function(){m.trigger("loading-done",m)})},_loadHistoryFromXHR:function(o,n){var m=this;o.then(function(p,q){m.JSONToModel(p,q,n)});o.fail(function(q,p){m.render()});return o},JSONToModel:function(p,m,n){this.log("JSONToModel:",p,m,n);n=n||{};var o=new g.History(p,m,n);this.setModel(o);return this},setModel:function(n,m,o){m=m||{};o=(o!==undefined)?(o):(true);this.log("setModel:",n,m,o);this.freeModel();this.selectedHdaIds=[];if(n){this.model=n;if(this.logger){this.model.logger=this.logger}this._setUpWebStorage(m.initiallyExpanded,m.show_deleted,m.show_hidden);this._setUpModelEventHandlers();this.trigger("new-model",this)}if(o){this.render()}return this},freeModel:function(){if(this.model){this.model.clearUpdateTimeout();this.stopListening(this.model);this.stopListening(this.model.hdas)}this.freeHdaViews();return this},freeHdaViews:function(){this.hdaViews={};return this},_setUpWebStorage:function(n,m,o){this.storage=new i({id:i.historyStorageKey(this.model.get("id"))});if(_.isObject(n)){this.storage.set("exandedHdas",n)}if(_.isBoolean(m)){this.storage.set("show_deleted",m)}if(_.isBoolean(o)){this.storage.set("show_hidden",o)}this.trigger("new-storage",this.storage,this);this.log(this+" (init'd) storage:",this.storage.get());return this},_setUpModelEventHandlers:function(){this.model.hdas.on("add",this.addContentView,this);this.model.on("error error:hdas",function(n,p,m,o){this.errorHandler(n,p,m,o)},this);return this},render:function(o,p){this.log("render:",o,p);o=(o===undefined)?(this.fxSpeed):(o);var m=this,n;if(this.model){n=this.renderModel()}else{n=this.renderWithoutModel()}$(m).queue("fx",[function(q){if(o&&m.$el.is(":visible")){m.$el.fadeOut(o,q)}else{q()}},function(q){m.$el.empty();if(n){m.$el.append(n.children())}q()},function(q){if(o&&!m.$el.is(":visible")){m.$el.fadeIn(o,q)}else{q()}},function(q){if(p){p.call(this)}m.trigger("rendered",this);q()}]);return this},renderWithoutModel:function(){var m=$("<div/>"),n=$("<div/>").addClass("message-container").css({margin:"4px"});return m.append(n)},renderModel:function(){var m=$("<div/>");m.append(j.templates.historyPanel(this.model.toJSON()));this.$emptyMessage(m).text(this.emptyMsg);m.find(".history-secondary-actions").prepend(this._renderSearchButton());this._setUpBehaviours(m);this.renderHdas(m);return m},_renderEmptyMsg:function(o){var n=this,m=n.$emptyMessage(o);if(!_.isEmpty(n.hdaViews)){m.hide()}else{if(n.searchFor){m.text(n.noneFoundMsg).show()}else{m.text(n.emptyMsg).show()}}return this},_renderSearchButton:function(m){return faIconButton({title:d("Search datasets"),classes:"history-search-btn",faIcon:"fa-search"})},_setUpBehaviours:function(m){m=m||this.$el;m.find("[title]").tooltip({placement:"bottom"});this._setUpSearchInput(m.find(".history-search-controls .history-search-input"));return this},$container:function(){return(this.findContainerFn)?(this.findContainerFn.call(this)):(this.$el.parent())},$datasetsList:function(m){return(m||this.$el).find(".datasets-list")},$messages:function(m){return(m||this.$el).find(".message-container")},$emptyMessage:function(m){return(m||this.$el).find(".empty-history-message")},renderHdas:function(n){n=n||this.$el;var m=this,p={},o=this.model.hdas.getVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"),this.filters);this.$datasetsList(n).empty();if(o.length){o.each(function(r){var q=r.get("id"),s=m._createContentView(r);p[q]=s;if(_.contains(m.selectedHdaIds,q)){s.selected=true}m.attachContentView(s.render(),n)})}this.hdaViews=p;this._renderEmptyMsg(n);return this.hdaViews},_createContentView:function(n){var m=n.get("id"),p=n.get("history_content_type"),o=null;if(p==="dataset"){o=new this.HDAViewClass({model:n,linkTarget:this.linkTarget,expanded:this.storage.get("expandedHdas")[m],hasUser:this.model.ownedByCurrUser(),logger:this.logger})}else{o=new k.DatasetCollectionBaseView({model:n,linkTarget:this.linkTarget,expanded:this.storage.get("expandedHdas")[m],hasUser:this.model.ownedByCurrUser(),logger:this.logger})}this._setUpHdaListeners(o);return o},_setUpHdaListeners:function(n){var m=this;n.on("error",function(p,r,o,q){m.errorHandler(p,r,o,q)});n.on("body-expanded",function(o){m.storage.addExpandedHda(o)});n.on("body-collapsed",function(o){m.storage.removeExpandedHda(o)});return this},attachContentView:function(o,n){n=n||this.$el;var m=this.$datasetsList(n);m.prepend(o.$el);return this},addContentView:function(p){this.log("add."+this,p);var n=this;if(!p.isVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"))){return n}$({}).queue([function o(r){var q=n.$emptyMessage();if(q.is(":visible")){q.fadeOut(n.fxSpeed,r)}else{r()}},function m(q){var r=n._createContentView(p);n.hdaViews[p.id]=r;r.render().$el.hide();n.scrollToTop();n.attachContentView(r);r.$el.slideDown(n.fxSpeed)}]);return n},refreshContents:function(n,m){if(this.model){return this.model.refresh(n,m)}return $.when()},hdaViewRange:function(p,o){if(p===o){return[p]}var m=this,n=false,q=[];this.model.hdas.getVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"),this.filters).each(function(r){if(n){q.push(m.hdaViews[r.id]);if(r===p.model||r===o.model){n=false}}else{if(r===p.model||r===o.model){n=true;q.push(m.hdaViews[r.id])}}});return q},events:{"click .message-container":"clearMessages","click .history-search-btn":"toggleSearchControls"},collapseAllHdaBodies:function(){_.each(this.hdaViews,function(m){m.toggleBodyVisibility(null,false)});this.storage.set("expandedHdas",{});return this},toggleShowDeleted:function(m){m=(m!==undefined)?(m):(!this.storage.get("show_deleted"));this.storage.set("show_deleted",m);this.renderHdas();return this.storage.get("show_deleted")},toggleShowHidden:function(m){m=(m!==undefined)?(m):(!this.storage.get("show_hidden"));this.storage.set("show_hidden",m);this.renderHdas();return this.storage.get("show_hidden")},_setUpSearchInput:function(n){var o=this,p=".history-search-input";function m(q){if(o.model.hdas.haveDetails()){o.searchHdas(q);return}o.$el.find(p).searchInput("toggle-loading");o.model.hdas.fetchAllDetails({silent:true}).always(function(){o.$el.find(p).searchInput("toggle-loading")}).done(function(){o.searchHdas(q)})}n.searchInput({initialVal:o.searchFor,name:"history-search",placeholder:"search datasets",classes:"history-search",onfirstsearch:m,onsearch:_.bind(this.searchHdas,this),onclear:_.bind(this.clearHdaSearch,this)});return n},toggleSearchControls:function(o,m){var n=this.$el.find(".history-search-controls"),p=(jQuery.type(o)==="number")?(o):(this.fxSpeed);m=(m!==undefined)?(m):(!n.is(":visible"));if(m){n.slideDown(p,function(){$(this).find("input").focus()})}else{n.slideUp(p)}return m},searchHdas:function(m){var n=this;this.searchFor=m;this.filters=[function(o){return o.matchesAll(n.searchFor)}];this.trigger("search:searching",m,this);this.renderHdas();return this},clearHdaSearch:function(m){this.searchFor="";this.filters=[];this.trigger("search:clear",this);this.renderHdas();return this},_showLoadingIndicator:function(n,m,o){m=(m!==undefined)?(m):(this.fxSpeed);if(!this.indicator){this.indicator=new LoadingIndicator(this.$el,this.$el.parent())}if(!this.$el.is(":visible")){this.indicator.show(0,o)}else{this.$el.fadeOut(m);this.indicator.show(n,m,o)}},_hideLoadingIndicator:function(m,n){m=(m!==undefined)?(m):(this.fxSpeed);if(this.indicator){this.indicator.hide(m,n)}},displayMessage:function(r,s,q){var o=this;this.scrollToTop();var p=this.$messages(),m=$("<div/>").addClass(r+"message").html(s);if(!_.isEmpty(q)){var n=$('<a href="javascript:void(0)">Details</a>').click(function(){Galaxy.modal.show(o._messageToModalOptions(r,s,q));return false});m.append(" ",n)}return p.html(m)},_messageToModalOptions:function(q,s,p){var m=this,r=$("<div/>"),o={title:"Details"};function n(t){t=_.omit(t,_.functions(t));return["<table>",_.map(t,function(v,u){v=(_.isObject(v))?(n(v)):(v);return'<tr><td style="vertical-align: top; color: grey">'+u+'</td><td style="padding-left: 8px">'+v+"</td></tr>"}).join(""),"</table>"].join("")}if(_.isObject(p)){o.body=r.append(n(p))}else{o.body=r.html(p)}o.buttons={Ok:function(){Galaxy.modal.hide();m.clearMessages()}};return o},clearMessages:function(){this.$messages().empty();return this},scrollPosition:function(){return this.$container().scrollTop()},scrollTo:function(m){this.$container().scrollTop(m);return this},scrollToTop:function(){this.$container().scrollTop(0);return this},scrollToId:function(n){if((!n)||(!this.hdaViews[n])){return this}var m=this.hdaViews[n];this.scrollTo(m.el.offsetTop);return this},scrollToHid:function(m){var n=this.model.hdas.getByHid(m);if(!n){return this}return this.scrollToId(n.id)},toString:function(){return"ReadOnlyHistoryPanel("+((this.model)?(this.model.get("name")):(""))+")"}});var l=['<div class="history-controls">','<div class="history-search-controls">','<div class="history-search-input"></div>',"</div>",'<div class="history-title">',"<% if( history.name ){ %>",'<div class="history-name"><%= history.name %></div>',"<% } %>","</div>",'<div class="history-subtitle clear">',"<% if( history.nice_size ){ %>",'<div class="history-size"><%= history.nice_size %></div>',"<% } %>",'<div class="history-secondary-actions"></div>',"</div>","<% if( history.deleted ){ %>",'<div class="warningmessagesmall"><strong>',d("You are currently viewing a deleted history!"),"</strong></div>","<% } %>",'<div class="message-container">',"<% if( history.message ){ %>",'<div class="<%= history.status %>message"><%= history.message %></div>',"<% } %>","</div>",'<div class="quota-message errormessage">',d("You are over your disk quota"),". ",d("Tool execution is on hold until your disk usage drops below your allocated quota"),".","</div>",'<div class="tags-display"></div>','<div class="annotation-display"></div>','<div class="history-dataset-actions">','<div class="btn-group">','<button class="history-select-all-datasets-btn btn btn-default"','data-mode="select">',d("All"),"</button>",'<button class="history-deselect-all-datasets-btn btn btn-default"','data-mode="select">',d("None"),"</button>","</div>",'<button class="history-dataset-action-popup-btn btn btn-default">',d("For all selected"),"...</button>","</div>","</div>",'<div class="datasets-list"></div>','<div class="empty-history-message infomessagesmall">',d("This history is empty"),"</div>"].join("");j.templates={historyPanel:function(m){return _.template(l,m,{variable:"history"})}};return{ReadOnlyHistoryPanel:j}});
\ No newline at end of file
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/9937a1344fe7/
Changeset: 9937a1344fe7
User: natefoo
Date: 2014-06-03 00:22:33
Summary: Rename the ambiguous concurrent_jobs limit to destination_user_concurrent jobs
and add a destination_total_concurrent_jobs limit that prevents Galaxy from
queueing *any* jobs at a destination or tagged group of destinations once the
limit is reached.
Affected #: 2 files
diff -r e79b7ea727c90c2c7ccebdafcd19a5a6d880c51c -r 9937a1344fe789be6111d1af4b746b203a0dd785 lib/galaxy/jobs/__init__.py
--- a/lib/galaxy/jobs/__init__.py
+++ b/lib/galaxy/jobs/__init__.py
@@ -211,16 +211,21 @@
walltime=None,
walltime_delta=None,
output_size=None,
- concurrent_jobs={})
+ destination_user_concurrent_jobs={},
+ destination_total_concurrent_jobs={})
# Parse job limits
limits = root.find('limits')
if limits is not None:
for limit in self.__findall_with_required(limits, 'limit', ('type',)):
type = limit.get('type')
- if type == 'concurrent_jobs':
+ # concurrent_jobs renamed to destination_user_concurrent_jobs in job_conf.xml
+ if type in ( 'destination_user_concurrent_jobs', 'concurrent_jobs', 'destination_total_concurrent_jobs' ):
id = limit.get('tag', None) or limit.get('id')
- self.limits.concurrent_jobs[id] = int(limit.text)
+ if type == 'destination_total_concurrent_jobs':
+ self.limits.destination_total_concurrent_jobs[id] = int(limit.text)
+ else:
+ self.limits.destination_user_concurrent_jobs[id] = int(limit.text)
elif limit.text:
self.limits.__dict__[type] = types.get(type, str)(limit.text)
@@ -287,7 +292,8 @@
walltime=self.app.config.job_walltime,
walltime_delta=self.app.config.job_walltime_delta,
output_size=self.app.config.output_size_limit,
- concurrent_jobs={})
+ destination_user_concurrent_jobs={},
+ destination_total_concurrent_jobs={})
log.debug('Done loading job configuration')
diff -r e79b7ea727c90c2c7ccebdafcd19a5a6d880c51c -r 9937a1344fe789be6111d1af4b746b203a0dd785 lib/galaxy/jobs/handler.py
--- a/lib/galaxy/jobs/handler.py
+++ b/lib/galaxy/jobs/handler.py
@@ -57,7 +57,7 @@
self.track_jobs_in_database = self.app.config.track_jobs_in_database
# Initialize structures for handling job limits
- self.__clear_user_job_count()
+ self.__clear_job_count()
# Keep track of the pid that started the job manager, only it
# has valid threads
@@ -232,7 +232,7 @@
except Empty:
pass
# Ensure that we get new job counts on each iteration
- self.__clear_user_job_count()
+ self.__clear_job_count()
# Iterate over new and waiting jobs and look for any that are
# ready to run
new_waiting_jobs = []
@@ -330,7 +330,10 @@
self.job_wrappers[job.id].fail( failure_message )
return JOB_ERROR
# job is ready to run, check limits
- state = self.__check_user_jobs( job, self.job_wrappers[job.id] )
+ # TODO: these checks should be refactored to minimize duplication and made more modular/pluggable
+ state = self.__check_destination_jobs( job, self.job_wrappers[job.id] )
+ if state == JOB_READY:
+ state = self.__check_user_jobs( job, self.job_wrappers[job.id] )
if state == JOB_READY and self.app.config.enable_quotas:
quota = self.app.quota_agent.get_quota( job.user )
if quota is not None:
@@ -340,11 +343,15 @@
return JOB_USER_OVER_QUOTA
except AssertionError, e:
pass # No history, should not happen with an anon user
+ if state == JOB_READY:
+ # PASS. increase usage by one job (if caching) so that multiple jobs aren't dispatched on this queue iteration
+ self.increase_running_job_count(job.user_id, self.job_wrappers[job.id].job_destination.id)
return state
- def __clear_user_job_count( self ):
+ def __clear_job_count( self ):
self.user_job_count = None
self.user_job_count_per_destination = None
+ self.total_job_count_per_destination = None
def get_user_job_count(self, user_id):
self.__cache_user_job_count()
@@ -404,14 +411,21 @@
self.user_job_count_per_destination = {}
def increase_running_job_count(self, user_id, destination_id):
- if self.user_job_count is None:
- self.user_job_count = {}
- if self.user_job_count_per_destination is None:
- self.user_job_count_per_destination = {}
- self.user_job_count[user_id] = self.user_job_count.get(user_id, 0) + 1
- if user_id not in self.user_job_count_per_destination:
- self.user_job_count_per_destination[user_id] = {}
- self.user_job_count_per_destination[user_id][destination_id] = self.user_job_count_per_destination[user_id].get(destination_id, 0) + 1
+ if self.app.job_config.limits.registered_user_concurrent_jobs or \
+ self.app.job_config.limits.anonymous_user_concurrent_jobs or \
+ self.app.job_config.limits.destination_user_concurrent_jobs:
+ if self.user_job_count is None:
+ self.user_job_count = {}
+ if self.user_job_count_per_destination is None:
+ self.user_job_count_per_destination = {}
+ self.user_job_count[user_id] = self.user_job_count.get(user_id, 0) + 1
+ if user_id not in self.user_job_count_per_destination:
+ self.user_job_count_per_destination[user_id] = {}
+ self.user_job_count_per_destination[user_id][destination_id] = self.user_job_count_per_destination[user_id].get(destination_id, 0) + 1
+ if self.app.job_config.limits.destination_total_concurrent_jobs:
+ if self.total_job_count_per_destination is None:
+ self.total_job_count_per_destination = {}
+ self.total_job_count_per_destination[destination_id] = self.total_job_count_per_destination.get(destination_id, 0) + 1
def __check_user_jobs( self, job, job_wrapper ):
if job.user:
@@ -424,25 +438,23 @@
# If we pass the hard limit, also check the per-destination count
id = job_wrapper.job_destination.id
count_per_id = self.get_user_job_count_per_destination(job.user_id)
- if id in self.app.job_config.limits.concurrent_jobs:
+ if id in self.app.job_config.limits.destination_user_concurrent_jobs:
count = count_per_id.get(id, 0)
# Check the user's number of dispatched jobs in the assigned destination id against the limit for that id
- if count >= self.app.job_config.limits.concurrent_jobs[id]:
+ if count >= self.app.job_config.limits.destination_user_concurrent_jobs[id]:
return JOB_WAIT
# If we pass the destination limit (if there is one), also check limits on any tags (if any)
if job_wrapper.job_destination.tags:
for tag in job_wrapper.job_destination.tags:
# Check each tag for this job's destination
- if tag in self.app.job_config.limits.concurrent_jobs:
+ if tag in self.app.job_config.limits.destination_user_concurrent_jobs:
# Only if there's a limit defined for this tag
count = 0
for id in [ d.id for d in self.app.job_config.get_destinations(tag) ]:
# Add up the aggregate job total for this tag
count += count_per_id.get(id, 0)
- if count >= self.app.job_config.limits.concurrent_jobs[tag]:
+ if count >= self.app.job_config.limits.destination_user_concurrent_jobs[tag]:
return JOB_WAIT
- # PASS. increase usage by one job (if caching) so that multiple jobs aren't dispatched on this queue iteration
- self.increase_running_job_count(job.user_id, id)
elif job.galaxy_session:
# Anonymous users only get the hard limit
if self.app.job_config.limits.anonymous_user_concurrent_jobs:
@@ -456,6 +468,46 @@
log.warning( 'Job %s is not associated with a user or session so job concurrency limit cannot be checked.' % job.id )
return JOB_READY
+ def __cache_total_job_count_per_destination( self ):
+ # Cache the job count if necessary
+ if self.total_job_count_per_destination is None:
+ self.total_job_count_per_destination = {}
+ result = self.sa_session.execute(select([model.Job.table.c.destination_id, func.count(model.Job.table.c.destination_id).label('job_count')]) \
+ .where(and_(model.Job.table.c.state.in_((model.Job.states.QUEUED, model.Job.states.RUNNING)))) \
+ .group_by(model.Job.table.c.destination_id))
+ for row in result:
+ self.total_job_count_per_destination[row['destination_id']] = row['job_count']
+
+ def get_total_job_count_per_destination(self):
+ self.__cache_total_job_count_per_destination()
+ # Always use caching (at worst a job will have to wait one iteration,
+ # and this would be more fair anyway as it ensures FIFO scheduling,
+ # insofar as FIFO would be fair...)
+ return self.total_job_count_per_destination
+
+ def __check_destination_jobs( self, job, job_wrapper ):
+ if self.app.job_config.limits.destination_total_concurrent_jobs:
+ id = job_wrapper.job_destination.id
+ count_per_id = self.get_total_job_count_per_destination()
+ if id in self.app.job_config.limits.destination_total_concurrent_jobs:
+ count = count_per_id.get(id, 0)
+ # Check the number of dispatched jobs in the assigned destination id against the limit for that id
+ if count >= self.app.job_config.limits.destination_total_concurrent_jobs[id]:
+ return JOB_WAIT
+ # If we pass the destination limit (if there is one), also check limits on any tags (if any)
+ if job_wrapper.job_destination.tags:
+ for tag in job_wrapper.job_destination.tags:
+ # Check each tag for this job's destination
+ if tag in self.app.job_config.limits.destination_total_concurrent_jobs:
+ # Only if there's a limit defined for this tag
+ count = 0
+ for id in [ d.id for d in self.app.job_config.get_destinations(tag) ]:
+ # Add up the aggregate job total for this tag
+ count += count_per_id.get(id, 0)
+ if count >= self.app.job_config.limits.destination_total_concurrent_jobs[tag]:
+ return JOB_WAIT
+ return JOB_READY
+
def put( self, job_id, tool_id ):
"""Add a job to the queue (by job identifier)"""
if not self.track_jobs_in_database:
https://bitbucket.org/galaxy/galaxy-central/commits/46a487e7d547/
Changeset: 46a487e7d547
User: natefoo
Date: 2014-06-03 00:23:07
Summary: Document limits available in job_conf.xml.
Affected #: 1 file
diff -r 9937a1344fe789be6111d1af4b746b203a0dd785 -r 46a487e7d5476429cb71885adcbcfb9746ce725a job_conf.xml.sample_advanced
--- a/job_conf.xml.sample_advanced
+++ b/job_conf.xml.sample_advanced
@@ -253,12 +253,44 @@
<tool id="baz" handler="special_handlers" destination="bigmem"/></tools><limits>
- <!-- Certain limits can be defined. -->
+ <!-- Certain limits can be defined. The 'concurrent_jobs' limits all
+ control the number of jobs that can be "active" at a time, that
+ is, dispatched to a runner and in the 'queued' or 'running'
+ states.
+
+ A race condition exists that will allow destination_* concurrency
+ limits to be surpassed when multiple handlers are allowed to
+ handle jobs for the same destination. To prevent this, assign all
+ jobs for a specific destination to a single handler.
+ -->
+ <!-- registered_user_concurrent_jobs:
+ Limit on the number of jobs a user with a registered Galaxy
+ account can have active across all destinations.
+ --><limit type="registered_user_concurrent_jobs">2</limit>
+ <!-- anonymous_user_concurrent_jobs:
+ Likewise, but for unregistered/anonymous users.
+ --><limit type="anonymous_user_concurrent_jobs">1</limit>
+ <!-- destination_user_concurrent_jobs:
+ The number of jobs a user can have active in the specified
+ destination, or across all destinations identified by the
+ specified tag. (formerly: concurrent_jobs)
+ -->
+ <limit type="destination_user_concurrent_jobs" id="local">1</limit>
+ <limit type="destination_user_concurrent_jobs" tag="mycluster">2</limit>
+ <limit type="destination_user_concurrent_jobs" tag="longjobs">1</limit>
+ <!-- destination_total_concurrent_jobs:
+ The number of jobs that can be active in the specified
+ destination (or across all destinations identified by the
+ specified tag) by any/all users.
+ -->
+ <limit type="destination_total_concurrent_jobs" id="local">16</limit>
+ <limit type="destination_total_concurrent_jobs" tag="longjobs">100</limit>
+ <!-- walltime:
+ Amount of time a job can run (in any destination) before it
+ will be terminated by Galaxy.
+ --><limit type="walltime">24:00:00</limit>
- <limit type="concurrent_jobs" id="local">1</limit>
- <limit type="concurrent_jobs" tag="mycluster">2</limit>
- <limit type="concurrent_jobs" tag="longjobs">1</limit></limits></job_conf>
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: Merge stable to default.
by commits-noreply@bitbucket.org 02 Jun '14
by commits-noreply@bitbucket.org 02 Jun '14
02 Jun '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/e79b7ea727c9/
Changeset: e79b7ea727c9
User: natefoo
Date: 2014-06-02 22:45:41
Summary: Merge stable to default.
Affected #: 1 file
diff -r 5273e0bf9ae54599f1dadbce9d943dcac828d0f0 -r e79b7ea727c90c2c7ccebdafcd19a5a6d880c51c .hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -7,3 +7,6 @@
26f58e05aa1068761660681583821e21e6cbf7ab release_2013.11.04
5e605ed6069fe4c5ca9875e95e91b2713499e8ca release_2014.02.10
9e53251b0b7e93b9563008a2b112f2e815a04bbc release_2014.04.14
+68a8b0397947c732b28207d465d3f3c4e2a7a8a0 latest_2014.04.14
+7e257c7b10badb65772b1528cb61d58175a42e47 release_2014.06.02
+7e257c7b10badb65772b1528cb61d58175a42e47 latest_2014.06.02
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