galaxy-commits
Threads by month
- ----- 2026 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- 15302 discussions
10 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/e20408b06d65/
Changeset: e20408b06d65
User: greg
Date: 2014-04-10 23:11:01
Summary: Add a new tool shed mercurial utility module named hg_util.py and begin to extract hg related utility functions out of the shed_util_common.py module. Enhance the functions that display the mercurial changeset rev and hash string to display one or the other or both. Display only the rev and not the hash string on the prominent grids in the tool shed, but continue to display the hash string on admin grids.
Affected #: 27 files
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 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
@@ -16,6 +16,7 @@
from tool_shed.util import data_manager_util
from tool_shed.util import datatype_util
from tool_shed.util import encoding_util
+from tool_shed.util import hg_util
from tool_shed.util import metadata_util
from tool_shed.util import readme_util
from tool_shed.util import repository_dependency_util
@@ -1851,7 +1852,7 @@
repo_files_dir = os.path.abspath( os.path.join( tool_path, relative_install_dir, name ) )
else:
repo_files_dir = os.path.abspath( os.path.join( relative_install_dir, name ) )
- repo = hg.repository( suc.get_configured_ui(), path=repo_files_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), path=repo_files_dir )
repository_clone_url = os.path.join( tool_shed_url, 'repos', owner, name )
repository_util.pull_repository( repo, repository_clone_url, latest_ctx_rev )
suc.update_repository( repo, latest_ctx_rev )
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/galaxy/webapps/tool_shed/api/repositories.py
--- a/lib/galaxy/webapps/tool_shed/api/repositories.py
+++ b/lib/galaxy/webapps/tool_shed/api/repositories.py
@@ -13,6 +13,7 @@
import tool_shed.util.shed_util_common as suc
from tool_shed.galaxy_install import repository_util
from tool_shed.util import encoding_util
+from tool_shed.util import hg_util
from tool_shed.util import import_util
from tool_shed.util import metadata_util
from tool_shed.util import repository_maintenance_util
@@ -49,7 +50,7 @@
log.debug( error_message )
return []
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
ordered_installable_revisions = suc.get_ordered_metadata_changeset_revisions( repository, repo, downloadable=True )
return ordered_installable_revisions
else:
@@ -133,7 +134,7 @@
# The changeset_revision column in the repository_metadata table has been updated with a new
# value value, so find the changeset_revision to which we need to update.
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
new_changeset_revision = suc.get_next_downloadable_changeset_revision( repository, repo, changeset_revision )
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans,
encoded_repository_id,
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/galaxy/webapps/tool_shed/api/repository_revisions.py
--- a/lib/galaxy/webapps/tool_shed/api/repository_revisions.py
+++ b/lib/galaxy/webapps/tool_shed/api/repository_revisions.py
@@ -6,6 +6,7 @@
from galaxy.model.orm import and_, not_, select
from galaxy.web.base.controller import BaseAPIController, HTTPBadRequest
from tool_shed.util import export_util
+from tool_shed.util import hg_util
import tool_shed.util.shed_util_common as suc
from galaxy import eggs
@@ -168,7 +169,7 @@
# The changeset_revision column in the repository_metadata table has been updated with a new
# value value, so find the changeset_revision to which we need to update.
repo_dir = repository_dependency.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
new_changeset_revision = suc.get_next_downloadable_changeset_revision( repository_dependency,
repo,
changeset_revision )
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/galaxy/webapps/tool_shed/controllers/repository.py
--- a/lib/galaxy/webapps/tool_shed/controllers/repository.py
+++ b/lib/galaxy/webapps/tool_shed/controllers/repository.py
@@ -19,6 +19,7 @@
from tool_shed.util import container_util
from tool_shed.util import encoding_util
from tool_shed.util import export_util
+from tool_shed.util import hg_util
from tool_shed.util import import_util
from tool_shed.util import metadata_util
from tool_shed.util import readme_util
@@ -719,7 +720,7 @@
status = kwd.get( 'status', 'done' )
commit_message = kwd.get( 'commit_message', 'Deleted selected files' )
repository = suc.get_repository_in_tool_shed( trans, id )
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
# Update repository files for browsing.
suc.update_repository( repo )
changeset_revision = repository.tip( trans.app )
@@ -891,9 +892,9 @@
changeset_revision = kwd.get( 'changeset_revision', None )
repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
# Default to the current changeset revision.
- update_to_ctx = suc.get_changectx_for_changeset( repo, changeset_revision )
+ update_to_ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision )
latest_changeset_revision = changeset_revision
from_update_manager = kwd.get( 'from_update_manager', False )
if from_update_manager:
@@ -937,10 +938,10 @@
update_to_changeset_hash = None
for changeset in repo.changelog:
changeset_hash = str( repo.changectx( changeset ) )
- ctx = suc.get_changectx_for_changeset( repo, changeset_hash )
+ ctx = hg_util.get_changectx_for_changeset( repo, changeset_hash )
if update_to_changeset_hash:
if changeset_hash == repository.tip( trans.app ):
- update_to_ctx = suc.get_changectx_for_changeset( repo, changeset_hash )
+ update_to_ctx = hg_util.get_changectx_for_changeset( repo, changeset_hash )
latest_changeset_revision = changeset_hash
break
else:
@@ -949,7 +950,7 @@
changeset_hash )
if repository_metadata:
# We found a RepositoryMetadata record.
- update_to_ctx = suc.get_changectx_for_changeset( repo, changeset_hash )
+ update_to_ctx = hg_util.get_changectx_for_changeset( repo, changeset_hash )
latest_changeset_revision = changeset_hash
break
else:
@@ -1213,7 +1214,7 @@
else:
containers_dict = None
export_repository_dependencies_check_box = None
- revision_label = suc.get_revision_label( trans, repository, changeset_revision, include_date=True )
+ revision_label = hg_util.get_revision_label( trans, repository, changeset_revision, include_date=True )
return trans.fill_template( "/webapps/tool_shed/repository/export_repository.mako",
changeset_revision=changeset_revision,
containers_dict=containers_dict,
@@ -1466,9 +1467,9 @@
has_repository_dependencies_only_if_compiling_contained_td = has_galaxy_utilities_dict[ 'has_repository_dependencies_only_if_compiling_contained_td' ]
includes_workflows = has_galaxy_utilities_dict[ 'includes_workflows' ]
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
# Default to the received changeset revision and ctx_rev.
- update_to_ctx = suc.get_changectx_for_changeset( repo, changeset_revision )
+ update_to_ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision )
ctx_rev = str( update_to_ctx.rev() )
latest_changeset_revision = changeset_revision
update_dict = dict( changeset_revision=changeset_revision,
@@ -1497,7 +1498,7 @@
has_repository_dependencies = False
has_repository_dependencies_only_if_compiling_contained_td = False
changeset_hash = str( repo.changectx( changeset ) )
- ctx = suc.get_changectx_for_changeset( repo, changeset_hash )
+ ctx = hg_util.get_changectx_for_changeset( repo, changeset_hash )
if update_to_changeset_hash:
update_to_repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans,
trans.security.encode_id( repository.id ),
@@ -1515,10 +1516,10 @@
# We found a RepositoryMetadata record.
if changeset_hash == repository.tip( trans.app ):
# The current ctx is the repository tip, so use it.
- update_to_ctx = suc.get_changectx_for_changeset( repo, changeset_hash )
+ update_to_ctx = hg_util.get_changectx_for_changeset( repo, changeset_hash )
latest_changeset_revision = changeset_hash
else:
- update_to_ctx = suc.get_changectx_for_changeset( repo, update_to_changeset_hash )
+ update_to_ctx = hg_util.get_changectx_for_changeset( repo, update_to_changeset_hash )
latest_changeset_revision = update_to_changeset_hash
break
elif not update_to_changeset_hash and changeset_hash == changeset_revision:
@@ -1544,8 +1545,8 @@
changeset_revision = kwd[ 'changeset_revision' ]
repository = suc.get_repository_by_name_and_owner( trans.app, repository_name, repository_owner )
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
- ctx = suc.get_changectx_for_changeset( repo, changeset_revision )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
+ ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision )
if ctx:
return str( ctx.rev() )
return ''
@@ -1560,8 +1561,8 @@
def get_file_from_changeset_revision( self, repo_files_dir, changeset_revision, file_name, dir ):
"""Return file_name from the received changeset_revision of the repository manifest."""
stripped_file_name = suc.strip_path( file_name )
- repo = hg.repository( suc.get_configured_ui(), repo_files_dir )
- ctx = suc.get_changectx_for_changeset( repo, changeset_revision )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_files_dir )
+ ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision )
named_tmp_file = suc.get_named_tmpfile_from_ctx( ctx, file_name, dir )
return named_tmp_file
@@ -1604,7 +1605,7 @@
trans.model.Repository.table.c.user_id == user.id ) ):
repository = repository_metadata.repository
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
latest_downloadable_changeset_revsion = suc.get_latest_downloadable_changeset_revision( trans, repository, repo )
if repository_metadata.changeset_revision == latest_downloadable_changeset_revsion:
# We'll display only the test run for the latest installable revision in the rss feed.
@@ -1672,7 +1673,7 @@
if repository_name is not None and repository_owner is not None:
repository = suc.get_repository_by_name_and_owner( trans.app, repository_name, repository_owner )
if repository:
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
return suc.get_latest_downloadable_changeset_revision( trans, repository, repo )
return suc.INITIAL_CHANGELOG_HASH
@@ -1855,7 +1856,7 @@
changeset_revision = kwd[ 'changeset_revision' ]
repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
tool_version_dicts = []
for changeset in repo.changelog:
current_changeset_revision = str( repo.changectx( changeset ) )
@@ -1880,7 +1881,7 @@
repository_id = trans.security.encode_id( repository.id )
repository_clone_url = common_util.generate_clone_url_for_repository_in_tool_shed( trans, repository )
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, repository_id, changeset_revision )
if not repository_metadata:
# The received changeset_revision is no longer associated with metadata, so get the next changeset_revision in the repository
@@ -1889,7 +1890,7 @@
repo,
after_changeset_revision=changeset_revision )
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, repository_id, changeset_revision )
- ctx = suc.get_changectx_for_changeset( repo, changeset_revision )
+ ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision )
repo_info_dict = repository_util.create_repo_info_dict( trans=trans,
repository_clone_url=repository_clone_url,
changeset_revision=changeset_revision,
@@ -2165,7 +2166,7 @@
repository = suc.get_repository_in_tool_shed( trans, id )
repository_type = kwd.get( 'repository_type', str( repository.type ) )
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
repo_name = kwd.get( 'repo_name', repository.name )
changeset_revision = kwd.get( 'changeset_revision', repository.tip( trans.app ) )
description = kwd.get( 'description', repository.description )
@@ -2317,7 +2318,7 @@
selected_value=changeset_revision,
add_id_to_name=False,
downloadable=False )
- revision_label = suc.get_revision_label( trans, repository, repository.tip( trans.app ), include_date=False )
+ revision_label = hg_util.get_revision_label( trans, repository, repository.tip( trans.app ), include_date=False )
repository_metadata = None
metadata = None
is_malicious = False
@@ -2326,7 +2327,7 @@
if changeset_revision != suc.INITIAL_CHANGELOG_HASH:
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, id, changeset_revision )
if repository_metadata:
- revision_label = suc.get_revision_label( trans, repository, changeset_revision, include_date=False )
+ revision_label = hg_util.get_revision_label( trans, repository, changeset_revision, include_date=False )
metadata = repository_metadata.metadata
is_malicious = repository_metadata.malicious
else:
@@ -2337,7 +2338,7 @@
if previous_changeset_revision != suc.INITIAL_CHANGELOG_HASH:
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, id, previous_changeset_revision )
if repository_metadata:
- revision_label = suc.get_revision_label( trans, repository, previous_changeset_revision, include_date=False )
+ revision_label = hg_util.get_revision_label( trans, repository, previous_changeset_revision, include_date=False )
metadata = repository_metadata.metadata
is_malicious = repository_metadata.malicious
changeset_revision = previous_changeset_revision
@@ -2443,7 +2444,7 @@
# There is no repository_metadata defined for the changeset_revision, so see if it was defined
# in a previous changeset in the changelog.
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
previous_changeset_revision = \
suc.get_previous_metadata_changeset_revision( repository,
repo,
@@ -2520,7 +2521,7 @@
changeset_revision = kwd.get( 'changeset_revision', None )
repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
# Get the next installable changeset_revision beyond the received changeset_revision.
changeset_revision = suc.get_next_downloadable_changeset_revision( repository, repo, changeset_revision )
if changeset_revision:
@@ -2540,7 +2541,7 @@
status = kwd.get( 'status', 'done' )
repository = suc.get_repository_in_tool_shed( trans, repository_id )
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
changeset_revision = kwd.get( 'changeset_revision', repository.tip( trans.app ) )
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, repository_id, changeset_revision )
if repository_metadata:
@@ -2577,7 +2578,7 @@
repository_metadata_id = None
metadata = None
repository_dependencies = None
- revision_label = suc.get_revision_label( trans, repository, changeset_revision, include_date=True )
+ revision_label = hg_util.get_revision_label( trans, repository, changeset_revision, include_date=True )
changeset_revision_select_field = grids_util.build_changeset_revision_select_field( trans,
repository,
selected_value=changeset_revision,
@@ -2607,7 +2608,7 @@
changeset_revision = kwd.get( 'changeset_revision', None )
repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
# Get the lower bound changeset revision.
lower_bound_changeset_revision = suc.get_previous_metadata_changeset_revision( repository, repo, changeset_revision, downloadable=True )
# Build the list of changeset revision hashes.
@@ -2633,7 +2634,7 @@
status='error' ) )
repository = suc.get_repository_in_tool_shed( trans, id )
changeset_revision = repository.tip( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
if repository.user == trans.user:
return trans.response.send_redirect( web.url_for( controller='repository',
action='browse_repositories',
@@ -2651,7 +2652,7 @@
changeset_revision,
metadata_only=True )
repository_type_select_field = rt_util.build_repository_type_select_field( trans, repository=repository )
- revision_label = suc.get_revision_label( trans, repository, changeset_revision, include_date=True )
+ revision_label = hg_util.get_revision_label( trans, repository, changeset_revision, include_date=True )
return trans.fill_template( '/webapps/tool_shed/repository/rate_repository.mako',
repository=repository,
metadata=metadata,
@@ -2702,7 +2703,7 @@
commit_message = kwd.get( 'commit_message', 'Deleted selected files' )
repository = suc.get_repository_in_tool_shed( trans, id )
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
selected_files_to_delete = kwd.get( 'selected_files_to_delete', '' )
if kwd.get( 'select_files_to_delete_button', False ):
if selected_files_to_delete:
@@ -2742,7 +2743,7 @@
# Update the repository files for browsing.
suc.update_repository( repo )
# Get the new repository tip.
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
if tip == repository.tip( trans.app ):
message += 'No changes to repository. '
kwd[ 'message' ] = message
@@ -2931,7 +2932,7 @@
if not repository_metadata:
# Get updates to the received changeset_revision if any exist.
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
upper_bound_changeset_revision = suc.get_next_downloadable_changeset_revision( repository, repo, changeset_revision )
if upper_bound_changeset_revision:
changeset_revision = upper_bound_changeset_revision
@@ -2971,7 +2972,7 @@
trans.security.encode_id( repository.id ),
changeset_revision )
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
tool_shed_status_dict = {}
# Handle repository deprecation.
tool_shed_status_dict[ 'repository_deprecated' ] = str( repository.deprecated )
@@ -3063,7 +3064,7 @@
message = kwd.get( 'message', '' )
status = kwd.get( 'status', 'done' )
repository = suc.get_repository_in_tool_shed( trans, id )
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
changesets = []
for changeset in repo.changelog:
ctx = repo.changectx( changeset )
@@ -3074,7 +3075,7 @@
change_dict = { 'ctx' : ctx,
'rev' : str( ctx.rev() ),
'date' : date,
- 'display_date' : suc.get_readable_ctx_date( ctx ),
+ 'display_date' : hg_util.get_readable_ctx_date( ctx ),
'description' : ctx.description(),
'files' : ctx.files(),
'user' : ctx.user(),
@@ -3098,8 +3099,8 @@
message = kwd.get( 'message', '' )
status = kwd.get( 'status', 'done' )
repository = suc.get_repository_in_tool_shed( trans, id )
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
- ctx = suc.get_changectx_for_changeset( repo, ctx_str )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
+ ctx = hg_util.get_changectx_for_changeset( repo, ctx_str )
if ctx is None:
message = "Repository does not include changeset revision '%s'." % str( ctx_str )
status = 'error'
@@ -3129,7 +3130,7 @@
metadata = metadata_util.get_repository_metadata_by_repository_id_changeset_revision( trans, id, ctx_str, metadata_only=True )
# For rendering the prev button.
if ctx_parent:
- ctx_parent_date = suc.get_readable_ctx_date( ctx_parent )
+ ctx_parent_date = hg_util.get_readable_ctx_date( ctx_parent )
ctx_parent_rev = ctx_parent.rev()
if ctx_parent_rev < 0:
prev = None
@@ -3138,7 +3139,7 @@
else:
prev = None
if ctx_child:
- ctx_child_date = suc.get_readable_ctx_date( ctx_child )
+ ctx_child_date = hg_util.get_readable_ctx_date( ctx_child )
ctx_child_rev = ctx_child.rev()
next = "<b>%s:%s</b><i>(%s)</i>" % ( ctx_child_rev, ctx_child, ctx_child_date )
else:
@@ -3187,7 +3188,7 @@
message = kwd.get( 'message', '' )
status = kwd.get( 'status', 'done' )
repository = suc.get_repository_in_tool_shed( trans, id )
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
avg_rating, num_ratings = self.get_ave_item_rating_data( trans.sa_session, repository, webapp_model=trans.model )
changeset_revision = kwd.get( 'changeset_revision', repository.tip( trans.app ) )
display_reviews = kwd.get( 'display_reviews', False )
@@ -3221,7 +3222,7 @@
selected_value=changeset_revision,
add_id_to_name=False,
downloadable=False )
- revision_label = suc.get_revision_label( trans, repository, changeset_revision, include_date=False )
+ revision_label = hg_util.get_revision_label( trans, repository, changeset_revision, include_date=False )
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, id, changeset_revision )
if repository_metadata:
metadata = repository_metadata.metadata
@@ -3277,13 +3278,13 @@
render_repository_actions_for = kwd.get( 'render_repository_actions_for', 'tool_shed' )
repository = suc.get_repository_in_tool_shed( trans, repository_id )
repo_files_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_files_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_files_dir )
tool_metadata_dict = {}
tool_lineage = []
tool = None
guid = None
original_tool_data_path = trans.app.config.tool_data_path
- revision_label = suc.get_revision_label( trans, repository, changeset_revision, include_date=False )
+ revision_label = hg_util.get_revision_label( trans, repository, changeset_revision, include_date=False )
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, repository_id, changeset_revision )
if repository_metadata:
repository_metadata_id = trans.security.encode_id( repository_metadata.id )
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/galaxy/webapps/tool_shed/controllers/repository_review.py
--- a/lib/galaxy/webapps/tool_shed/controllers/repository_review.py
+++ b/lib/galaxy/webapps/tool_shed/controllers/repository_review.py
@@ -7,6 +7,7 @@
from galaxy.webapps.tool_shed.util import ratings_util
from tool_shed.util.container_util import STRSEP
import tool_shed.util.shed_util_common as suc
+from tool_shed.util import hg_util
from tool_shed.util import review_util
from galaxy.util.odict import odict
import tool_shed.grids.repository_review_grids as repository_review_grids
@@ -72,8 +73,8 @@
status = kwd.get( 'status', 'done' )
review = review_util.get_review( trans, kwd[ 'id' ] )
repository = review.repository
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
- rev, changeset_revision_label = suc.get_rev_label_from_changeset_revision( repo, review.changeset_revision )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
+ rev, changeset_revision_label = hg_util.get_rev_label_from_changeset_revision( repo, review.changeset_revision )
return trans.fill_template( '/webapps/tool_shed/repository_review/browse_review.mako',
repository=repository,
changeset_revision_label=changeset_revision_label,
@@ -232,7 +233,7 @@
for component in review_util.get_components( trans ):
components_dict[ component.name ] = dict( component=component, component_review=None )
repository = review.repository
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
for component_review in review.component_reviews:
if component_review and component_review.component:
component_name = component_review.component.name
@@ -337,7 +338,7 @@
name='revision_approved',
selected_value=selected_value,
for_component=False )
- rev, changeset_revision_label = suc.get_rev_label_from_changeset_revision( repo, review.changeset_revision )
+ rev, changeset_revision_label = hg_util.get_rev_label_from_changeset_revision( repo, review.changeset_revision )
return trans.fill_template( '/webapps/tool_shed/repository_review/edit_review.mako',
repository=repository,
review=review,
@@ -470,7 +471,7 @@
if repository_id:
repository = suc.get_repository_in_tool_shed( trans, repository_id )
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
metadata_revision_hashes = [ metadata_revision.changeset_revision for metadata_revision in repository.metadata_revisions ]
reviewed_revision_hashes = [ review.changeset_revision for review in repository.reviews ]
reviews_dict = odict()
@@ -478,7 +479,7 @@
ctx = repo.changectx( changeset )
changeset_revision = str( ctx )
if changeset_revision in metadata_revision_hashes or changeset_revision in reviewed_revision_hashes:
- rev, changeset_revision_label = suc.get_rev_label_from_changeset_revision( repo, changeset_revision )
+ rev, changeset_revision_label = hg_util.get_rev_label_from_changeset_revision( repo, changeset_revision )
if changeset_revision in reviewed_revision_hashes:
# Find the review for this changeset_revision
repository_reviews = review_util.get_reviews_by_repository_id_changeset_revision( trans, repository_id, changeset_revision )
@@ -517,9 +518,9 @@
changeset_revision = kwd.get( 'changeset_revision', None )
repository = suc.get_repository_in_tool_shed( trans, repository_id )
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
installable = changeset_revision in [ metadata_revision.changeset_revision for metadata_revision in repository.metadata_revisions ]
- rev, changeset_revision_label = suc.get_rev_label_from_changeset_revision( repo, changeset_revision )
+ rev, changeset_revision_label = hg_util.get_rev_label_from_changeset_revision( repo, changeset_revision )
reviews = review_util.get_reviews_by_repository_id_changeset_revision( trans, repository_id, changeset_revision )
return trans.fill_template( '/webapps/tool_shed/repository_review/reviews_of_changeset_revision.mako',
repository=repository,
@@ -582,9 +583,9 @@
status = kwd.get( 'status', 'done' )
repository = suc.get_repository_in_tool_shed( trans, kwd[ 'id' ] )
changeset_revision = kwd.get( 'changeset_revision', None )
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
previous_reviews_dict = review_util.get_previous_repository_reviews( trans, repository, changeset_revision )
- rev, changeset_revision_label = suc.get_rev_label_from_changeset_revision( repo, changeset_revision )
+ rev, changeset_revision_label = hg_util.get_rev_label_from_changeset_revision( repo, changeset_revision )
return trans.fill_template( '/webapps/tool_shed/repository_review/select_previous_review.mako',
repository=repository,
changeset_revision=changeset_revision,
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/galaxy/webapps/tool_shed/controllers/upload.py
--- a/lib/galaxy/webapps/tool_shed/controllers/upload.py
+++ b/lib/galaxy/webapps/tool_shed/controllers/upload.py
@@ -11,6 +11,7 @@
import tool_shed.repository_types.util as rt_util
import tool_shed.util.shed_util_common as suc
from tool_shed.util import commit_util
+from tool_shed.util import hg_util
from tool_shed.util import metadata_util
from tool_shed.util import repository_dependency_util
from tool_shed.util import tool_dependency_util
@@ -39,7 +40,7 @@
repository_id = kwd.get( 'repository_id', '' )
repository = suc.get_repository_in_tool_shed( trans, repository_id )
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
uncompress_file = util.string_as_bool( kwd.get( 'uncompress_file', 'true' ) )
remove_repo_files_not_in_tar = util.string_as_bool( kwd.get( 'remove_repo_files_not_in_tar', 'true' ) )
uploaded_file = None
@@ -63,7 +64,7 @@
repo_url = 'http%s' % url[ len( 'hg' ): ]
repo_url = repo_url.encode( 'ascii', 'replace' )
try:
- commands.clone( suc.get_configured_ui(), repo_url, uploaded_directory )
+ commands.clone( hg_util.get_configured_ui(), repo_url, uploaded_directory )
except Exception, e:
message = 'Error uploading via mercurial clone: %s' % suc.to_html_string( str( e ) )
status = 'error'
@@ -323,7 +324,7 @@
def upload_directory( self, trans, repository, uploaded_directory, upload_point, remove_repo_files_not_in_tar,
commit_message, new_repo_alert ):
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
undesirable_dirs_removed = 0
undesirable_files_removed = 0
if upload_point is not None:
@@ -387,7 +388,7 @@
def upload_tar( self, trans, repository, tar, uploaded_file, upload_point, remove_repo_files_not_in_tar, commit_message, new_repo_alert ):
# Upload a tar archive of files.
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
undesirable_dirs_removed = 0
undesirable_files_removed = 0
ok, message = commit_util.check_archive( repository, tar )
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/tool_shed/galaxy_install/repository_util.py
--- a/lib/tool_shed/galaxy_install/repository_util.py
+++ b/lib/tool_shed/galaxy_install/repository_util.py
@@ -15,6 +15,7 @@
from tool_shed.util import data_manager_util
from tool_shed.util import datatype_util
from tool_shed.util import encoding_util
+from tool_shed.util import hg_util
from tool_shed.util import repository_dependency_util
from tool_shed.util import metadata_util
from tool_shed.util import tool_dependency_util
@@ -186,7 +187,7 @@
def get_repo_info_dict( trans, repository_id, changeset_revision ):
repository = suc.get_repository_in_tool_shed( trans, repository_id )
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
repository_clone_url = common_util.generate_clone_url_for_repository_in_tool_shed( trans, repository )
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans,
repository_id,
@@ -225,7 +226,7 @@
has_repository_dependencies_only_if_compiling_contained_td = False
includes_tool_dependencies = False
includes_tools_for_display_in_tool_panel = False
- ctx = suc.get_changectx_for_changeset( repo, changeset_revision )
+ ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision )
repo_info_dict = create_repo_info_dict( trans=trans,
repository_clone_url=repository_clone_url,
changeset_revision=changeset_revision,
@@ -574,7 +575,7 @@
current_changeset_revision = changeset_revision_dict.get( 'changeset_revision', None )
current_ctx_rev = changeset_revision_dict.get( 'ctx_rev', None )
if current_ctx_rev != ctx_rev:
- repo = hg.repository( suc.get_configured_ui(), path=os.path.abspath( install_dir ) )
+ repo = hg.repository( hg_util.get_configured_ui(), path=os.path.abspath( install_dir ) )
pull_repository( repo, repository_clone_url, current_changeset_revision )
suc.update_repository( repo, ctx_rev=current_ctx_rev )
handle_repository_contents( trans,
@@ -804,7 +805,7 @@
def pull_repository( repo, repository_clone_url, ctx_rev ):
"""Pull changes from a remote repository to a local one."""
- commands.pull( suc.get_configured_ui(), repo, source=repository_clone_url, rev=[ ctx_rev ] )
+ commands.pull( hg_util.get_configured_ui(), repo, source=repository_clone_url, rev=[ ctx_rev ] )
def repair_tool_shed_repository( trans, repository, repo_info_dict ):
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/tool_shed/grids/admin_grids.py
--- a/lib/tool_shed/grids/admin_grids.py
+++ b/lib/tool_shed/grids/admin_grids.py
@@ -5,6 +5,7 @@
from galaxy.webapps.tool_shed import model
from galaxy.model.orm import and_
import tool_shed.util.shed_util_common as suc
+from tool_shed.util import hg_util
from tool_shed.grids.repository_grids import CategoryGrid
from tool_shed.grids.repository_grids import RepositoryGrid
@@ -425,9 +426,11 @@
def get_value( self, trans, grid, repository_metadata ):
repository = repository_metadata.repository
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
- ctx = suc.get_changectx_for_changeset( repo, repository_metadata.changeset_revision )
- return suc.get_revision_label( trans, repository, repository_metadata.changeset_revision, include_date=True )
+ return hg_util.get_revision_label( trans,
+ repository,
+ repository_metadata.changeset_revision,
+ include_date=True,
+ include_hash=True )
class ToolsColumn( grids.TextColumn ):
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/tool_shed/grids/repository_grids.py
--- a/lib/tool_shed/grids/repository_grids.py
+++ b/lib/tool_shed/grids/repository_grids.py
@@ -6,6 +6,7 @@
from galaxy.model.orm import or_
from galaxy.util import json
from galaxy.util import listify
+from tool_shed.util import hg_util
import tool_shed.util.shed_util_common as suc
import tool_shed.grids.util as grids_util
import tool_shed.repository_types.util as rt_util
@@ -116,7 +117,7 @@
def get_value( self, trans, grid, repository ):
"""Display the current repository heads."""
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
heads = suc.get_repository_heads( repo )
multiple_heads = len( heads ) > 1
if multiple_heads:
@@ -124,7 +125,7 @@
else:
heads_str = ''
for ctx in heads:
- heads_str += '%s<br/>' % suc.get_revision_label_from_ctx( ctx, include_date=True )
+ heads_str += '%s<br/>' % hg_util.get_revision_label_from_ctx( ctx, include_date=True )
heads_str.rstrip( '<br/>' )
if multiple_heads:
heads_str += '</font>'
@@ -1338,7 +1339,7 @@
def get_value( self, trans, grid, repository_metadata ):
repository = repository_metadata.repository
changeset_revision = repository_metadata.changeset_revision
- changeset_revision_label = suc.get_revision_label( trans, repository, changeset_revision, include_date=True )
+ changeset_revision_label = hg_util.get_revision_label( trans, repository, changeset_revision, include_date=True )
return changeset_revision_label
@@ -1482,7 +1483,7 @@
changeset_revision )
if not required_repository_metadata:
repo_dir = required_repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
updated_changeset_revision = suc.get_next_downloadable_changeset_revision( required_repository, repo, changeset_revision )
required_repository_metadata = metadata_util.get_repository_metadata_by_repository_id_changeset_revision( trans,
required_repository_id,
@@ -2029,7 +2030,7 @@
tool_dependency_definition.
"""
encoded_repository_id = trans.security.encode_id( repository.id )
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
tip_ctx = str( repo.changectx( repo.changelog.tip() ) )
repository_metadata = None
try:
@@ -2077,7 +2078,7 @@
tool_dependency_definition.
"""
encoded_repository_id = trans.security.encode_id( repository.id )
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
tip_ctx = str( repo.changectx( repo.changelog.tip() ) )
try:
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, encoded_repository_id, tip_ctx )
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/tool_shed/grids/repository_review_grids.py
--- a/lib/tool_shed/grids/repository_review_grids.py
+++ b/lib/tool_shed/grids/repository_review_grids.py
@@ -6,6 +6,7 @@
from galaxy.model.orm import or_
from tool_shed.grids.repository_grids import RepositoryGrid
import tool_shed.util.shed_util_common as suc
+from tool_shed.util import hg_util
from tool_shed.util import metadata_util
from galaxy import eggs
@@ -66,10 +67,10 @@
# Restrict to revisions that have been reviewed.
if repository.reviews:
rval = ''
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
for review in repository.reviews:
changeset_revision = review.changeset_revision
- rev, label = suc.get_rev_label_from_changeset_revision( repo, changeset_revision )
+ rev, label = hg_util.get_rev_label_from_changeset_revision( repo, changeset_revision )
rval += '<a href="manage_repository_reviews_of_revision?id=%s&changeset_revision=%s">%s</a><br/>' % \
( trans.security.encode_id( repository.id ), changeset_revision, label )
return rval
@@ -85,9 +86,11 @@
rval = ''
for repository_metadata in repository_metadata_revisions:
rev, label, changeset_revision = \
- metadata_util.get_rev_label_changeset_revision_from_repository_metadata( trans,
- repository_metadata,
- repository=repository )
+ hg_util.get_rev_label_changeset_revision_from_repository_metadata( trans,
+ repository_metadata,
+ repository=repository,
+ include_date=True,
+ include_hash=False )
rval += '<a href="manage_repository_reviews_of_revision?id=%s&changeset_revision=%s">%s</a><br/>' % \
( trans.security.encode_id( repository.id ), changeset_revision, label )
return rval
@@ -308,7 +311,11 @@
rval += 'edit_review'
else:
rval +='browse_review'
- revision_label = suc.get_revision_label( trans, review.repository, review.changeset_revision, include_date=True )
+ revision_label = hg_util.get_revision_label( trans,
+ review.repository,
+ review.changeset_revision,
+ include_date=True,
+ include_hash=False )
rval += '?id=%s">%s</a>' % ( encoded_review_id, revision_label )
return rval
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/tool_shed/grids/util.py
--- a/lib/tool_shed/grids/util.py
+++ b/lib/tool_shed/grids/util.py
@@ -1,7 +1,7 @@
import logging
import os
import tool_shed.util.shed_util_common as suc
-import tool_shed.util.metadata_util as metadata_util
+from tool_shed.util import hg_util
from galaxy.web.form_builder import SelectField
from galaxy.util.bunch import Bunch
@@ -96,9 +96,11 @@
repository_metadata_revisions = repository.metadata_revisions
for repository_metadata in repository_metadata_revisions:
rev, label, changeset_revision = \
- metadata_util.get_rev_label_changeset_revision_from_repository_metadata( trans,
- repository_metadata,
- repository=repository )
+ hg_util.get_rev_label_changeset_revision_from_repository_metadata( trans,
+ repository_metadata,
+ repository=repository,
+ include_date=True,
+ include_hash=False )
changeset_tups.append( ( rev, label, changeset_revision ) )
refresh_on_change_values.append( changeset_revision )
# Sort options by the revision label. Even though the downloadable_revisions query sorts by update_time,
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/tool_shed/scripts/check_repositories_for_functional_tests.py
--- a/lib/tool_shed/scripts/check_repositories_for_functional_tests.py
+++ b/lib/tool_shed/scripts/check_repositories_for_functional_tests.py
@@ -14,6 +14,7 @@
import ConfigParser
import galaxy.webapps.tool_shed.config as tool_shed_config
+from tool_shed.util import hg_util
import tool_shed.util.shed_util_common as suc
import logging
import shutil
@@ -109,7 +110,7 @@
if tool_dicts is not None:
# Clone the repository up to the changeset revision we're checking.
repo_dir = repository.repo_path( app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
work_dir = tempfile.mkdtemp( prefix="tmp-toolshed-cafr" )
cloned_ok, error_message = suc.clone_repository( repo_dir, work_dir, changeset_revision )
if cloned_ok:
@@ -368,7 +369,7 @@
"""
if not testable_revision:
repo_dir = repository.repo_path( app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
changeset_revisions = suc.get_ordered_metadata_changeset_revisions( repository, repo, downloadable=True )
if len( changeset_revisions ) > 1:
latest_downloadable_revision = changeset_revisions[ -1 ]
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/tool_shed/util/commit_util.py
--- a/lib/tool_shed/util/commit_util.py
+++ b/lib/tool_shed/util/commit_util.py
@@ -12,6 +12,7 @@
from galaxy.util.odict import odict
from galaxy.web import url_for
import tool_shed.util.shed_util_common as suc
+from tool_shed.util import hg_util
from tool_shed.util import tool_util
from tool_shed.util import xml_util
import tool_shed.repository_types.util as rt_util
@@ -156,7 +157,7 @@
def handle_directory_changes( trans, repository, full_path, filenames_in_archive, remove_repo_files_not_in_tar, new_repo_alert,
commit_message, undesirable_dirs_removed, undesirable_files_removed ):
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
content_alert_str = ''
files_to_remove = []
filenames_in_archive = [ os.path.join( full_path, name ) for name in filenames_in_archive ]
@@ -342,7 +343,7 @@
repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
if repository:
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
lastest_installable_changeset_revision = suc.get_latest_downloadable_changeset_revision( trans, repository, repo )
if lastest_installable_changeset_revision != suc.INITIAL_CHANGELOG_HASH:
elem.attrib[ 'changeset_revision' ] = lastest_installable_changeset_revision
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/tool_shed/util/export_util.py
--- a/lib/tool_shed/util/export_util.py
+++ b/lib/tool_shed/util/export_util.py
@@ -14,6 +14,7 @@
from tool_shed.util import common_install_util
from tool_shed.util import common_util
from tool_shed.util import encoding_util
+from tool_shed.util import hg_util
from tool_shed.util import repository_dependency_util
from tool_shed.util import xml_util
@@ -37,7 +38,7 @@
def archive_repository_revision( trans, ui, repository, archive_dir, changeset_revision ):
'''Create an un-versioned archive of a repository.'''
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
options_dict = suc.get_mercurial_default_options_dict( 'archive' )
options_dict[ 'rev' ] = changeset_revision
error_message = ''
@@ -233,8 +234,8 @@
key_rd_dicts_to_be_processed=None,
all_repository_dependencies=None,
handled_key_rd_dicts=None )
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
- ctx = suc.get_changectx_for_changeset( repo, changeset_revision )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
+ ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision )
repo_info_dict = {}
# Cast unicode to string.
repo_info_dict[ str( repository.name ) ] = ( str( repository.description ),
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/tool_shed/util/hg_util.py
--- /dev/null
+++ b/lib/tool_shed/util/hg_util.py
@@ -0,0 +1,108 @@
+import logging
+from datetime import datetime
+from time import gmtime
+from time import strftime
+
+from galaxy import eggs
+eggs.require( 'mercurial' )
+
+from mercurial import cmdutil
+from mercurial import commands
+from mercurial import hg
+from mercurial import ui
+
+def get_changectx_for_changeset( repo, changeset_revision, **kwd ):
+ """Retrieve a specified changectx from a repository."""
+ for changeset in repo.changelog:
+ ctx = repo.changectx( changeset )
+ if str( ctx ) == changeset_revision:
+ return ctx
+ return None
+
+def get_configured_ui():
+ """Configure any desired ui settings."""
+ _ui = ui.ui()
+ # The following will suppress all messages. This is
+ # the same as adding the following setting to the repo
+ # hgrc file' [ui] section:
+ # quiet = True
+ _ui.setconfig( 'ui', 'quiet', True )
+ return _ui
+
+def get_readable_ctx_date( ctx ):
+ """Convert the date of the changeset (the received ctx) to a human-readable date."""
+ t, tz = ctx.date()
+ date = datetime( *gmtime( float( t ) - tz )[ :6 ] )
+ ctx_date = date.strftime( "%Y-%m-%d" )
+ return ctx_date
+
+def get_revision_label( trans, repository, changeset_revision, include_date=True, include_hash=True ):
+ """
+ Return a string consisting of the human read-able changeset rev and the changeset revision string
+ which includes the revision date if the receive include_date is True.
+ """
+ repo = hg.repository( get_configured_ui(), repository.repo_path( trans.app ) )
+ ctx = get_changectx_for_changeset( repo, changeset_revision )
+ if ctx:
+ return get_revision_label_from_ctx( ctx, include_date=include_date, include_hash=include_hash )
+ else:
+ if include_hash:
+ return "-1:%s" % changeset_revision
+ else:
+ return "-1"
+
+def get_rev_label_changeset_revision_from_repository_metadata( trans, repository_metadata, repository=None,
+ include_date=True, include_hash=True ):
+ if repository is None:
+ repository = repository_metadata.repository
+ repo = hg.repository( get_configured_ui(), repository.repo_path( trans.app ) )
+ changeset_revision = repository_metadata.changeset_revision
+ ctx = get_changectx_for_changeset( repo, changeset_revision )
+ if ctx:
+ rev = '%04d' % ctx.rev()
+ if include_date:
+ changeset_revision_date = get_readable_ctx_date( ctx )
+ if include_hash:
+ label = "%s:%s (%s)" % ( str( ctx.rev() ), changeset_revision, changeset_revision_date )
+ else:
+ label = "%s (%s)" % ( str( ctx.rev() ), changeset_revision_date )
+ else:
+ if include_hash:
+ label = "%s:%s" % ( str( ctx.rev() ), changeset_revision )
+ else:
+ label = "%s" % str( ctx.rev() )
+ else:
+ rev = '-1'
+ if include_hash:
+ label = "-1:%s" % changeset_revision
+ else:
+ label = "-1"
+ return rev, label, changeset_revision
+
+def get_revision_label_from_ctx( ctx, include_date=True, include_hash=True ):
+ if include_date:
+ if include_hash:
+ return '%s:%s <i><font color="#666666">(%s)</font></i>' % \
+ ( str( ctx.rev() ), str( ctx ), str( get_readable_ctx_date( ctx ) ) )
+ else:
+ return '%s <i><font color="#666666">(%s)</font></i>' % \
+ ( str( ctx.rev() ), str( get_readable_ctx_date( ctx ) ) )
+ else:
+ if include_hash:
+ return '%s:%s' % ( str( ctx.rev() ), str( ctx ) )
+ else:
+ return '%s' % str( ctx.rev() )
+
+def get_rev_label_from_changeset_revision( repo, changeset_revision, include_date=True, include_hash=True ):
+ """
+ Given a changeset revision hash, return two strings, the changeset rev and the changeset revision hash
+ which includes the revision date if the receive include_date is True.
+ """
+ ctx = get_changectx_for_changeset( repo, changeset_revision )
+ if ctx:
+ rev = '%04d' % ctx.rev()
+ label = get_revision_label_from_ctx( ctx, include_date=include_date )
+ else:
+ rev = '-1'
+ label = "-1:%s" % changeset_revision
+ return rev, label
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/tool_shed/util/import_util.py
--- a/lib/tool_shed/util/import_util.py
+++ b/lib/tool_shed/util/import_util.py
@@ -8,6 +8,7 @@
from galaxy.datatypes import checkers
from tool_shed.util import commit_util
from tool_shed.util import encoding_util
+from tool_shed.util import hg_util
from tool_shed.util import metadata_util
from tool_shed.util import xml_util
import tool_shed.util.shed_util_common as suc
@@ -212,7 +213,7 @@
archive_file_path = os.path.join( file_path, archive_file_name )
archive = tarfile.open( archive_file_path, 'r:*' )
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
undesirable_dirs_removed = 0
undesirable_files_removed = 0
ok, error_message = commit_util.check_archive( repository, archive )
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/tool_shed/util/metadata_util.py
--- a/lib/tool_shed/util/metadata_util.py
+++ b/lib/tool_shed/util/metadata_util.py
@@ -15,6 +15,7 @@
from tool_shed.util import common_util
from tool_shed.util import common_install_util
from tool_shed.util import container_util
+from tool_shed.util import hg_util
from tool_shed.util import readme_util
from tool_shed.util import tool_dependency_util
from tool_shed.util import tool_util
@@ -347,7 +348,7 @@
# changeset revision in the received repository's changelog (up to the received changeset revision) to see if it is contained in the
# skip_tool_test table. If it is, but is not associated with a repository_metadata record, reset that skip_tool_test record to the
# newly created repository_metadata record.
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
for changeset in repo.changelog:
changeset_hash = str( repo.changectx( changeset ) )
skip_tool_test = suc.get_skip_tool_test_by_changeset_revision( trans, changeset_hash )
@@ -1048,7 +1049,7 @@
def get_latest_repository_metadata( trans, decoded_repository_id, downloadable=False ):
"""Get last metadata defined for a specified repository from the database."""
repository = trans.sa_session.query( trans.model.Repository ).get( decoded_repository_id )
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
if downloadable:
changeset_revision = suc.get_latest_downloadable_changeset_revision( trans, repository, repo )
else:
@@ -1121,21 +1122,6 @@
repository_metadata_revisions.append( metadata_revision )
return repository_metadata_revisions
-def get_rev_label_changeset_revision_from_repository_metadata( trans, repository_metadata, repository=None ):
- if repository is None:
- repository = repository_metadata.repository
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
- changeset_revision = repository_metadata.changeset_revision
- ctx = suc.get_changectx_for_changeset( repo, changeset_revision )
- if ctx:
- changeset_revision_date = suc.get_readable_ctx_date( ctx )
- rev = '%04d' % ctx.rev()
- label = "%s:%s (%s)" % ( str( ctx.rev() ), changeset_revision, changeset_revision_date )
- else:
- rev = '-1'
- label = "-1:%s" % changeset_revision
- return rev, label, changeset_revision
-
def get_sample_files_from_disk( repository_files_dir, tool_path=None, relative_install_dir=None,
resetting_all_metadata_on_repository=False ):
if resetting_all_metadata_on_repository:
@@ -1294,7 +1280,7 @@
log.debug( error_message )
is_valid = False
return repository_dependency_tup, is_valid, error_message
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( app ) )
# The received changeset_revision may be None since defining it in the dependency definition is optional.
# If this is the case, the default will be to set it's value to the repository dependency tip revision.
# This probably occurs only when handling circular dependency definitions.
@@ -1360,7 +1346,7 @@
"""
if repository.deleted:
return ( None, False )
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
# Get the latest installable changeset revision since that is all that is currently configured for testing.
latest_installable_changeset_revision = suc.get_latest_downloadable_changeset_revision( trans, repository, repo )
if latest_installable_changeset_revision not in [ None, suc.INITIAL_CHANGELOG_HASH ]:
@@ -1797,7 +1783,7 @@
repository = suc.get_repository_in_tool_shed( trans, id )
log.debug( "Resetting all metadata on repository: %s" % repository.name )
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
repository_clone_url = common_util.generate_clone_url_for_repository_in_tool_shed( trans, repository )
# The list of changeset_revisions refers to repository_metadata records that have been created or updated. When the following loop
# completes, we'll delete all repository_metadata records for this repository that do not have a changeset_revision value in this list.
@@ -1978,7 +1964,7 @@
encoded_id = trans.security.encode_id( repository.id )
repository_clone_url = common_util.generate_clone_url_for_repository_in_tool_shed( trans, repository )
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
metadata_dict, invalid_file_tups = generate_metadata_for_changeset_revision( app=trans.app,
repository=repository,
changeset_revision=repository.tip( trans.app ),
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/tool_shed/util/readme_util.py
--- a/lib/tool_shed/util/readme_util.py
+++ b/lib/tool_shed/util/readme_util.py
@@ -9,6 +9,7 @@
from galaxy.util import unicodify
import tool_shed.util.shed_util_common as suc
from tool_shed.util import common_util
+from tool_shed.util import hg_util
eggs.require( 'mercurial' )
@@ -25,7 +26,7 @@
if trans.webapp.name == 'galaxy':
can_use_disk_files = True
else:
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
latest_downloadable_changeset_revision = suc.get_latest_downloadable_changeset_revision( trans, repository, repo )
can_use_disk_files = changeset_revision == latest_downloadable_changeset_revision
readme_files_dict = {}
@@ -74,7 +75,7 @@
readme_files_dict[ readme_file_name ] = text_of_reasonable_length
else:
# We must be in the tool shed and have an old changeset_revision, so we need to retrieve the file contents from the repository manifest.
- ctx = suc.get_changectx_for_changeset( repo, changeset_revision )
+ ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision )
if ctx:
fctx = suc.get_file_context_from_ctx( ctx, readme_file_name )
if fctx and fctx not in [ 'DELETED' ]:
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/tool_shed/util/repository_dependency_util.py
--- a/lib/tool_shed/util/repository_dependency_util.py
+++ b/lib/tool_shed/util/repository_dependency_util.py
@@ -9,6 +9,7 @@
from tool_shed.util import common_install_util
from tool_shed.util import container_util
from tool_shed.util import encoding_util
+from tool_shed.util import hg_util
from tool_shed.util import metadata_util
from tool_shed.util import tool_util
@@ -532,7 +533,7 @@
else:
# The repository changeset_revision is no longer installable, so see if there's been an update.
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
changeset_revision = suc.get_next_downloadable_changeset_revision( repository, repo, rd_changeset_revision )
repository_metadata = metadata_util.get_repository_metadata_by_repository_id_changeset_revision( trans,
trans.security.encode_id( repository.id ),
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/tool_shed/util/repository_maintenance_util.py
--- a/lib/tool_shed/util/repository_maintenance_util.py
+++ b/lib/tool_shed/util/repository_maintenance_util.py
@@ -3,6 +3,7 @@
import os
import re
import tool_shed.util.shed_util_common as suc
+from tool_shed.util import hg_util
from tool_shed.util import import_util
from galaxy import util
from galaxy.web.form_builder import build_select_field
@@ -47,7 +48,7 @@
# Since we support both http and https, we set push_ssl to False to override the default (which is True) in the mercurial api. The hg
# purge extension purges all files and directories not being tracked by mercurial in the current repository. It'll remove unknown files
# and empty directories. This is not currently used because it is not supported in the mercurial API.
- repo = hg.repository( suc.get_configured_ui(), path=repository.repo_path( trans.app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), path=repository.repo_path( trans.app ) )
fp = repo.opener( 'hgrc', 'wb' )
fp.write( '[paths]\n' )
fp.write( 'default = .\n' )
@@ -83,7 +84,7 @@
if not os.path.exists( repository_path ):
os.makedirs( repository_path )
# Create the local repository.
- repo = hg.repository( suc.get_configured_ui(), repository_path, create=True )
+ repo = hg.repository( hg_util.get_configured_ui(), repository_path, create=True )
# Add an entry in the hgweb.config file for the local repository.
lhs = "repos/%s/%s" % ( repository.user.username, repository.name )
trans.app.hgweb_config_manager.add_entry( lhs, repository_path )
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/tool_shed/util/review_util.py
--- a/lib/tool_shed/util/review_util.py
+++ b/lib/tool_shed/util/review_util.py
@@ -3,6 +3,7 @@
from galaxy import eggs
from galaxy.model.orm import and_
from galaxy.util.odict import odict
+from tool_shed.util import hg_util
import tool_shed.util.shed_util_common as suc
eggs.require( 'mercurial' )
@@ -58,13 +59,13 @@
def get_previous_repository_reviews( trans, repository, changeset_revision ):
"""Return an ordered dictionary of repository reviews up to and including the received changeset revision."""
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
reviewed_revision_hashes = [ review.changeset_revision for review in repository.reviews ]
previous_reviews_dict = odict()
for changeset in suc.reversed_upper_bounded_changelog( repo, changeset_revision ):
previous_changeset_revision = str( repo.changectx( changeset ) )
if previous_changeset_revision in reviewed_revision_hashes:
- previous_rev, previous_changeset_revision_label = suc.get_rev_label_from_changeset_revision( repo, previous_changeset_revision )
+ previous_rev, previous_changeset_revision_label = hg_util.get_rev_label_from_changeset_revision( repo, previous_changeset_revision )
revision_reviews = get_reviews_by_repository_id_changeset_revision( trans,
trans.security.encode_id( repository.id ),
previous_changeset_revision )
@@ -93,7 +94,7 @@
def has_previous_repository_reviews( trans, repository, changeset_revision ):
"""Determine if a repository has a changeset revision review prior to the received changeset revision."""
- repo = hg.repository( suc.get_configured_ui(), repository.repo_path( trans.app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
reviewed_revision_hashes = [ review.changeset_revision for review in repository.reviews ]
for changeset in suc.reversed_upper_bounded_changelog( repo, changeset_revision ):
previous_changeset_revision = str( repo.changectx( changeset ) )
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/tool_shed/util/shed_util_common.py
--- a/lib/tool_shed/util/shed_util_common.py
+++ b/lib/tool_shed/util/shed_util_common.py
@@ -4,9 +4,6 @@
import shutil
import string
import tempfile
-from datetime import datetime
-from time import gmtime
-from time import strftime
from galaxy import util
from galaxy.util import asbool
from galaxy.util import json
@@ -19,6 +16,7 @@
import sqlalchemy.orm.exc
from tool_shed.util import common_util
from tool_shed.util import encoding_util
+from tool_shed.util import hg_util
from tool_shed.util import xml_util
import tool_shed.repository_types.util as rt_util
from xml.etree import ElementTree as XmlET
@@ -143,7 +141,7 @@
def changeset_is_valid( app, repository, changeset_revision ):
"""Make sure a changeset hash is valid for a specified repository."""
- repo = hg.repository( get_configured_ui(), repository.repo_path( app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( app ) )
for changeset in repo.changelog:
changeset_hash = str( repo.changectx( changeset ) )
if changeset_revision == changeset_hash:
@@ -167,7 +165,7 @@
def clone_repository( repository_clone_url, repository_file_dir, ctx_rev ):
"""Clone the repository up to the specified changeset_revision. No subsequent revisions will be present in the cloned repository."""
try:
- commands.clone( get_configured_ui(),
+ commands.clone( hg_util.get_configured_ui(),
str( repository_clone_url ),
dest=str( repository_file_dir ),
pull=True,
@@ -469,14 +467,6 @@
except sqlalchemy.orm.exc.NoResultFound:
return None
-def get_changectx_for_changeset( repo, changeset_revision, **kwd ):
- """Retrieve a specified changectx from a repository."""
- for changeset in repo.changelog:
- ctx = repo.changectx( changeset )
- if str( ctx ) == changeset_revision:
- return ctx
- return None
-
def get_config( config_file, repo, ctx, dir ):
"""Return the latest version of config_filename from the repository manifest."""
config_file = strip_path( config_file )
@@ -496,16 +486,6 @@
return os.path.abspath( os.path.join( root, name ) )
return None
-def get_configured_ui():
- """Configure any desired ui settings."""
- _ui = ui.ui()
- # The following will suppress all messages. This is
- # the same as adding the following setting to the repo
- # hgrc file' [ui] section:
- # quiet = True
- _ui.setconfig( 'ui', 'quiet', True )
- return _ui
-
def get_ctx_rev( app, tool_shed_url, name, owner, changeset_revision ):
"""
Send a request to the tool shed to retrieve the ctx_rev for a repository defined by the
@@ -539,7 +519,7 @@
if repository_metadata:
return repository_metadata
# The installable changeset_revision may have been changed because it was "moved ahead" in the repository changelog.
- repo = hg.repository( get_configured_ui(), repository.repo_path( trans.app ) )
+ repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
updated_changeset_revision = get_next_downloadable_changeset_revision( repository, repo, after_changeset_revision=changeset_revision )
if updated_changeset_revision:
repository_metadata = get_repository_metadata_by_changeset_revision( trans, encoded_repository_id, updated_changeset_revision )
@@ -590,7 +570,7 @@
# record, so updates must be necessary.
defined_repository = get_repository_by_name_and_owner( trans.app, name, owner )
defined_repo_dir = defined_repository.repo_path( trans.app )
- defined_repo = hg.repository( get_configured_ui(), defined_repo_dir )
+ defined_repo = hg.repository( hg_util.get_configured_ui(), defined_repo_dir )
updated_changeset_revision = \
get_next_downloadable_changeset_revision( defined_repository,
defined_repo,
@@ -799,7 +779,7 @@
changeset_tups = []
for repository_metadata in metadata_revisions:
changeset_revision = repository_metadata.changeset_revision
- ctx = get_changectx_for_changeset( repo, changeset_revision )
+ ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision )
if ctx:
rev = '%04d' % ctx.rev()
else:
@@ -913,13 +893,6 @@
return trans.install_model.context.query( trans.install_model.ToolShedRepository ) \
.filter( trans.install_model.ToolShedRepository.table.c.uninstalled == False )
-def get_readable_ctx_date( ctx ):
- """Convert the date of the changeset (the received ctx) to a human-readable date."""
- t, tz = ctx.date()
- date = datetime( *gmtime( float( t ) - tz )[ :6 ] )
- ctx_date = date.strftime( "%Y-%m-%d" )
- return ctx_date
-
def get_repo_info_tuple_contents( repo_info_tuple ):
"""Take care in handling the repo_info_tuple as it evolves over time as new tool shed features are introduced."""
if len( repo_info_tuple ) == 6:
@@ -1211,38 +1184,6 @@
reversed_changelog.insert( 0, changeset )
return reversed_changelog
-def get_revision_label( trans, repository, changeset_revision, include_date=True ):
- """
- Return a string consisting of the human read-able changeset rev and the changeset revision string
- which includes the revision date if the receive include_date is True.
- """
- repo = hg.repository( get_configured_ui(), repository.repo_path( trans.app ) )
- ctx = get_changectx_for_changeset( repo, changeset_revision )
- if ctx:
- return get_revision_label_from_ctx( ctx, include_date=include_date )
- else:
- return "-1:%s" % changeset_revision
-
-def get_revision_label_from_ctx( ctx, include_date=True ):
- if include_date:
- return '%s:%s <i><font color="#666666">(%s)</font></i>' % \
- ( str( ctx.rev() ), str( ctx ), str( get_readable_ctx_date( ctx ) ) )
- return '%s:%s' % ( str( ctx.rev() ), str( ctx ) )
-
-def get_rev_label_from_changeset_revision( repo, changeset_revision, include_date=True ):
- """
- Given a changeset revision hash, return two strings, the changeset rev and the changeset revision hash
- which includes the revision date if the receive include_date is True.
- """
- ctx = get_changectx_for_changeset( repo, changeset_revision )
- if ctx:
- rev = '%04d' % ctx.rev()
- label = get_revision_label_from_ctx( ctx, include_date=include_date )
- else:
- rev = '-1'
- label = "-1:%s" % changeset_revision
- return rev, label
-
def get_shed_tool_conf_dict( app, shed_tool_conf ):
"""Return the in-memory version of the shed_tool_conf file, which is stored in the config_elems entry in the shed_tool_conf_dict associated with the file."""
for index, shed_tool_conf_dict in enumerate( app.toolbox.shed_tool_confs ):
@@ -1434,7 +1375,7 @@
"""
repository = get_repository_by_name_and_owner( trans.app, name, owner )
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
# Get the upper bound changeset revision.
upper_bound_changeset_revision = get_next_downloadable_changeset_revision( repository, repo, changeset_revision )
# Build the list of changeset revision hashes defining each available update up to, but excluding, upper_bound_changeset_revision.
@@ -1487,7 +1428,7 @@
that was included in the change set.
"""
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
sharable_link = generate_sharable_link_for_repository_in_tool_shed( trans, repository, changeset_revision=None )
smtp_server = trans.app.config.smtp_server
if smtp_server and ( new_repo_alert or repository.email_alerts ):
@@ -1510,7 +1451,7 @@
template = new_repo_email_alert_template
else:
template = email_alert_template
- display_date = get_readable_ctx_date( ctx )
+ display_date = hg_util.get_readable_ctx_date( ctx )
admin_body = string.Template( template ).safe_substitute( host=trans.request.host,
sharable_link=sharable_link,
repository_name=repository.name,
@@ -1859,7 +1800,7 @@
# I = ignored
# It would be nice if we could use mercurial's purge extension to remove untracked files. The problem is that
# purging is not supported by the mercurial API.
- commands.update( get_configured_ui(), repo, rev=ctx_rev )
+ commands.update( hg_util.get_configured_ui(), repo, rev=ctx_rev )
def update_tool_shed_repository_status( app, tool_shed_repository, status, error_message=None ):
"""Update the status of a tool shed repository in the process of being installed into Galaxy."""
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 lib/tool_shed/util/tool_util.py
--- a/lib/tool_shed/util/tool_util.py
+++ b/lib/tool_shed/util/tool_util.py
@@ -15,6 +15,7 @@
from galaxy.web.form_builder import SelectField
from galaxy.tools.actions.upload import UploadToolAction
from tool_shed.util import common_util
+from tool_shed.util import hg_util
from tool_shed.util import xml_util
import tool_shed.util.shed_util_common as suc
from xml.etree import ElementTree as XmlET
@@ -538,7 +539,7 @@
"""
repository = suc.get_repository_by_id( trans, repository_id )
repo_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
# Initialize the tool lineage
version_lineage = [ guid ]
# Get all ancestor guids of the received guid.
@@ -637,7 +638,7 @@
def handle_sample_files_and_load_tool_from_tmp_config( trans, repo, repository_id, changeset_revision, tool_config_filename, work_dir ):
tool = None
message = ''
- ctx = suc.get_changectx_for_changeset( repo, changeset_revision )
+ ctx = hg_util.get_changectx_for_changeset( repo, changeset_revision )
# We're not currently doing anything with the returned list of deleted_sample_files here. It is intended to help handle sample files that are in
# the manifest, but have been deleted from disk.
sample_files, deleted_sample_files = get_list_of_copied_sample_files( repo, ctx, dir=work_dir )
@@ -866,7 +867,7 @@
original_tool_data_path = trans.app.config.tool_data_path
repository = suc.get_repository_in_tool_shed( trans, repository_id )
repo_files_dir = repository.repo_path( trans.app )
- repo = hg.repository( suc.get_configured_ui(), repo_files_dir )
+ repo = hg.repository( hg_util.get_configured_ui(), repo_files_dir )
message = ''
tool = None
can_use_disk_file = False
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 templates/webapps/tool_shed/common/common.mako
--- a/templates/webapps/tool_shed/common/common.mako
+++ b/templates/webapps/tool_shed/common/common.mako
@@ -107,7 +107,7 @@
<%def name="render_multiple_heads_message( heads )"><div class="warningmessage"><%
- from tool_shed.util.shed_util_common import get_revision_label_from_ctx
+ from tool_shed.util.hg_util import get_revision_label_from_ctx
heads_str = ''
for ctx in heads:
heads_str += '%s<br/>' % get_revision_label_from_ctx( ctx, include_date=True )
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 templates/webapps/tool_shed/repository/view_changeset.mako
--- a/templates/webapps/tool_shed/repository/view_changeset.mako
+++ b/templates/webapps/tool_shed/repository/view_changeset.mako
@@ -49,7 +49,7 @@
%endif
<div class="toolForm"><%
- from tool_shed.util.shed_util_common import get_readable_ctx_date
+ from tool_shed.util.hg_util import get_readable_ctx_date
changeset_revision_date = get_readable_ctx_date( ctx )
if can_download:
title_str = 'Changeset <b>%s:%s</b><i>(%s)</i>' % ( ctx.rev(), ctx, changeset_revision_date )
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 test/tool_shed/base/twilltestcase.py
--- a/test/tool_shed/base/twilltestcase.py
+++ b/test/tool_shed/base/twilltestcase.py
@@ -1418,10 +1418,10 @@
def verify_repository_reviews( self, repository, reviewer=None, strings_displayed=[], strings_not_displayed=[] ):
changeset_revision = self.get_repository_tip( repository )
# Verify that the currently logged in user has a repository review for the specified repository, reviewer, and changeset revision.
- strings_displayed=[ repository.name, reviewer.username, changeset_revision ]
+ strings_displayed=[ repository.name, reviewer.username ]
self.display_reviewed_repositories_owned_by_user( strings_displayed=strings_displayed )
# Verify that the reviewer has reviewed the specified repository's changeset revision.
- strings_displayed=[ repository.name, repository.description, changeset_revision ]
+ strings_displayed=[ repository.name, repository.description ]
self.display_repository_reviews_by_user( reviewer, strings_displayed=strings_displayed )
# Load the review and check for the components passed in strings_displayed.
review = test_db_util.get_repository_review_by_user_id_changeset_revision( reviewer.id, repository.id, changeset_revision )
diff -r 452af6869205b773d42f6e49197fbbe413947eca -r e20408b06d65f4902017bdca1cbc08bc1ec0fdd1 test/tool_shed/functional/test_0420_citable_urls_for_repositories.py
--- a/test/tool_shed/functional/test_0420_citable_urls_for_repositories.py
+++ b/test/tool_shed/functional/test_0420_citable_urls_for_repositories.py
@@ -104,7 +104,6 @@
strings_displayed = [ '/repository/browse_repositories', encoded_user_id, 'operation=repositories_by_user' ]
strings_displayed.append( encoded_user_id )
strings_displayed_in_iframe = [ 'user1', 'filtering_0420', 'Galaxy filtering tool for test 0420' ]
- strings_displayed_in_iframe.append( self.get_repository_tip( repository ) )
self.load_citable_url( username='user1',
repository_name=None,
changeset_revision=None,
@@ -208,7 +207,6 @@
strings_displayed.extend( [ 'list+of+repositories+owned', 'does+not+include+one+named', '%21%21invalid%21%21', 'status=error' ] )
strings_displayed_in_iframe = [ 'user1', 'filtering_0420' ]
strings_displayed_in_iframe.append( 'Repositories Owned by user1' )
- strings_displayed_in_iframe.append( tip_revision )
self.load_citable_url( username='user1',
repository_name='!!invalid!!',
changeset_revision=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
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/9854b48f8902/
Changeset: 9854b48f8902
Branch: next-stable
User: dan
Date: 2014-04-10 22:48:07
Summary: Fix for route used in displaying images on tool installed from a toolshed.
Affected #: 1 file
diff -r 5b01864ad7902af1174478a9f440cad26927f178 -r 9854b48f89026970f99b004d465ffa63aad54aad lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -284,7 +284,7 @@
# ====================
# Handle displaying tool help images and README file images contained in repositories installed from the tool shed.
- webapp.add_route( '/admin_toolshed/static/images/:repository_id/:image_file',
+ webapp.add_route( '/admin_toolshed/static/images/:repository_id/{image_file:.+?}',
controller='admin_toolshed',
action='display_image_in_repository',
repository_id=None,
https://bitbucket.org/galaxy/galaxy-central/commits/452af6869205/
Changeset: 452af6869205
User: dan
Date: 2014-04-10 22:48:31
Summary: merge next-stable
Affected #: 1 file
diff -r d46493c6d83c13db73209373d2fcaf46e843f4b3 -r 452af6869205b773d42f6e49197fbbe413947eca lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -284,7 +284,7 @@
# ====================
# Handle displaying tool help images and README file images contained in repositories installed from the tool shed.
- webapp.add_route( '/admin_toolshed/static/images/:repository_id/:image_file',
+ webapp.add_route( '/admin_toolshed/static/images/:repository_id/{image_file:.+?}',
controller='admin_toolshed',
action='display_image_in_repository',
repository_id=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: martenson: history API: allow anon users import public datasets into their (only) history, add exception for unknown datatype
by commits-noreply@bitbucket.org 10 Apr '14
by commits-noreply@bitbucket.org 10 Apr '14
10 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/d46493c6d83c/
Changeset: d46493c6d83c
User: martenson
Date: 2014-04-10 22:45:59
Summary: history API: allow anon users import public datasets into their (only) history, add exception for unknown datatype
library API: don't show folders without single accesible item to anonyms
Affected #: 5 files
diff -r 12e6db99d15193b700cbde74f31c71a2ef9bcc2d -r d46493c6d83c13db73209373d2fcaf46e843f4b3 lib/galaxy/exceptions/__init__.py
--- a/lib/galaxy/exceptions/__init__.py
+++ b/lib/galaxy/exceptions/__init__.py
@@ -60,6 +60,10 @@
status_code = 400
err_code = error_codes.MALFORMED_ID
+class UnknownContentsType( MessageException ):
+ status_code = 400
+ err_code = error_codes.UNKNOWN_CONTENTS_TYPE
+
class RequestParameterMissingException( MessageException ):
status_code = 400
err_code = error_codes.USER_REQUEST_MISSING_PARAMETER
diff -r 12e6db99d15193b700cbde74f31c71a2ef9bcc2d -r d46493c6d83c13db73209373d2fcaf46e843f4b3 lib/galaxy/exceptions/error_codes.json
--- a/lib/galaxy/exceptions/error_codes.json
+++ b/lib/galaxy/exceptions/error_codes.json
@@ -50,6 +50,11 @@
"message": "The id of the resource is malformed."
},
{
+ "name": "UNKNOWN_CONTENTS_TYPE",
+ "code": 400010,
+ "message": "The request contains unknown type of contents."
+ },
+ {
"name": "USER_NO_API_KEY",
"code": 403001,
"message": "API authentication required for this request"
diff -r 12e6db99d15193b700cbde74f31c71a2ef9bcc2d -r d46493c6d83c13db73209373d2fcaf46e843f4b3 lib/galaxy/webapps/galaxy/api/folder_contents.py
--- a/lib/galaxy/webapps/galaxy/api/folder_contents.py
+++ b/lib/galaxy/webapps/galaxy/api/folder_contents.py
@@ -86,40 +86,40 @@
# Return the reversed path so it starts with the library node.
full_path = build_path( folder )[::-1]
-
folder_contents = []
time_updated = ''
time_created = ''
- # Go through every item in the folder and include its meta-data.
+ # Go through every accessible item in the folder and include its meta-data.
for content_item in self._load_folder_contents( trans, folder ):
- return_item = {}
- encoded_id = trans.security.encode_id( content_item.id )
- time_updated = content_item.update_time.strftime( "%Y-%m-%d %I:%M %p" )
- time_created = content_item.create_time.strftime( "%Y-%m-%d %I:%M %p" )
-
- # For folder return also hierarchy values
- if content_item.api_type == 'folder':
- encoded_id = 'F' + encoded_id
- return_item.update ( dict ( item_count = content_item.item_count ) )
+ if trans.app.security_agent.can_access_library_item( current_user_roles, content_item, trans.user ):
+ return_item = {}
+ encoded_id = trans.security.encode_id( content_item.id )
+ time_updated = content_item.update_time.strftime( "%Y-%m-%d %I:%M %p" )
+ time_created = content_item.create_time.strftime( "%Y-%m-%d %I:%M %p" )
- if content_item.api_type == 'file':
- library_dataset_dict = content_item.to_dict()
- library_dataset_dict['data_type']
- library_dataset_dict['file_size']
- library_dataset_dict['date_uploaded']
- return_item.update ( dict ( data_type = library_dataset_dict['data_type'],
- file_size = library_dataset_dict['file_size'],
- date_uploaded = library_dataset_dict['date_uploaded'] ) )
+ # For folder return also hierarchy values
+ if content_item.api_type == 'folder':
+ encoded_id = 'F' + encoded_id
+ return_item.update ( dict ( item_count = content_item.item_count ) )
- # For every item return also the default meta-data
- return_item.update( dict( id = encoded_id,
- type = content_item.api_type,
- name = content_item.name,
- time_updated = time_updated,
- time_created = time_created
- ) )
- folder_contents.append( return_item )
+ if content_item.api_type == 'file':
+ library_dataset_dict = content_item.to_dict()
+ library_dataset_dict['data_type']
+ library_dataset_dict['file_size']
+ library_dataset_dict['date_uploaded']
+ return_item.update ( dict ( data_type = library_dataset_dict['data_type'],
+ file_size = library_dataset_dict['file_size'],
+ date_uploaded = library_dataset_dict['date_uploaded'] ) )
+
+ # For every item return also the default meta-data
+ return_item.update( dict( id = encoded_id,
+ type = content_item.api_type,
+ name = content_item.name,
+ time_updated = time_updated,
+ time_created = time_created
+ ) )
+ folder_contents.append( return_item )
return { 'metadata' : { 'full_path' : full_path, 'can_add_library_item': can_add_library_item }, 'folder_contents' : folder_contents }
diff -r 12e6db99d15193b700cbde74f31c71a2ef9bcc2d -r d46493c6d83c13db73209373d2fcaf46e843f4b3 lib/galaxy/webapps/galaxy/api/history_contents.py
--- a/lib/galaxy/webapps/galaxy/api/history_contents.py
+++ b/lib/galaxy/webapps/galaxy/api/history_contents.py
@@ -190,8 +190,7 @@
hda_dict[ 'display_apps' ] = self.get_display_apps( trans, hda )
return hda_dict
- #TODO: allow anon users to copy hdas, ldas
- @expose_api
+ @expose_api_anonymous
def create( self, trans, history_id, payload, **kwd ):
"""
create( self, trans, history_id, payload, **kwd )
@@ -436,10 +435,7 @@
return validated_payload
def __handle_unknown_contents_type( self, trans, contents_type ):
- # TODO: raise a message exception instead of setting status and returning dict.
- trans.response.status = 400
- return { 'error': 'Unknown contents type %s' % type }
-
+ raise exceptions.UnknownContentsType('Unknown contents type: %s' % type)
class HDAManager( object ):
diff -r 12e6db99d15193b700cbde74f31c71a2ef9bcc2d -r d46493c6d83c13db73209373d2fcaf46e843f4b3 lib/galaxy/webapps/galaxy/api/lda_datasets.py
--- a/lib/galaxy/webapps/galaxy/api/lda_datasets.py
+++ b/lib/galaxy/webapps/galaxy/api/lda_datasets.py
@@ -12,9 +12,13 @@
import urllib
import urllib2
import zipfile
-from paste.httpexceptions import HTTPBadRequest
-from galaxy import util, web
-from galaxy.exceptions import ItemAccessibilityException, MessageException, ItemDeletionException, ObjectNotFound
+from galaxy import exceptions
+from galaxy.web import _future_expose_api as expose_api
+from galaxy.web import _future_expose_api_anonymous as expose_api_anonymous
+# from paste.httpexceptions import HTTPBadRequest
+from galaxy import util
+from galaxy import web
+# from galaxy.exceptions import ItemAccessibilityException, MessageException, ItemDeletionException, ObjectNotFound
from galaxy.security import Action
from galaxy.util.streamball import StreamBall
from galaxy.web.base.controller import BaseAPIController, UsesVisualizationMixin
@@ -24,7 +28,7 @@
class LibraryDatasetsController( BaseAPIController, UsesVisualizationMixin ):
- @web.expose_api
+ @expose_api_anonymous
def show( self, trans, id, **kwd ):
"""
show( self, trans, id, **kwd )
@@ -41,19 +45,20 @@
try:
dataset = self.get_library_dataset( trans, id = id, check_ownership=False, check_accessible=True )
except Exception, e:
- trans.response.status = 500
- return str( e )
- try:
- rval = dataset.to_dict()
- except Exception, e:
- rval = "Error in dataset API at listing contents: " + str( e )
- log.error( rval + ": %s" % str(e), exc_info=True )
- trans.response.status = 500
- return "Error in dataset API at listing contents: " + str( e )
+ raise exceptions.ObjectNotFound( 'Requested dataset was not found.' )
+ # trans.response.status = 500
+ # return str( e )
+ # try:
+ rval = dataset.to_dict()
+ # except Exception, e:
+ # rval = "Error in dataset API at listing contents: " + str( e )
+ # log.error( rval + ": %s" % str(e), exc_info=True )
+ # trans.response.status = 500
+ # return "Error in dataset API at listing contents: " + str( e )
rval['id'] = trans.security.encode_id(rval['id']);
rval['ldda_id'] = trans.security.encode_id(rval['ldda_id']);
- rval['folder_id'] = 'f' + trans.security.encode_id(rval['folder_id'])
+ rval['folder_id'] = 'F' + trans.security.encode_id(rval['folder_id'])
return rval
@web.expose
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: Metrics: initial commit of client side logger
by commits-noreply@bitbucket.org 10 Apr '14
by commits-noreply@bitbucket.org 10 Apr '14
10 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/12e6db99d151/
Changeset: 12e6db99d151
User: carlfeberhard
Date: 2014-04-10 22:28:16
Summary: Metrics: initial commit of client side logger
Affected #: 4 files
diff -r acec53247232cffb773b2e4a8de67fd3bdc3424e -r 12e6db99d15193b700cbde74f31c71a2ef9bcc2d static/scripts/packed/galaxy.workflow_editor.canvas.js
--- a/static/scripts/packed/galaxy.workflow_editor.canvas.js
+++ b/static/scripts/packed/galaxy.workflow_editor.canvas.js
@@ -1,1 +1,1 @@
-function Terminal(a){this.element=a;this.connectors=[]}$.extend(Terminal.prototype,{connect:function(a){this.connectors.push(a);if(this.node){this.node.changed()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.changed()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})}});function OutputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}OutputTerminal.prototype=new Terminal();function InputTerminal(b,c,a){Terminal.call(this,b);this.datatypes=c;this.multiple=a}InputTerminal.prototype=new Terminal();$.extend(InputTerminal.prototype,{can_accept:function(a){if(this.connectors.length<1||this.multiple){for(var c in this.datatypes){var f=new Array();f=f.concat(a.datatypes);if(a.node.post_job_actions){for(var d in a.node.post_job_actions){var g=a.node.post_job_actions[d];if(g.action_type=="ChangeDatatypeAction"&&(g.output_name==""||g.output_name==a.name)&&g.action_arguments){f.push(g.action_arguments.newtype)}}}for(var b in f){if(f[b]=="input"||issubtype(f[b],this.datatypes[c])){return true}}}}return false}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a){this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;if(this.handle1){this.handle1.connect(this)}this.handle2=a;if(this.handle2){this.handle2.connect(this)}},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},redraw:function(){var d=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}d.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var n=function(c){return $(c).offset().left-d.offset().left};var i=function(c){return $(c).offset().top-d.offset().top};if(!this.handle1||!this.handle2){return}var h=n(this.handle1.element)+5;var g=i(this.handle1.element)+5;var p=n(this.handle2.element)+5;var m=i(this.handle2.element)+5;var f=100;var k=Math.min(h,p);var a=Math.max(h,p);var j=Math.min(g,m);var t=Math.max(g,m);var b=Math.min(Math.max(Math.abs(t-j)/2,100),300);var o=k-f;var s=j-f;var q=a-k+2*f;var l=t-j+2*f;this.canvas.style.left=o+"px";this.canvas.style.top=s+"px";this.canvas.setAttribute("width",q);this.canvas.setAttribute("height",l);h-=o;g-=s;p-=o;m-=s;var r=this.canvas.getContext("2d");r.lineCap="round";r.strokeStyle=this.outer_color;r.lineWidth=7;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke();r.strokeStyle=this.inner_color;r.lineWidth=5;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke()}});function Node(a){this.element=a;this.input_terminals={};this.output_terminals={};this.tool_errors={}}$.extend(Node.prototype,{new_input_terminal:function(a){var b=$("<div class='terminal input-terminal'></div>");this.enable_input_terminal(b,a.name,a.extensions,a.multiple);return b},enable_input_terminal:function(f,b,c,a){var d=this;$(f).each(function(){var g=this.terminal=new InputTerminal(this,c,a);g.node=d;g.name=b;$(this).bind("dropinit",function(h,i){return $(i.drag).hasClass("output-terminal")&&g.can_accept(i.drag.terminal)}).bind("dropstart",function(h,i){if(i.proxy.terminal){i.proxy.terminal.connectors[0].inner_color="#BBFFBB"}}).bind("dropend",function(h,i){if(i.proxy.terminal){i.proxy.terminal.connectors[0].inner_color="#FFFFFF"}}).bind("drop",function(h,i){(new Connector(i.drag.terminal,g)).redraw()}).bind("hover",function(){if(g.connectors.length>0){var h=$("<div class='callout'></div>").css({display:"none"}).appendTo("body").append($("<div class='button'></div>").append($("<div/>").addClass("fa-icon-button fa fa-times").click(function(){$.each(g.connectors,function(j,i){if(i){i.destroy()}});h.remove()}))).bind("mouseleave",function(){$(this).remove()});h.css({top:$(this).offset().top-2,left:$(this).offset().left-h.width(),"padding-right":$(this).width()}).show()}});d.input_terminals[b]=g})},enable_output_terminal:function(d,a,b){var c=this;$(d).each(function(){var g=this;var f=this.terminal=new OutputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dragstart",function(j,k){$(k.available).addClass("input-terminal-active");workflow.check_changes_in_active_form();var i=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);i.terminal=new OutputTerminal(i);var l=new Connector();l.dragging=true;l.connect(this.terminal,i.terminal);return i}).bind("drag",function(i,j){var h=function(){var l=$(j.proxy).offsetParent().offset(),k=j.offsetX-l.left,m=j.offsetY-l.top;$(j.proxy).css({left:k,top:m});j.proxy.terminal.redraw();canvas_manager.update_viewport_overlay()};h();$("#canvas-container").get(0).scroll_panel.test(i,h)}).bind("dragend",function(h,i){i.proxy.terminal.connectors[0].destroy();$(i.proxy).remove();$(i.available).removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()});c.output_terminals[a]=f})},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b.appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(h){var g=this.element;if(h.type){this.type=h.type}this.name=h.name;this.form_html=h.form_html;this.tool_state=h.tool_state;this.tool_errors=h.tool_errors;this.tooltip=h.tooltip?h.tooltip:"";this.annotation=h.annotation;this.post_job_actions=h.post_job_actions?h.post_job_actions:{};this.workflow_outputs=h.workflow_outputs?h.workflow_outputs:[];if(this.tool_errors){g.addClass("tool-node-error")}else{g.removeClass("tool-node-error")}var d=this;var c=Math.max(150,g.width());var a=g.find(".toolFormBody");a.find("div").remove();var i=$("<div class='inputs'></div>").appendTo(a);$.each(h.data_inputs,function(k,f){var j=d.new_input_terminal(f);var b=$("<div class='form-row dataRow input-data-row' name='"+f.name+"'>"+f.label+"</div>");b.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(b);c=Math.max(c,b.outerWidth());b.css({position:"",left:"",top:"",display:""});b.remove();i.append(b.prepend(j))});if((h.data_inputs.length>0)&&(h.data_outputs.length>0)){a.append($("<div class='rule'></div>"))}$.each(h.data_outputs,function(k,b){var j=$("<div class='terminal output-terminal'></div>");d.enable_output_terminal(j,b.name,b.extensions);var f=b.name;if(b.extensions.indexOf("input")<0){f=f+" ("+b.extensions.join(", ")+")"}var m=$("<div class='form-row dataRow'>"+f+"</div>");if(d.type=="tool"){var l=$("<div class='callout "+f+"'></div>").css({display:"none"}).append($("<div class='buttons'></div>").append($("<img/>").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png").click(function(){if($.inArray(b.name,d.workflow_outputs)!=-1){d.workflow_outputs.splice($.inArray(b.name,d.workflow_outputs),1);l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{d.workflow_outputs.push(b.name);l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}workflow.has_changes=true;canvas_manager.draw_overview()}))).tooltip({delay:500,title:"Mark dataset as a workflow output. All unmarked datasets will be hidden."});l.css({top:"50%",margin:"-8px 0px 0px 0px",right:8});l.show();m.append(l);if($.inArray(b.name,d.workflow_outputs)===-1){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}m.hover(function(){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-yellow.png")},function(){if($.inArray(b.name,d.workflow_outputs)===-1){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}})}m.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(m);c=Math.max(c,m.outerWidth()+17);m.css({position:"",left:"",top:"",display:""});m.detach();a.append(m.append(j))});g.css("width",Math.min(250,Math.max(g.width(),c)));workflow.node_changed(this)},update_field_data:function(f){var c=$(this.element),d=this;this.tool_state=f.tool_state;this.form_html=f.form_html;this.tool_errors=f.tool_errors;this.annotation=f.annotation;var g=$.parseJSON(f.post_job_actions);this.post_job_actions=g?g:{};if(this.tool_errors){c.addClass("tool-node-error")}else{c.removeClass("tool-node-error")}var h=c.find("div.inputs");var b=$("<div class='inputs'></div>");var a=h.find("div.input-data-row");$.each(f.data_inputs,function(l,j){var k=d.new_input_terminal(j);h.find("div[name='"+j.name+"']").each(function(){$(this).find(".input-terminal").each(function(){var i=this.terminal.connectors[0];if(i){k[0].terminal.connectors[0]=i;i.handle2=k[0].terminal}});$(this).remove()});b.append($("<div class='form-row dataRow input-data-row' name='"+j.name+"'>"+j.label+"</div>").prepend(k))});h.replaceWith(b);h.find("div.input-data-row > .terminal").each(function(){this.terminal.destroy()});this.changed();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="<div style='color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},changed:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;this.active_form_has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this.nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},rectify_workflow_outputs:function(){var b=false;var a=false;$.each(this.nodes,function(c,d){if(d.workflow_outputs&&d.workflow_outputs.length>0){b=true}$.each(d.post_job_actions,function(g,f){if(f.action_type==="HideDatasetAction"){a=true}})});if(b!==false||a!==false){$.each(this.nodes,function(c,g){if(g.type==="tool"){var f=false;if(g.post_job_actions==null){g.post_job_actions={};f=true}var d=[];$.each(g.post_job_actions,function(i,h){if(h.action_type=="HideDatasetAction"){d.push(i)}});if(d.length>0){$.each(d,function(h,j){f=true;delete g.post_job_actions[j]})}if(b){$.each(g.output_terminals,function(i,j){var h=true;$.each(g.workflow_outputs,function(l,m){if(j.name===m){h=false}});if(h===true){f=true;var k={action_type:"HideDatasetAction",output_name:j.name,action_arguments:{}};g.post_job_actions["HideDatasetAction"+j.name]=null;g.post_job_actions["HideDatasetAction"+j.name]=k}})}if(workflow.active_node==g&&f===true){workflow.reload_active_node()}}})}},to_simple:function(){var a={};$.each(this.nodes,function(c,f){var g={};$.each(f.input_terminals,function(i,j){g[j.name]=null;var h=[];$.each(j.connectors,function(k,l){h[k]={id:l.handle1.node.id,output_name:l.handle1.name};g[j.name]=h})});var b={};if(f.post_job_actions){$.each(f.post_job_actions,function(j,h){var k={action_type:h.action_type,output_name:h.output_name,action_arguments:h.action_arguments};b[h.action_type+h.output_name]=null;b[h.action_type+h.output_name]=k})}if(!f.workflow_outputs){f.workflow_outputs=[]}var d={id:f.id,type:f.type,tool_id:f.tool_id,tool_state:f.tool_state,tool_errors:f.tool_errors,input_connections:g,position:$(f.element).position(),annotation:f.annotation,post_job_actions:f.post_job_actions,workflow_outputs:f.workflow_outputs};a[f.id]=d});return{steps:a}},from_simple:function(b){wf=this;var c=0;wf.name=b.name;var a=false;$.each(b.steps,function(g,f){var d=prebuild_node(f.type,f.name,f.tool_id);d.init_field_data(f);if(f.position){d.element.css({top:f.position.top,left:f.position.left})}d.id=f.id;wf.nodes[d.id]=d;c=Math.max(c,parseInt(g));if(!a&&d.type==="tool"){if(d.workflow_outputs.length>0){a=true}else{$.each(d.post_job_actions,function(i,h){if(h.action_type==="HideDatasetAction"){a=true}})}}});wf.id_counter=c+1;$.each(b.steps,function(g,f){var d=wf.nodes[g];$.each(f.input_connections,function(i,h){if(h){if(!$.isArray(h)){h=[h]}$.each(h,function(k,j){var m=wf.nodes[j.id];var n=new Connector();n.connect(m.output_terminals[j.output_name],d.input_terminals[i]);n.redraw()})}});if(a&&d.type==="tool"){$.each(d.output_terminals,function(h,i){if(d.post_job_actions["HideDatasetAction"+i.name]===undefined){d.workflow_outputs.push(i.name);callout=$(d.element).find(".callout."+i.name);callout.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png");workflow.has_changes=true}})}})},check_changes_in_active_form:function(){if(this.active_form_has_changes){this.has_changes=true;$("#right-content").find("form").submit();this.active_form_has_changes=false}},reload_active_node:function(){if(this.active_node){var a=this.active_node;this.clear_active_node();this.activate_node(a)}},clear_active_node:function(){if(this.active_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("<div>No node selected</div>")},activate_node:function(a){if(this.active_node!=a){this.check_changes_in_active_form();this.clear_active_node();parent.show_form_for_tool(a.form_html+a.tooltip,a);a.make_active();this.active_node=a}},node_changed:function(a){this.has_changes=true;if(this.active_node==a){this.check_changes_in_active_form();parent.show_form_for_tool(a.form_html+a.tooltip,a)}},layout:function(){this.check_changes_in_active_form();this.has_changes=true;var i={};var b={};$.each(this.nodes,function(l,k){if(i[l]===undefined){i[l]=0}if(b[l]===undefined){b[l]=[]}});$.each(this.nodes,function(l,k){$.each(k.input_terminals,function(m,n){$.each(n.connectors,function(p,q){var o=q.handle1.node;i[k.id]+=1;b[o.id].push(k.id)})})});node_ids_by_level=[];while(true){level_parents=[];for(var a in i){if(i[a]==0){level_parents.push(a)}}if(level_parents.length==0){break}node_ids_by_level.push(level_parents);for(var f in level_parents){var j=level_parents[f];delete i[j];for(var g in b[j]){i[b[j][g]]-=1}}}if(i.length){return}var d=this.nodes;var h=80;v_pad=30;var c=h;$.each(node_ids_by_level,function(k,l){l.sort(function(p,o){return $(d[p].element).position().top-$(d[o].element).position().top});var m=0;var n=v_pad;$.each(l,function(o,r){var q=d[r];var p=$(q.element);$(p).css({top:n,left:c});m=Math.max(m,$(p).width());n+=$(p).height()+v_pad});c+=m+h});$.each(d,function(k,l){l.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(h,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var i=this.canvas_container.parent();var d=fix_delta(a.xmin,100);var h=fix_delta(a.ymin,100);d=Math.max(d,f.left);h=Math.max(h,f.top);var c=f.left-d;var g=f.top-h;var b=round_up(a.xmax+100,100)+d;var j=round_up(a.ymax+100,100)+h;b=Math.max(b,-c+i.width());j=Math.max(j,-g+i.height());this.canvas_container.css({left:c,top:g,width:b,height:j});this.canvas_container.children().each(function(){var k=$(this).position();$(this).css("left",k.left+d);$(this).css("top",k.top+h)})}});function fix_delta(a,b){if(a<b||a>3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(l,j,r){var i=$("<div class='toolForm toolFormInCanvas'></div>");var g=new Node(i);g.type=l;if(l=="tool"){g.tool_id=r}var n=$("<div class='toolFormTitle unselectable'>"+j+"</div>");i.append(n);i.css("left",$(window).scrollLeft()+20);i.css("top",$(window).scrollTop()+20);var m=$("<div class='toolFormBody'></div>");var h="<div><img height='16' align='middle' src='"+galaxy_config.root+"static/images/loading_small_white_bg.gif'/> loading tool info...</div>";m.append(h);g.form_html=h;i.append(m);var k=$("<div class='buttons' style='float: right;'></div>");k.append($("<div>").addClass("fa-icon-button fa fa-times").click(function(b){g.destroy()}));i.appendTo("#canvas-container");var d=$("#canvas-container").position();var c=$("#canvas-container").parent();var a=i.width();var q=i.height();i.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(q/2)});k.prependTo(n);a+=(k.width()+10);i.css("width",a);$(i).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o,p){var f=$(this).offsetParent().offset(),b=p.offsetX-f.left,s=p.offsetY-f.top;$(this).css({left:b,top:s});$(this).find(".terminal").each(function(){this.terminal.redraw()})});return g}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}function ScrollPanel(a){this.panel=a}$.extend(ScrollPanel.prototype,{test:function(v,d){clearTimeout(this.timeout);var k=v.pageX,j=v.pageY,l=$(this.panel),c=l.position(),b=l.width(),i=l.height(),w=l.parent(),s=w.width(),a=w.height(),r=w.offset(),p=r.left,m=r.top,A=p+w.width(),u=m+w.height(),B=-(b-(s/2)),z=-(i-(a/2)),g=(s/2),f=(a/2),h=false,q=5,o=23;if(k-q<p){if(c.left<g){var n=Math.min(o,g-c.left);l.css("left",c.left+n);h=true}}else{if(k+q>A){if(c.left>B){var n=Math.min(o,c.left-B);l.css("left",c.left-n);h=true}}else{if(j-q<m){if(c.top<f){var n=Math.min(o,f-c.top);l.css("top",c.top+n);h=true}}else{if(j+q>u){if(c.top>z){var n=Math.min(o,c.top-B);l.css("top",(c.top-n)+"px");h=true}}}}}if(h){d();var l=this;this.timeout=setTimeout(function(){l.test(v,d)},50)}},stop:function(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManager.prototype,{init_drag:function(){var b=this;var a=function(f,g){f=Math.min(f,b.cv.width()/2);f=Math.max(f,-b.cc.width()+b.cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(){var g=$(this).offset();var f=b.cc.position();c=f.top-g.top;d=f.left-g.left}).bind("drag",function(f,g){a(g.offsetX+d,g.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("drag",function(k,l){var h=b.cc.width(),n=b.cc.height(),m=b.oc.width(),j=b.oc.height(),f=$(this).offsetParent().offset(),i=l.offsetX-f.left,g=l.offsetY-f.top;a(-(i/m*h),-(g/j*n))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g,i){var j=$(this).offsetParent();var h=j.offset();var f=Math.max(j.width()-(i.offsetX-h.left),j.height()-(i.offsetY-h.top));$(this).css({width:f,height:f});b.draw_overview()});$("#overview-border div").bind("drag",function(){})},update_viewport_overlay:function(){var b=this.cc,f=this.cv,a=this.oc,c=this.ov,d=b.width(),j=b.height(),i=a.width(),g=a.height(),h=b.position();c.css({left:-(h.left/d*i),top:-(h.top/j*g),width:(f.width()/d*i)-2,height:(f.height()/j*g)-2})},draw_overview:function(){var j=$("#overview-canvas"),m=j.parent().parent().width(),i=j.get(0).getContext("2d"),d=$("#canvas-container").width(),l=$("#canvas-container").height();var g,a,k,f;var h=this.cv.width();var b=this.cv.height();if(d<h&&l<b){k=d/h*m;f=(m-k)/2;g=l/b*m;a=(m-g)/2}else{if(d<l){a=0;g=m;k=Math.ceil(g*d/l);f=(m-k)/2}else{k=m;f=0;g=Math.ceil(k*l/d);a=(m-g)/2}}j.parent().css({left:f,top:a,width:k,height:g});j.attr("width",k);j.attr("height",g);$.each(workflow.nodes,function(t,q){i.fillStyle="#D2C099";i.strokeStyle="#D8B365";i.lineWidth=1;var s=$(q.element),n=s.position(),c=n.left/d*k,r=n.top/l*g,o=s.width()/d*k,p=s.height()/l*g;if(q.tool_errors){i.fillStyle="#FFCCCC";i.strokeStyle="#AA6666"}else{if(q.workflow_outputs!=undefined&&q.workflow_outputs.length>0){i.fillStyle="#E8A92D";i.strokeStyle="#E8A92D"}}i.fillRect(c,r,o,p);i.strokeRect(c,r,o,p)});this.update_viewport_overlay()}});
\ No newline at end of file
+function Terminal(a){this.element=a;this.connectors=[]}$.extend(Terminal.prototype,{connect:function(a){this.connectors.push(a);if(this.node){this.node.changed()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.changed()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})}});function OutputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}OutputTerminal.prototype=new Terminal();function InputTerminal(b,c,a){Terminal.call(this,b);this.datatypes=c;this.multiple=a}InputTerminal.prototype=new Terminal();$.extend(InputTerminal.prototype,{can_accept:function(a){if(this.connectors.length<1||this.multiple){for(var c in this.datatypes){var f=new Array();f=f.concat(a.datatypes);if(a.node.post_job_actions){for(var d in a.node.post_job_actions){var g=a.node.post_job_actions[d];if(g.action_type=="ChangeDatatypeAction"&&(g.output_name==""||g.output_name==a.name)&&g.action_arguments){f.push(g.action_arguments.newtype)}}}for(var b in f){if(f[b]=="input"||issubtype(f[b],this.datatypes[c])){return true}}}}return false}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a){this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;if(this.handle1){this.handle1.connect(this)}this.handle2=a;if(this.handle2){this.handle2.connect(this)}},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},redraw:function(){var d=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}d.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var n=function(c){return $(c).offset().left-d.offset().left};var i=function(c){return $(c).offset().top-d.offset().top};if(!this.handle1||!this.handle2){return}var h=n(this.handle1.element)+5;var g=i(this.handle1.element)+5;var p=n(this.handle2.element)+5;var m=i(this.handle2.element)+5;var f=100;var k=Math.min(h,p);var a=Math.max(h,p);var j=Math.min(g,m);var t=Math.max(g,m);var b=Math.min(Math.max(Math.abs(t-j)/2,100),300);var o=k-f;var s=j-f;var q=a-k+2*f;var l=t-j+2*f;this.canvas.style.left=o+"px";this.canvas.style.top=s+"px";this.canvas.setAttribute("width",q);this.canvas.setAttribute("height",l);h-=o;g-=s;p-=o;m-=s;var r=this.canvas.getContext("2d");r.lineCap="round";r.strokeStyle=this.outer_color;r.lineWidth=7;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke();r.strokeStyle=this.inner_color;r.lineWidth=5;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke()}});function Node(a){this.element=a;this.input_terminals={};this.output_terminals={};this.tool_errors={}}$.extend(Node.prototype,{new_input_terminal:function(a){var b=$("<div class='terminal input-terminal'></div>")[0];this.enable_input_terminal(b,a.name,a.extensions,a.multiple);return b},enable_input_terminal:function(f,b,d,a){var g=this;var c=f.terminal=new InputTerminal(f,d,a);c.node=g;c.name=b;$(f).bind("dropinit",function(h,i){return $(i.drag).hasClass("output-terminal")&&c.can_accept(i.drag.terminal)}).bind("dropstart",function(h,i){if(i.proxy.terminal){i.proxy.terminal.connectors[0].inner_color="#BBFFBB"}}).bind("dropend",function(h,i){if(i.proxy.terminal){i.proxy.terminal.connectors[0].inner_color="#FFFFFF"}}).bind("drop",function(h,i){(new Connector(i.drag.terminal,c)).redraw()}).bind("hover",function(){if(c.connectors.length>0){var h=$("<div class='callout'></div>").css({display:"none"}).appendTo("body").append($("<div class='button'></div>").append($("<div/>").addClass("fa-icon-button fa fa-times").click(function(){$.each(c.connectors,function(j,i){if(i){i.destroy()}});h.remove()}))).bind("mouseleave",function(){$(this).remove()});h.css({top:$(f).offset().top-2,left:$(f).offset().left-h.width(),"padding-right":$(f).width()}).show()}});g.input_terminals[b]=c},enable_output_terminal:function(d,a,f){var g=this;var c=d;var b=d.terminal=new OutputTerminal(d,f);b.node=g;b.name=a;$(d).bind("dragstart",function(j,k){$(k.available).addClass("input-terminal-active");workflow.check_changes_in_active_form();var i=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);i.terminal=new OutputTerminal(i);var l=new Connector();l.dragging=true;l.connect(d.terminal,i.terminal);return i}).bind("drag",function(i,j){var h=function(){var l=$(j.proxy).offsetParent().offset(),k=j.offsetX-l.left,m=j.offsetY-l.top;$(j.proxy).css({left:k,top:m});j.proxy.terminal.redraw();canvas_manager.update_viewport_overlay()};h();$("#canvas-container").get(0).scroll_panel.test(i,h)}).bind("dragend",function(h,i){i.proxy.terminal.connectors[0].destroy();$(i.proxy).remove();$(i.available).removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()});g.output_terminals[a]=b},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b.appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(h){var g=this.element;if(h.type){this.type=h.type}this.name=h.name;this.form_html=h.form_html;this.tool_state=h.tool_state;this.tool_errors=h.tool_errors;this.tooltip=h.tooltip?h.tooltip:"";this.annotation=h.annotation;this.post_job_actions=h.post_job_actions?h.post_job_actions:{};this.workflow_outputs=h.workflow_outputs?h.workflow_outputs:[];if(this.tool_errors){g.addClass("tool-node-error")}else{g.removeClass("tool-node-error")}var d=this;var c=Math.max(150,g.width());var a=g.find(".toolFormBody");a.find("div").remove();var i=$("<div class='inputs'></div>").appendTo(a);$.each(h.data_inputs,function(k,f){var j=d.new_input_terminal(f);var b=$("<div class='form-row dataRow input-data-row' name='"+f.name+"'>"+f.label+"</div>");b.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(b);c=Math.max(c,b.outerWidth());b.css({position:"",left:"",top:"",display:""});b.remove();i.append(b.prepend(j))});if((h.data_inputs.length>0)&&(h.data_outputs.length>0)){a.append($("<div class='rule'></div>"))}$.each(h.data_outputs,function(k,b){var j=$("<div class='terminal output-terminal'></div>");d.enable_output_terminal(j[0],b.name,b.extensions);var f=b.name;if(b.extensions.indexOf("input")<0){f=f+" ("+b.extensions.join(", ")+")"}var m=$("<div class='form-row dataRow'>"+f+"</div>");if(d.type=="tool"){var l=$("<div class='callout "+f+"'></div>").css({display:"none"}).append($("<div class='buttons'></div>").append($("<img/>").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png").click(function(){if($.inArray(b.name,d.workflow_outputs)!=-1){d.workflow_outputs.splice($.inArray(b.name,d.workflow_outputs),1);l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{d.workflow_outputs.push(b.name);l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}workflow.has_changes=true;canvas_manager.draw_overview()}))).tooltip({delay:500,title:"Mark dataset as a workflow output. All unmarked datasets will be hidden."});l.css({top:"50%",margin:"-8px 0px 0px 0px",right:8});l.show();m.append(l);if($.inArray(b.name,d.workflow_outputs)===-1){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}m.hover(function(){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-yellow.png")},function(){if($.inArray(b.name,d.workflow_outputs)===-1){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}})}m.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(m);c=Math.max(c,m.outerWidth()+17);m.css({position:"",left:"",top:"",display:""});m.detach();a.append(m.append(j))});g.css("width",Math.min(250,Math.max(g.width(),c)));workflow.node_changed(this)},update_field_data:function(d){var b=$(this.element),c=this;this.tool_state=d.tool_state;this.form_html=d.form_html;this.tool_errors=d.tool_errors;this.annotation=d.annotation;var f=$.parseJSON(d.post_job_actions);this.post_job_actions=f?f:{};if(this.tool_errors){b.addClass("tool-node-error")}else{b.removeClass("tool-node-error")}var g=b.find("div.inputs");var a=$("<div class='inputs'></div>");$.each(d.data_inputs,function(k,h){var j=c.new_input_terminal(h);g.find("div[name='"+h.name+"']").each(function(){$(this).find(".input-terminal").each(function(){var i=this.terminal.connectors[0];if(i){j.terminal.connectors[0]=i;i.handle2=j.terminal}});$(this).remove()});a.append($("<div class='form-row dataRow input-data-row' name='"+h.name+"'>"+h.label+"</div>").prepend(j))});g.replaceWith(a);g.find("div.input-data-row > .terminal").each(function(){this.terminal.destroy()});this.changed();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="<div style='color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},changed:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;this.active_form_has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this.nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},rectify_workflow_outputs:function(){var b=false;var a=false;$.each(this.nodes,function(c,d){if(d.workflow_outputs&&d.workflow_outputs.length>0){b=true}$.each(d.post_job_actions,function(g,f){if(f.action_type==="HideDatasetAction"){a=true}})});if(b!==false||a!==false){$.each(this.nodes,function(c,g){if(g.type==="tool"){var f=false;if(g.post_job_actions==null){g.post_job_actions={};f=true}var d=[];$.each(g.post_job_actions,function(i,h){if(h.action_type=="HideDatasetAction"){d.push(i)}});if(d.length>0){$.each(d,function(h,j){f=true;delete g.post_job_actions[j]})}if(b){$.each(g.output_terminals,function(i,j){var h=true;$.each(g.workflow_outputs,function(l,m){if(j.name===m){h=false}});if(h===true){f=true;var k={action_type:"HideDatasetAction",output_name:j.name,action_arguments:{}};g.post_job_actions["HideDatasetAction"+j.name]=null;g.post_job_actions["HideDatasetAction"+j.name]=k}})}if(workflow.active_node==g&&f===true){workflow.reload_active_node()}}})}},to_simple:function(){var a={};$.each(this.nodes,function(c,f){var g={};$.each(f.input_terminals,function(i,j){g[j.name]=null;var h=[];$.each(j.connectors,function(k,l){h[k]={id:l.handle1.node.id,output_name:l.handle1.name};g[j.name]=h})});var b={};if(f.post_job_actions){$.each(f.post_job_actions,function(j,h){var k={action_type:h.action_type,output_name:h.output_name,action_arguments:h.action_arguments};b[h.action_type+h.output_name]=null;b[h.action_type+h.output_name]=k})}if(!f.workflow_outputs){f.workflow_outputs=[]}var d={id:f.id,type:f.type,tool_id:f.tool_id,tool_state:f.tool_state,tool_errors:f.tool_errors,input_connections:g,position:$(f.element).position(),annotation:f.annotation,post_job_actions:f.post_job_actions,workflow_outputs:f.workflow_outputs};a[f.id]=d});return{steps:a}},from_simple:function(b){wf=this;var c=0;wf.name=b.name;var a=false;$.each(b.steps,function(g,f){var d=prebuild_node(f.type,f.name,f.tool_id);d.init_field_data(f);if(f.position){d.element.css({top:f.position.top,left:f.position.left})}d.id=f.id;wf.nodes[d.id]=d;c=Math.max(c,parseInt(g));if(!a&&d.type==="tool"){if(d.workflow_outputs.length>0){a=true}else{$.each(d.post_job_actions,function(i,h){if(h.action_type==="HideDatasetAction"){a=true}})}}});wf.id_counter=c+1;$.each(b.steps,function(g,f){var d=wf.nodes[g];$.each(f.input_connections,function(i,h){if(h){if(!$.isArray(h)){h=[h]}$.each(h,function(k,j){var m=wf.nodes[j.id];var n=new Connector();n.connect(m.output_terminals[j.output_name],d.input_terminals[i]);n.redraw()})}});if(a&&d.type==="tool"){$.each(d.output_terminals,function(h,i){if(d.post_job_actions["HideDatasetAction"+i.name]===undefined){d.workflow_outputs.push(i.name);callout=$(d.element).find(".callout."+i.name);callout.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png");workflow.has_changes=true}})}})},check_changes_in_active_form:function(){if(this.active_form_has_changes){this.has_changes=true;$("#right-content").find("form").submit();this.active_form_has_changes=false}},reload_active_node:function(){if(this.active_node){var a=this.active_node;this.clear_active_node();this.activate_node(a)}},clear_active_node:function(){if(this.active_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("<div>No node selected</div>")},activate_node:function(a){if(this.active_node!=a){this.check_changes_in_active_form();this.clear_active_node();parent.show_form_for_tool(a.form_html+a.tooltip,a);a.make_active();this.active_node=a}},node_changed:function(a){this.has_changes=true;if(this.active_node==a){this.check_changes_in_active_form();parent.show_form_for_tool(a.form_html+a.tooltip,a)}},layout:function(){this.check_changes_in_active_form();this.has_changes=true;var i={};var b={};$.each(this.nodes,function(l,k){if(i[l]===undefined){i[l]=0}if(b[l]===undefined){b[l]=[]}});$.each(this.nodes,function(l,k){$.each(k.input_terminals,function(m,n){$.each(n.connectors,function(p,q){var o=q.handle1.node;i[k.id]+=1;b[o.id].push(k.id)})})});node_ids_by_level=[];while(true){level_parents=[];for(var a in i){if(i[a]==0){level_parents.push(a)}}if(level_parents.length==0){break}node_ids_by_level.push(level_parents);for(var f in level_parents){var j=level_parents[f];delete i[j];for(var g in b[j]){i[b[j][g]]-=1}}}if(i.length){return}var d=this.nodes;var h=80;v_pad=30;var c=h;$.each(node_ids_by_level,function(k,l){l.sort(function(p,o){return $(d[p].element).position().top-$(d[o].element).position().top});var m=0;var n=v_pad;$.each(l,function(o,r){var q=d[r];var p=$(q.element);$(p).css({top:n,left:c});m=Math.max(m,$(p).width());n+=$(p).height()+v_pad});c+=m+h});$.each(d,function(k,l){l.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(h,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var i=this.canvas_container.parent();var d=fix_delta(a.xmin,100);var h=fix_delta(a.ymin,100);d=Math.max(d,f.left);h=Math.max(h,f.top);var c=f.left-d;var g=f.top-h;var b=round_up(a.xmax+100,100)+d;var j=round_up(a.ymax+100,100)+h;b=Math.max(b,-c+i.width());j=Math.max(j,-g+i.height());this.canvas_container.css({left:c,top:g,width:b,height:j});this.canvas_container.children().each(function(){var k=$(this).position();$(this).css("left",k.left+d);$(this).css("top",k.top+h)})}});function fix_delta(a,b){if(a<b||a>3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(l,j,r){var i=$("<div class='toolForm toolFormInCanvas'></div>");var g=new Node(i);g.type=l;if(l=="tool"){g.tool_id=r}var n=$("<div class='toolFormTitle unselectable'>"+j+"</div>");i.append(n);i.css("left",$(window).scrollLeft()+20);i.css("top",$(window).scrollTop()+20);var m=$("<div class='toolFormBody'></div>");var h="<div><img height='16' align='middle' src='"+galaxy_config.root+"static/images/loading_small_white_bg.gif'/> loading tool info...</div>";m.append(h);g.form_html=h;i.append(m);var k=$("<div class='buttons' style='float: right;'></div>");k.append($("<div>").addClass("fa-icon-button fa fa-times").click(function(b){g.destroy()}));i.appendTo("#canvas-container");var d=$("#canvas-container").position();var c=$("#canvas-container").parent();var a=i.width();var q=i.height();i.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(q/2)});k.prependTo(n);a+=(k.width()+10);i.css("width",a);$(i).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o,p){var f=$(this).offsetParent().offset(),b=p.offsetX-f.left,s=p.offsetY-f.top;$(this).css({left:b,top:s});$(this).find(".terminal").each(function(){this.terminal.redraw()})});return g}function add_node(b,d,a){var c=prebuild_node(b,d,a);workflow.add_node(c);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview();workflow.activate_node(c);return c}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}function ScrollPanel(a){this.panel=a}$.extend(ScrollPanel.prototype,{test:function(v,d){clearTimeout(this.timeout);var k=v.pageX,j=v.pageY,l=$(this.panel),c=l.position(),b=l.width(),i=l.height(),w=l.parent(),s=w.width(),a=w.height(),r=w.offset(),p=r.left,m=r.top,A=p+w.width(),u=m+w.height(),B=-(b-(s/2)),z=-(i-(a/2)),g=(s/2),f=(a/2),h=false,q=5,o=23;if(k-q<p){if(c.left<g){var n=Math.min(o,g-c.left);l.css("left",c.left+n);h=true}}else{if(k+q>A){if(c.left>B){var n=Math.min(o,c.left-B);l.css("left",c.left-n);h=true}}else{if(j-q<m){if(c.top<f){var n=Math.min(o,f-c.top);l.css("top",c.top+n);h=true}}else{if(j+q>u){if(c.top>z){var n=Math.min(o,c.top-B);l.css("top",(c.top-n)+"px");h=true}}}}}if(h){d();var l=this;this.timeout=setTimeout(function(){l.test(v,d)},50)}},stop:function(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManager.prototype,{init_drag:function(){var b=this;var a=function(f,g){f=Math.min(f,b.cv.width()/2);f=Math.max(f,-b.cc.width()+b.cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(){var g=$(this).offset();var f=b.cc.position();c=f.top-g.top;d=f.left-g.left}).bind("drag",function(f,g){a(g.offsetX+d,g.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("drag",function(k,l){var h=b.cc.width(),n=b.cc.height(),m=b.oc.width(),j=b.oc.height(),f=$(this).offsetParent().offset(),i=l.offsetX-f.left,g=l.offsetY-f.top;a(-(i/m*h),-(g/j*n))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g,i){var j=$(this).offsetParent();var h=j.offset();var f=Math.max(j.width()-(i.offsetX-h.left),j.height()-(i.offsetY-h.top));$(this).css({width:f,height:f});b.draw_overview()});$("#overview-border div").bind("drag",function(){})},update_viewport_overlay:function(){var b=this.cc,f=this.cv,a=this.oc,c=this.ov,d=b.width(),j=b.height(),i=a.width(),g=a.height(),h=b.position();c.css({left:-(h.left/d*i),top:-(h.top/j*g),width:(f.width()/d*i)-2,height:(f.height()/j*g)-2})},draw_overview:function(){var j=$("#overview-canvas"),m=j.parent().parent().width(),i=j.get(0).getContext("2d"),d=$("#canvas-container").width(),l=$("#canvas-container").height();var g,a,k,f;var h=this.cv.width();var b=this.cv.height();if(d<h&&l<b){k=d/h*m;f=(m-k)/2;g=l/b*m;a=(m-g)/2}else{if(d<l){a=0;g=m;k=Math.ceil(g*d/l);f=(m-k)/2}else{k=m;f=0;g=Math.ceil(k*l/d);a=(m-g)/2}}j.parent().css({left:f,top:a,width:k,height:g});j.attr("width",k);j.attr("height",g);$.each(workflow.nodes,function(t,q){i.fillStyle="#D2C099";i.strokeStyle="#D8B365";i.lineWidth=1;var s=$(q.element),n=s.position(),c=n.left/d*k,r=n.top/l*g,o=s.width()/d*k,p=s.height()/l*g;if(q.tool_errors){i.fillStyle="#FFCCCC";i.strokeStyle="#AA6666"}else{if(q.workflow_outputs!=undefined&&q.workflow_outputs.length>0){i.fillStyle="#E8A92D";i.strokeStyle="#E8A92D"}}i.fillRect(c,r,o,p);i.strokeRect(c,r,o,p)});this.update_viewport_overlay()}});
\ No newline at end of file
diff -r acec53247232cffb773b2e4a8de67fd3bdc3424e -r 12e6db99d15193b700cbde74f31c71a2ef9bcc2d static/scripts/packed/galaxy.workflows.js
--- a/static/scripts/packed/galaxy.workflows.js
+++ b/static/scripts/packed/galaxy.workflows.js
@@ -1,1 +1,1 @@
-$(function(){if(window.lt_ie_7){show_modal("Browser not supported","Sorry, the workflow editor is not supported for IE6 and below.");return}$("#tool-search-query").click(function(){$(this).focus();$(this).select()}).keyup(function(){$(this).css("font-style","normal");if(this.value.length<3){reset_tool_search(false)}else{if(this.value!=this.lastValue){$(this).addClass("search_active");var g=this.value+"*";if(this.timer){clearTimeout(this.timer)}$("#search-spinner").show();this.timer=setTimeout(function(){$.get(tool_search_url,{query:g},function(i){$("#search-no-results").hide();$(".toolSectionWrapper").hide();$(".toolSectionWrapper").find(".toolTitle").hide();if(i.length!=0){var h=$.map(i,function(k,j){return"link-"+k});$(h).each(function(j,k){$("[id='"+k+"']").parent().addClass("search_match");$("[id='"+k+"']").parent().show().parent().parent().show().parent().show()});$(".toolPanelLabel").each(function(){var l=$(this);var k=l.next();var j=true;while(k.length!==0&&k.hasClass("toolTitle")){if(k.is(":visible")){j=false;break}else{k=k.next()}}if(j){l.hide()}})}else{$("#search-no-results").show()}$("#search-spinner").hide()},"json")},200)}}this.lastValue=this.value});canvas_manager=new CanvasManager($("#canvas-viewport"),$("#overview"));reset();$.ajax({url:get_datatypes_url,dataType:"json",cache:false,success:function(g){populate_datatype_info(g);$.ajax({url:load_workflow_url,data:{id:workflow_id,_:"true"},dataType:"json",cache:false,success:function(h){reset();workflow.from_simple(h);workflow.has_changes=false;workflow.fit_canvas_to_nodes();scroll_to_nodes();canvas_manager.draw_overview();upgrade_message="";$.each(h.upgrade_messages,function(j,i){upgrade_message+=("<li>Step "+(parseInt(j,10)+1)+": "+workflow.nodes[j].name+"<ul>");$.each(i,function(k,l){upgrade_message+="<li>"+l+"</li>"});upgrade_message+="</ul></li>"});if(upgrade_message){show_modal("Workflow loaded with changes","Problems were encountered loading this workflow (possibly a result of tool upgrades). Please review the following parameters and then save.<ul>"+upgrade_message+"</ul>",{Continue:hide_modal})}else{hide_modal()}show_workflow_parameters()},beforeSubmit:function(h){show_message("Loading workflow","progress")}})}});$(document).ajaxStart(function(){active_ajax_call=true;$(document).bind("ajaxStop.global",function(){active_ajax_call=false})});$(document).ajaxError(function(i,g){var h=g.responseText||g.statusText||"Could not connect to server";show_modal("Server error",h,{"Ignore error":hide_modal});return false});make_popupmenu($("#workflow-options-button"),{Save:save_current_workflow,Run:function(){window.location=run_workflow_url},"Edit Attributes":c,"Auto Re-layout":f,Close:close_editor});function b(){workflow.clear_active_node();$(".right-content").hide();var j="";for(var h in workflow.nodes){var i=workflow.nodes[h];if(i.type=="tool"){j+="<div class='toolForm' style='margin-bottom:5px;'><div class='toolFormTitle'>Step "+i.id+" - "+i.name+"</div>";for(var k in i.output_terminals){var g=i.output_terminals[k];if($.inArray(g.name,i.workflow_outputs)!=-1){j+="<p>"+g.name+"<input type='checkbox' name='"+i.id+"|"+g.name+"' checked /></p>"}else{j+="<p>"+g.name+"<input type='checkbox' name='"+i.id+"|"+g.name+"' /></p>"}}j+="</div>"}}$("#output-fill-area").html(j);$("#output-fill-area input").bind("click",function(){var n=this.name.split("|")[0];var l=this.name.split("|")[1];if(this.checked){if($.inArray(l,workflow.nodes[n].workflow_outputs)==-1){workflow.nodes[n].workflow_outputs.push(l)}}else{while($.inArray(l,workflow.nodes[n].workflow_outputs)!=-1){var m=$.inArray(l,workflow.nodes[n].workflow_outputs);workflow.nodes[n].workflow_outputs=workflow.nodes[n].workflow_outputs.slice(0,m).concat(workflow.nodes[n].workflow_outputs.slice(m+1))}}workflow.has_changes=true});$("#workflow-output-area").show()}function f(){workflow.layout();workflow.fit_canvas_to_nodes();scroll_to_nodes();canvas_manager.draw_overview()}function c(){workflow.clear_active_node();$(".right-content").hide();$("#edit-attributes").show()}overview_size=$.jStorage.get("overview-size");if(overview_size!==undefined){$("#overview-border").css({width:overview_size,height:overview_size})}if($.jStorage.get("overview-off")){d()}else{e()}$("#overview-border").bind("dragend",function(h,j){var k=$(this).offsetParent();var i=k.offset();var g=Math.max(k.width()-(j.offsetX-i.left),k.height()-(j.offsetY-i.top));$.jStorage.set("overview-size",g+"px")});function e(){$.jStorage.set("overview-off",false);$("#overview-border").css("right","0px");$("#close-viewport").css("background-position","0px 0px")}function d(){$.jStorage.set("overview-off",true);$("#overview-border").css("right","20000px");$("#close-viewport").css("background-position","12px 0px")}$("#close-viewport").click(function(){if($("#overview-border").css("right")==="0px"){d()}else{e()}});window.onbeforeunload=function(){if(workflow&&workflow.has_changes){return"There are unsaved changes to your workflow which will be lost."}};$("div.toolSectionBody").hide();$("div.toolSectionTitle > span").wrap("<a href='#'></a>");var a=null;$("div.toolSectionTitle").each(function(){var g=$(this).next("div.toolSectionBody");$(this).click(function(){if(g.is(":hidden")){if(a){a.slideUp("fast")}a=g;g.slideDown("fast")}else{g.slideUp("fast");a=null}})});async_save_text("workflow-name","workflow-name",rename_async_url,"new_name");$("#workflow-tag").click(function(){$(".tag-area").click();return false});async_save_text("workflow-annotation","workflow-annotation",annotate_async_url,"new_annotation",25,true,4)});function reset(){if(workflow){workflow.remove_all()}workflow=new Workflow($("#canvas-container"))}function scroll_to_nodes(){var a=$("#canvas-viewport");var d=$("#canvas-container");var c,b;if(d.width()<a.width()){b=(a.width()-d.width())/2}else{b=0}if(d.height()<a.height()){c=(a.height()-d.height())/2}else{c=0}d.css({left:b,top:c})}function add_node_for_tool(c,b){var a=prebuild_node("tool",b,c);workflow.add_node(a);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview();workflow.activate_node(a);$.ajax({url:get_new_module_info_url,data:{type:"tool",tool_id:c,_:"true"},global:false,dataType:"json",success:function(d){a.init_field_data(d)},error:function(f,g){var d="error loading field data";if(f.status===0){d+=", server unavailable"}a.error(d)}})}function add_node_for_module(a,b){node=prebuild_node(a,b);workflow.add_node(node);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview();workflow.activate_node(node);$.ajax({url:get_new_module_info_url,data:{type:a,_:"true"},dataType:"json",success:function(c){node.init_field_data(c)},error:function(d,f){var c="error loading field data";if(d.status==0){c+=", server unavailable"}node.error(c)}})}function display_pja(b,a){$("#pja_container").append(get_pja_form(b));$("#pja_container>.toolForm:last>.toolFormTitle>.buttons").click(function(){action_to_rem=$(this).closest(".toolForm",".action_tag").children(".action_tag:first").text();$(this).closest(".toolForm").remove();delete workflow.active_node.post_job_actions[action_to_rem];workflow.active_form_has_changes=true})}function display_pja_list(){return pja_list}function display_file_list(b){addlist="<select id='node_data_list' name='node_data_list'>";for(var a in b.output_terminals){addlist+="<option value='"+a+"'>"+a+"</option>"}addlist+="</select>";return addlist}function new_pja(d,b,a){if(a.post_job_actions===undefined){a.post_job_actions={}}if(a.post_job_actions[d+b]===undefined){var c={};c.action_type=d;c.output_name=b;a.post_job_actions[d+b]=null;a.post_job_actions[d+b]=c;display_pja(c,a);workflow.active_form_has_changes=true;return true}else{return false}}function show_workflow_parameters(){var c=/\$\{.+?\}/g;var b=[];var f=$("#workflow-parameters-container");var e=$("#workflow-parameters-box");var a="";var d=[];$.each(workflow.nodes,function(g,h){var i=h.form_html.match(c);if(i){d=d.concat(i)}if(h.post_job_actions){$.each(h.post_job_actions,function(j,l){if(l.action_arguments){$.each(l.action_arguments,function(m,n){var o=n.match(c);if(o){d=d.concat(o)}})}});if(d){$.each(d,function(j,l){if($.inArray(l,b)===-1){b.push(l)}})}}});if(b&&b.length!==0){$.each(b,function(g,h){a+="<div>"+h.substring(2,h.length-1)+"</div>"});f.html(a);e.show()}else{f.html(a);e.hide()}}function show_form_for_tool(c,b){$(".right-content").hide();$("#right-content").show().html(c);if(b){$("#right-content").find(".toolForm:first").after("<p><div class='metadataForm'><div class='metadataFormTitle'>Edit Step Attributes</div><div class='form-row'><label>Annotation / Notes:</label><div style='margin-right: 10px;'><textarea name='annotation' rows='3' style='width: 100%'>"+b.annotation+"</textarea><div class='toolParamHelp'>Add an annotation or notes to this step; annotations are available when a workflow is viewed.</div></div></div></div>")}if(b&&b.type=="tool"){pjastr="<p><div class='metadataForm'><div class='metadataFormTitle'>Edit Step Actions</div><div class='form-row'> "+display_pja_list()+" <br/> "+display_file_list(b)+" <div class='action-button' style='border:1px solid black;display:inline;' id='add_pja'>Create</div></div><div class='form-row'><div style='margin-right: 10px;'><span id='pja_container'></span>";pjastr+="<div class='toolParamHelp'>Add actions to this step; actions are applied when this workflow step completes.</div></div></div></div>";$("#right-content").find(".toolForm").after(pjastr);for(var a in b.post_job_actions){if(a!="undefined"){display_pja(b.post_job_actions[a],b)}}$("#add_pja").click(function(){new_pja($("#new_pja_list").val(),$("#node_data_list").val(),b)})}$("#right-content").find("form").ajaxForm({type:"POST",dataType:"json",success:function(d){workflow.active_form_has_changes=false;b.update_field_data(d);show_workflow_parameters()},beforeSubmit:function(d){d.push({name:"tool_state",value:b.tool_state});d.push({name:"_",value:"true"})}}).each(function(){var d=this;$(this).find("select[refresh_on_change='true']").change(function(){$(d).submit()});$(this).find(".popupmenu").each(function(){var g=$(this).parents("div.form-row").attr("id");var e=$('<a class="popup-arrow" id="popup-arrow-for-'+g+'">▼</a>');var f={};$(this).find("button").each(function(){var h=$(this).attr("name");var i=$(this).attr("value");f[$(this).text()]=function(){$(d).append("<input type='hidden' name='"+h+"' value='"+i+"' />").submit()}});e.insertAfter(this);$(this).remove();make_popupmenu(e,f)});$(this).find("input,textarea,select").each(function(){$(this).bind("focus click",function(){workflow.active_form_has_changes=true})})})}var close_editor=function(){workflow.check_changes_in_active_form();if(workflow&&workflow.has_changes){do_close=function(){window.onbeforeunload=undefined;window.document.location=workflow_index_url};show_modal("Close workflow editor","There are unsaved changes to your workflow which will be lost.",{Cancel:hide_modal,"Save Changes":function(){save_current_workflow(null,do_close)}},{"Don't Save":do_close})}else{window.document.location=workflow_index_url}};var save_current_workflow=function(b,c){show_message("Saving workflow","progress");workflow.check_changes_in_active_form();if(!workflow.has_changes){hide_modal();if(c){c()}return}workflow.rectify_workflow_outputs();var a=function(d){$.ajax({url:save_workflow_url,type:"POST",data:{id:workflow_id,workflow_data:function(){return JSON.stringify(workflow.to_simple())},_:"true"},dataType:"json",success:function(g){var e=$("<div></div>").text(g.message);if(g.errors){e.addClass("warningmark");var f=$("<ul/>");$.each(g.errors,function(j,h){$("<li></li>").text(h).appendTo(f)});e.append(f)}else{e.addClass("donemark")}workflow.name=g.name;workflow.has_changes=false;workflow.stored=true;show_workflow_parameters();if(g.errors){show_modal("Saving workflow",e,{Ok:hide_modal})}else{if(d){d()}hide_modal()}}})};if(active_ajax_call){$(document).bind("ajaxStop.save_workflow",function(){$(document).unbind("ajaxStop.save_workflow");a();$(document).unbind("ajaxStop.save_workflow");active_ajax_call=false})}else{a(c)}};
\ No newline at end of file
+$(function(){if(window.lt_ie_7){show_modal("Browser not supported","Sorry, the workflow editor is not supported for IE6 and below.");return}$("#tool-search-query").click(function(){$(this).focus();$(this).select()}).keyup(function(){$(this).css("font-style","normal");if(this.value.length<3){reset_tool_search(false)}else{if(this.value!=this.lastValue){$(this).addClass("search_active");var g=this.value+"*";if(this.timer){clearTimeout(this.timer)}$("#search-spinner").show();this.timer=setTimeout(function(){$.get(tool_search_url,{query:g},function(i){$("#search-no-results").hide();$(".toolSectionWrapper").hide();$(".toolSectionWrapper").find(".toolTitle").hide();if(i.length!=0){var h=$.map(i,function(k,j){return"link-"+k});$(h).each(function(j,k){$("[id='"+k+"']").parent().addClass("search_match");$("[id='"+k+"']").parent().show().parent().parent().show().parent().show()});$(".toolPanelLabel").each(function(){var l=$(this);var k=l.next();var j=true;while(k.length!==0&&k.hasClass("toolTitle")){if(k.is(":visible")){j=false;break}else{k=k.next()}}if(j){l.hide()}})}else{$("#search-no-results").show()}$("#search-spinner").hide()},"json")},200)}}this.lastValue=this.value});canvas_manager=new CanvasManager($("#canvas-viewport"),$("#overview"));reset();$.ajax({url:get_datatypes_url,dataType:"json",cache:false,success:function(g){populate_datatype_info(g);$.ajax({url:load_workflow_url,data:{id:workflow_id,_:"true"},dataType:"json",cache:false,success:function(h){reset();workflow.from_simple(h);workflow.has_changes=false;workflow.fit_canvas_to_nodes();scroll_to_nodes();canvas_manager.draw_overview();upgrade_message="";$.each(h.upgrade_messages,function(j,i){upgrade_message+=("<li>Step "+(parseInt(j,10)+1)+": "+workflow.nodes[j].name+"<ul>");$.each(i,function(k,l){upgrade_message+="<li>"+l+"</li>"});upgrade_message+="</ul></li>"});if(upgrade_message){show_modal("Workflow loaded with changes","Problems were encountered loading this workflow (possibly a result of tool upgrades). Please review the following parameters and then save.<ul>"+upgrade_message+"</ul>",{Continue:hide_modal})}else{hide_modal()}show_workflow_parameters()},beforeSubmit:function(h){show_message("Loading workflow","progress")}})}});$(document).ajaxStart(function(){active_ajax_call=true;$(document).bind("ajaxStop.global",function(){active_ajax_call=false})});$(document).ajaxError(function(i,g){var h=g.responseText||g.statusText||"Could not connect to server";show_modal("Server error",h,{"Ignore error":hide_modal});return false});make_popupmenu($("#workflow-options-button"),{Save:save_current_workflow,Run:function(){window.location=run_workflow_url},"Edit Attributes":c,"Auto Re-layout":f,Close:close_editor});function b(){workflow.clear_active_node();$(".right-content").hide();var j="";for(var h in workflow.nodes){var i=workflow.nodes[h];if(i.type=="tool"){j+="<div class='toolForm' style='margin-bottom:5px;'><div class='toolFormTitle'>Step "+i.id+" - "+i.name+"</div>";for(var k in i.output_terminals){var g=i.output_terminals[k];if($.inArray(g.name,i.workflow_outputs)!=-1){j+="<p>"+g.name+"<input type='checkbox' name='"+i.id+"|"+g.name+"' checked /></p>"}else{j+="<p>"+g.name+"<input type='checkbox' name='"+i.id+"|"+g.name+"' /></p>"}}j+="</div>"}}$("#output-fill-area").html(j);$("#output-fill-area input").bind("click",function(){var n=this.name.split("|")[0];var l=this.name.split("|")[1];if(this.checked){if($.inArray(l,workflow.nodes[n].workflow_outputs)==-1){workflow.nodes[n].workflow_outputs.push(l)}}else{while($.inArray(l,workflow.nodes[n].workflow_outputs)!=-1){var m=$.inArray(l,workflow.nodes[n].workflow_outputs);workflow.nodes[n].workflow_outputs=workflow.nodes[n].workflow_outputs.slice(0,m).concat(workflow.nodes[n].workflow_outputs.slice(m+1))}}workflow.has_changes=true});$("#workflow-output-area").show()}function f(){workflow.layout();workflow.fit_canvas_to_nodes();scroll_to_nodes();canvas_manager.draw_overview()}function c(){workflow.clear_active_node();$(".right-content").hide();$("#edit-attributes").show()}overview_size=$.jStorage.get("overview-size");if(overview_size!==undefined){$("#overview-border").css({width:overview_size,height:overview_size})}if($.jStorage.get("overview-off")){d()}else{e()}$("#overview-border").bind("dragend",function(h,j){var k=$(this).offsetParent();var i=k.offset();var g=Math.max(k.width()-(j.offsetX-i.left),k.height()-(j.offsetY-i.top));$.jStorage.set("overview-size",g+"px")});function e(){$.jStorage.set("overview-off",false);$("#overview-border").css("right","0px");$("#close-viewport").css("background-position","0px 0px")}function d(){$.jStorage.set("overview-off",true);$("#overview-border").css("right","20000px");$("#close-viewport").css("background-position","12px 0px")}$("#close-viewport").click(function(){if($("#overview-border").css("right")==="0px"){d()}else{e()}});window.onbeforeunload=function(){if(workflow&&workflow.has_changes){return"There are unsaved changes to your workflow which will be lost."}};$("div.toolSectionBody").hide();$("div.toolSectionTitle > span").wrap("<a href='#'></a>");var a=null;$("div.toolSectionTitle").each(function(){var g=$(this).next("div.toolSectionBody");$(this).click(function(){if(g.is(":hidden")){if(a){a.slideUp("fast")}a=g;g.slideDown("fast")}else{g.slideUp("fast");a=null}})});async_save_text("workflow-name","workflow-name",rename_async_url,"new_name");$("#workflow-tag").click(function(){$(".tag-area").click();return false});async_save_text("workflow-annotation","workflow-annotation",annotate_async_url,"new_annotation",25,true,4)});function reset(){if(workflow){workflow.remove_all()}workflow=new Workflow($("#canvas-container"))}function scroll_to_nodes(){var a=$("#canvas-viewport");var d=$("#canvas-container");var c,b;if(d.width()<a.width()){b=(a.width()-d.width())/2}else{b=0}if(d.height()<a.height()){c=(a.height()-d.height())/2}else{c=0}d.css({left:b,top:c})}function add_node_for_tool(b,a){node=add_node("tool",a,b);$.ajax({url:get_new_module_info_url,data:{type:"tool",tool_id:b,_:"true"},global:false,dataType:"json",success:function(c){node.init_field_data(c)},error:function(d,f){var c="error loading field data";if(d.status===0){c+=", server unavailable"}node.error(c)}})}function add_node_for_module(a,b){node=add_node(a,b);$.ajax({url:get_new_module_info_url,data:{type:a,_:"true"},dataType:"json",success:function(c){node.init_field_data(c)},error:function(d,f){var c="error loading field data";if(d.status==0){c+=", server unavailable"}node.error(c)}})}function display_pja(b,a){$("#pja_container").append(get_pja_form(b));$("#pja_container>.toolForm:last>.toolFormTitle>.buttons").click(function(){action_to_rem=$(this).closest(".toolForm",".action_tag").children(".action_tag:first").text();$(this).closest(".toolForm").remove();delete workflow.active_node.post_job_actions[action_to_rem];workflow.active_form_has_changes=true})}function display_pja_list(){return pja_list}function display_file_list(b){addlist="<select id='node_data_list' name='node_data_list'>";for(var a in b.output_terminals){addlist+="<option value='"+a+"'>"+a+"</option>"}addlist+="</select>";return addlist}function new_pja(d,b,a){if(a.post_job_actions===undefined){a.post_job_actions={}}if(a.post_job_actions[d+b]===undefined){var c={};c.action_type=d;c.output_name=b;a.post_job_actions[d+b]=null;a.post_job_actions[d+b]=c;display_pja(c,a);workflow.active_form_has_changes=true;return true}else{return false}}function show_workflow_parameters(){var c=/\$\{.+?\}/g;var b=[];var f=$("#workflow-parameters-container");var e=$("#workflow-parameters-box");var a="";var d=[];$.each(workflow.nodes,function(g,h){var i=h.form_html.match(c);if(i){d=d.concat(i)}if(h.post_job_actions){$.each(h.post_job_actions,function(j,l){if(l.action_arguments){$.each(l.action_arguments,function(m,n){var o=n.match(c);if(o){d=d.concat(o)}})}});if(d){$.each(d,function(j,l){if($.inArray(l,b)===-1){b.push(l)}})}}});if(b&&b.length!==0){$.each(b,function(g,h){a+="<div>"+h.substring(2,h.length-1)+"</div>"});f.html(a);e.show()}else{f.html(a);e.hide()}}function show_form_for_tool(c,b){$(".right-content").hide();$("#right-content").show().html(c);if(b){$("#right-content").find(".toolForm:first").after("<p><div class='metadataForm'><div class='metadataFormTitle'>Edit Step Attributes</div><div class='form-row'><label>Annotation / Notes:</label><div style='margin-right: 10px;'><textarea name='annotation' rows='3' style='width: 100%'>"+b.annotation+"</textarea><div class='toolParamHelp'>Add an annotation or notes to this step; annotations are available when a workflow is viewed.</div></div></div></div>")}if(b&&b.type=="tool"){pjastr="<p><div class='metadataForm'><div class='metadataFormTitle'>Edit Step Actions</div><div class='form-row'> "+display_pja_list()+" <br/> "+display_file_list(b)+" <div class='action-button' style='border:1px solid black;display:inline;' id='add_pja'>Create</div></div><div class='form-row'><div style='margin-right: 10px;'><span id='pja_container'></span>";pjastr+="<div class='toolParamHelp'>Add actions to this step; actions are applied when this workflow step completes.</div></div></div></div>";$("#right-content").find(".toolForm").after(pjastr);for(var a in b.post_job_actions){if(a!="undefined"){display_pja(b.post_job_actions[a],b)}}$("#add_pja").click(function(){new_pja($("#new_pja_list").val(),$("#node_data_list").val(),b)})}$("#right-content").find("form").ajaxForm({type:"POST",dataType:"json",success:function(d){workflow.active_form_has_changes=false;b.update_field_data(d);show_workflow_parameters()},beforeSubmit:function(d){d.push({name:"tool_state",value:b.tool_state});d.push({name:"_",value:"true"})}}).each(function(){var d=this;$(this).find("select[refresh_on_change='true']").change(function(){$(d).submit()});$(this).find(".popupmenu").each(function(){var g=$(this).parents("div.form-row").attr("id");var e=$('<a class="popup-arrow" id="popup-arrow-for-'+g+'">▼</a>');var f={};$(this).find("button").each(function(){var h=$(this).attr("name");var i=$(this).attr("value");f[$(this).text()]=function(){$(d).append("<input type='hidden' name='"+h+"' value='"+i+"' />").submit()}});e.insertAfter(this);$(this).remove();make_popupmenu(e,f)});$(this).find("input,textarea,select").each(function(){$(this).bind("focus click",function(){workflow.active_form_has_changes=true})})})}var close_editor=function(){workflow.check_changes_in_active_form();if(workflow&&workflow.has_changes){do_close=function(){window.onbeforeunload=undefined;window.document.location=workflow_index_url};show_modal("Close workflow editor","There are unsaved changes to your workflow which will be lost.",{Cancel:hide_modal,"Save Changes":function(){save_current_workflow(null,do_close)}},{"Don't Save":do_close})}else{window.document.location=workflow_index_url}};var save_current_workflow=function(b,c){show_message("Saving workflow","progress");workflow.check_changes_in_active_form();if(!workflow.has_changes){hide_modal();if(c){c()}return}workflow.rectify_workflow_outputs();var a=function(d){$.ajax({url:save_workflow_url,type:"POST",data:{id:workflow_id,workflow_data:function(){return JSON.stringify(workflow.to_simple())},_:"true"},dataType:"json",success:function(g){var e=$("<div></div>").text(g.message);if(g.errors){e.addClass("warningmark");var f=$("<ul/>");$.each(g.errors,function(j,h){$("<li></li>").text(h).appendTo(f)});e.append(f)}else{e.addClass("donemark")}workflow.name=g.name;workflow.has_changes=false;workflow.stored=true;show_workflow_parameters();if(g.errors){show_modal("Saving workflow",e,{Ok:hide_modal})}else{if(d){d()}hide_modal()}}})};if(active_ajax_call){$(document).bind("ajaxStop.save_workflow",function(){$(document).unbind("ajaxStop.save_workflow");a();$(document).unbind("ajaxStop.save_workflow");active_ajax_call=false})}else{a(c)}};
\ No newline at end of file
diff -r acec53247232cffb773b2e4a8de67fd3bdc3424e -r 12e6db99d15193b700cbde74f31c71a2ef9bcc2d static/scripts/packed/utils/metrics-logger.js
--- /dev/null
+++ b/static/scripts/packed/utils/metrics-logger.js
@@ -0,0 +1,1 @@
+define([],function(){function h(z){z=z||{};var y=this;y.consoleLogger=z.consoleLogger||null;y._init(z);return y}h.ALL=0;h.DEBUG=10;h.INFO=20;h.WARN=30;h.ERROR=40;h.METRIC=50;h.NONE=100;h.defaultOptions={logLevel:h.INFO,consoleLevel:h.NONE,defaultNamespace:"Galaxy",clientPrefix:"client.",maxCacheSize:3000,postSize:1000,addTime:true,postUrl:"/api/metrics",postOnUnload:true,getPingData:undefined,onServerResponse:undefined};h.prototype._init=function i(A){var z=this;z.options={};for(var y in h.defaultOptions){if(h.defaultOptions.hasOwnProperty(y)){z.options[y]=(A.hasOwnProperty(y))?(A[y]):(h.defaultOptions[y])}}z.options.logLevel=z._parseLevel(z.options.logLevel);z.options.consoleLevel=z._parseLevel(z.options.consoleLevel);z._sending=false;z._postSize=z.options.postSize;z._initCache();if(z.options.postOnUnload){z.onpageunload=function B(C){C.preventDefault();z._postCache({count:z.cache.length()})};window.addEventListener("unload",z.onpageunload)}return z};h.prototype._initCache=function a(){this.cache=new w({maxSize:this.options.maxCacheSize})};h.prototype._parseLevel=function j(A){var z=typeof A;if(z==="number"){return A}var y=A.toUpperCase();if(z==="string"&&h.hasOwnProperty(y)){return h[y]}throw new Error("Unknown log level: "+A)};h.prototype.emit=function m(B,A,z){var y=this;A=A||y.options.defaultNamespace;if(!B||!z){return y}B=y._parseLevel(B);if(B>=y.options.logLevel){y._addToCache(B,A,z)}if(y.consoleLogger&&B>=y.options.consoleLevel){y._emitToConsole(B,A,z)}return y};h.prototype._addToCache=function b(D,A,z){this._emitToConsole("debug","MetricsLogger",["_addToCache:",arguments,this.options.addTime,this.cache.length()]);var y=this;try{var C=y.cache.add(y._buildEntry(D,A,z));if(C>=y._postSize){y._postCache()}}catch(B){if(y.options.consoleLevel<=h.WARN){console.warn("Metrics logger could not stringify logArguments:",A,z);console.error(B)}}return y};h.prototype._buildEntry=function r(B,z,y){this._emitToConsole("debug","MetricsLogger",["_buildEntry:",arguments]);var A={level:B,namespace:this.options.clientPrefix+z,args:y};if(this.options.addTime){A.time=new Date().toISOString()}return A};h.prototype._postCache=function s(B){B=B||{};this._emitToConsole("info","MetricsLogger",["_postCache",B,this._postSize]);if(!this.options.postUrl||this._sending){return jQuery.when({})}var A=this,D=B.count||A._postSize,y=A.cache.get(D),C=y.length,z=(typeof A.options.getPingData==="function")?(A.options.getPingData()):({});z.metrics=A._preprocessCache(y);A._sending=true;return jQuery.post(A.options.postUrl,z).always(function(){A._sending=false}).fail(function(){A._postSize=A.options.maxCacheSize}).done(function(E){if(typeof A.options.onServerResponse==="function"){A.options.onServerResponse(E)}A.cache.remove(C);console.debug("removed entries:",C,"size now:",A.cache.length());A._postSize=A.options.postSize})};h.prototype._preprocessCache=function f(y){return["[",(y.join(",\n")),"]"].join("\n")};h.prototype._emitToConsole=function c(C,B,A){var y=this;if(!y.consoleLogger){return y}var z=Array.prototype.slice.call(A,0);z.unshift(B);if(C>=h.METRIC&&typeof(y.consoleLogger.info)==="function"){return y.consoleLogger.info.apply(y.consoleLogger,z)}else{if(C>=h.ERROR&&typeof(y.consoleLogger.error)==="function"){return y.consoleLogger.error.apply(y.consoleLogger,z)}else{if(C>=h.WARN&&typeof(y.consoleLogger.warn)==="function"){y.consoleLogger.warn.apply(y.consoleLogger,z)}else{if(C>=h.INFO&&typeof(y.consoleLogger.info)==="function"){y.consoleLogger.info.apply(y.consoleLogger,z)}else{if(C>=h.DEBUG&&typeof(y.consoleLogger.debug)==="function"){y.consoleLogger.debug.apply(y.consoleLogger,z)}else{if(typeof(y.consoleLogger.log)==="function"){y.consoleLogger.log.apply(y.consoleLogger,z)}}}}}}return y};h.prototype.debug=function l(){this.emit(h.DEBUG,this.options.defaultNamespace,arguments)};h.prototype.log=function g(){this.emit(1,this.options.defaultNamespace,arguments)};h.prototype.info=function u(){this.emit(h.INFO,this.options.defaultNamespace,arguments)};h.prototype.warn=function t(){this.emit(h.WARN,this.options.defaultNamespace,arguments)};h.prototype.error=function p(){this.emit(h.ERROR,this.options.defaultNamespace,arguments)};h.prototype.metric=function n(){this.emit(h.METRIC,this.options.defaultNamespace,arguments)};function w(z){var y=this;y._cache=[];return y._init(z||{})}w.defaultOptions={maxSize:5000};w.prototype._init=function i(y){this.maxSize=y.maxSize||w.defaultOptions.maxSize;return this};w.prototype.add=function k(A){var z=this,y=(z.length()+1)-z.maxSize;if(y>0){z.remove(y)}z._cache.push(z._preprocessEntry(A));return z.length()};w.prototype._preprocessEntry=function q(y){return JSON.stringify(y)};w.prototype.length=function e(){return this._cache.length};w.prototype.get=function v(y){return this._cache.slice(0,y)};w.prototype.remove=function x(y){return this._cache.splice(0,y)};w.prototype.stringify=function o(y){return["[",(this.get(y).join(",\n")),"]"].join("\n")};w.prototype.print=function d(){this._cache.forEach(function(y){console.log(y)})};return{MetricsLogger:h}});
\ No newline at end of file
diff -r acec53247232cffb773b2e4a8de67fd3bdc3424e -r 12e6db99d15193b700cbde74f31c71a2ef9bcc2d static/scripts/utils/metrics-logger.js
--- /dev/null
+++ b/static/scripts/utils/metrics-logger.js
@@ -0,0 +1,386 @@
+define([
+], function(){
+/*global window, jQuery, console */
+/*=============================================================================
+TODO:
+ broken pipe due to onunload post in webkit, safari
+ need to use persistence
+
+=============================================================================*/
+/** @class MetricsLogger
+ *
+ * Object to cache, output, and post log/metric messages to the server.
+ * Meant to be attached to the Galaxy object.
+ *
+ * Log from objects by either attaching logger directly:
+ * panel.logger.metric( 'user dataset deletion', panel.user.id, hda.toJSON() )
+ * or using the LoggableMixin or addLogging function:
+ * MyBackboneModel.extend( LoggableMixin ).extend({ ... })
+ * addLogging( MyBackboneModel, 'my-backbone-model' )
+ *
+ * Log from templates by calling directly from Galaxy object:
+ * Galaxy.logger.metric( 'template loaded', { ownedByUser : true });
+ *
+ * If you attempt to log an un-serializable object (circular reference, window, etc.),
+ * that entry will not be cached (or sent). If you set consoleLevel and consoleLogger
+ * appropriately, a warning will be shown when this happens:
+ * > panel.metric( 'something weird with window', { window : window })
+ * !'Metrics logger could not stringify logArguments: ...'
+ */
+function MetricsLogger( options ){
+ options = options || {};
+ var self = this;
+
+ //TODO: this might be used if we store the logs in browser storage
+ ///** */
+ //self.userId = options.userId || null;
+
+ /** the (optional) console to emit logs to */
+ self.consoleLogger = options.consoleLogger || null;
+
+ self._init( options );
+ return self;
+}
+
+//----------------------------------------------------------------------------- defaults and constants
+// see: python std lib, logging
+MetricsLogger.ALL = 0;
+MetricsLogger.DEBUG = 10;
+MetricsLogger.INFO = 20;
+MetricsLogger.WARN = 30;
+MetricsLogger.ERROR = 40;
+// metrics levels here?
+//MetricsLogger.MinorEvent = 45;
+//MetricsLogger.MajorEvent = 50;
+MetricsLogger.METRIC = 50;
+MetricsLogger.NONE = 100;
+
+/** default options - override these through the constructor */
+MetricsLogger.defaultOptions = {
+ /** if an incoming message has a level >= this, it will be cached - can also be a string (e.g. 'debug') */
+ logLevel : MetricsLogger.INFO,
+ /** if an incoming message has a level >= this, it will be output to the console */
+ consoleLevel : MetricsLogger.NONE,
+ /** the default 'namespace' or label associated with an incoming message (if none is passed) */
+ defaultNamespace : 'Galaxy',
+ /** the prefix attached to client-side logs to distinguish them in the metrics db */
+ clientPrefix : 'client.',
+
+ /** the maximum number of messages the cache should hold; if exceeded older messages are removed first */
+ maxCacheSize : 3000,
+ /** the number of messages accumulate before posting to the server; should be <= maxCacheSize */
+ postSize : 1000,
+ /** T/F whether to add a timestamp to incoming cached messages */
+ addTime : true,
+
+ /** the relative url to post messages to */
+ postUrl : '/api/metrics',
+
+ /** post when the page is unloaded? */// needs to be true if using the LoggingCache (for now)
+ postOnUnload : true,
+
+ /** an (optional) function that should return an object; used to send additional data with the metrics */
+ getPingData : undefined,
+ /** an (optional) function that will handle the servers response after successfully posting messages */
+ onServerResponse : undefined
+};
+
+//----------------------------------------------------------------------------- set up
+/** initialize the logger with options, set up instance vars and cache, and add onpageunload to window */
+MetricsLogger.prototype._init = function _init( options ){
+ var self = this;
+ self.options = {};
+ for( var k in MetricsLogger.defaultOptions ){
+ if( MetricsLogger.defaultOptions.hasOwnProperty( k ) ){
+ self.options[ k ] = ( options.hasOwnProperty( k ) )?( options[ k ] ):( MetricsLogger.defaultOptions[ k ] );
+ }
+ }
+ self.options.logLevel = self._parseLevel( self.options.logLevel );
+ self.options.consoleLevel = self._parseLevel( self.options.consoleLevel );
+ //self._emitToConsole( 'debug', 'MetricsLogger', 'MetricsLogger.options:', self.options );
+
+ self._sending = false;
+ self._postSize = self.options.postSize;
+ self._initCache();
+
+ // post the entire cache on unload (since LoggingCache isn't persistent ATM)
+ if( self.options.postOnUnload ){
+ self.onpageunload = function onpageunload( ev ){
+ ev.preventDefault();
+ self._postCache({ count: self.cache.length() });
+ };
+ window.addEventListener( 'unload', self.onpageunload );
+ }
+
+ return self;
+};
+
+/** initialize the cache */
+MetricsLogger.prototype._initCache = function _initCache(){
+ this.cache = new LoggingCache({ maxSize : this.options.maxCacheSize });
+
+};
+
+/** return the numeric log level if level in 'none, debug, log, info, warn, error' */
+MetricsLogger.prototype._parseLevel = function _parseLevel( level ){
+ var type = typeof level;
+ if( type === 'number' ){ return level; }
+ var upper = level.toUpperCase();
+ if( type === 'string' && MetricsLogger.hasOwnProperty( upper ) ){
+ return MetricsLogger[ upper ];
+ }
+ throw new Error( 'Unknown log level: ' + level );
+};
+
+
+//----------------------------------------------------------------------------- main entry point
+/** record a log/message's arguments to the cache and/or the console based on level and namespace */
+MetricsLogger.prototype.emit = function emit( level, namespace, logArguments ){
+ //this._emitToConsole( 'debug', 'MetricsLogger', [ 'emit:', level, namespace, logArguments ]);
+ var self = this;
+ namespace = namespace || self.options.defaultNamespace;
+ if( !level || !logArguments ){
+ return self;
+ }
+ // add to cache if proper level
+//TODO: respect do not track?
+ //if( !navigator.doNotTrack && level >= self.options.logLevel ){
+ level = self._parseLevel( level );
+ if( level >= self.options.logLevel ){
+ self._addToCache( level, namespace, logArguments );
+ }
+ // also emit to consoleLogger if proper level for that
+ if( self.consoleLogger && level >= self.options.consoleLevel ){
+ self._emitToConsole( level, namespace, logArguments );
+ }
+ return self;
+};
+
+//----------------------------------------------------------------------------- cache
+/** add a message to the cache and if messages.length is high enough post them to the server */
+MetricsLogger.prototype._addToCache = function _addToCache( level, namespace, logArguments ){
+ this._emitToConsole( 'debug', 'MetricsLogger',
+ [ '_addToCache:', arguments, this.options.addTime, this.cache.length() ]);
+ //this._emitToConsole( 'debug', 'MetricsLogger', [ '\t logArguments:', logArguments ]);
+ var self = this;
+ // try add to the cache and if we've got _postSize number of entries, attempt to post them to the server
+ try {
+ var newLength = self.cache.add( self._buildEntry( level, namespace, logArguments ) );
+ if( newLength >= self._postSize ){
+ self._postCache();
+ }
+ // discard entry if an error occurs, but warn if level set to do so
+ } catch( err ){
+ if( self.options.consoleLevel <= MetricsLogger.WARN ){
+ console.warn( 'Metrics logger could not stringify logArguments:', namespace, logArguments );
+ console.error( err );
+ }
+ }
+ return self;
+};
+
+/** build a log cache entry object from the given level, namespace, and arguments (optionally adding timestamp */
+MetricsLogger.prototype._buildEntry = function _buildEntry( level, namespace, logArguments ){
+ this._emitToConsole( 'debug', 'MetricsLogger', [ '_buildEntry:', arguments ]);
+ var entry = {
+ level : level,
+ namespace : this.options.clientPrefix + namespace,
+ args : logArguments
+ };
+ if( this.options.addTime ){
+ entry.time = new Date().toISOString();
+ }
+ return entry;
+};
+
+/** post _postSize messages from the cache to the server, removing them if successful
+ * if the post fails, wait until maxCacheSize is accumulated instead and try again then
+ * in addition to the messages from the cache ('metrics'), any info from getPingData (if set) will be sent
+ * onServerResponse will be called (if set) with any response from the server
+ */
+MetricsLogger.prototype._postCache = function _postCache( options ){
+ options = options || {};
+ this._emitToConsole( 'info', 'MetricsLogger', [ '_postCache', options, this._postSize ]);
+//TODO: remove jq dependence
+
+ // short circuit if we're already sending
+ if( !this.options.postUrl || this._sending ){
+ return jQuery.when({});
+ }
+
+ var self = this,
+ postSize = options.count || self._postSize,
+ // do not splice - remove after *successful* post
+ entries = self.cache.get( postSize ),
+ entriesLength = entries.length,
+ // use the optional getPingData to add any extra info we may want to send
+ postData = ( typeof self.options.getPingData === 'function' )?( self.options.getPingData() ):( {} );
+ //console.debug( postSize, entriesLength );
+
+ // add the metrics and send
+ postData.metrics = self._preprocessCache( entries );
+ self._sending = true;
+ return jQuery.post( self.options.postUrl, postData )
+ .always( function(){
+ self._sending = false;
+ })
+ .fail( function(){
+ // if we failed the previous time, set the next post target to the max num of entries
+ self._postSize = self.options.maxCacheSize;
+ })
+ .done( function( response ){
+ if( typeof self.options.onServerResponse === 'function' ){
+ self.options.onServerResponse( response );
+ }
+ // only remove if post successful
+ self.cache.remove( entriesLength );
+ console.debug( 'removed entries:', entriesLength, 'size now:', self.cache.length() );
+ // if we succeeded, reset the post target to the normal num of entries
+ self._postSize = self.options.postSize;
+ });
+ // return the xhr promise
+};
+
+/** Preprocess a number of cache entries for sending to the server (stringification) */
+MetricsLogger.prototype._preprocessCache = function _preprocessCache( entries ){
+ return [ '[', ( entries.join( ',\n' ) ), ']' ].join( '\n' );
+ //return [ '[', ( entries.join( ',' ) ), ']' ].join( '' );
+};
+
+
+//----------------------------------------------------------------------------- console
+/** output message to console based on level and consoleLogger type */
+MetricsLogger.prototype._emitToConsole = function _emitToConsole( level, namespace, logArguments ){
+ //console.debug( '_emitToConsole:', level, namespace, logArguments );
+ var self = this;
+ if( !self.consoleLogger ){ return self; }
+
+ var args = Array.prototype.slice.call( logArguments, 0 );
+ args.unshift( namespace );
+//TODO: script location and/or source maps?
+//TODO: branch on navigator.userAgent == AIIEEE - it only has log
+ if( level >= MetricsLogger.METRIC && typeof( self.consoleLogger.info ) === 'function' ){
+ return self.consoleLogger.info.apply( self.consoleLogger, args );
+
+ } else if( level >= MetricsLogger.ERROR && typeof( self.consoleLogger.error ) === 'function' ){
+ return self.consoleLogger.error.apply( self.consoleLogger, args );
+ } else if( level >= MetricsLogger.WARN && typeof( self.consoleLogger.warn ) === 'function' ){
+ self.consoleLogger.warn.apply( self.consoleLogger, args );
+ } else if( level >= MetricsLogger.INFO && typeof( self.consoleLogger.info ) === 'function' ){
+ self.consoleLogger.info.apply( self.consoleLogger, args );
+ } else if( level >= MetricsLogger.DEBUG && typeof( self.consoleLogger.debug ) === 'function' ){
+ self.consoleLogger.debug.apply( self.consoleLogger, args );
+ } else if( typeof( self.consoleLogger.log ) === 'function' ){
+ self.consoleLogger.log.apply( self.consoleLogger, args );
+ }
+ return self;
+};
+
+//----------------------------------------------------------------------------- shortcuts
+// generic functions when logging from non-namespaced object (e.g. templates)
+/** debug to default namespace */
+MetricsLogger.prototype.debug = function debug(){
+ this.emit( MetricsLogger.DEBUG, this.options.defaultNamespace, arguments );
+};
+
+/** log to default namespace */
+MetricsLogger.prototype.log = function log(){
+ this.emit( 1, this.options.defaultNamespace, arguments );
+};
+
+/** info to default namespace */
+MetricsLogger.prototype.info = function info(){
+ this.emit( MetricsLogger.INFO, this.options.defaultNamespace, arguments );
+};
+
+/** warn to default namespace */
+MetricsLogger.prototype.warn = function warn(){
+ this.emit( MetricsLogger.WARN, this.options.defaultNamespace, arguments );
+};
+
+/** error to default namespace */
+MetricsLogger.prototype.error = function error(){
+ this.emit( MetricsLogger.ERROR, this.options.defaultNamespace, arguments );
+};
+
+/** metric to default namespace */
+MetricsLogger.prototype.metric = function metric(){
+ this.emit( MetricsLogger.METRIC, this.options.defaultNamespace, arguments );
+};
+
+
+//=============================================================================
+/** @class LoggingCache
+ * Simple implementation of cache wrapping an array.
+ *
+ * Formats an entry before it's cached and only keeps options.maxSize number
+ * of entries. Older entries are deleted first.
+ */
+function LoggingCache( options ){
+ var self = this;
+ self._cache = [];
+ return self._init( options || {} );
+}
+
+/** default options */
+LoggingCache.defaultOptions = {
+ /** maximum number of entries to keep before discarding oldest */
+ maxSize : 5000
+};
+
+/** initialize with options */
+LoggingCache.prototype._init = function _init( options ){
+ this.maxSize = options.maxSize || LoggingCache.defaultOptions.maxSize;
+ return this;
+};
+
+/** add an entry to the cache, removing the oldest beforehand if size >= maxSize */
+LoggingCache.prototype.add = function add( entry ){
+ var self = this,
+ overage = ( self.length() + 1 ) - self.maxSize;
+ if( overage > 0 ){
+ self.remove( overage );
+ }
+ self._cache.push( self._preprocessEntry( entry ) );
+ return self.length();
+};
+
+/** process the entry before caching */
+LoggingCache.prototype._preprocessEntry = function _preprocessEntry( entry ){
+ return JSON.stringify( entry );
+};
+
+/** return the length --- oh, getters where are you? */
+LoggingCache.prototype.length = function length(){
+ return this._cache.length;
+};
+
+/** get count number of entries starting with the oldest */
+LoggingCache.prototype.get = function get( count ){
+ return this._cache.slice( 0, count );
+};
+
+/** remove count number of entries starting with the oldest */
+LoggingCache.prototype.remove = function remove( count ){
+ return this._cache.splice( 0, count );
+};
+
+/** stringify count number of entries (but do not remove) */
+LoggingCache.prototype.stringify = function stringify( count ){
+ return [ '[', ( this.get( count ).join( ',\n' ) ), ']' ].join( '\n' );
+};
+
+/** outputs entire cache to console */
+LoggingCache.prototype.print = function print(){
+ // popup? (really, carl? a popup?) - easier to copy/paste
+ this._cache.forEach( function( entry ){
+ console.log( entry );
+ });
+};
+
+
+//=============================================================================
+ return {
+ MetricsLogger : MetricsLogger
+ };
+});
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: dan: Add a link to a tool's toolshed repository if it was installed from a ToolShed.
by commits-noreply@bitbucket.org 10 Apr '14
by commits-noreply@bitbucket.org 10 Apr '14
10 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/acec53247232/
Changeset: acec53247232
User: dan
Date: 2014-04-10 21:55:26
Summary: Add a link to a tool's toolshed repository if it was installed from a ToolShed.
Affected #: 1 file
diff -r c6d9b2f1b26b219b03a74c321202dc68160e9a15 -r acec53247232cffb773b2e4a8de67fd3bdc3424e templates/webapps/galaxy/tool_form.mako
--- a/templates/webapps/galaxy/tool_form.mako
+++ b/templates/webapps/galaxy/tool_form.mako
@@ -378,3 +378,10 @@
</div></div>
%endif
+%if tool.tool_shed_repository:
+ <% tool_url = tool.tool_shed_repository.get_sharable_url( tool.app ) %>
+ %if tool_url:
+ <br/>
+ ${ render_msg( 'This tool was installed from a ToolShed, you may be able to find additional information by following this link: <a href="%s" target="_blank">%s</a>' % ( tool_url, tool_url ), 'info' ) }
+ %endif
+%endif
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: martenson: forgotten files for previous commit
by commits-noreply@bitbucket.org 10 Apr '14
by commits-noreply@bitbucket.org 10 Apr '14
10 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/c6d9b2f1b26b/
Changeset: c6d9b2f1b26b
User: martenson
Date: 2014-04-10 21:07:01
Summary: forgotten files for previous commit
data libraries: API refactoring and improvements; backbone decoupling; role UI first implementation
Affected #: 4 files
diff -r a70f236803f7d398b4f486342e864add77e9ad3f -r c6d9b2f1b26b219b03a74c321202dc68160e9a15 static/scripts/mvc/library/library-folderrow-view.js
--- /dev/null
+++ b/static/scripts/mvc/library/library-folderrow-view.js
@@ -0,0 +1,310 @@
+// dependencies
+define([
+ "galaxy.masthead",
+ "utils/utils",
+ "libs/toastr",
+ "mvc/library/library-model"],
+function(mod_masthead,
+ mod_utils,
+ mod_toastr,
+ mod_library_model) {
+
+// galaxy library row view
+var FolderRowView = Backbone.View.extend({
+ // last selected history in modal for UX
+ lastSelectedHistory: '',
+
+ events: {
+ 'click .library-dataset' : 'showDatasetDetails'
+ },
+
+ options: {
+ type: null
+ },
+
+ initialize : function(folder_item){
+ this.render(folder_item);
+ },
+
+ render: function(folder_item){
+ // if (typeof folder_item === 'undefined'){
+ // folder_item = Galaxy.libraries.libraryFolderView.collection.get(this.$el.data('id'));
+ // }
+ var template = null;
+ if (folder_item.get('type') === 'folder'){
+ this.options.type = 'folder';
+ template = this.templateRowFolder();
+ } else {
+ this.options.type = 'file';
+ template = this.templateRowFile();
+ }
+ this.setElement(template({content_item:folder_item}));
+ this.$el.show();
+ return this;
+ },
+
+ //show modal with current dataset info
+ showDatasetDetails : function(event){
+ // prevent default
+ event.preventDefault();
+
+ var id = this.id;
+
+ //create new item
+ var item = new mod_library_model.Item();
+ var histories = new mod_library_model.GalaxyHistories();
+ item.id = id;
+ var self = this;
+
+ //fetch the dataset info
+ item.fetch({
+ success: function (item) {
+ // TODO can start rendering here already
+ //fetch user histories for import purposes
+ histories.fetch({
+ success: function (histories){
+ self.renderModalAfterFetch(item, histories);
+ },
+ error: function(){
+ mod_toastr.error('An error occured during fetching histories:(');
+ self.renderModalAfterFetch(item);
+ }
+ });
+ },
+ error: function(){
+ mod_toastr.error('An error occured during loading dataset details :(');
+ }
+ });
+},
+
+ // show the current dataset in a modal
+ renderModalAfterFetch : function(item, histories){
+ var size = this.size_to_string(item.get('file_size'));
+ var template = _.template(this.templateDatasetModal(), { item : item, size : size });
+ // make modal
+ var self = this;
+ this.modal = Galaxy.modal;
+ this.modal.show({
+ closing_events : true,
+ title : 'Dataset Details',
+ body : template,
+ buttons : {
+ 'Import' : function() { self.importCurrentIntoHistory(); },
+ 'Download' : function() { self.downloadCurrent(); },
+ 'Close' : function() { self.modal.hide(); }
+ }
+ });
+
+ $(".peek").html(item.get("peek"));
+
+ // show the import-into-history footer only if the request for histories succeeded
+ if (typeof history.models !== undefined){
+ var history_footer_tmpl = _.template(this.templateHistorySelectInModal(), {histories : histories.models});
+ $(this.modal.elMain).find('.buttons').prepend(history_footer_tmpl);
+ // preset last selected history if we know it
+ if (self.lastSelectedHistory.length > 0) {
+ $(this.modal.elMain).find('#dataset_import_single').val(self.lastSelectedHistory);
+ }
+ }
+ },
+
+ // TODO this is dup func, unify
+ // convert size to nice string
+ size_to_string : function (size){
+ // identify unit
+ var unit = "";
+ if (size >= 100000000000) { size = size / 100000000000; unit = "TB"; } else
+ if (size >= 100000000) { size = size / 100000000; unit = "GB"; } else
+ if (size >= 100000) { size = size / 100000; unit = "MB"; } else
+ if (size >= 100) { size = size / 100; unit = "KB"; } else
+ { size = size * 10; unit = "b"; }
+ // return formatted string
+ return (Math.round(size) / 10) + unit;
+ },
+
+ // download dataset shown currently in modal
+ downloadCurrent : function(){
+ //disable the buttons
+ this.modal.disableButton('Import');
+ this.modal.disableButton('Download');
+
+ var library_dataset_id = [];
+ library_dataset_id.push($('#id_row').attr('data-id'));
+ var url = '/api/libraries/datasets/download/uncompressed';
+ var data = {'ldda_ids' : library_dataset_id};
+
+ this.processDownload(url, data);
+ this.modal.enableButton('Import');
+ this.modal.enableButton('Download');
+ },
+
+ // TODO this is dup func, unify
+ // create hidden form and submit through POST to initialize download
+ processDownload: function(url, data, method){
+ //url and data options required
+ if( url && data ){
+ //data can be string of parameters or array/object
+ data = typeof data == 'string' ? data : $.param(data);
+ //split params into form inputs
+ var inputs = '';
+ $.each(data.split('&'), function(){
+ var pair = this.split('=');
+ inputs+='<input type="hidden" name="'+ pair[0] +'" value="'+ pair[1] +'" />';
+ });
+ //send request
+ $('<form action="'+ url +'" method="'+ (method||'post') +'">'+inputs+'</form>')
+ .appendTo('body').submit().remove();
+
+ mod_toastr.info('Your download will begin soon');
+ }
+ },
+
+ // import dataset shown currently in modal into selected history
+ importCurrentIntoHistory : function(){
+ //disable the buttons
+ this.modal.disableButton('Import');
+ this.modal.disableButton('Download');
+
+ var history_id = $(this.modal.elMain).find('select[name=dataset_import_single] option:selected').val();
+ this.lastSelectedHistory = history_id; //save selected history for further use
+
+ var library_dataset_id = $('#id_row').attr('data-id');
+ var historyItem = new mod_library_model.HistoryItem();
+ var self = this;
+ historyItem.url = historyItem.urlRoot + history_id + '/contents';
+
+ // save the dataset into selected history
+ historyItem.save({ content : library_dataset_id, source : 'library' }, { success : function(){
+ mod_toastr.success('Dataset imported');
+ //enable the buttons
+ self.modal.enableButton('Import');
+ self.modal.enableButton('Download');
+ }, error : function(){
+ mod_toastr.error('An error occured! Dataset not imported. Please try again.');
+ //enable the buttons
+ self.modal.enableButton('Import');
+ self.modal.enableButton('Download');
+ }
+ });
+ },
+
+ templateRowFolder: function() {
+ tmpl_array = [];
+
+ tmpl_array.push('<tr class="folder_row light" id="<%- content_item.id %>">');
+ tmpl_array.push(' <td>');
+ tmpl_array.push(' <span title="Folder" class="fa fa-folder-o"></span>');
+ tmpl_array.push(' </td>');
+ tmpl_array.push(' <td></td>');
+ tmpl_array.push(' <td>');
+ tmpl_array.push(' <a href="#folders/<%- content_item.id %>"><%- content_item.get("name") %></a>');
+ tmpl_array.push(' <% if (content_item.get("item_count") === 0) { %>'); // empty folder
+ tmpl_array.push(' <span>(empty folder)</span>');
+ tmpl_array.push(' <% } %>');
+ tmpl_array.push(' </td>');
+ tmpl_array.push(' <td>folder</td>');
+ tmpl_array.push(' <td><%= _.escape(content_item.get("item_count")) %> item(s)</td>'); // size
+ tmpl_array.push(' <td><%= _.escape(content_item.get("time_updated")) %></td>'); // time updated
+ tmpl_array.push('</tr>');
+
+ return _.template(tmpl_array.join(''));
+ },
+
+ templateRowFile: function(){
+ tmpl_array = [];
+
+ tmpl_array.push('<tr class="dataset_row light" id="<%- content_item.id %>">');
+ tmpl_array.push(' <td>');
+ tmpl_array.push(' <span title="Dataset" class="fa fa-file-o"></span>');
+ tmpl_array.push(' </td>');
+ tmpl_array.push(' <td style="text-align: center; "><input style="margin: 0;" type="checkbox"></td>');
+ tmpl_array.push(' <td><a href="#" class="library-dataset"><%- content_item.get("name") %><a></td>'); // dataset
+ tmpl_array.push(' <td><%= _.escape(content_item.get("data_type")) %></td>'); // data type
+ tmpl_array.push(' <td><%= _.escape(content_item.get("readable_size")) %></td>'); // size
+ tmpl_array.push(' <td><%= _.escape(content_item.get("time_updated")) %></td>'); // time updated
+ tmpl_array.push('</tr>');
+
+ return _.template(tmpl_array.join(''));
+ },
+
+templateDatasetModal : function(){
+ var tmpl_array = [];
+
+ tmpl_array.push('<div class="modal_table">');
+ tmpl_array.push(' <table class="grid table table-striped table-condensed">');
+ tmpl_array.push(' <tr>');
+ tmpl_array.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');
+ tmpl_array.push(' <td><%= _.escape(item.get("name")) %></td>');
+ tmpl_array.push(' </tr>');
+ tmpl_array.push(' <tr>');
+ tmpl_array.push(' <th scope="row">Data type</th>');
+ tmpl_array.push(' <td><%= _.escape(item.get("data_type")) %></td>');
+ tmpl_array.push(' </tr>');
+ tmpl_array.push(' <tr>');
+ tmpl_array.push(' <th scope="row">Genome build</th>');
+ tmpl_array.push(' <td><%= _.escape(item.get("genome_build")) %></td>');
+ tmpl_array.push(' </tr>');
+ tmpl_array.push(' <th scope="row">Size</th>');
+ tmpl_array.push(' <td><%= _.escape(size) %></td>');
+ tmpl_array.push(' </tr>');
+ tmpl_array.push(' <tr>');
+ tmpl_array.push(' <th scope="row">Date uploaded (UTC)</th>');
+ tmpl_array.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');
+ tmpl_array.push(' </tr>');
+ tmpl_array.push(' <tr>');
+ tmpl_array.push(' <th scope="row">Uploaded by</th>');
+ tmpl_array.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');
+ tmpl_array.push(' </tr>');
+ tmpl_array.push(' <tr scope="row">');
+ tmpl_array.push(' <th scope="row">Data Lines</th>');
+ tmpl_array.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');
+ tmpl_array.push(' </tr>');
+ tmpl_array.push(' <th scope="row">Comment Lines</th>');
+ tmpl_array.push(' <% if (item.get("metadata_comment_lines") === "") { %>');
+ tmpl_array.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');
+ tmpl_array.push(' <% } else { %>');
+ tmpl_array.push(' <td scope="row">unknown</td>');
+ tmpl_array.push(' <% } %>');
+ tmpl_array.push(' </tr>');
+ tmpl_array.push(' <tr>');
+ tmpl_array.push(' <th scope="row">Number of Columns</th>');
+ tmpl_array.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');
+ tmpl_array.push(' </tr>');
+ tmpl_array.push(' <tr>');
+ tmpl_array.push(' <th scope="row">Column Types</th>');
+ tmpl_array.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');
+ tmpl_array.push(' </tr>');
+ tmpl_array.push(' <tr>');
+ tmpl_array.push(' <th scope="row">Miscellaneous information</th>');
+ tmpl_array.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');
+ tmpl_array.push(' </tr>');
+ tmpl_array.push(' </table>');
+ tmpl_array.push(' <pre class="peek">');
+ tmpl_array.push(' </pre>');
+ tmpl_array.push('</div>');
+
+ return tmpl_array.join('');
+},
+
+templateHistorySelectInModal : function(){
+ var tmpl_array = [];
+
+ tmpl_array.push('<span id="history_modal_combo" style="width:100%; margin-left: 1em; margin-right: 1em; ">');
+ tmpl_array.push('Select history: ');
+ tmpl_array.push('<select id="dataset_import_single" name="dataset_import_single" style="width:40%; margin-bottom: 1em; "> ');
+ tmpl_array.push(' <% _.each(histories, function(history) { %>'); //history select box
+ tmpl_array.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');
+ tmpl_array.push(' <% }); %>');
+ tmpl_array.push('</select>');
+ tmpl_array.push('</span>');
+
+ return tmpl_array.join('');
+}
+
+});
+
+return {
+ FolderRowView: FolderRowView
+};
+
+});
diff -r a70f236803f7d398b4f486342e864add77e9ad3f -r c6d9b2f1b26b219b03a74c321202dc68160e9a15 static/scripts/mvc/library/library-foldertoolbar-view.js
--- /dev/null
+++ b/static/scripts/mvc/library/library-foldertoolbar-view.js
@@ -0,0 +1,320 @@
+// dependencies
+define([
+ "galaxy.masthead",
+ "utils/utils",
+ "libs/toastr",
+ "mvc/library/library-model"],
+function(mod_masthead,
+ mod_utils,
+ mod_toastr,
+ mod_library_model) {
+
+var FolderToolbarView = Backbone.View.extend({
+ el: '#center',
+
+ events: {
+ 'click #toolbtn_create_folder' : 'createFolderFromModal',
+ 'click #toolbtn_bulk_import' : 'modalBulkImport'
+ },
+
+ defaults: {
+ 'can_add_library_item' : false,
+ 'contains_file' : false
+ },
+
+ modal : null,
+
+ initialize: function(options){
+ this.options = _.defaults(options || {}, this.defaults);
+ this.render();
+ },
+
+ render: function(options){
+ this.options = _.extend(this.options, options);
+ var toolbar_template = this.templateToolBar();
+ var is_admin = Galaxy.currUser.isAdmin();
+ this.$el.html(toolbar_template({id: this.options.id, admin_user: is_admin}));
+ },
+
+ configureElements: function(options){
+ this.options = _.extend(this.options, options);
+ if (this.options.can_add_library_item === true){
+ $('#toolbtn_create_folder').show();
+ $('#toolbtn_upload_files').show();
+ }
+ if (this.options.contains_file === true){
+ $('#toolbtn_bulk_import').show();
+ $('#toolbtn_dl').show();
+ }
+ this.$el.find('[data-toggle]').tooltip();
+ },
+
+ // shows modal for creating folder
+ createFolderFromModal: function(){
+ event.preventDefault();
+ event.stopPropagation();
+
+ // create modal
+ var self = this;
+ var template = this.templateNewFolderInModal();
+ this.modal = Galaxy.modal;
+ this.modal.show({
+ closing_events : true,
+ title : 'Create New Folder',
+ body : template(),
+ buttons : {
+ 'Create' : function() {self.create_new_folder_event();},
+ 'Close' : function() {self.modal.hide(); self.modal = null;}
+ }
+ });
+ },
+
+ // create the new folder from modal
+ create_new_folder_event: function(){
+ var folderDetails = this.serialize_new_folder();
+ if (this.validate_new_folder(folderDetails)){
+ var folder = new mod_library_model.FolderAsModel();
+ url_items = Backbone.history.fragment.split('/');
+ current_folder_id = url_items[url_items.length-1];
+ folder.url = folder.urlRoot + '/' + current_folder_id ;
+
+ var self = this;
+ folder.save(folderDetails, {
+ success: function (folder) {
+ self.modal.hide();
+ mod_toastr.success('Folder created');
+ Galaxy.libraries.folderListView.render({id: current_folder_id});
+ },
+ error: function(){
+ mod_toastr.error('An error occured :(');
+ }
+ });
+ } else {
+ mod_toastr.error('Folder\'s name is missing');
+ }
+ return false;
+ },
+
+ // serialize data from the modal
+ serialize_new_folder : function(){
+ return {
+ name: $("input[name='Name']").val(),
+ description: $("input[name='Description']").val()
+ };
+ },
+
+ // validate new folder info
+ validate_new_folder: function(folderDetails){
+ return folderDetails.name !== '';
+ },
+
+
+ // show bulk import modal
+ modalBulkImport : function(){
+ var checkedValues = $('#folder_table').find(':checked');
+ if(checkedValues.length === 0){
+ mod_toastr.info('You have to select some datasets first');
+ } else {
+ var self = this;
+ // fetch histories
+ var template = this.templateBulkImportInModal();
+ var histories = new mod_library_model.GalaxyHistories();
+ histories.fetch({
+ success: function (histories){
+ // make modal
+ // var history_modal_tmpl = template({histories : histories.models});
+ self.modal = Galaxy.modal;
+ self.modal.show({
+ closing_events : true,
+ title : 'Import into History',
+ body : template({histories : histories.models}),
+ buttons : {
+ 'Import' : function() {self.importAllIntoHistory();},
+ 'Close' : function() {self.modal.hide();}
+ }
+ });
+ },
+ error: function(){
+ mod_toastr.error('An error occured :(');
+ }
+ });
+ }
+ },
+
+ // import all selected datasets into history
+ importAllIntoHistory : function (){
+ //disable the button to prevent multiple submission
+ this.modal.disableButton('Import');
+
+ var history_id = $("select[name=dataset_import_bulk] option:selected").val();
+ var history_name = $("select[name=dataset_import_bulk] option:selected").text();
+
+ var dataset_ids = [];
+ $('#folder_table').find(':checked').each(function(){
+ if (this.parentElement.parentElement.id !== '') {
+ dataset_ids.push(this.parentElement.parentElement.id);
+ }
+ });
+ var progress_bar_tmpl = this.templateProgressBar();
+ $(this.modal.elMain).find('.modal-body').html(progress_bar_tmpl({ history_name : history_name }));
+
+ // init the progress bar
+ var progressStep = 100 / dataset_ids.length;
+ this.initProgress(progressStep);
+
+ // prepare the dataset objects to be imported
+ var datasets_to_import = [];
+ for (var i = dataset_ids.length - 1; i >= 0; i--) {
+ library_dataset_id = dataset_ids[i];
+ var historyItem = new mod_library_model.HistoryItem();
+ var self = this;
+ historyItem.url = historyItem.urlRoot + history_id + '/contents';
+ historyItem.content = library_dataset_id;
+ historyItem.source = 'library';
+ datasets_to_import.push(historyItem);
+ }
+ // call the recursive function to call ajax one after each other (request FIFO queue)
+ this.chainCall(datasets_to_import);
+ },
+
+ chainCall: function(history_item_set){
+ var self = this;
+ var popped_item = history_item_set.pop();
+ if (typeof popped_item === "undefined") {
+ mod_toastr.success('All datasets imported');
+ this.modal.hide();
+ return;
+ }
+ var promise = $.when(popped_item.save({content: popped_item.content, source: popped_item.source})).done(function(a1){
+ self.updateProgress();
+ self.chainCall(history_item_set);
+ });
+ },
+
+ initProgress: function(progressStep){
+ this.progress = 0;
+ this.progressStep = progressStep;
+ },
+
+ updateProgress: function(){
+ this.progress += this.progressStep;
+ $('.progress-bar-import').width(Math.round(this.progress) + '%');
+ txt_representation = Math.round(this.progress) + '% Complete';
+ $('.completion_span').text(txt_representation);
+ },
+
+ // download selected datasets
+ download : function(folder_id, format){
+ var dataset_ids = [];
+ $('#folder_table').find(':checked').each(function(){
+ if (this.parentElement.parentElement.id !== '') {
+ dataset_ids.push(this.parentElement.parentElement.id);
+ }
+ });
+
+ var url = '/api/libraries/datasets/download/' + format;
+ var data = {'ldda_ids' : dataset_ids};
+ this.processDownload(url, data, 'get');
+ },
+
+ // create hidden form and submit through POST to initialize download
+ processDownload: function(url, data, method){
+ //url and data options required
+ if( url && data ){
+ //data can be string of parameters or array/object
+ data = typeof data == 'string' ? data : $.param(data);
+ //split params into form inputs
+ var inputs = '';
+ $.each(data.split('&'), function(){
+ var pair = this.split('=');
+ inputs+='<input type="hidden" name="'+ pair[0] +'" value="'+ pair[1] +'" />';
+ });
+ //send request
+ $('<form action="'+ url +'" method="'+ (method||'post') +'">'+inputs+'</form>')
+ .appendTo('body').submit().remove();
+
+ mod_toastr.info('Your download will begin soon');
+ }
+ },
+
+ templateToolBar: function(){
+ tmpl_array = [];
+
+ // CONTAINER
+ tmpl_array.push('<div class="library_style_container">');
+ tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');
+ // TOOLBAR
+ tmpl_array.push('<div id="library_folder_toolbar" >');
+ tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Create New Folder" id="toolbtn_create_folder" class="primary-button" type="button" style="display:none;"><span class="fa fa-plus"></span><span class="fa fa-folder-close"></span> folder</button>');
+ tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Upload Files to Current Folder" id="toolbtn_upload_files" class="primary-button" type="button" style="display:none;"><span class="fa fa-upload"></span> upload</button>');
+ tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button" style="margin-left: 0.5em; display:none;" type="button"><span class="fa fa-book"></span> to history</button>');
+ tmpl_array.push(' <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; display:none; ">');
+ tmpl_array.push(' <button title="Download selected datasets" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');
+ tmpl_array.push(' <span class="fa fa-download"></span> download <span class="caret"></span>');
+ tmpl_array.push(' </button>');
+ tmpl_array.push(' <ul class="dropdown-menu" role="menu">');
+ tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');
+ tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');
+ tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');
+ tmpl_array.push(' </ul>');
+ tmpl_array.push(' </div>');
+ tmpl_array.push(' </div>');
+ tmpl_array.push(' <div id="folder_items_element">');
+ // library items will append here
+ tmpl_array.push(' </div>');
+ tmpl_array.push('</div>');
+
+ return _.template(tmpl_array.join(''));
+ },
+
+ templateNewFolderInModal: function(){
+ tmpl_array = [];
+
+ tmpl_array.push('<div id="new_folder_modal">');
+ tmpl_array.push('<form>');
+ tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');
+ tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');
+ tmpl_array.push('</form>');
+ tmpl_array.push('</div>');
+
+ return _.template(tmpl_array.join(''));
+ },
+
+
+ templateBulkImportInModal : function(){
+ var tmpl_array = [];
+
+ tmpl_array.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');
+ tmpl_array.push('Select history: ');
+ tmpl_array.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');
+ tmpl_array.push(' <% _.each(histories, function(history) { %>'); //history select box
+ tmpl_array.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');
+ tmpl_array.push(' <% }); %>');
+ tmpl_array.push('</select>');
+ tmpl_array.push('</span>');
+
+ return _.template(tmpl_array.join(''));
+ },
+
+ templateProgressBar : function (){
+ var tmpl_array = [];
+
+ tmpl_array.push('<div class="import_text">');
+ tmpl_array.push('Importing selected datasets to history <b><%= _.escape(history_name) %></b>');
+ tmpl_array.push('</div>');
+ tmpl_array.push('<div class="progress">');
+ tmpl_array.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');
+ tmpl_array.push(' <span class="completion_span">0% Complete</span>');
+ tmpl_array.push(' </div>');
+ tmpl_array.push('</div>');
+ tmpl_array.push('');
+
+ return _.template(tmpl_array.join(''));
+ }
+});
+
+return {
+ FolderToolbarView: FolderToolbarView
+};
+
+});
diff -r a70f236803f7d398b4f486342e864add77e9ad3f -r c6d9b2f1b26b219b03a74c321202dc68160e9a15 static/scripts/packed/mvc/library/library-folderrow-view.js
--- /dev/null
+++ b/static/scripts/packed/mvc/library/library-folderrow-view.js
@@ -0,0 +1,1 @@
+define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(b,d,e,c){var a=Backbone.View.extend({lastSelectedHistory:"",events:{"click .library-dataset":"showDatasetDetails"},options:{type:null},initialize:function(f){this.render(f)},render:function(f){var g=null;if(f.get("type")==="folder"){this.options.type="folder";g=this.templateRowFolder()}else{this.options.type="file";g=this.templateRowFile()}this.setElement(g({content_item:f}));this.$el.show();return this},showDatasetDetails:function(i){i.preventDefault();var j=this.id;var h=new c.Item();var g=new c.GalaxyHistories();h.id=j;var f=this;h.fetch({success:function(k){g.fetch({success:function(l){f.renderModalAfterFetch(k,l)},error:function(){e.error("An error occured during fetching histories:(");f.renderModalAfterFetch(k)}})},error:function(){e.error("An error occured during loading dataset details :(")}})},renderModalAfterFetch:function(k,h){var i=this.size_to_string(k.get("file_size"));var j=_.template(this.templateDatasetModal(),{item:k,size:i});var g=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Dataset Details",body:j,buttons:{Import:function(){g.importCurrentIntoHistory()},Download:function(){g.downloadCurrent()},Close:function(){g.modal.hide()}}});$(".peek").html(k.get("peek"));if(typeof history.models!==undefined){var f=_.template(this.templateHistorySelectInModal(),{histories:h.models});$(this.modal.elMain).find(".buttons").prepend(f);if(g.lastSelectedHistory.length>0){$(this.modal.elMain).find("#dataset_import_single").val(g.lastSelectedHistory)}}},size_to_string:function(f){var g="";if(f>=100000000000){f=f/100000000000;g="TB"}else{if(f>=100000000){f=f/100000000;g="GB"}else{if(f>=100000){f=f/100000;g="MB"}else{if(f>=100){f=f/100;g="KB"}else{f=f*10;g="b"}}}}return(Math.round(f)/10)+g},downloadCurrent:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var f=[];f.push($("#id_row").attr("data-id"));var g="/api/libraries/datasets/download/uncompressed";var h={ldda_ids:f};this.processDownload(g,h);this.modal.enableButton("Import");this.modal.enableButton("Download")},processDownload:function(g,h,i){if(g&&h){h=typeof h=="string"?h:$.param(h);var f="";$.each(h.split("&"),function(){var j=this.split("=");f+='<input type="hidden" name="'+j[0]+'" value="'+j[1]+'" />'});$('<form action="'+g+'" method="'+(i||"post")+'">'+f+"</form>").appendTo("body").submit().remove();e.info("Your download will begin soon")}},importCurrentIntoHistory:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var h=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();this.lastSelectedHistory=h;var f=$("#id_row").attr("data-id");var i=new c.HistoryItem();var g=this;i.url=i.urlRoot+h+"/contents";i.save({content:f,source:"library"},{success:function(){e.success("Dataset imported");g.modal.enableButton("Import");g.modal.enableButton("Download")},error:function(){e.error("An error occured! Dataset not imported. Please try again.");g.modal.enableButton("Import");g.modal.enableButton("Download")}})},templateRowFolder:function(){tmpl_array=[];tmpl_array.push('<tr class="folder_row light" id="<%- content_item.id %>">');tmpl_array.push(" <td>");tmpl_array.push(' <span title="Folder" class="fa fa-folder-o"></span>');tmpl_array.push(" </td>");tmpl_array.push(" <td></td>");tmpl_array.push(" <td>");tmpl_array.push(' <a href="#folders/<%- content_item.id %>"><%- content_item.get("name") %></a>');tmpl_array.push(' <% if (content_item.get("item_count") === 0) { %>');tmpl_array.push(" <span>(empty folder)</span>");tmpl_array.push(" <% } %>");tmpl_array.push(" </td>");tmpl_array.push(" <td>folder</td>");tmpl_array.push(' <td><%= _.escape(content_item.get("item_count")) %> item(s)</td>');tmpl_array.push(' <td><%= _.escape(content_item.get("time_updated")) %></td>');tmpl_array.push("</tr>");return _.template(tmpl_array.join(""))},templateRowFile:function(){tmpl_array=[];tmpl_array.push('<tr class="dataset_row light" id="<%- content_item.id %>">');tmpl_array.push(" <td>");tmpl_array.push(' <span title="Dataset" class="fa fa-file-o"></span>');tmpl_array.push(" </td>");tmpl_array.push(' <td style="text-align: center; "><input style="margin: 0;" type="checkbox"></td>');tmpl_array.push(' <td><a href="#" class="library-dataset"><%- content_item.get("name") %><a></td>');tmpl_array.push(' <td><%= _.escape(content_item.get("data_type")) %></td>');tmpl_array.push(' <td><%= _.escape(content_item.get("readable_size")) %></td>');tmpl_array.push(' <td><%= _.escape(content_item.get("time_updated")) %></td>');tmpl_array.push("</tr>");return _.template(tmpl_array.join(""))},templateDatasetModal:function(){var f=[];f.push('<div class="modal_table">');f.push(' <table class="grid table table-striped table-condensed">');f.push(" <tr>");f.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');f.push(' <td><%= _.escape(item.get("name")) %></td>');f.push(" </tr>");f.push(" <tr>");f.push(' <th scope="row">Data type</th>');f.push(' <td><%= _.escape(item.get("data_type")) %></td>');f.push(" </tr>");f.push(" <tr>");f.push(' <th scope="row">Genome build</th>');f.push(' <td><%= _.escape(item.get("genome_build")) %></td>');f.push(" </tr>");f.push(' <th scope="row">Size</th>');f.push(" <td><%= _.escape(size) %></td>");f.push(" </tr>");f.push(" <tr>");f.push(' <th scope="row">Date uploaded (UTC)</th>');f.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');f.push(" </tr>");f.push(" <tr>");f.push(' <th scope="row">Uploaded by</th>');f.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');f.push(" </tr>");f.push(' <tr scope="row">');f.push(' <th scope="row">Data Lines</th>');f.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');f.push(" </tr>");f.push(' <th scope="row">Comment Lines</th>');f.push(' <% if (item.get("metadata_comment_lines") === "") { %>');f.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');f.push(" <% } else { %>");f.push(' <td scope="row">unknown</td>');f.push(" <% } %>");f.push(" </tr>");f.push(" <tr>");f.push(' <th scope="row">Number of Columns</th>');f.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');f.push(" </tr>");f.push(" <tr>");f.push(' <th scope="row">Column Types</th>');f.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');f.push(" </tr>");f.push(" <tr>");f.push(' <th scope="row">Miscellaneous information</th>');f.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');f.push(" </tr>");f.push(" </table>");f.push(' <pre class="peek">');f.push(" </pre>");f.push("</div>");return f.join("")},templateHistorySelectInModal:function(){var f=[];f.push('<span id="history_modal_combo" style="width:100%; margin-left: 1em; margin-right: 1em; ">');f.push("Select history: ");f.push('<select id="dataset_import_single" name="dataset_import_single" style="width:40%; margin-bottom: 1em; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</span>");return f.join("")}});return{FolderRowView:a}});
\ No newline at end of file
diff -r a70f236803f7d398b4f486342e864add77e9ad3f -r c6d9b2f1b26b219b03a74c321202dc68160e9a15 static/scripts/packed/mvc/library/library-foldertoolbar-view.js
--- /dev/null
+++ b/static/scripts/packed/mvc/library/library-foldertoolbar-view.js
@@ -0,0 +1,1 @@
+define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(b,d,e,c){var a=Backbone.View.extend({el:"#center",events:{"click #toolbtn_create_folder":"createFolderFromModal","click #toolbtn_bulk_import":"modalBulkImport"},defaults:{can_add_library_item:false,contains_file:false},modal:null,initialize:function(f){this.options=_.defaults(f||{},this.defaults);this.render()},render:function(f){this.options=_.extend(this.options,f);var h=this.templateToolBar();var g=Galaxy.currUser.isAdmin();this.$el.html(h({id:this.options.id,admin_user:g}))},configureElements:function(f){this.options=_.extend(this.options,f);if(this.options.can_add_library_item===true){$("#toolbtn_create_folder").show();$("#toolbtn_upload_files").show()}if(this.options.contains_file===true){$("#toolbtn_bulk_import").show();$("#toolbtn_dl").show()}this.$el.find("[data-toggle]").tooltip()},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var f=this;var g=this.templateNewFolderInModal();this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Folder",body:g(),buttons:{Create:function(){f.create_new_folder_event()},Close:function(){f.modal.hide();f.modal=null}}})},create_new_folder_event:function(){var f=this.serialize_new_folder();if(this.validate_new_folder(f)){var h=new c.FolderAsModel();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];h.url=h.urlRoot+"/"+current_folder_id;var g=this;h.save(f,{success:function(i){g.modal.hide();e.success("Folder created");Galaxy.libraries.folderListView.render({id:current_folder_id})},error:function(){e.error("An error occured :(")}})}else{e.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(f){return f.name!==""},modalBulkImport:function(){var f=$("#folder_table").find(":checked");if(f.length===0){e.info("You have to select some datasets first")}else{var h=this;var i=this.templateBulkImportInModal();var g=new c.GalaxyHistories();g.fetch({success:function(j){h.modal=Galaxy.modal;h.modal.show({closing_events:true,title:"Import into History",body:i({histories:j.models}),buttons:{Import:function(){h.importAllIntoHistory()},Close:function(){h.modal.hide()}}})},error:function(){e.error("An error occured :(")}})}},importAllIntoHistory:function(){this.modal.disableButton("Import");var h=$("select[name=dataset_import_bulk] option:selected").val();var m=$("select[name=dataset_import_bulk] option:selected").text();var o=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){o.push(this.parentElement.parentElement.id)}});var n=this.templateProgressBar();$(this.modal.elMain).find(".modal-body").html(n({history_name:m}));var j=100/o.length;this.initProgress(j);var f=[];for(var g=o.length-1;g>=0;g--){library_dataset_id=o[g];var k=new c.HistoryItem();var l=this;k.url=k.urlRoot+h+"/contents";k.content=library_dataset_id;k.source="library";f.push(k)}this.chainCall(f)},chainCall:function(g){var f=this;var h=g.pop();if(typeof h==="undefined"){e.success("All datasets imported");this.modal.hide();return}var i=$.when(h.save({content:h.content,source:h.source})).done(function(j){f.updateProgress();f.chainCall(g)})},initProgress:function(f){this.progress=0;this.progressStep=f},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(f,j){var h=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){h.push(this.parentElement.parentElement.id)}});var g="/api/libraries/datasets/download/"+j;var i={ldda_ids:h};this.processDownload(g,i,"get")},processDownload:function(g,h,i){if(g&&h){h=typeof h=="string"?h:$.param(h);var f="";$.each(h.split("&"),function(){var j=this.split("=");f+='<input type="hidden" name="'+j[0]+'" value="'+j[1]+'" />'});$('<form action="'+g+'" method="'+(i||"post")+'">'+f+"</form>").appendTo("body").submit().remove();e.info("Your download will begin soon")}},templateToolBar:function(){tmpl_array=[];tmpl_array.push('<div class="library_style_container">');tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');tmpl_array.push('<div id="library_folder_toolbar" >');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Create New Folder" id="toolbtn_create_folder" class="primary-button" type="button" style="display:none;"><span class="fa fa-plus"></span><span class="fa fa-folder-close"></span> folder</button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Upload Files to Current Folder" id="toolbtn_upload_files" class="primary-button" type="button" style="display:none;"><span class="fa fa-upload"></span> upload</button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button" style="margin-left: 0.5em; display:none;" type="button"><span class="fa fa-book"></span> to history</button>');tmpl_array.push(' <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; display:none; ">');tmpl_array.push(' <button title="Download selected datasets" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');tmpl_array.push(' <span class="fa fa-download"></span> download <span class="caret"></span>');tmpl_array.push(" </button>");tmpl_array.push(' <ul class="dropdown-menu" role="menu">');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');tmpl_array.push(" </ul>");tmpl_array.push(" </div>");tmpl_array.push(" </div>");tmpl_array.push(' <div id="folder_items_element">');tmpl_array.push(" </div>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateBulkImportInModal:function(){var f=[];f.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');f.push("Select history: ");f.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</span>");return _.template(f.join(""))},templateProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))}});return{FolderToolbarView:a}});
\ 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
commit/galaxy-central: martenson: data libraries: API refactoring and improvements; backbone decoupling; role UI first implementation
by commits-noreply@bitbucket.org 10 Apr '14
by commits-noreply@bitbucket.org 10 Apr '14
10 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/a70f236803f7/
Changeset: a70f236803f7
User: martenson
Date: 2014-04-10 21:05:33
Summary: data libraries: API refactoring and improvements; backbone decoupling; role UI first implementation
Affected #: 19 files
diff -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c -r a70f236803f7d398b4f486342e864add77e9ad3f lib/galaxy/webapps/galaxy/api/folder_contents.py
--- a/lib/galaxy/webapps/galaxy/api/folder_contents.py
+++ b/lib/galaxy/webapps/galaxy/api/folder_contents.py
@@ -1,13 +1,16 @@
"""
-API operations on the contents of a folder.
+API operations on the contents of a library folder.
"""
-import logging, os, string, shutil, urllib, re, socket
-from cgi import escape, FieldStorage
-from galaxy import util, datatypes, jobs, web, util
-from galaxy.web.base.controller import *
-from galaxy.util.sanitize_html import sanitize_html
-from galaxy.model.orm import *
+from galaxy import util
+from galaxy import web
+from galaxy import exceptions
+from galaxy.web import _future_expose_api as expose_api
+from galaxy.web import _future_expose_api_anonymous as expose_api_anonymous
+from sqlalchemy.orm.exc import MultipleResultsFound
+from sqlalchemy.orm.exc import NoResultFound
+from galaxy.web.base.controller import BaseAPIController, UsesLibraryMixin, UsesLibraryMixinItems
+import logging
log = logging.getLogger( __name__ )
class FolderContentsController( BaseAPIController, UsesLibraryMixin, UsesLibraryMixinItems ):
@@ -15,65 +18,60 @@
Class controls retrieval, creation and updating of folder contents.
"""
- def load_folder_contents( self, trans, folder ):
- """
- Loads all contents of the folder (folders and data sets) but only in the first level.
- """
- current_user_roles = trans.get_current_user_roles()
- is_admin = trans.user_is_admin()
- content_items = []
- for subfolder in folder.active_folders:
- if not is_admin:
- can_access, folder_ids = trans.app.security_agent.check_folder_contents( trans.user, current_user_roles, subfolder )
- if (is_admin or can_access) and not subfolder.deleted:
- subfolder.api_type = 'folder'
- content_items.append( subfolder )
- for dataset in folder.datasets:
- if not is_admin:
- can_access = trans.app.security_agent.can_access_dataset( current_user_roles, dataset.library_dataset_dataset_association.dataset )
- if (is_admin or can_access) and not dataset.deleted:
- dataset.api_type = 'file'
- content_items.append( dataset )
- return content_items
-
- @web.expose_api
+ @expose_api_anonymous
def index( self, trans, folder_id, **kwd ):
"""
GET /api/folders/{encoded_folder_id}/contents
Displays a collection (list) of a folder's contents (files and folders).
Encoded folder ID is prepended with 'F' if it is a folder as opposed to a data set which does not have it.
- Full path is provided as a separate object in response providing data for breadcrumb path building.
+ Full path is provided in response as a separate object providing data for breadcrumb path building.
"""
- folder_container = []
- current_user_roles = trans.get_current_user_roles()
- if ( folder_id.startswith( 'F' ) ):
+ if ( len( folder_id ) == 17 and folder_id.startswith( 'F' ) ):
try:
- decoded_folder_id = trans.security.decode_id( folder_id[1:] )
+ decoded_folder_id = trans.security.decode_id( folder_id[ 1: ] )
except TypeError:
- trans.response.status = 400
- return "Malformed folder id ( %s ) specified, unable to decode." % str( folder_id )
+ raise exceptions.MalformedId( 'Malformed folder id ( %s ) specified, unable to decode.' % str( folder_id ) )
+ else:
+ raise exceptions.MalformedId( 'Malformed folder id ( %s ) specified, unable to decode.' % str( folder_id ) )
try:
- folder = trans.sa_session.query( trans.app.model.LibraryFolder ).get( decoded_folder_id )
- except:
- folder = None
- log.error( "FolderContentsController.index: Unable to retrieve folder with ID: %s" % folder_id )
+ folder = trans.sa_session.query( trans.app.model.LibraryFolder ).filter( trans.app.model.LibraryFolder.table.c.id == decoded_folder_id ).one()
+ except MultipleResultsFound:
+ raise exceptions.InconsistentDatabase( 'Multiple folders with same id found.' )
+ except NoResultFound:
+ raise exceptions.ObjectNotFound( 'Folder with the id provided ( %s ) was not found' % str( folder_id ) )
+ except Exception:
+ raise exceptions.InternalServerError( 'Error loading from the database.' )
- # We didn't find the folder or user does not have an access to it.
- if not folder:
- trans.response.status = 400
- return "Invalid folder id ( %s ) specified." % str( folder_id )
-
+ current_user_roles = trans.get_current_user_roles()
+ can_add_library_item = trans.user_is_admin() or trans.app.security_agent.can_add_library_item( current_user_roles, folder )
+
if not ( trans.user_is_admin() or trans.app.security_agent.can_access_library_item( current_user_roles, folder, trans.user ) ):
- log.warning( "SECURITY: User (id: %s) without proper access rights is trying to load folder with ID of %s" % ( trans.user.id, folder.id ) )
- trans.response.status = 400
- return "Invalid folder id ( %s ) specified." % str( folder_id )
+ if folder.parent_id == None:
+ try:
+ library = trans.sa_session.query( trans.app.model.Library ).filter( trans.app.model.Library.table.c.root_folder_id == decoded_folder_id ).one()
+ except Exception:
+ raise exceptions.InternalServerError( 'Error loading from the database.' )
+ if trans.app.security_agent.library_is_public( library, contents=False ):
+ pass
+ else:
+ if trans.user:
+ log.warning( "SECURITY: User (id: %s) without proper access rights is trying to load folder with ID of %s" % ( trans.user.id, decoded_folder_id ) )
+ else:
+ log.warning( "SECURITY: Anonymous user without proper access rights is trying to load folder with ID of %s" % ( decoded_folder_id ) )
+ raise exceptions.ObjectNotFound( 'Folder with the id provided ( %s ) was not found' % str( folder_id ) )
+ else:
+ if trans.user:
+ log.warning( "SECURITY: User (id: %s) without proper access rights is trying to load folder with ID of %s" % ( trans.user.id, decoded_folder_id ) )
+ else:
+ log.warning( "SECURITY: Anonymous user without proper access rights is trying to load folder with ID of %s" % ( decoded_folder_id ) )
+ raise exceptions.ObjectNotFound( 'Folder with the id provided ( %s ) was not found' % str( folder_id ) )
path_to_root = []
def build_path ( folder ):
"""
- Search the path upwards recursively and load the whole route of names and ids for breadcrumb purposes.
+ Search the path upwards recursively and load the whole route of names and ids for breadcrumb building purposes.
"""
path_to_root = []
# We are almost in root
@@ -88,13 +86,13 @@
# Return the reversed path so it starts with the library node.
full_path = build_path( folder )[::-1]
- folder_container.append( dict( full_path = full_path ) )
+
folder_contents = []
time_updated = ''
time_created = ''
# Go through every item in the folder and include its meta-data.
- for content_item in self.load_folder_contents( trans, folder ):
+ for content_item in self._load_folder_contents( trans, folder ):
return_item = {}
encoded_id = trans.security.encode_id( content_item.id )
time_updated = content_item.update_time.strftime( "%Y-%m-%d %I:%M %p" )
@@ -122,16 +120,36 @@
time_created = time_created
) )
folder_contents.append( return_item )
- # Put the data in the container
- folder_container.append( dict( folder_contents = folder_contents ) )
- return folder_container
+
+ return { 'metadata' : { 'full_path' : full_path, 'can_add_library_item': can_add_library_item }, 'folder_contents' : folder_contents }
+
+ def _load_folder_contents( self, trans, folder ):
+ """
+ Loads all contents of the folder (folders and data sets) but only in the first level.
+ """
+ current_user_roles = trans.get_current_user_roles()
+ is_admin = trans.user_is_admin()
+ content_items = []
+ for subfolder in folder.active_folders:
+ if not is_admin:
+ can_access, folder_ids = trans.app.security_agent.check_folder_contents( trans.user, current_user_roles, subfolder )
+ if (is_admin or can_access) and not subfolder.deleted:
+ subfolder.api_type = 'folder'
+ content_items.append( subfolder )
+ for dataset in folder.datasets:
+ if not is_admin:
+ can_access = trans.app.security_agent.can_access_dataset( current_user_roles, dataset.library_dataset_dataset_association.dataset )
+ if (is_admin or can_access) and not dataset.deleted:
+ dataset.api_type = 'file'
+ content_items.append( dataset )
+ return content_items
@web.expose_api
def show( self, trans, id, library_id, **kwd ):
"""
GET /api/folders/{encoded_folder_id}/
"""
- pass
+ raise exceptions.NotImplemented( 'Showing the library folder content is not implemented.' )
@web.expose_api
def create( self, trans, library_id, payload, **kwd ):
@@ -140,20 +158,21 @@
Creates a new folder. This should be superseded by the
LibraryController.
"""
- pass
+ raise exceptions.NotImplemented( 'Creating the library folder content is not implemented.' )
@web.expose_api
def update( self, trans, id, library_id, payload, **kwd ):
"""
PUT /api/folders/{encoded_folder_id}/contents
"""
- pass
+ raise exceptions.NotImplemented( 'Updating the library folder content is not implemented.' )
# TODO: Move to library_common.
- def __decode_library_content_id( self, trans, content_id ):
- if ( len( content_id ) % 16 == 0 ):
- return 'LibraryDataset', content_id
- elif ( content_id.startswith( 'F' ) ):
- return 'LibraryFolder', content_id[1:]
- else:
- raise HTTPBadRequest( 'Malformed library content id ( %s ) specified, unable to decode.' % str( content_id ) )
+ # def __decode_library_content_id( self, trans, content_id ):
+ # if ( len( content_id ) % 16 == 0 ):
+ # return 'LibraryDataset', content_id
+ # elif ( content_id.startswith( 'F' ) ):
+ # return 'LibraryFolder', content_id[1:]
+ # else:
+ # raise HTTPBadRequest( 'Malformed library content id ( %s ) specified, unable to decode.' % str( content_id ) )
+
diff -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c -r a70f236803f7d398b4f486342e864add77e9ad3f lib/galaxy/webapps/galaxy/api/folders.py
--- a/lib/galaxy/webapps/galaxy/api/folders.py
+++ b/lib/galaxy/webapps/galaxy/api/folders.py
@@ -1,14 +1,17 @@
"""
-API operations on folders
+API operations on library folders
"""
-import logging, os, string, shutil, urllib, re, socket, traceback
+import os, string, shutil, urllib, re, socket, traceback
from galaxy import datatypes, jobs, web, security
+from galaxy.web import _future_expose_api as expose_api
+from galaxy.web import _future_expose_api_anonymous as expose_api_anonymous
from galaxy.web.base.controller import BaseAPIController,UsesLibraryMixin,UsesLibraryMixinItems
from galaxy.util.sanitize_html import sanitize_html
from cgi import escape, FieldStorage
from paste.httpexceptions import HTTPBadRequest
+import logging
log = logging.getLogger( __name__ )
class FoldersController( BaseAPIController, UsesLibraryMixin, UsesLibraryMixinItems ):
@@ -18,9 +21,9 @@
"""
GET /api/folders/
This would normally display a list of folders. However, that would
- be across multiple libraries, so it's not implemented yet.
+ be across multiple libraries, so it's not implemented.
"""
- pass
+ raise exceptions.NotImplemented( 'Listing all accessible library folders is not implemented.' )
@web.expose_api
def show( self, trans, id, **kwd ):
diff -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c -r a70f236803f7d398b4f486342e864add77e9ad3f lib/galaxy/webapps/galaxy/api/libraries.py
--- a/lib/galaxy/webapps/galaxy/api/libraries.py
+++ b/lib/galaxy/webapps/galaxy/api/libraries.py
@@ -7,7 +7,7 @@
from galaxy.web import _future_expose_api as expose_api
from galaxy.web import _future_expose_api_anonymous as expose_api_anonymous
from galaxy.model.orm import and_, not_, or_
-from galaxy.web.base.controller import BaseAPIController, url_for
+from galaxy.web.base.controller import BaseAPIController
import logging
log = logging.getLogger( __name__ )
@@ -61,7 +61,6 @@
if trans.app.security_agent.library_is_public( library, contents=False ):
item[ 'public' ] = True
current_user_roles = trans.get_current_user_roles()
- # can_user_add = trans.app.security_agent.can_add_library_item( current_user_roles, library.root_folder )
if not trans.user_is_admin():
item['can_user_add'] = trans.app.security_agent.can_add_library_item( current_user_roles, library )
item['can_user_modify'] = trans.app.security_agent.can_modify_library_item( current_user_roles, library )
@@ -98,7 +97,7 @@
deleted = util.string_as_bool( deleted )
try:
decoded_library_id = trans.security.decode_id( library_id )
- except Exception:
+ except TypeError:
raise exceptions.MalformedId( 'Malformed library id ( %s ) specified, unable to decode.' % id )
try:
library = trans.sa_session.query( trans.app.model.Library ).get( decoded_library_id )
@@ -144,7 +143,14 @@
library.root_folder = root_folder
trans.sa_session.add_all( ( library, root_folder ) )
trans.sa_session.flush()
- return library.to_dict( view='element', value_mapper={ 'id' : trans.security.encode_id , 'root_folder_id' : trans.security.encode_id } )
+
+ item = library.to_dict( view='element', value_mapper={ 'id' : trans.security.encode_id , 'root_folder_id' : trans.security.encode_id } )
+ item['can_user_add'] = True
+ item['can_user_modify'] = True
+ item['can_user_manage'] = True
+ if trans.app.security_agent.library_is_public( library, contents=False ):
+ item[ 'public' ] = True
+ return item
@expose_api
def update( self, trans, id, **kwd ):
diff -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c -r a70f236803f7d398b4f486342e864add77e9ad3f lib/galaxy/webapps/galaxy/api/library_contents.py
--- a/lib/galaxy/webapps/galaxy/api/library_contents.py
+++ b/lib/galaxy/webapps/galaxy/api/library_contents.py
@@ -17,8 +17,7 @@
log = logging.getLogger( __name__ )
-class LibraryContentsController( BaseAPIController, UsesLibraryMixin, UsesLibraryMixinItems,
- UsesHistoryDatasetAssociationMixin ):
+class LibraryContentsController( BaseAPIController, UsesLibraryMixin, UsesLibraryMixinItems, UsesHistoryDatasetAssociationMixin ):
@expose_api
def index( self, trans, library_id, **kwd ):
diff -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c -r a70f236803f7d398b4f486342e864add77e9ad3f static/scripts/galaxy.library.js
--- a/static/scripts/galaxy.library.js
+++ b/static/scripts/galaxy.library.js
@@ -2,28 +2,30 @@
// === MAIN GALAXY LIBRARY MODULE ====
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
-// global variables
-var library_router = null;
-
// dependencies
define([
- "galaxy.masthead",
+ "galaxy.masthead",
"utils/utils",
"libs/toastr",
"mvc/base-mvc",
"mvc/library/library-model",
"mvc/library/library-folderlist-view",
"mvc/library/library-librarylist-view",
- "mvc/library/library-librarytoolbar-view"],
-function(mod_masthead,
- mod_utils,
+ "mvc/library/library-librarytoolbar-view",
+ "mvc/library/library-foldertoolbar-view"
+ ],
+function(mod_masthead,
+ mod_utils,
mod_toastr,
mod_baseMVC,
mod_library_model,
mod_folderlist_view,
mod_librarylist_view,
- mod_librarytoolbar_view) {
+ mod_librarytoolbar_view,
+ mod_foldertoolbar_view
+ ) {
+// ============================================================================
//ROUTER
var LibraryRouter = Backbone.Router.extend({
routes: {
@@ -44,12 +46,14 @@
}
});
-// galaxy library wrapper View
+// ============================================================================
+// Main controller of Galaxy Library
var GalaxyLibrary = Backbone.View.extend({
- toolbarView: null,
+ libraryToolbarView: null,
libraryListView: null,
library_router: null,
- folderContentView: null,
+ folderToolbarView: null,
+ folderListView: null,
initialize : function(){
Galaxy.libraries = this;
@@ -59,25 +63,26 @@
this.library_router.on('route:libraries', function() {
// initialize and render the toolbar first
- Galaxy.libraries.toolbarView = new mod_librarytoolbar_view.ToolbarView();
+ Galaxy.libraries.libraryToolbarView = new mod_librarytoolbar_view.LibraryToolbarView();
// initialize and render libraries second
Galaxy.libraries.libraryListView = new mod_librarylist_view.LibraryListView();
});
this.library_router.on('route:folder_content', function(id) {
- // render folder contents
- if (!Galaxy.libraries.folderContentView) {Galaxy.libraries.folderContentView = new mod_folderlist_view.FolderContentView();}
- Galaxy.libraries.folderContentView.render({id: id});
+ // TODO place caching here, sessionstorage/localstorage?
+ Galaxy.libraries.folderToolbarView = new mod_foldertoolbar_view.FolderToolbarView({id: id});
+ Galaxy.libraries.folderListView = new mod_folderlist_view.FolderListView({id: id});
});
this.library_router.on('route:download', function(folder_id, format) {
- if ($('#center').find(':checked').length === 0) {
+ if ($('#center').find(':checked').length === 0) {
+ mod_toastr.info('You have to select some datasets to download')
// this happens rarely when there is a server/data error and client gets an actual response instead of an attachment
// we don't know what was selected so we can't download again, we redirect to the folder provided
Galaxy.libraries.library_router.navigate('folders/' + folder_id, {trigger: true, replace: true});
} else {
// send download stream
- Galaxy.libraries.folderContentView.download(folder_id, format);
+ Galaxy.libraries.folderToolbarView.download(folder_id, format);
Galaxy.libraries.library_router.navigate('folders/' + folder_id, {trigger: false, replace: true});
}
});
@@ -86,7 +91,6 @@
}
});
-// return
return {
GalaxyApp: GalaxyLibrary
};
diff -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c -r a70f236803f7d398b4f486342e864add77e9ad3f static/scripts/mvc/library/library-folderlist-view.js
--- a/static/scripts/mvc/library/library-folderlist-view.js
+++ b/static/scripts/mvc/library/library-folderlist-view.js
@@ -1,458 +1,126 @@
// dependencies
define([
- "galaxy.masthead",
+ "galaxy.masthead",
"utils/utils",
"libs/toastr",
- "mvc/library/library-model"],
-function(mod_masthead,
- mod_utils,
+ "mvc/library/library-model",
+ "mvc/library/library-folderrow-view"],
+function(mod_masthead,
+ mod_utils,
mod_toastr,
- mod_library_model) {
+ mod_library_model,
+ mod_library_folderrow_view) {
- //main view for folder browsing
-var FolderContentView = Backbone.View.extend({
- // main element definition
- el : '#center',
- // progress percentage
- progress: 0,
- // progress rate per one item
- progressStep: 1,
- // last selected history in modal for UX
- lastSelectedHistory: '',
- // self modal
- modal : null,
- // loaded folders
- folders : null,
+var FolderListView = Backbone.View.extend({
+ // main element definition
+ el : '#folder_items_element',
+ // progress percentage
+ progress: 0,
+ // progress rate per one item
+ progressStep: 1,
+ // self modal
+ modal : null,
+ folderContainer: null,
+
+ // event binding
+ events: {
+ 'click #select-all-checkboxes' : 'selectAll',
+ 'click .dataset_row' : 'selectClickedRow'
+ },
// initialize
- initialize : function(){
- this.folders = [];
+ initialize : function(options){
+ var that = this;
+ this.options = _.defaults(this.options || {}, options);
this.queue = jQuery.Deferred();
this.queue.resolve();
- },
-// MMMMMMMMMMMMMMMMMM
-// === TEMPLATES ====
-// MMMMMMMMMMMMMMMMMM
-
- // main template for folder browsing
- templateFolder : function (){
- var tmpl_array = [];
-
- // CONTAINER
- tmpl_array.push('<div class="library_container" style="width: 90%; margin: auto; margin-top: 2em; ">');
- tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');
-
- // TOOLBAR
- tmpl_array.push('<div id="library_folder_toolbar" >');
- tmpl_array.push(' <button title="Create New Folder" id="toolbtn_create_folder" class="primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder-close"></span> folder</button>');
- tmpl_array.push(' <button title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button" style="display: none; margin-left: 0.5em;" type="button"><span class="fa fa-book"></span> to history</button>');
- tmpl_array.push(' <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; display: none; ">');
- tmpl_array.push(' <button title="Download selected datasets" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');
- tmpl_array.push(' <span class="fa fa-download"></span> download <span class="caret"></span>');
- tmpl_array.push(' </button>');
- tmpl_array.push(' <ul class="dropdown-menu" role="menu">');
- tmpl_array.push(' <li><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');
- tmpl_array.push(' <li><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');
- tmpl_array.push(' <li><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');
- tmpl_array.push(' </ul>');
- tmpl_array.push(' </div>');
-
- tmpl_array.push('</div>');
-
- // BREADCRUMBS
- tmpl_array.push('<ol class="breadcrumb">');
- tmpl_array.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');
- tmpl_array.push(' <% _.each(path, function(path_item) { %>');
- tmpl_array.push(' <% if (path_item[0] != id) { %>');
- tmpl_array.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');
- tmpl_array.push( '<% } else { %>');
- tmpl_array.push(' <li class="active"><span title="You are in this folder"><%- path_item[1] %></span></li>');
- tmpl_array.push(' <% } %>');
- tmpl_array.push(' <% }); %>');
- tmpl_array.push('</ol>');
-
-
- // FOLDER CONTENT
- tmpl_array.push('<table id="folder_table" class="grid table table-condensed">');
- tmpl_array.push(' <thead>');
- tmpl_array.push(' <th class="button_heading"></th>');
- tmpl_array.push(' <th style="text-align: center; width: 20px; "><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');
- tmpl_array.push(' <th>name</th>');
- tmpl_array.push(' <th>data type</th>');
- tmpl_array.push(' <th>size</th>');
- tmpl_array.push(' <th>date (UTC)</th>');
- tmpl_array.push(' </thead>');
- tmpl_array.push(' <tbody>');
- tmpl_array.push(' <td><a href="#<% if (upper_folder_id !== 0){ print("folders/" + upper_folder_id)} %>" title="Go to parent folder" class="btn_open_folder btn btn-default btn-xs">..<a></td>');
- tmpl_array.push(' <td></td>');
- tmpl_array.push(' <td></td>');
- tmpl_array.push(' <td></td>');
- tmpl_array.push(' <td></td>');
- tmpl_array.push(' <td></td>');
- tmpl_array.push(' </tr>');
- tmpl_array.push(' <% _.each(items, function(content_item) { %>');
- tmpl_array.push(' <% if (content_item.get("type") === "folder") { %>'); // folder
- tmpl_array.push(' <tr class="folder_row light" id="<%- content_item.id %>">');
- tmpl_array.push(' <td>');
- tmpl_array.push(' <span title="Folder" class="fa fa-folder-o"></span>');
- tmpl_array.push(' </td>');
- tmpl_array.push(' <td></td>');
- tmpl_array.push(' <td>');
- tmpl_array.push(' <a href="#folders/<%- content_item.id %>"><%- content_item.get("name") %></a>');
- tmpl_array.push(' <% if (content_item.get("item_count") === 0) { %>'); // empty folder
- tmpl_array.push(' <span class="muted">(empty folder)</span>');
- tmpl_array.push(' <% } %>');
- tmpl_array.push(' </td>');
- tmpl_array.push(' <td>folder</td>');
- tmpl_array.push(' <td><%= _.escape(content_item.get("item_count")) %> item(s)</td>'); // size
- tmpl_array.push(' <td><%= _.escape(content_item.get("time_updated")) %></td>'); // time updated
- tmpl_array.push(' </tr>');
- tmpl_array.push(' <% } else { %>');
- tmpl_array.push(' <tr class="dataset_row light" id="<%- content_item.id %>">');
- tmpl_array.push(' <td>');
- tmpl_array.push(' <span title="Dataset" class="fa fa-file-o"></span>');
- tmpl_array.push(' </td>');
- tmpl_array.push(' <td style="text-align: center; "><input style="margin: 0;" type="checkbox"></td>');
- tmpl_array.push(' <td><a href="#" class="library-dataset"><%- content_item.get("name") %><a></td>'); // dataset
- tmpl_array.push(' <td><%= _.escape(content_item.get("data_type")) %></td>'); // data type
- tmpl_array.push(' <td><%= _.escape(content_item.get("readable_size")) %></td>'); // size
- tmpl_array.push(' <td><%= _.escape(content_item.get("time_updated")) %></td>'); // time updated
- tmpl_array.push(' </tr>');
- tmpl_array.push(' <% } %> ');
- tmpl_array.push(' <% }); %>');
- tmpl_array.push(' ');
- tmpl_array.push(' </tbody>');
- tmpl_array.push('</table>');
-
- tmpl_array.push('</div>');
- return tmpl_array.join('');
- },
- templateDatasetModal : function(){
- var tmpl_array = [];
-
- tmpl_array.push('<div class="modal_table">');
- tmpl_array.push(' <table class="grid table table-striped table-condensed">');
- tmpl_array.push(' <tr>');
- tmpl_array.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');
- tmpl_array.push(' <td><%= _.escape(item.get("name")) %></td>');
- tmpl_array.push(' </tr>');
- tmpl_array.push(' <tr>');
- tmpl_array.push(' <th scope="row">Data type</th>');
- tmpl_array.push(' <td><%= _.escape(item.get("data_type")) %></td>');
- tmpl_array.push(' </tr>');
- tmpl_array.push(' <tr>');
- tmpl_array.push(' <th scope="row">Genome build</th>');
- tmpl_array.push(' <td><%= _.escape(item.get("genome_build")) %></td>');
- tmpl_array.push(' </tr>');
- tmpl_array.push(' <th scope="row">Size</th>');
- tmpl_array.push(' <td><%= _.escape(size) %></td>');
- tmpl_array.push(' </tr>');
- tmpl_array.push(' <tr>');
- tmpl_array.push(' <th scope="row">Date uploaded (UTC)</th>');
- tmpl_array.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');
- tmpl_array.push(' </tr>');
- tmpl_array.push(' <tr>');
- tmpl_array.push(' <th scope="row">Uploaded by</th>');
- tmpl_array.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');
- tmpl_array.push(' </tr>');
- tmpl_array.push(' <tr scope="row">');
- tmpl_array.push(' <th scope="row">Data Lines</th>');
- tmpl_array.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');
- tmpl_array.push(' </tr>');
- tmpl_array.push(' <th scope="row">Comment Lines</th>');
- tmpl_array.push(' <% if (item.get("metadata_comment_lines") === "") { %>');
- tmpl_array.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');
- tmpl_array.push(' <% } else { %>');
- tmpl_array.push(' <td scope="row">unknown</td>');
- tmpl_array.push(' <% } %>');
- tmpl_array.push(' </tr>');
- tmpl_array.push(' <tr>');
- tmpl_array.push(' <th scope="row">Number of Columns</th>');
- tmpl_array.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');
- tmpl_array.push(' </tr>');
- tmpl_array.push(' <tr>');
- tmpl_array.push(' <th scope="row">Column Types</th>');
- tmpl_array.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');
- tmpl_array.push(' </tr>');
- tmpl_array.push(' <tr>');
- tmpl_array.push(' <th scope="row">Miscellaneous information</th>');
- tmpl_array.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');
- tmpl_array.push(' </tr>');
- tmpl_array.push(' </table>');
- tmpl_array.push(' <pre class="peek">');
- tmpl_array.push(' </pre>');
- tmpl_array.push('</div>');
-
- return tmpl_array.join('');
- },
-
- templateHistorySelectInModal : function(){
- var tmpl_array = [];
-
- tmpl_array.push('<span id="history_modal_combo" style="width:100%; margin-left: 1em; margin-right: 1em; ">');
- tmpl_array.push('Select history: ');
- tmpl_array.push('<select id="dataset_import_single" name="dataset_import_single" style="width:40%; margin-bottom: 1em; "> ');
- tmpl_array.push(' <% _.each(histories, function(history) { %>'); //history select box
- tmpl_array.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');
- tmpl_array.push(' <% }); %>');
- tmpl_array.push('</select>');
- tmpl_array.push('</span>');
-
- return tmpl_array.join('');
- },
-
- templateBulkImportInModal : function(){
- var tmpl_array = [];
-
- tmpl_array.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');
- tmpl_array.push('Select history: ');
- tmpl_array.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');
- tmpl_array.push(' <% _.each(histories, function(history) { %>'); //history select box
- tmpl_array.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');
- tmpl_array.push(' <% }); %>');
- tmpl_array.push('</select>');
- tmpl_array.push('</span>');
-
- return tmpl_array.join('');
- },
-
- templateProgressBar : function (){
- var tmpl_array = [];
-
- tmpl_array.push('<div class="import_text">');
- tmpl_array.push('Importing selected datasets to history <b><%= _.escape(history_name) %></b>');
- tmpl_array.push('</div>');
- tmpl_array.push('<div class="progress">');
- tmpl_array.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');
- tmpl_array.push(' <span class="completion_span">0% Complete</span>');
- tmpl_array.push(' </div>');
- tmpl_array.push('</div>');
- tmpl_array.push('');
-
- return tmpl_array.join('');
- },
-
- templateNewFolderInModal: function(){
- tmpl_array = [];
-
- tmpl_array.push('<div id="new_folder_modal">');
- tmpl_array.push('<form>');
- tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');
- tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');
- tmpl_array.push('</form>');
- tmpl_array.push('</div>');
-
- return tmpl_array.join('');
- },
-
-// MMMMMMMMMMMMMMM
-// === EVENTS ====
-// MMMMMMMMMMMMMMM
-
- // event binding
- events: {
- 'click #select-all-checkboxes' : 'selectAll',
- 'click #toolbtn_bulk_import' : 'modalBulkImport',
- 'click #toolbtn_dl' : 'bulkDownload',
- 'click #toolbtn_create_folder' : 'createFolderFromModal',
- 'click .library-dataset' : 'showDatasetDetails',
- 'click .dataset_row' : 'selectClickedRow'
- },
-
-// MMMMMMMMMMMMMMMMMM
-// === FUNCTIONS ====
-// MMMMMMMMMMMMMMMMMM
-
- //render the folder view
- render: function (options) {
- //hack to show scrollbars
- $("#center").css('overflow','auto');
-
- view = this;
- var that = this;
-
- var folderContainer = new mod_library_model.FolderContainer({id: options.id});
- folderContainer.url = folderContainer.attributes.urlRoot + options.id + '/contents';
-
- folderContainer.fetch({
- success: function (container) {
-
- // prepare nice size strings
- for (var i = 0; i < folderContainer.attributes.folder.models.length; i++) {
- var model = folderContainer.attributes.folder.models[i]
- if (model.get('type') === 'file'){
- model.set('readable_size', that.size_to_string(model.get('file_size')))
- }
- };
-
- // find the upper id
- var path = folderContainer.full_path;
- var upper_folder_id;
- if (path.length === 1){ // library is above us
- upper_folder_id = 0;
- } else {
- upper_folder_id = path[path.length-2][0];
- }
-
- var template = _.template(that.templateFolder(), { path: folderContainer.full_path, items: folderContainer.attributes.folder.models, id: options.id, upper_folder_id: upper_folder_id });
- // var template = _.template(that.templateFolder(), { path: folderContainer.full_path, items: folderContainer.attributes.folder.models, id: options.id });
- that.$el.html(template);
-
+ this.folderContainer = new mod_library_model.FolderContainer({id: this.options.id});
+ this.folderContainer.url = this.folderContainer.attributes.urlRoot + this.options.id + '/contents';
+ this.folderContainer.fetch({
+ success: function (folderContainer) {
+ that.render();
},
- error: function(){
- mod_toastr.error('An error occured :(');
- }
- })
- },
-
- // convert size to nice string
- size_to_string : function (size)
- {
- // identify unit
- var unit = "";
- if (size >= 100000000000) { size = size / 100000000000; unit = "TB"; } else
- if (size >= 100000000) { size = size / 100000000; unit = "GB"; } else
- if (size >= 100000) { size = size / 100000; unit = "MB"; } else
- if (size >= 100) { size = size / 100; unit = "KB"; } else
- { size = size * 10; unit = "b"; }
- // return formatted string
- return (Math.round(size) / 10) + unit;
- },
-
- //show modal with current dataset info
- showDatasetDetails : function(event){
- // prevent default
- event.preventDefault();
-
- //TODO check whether we already have the data
-
- //load the ID of the row
- var id = $(event.target).parent().parent().parent().attr('id');
- if (typeof id === 'undefined'){
- id = $(event.target).parent().attr('id');
- }
- if (typeof id === 'undefined'){
- id = $(event.target).parent().parent().attr('id')
- }
-
- //create new item
- var item = new mod_library_model.Item();
- var histories = new mod_library_model.GalaxyHistories();
- item.id = id;
- var self = this;
-
- //fetch the dataset info
- item.fetch({
- success: function (item) {
- // TODO can render here already
- //fetch user histories for import purposes
- histories.fetch({
- success: function (histories){
- self.renderModalAfterFetch(item, histories)
- },
- error: function(){
- mod_toastr.error('An error occured during fetching histories:(');
- self.renderModalAfterFetch(item)
- }
- });
- },
- error: function(){
- mod_toastr.error('An error occured during loading dataset details :(');
- }
+ error: function(){
+ mod_toastr.error('An error occured :(');
+ }
});
},
- // show the current dataset in a modal
- renderModalAfterFetch : function(item, histories){
- var size = this.size_to_string(item.get('file_size'));
- var template = _.template(this.templateDatasetModal(), { item : item, size : size });
- // make modal
- var self = this;
- this.modal = Galaxy.modal;
- this.modal.show({
- closing_events : true,
- title : 'Dataset Details',
- body : template,
- buttons : {
- 'Import' : function() { self.importCurrentIntoHistory() },
- 'Download' : function() { self.downloadCurrent() },
- 'Close' : function() { self.modal.hide() }
- }
- });
-
- $(".peek").html('Peek:' + item.get("peek"));
+ render: function (options) {
+ this.options = _.defaults(this.options || {}, options);
+ var template = this.templateFolder();
+ var contains_file = false;
- // show the import-into-history footer only if the request for histories succeeded
- if (typeof history.models !== undefined){
- var history_footer_tmpl = _.template(this.templateHistorySelectInModal(), {histories : histories.models});
- $(this.modal.elMain).find('.buttons').prepend(history_footer_tmpl);
- // preset last selected history if we know it
- if (self.lastSelectedHistory.length > 0) {
- $(this.modal.elMain).find('#dataset_import_single').val(self.lastSelectedHistory);
- }
- }
- },
+ // TODO move to server
+ // prepare nice size strings
+ for (var i = 0; i < this.folderContainer.attributes.folder.models.length; i++) {
+ var model = this.folderContainer.attributes.folder.models[i];
+ if (model.get('type') === 'file'){
+ contains_file = true;
+ model.set('readable_size', this.size_to_string(model.get('file_size')));
+ }
+ }
- // download dataset shown currently in modal
- downloadCurrent : function(){
- //disable the buttons
- this.modal.disableButton('Import');
- this.modal.disableButton('Download');
+ // TODO move to server
+ // find the upper id in the full path
+ var path = this.folderContainer.attributes.metadata.full_path;
+ var upper_folder_id;
+ if (path.length === 1){ // the library is above us
+ upper_folder_id = 0;
+ } else {
+ upper_folder_id = path[path.length-2][0];
+ }
- var library_dataset_id = [];
- library_dataset_id.push($('#id_row').attr('data-id'));
- var url = '/api/libraries/datasets/download/uncompressed';
- var data = {'ldda_ids' : library_dataset_id};
+ this.$el.html(template({ path: this.folderContainer.attributes.metadata.full_path, items: this.folderContainer.attributes.folder.models, id: this.options.id, upper_folder_id: upper_folder_id }));
- // we assume the view is existent
- folderContentView.processDownload(url, data);
- this.modal.enableButton('Import');
- this.modal.enableButton('Download');
- },
+ if (this.folderContainer.attributes.folder.models.length > 0){
+ this.renderRows();
+ }
+ if (this.folderContainer.attributes.metadata.can_add_library_item === true){
+ Galaxy.libraries.folderToolbarView.configureElements({ can_add_library_item: this.folderContainer.attributes.metadata.can_add_library_item, contains_file: contains_file });
+ }
- // import dataset shown currently in modal into selected history
- importCurrentIntoHistory : function(){
- //disable the buttons
- this.modal.disableButton('Import');
- this.modal.disableButton('Download');
+ // initialize the library tooltips
+ $("#center [data-toggle]").tooltip();
+ //hack to show scrollbars
+ $("#center").css('overflow','auto');
+ },
- var history_id = $(this.modal.elMain).find('select[name=dataset_import_single] option:selected').val();
- this.lastSelectedHistory = history_id; //save selected history for further use
+ renderRows: function(){
+ for (var i = 0; i < this.folderContainer.attributes.folder.models.length; i++) {
+ var folder_item = this.folderContainer.attributes.folder.models[i];
+ var rowView = new mod_library_folderrow_view.FolderRowView(folder_item);
+ this.$el.find('#folder_list_body').append(rowView.el);
+ }
+ },
- var library_dataset_id = $('#id_row').attr('data-id');
- var historyItem = new mod_library_model.HistoryItem();
- var self = this;
- historyItem.url = historyItem.urlRoot + history_id + '/contents';
-
- // save the dataset into selected history
- historyItem.save({ content : library_dataset_id, source : 'library' }, { success : function(){
- mod_toastr.success('Dataset imported');
- //enable the buttons
- self.modal.enableButton('Import');
- self.modal.enableButton('Download');
- }, error : function(){
- mod_toastr.error('An error occured! Dataset not imported. Please try again.')
- //enable the buttons
- self.modal.enableButton('Import');
- self.modal.enableButton('Download');
- }
- });
- },
+ // convert size to nice string
+ size_to_string : function (size){
+ // identify unit
+ var unit = "";
+ if (size >= 100000000000) { size = size / 100000000000; unit = "TB"; } else
+ if (size >= 100000000) { size = size / 100000000; unit = "GB"; } else
+ if (size >= 100000) { size = size / 100000; unit = "MB"; } else
+ if (size >= 100) { size = size / 100; unit = "KB"; } else
+ { size = size * 10; unit = "b"; }
+ // return formatted string
+ return (Math.round(size) / 10) + unit;
+ },
// select all datasets
selectAll : function (event) {
var selected = event.target.checked;
that = this;
// Iterate each checkbox
- $(':checkbox').each(function () {
- this.checked = selected;
+ $(':checkbox').each(function() {
+ this.checked = selected;
$row = $(this.parentElement.parentElement);
// Change color of selected/unselected
(selected) ? that.makeDarkRow($row) : that.makeWhiteRow($row);
});
// Show the tools in menu
- this.checkTools();
+ // this.checkTools();
},
// Check checkbox on row itself or row checkbox click
@@ -485,7 +153,7 @@
this.makeWhiteRow($row);
}
}
- this.checkTools();
+ // this.checkTools();
},
makeDarkRow: function($row){
@@ -507,207 +175,56 @@
$row.find('span').removeClass('fa-file');
},
- // show toolbar in case something is selected
- checkTools : function(){
- var checkedValues = $('#folder_table').find(':checked');
- if(checkedValues.length > 0){
- $('#toolbtn_bulk_import').show();
- $('#toolbtn_dl').show();
- } else {
- $('#toolbtn_bulk_import').hide();
- $('#toolbtn_dl').hide();
- }
- },
+// MMMMMMMMMMMMMMMMMM
+// === TEMPLATES ====
+// MMMMMMMMMMMMMMMMMM
- // show bulk import modal
- modalBulkImport : function(){
- var self = this;
- // fetch histories
- var histories = new mod_library_model.GalaxyHistories();
- histories.fetch({
- success: function (histories){
- // make modal
- var history_modal_tmpl = _.template(self.templateBulkImportInModal(), {histories : histories.models});
- self.modal = Galaxy.modal;
- self.modal.show({
- closing_events : true,
- title : 'Import into History',
- body : history_modal_tmpl,
- buttons : {
- 'Import' : function() {self.importAllIntoHistory()},
- 'Close' : function() {self.modal.hide();}
- }
- });
- },
- error: function(){
- mod_toastr.error('An error occured :(');
- }
- });
- },
+ // main template for folder browsing
+ templateFolder : function (){
+ var tmpl_array = [];
- // import all selected datasets into history
- importAllIntoHistory : function (){
- //disable the button to prevent multiple submission
- this.modal.disableButton('Import');
+ // BREADCRUMBS
+ tmpl_array.push('<ol class="breadcrumb">');
+ tmpl_array.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');
+ tmpl_array.push(' <% _.each(path, function(path_item) { %>');
+ tmpl_array.push(' <% if (path_item[0] != id) { %>');
+ tmpl_array.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');
+ tmpl_array.push( '<% } else { %>');
+ tmpl_array.push(' <li class="active"><span title="You are in this folder"><%- path_item[1] %></span></li>');
+ tmpl_array.push(' <% } %>');
+ tmpl_array.push(' <% }); %>');
+ tmpl_array.push('</ol>');
- var history_id = $("select[name=dataset_import_bulk] option:selected").val();
- var history_name = $("select[name=dataset_import_bulk] option:selected").text();
+ // FOLDER CONTENT
+ tmpl_array.push('<table id="folder_table" class="grid table table-condensed">');
+ tmpl_array.push(' <thead>');
+ tmpl_array.push(' <th class="button_heading"></th>');
+ tmpl_array.push(' <th style="text-align: center; width: 20px; "><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');
+ tmpl_array.push(' <th>name</th>');
+ tmpl_array.push(' <th>data type</th>');
+ tmpl_array.push(' <th>size</th>');
+ tmpl_array.push(' <th>date (UTC)</th>');
+ tmpl_array.push(' </thead>');
+ tmpl_array.push(' <tbody id="folder_list_body">');
+ tmpl_array.push(' <tr>');
+ tmpl_array.push(' <td><a href="#<% if (upper_folder_id !== 0){ print("folders/" + upper_folder_id)} %>" title="Go to parent folder" class="btn_open_folder btn btn-default btn-xs">..<a></td>');
+ tmpl_array.push(' <td></td>');
+ tmpl_array.push(' <td></td>');
+ tmpl_array.push(' <td></td>');
+ tmpl_array.push(' <td></td>');
+ tmpl_array.push(' <td></td>');
+ tmpl_array.push(' </tr>');
- var dataset_ids = [];
- $('#folder_table').find(':checked').each(function(){
- if (this.parentElement.parentElement.id != '') {
- dataset_ids.push(this.parentElement.parentElement.id);
- }
- });
- var progress_bar_tmpl = _.template(this.templateProgressBar(), { history_name : history_name });
- $(this.modal.elMain).find('.modal-body').html(progress_bar_tmpl);
+ tmpl_array.push(' </tbody>');
+ tmpl_array.push('</table>');
- // init the progress bar
- var progressStep = 100 / dataset_ids.length;
- this.initProgress(progressStep);
-
- // prepare the dataset objects to be imported
- var datasets_to_import = [];
- for (var i = dataset_ids.length - 1; i >= 0; i--) {
- library_dataset_id = dataset_ids[i];
- var historyItem = new mod_library_model.HistoryItem();
- var self = this;
- historyItem.url = historyItem.urlRoot + history_id + '/contents';
- historyItem.content = library_dataset_id;
- historyItem.source = 'library';
- datasets_to_import.push(historyItem);
- };
-
- // call the recursive function to call ajax one after each other (request FIFO queue)
- this.chainCall(datasets_to_import);
- },
-
- chainCall: function(history_item_set){
- var self = this;
- var popped_item = history_item_set.pop();
- if (typeof popped_item === "undefined") {
- mod_toastr.success('All datasets imported');
- this.modal.hide();
- return
- }
- var promise = $.when(popped_item.save({content: popped_item.content, source: popped_item.source})).done(function(a1){
- self.updateProgress();
- // responses.push(a1);
- self.chainCall(history_item_set);
- });
- },
-
- initProgress: function(progressStep){
- this.progress = 0;
- this.progressStep = progressStep;
- },
- updateProgress: function(){
- this.progress += this.progressStep;
- $('.progress-bar-import').width(Math.round(this.progress) + '%');
- txt_representation = Math.round(this.progress) + '% Complete';
- $('.completion_span').text(txt_representation);
- },
-
-
-
- // download selected datasets
- download : function(folder_id, format){
- var dataset_ids = [];
- $('#folder_table').find(':checked').each(function(){
- if (this.parentElement.parentElement.id != '') {
- dataset_ids.push(this.parentElement.parentElement.id);
- }
- });
-
- var url = '/api/libraries/datasets/download/' + format;
- var data = {'ldda_ids' : dataset_ids};
- this.processDownload(url, data, 'get');
- },
-
- // create hidden form and submit through POST to initialize download
- processDownload: function(url, data, method){
- //url and data options required
- if( url && data ){
- //data can be string of parameters or array/object
- data = typeof data == 'string' ? data : $.param(data);
- //split params into form inputs
- var inputs = '';
- $.each(data.split('&'), function(){
- var pair = this.split('=');
- inputs+='<input type="hidden" name="'+ pair[0] +'" value="'+ pair[1] +'" />';
- });
- //send request
- $('<form action="'+ url +'" method="'+ (method||'post') +'">'+inputs+'</form>')
- .appendTo('body').submit().remove();
-
- mod_toastr.info('Your download will begin soon');
- };
- },
-
- // shows modal for creating folder
- createFolderFromModal: function(){
- event.preventDefault();
- event.stopPropagation();
-
- // create modal
- var self = this;
- this.modal = Galaxy.modal;
- this.modal.show({
- closing_events : true,
- title : 'Create New Folder',
- body : this.templateNewFolderInModal(),
- buttons : {
- 'Create' : function() {self.create_new_folder_event()},
- 'Close' : function() {self.modal.hide(); self.modal = null;}
- }
- });
- },
-
- // create the new folder from modal
- create_new_folder_event: function(){
- var folderDetails = this.serialize_new_folder();
- if (this.validate_new_folder(folderDetails)){
- var folder = new mod_library_model.FolderAsModel();
-
- url_items = Backbone.history.fragment.split('/');
- current_folder_id = url_items[url_items.length-1];
- folder.url = folder.urlRoot + '/' + current_folder_id ;
-
- var self = this;
- folder.save(folderDetails, {
- success: function (folder) {
- self.modal.hide();
- mod_toastr.success('Folder created');
- self.render({id: current_folder_id});
- },
- error: function(){
- mod_toastr.error('An error occured :(');
- }
- });
- } else {
- mod_toastr.error('Folder\'s name is missing');
- }
- return false;
- },
-
- // serialize data from the form
- serialize_new_folder : function(){
- return {
- name: $("input[name='Name']").val(),
- description: $("input[name='Description']").val()
- };
- },
-
- // validate new library info
- validate_new_folder: function(folderDetails){
- return folderDetails.name !== '';
+ return _.template(tmpl_array.join(''));
}
});
-// return
return {
- FolderContentView: FolderContentView
+ FolderListView: FolderListView
};
});
diff -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c -r a70f236803f7d398b4f486342e864add77e9ad3f static/scripts/mvc/library/library-librarylist-view.js
--- a/static/scripts/mvc/library/library-librarylist-view.js
+++ b/static/scripts/mvc/library/library-librarylist-view.js
@@ -1,14 +1,14 @@
// dependencies
define([
"galaxy.masthead",
- "mvc/base-mvc",
+ "mvc/base-mvc",
"utils/utils",
"libs/toastr",
"mvc/library/library-model",
- "mvc/library/library-libraryrow-view"],
+ "mvc/library/library-libraryrow-view"],
function(mod_masthead,
- mod_baseMVC,
- mod_utils,
+ mod_baseMVC,
+ mod_utils,
mod_toastr,
mod_library_model,
mod_library_libraryrow_view) {
@@ -29,7 +29,8 @@
rowViews: {},
// initialize
- initialize : function(){
+ initialize : function(options){
+ this.options = _.defaults(this.options || {}, options);
var viewContext = this;
this.rowViews = {};
@@ -43,7 +44,7 @@
error: function(model, response){
mod_toastr.error('An error occured. Please try again.');
}
- })
+ });
},
/** Renders the libraries table either from the object's own collection,
@@ -52,9 +53,8 @@
render: function (options) {
var template = this.templateLibraryList();
var libraries_to_render = null;
- var include_deleted = true;
var include_deleted = Galaxy.libraries.preferences.get('with_deleted');
- var models = null
+ var models = null;
if (typeof options !== 'undefined'){
include_deleted = typeof options.with_deleted !== 'undefined' ? options.with_deleted : false;
models = typeof options.models !== 'undefined' ? options.models : null;
@@ -64,7 +64,7 @@
if (include_deleted){ // show all the libraries
libraries_to_render = this.collection.models;
} else{ // show only undeleted libraries
- libraries_to_render = this.collection.where({deleted: false});;
+ libraries_to_render = this.collection.where({deleted: false});
}
} else if (models !== null){
libraries_to_render = models;
@@ -74,7 +74,9 @@
this.$el.html(template({length: libraries_to_render.length, order: Galaxy.libraries.preferences.get('sort_order') }));
- this.renderRows(libraries_to_render);
+ if (libraries_to_render.length > 0){
+ this.renderRows(libraries_to_render);
+ }
// initialize the library tooltips
$("#center [data-toggle]").tooltip();
// modification of upper DOM element to show scrollbars due to the #center element inheritance
@@ -92,9 +94,9 @@
var rowView = new mod_library_libraryrow_view.LibraryRowView(library);
this.$el.find('#library_list_body').append(rowView.el);
// save new rowView to cache
- this.rowViews[library.get('id')] = rowView;
+ this.rowViews[library.get('id')] = rowView;
}
- };
+ }
},
sort_clicked : function(){
@@ -115,17 +117,17 @@
if (order === 'asc'){
// this.collection.sort_order = 'asc';
this.collection.comparator = function(libraryA, libraryB){
- if (libraryA.get('name').toLowerCase() > libraryB.get('name').toLowerCase()) return 1; // after
- if (libraryB.get('name').toLowerCase() > libraryA.get('name').toLowerCase()) return -1; // before
+ if (libraryA.get('name').toLowerCase() > libraryB.get('name').toLowerCase()) {return 1;} // after
+ if (libraryB.get('name').toLowerCase() > libraryA.get('name').toLowerCase()) {return -1;} // before
return 0; // equal
- }
+ };
} else if (order === 'desc'){
// this.collection.sort_order = 'desc';
this.collection.comparator = function(libraryA, libraryB){
- if (libraryA.get('name').toLowerCase() > libraryB.get('name').toLowerCase()) return -1; // before
- if (libraryB.get('name').toLowerCase() > libraryA.get('name').toLowerCase()) return 1; // after
+ if (libraryA.get('name').toLowerCase() > libraryB.get('name').toLowerCase()) {return -1;} // before
+ if (libraryB.get('name').toLowerCase() > libraryA.get('name').toLowerCase()) {return 1;} // after
return 0; // equal
- }
+ };
}
this.collection.sort();
}
@@ -140,7 +142,7 @@
tmpl_array.push('<div class="library_container table-responsive">');
tmpl_array.push('<% if(length === 0) { %>');
- tmpl_array.push("<div>I see no libraries. Why don't you create one?</div>");
+ tmpl_array.push('<div>There are no libraries visible to you. If you expected some to show up please consult the <a href="https://wiki.galaxyproject.org/Admin/DataLibraries/LibrarySecurity">library security wikipage</a>.</div>');
tmpl_array.push('<% } else{ %>');
tmpl_array.push('<table class="grid table table-condensed">');
tmpl_array.push(' <thead>');
@@ -175,7 +177,7 @@
redirectToHome: function(){
window.location = '../';
- },
+ },
redirectToLogin: function(){
window.location = '/user/login';
},
@@ -193,7 +195,7 @@
title : 'Create New Library',
body : this.templateNewLibraryInModal(),
buttons : {
- 'Create' : function() {self.create_new_library_event()},
+ 'Create' : function() {self.create_new_library_event();},
'Close' : function() {self.modal.hide();}
}
});
@@ -245,7 +247,6 @@
}
});
-// return
return {
LibraryListView: LibraryListView
};
diff -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c -r a70f236803f7d398b4f486342e864add77e9ad3f static/scripts/mvc/library/library-libraryrow-view.js
--- a/static/scripts/mvc/library/library-libraryrow-view.js
+++ b/static/scripts/mvc/library/library-libraryrow-view.js
@@ -1,11 +1,11 @@
// dependencies
define([
- "galaxy.masthead",
+ "galaxy.masthead",
"utils/utils",
"libs/toastr",
- "mvc/library/library-model"],
-function(mod_masthead,
- mod_utils,
+ "mvc/library/library-model"],
+function(mod_masthead,
+ mod_utils,
mod_toastr,
mod_library_model) {
@@ -39,7 +39,7 @@
render: function(library){
if (typeof library === 'undefined'){
- var library = Galaxy.libraries.libraryListView.collection.get(this.$el.data('id'));
+ library = Galaxy.libraries.libraryListView.collection.get(this.$el.data('id'));
}
this.prepareButtons(library);
var tmpl = this.templateRow();
@@ -51,7 +51,7 @@
repaint: function(library){
/* need to hide manually because of the element removal in setElement
invoked in render() */
- $(".tooltip").hide();
+ $(".tooltip").hide();
/* we need to store the old element to be able to replace it with
new one */
var old_element = this.$el;
@@ -83,13 +83,13 @@
vis_config.undelete_library_btn = false;
if (library.get('can_user_add') === true){
vis_config.upload_library_btn = true;
- }
+ }
if (library.get('can_user_modify') === true){
vis_config.edit_library_btn = true;
- }
+ }
if (library.get('can_user_manage') === true){
vis_config.permission_library_btn = true;
- }
+ }
}
} else if (this.edit_mode === true){
vis_config.upload_library_btn = false;
@@ -136,7 +136,7 @@
is_changed = true;
} else{
mod_toastr.warning('Library name has to be at least 3 characters long');
- return
+ return;
}
}
@@ -183,7 +183,7 @@
Galaxy.libraries.libraryListView.collection.add(library);
row_view.edit_mode = false;
if (Galaxy.libraries.preferences.get('with_deleted') === false){
- $(".tooltip").hide();
+ $('.tooltip').hide();
row_view.$el.remove();
} else if (Galaxy.libraries.preferences.get('with_deleted') === true){
row_view.repaint(library);
@@ -247,12 +247,11 @@
tmpl_array.push(' </td>');
tmpl_array.push(' </tr>');
- return _.template(tmpl_array.join(''));
+ return _.template(tmpl_array.join(''));
}
});
- // return
return {
LibraryRowView: LibraryRowView
};
diff -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c -r a70f236803f7d398b4f486342e864add77e9ad3f static/scripts/mvc/library/library-librarytoolbar-view.js
--- a/static/scripts/mvc/library/library-librarytoolbar-view.js
+++ b/static/scripts/mvc/library/library-librarytoolbar-view.js
@@ -1,18 +1,18 @@
// dependencies
define([
- "galaxy.masthead",
+ "galaxy.masthead",
"utils/utils",
"libs/toastr",
- "mvc/library/library-model"],
-function(mod_masthead,
- mod_utils,
+ "mvc/library/library-model"],
+function(mod_masthead,
+ mod_utils,
mod_toastr,
mod_library_model) {
-var ToolbarView = Backbone.View.extend({
+var LibraryToolbarView = Backbone.View.extend({
el: '#center',
- events: {
+ events: {
'click #create_new_library_btn' : 'delegate_modal',
'click #include_deleted_chk' : 'check_include_deleted'
},
@@ -23,14 +23,16 @@
render: function(){
var toolbar_template = this.templateToolBar();
- this.$el.html(toolbar_template({admin_user: Galaxy.currUser.isAdmin(), anon_user: Galaxy.currUser.isAnonymous()}))
+ var is_admin = Galaxy.currUser.isAdmin();
+ var is_anonym = Galaxy.currUser.isAnonymous();
+ this.$el.html(toolbar_template({admin_user: is_admin, anon_user: is_anonym}));
if (Galaxy.currUser.isAdmin() === true){
this.$el.find('#include_deleted_chk')[0].checked = Galaxy.libraries.preferences.get('with_deleted');
}
},
delegate_modal: function(event){
- // probably should refactor to have this functionality in this view, not in the library view
+ // probably should refactor to have this functionality in this view, not in the library list view
Galaxy.libraries.libraryListView.show_library_modal(event);
},
@@ -48,7 +50,7 @@
templateToolBar: function(){
tmpl_array = [];
- tmpl_array.push('<div id="libraries_container" style="width: 90%; margin: auto; margin-top:2em; overflow: auto !important; ">');
+ tmpl_array.push('<div class="library_style_container">');
// TOOLBAR
tmpl_array.push(' <div id="toolbar_form" margin-top:0.5em; ">');
tmpl_array.push(' <h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');
@@ -60,16 +62,16 @@
tmpl_array.push(' <% } %>');
tmpl_array.push(' </div>');
tmpl_array.push(' <div id="libraries_element">');
+ // table with libraries will append here
tmpl_array.push(' </div>');
tmpl_array.push('</div>');
return _.template(tmpl_array.join(''));
}
-})
+});
-// return
return {
- ToolbarView: ToolbarView
+ LibraryToolbarView: LibraryToolbarView
};
});
diff -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c -r a70f236803f7d398b4f486342e864add77e9ad3f static/scripts/mvc/library/library-model.js
--- a/static/scripts/mvc/library/library-model.js
+++ b/static/scripts/mvc/library/library-model.js
@@ -66,16 +66,14 @@
var FolderContainer = Backbone.Model.extend({
defaults : {
folder : new Folder(),
- full_path : "unknown",
urlRoot : "/api/folders/",
id : "unknown"
},
parse : function(obj) {
- this.full_path = obj[0].full_path;
- // response is not a simple array, it contains metadata
- // this will update the inner collection
- this.get("folder").reset(obj[1].folder_contents);
- return obj;
+ // response is not a simple array, it contains metadata
+ // this will update the inner collection
+ this.get("folder").reset(obj.folder_contents);
+ return obj;
}
});
diff -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c -r a70f236803f7d398b4f486342e864add77e9ad3f static/scripts/packed/galaxy.library.js
--- a/static/scripts/packed/galaxy.library.js
+++ b/static/scripts/packed/galaxy.library.js
@@ -1,1 +1,1 @@
-var library_router=null;define(["galaxy.masthead","utils/utils","libs/toastr","mvc/base-mvc","mvc/library/library-model","mvc/library/library-folderlist-view","mvc/library/library-librarylist-view","mvc/library/library-librarytoolbar-view"],function(e,c,g,j,h,a,f,d){var k=Backbone.Router.extend({routes:{"":"libraries","sort/:sort_by/:order":"sort_libraries","folders/:id":"folder_content","folders/:folder_id/download/:format":"download"}});var i=j.SessionStorageModel.extend({defaults:{with_deleted:false,sort_order:"asc",sort_by:"name"}});var b=Backbone.View.extend({toolbarView:null,libraryListView:null,library_router:null,folderContentView:null,initialize:function(){Galaxy.libraries=this;this.preferences=new i({id:"global-lib-prefs"});this.library_router=new k();this.library_router.on("route:libraries",function(){Galaxy.libraries.toolbarView=new d.ToolbarView();Galaxy.libraries.libraryListView=new f.LibraryListView()});this.library_router.on("route:folder_content",function(l){if(!Galaxy.libraries.folderContentView){Galaxy.libraries.folderContentView=new a.FolderContentView()}Galaxy.libraries.folderContentView.render({id:l})});this.library_router.on("route:download",function(l,m){if($("#center").find(":checked").length===0){Galaxy.libraries.library_router.navigate("folders/"+l,{trigger:true,replace:true})}else{Galaxy.libraries.folderContentView.download(l,m);Galaxy.libraries.library_router.navigate("folders/"+l,{trigger:false,replace:true})}});Backbone.history.start({pushState:false})}});return{GalaxyApp:b}});
\ No newline at end of file
+define(["galaxy.masthead","utils/utils","libs/toastr","mvc/base-mvc","mvc/library/library-model","mvc/library/library-folderlist-view","mvc/library/library-librarylist-view","mvc/library/library-librarytoolbar-view","mvc/library/library-foldertoolbar-view"],function(e,c,g,k,h,a,f,d,i){var l=Backbone.Router.extend({routes:{"":"libraries","sort/:sort_by/:order":"sort_libraries","folders/:id":"folder_content","folders/:folder_id/download/:format":"download"}});var j=k.SessionStorageModel.extend({defaults:{with_deleted:false,sort_order:"asc",sort_by:"name"}});var b=Backbone.View.extend({libraryToolbarView:null,libraryListView:null,library_router:null,folderToolbarView:null,folderListView:null,initialize:function(){Galaxy.libraries=this;this.preferences=new j({id:"global-lib-prefs"});this.library_router=new l();this.library_router.on("route:libraries",function(){Galaxy.libraries.libraryToolbarView=new d.LibraryToolbarView();Galaxy.libraries.libraryListView=new f.LibraryListView()});this.library_router.on("route:folder_content",function(m){Galaxy.libraries.folderToolbarView=new i.FolderToolbarView({id:m});Galaxy.libraries.folderListView=new a.FolderListView({id:m})});this.library_router.on("route:download",function(m,n){if($("#center").find(":checked").length===0){g.info("You have to select some datasets to download");Galaxy.libraries.library_router.navigate("folders/"+m,{trigger:true,replace:true})}else{Galaxy.libraries.folderToolbarView.download(m,n);Galaxy.libraries.library_router.navigate("folders/"+m,{trigger:false,replace:true})}});Backbone.history.start({pushState:false})}});return{GalaxyApp:b}});
\ No newline at end of file
diff -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c -r a70f236803f7d398b4f486342e864add77e9ad3f static/scripts/packed/mvc/library/library-folderlist-view.js
--- a/static/scripts/packed/mvc/library/library-folderlist-view.js
+++ b/static/scripts/packed/mvc/library/library-folderlist-view.js
@@ -1,1 +1,1 @@
-define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(a,c,d,b){var e=Backbone.View.extend({el:"#center",progress:0,progressStep:1,lastSelectedHistory:"",modal:null,folders:null,initialize:function(){this.folders=[];this.queue=jQuery.Deferred();this.queue.resolve()},templateFolder:function(){var f=[];f.push('<div class="library_container" style="width: 90%; margin: auto; margin-top: 2em; ">');f.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');f.push('<div id="library_folder_toolbar" >');f.push(' <button title="Create New Folder" id="toolbtn_create_folder" class="primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder-close"></span> folder</button>');f.push(' <button title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button" style="display: none; margin-left: 0.5em;" type="button"><span class="fa fa-book"></span> to history</button>');f.push(' <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; display: none; ">');f.push(' <button title="Download selected datasets" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');f.push(' <span class="fa fa-download"></span> download <span class="caret"></span>');f.push(" </button>");f.push(' <ul class="dropdown-menu" role="menu">');f.push(' <li><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');f.push(' <li><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');f.push(' <li><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');f.push(" </ul>");f.push(" </div>");f.push("</div>");f.push('<ol class="breadcrumb">');f.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');f.push(" <% _.each(path, function(path_item) { %>");f.push(" <% if (path_item[0] != id) { %>");f.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');f.push("<% } else { %>");f.push(' <li class="active"><span title="You are in this folder"><%- path_item[1] %></span></li>');f.push(" <% } %>");f.push(" <% }); %>");f.push("</ol>");f.push('<table id="folder_table" class="grid table table-condensed">');f.push(" <thead>");f.push(' <th class="button_heading"></th>');f.push(' <th style="text-align: center; width: 20px; "><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');f.push(" <th>name</th>");f.push(" <th>data type</th>");f.push(" <th>size</th>");f.push(" <th>date (UTC)</th>");f.push(" </thead>");f.push(" <tbody>");f.push(' <td><a href="#<% if (upper_folder_id !== 0){ print("folders/" + upper_folder_id)} %>" title="Go to parent folder" class="btn_open_folder btn btn-default btn-xs">..<a></td>');f.push(" <td></td>");f.push(" <td></td>");f.push(" <td></td>");f.push(" <td></td>");f.push(" <td></td>");f.push(" </tr>");f.push(" <% _.each(items, function(content_item) { %>");f.push(' <% if (content_item.get("type") === "folder") { %>');f.push(' <tr class="folder_row light" id="<%- content_item.id %>">');f.push(" <td>");f.push(' <span title="Folder" class="fa fa-folder-o"></span>');f.push(" </td>");f.push(" <td></td>");f.push(" <td>");f.push(' <a href="#folders/<%- content_item.id %>"><%- content_item.get("name") %></a>');f.push(' <% if (content_item.get("item_count") === 0) { %>');f.push(' <span class="muted">(empty folder)</span>');f.push(" <% } %>");f.push(" </td>");f.push(" <td>folder</td>");f.push(' <td><%= _.escape(content_item.get("item_count")) %> item(s)</td>');f.push(' <td><%= _.escape(content_item.get("time_updated")) %></td>');f.push(" </tr>");f.push(" <% } else { %>");f.push(' <tr class="dataset_row light" id="<%- content_item.id %>">');f.push(" <td>");f.push(' <span title="Dataset" class="fa fa-file-o"></span>');f.push(" </td>");f.push(' <td style="text-align: center; "><input style="margin: 0;" type="checkbox"></td>');f.push(' <td><a href="#" class="library-dataset"><%- content_item.get("name") %><a></td>');f.push(' <td><%= _.escape(content_item.get("data_type")) %></td>');f.push(' <td><%= _.escape(content_item.get("readable_size")) %></td>');f.push(' <td><%= _.escape(content_item.get("time_updated")) %></td>');f.push(" </tr>");f.push(" <% } %> ");f.push(" <% }); %>");f.push(" ");f.push(" </tbody>");f.push("</table>");f.push("</div>");return f.join("")},templateDatasetModal:function(){var f=[];f.push('<div class="modal_table">');f.push(' <table class="grid table table-striped table-condensed">');f.push(" <tr>");f.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');f.push(' <td><%= _.escape(item.get("name")) %></td>');f.push(" </tr>");f.push(" <tr>");f.push(' <th scope="row">Data type</th>');f.push(' <td><%= _.escape(item.get("data_type")) %></td>');f.push(" </tr>");f.push(" <tr>");f.push(' <th scope="row">Genome build</th>');f.push(' <td><%= _.escape(item.get("genome_build")) %></td>');f.push(" </tr>");f.push(' <th scope="row">Size</th>');f.push(" <td><%= _.escape(size) %></td>");f.push(" </tr>");f.push(" <tr>");f.push(' <th scope="row">Date uploaded (UTC)</th>');f.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');f.push(" </tr>");f.push(" <tr>");f.push(' <th scope="row">Uploaded by</th>');f.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');f.push(" </tr>");f.push(' <tr scope="row">');f.push(' <th scope="row">Data Lines</th>');f.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');f.push(" </tr>");f.push(' <th scope="row">Comment Lines</th>');f.push(' <% if (item.get("metadata_comment_lines") === "") { %>');f.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');f.push(" <% } else { %>");f.push(' <td scope="row">unknown</td>');f.push(" <% } %>");f.push(" </tr>");f.push(" <tr>");f.push(' <th scope="row">Number of Columns</th>');f.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');f.push(" </tr>");f.push(" <tr>");f.push(' <th scope="row">Column Types</th>');f.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');f.push(" </tr>");f.push(" <tr>");f.push(' <th scope="row">Miscellaneous information</th>');f.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');f.push(" </tr>");f.push(" </table>");f.push(' <pre class="peek">');f.push(" </pre>");f.push("</div>");return f.join("")},templateHistorySelectInModal:function(){var f=[];f.push('<span id="history_modal_combo" style="width:100%; margin-left: 1em; margin-right: 1em; ">');f.push("Select history: ");f.push('<select id="dataset_import_single" name="dataset_import_single" style="width:40%; margin-bottom: 1em; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</span>");return f.join("")},templateBulkImportInModal:function(){var f=[];f.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');f.push("Select history: ");f.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</span>");return f.join("")},templateProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return f.join("")},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return tmpl_array.join("")},events:{"click #select-all-checkboxes":"selectAll","click #toolbtn_bulk_import":"modalBulkImport","click #toolbtn_dl":"bulkDownload","click #toolbtn_create_folder":"createFolderFromModal","click .library-dataset":"showDatasetDetails","click .dataset_row":"selectClickedRow"},render:function(f){$("#center").css("overflow","auto");view=this;var h=this;var g=new b.FolderContainer({id:f.id});g.url=g.attributes.urlRoot+f.id+"/contents";g.fetch({success:function(j){for(var l=0;l<g.attributes.folder.models.length;l++){var k=g.attributes.folder.models[l];if(k.get("type")==="file"){k.set("readable_size",h.size_to_string(k.get("file_size")))}}var n=g.full_path;var o;if(n.length===1){o=0}else{o=n[n.length-2][0]}var m=_.template(h.templateFolder(),{path:g.full_path,items:g.attributes.folder.models,id:f.id,upper_folder_id:o});h.$el.html(m)},error:function(){d.error("An error occured :(")}})},size_to_string:function(f){var g="";if(f>=100000000000){f=f/100000000000;g="TB"}else{if(f>=100000000){f=f/100000000;g="GB"}else{if(f>=100000){f=f/100000;g="MB"}else{if(f>=100){f=f/100;g="KB"}else{f=f*10;g="b"}}}}return(Math.round(f)/10)+g},showDatasetDetails:function(i){i.preventDefault();var j=$(i.target).parent().parent().parent().attr("id");if(typeof j==="undefined"){j=$(i.target).parent().attr("id")}if(typeof j==="undefined"){j=$(i.target).parent().parent().attr("id")}var h=new b.Item();var g=new b.GalaxyHistories();h.id=j;var f=this;h.fetch({success:function(k){g.fetch({success:function(l){f.renderModalAfterFetch(k,l)},error:function(){d.error("An error occured during fetching histories:(");f.renderModalAfterFetch(k)}})},error:function(){d.error("An error occured during loading dataset details :(")}})},renderModalAfterFetch:function(k,h){var i=this.size_to_string(k.get("file_size"));var j=_.template(this.templateDatasetModal(),{item:k,size:i});var g=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Dataset Details",body:j,buttons:{Import:function(){g.importCurrentIntoHistory()},Download:function(){g.downloadCurrent()},Close:function(){g.modal.hide()}}});$(".peek").html("Peek:"+k.get("peek"));if(typeof history.models!==undefined){var f=_.template(this.templateHistorySelectInModal(),{histories:h.models});$(this.modal.elMain).find(".buttons").prepend(f);if(g.lastSelectedHistory.length>0){$(this.modal.elMain).find("#dataset_import_single").val(g.lastSelectedHistory)}}},downloadCurrent:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var f=[];f.push($("#id_row").attr("data-id"));var g="/api/libraries/datasets/download/uncompressed";var h={ldda_ids:f};folderContentView.processDownload(g,h);this.modal.enableButton("Import");this.modal.enableButton("Download")},importCurrentIntoHistory:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var h=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();this.lastSelectedHistory=h;var f=$("#id_row").attr("data-id");var i=new b.HistoryItem();var g=this;i.url=i.urlRoot+h+"/contents";i.save({content:f,source:"library"},{success:function(){d.success("Dataset imported");g.modal.enableButton("Import");g.modal.enableButton("Download")},error:function(){d.error("An error occured! Dataset not imported. Please try again.");g.modal.enableButton("Import");g.modal.enableButton("Download")}})},selectAll:function(g){var f=g.target.checked;that=this;$(":checkbox").each(function(){this.checked=f;$row=$(this.parentElement.parentElement);(f)?that.makeDarkRow($row):that.makeWhiteRow($row)});this.checkTools()},selectClickedRow:function(g){var i="";var f;var h;if(g.target.localName==="input"){i=g.target;f=$(g.target.parentElement.parentElement);h="input"}else{if(g.target.localName==="td"){i=$("#"+g.target.parentElement.id).find(":checkbox")[0];f=$(g.target.parentElement);h="td"}}if(i.checked){if(h==="td"){i.checked="";this.makeWhiteRow(f)}else{if(h==="input"){this.makeDarkRow(f)}}}else{if(h==="td"){i.checked="selected";this.makeDarkRow(f)}else{if(h==="input"){this.makeWhiteRow(f)}}}this.checkTools()},makeDarkRow:function(f){f.removeClass("light");f.find("a").removeClass("light");f.addClass("dark");f.find("a").addClass("dark");f.find("span").removeClass("fa-file-o");f.find("span").addClass("fa-file")},makeWhiteRow:function(f){f.removeClass("dark");f.find("a").removeClass("dark");f.addClass("light");f.find("a").addClass("light");f.find("span").addClass("fa-file-o");f.find("span").removeClass("fa-file")},checkTools:function(){var f=$("#folder_table").find(":checked");if(f.length>0){$("#toolbtn_bulk_import").show();$("#toolbtn_dl").show()}else{$("#toolbtn_bulk_import").hide();$("#toolbtn_dl").hide()}},modalBulkImport:function(){var g=this;var f=new b.GalaxyHistories();f.fetch({success:function(h){var i=_.template(g.templateBulkImportInModal(),{histories:h.models});g.modal=Galaxy.modal;g.modal.show({closing_events:true,title:"Import into History",body:i,buttons:{Import:function(){g.importAllIntoHistory()},Close:function(){g.modal.hide()}}})},error:function(){d.error("An error occured :(")}})},importAllIntoHistory:function(){this.modal.disableButton("Import");var h=$("select[name=dataset_import_bulk] option:selected").val();var m=$("select[name=dataset_import_bulk] option:selected").text();var o=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){o.push(this.parentElement.parentElement.id)}});var n=_.template(this.templateProgressBar(),{history_name:m});$(this.modal.elMain).find(".modal-body").html(n);var j=100/o.length;this.initProgress(j);var f=[];for(var g=o.length-1;g>=0;g--){library_dataset_id=o[g];var k=new b.HistoryItem();var l=this;k.url=k.urlRoot+h+"/contents";k.content=library_dataset_id;k.source="library";f.push(k)}this.chainCall(f)},chainCall:function(g){var f=this;var h=g.pop();if(typeof h==="undefined"){d.success("All datasets imported");this.modal.hide();return}var i=$.when(h.save({content:h.content,source:h.source})).done(function(j){f.updateProgress();f.chainCall(g)})},initProgress:function(f){this.progress=0;this.progressStep=f},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(f,j){var h=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){h.push(this.parentElement.parentElement.id)}});var g="/api/libraries/datasets/download/"+j;var i={ldda_ids:h};this.processDownload(g,i,"get")},processDownload:function(g,h,i){if(g&&h){h=typeof h=="string"?h:$.param(h);var f="";$.each(h.split("&"),function(){var j=this.split("=");f+='<input type="hidden" name="'+j[0]+'" value="'+j[1]+'" />'});$('<form action="'+g+'" method="'+(i||"post")+'">'+f+"</form>").appendTo("body").submit().remove();d.info("Your download will begin soon")}},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var f=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Folder",body:this.templateNewFolderInModal(),buttons:{Create:function(){f.create_new_folder_event()},Close:function(){f.modal.hide();f.modal=null}}})},create_new_folder_event:function(){var f=this.serialize_new_folder();if(this.validate_new_folder(f)){var h=new b.FolderAsModel();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];h.url=h.urlRoot+"/"+current_folder_id;var g=this;h.save(f,{success:function(i){g.modal.hide();d.success("Folder created");g.render({id:current_folder_id})},error:function(){d.error("An error occured :(")}})}else{d.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(f){return f.name!==""}});return{FolderContentView:e}});
\ No newline at end of file
+define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model","mvc/library/library-folderrow-view"],function(c,e,f,d,a){var b=Backbone.View.extend({el:"#folder_items_element",progress:0,progressStep:1,modal:null,folderContainer:null,events:{"click #select-all-checkboxes":"selectAll","click .dataset_row":"selectClickedRow"},initialize:function(g){var h=this;this.options=_.defaults(this.options||{},g);this.queue=jQuery.Deferred();this.queue.resolve();this.folderContainer=new d.FolderContainer({id:this.options.id});this.folderContainer.url=this.folderContainer.attributes.urlRoot+this.options.id+"/contents";this.folderContainer.fetch({success:function(i){h.render()},error:function(){f.error("An error occured :(")}})},render:function(h){this.options=_.defaults(this.options||{},h);var k=this.templateFolder();var l=false;for(var j=0;j<this.folderContainer.attributes.folder.models.length;j++){var g=this.folderContainer.attributes.folder.models[j];if(g.get("type")==="file"){l=true;g.set("readable_size",this.size_to_string(g.get("file_size")))}}var m=this.folderContainer.attributes.metadata.full_path;var n;if(m.length===1){n=0}else{n=m[m.length-2][0]}this.$el.html(k({path:this.folderContainer.attributes.metadata.full_path,items:this.folderContainer.attributes.folder.models,id:this.options.id,upper_folder_id:n}));if(this.folderContainer.attributes.folder.models.length>0){this.renderRows()}if(this.folderContainer.attributes.metadata.can_add_library_item===true){Galaxy.libraries.folderToolbarView.configureElements({can_add_library_item:this.folderContainer.attributes.metadata.can_add_library_item,contains_file:l})}$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},renderRows:function(){for(var j=0;j<this.folderContainer.attributes.folder.models.length;j++){var h=this.folderContainer.attributes.folder.models[j];var g=new a.FolderRowView(h);this.$el.find("#folder_list_body").append(g.el)}},size_to_string:function(g){var h="";if(g>=100000000000){g=g/100000000000;h="TB"}else{if(g>=100000000){g=g/100000000;h="GB"}else{if(g>=100000){g=g/100000;h="MB"}else{if(g>=100){g=g/100;h="KB"}else{g=g*10;h="b"}}}}return(Math.round(g)/10)+h},selectAll:function(h){var g=h.target.checked;that=this;$(":checkbox").each(function(){this.checked=g;$row=$(this.parentElement.parentElement);(g)?that.makeDarkRow($row):that.makeWhiteRow($row)})},selectClickedRow:function(h){var j="";var g;var i;if(h.target.localName==="input"){j=h.target;g=$(h.target.parentElement.parentElement);i="input"}else{if(h.target.localName==="td"){j=$("#"+h.target.parentElement.id).find(":checkbox")[0];g=$(h.target.parentElement);i="td"}}if(j.checked){if(i==="td"){j.checked="";this.makeWhiteRow(g)}else{if(i==="input"){this.makeDarkRow(g)}}}else{if(i==="td"){j.checked="selected";this.makeDarkRow(g)}else{if(i==="input"){this.makeWhiteRow(g)}}}},makeDarkRow:function(g){g.removeClass("light");g.find("a").removeClass("light");g.addClass("dark");g.find("a").addClass("dark");g.find("span").removeClass("fa-file-o");g.find("span").addClass("fa-file")},makeWhiteRow:function(g){g.removeClass("dark");g.find("a").removeClass("dark");g.addClass("light");g.find("a").addClass("light");g.find("span").addClass("fa-file-o");g.find("span").removeClass("fa-file")},templateFolder:function(){var g=[];g.push('<ol class="breadcrumb">');g.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');g.push(" <% _.each(path, function(path_item) { %>");g.push(" <% if (path_item[0] != id) { %>");g.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');g.push("<% } else { %>");g.push(' <li class="active"><span title="You are in this folder"><%- path_item[1] %></span></li>');g.push(" <% } %>");g.push(" <% }); %>");g.push("</ol>");g.push('<table id="folder_table" class="grid table table-condensed">');g.push(" <thead>");g.push(' <th class="button_heading"></th>');g.push(' <th style="text-align: center; width: 20px; "><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');g.push(" <th>name</th>");g.push(" <th>data type</th>");g.push(" <th>size</th>");g.push(" <th>date (UTC)</th>");g.push(" </thead>");g.push(' <tbody id="folder_list_body">');g.push(" <tr>");g.push(' <td><a href="#<% if (upper_folder_id !== 0){ print("folders/" + upper_folder_id)} %>" title="Go to parent folder" class="btn_open_folder btn btn-default btn-xs">..<a></td>');g.push(" <td></td>");g.push(" <td></td>");g.push(" <td></td>");g.push(" <td></td>");g.push(" <td></td>");g.push(" </tr>");g.push(" </tbody>");g.push("</table>");return _.template(g.join(""))}});return{FolderListView:b}});
\ No newline at end of file
diff -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c -r a70f236803f7d398b4f486342e864add77e9ad3f static/scripts/packed/mvc/library/library-librarylist-view.js
--- a/static/scripts/packed/mvc/library/library-librarylist-view.js
+++ b/static/scripts/packed/mvc/library/library-librarylist-view.js
@@ -1,1 +1,1 @@
-define(["galaxy.masthead","mvc/base-mvc","utils/utils","libs/toastr","mvc/library/library-model","mvc/library/library-libraryrow-view"],function(b,g,d,e,c,a){var f=Backbone.View.extend({el:"#libraries_element",events:{"click .sort-libraries-link":"sort_clicked"},modal:null,collection:null,rowViews:{},initialize:function(){var h=this;this.rowViews={};this.collection=new c.Libraries();this.collection.fetch({success:function(i){h.render()},error:function(j,i){e.error("An error occured. Please try again.")}})},render:function(i){var j=this.templateLibraryList();var k=null;var h=true;var h=Galaxy.libraries.preferences.get("with_deleted");var l=null;if(typeof i!=="undefined"){h=typeof i.with_deleted!=="undefined"?i.with_deleted:false;l=typeof i.models!=="undefined"?i.models:null}if(this.collection!==null&&l===null){if(h){k=this.collection.models}else{k=this.collection.where({deleted:false})}}else{if(l!==null){k=l}else{k=[]}}this.$el.html(j({length:k.length,order:Galaxy.libraries.preferences.get("sort_order")}));this.renderRows(k);$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},renderRows:function(m){for(var l=0;l<m.length;l++){var k=m[l];var j=_.findWhere(this.rowViews,{id:k.get("id")});if(j!==undefined&&this instanceof Backbone.View){j.delegateEvents();this.$el.find("#library_list_body").append(j.el)}else{var h=new a.LibraryRowView(k);this.$el.find("#library_list_body").append(h.el);this.rowViews[k.get("id")]=h}}},sort_clicked:function(){if(Galaxy.libraries.preferences.get("sort_order")==="asc"){this.sortLibraries("name","desc");Galaxy.libraries.preferences.set({sort_order:"desc"})}else{this.sortLibraries("name","asc");Galaxy.libraries.preferences.set({sort_order:"asc"})}this.render()},sortLibraries:function(i,h){if(i==="name"){if(h==="asc"){this.collection.comparator=function(k,j){if(k.get("name").toLowerCase()>j.get("name").toLowerCase()){return 1}if(j.get("name").toLowerCase()>k.get("name").toLowerCase()){return -1}return 0}}else{if(h==="desc"){this.collection.comparator=function(k,j){if(k.get("name").toLowerCase()>j.get("name").toLowerCase()){return -1}if(j.get("name").toLowerCase()>k.get("name").toLowerCase()){return 1}return 0}}}this.collection.sort()}},templateLibraryList:function(){tmpl_array=[];tmpl_array.push('<div class="library_container table-responsive">');tmpl_array.push("<% if(length === 0) { %>");tmpl_array.push("<div>I see no libraries. Why don't you create one?</div>");tmpl_array.push("<% } else{ %>");tmpl_array.push('<table class="grid table table-condensed">');tmpl_array.push(" <thead>");tmpl_array.push(' <th style="width:30%;"><a class="sort-libraries-link" title="Click to reverse order" href="#">name</a><span title="Sorted alphabetically" class="fa fa-sort-alpha-<%- order %>"></span></th>');tmpl_array.push(' <th style="width:22%;">description</th>');tmpl_array.push(' <th style="width:22%;">synopsis</th> ');tmpl_array.push(' <th style="width:26%;"></th> ');tmpl_array.push(" </thead>");tmpl_array.push(' <tbody id="library_list_body">');tmpl_array.push(" </tbody>");tmpl_array.push("</table>");tmpl_array.push("<% }%>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateNewLibraryInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_library_modal">');tmpl_array.push(" <form>");tmpl_array.push(' <input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push(' <input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push(' <input type="text" name="Synopsis" value="" placeholder="Synopsis">');tmpl_array.push(" </form>");tmpl_array.push("</div>");return tmpl_array.join("")},redirectToHome:function(){window.location="../"},redirectToLogin:function(){window.location="/user/login"},show_library_modal:function(i){i.preventDefault();i.stopPropagation();var h=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Library",body:this.templateNewLibraryInModal(),buttons:{Create:function(){h.create_new_library_event()},Close:function(){h.modal.hide()}}})},create_new_library_event:function(){var j=this.serialize_new_library();if(this.validate_new_library(j)){var i=new c.Library();var h=this;i.save(j,{success:function(k){h.collection.add(k);h.modal.hide();h.clear_library_modal();h.render();e.success("Library created")},error:function(){e.error("An error occured :(")}})}else{e.error("Library's name is missing")}return false},clear_library_modal:function(){$("input[name='Name']").val("");$("input[name='Description']").val("");$("input[name='Synopsis']").val("")},serialize_new_library:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val(),synopsis:$("input[name='Synopsis']").val()}},validate_new_library:function(h){return h.name!==""}});return{LibraryListView:f}});
\ No newline at end of file
+define(["galaxy.masthead","mvc/base-mvc","utils/utils","libs/toastr","mvc/library/library-model","mvc/library/library-libraryrow-view"],function(b,g,d,e,c,a){var f=Backbone.View.extend({el:"#libraries_element",events:{"click .sort-libraries-link":"sort_clicked"},modal:null,collection:null,rowViews:{},initialize:function(i){this.options=_.defaults(this.options||{},i);var h=this;this.rowViews={};this.collection=new c.Libraries();this.collection.fetch({success:function(j){h.render()},error:function(k,j){e.error("An error occured. Please try again.")}})},render:function(i){var j=this.templateLibraryList();var k=null;var h=Galaxy.libraries.preferences.get("with_deleted");var l=null;if(typeof i!=="undefined"){h=typeof i.with_deleted!=="undefined"?i.with_deleted:false;l=typeof i.models!=="undefined"?i.models:null}if(this.collection!==null&&l===null){if(h){k=this.collection.models}else{k=this.collection.where({deleted:false})}}else{if(l!==null){k=l}else{k=[]}}this.$el.html(j({length:k.length,order:Galaxy.libraries.preferences.get("sort_order")}));if(k.length>0){this.renderRows(k)}$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},renderRows:function(m){for(var l=0;l<m.length;l++){var k=m[l];var j=_.findWhere(this.rowViews,{id:k.get("id")});if(j!==undefined&&this instanceof Backbone.View){j.delegateEvents();this.$el.find("#library_list_body").append(j.el)}else{var h=new a.LibraryRowView(k);this.$el.find("#library_list_body").append(h.el);this.rowViews[k.get("id")]=h}}},sort_clicked:function(){if(Galaxy.libraries.preferences.get("sort_order")==="asc"){this.sortLibraries("name","desc");Galaxy.libraries.preferences.set({sort_order:"desc"})}else{this.sortLibraries("name","asc");Galaxy.libraries.preferences.set({sort_order:"asc"})}this.render()},sortLibraries:function(i,h){if(i==="name"){if(h==="asc"){this.collection.comparator=function(k,j){if(k.get("name").toLowerCase()>j.get("name").toLowerCase()){return 1}if(j.get("name").toLowerCase()>k.get("name").toLowerCase()){return -1}return 0}}else{if(h==="desc"){this.collection.comparator=function(k,j){if(k.get("name").toLowerCase()>j.get("name").toLowerCase()){return -1}if(j.get("name").toLowerCase()>k.get("name").toLowerCase()){return 1}return 0}}}this.collection.sort()}},templateLibraryList:function(){tmpl_array=[];tmpl_array.push('<div class="library_container table-responsive">');tmpl_array.push("<% if(length === 0) { %>");tmpl_array.push('<div>There are no libraries visible to you. If you expected some to show up please consult the <a href="https://wiki.galaxyproject.org/Admin/DataLibraries/LibrarySecurity">library security wikipage</a>.</div>');tmpl_array.push("<% } else{ %>");tmpl_array.push('<table class="grid table table-condensed">');tmpl_array.push(" <thead>");tmpl_array.push(' <th style="width:30%;"><a class="sort-libraries-link" title="Click to reverse order" href="#">name</a><span title="Sorted alphabetically" class="fa fa-sort-alpha-<%- order %>"></span></th>');tmpl_array.push(' <th style="width:22%;">description</th>');tmpl_array.push(' <th style="width:22%;">synopsis</th> ');tmpl_array.push(' <th style="width:26%;"></th> ');tmpl_array.push(" </thead>");tmpl_array.push(' <tbody id="library_list_body">');tmpl_array.push(" </tbody>");tmpl_array.push("</table>");tmpl_array.push("<% }%>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateNewLibraryInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_library_modal">');tmpl_array.push(" <form>");tmpl_array.push(' <input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push(' <input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push(' <input type="text" name="Synopsis" value="" placeholder="Synopsis">');tmpl_array.push(" </form>");tmpl_array.push("</div>");return tmpl_array.join("")},redirectToHome:function(){window.location="../"},redirectToLogin:function(){window.location="/user/login"},show_library_modal:function(i){i.preventDefault();i.stopPropagation();var h=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Library",body:this.templateNewLibraryInModal(),buttons:{Create:function(){h.create_new_library_event()},Close:function(){h.modal.hide()}}})},create_new_library_event:function(){var j=this.serialize_new_library();if(this.validate_new_library(j)){var i=new c.Library();var h=this;i.save(j,{success:function(k){h.collection.add(k);h.modal.hide();h.clear_library_modal();h.render();e.success("Library created")},error:function(){e.error("An error occured :(")}})}else{e.error("Library's name is missing")}return false},clear_library_modal:function(){$("input[name='Name']").val("");$("input[name='Description']").val("");$("input[name='Synopsis']").val("")},serialize_new_library:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val(),synopsis:$("input[name='Synopsis']").val()}},validate_new_library:function(h){return h.name!==""}});return{LibraryListView:f}});
\ No newline at end of file
diff -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c -r a70f236803f7d398b4f486342e864add77e9ad3f static/scripts/packed/mvc/library/library-libraryrow-view.js
--- a/static/scripts/packed/mvc/library/library-libraryrow-view.js
+++ b/static/scripts/packed/mvc/library/library-libraryrow-view.js
@@ -1,1 +1,1 @@
-define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(b,d,e,c){var a=Backbone.View.extend({events:{"click .edit_library_btn":"edit_button_clicked","click .cancel_library_btn":"cancel_library_modification","click .save_library_btn":"save_library_modification","click .delete_library_btn":"delete_library","click .undelete_library_btn":"undelete_library","click .upload_library_btn":"upload_to_library","click .permission_library_btn":"permissions_on_library"},edit_mode:false,element_visibility_config:{upload_library_btn:false,edit_library_btn:false,permission_library_btn:false,save_library_btn:false,cancel_library_btn:false,delete_library_btn:false,undelete_library_btn:false},initialize:function(f){this.render(f)},render:function(g){if(typeof g==="undefined"){var g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"))}this.prepareButtons(g);var f=this.templateRow();this.setElement(f({library:g,button_config:this.element_visibility_config,edit_mode:this.edit_mode}));this.$el.show();return this},repaint:function(f){$(".tooltip").hide();var g=this.$el;this.render(f);g.replaceWith(this.$el);this.$el.find("[data-toggle]").tooltip()},prepareButtons:function(f){vis_config=this.element_visibility_config;if(this.edit_mode===false){vis_config.save_library_btn=false;vis_config.cancel_library_btn=false;vis_config.delete_library_btn=false;if(f.get("deleted")===true){vis_config.undelete_library_btn=true;vis_config.upload_library_btn=false;vis_config.edit_library_btn=false;vis_config.permission_library_btn=false}else{if(f.get("deleted")===false){vis_config.save_library_btn=false;vis_config.cancel_library_btn=false;vis_config.undelete_library_btn=false;if(f.get("can_user_add")===true){vis_config.upload_library_btn=true}if(f.get("can_user_modify")===true){vis_config.edit_library_btn=true}if(f.get("can_user_manage")===true){vis_config.permission_library_btn=true}}}}else{if(this.edit_mode===true){vis_config.upload_library_btn=false;vis_config.edit_library_btn=false;vis_config.permission_library_btn=false;vis_config.save_library_btn=true;vis_config.cancel_library_btn=true;vis_config.delete_library_btn=true}}this.element_visibility_config=vis_config},upload_to_library:function(){e.info("Coming soon. Stay tuned.")},permissions_on_library:function(){e.info("Coming soon. Stay tuned.")},edit_button_clicked:function(){this.edit_mode=true;this.repaint()},cancel_library_modification:function(){e.info("Modifications canceled");this.edit_mode=false;this.repaint()},save_library_modification:function(){var g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"));var h=false;var j=this.$el.find(".input_library_name").val();if(typeof j!=="undefined"&&j!==g.get("name")){if(j.length>2){g.set("name",j);h=true}else{e.warning("Library name has to be at least 3 characters long");return}}var i=this.$el.find(".input_library_description").val();if(typeof i!=="undefined"&&i!==g.get("description")){g.set("description",i);h=true}var k=this.$el.find(".input_library_synopsis").val();if(typeof k!=="undefined"&&k!==g.get("synopsis")){g.set("synopsis",k);h=true}if(h){var f=this;g.save(null,{patch:true,success:function(l){f.edit_mode=false;f.repaint(l);e.success("Changes to library saved")},error:function(m,l){e.error("An error occured during updating the library :(")}})}else{this.edit_mode=false;this.repaint(g);e.info("Nothing has changed")}},delete_library:function(){var g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"));var f=this;g.destroy({success:function(h){h.set("deleted",true);Galaxy.libraries.libraryListView.collection.add(h);f.edit_mode=false;if(Galaxy.libraries.preferences.get("with_deleted")===false){$(".tooltip").hide();f.$el.remove()}else{if(Galaxy.libraries.preferences.get("with_deleted")===true){f.repaint(h)}}e.success("Library has been marked deleted")},error:function(){e.error("An error occured during deleting the library :(")}})},undelete_library:function(){var g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"));var f=this;g.url=g.urlRoot+g.id+"?undelete=true";g.destroy({success:function(h){h.set("deleted",false);Galaxy.libraries.libraryListView.collection.add(h);f.edit_mode=false;f.repaint(h);e.success("Library has been undeleted")},error:function(){e.error("An error occured while undeleting the library :(")}})},templateRow:function(){tmpl_array=[];tmpl_array.push(' <tr class="<% if(library.get("deleted") === true) { print("active") } %>" style="display:none;" data-id="<%- library.get("id") %>">');tmpl_array.push(" <% if(!edit_mode) { %>");tmpl_array.push(' <td><a href="#folders/<%- library.get("root_folder_id") %>"><%- library.get("name") %></a></td>');tmpl_array.push(' <td><%= _.escape(library.get("description")) %></td>');tmpl_array.push(' <td><%= _.escape(library.get("synopsis")) %></td>');tmpl_array.push(" <% } else if(edit_mode){ %>");tmpl_array.push(' <td><input type="text" class="form-control input_library_name" placeholder="name" value="<%- library.get("name") %>"></td>');tmpl_array.push(' <td><input type="text" class="form-control input_library_description" placeholder="description" value="<%- library.get("description") %>"></td>');tmpl_array.push(' <td><input type="text" class="form-control input_library_synopsis" placeholder="synopsis" value="<%- library.get("synopsis") %>"></td>');tmpl_array.push(" <% } %>");tmpl_array.push(' <td class="right-center">');tmpl_array.push(' <% if(library.get("deleted") === true) { %>');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Marked deleted" style="color:grey;" class="fa fa-ban fa-lg deleted_lib_ico"></span>');tmpl_array.push(' <% } else if(library.get("public") === true) { %>');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Public" style="color:grey;" class="fa fa-globe fa-lg public_lib_ico"></span>');tmpl_array.push(" <% }%>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Upload to library" class="primary-button btn-xs upload_library_btn" type="button" style="<% if(button_config.upload_library_btn === false) { print("display:none;") } %>"><span class="fa fa-upload"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Modify library" class="primary-button btn-xs edit_library_btn" type="button" style="<% if(button_config.edit_library_btn === false) { print("display:none;") } %>"><span class="fa fa-pencil"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Modify permissions" class="primary-button btn-xs permission_library_btn" type="button" style="<% if(button_config.permission_library_btn === false) { print("display:none;") } %>"><span class="fa fa-group"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Save changes" class="primary-button btn-xs save_library_btn" type="button" style="<% if(button_config.save_library_btn === false) { print("display:none;") } %>"><span class="fa fa-floppy-o"> Save</span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Discard changes" class="primary-button btn-xs cancel_library_btn" type="button" style="<% if(button_config.cancel_library_btn === false) { print("display:none;") } %>"><span class="fa fa-times"> Cancel</span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Delete library (can be undeleted later)" class="primary-button btn-xs delete_library_btn" type="button" style="<% if(button_config.delete_library_btn === false) { print("display:none;") } %>"><span class="fa fa-trash-o"> Delete</span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Undelete library" class="primary-button btn-xs undelete_library_btn" type="button" style="<% if(button_config.undelete_library_btn === false) { print("display:none;") } %>"><span class="fa fa-unlock"> Undelete</span></button>');tmpl_array.push(" </td>");tmpl_array.push(" </tr>");return _.template(tmpl_array.join(""))}});return{LibraryRowView:a}});
\ No newline at end of file
+define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(b,d,e,c){var a=Backbone.View.extend({events:{"click .edit_library_btn":"edit_button_clicked","click .cancel_library_btn":"cancel_library_modification","click .save_library_btn":"save_library_modification","click .delete_library_btn":"delete_library","click .undelete_library_btn":"undelete_library","click .upload_library_btn":"upload_to_library","click .permission_library_btn":"permissions_on_library"},edit_mode:false,element_visibility_config:{upload_library_btn:false,edit_library_btn:false,permission_library_btn:false,save_library_btn:false,cancel_library_btn:false,delete_library_btn:false,undelete_library_btn:false},initialize:function(f){this.render(f)},render:function(g){if(typeof g==="undefined"){g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"))}this.prepareButtons(g);var f=this.templateRow();this.setElement(f({library:g,button_config:this.element_visibility_config,edit_mode:this.edit_mode}));this.$el.show();return this},repaint:function(f){$(".tooltip").hide();var g=this.$el;this.render(f);g.replaceWith(this.$el);this.$el.find("[data-toggle]").tooltip()},prepareButtons:function(f){vis_config=this.element_visibility_config;if(this.edit_mode===false){vis_config.save_library_btn=false;vis_config.cancel_library_btn=false;vis_config.delete_library_btn=false;if(f.get("deleted")===true){vis_config.undelete_library_btn=true;vis_config.upload_library_btn=false;vis_config.edit_library_btn=false;vis_config.permission_library_btn=false}else{if(f.get("deleted")===false){vis_config.save_library_btn=false;vis_config.cancel_library_btn=false;vis_config.undelete_library_btn=false;if(f.get("can_user_add")===true){vis_config.upload_library_btn=true}if(f.get("can_user_modify")===true){vis_config.edit_library_btn=true}if(f.get("can_user_manage")===true){vis_config.permission_library_btn=true}}}}else{if(this.edit_mode===true){vis_config.upload_library_btn=false;vis_config.edit_library_btn=false;vis_config.permission_library_btn=false;vis_config.save_library_btn=true;vis_config.cancel_library_btn=true;vis_config.delete_library_btn=true}}this.element_visibility_config=vis_config},upload_to_library:function(){e.info("Coming soon. Stay tuned.")},permissions_on_library:function(){e.info("Coming soon. Stay tuned.")},edit_button_clicked:function(){this.edit_mode=true;this.repaint()},cancel_library_modification:function(){e.info("Modifications canceled");this.edit_mode=false;this.repaint()},save_library_modification:function(){var g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"));var h=false;var j=this.$el.find(".input_library_name").val();if(typeof j!=="undefined"&&j!==g.get("name")){if(j.length>2){g.set("name",j);h=true}else{e.warning("Library name has to be at least 3 characters long");return}}var i=this.$el.find(".input_library_description").val();if(typeof i!=="undefined"&&i!==g.get("description")){g.set("description",i);h=true}var k=this.$el.find(".input_library_synopsis").val();if(typeof k!=="undefined"&&k!==g.get("synopsis")){g.set("synopsis",k);h=true}if(h){var f=this;g.save(null,{patch:true,success:function(l){f.edit_mode=false;f.repaint(l);e.success("Changes to library saved")},error:function(m,l){e.error("An error occured during updating the library :(")}})}else{this.edit_mode=false;this.repaint(g);e.info("Nothing has changed")}},delete_library:function(){var g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"));var f=this;g.destroy({success:function(h){h.set("deleted",true);Galaxy.libraries.libraryListView.collection.add(h);f.edit_mode=false;if(Galaxy.libraries.preferences.get("with_deleted")===false){$(".tooltip").hide();f.$el.remove()}else{if(Galaxy.libraries.preferences.get("with_deleted")===true){f.repaint(h)}}e.success("Library has been marked deleted")},error:function(){e.error("An error occured during deleting the library :(")}})},undelete_library:function(){var g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"));var f=this;g.url=g.urlRoot+g.id+"?undelete=true";g.destroy({success:function(h){h.set("deleted",false);Galaxy.libraries.libraryListView.collection.add(h);f.edit_mode=false;f.repaint(h);e.success("Library has been undeleted")},error:function(){e.error("An error occured while undeleting the library :(")}})},templateRow:function(){tmpl_array=[];tmpl_array.push(' <tr class="<% if(library.get("deleted") === true) { print("active") } %>" style="display:none;" data-id="<%- library.get("id") %>">');tmpl_array.push(" <% if(!edit_mode) { %>");tmpl_array.push(' <td><a href="#folders/<%- library.get("root_folder_id") %>"><%- library.get("name") %></a></td>');tmpl_array.push(' <td><%= _.escape(library.get("description")) %></td>');tmpl_array.push(' <td><%= _.escape(library.get("synopsis")) %></td>');tmpl_array.push(" <% } else if(edit_mode){ %>");tmpl_array.push(' <td><input type="text" class="form-control input_library_name" placeholder="name" value="<%- library.get("name") %>"></td>');tmpl_array.push(' <td><input type="text" class="form-control input_library_description" placeholder="description" value="<%- library.get("description") %>"></td>');tmpl_array.push(' <td><input type="text" class="form-control input_library_synopsis" placeholder="synopsis" value="<%- library.get("synopsis") %>"></td>');tmpl_array.push(" <% } %>");tmpl_array.push(' <td class="right-center">');tmpl_array.push(' <% if(library.get("deleted") === true) { %>');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Marked deleted" style="color:grey;" class="fa fa-ban fa-lg deleted_lib_ico"></span>');tmpl_array.push(' <% } else if(library.get("public") === true) { %>');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Public" style="color:grey;" class="fa fa-globe fa-lg public_lib_ico"></span>');tmpl_array.push(" <% }%>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Upload to library" class="primary-button btn-xs upload_library_btn" type="button" style="<% if(button_config.upload_library_btn === false) { print("display:none;") } %>"><span class="fa fa-upload"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Modify library" class="primary-button btn-xs edit_library_btn" type="button" style="<% if(button_config.edit_library_btn === false) { print("display:none;") } %>"><span class="fa fa-pencil"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Modify permissions" class="primary-button btn-xs permission_library_btn" type="button" style="<% if(button_config.permission_library_btn === false) { print("display:none;") } %>"><span class="fa fa-group"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Save changes" class="primary-button btn-xs save_library_btn" type="button" style="<% if(button_config.save_library_btn === false) { print("display:none;") } %>"><span class="fa fa-floppy-o"> Save</span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Discard changes" class="primary-button btn-xs cancel_library_btn" type="button" style="<% if(button_config.cancel_library_btn === false) { print("display:none;") } %>"><span class="fa fa-times"> Cancel</span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Delete library (can be undeleted later)" class="primary-button btn-xs delete_library_btn" type="button" style="<% if(button_config.delete_library_btn === false) { print("display:none;") } %>"><span class="fa fa-trash-o"> Delete</span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Undelete library" class="primary-button btn-xs undelete_library_btn" type="button" style="<% if(button_config.undelete_library_btn === false) { print("display:none;") } %>"><span class="fa fa-unlock"> Undelete</span></button>');tmpl_array.push(" </td>");tmpl_array.push(" </tr>");return _.template(tmpl_array.join(""))}});return{LibraryRowView:a}});
\ No newline at end of file
diff -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c -r a70f236803f7d398b4f486342e864add77e9ad3f static/scripts/packed/mvc/library/library-librarytoolbar-view.js
--- a/static/scripts/packed/mvc/library/library-librarytoolbar-view.js
+++ b/static/scripts/packed/mvc/library/library-librarytoolbar-view.js
@@ -1,1 +1,1 @@
-define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(a,d,e,c){var b=Backbone.View.extend({el:"#center",events:{"click #create_new_library_btn":"delegate_modal","click #include_deleted_chk":"check_include_deleted"},initialize:function(){this.render()},render:function(){var f=this.templateToolBar();this.$el.html(f({admin_user:Galaxy.currUser.isAdmin(),anon_user:Galaxy.currUser.isAnonymous()}));if(Galaxy.currUser.isAdmin()===true){this.$el.find("#include_deleted_chk")[0].checked=Galaxy.libraries.preferences.get("with_deleted")}},delegate_modal:function(f){Galaxy.libraries.libraryListView.show_library_modal(f)},check_include_deleted:function(f){if(f.target.checked){Galaxy.libraries.preferences.set({with_deleted:true});Galaxy.libraries.libraryListView.render()}else{Galaxy.libraries.preferences.set({with_deleted:false});Galaxy.libraries.libraryListView.render()}},templateToolBar:function(){tmpl_array=[];tmpl_array.push('<div id="libraries_container" style="width: 90%; margin: auto; margin-top:2em; overflow: auto !important; ">');tmpl_array.push(' <div id="toolbar_form" margin-top:0.5em; ">');tmpl_array.push(' <h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');tmpl_array.push(" <% if(admin_user === true) { %>");tmpl_array.push(' <div id="library_toolbar">');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Include deleted libraries"><input id="include_deleted_chk" style="margin: 0;" type="checkbox"><span class="fa fa-trash-o fa-lg"></span></input></span>');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Create New Library"><button id="create_new_library_btn" class="primary-button btn-xs" type="button"><span class="fa fa-plus"></span> New Library</button><span>');tmpl_array.push(" </div>");tmpl_array.push(" <% } %>");tmpl_array.push(" </div>");tmpl_array.push(' <div id="libraries_element">');tmpl_array.push(" </div>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))}});return{ToolbarView:b}});
\ No newline at end of file
+define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(a,c,d,b){var e=Backbone.View.extend({el:"#center",events:{"click #create_new_library_btn":"delegate_modal","click #include_deleted_chk":"check_include_deleted"},initialize:function(){this.render()},render:function(){var h=this.templateToolBar();var g=Galaxy.currUser.isAdmin();var f=Galaxy.currUser.isAnonymous();this.$el.html(h({admin_user:g,anon_user:f}));if(Galaxy.currUser.isAdmin()===true){this.$el.find("#include_deleted_chk")[0].checked=Galaxy.libraries.preferences.get("with_deleted")}},delegate_modal:function(f){Galaxy.libraries.libraryListView.show_library_modal(f)},check_include_deleted:function(f){if(f.target.checked){Galaxy.libraries.preferences.set({with_deleted:true});Galaxy.libraries.libraryListView.render()}else{Galaxy.libraries.preferences.set({with_deleted:false});Galaxy.libraries.libraryListView.render()}},templateToolBar:function(){tmpl_array=[];tmpl_array.push('<div class="library_style_container">');tmpl_array.push(' <div id="toolbar_form" margin-top:0.5em; ">');tmpl_array.push(' <h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');tmpl_array.push(" <% if(admin_user === true) { %>");tmpl_array.push(' <div id="library_toolbar">');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Include deleted libraries"><input id="include_deleted_chk" style="margin: 0;" type="checkbox"><span class="fa fa-trash-o fa-lg"></span></input></span>');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Create New Library"><button id="create_new_library_btn" class="primary-button btn-xs" type="button"><span class="fa fa-plus"></span> New Library</button><span>');tmpl_array.push(" </div>");tmpl_array.push(" <% } %>");tmpl_array.push(" </div>");tmpl_array.push(' <div id="libraries_element">');tmpl_array.push(" </div>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))}});return{LibraryToolbarView:e}});
\ No newline at end of file
diff -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c -r a70f236803f7d398b4f486342e864add77e9ad3f static/scripts/packed/mvc/library/library-model.js
--- a/static/scripts/packed/mvc/library/library-model.js
+++ b/static/scripts/packed/mvc/library/library-model.js
@@ -1,1 +1,1 @@
-define([],function(){var e=Backbone.Model.extend({urlRoot:"/api/libraries/",isVisible:function(k){var j=true;if((!show_delete)&&(this.get("deleted"))){j=false}return j}});var a=Backbone.Model.extend({urlRoot:"/api/folders"});var h=Backbone.Collection.extend({url:"/api/libraries",model:e,sort_key:"name",sort_order:null,initialize:function(j){j=j||{}},getVisible:function(k,l){l=l||[];var j=new h(this.filter(function(m){return m.isVisible(k)}));return j}});var f=Backbone.Model.extend({urlRoot:"/api/libraries/datasets"});var c=Backbone.Collection.extend({model:f});var d=Backbone.Model.extend({defaults:{folder:new c(),full_path:"unknown",urlRoot:"/api/folders/",id:"unknown"},parse:function(j){this.full_path=j[0].full_path;this.get("folder").reset(j[1].folder_contents);return j}});var b=Backbone.Model.extend({urlRoot:"/api/histories/"});var g=Backbone.Model.extend({url:"/api/histories/"});var i=Backbone.Collection.extend({url:"/api/histories",model:g});return{Library:e,FolderAsModel:a,Libraries:h,Item:f,Folder:c,FolderContainer:d,HistoryItem:b,GalaxyHistory:g,GalaxyHistories:i}});
\ No newline at end of file
+define([],function(){var e=Backbone.Model.extend({urlRoot:"/api/libraries/",isVisible:function(k){var j=true;if((!show_delete)&&(this.get("deleted"))){j=false}return j}});var a=Backbone.Model.extend({urlRoot:"/api/folders"});var h=Backbone.Collection.extend({url:"/api/libraries",model:e,sort_key:"name",sort_order:null,initialize:function(j){j=j||{}},getVisible:function(k,l){l=l||[];var j=new h(this.filter(function(m){return m.isVisible(k)}));return j}});var f=Backbone.Model.extend({urlRoot:"/api/libraries/datasets"});var c=Backbone.Collection.extend({model:f});var d=Backbone.Model.extend({defaults:{folder:new c(),urlRoot:"/api/folders/",id:"unknown"},parse:function(j){this.get("folder").reset(j.folder_contents);return j}});var b=Backbone.Model.extend({urlRoot:"/api/histories/"});var g=Backbone.Model.extend({url:"/api/histories/"});var i=Backbone.Collection.extend({url:"/api/histories",model:g});return{Library:e,FolderAsModel:a,Libraries:h,Item:f,Folder:c,FolderContainer:d,HistoryItem:b,GalaxyHistory:g,GalaxyHistories:i}});
\ No newline at end of file
diff -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c -r a70f236803f7d398b4f486342e864add77e9ad3f static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -1299,6 +1299,7 @@
.library_table td{border-top:1px solid #5f6990 !important}
.library_table th{border-bottom:2px solid #5f6990 !important}
.library_table a{color:#0A143D}.library_table a:hover{color:maroon}
+.library_style_container{width:95%;margin:auto;margin-top:2em;overflow:auto !important}
tr.light td{background-color:white;color:black}
tr.light:hover td{background-color:#f5e8cc}
tr.dark td{background-color:#d6b161;color:white}
diff -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c -r a70f236803f7d398b4f486342e864add77e9ad3f static/style/blue/library.css
--- a/static/style/blue/library.css
+++ b/static/style/blue/library.css
@@ -10,6 +10,7 @@
.library_table td{border-top:1px solid #5f6990 !important}
.library_table th{border-bottom:2px solid #5f6990 !important}
.library_table a{color:#0A143D}.library_table a:hover{color:maroon}
+.library_style_container{width:95%;margin:auto;margin-top:2em;overflow:auto !important}
tr.light td{background-color:white;color:black}
tr.light:hover td{background-color:#f5e8cc}
tr.dark td{background-color:#d6b161;color:white}
diff -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c -r a70f236803f7d398b4f486342e864add77e9ad3f static/style/src/less/library.less
--- a/static/style/src/less/library.less
+++ b/static/style/src/less/library.less
@@ -49,6 +49,12 @@
}
}
}
+.library_style_container{
+ width: 95%;
+ margin: auto;
+ margin-top:2em;
+ overflow: auto !important;
+}
tr.light td
{
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
4 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/9d7aa747eb7e/
Changeset: 9d7aa747eb7e
User: jmchilton
Date: 2014-04-10 20:31:46
Summary: Remove unused variable?
Affected #: 1 file
diff -r 2eb03ce13018bbd46ddf55b296246b355afd7ba4 -r 9d7aa747eb7ee1f01db0821e51bc80f0271204a5 static/scripts/galaxy.workflow_editor.canvas.js
--- a/static/scripts/galaxy.workflow_editor.canvas.js
+++ b/static/scripts/galaxy.workflow_editor.canvas.js
@@ -422,7 +422,6 @@
// Update input rows
var old_body = el.find( "div.inputs" );
var new_body = $("<div class='inputs'></div>");
- var old = old_body.find( "div.input-data-row");
$.each( data.data_inputs, function( i, input ) {
var t = node.new_input_terminal( input );
// If already connected save old connection
https://bitbucket.org/galaxy/galaxy-central/commits/b51841ba5ce8/
Changeset: b51841ba5ce8
User: jmchilton
Date: 2014-04-10 20:31:47
Summary: Refactor interaction between workflows JS and editor JS for adding nodes.
Add abstraction into editor for use by galaxy.workflow.js to hide some editor details from workflow code and reduce duplication between add_node_for_tool and add_node_for_module.
Affected #: 2 files
diff -r 9d7aa747eb7ee1f01db0821e51bc80f0271204a5 -r b51841ba5ce81e0adb416c80123ed28184e4c549 static/scripts/galaxy.workflow_editor.canvas.js
--- a/static/scripts/galaxy.workflow_editor.canvas.js
+++ b/static/scripts/galaxy.workflow_editor.canvas.js
@@ -892,6 +892,18 @@
return node;
}
+function add_node( type, title_text, tool_id ) {
+ // Abstraction for use by galaxy.workflow.js to hide
+ // some editor details from workflow code and reduce duplication
+ // between add_node_for_tool and add_node_for_module.
+ var node = prebuild_node( type, title_text, tool_id );
+ workflow.add_node( node );
+ workflow.fit_canvas_to_nodes();
+ canvas_manager.draw_overview();
+ workflow.activate_node( node );
+ return node;
+}
+
var ext_to_type = null;
var type_to_type = null;
diff -r 9d7aa747eb7ee1f01db0821e51bc80f0271204a5 -r b51841ba5ce81e0adb416c80123ed28184e4c549 static/scripts/galaxy.workflows.js
--- a/static/scripts/galaxy.workflows.js
+++ b/static/scripts/galaxy.workflows.js
@@ -320,11 +320,7 @@
// Add a new step to the workflow by tool id
function add_node_for_tool( id, title ) {
- var node = prebuild_node( 'tool', title, id );
- workflow.add_node( node );
- workflow.fit_canvas_to_nodes();
- canvas_manager.draw_overview();
- workflow.activate_node( node );
+ node = add_node( 'tool', title, id );
$.ajax( {
url: get_new_module_info_url,
data: { type: "tool", tool_id: id, "_": "true" },
@@ -344,11 +340,7 @@
}
function add_node_for_module( type, title ) {
- node = prebuild_node( type, title );
- workflow.add_node( node );
- workflow.fit_canvas_to_nodes();
- canvas_manager.draw_overview();
- workflow.activate_node( node );
+ node = add_node( type, title );
$.ajax( {
url: get_new_module_info_url,
data: { type: type, "_": "true" },
https://bitbucket.org/galaxy/galaxy-central/commits/8f577a1a3901/
Changeset: 8f577a1a3901
User: jmchilton
Date: 2014-04-10 20:31:48
Summary: Outline workflow editor tests.
Affected #: 2 files
diff -r b51841ba5ce81e0adb416c80123ed28184e4c549 -r 8f577a1a390145aaab909ccbfbd31a78241f2e45 test/qunit/tests/workflow_editor_tests.html
--- /dev/null
+++ b/test/qunit/tests/workflow_editor_tests.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<!-- Minimal outline test page for a requirejs+qunit testing setup,
+ test environment is bootstrapped in test-common.js -->
+<html>
+ <head>
+ <script data-main="../test-common" src="../scripts/libs/require.js"></script>
+ </head>
+ <body>
+ </body>
+</html>
diff -r b51841ba5ce81e0adb416c80123ed28184e4c549 -r 8f577a1a390145aaab909ccbfbd31a78241f2e45 test/qunit/tests/workflow_editor_tests.js
--- /dev/null
+++ b/test/qunit/tests/workflow_editor_tests.js
@@ -0,0 +1,379 @@
+/* global define, QUnit, module, test, ok, equal, deepEqual, notEqual */
+/* global Workflow, CanvasManager, InputTerminal, Connector, add_node */
+define([
+ "galaxy.workflow_editor.canvas",
+ "jquery",
+ "sinon-qunit"
+], function(
+ workflowEditor,
+ $,
+ sinon
+){
+ "use strict";
+
+ // globals cosumed by workflow editor
+ window.show_form_for_tool = sinon.spy();
+ window.workflow = null;
+ window.canvas_manager = null;
+
+ // Stub used over stubbing issubtype for unit testing datatype comparisons.
+ var issubtypeStub = null;
+
+ QUnit.moduleStart(function() {
+ if( issubtypeStub === null) {
+ issubtypeStub = sinon.stub( window, "issubtype" );
+ }
+ });
+ QUnit.moduleDone(function() {
+ if( issubtypeStub !== null) {
+ issubtypeStub.restore();
+ issubtypeStub = null;
+ }
+ });
+
+ var with_canvas_container = function( f ) {
+ var canvas_container = $("<div id='canvas-container'>");
+ $("body").append( canvas_container );
+ f( canvas_container );
+ canvas_container.remove();
+ };
+
+ var with_workflow_global = function( f ) {
+ var overview = $( "<div id='overview'><canvas id='overview-canvas'></canvas><div id='overview-viewport'></div></div>" );
+ var canvas_viewport = $( "<div id='canvas-viewport'><div id='canvas-container'></div></div>" );
+
+ $("body").append( overview, canvas_viewport );
+ window.canvas_manager = new CanvasManager( canvas_viewport, overview );
+ with_canvas_container( function( canvas_container ) {
+ window.workflow = new Workflow( canvas_container );
+ f( window.workflow );
+ window.workflow = null;
+ } );
+ window.canvas_manager = null;
+ overview.remove();
+ canvas_viewport.remove();
+ };
+
+ module( "Input terminal model test", {
+ setup: function() {
+ this.node = { };
+ this.element = $( "<div>" );
+ this.input_terminal = new InputTerminal( this.element, [ "txt" ] );
+ this.input_terminal.node = this.node;
+ },
+ test_connector: function( attr ) {
+ var connector = attr || {};
+ this.input_terminal.connectors.push( connector );
+ return connector;
+ },
+ with_test_connector: function( attr, f ) {
+ this.test_connector( attr );
+ f();
+ this.reset_connectors();
+ },
+ reset_connectors: function( ) {
+ this.input_terminal.connectors = [];
+ },
+ test_accept: function( other ) {
+ other = other || { node: {}, datatypes: [ "txt" ] };
+ return this.input_terminal.can_accept( other );
+ }
+ } );
+
+ test( "test connect", function() {
+ this.node.changed = sinon.spy();
+
+ var connector = {};
+ this.input_terminal.connect( connector );
+
+ // Assert node changed called
+ ok( this.node.changed.called );
+ // Assert connectors updated
+ ok( this.input_terminal.connectors[ 0 ] === connector );
+ } );
+
+ test( "test disconnect", function() {
+ this.node.changed = sinon.spy();
+
+ var connector = this.test_connector( {} );
+ this.input_terminal.disconnect( connector );
+
+ // Assert node changed called
+ ok( this.node.changed.called );
+ // Assert connectors updated
+ equal( this.input_terminal.connectors.length, 0 );
+ } );
+
+ test( "test redraw", function() {
+ var connector = this.test_connector( { redraw: sinon.spy() } );
+ this.input_terminal.redraw();
+ // Assert connectors were redrawn
+ ok( connector.redraw.called );
+ } );
+
+ test( "test destroy", function() {
+ var connector = this.test_connector( { destroy: sinon.spy() } );
+
+ this.input_terminal.destroy();
+ // Assert connectors were redrawn
+ ok( connector.destroy.called );
+ } );
+
+ test( "can accept correct datatype", function() {
+ issubtypeStub.returns(true);
+ ok( this.test_accept() ) ;
+ } );
+
+ test( "cannot accept incorrect datatypes", function() {
+ issubtypeStub.returns(false);
+ ok( ! this.test_accept() );
+ } );
+
+ test( "can accept inputs", function() {
+ issubtypeStub.returns(false);
+ // Other is data input module - always accept (currently - could be
+ // more intelligent by looking at what else input is connected to.
+ var other = { node: {}, datatypes: [ "input" ] };
+ ok( this.test_accept( other ) );
+ } );
+
+ test( "cannot accept when already connected", function() {
+ issubtypeStub.returns(true);
+ var self = this;
+ // If other is subtype but already connected, cannot accept
+ this.with_test_connector( {}, function() {
+ ok( ! self.test_accept() );
+ } );
+ } );
+
+ module( "Connector test", {
+
+ } );
+
+ test( "connects only if both valid handles", function() {
+ var input = { connect: sinon.spy() };
+ var output = { connect: sinon.spy() };
+ new Connector( input, null );
+ new Connector( null, output );
+ // Not attempts to connect...
+ ok( ! input.connect.called );
+ ok( ! output.connect.called );
+
+ new Connector( input, output );
+ ok( input.connect.called );
+ ok( output.connect.called );
+ });
+
+ test( "default attributes", function() {
+ var input = { connect: sinon.spy() };
+ var output = { connect: sinon.spy() };
+ var connector = new Connector( input, output );
+
+ equal( connector.dragging, false );
+ equal( connector.canvas, null );
+ equal( connector.inner_color, "#FFFFFF" );
+ equal( connector.outer_color, "#D8B365" );
+ } );
+
+ test( "destroy", function() {
+ var input = { connect: sinon.spy(), disconnect: sinon.spy() };
+ var output = { connect: sinon.spy(), disconnect: sinon.spy() };
+ var connector = new Connector( input, output );
+
+ connector.destroy();
+ ok( input.disconnect.called );
+ ok( output.disconnect.called );
+ } );
+
+ test( "initial redraw", function() {
+ with_canvas_container( function( canvas_container ) {
+ var input = { connect: sinon.spy(), element: $("<div>") };
+ var output = { connect: sinon.spy(), element: $("<div>") };
+ var connector = new Connector( input, output );
+
+ connector.redraw();
+ // Ensure canvas gets set
+ ok( connector.canvas );
+ // Ensure it gest added to canvas container
+ equal( canvas_container.children()[ 0 ], connector.canvas );
+ } );
+ } );
+
+ module( "Node unit test", {
+ setup: function() {
+ this.input_terminal = { destroy: sinon.spy(), redraw: sinon.spy() };
+ this.output_terminal = { destroy: sinon.spy(), redraw: sinon.spy() };
+ this.element = $("<div><div class='toolFormBody'></div></div>");
+ this.node = new Node( this.element );
+ this.node.input_terminals.i1 = this.input_terminal;
+ this.node.output_terminals.o1 = this.output_terminal;
+ },
+ $: function( selector ) {
+ return $( this.node.element.find( selector ) );
+ },
+ expect_workflow_node_changed: function( f ) {
+ var node = this.node;
+ with_workflow_global( function( workflow ) {
+ var node_changed_spy = sinon.spy( workflow, "node_changed" );
+ f();
+ ok( node_changed_spy.calledWith( node ) );
+ } );
+ },
+ init_field_data_simple: function() {
+ var data = {
+ data_inputs: [ {name: "input1", extensions: [ "data" ] } ],
+ data_outputs: [ {name: "output1", extensions: [ "data" ] } ],
+ };
+ this.node.init_field_data( data );
+ },
+ update_field_data_with_new_input: function() {
+ var new_data = {
+ data_inputs: [
+ { name: "input1", extensions: [ "data" ] },
+ { name: "extra_0|input1", extensions: [ "data" ] },
+ ],
+ data_outputs: [ {name: "output1", extensions: [ "data" ] } ],
+ post_job_actions: "{}"
+ };
+ this.node.update_field_data( new_data );
+ }
+ } );
+
+ test( "make active", function() {
+ ok( ! this.element.hasClass( "toolForm-active" ) );
+ this.node.make_active();
+ ok( this.element.hasClass( "toolForm-active" ) );
+ } );
+
+ test( "destroy", function() {
+ var test = this;
+ with_workflow_global( function( workflow ) {
+ var remove_node_spy = sinon.spy( workflow, "remove_node" );
+ test.node.destroy();
+ ok( test.input_terminal.destroy.called );
+ ok( test.output_terminal.destroy.called );
+ ok( remove_node_spy.calledWith( test.node ) );
+ } );
+ } );
+
+ test( "error", function() {
+ // Test body of toolFormBody div updated and workflow notified of change.
+ var test = this;
+ this.expect_workflow_node_changed( function() {
+ test.node.error( "TOOL ERROR" );
+ equal( $( test.$(".toolFormBody").children()[ 0 ] ).html(), "TOOL ERROR" );
+ } );
+ } );
+
+ test( "init_field_data properties", function() {
+ var node = this.node;
+ this.expect_workflow_node_changed( function( ) {
+ var data = {
+ data_inputs: [],
+ data_outputs: [],
+ type: "tool",
+ name: "cat1",
+ form_html: "<form>",
+ tool_state: "ok",
+ tool_errors: false,
+ tooltip: "tool tooltip",
+ annotation: "tool annotation",
+ workflow_outputs: [ "out1" ],
+ };
+ node.init_field_data( data );
+ equal( node.type, "tool" );
+ equal( node.name, "cat1" );
+ equal( node.form_html, "<form>" );
+ equal( node.tool_state, "ok" );
+ equal( node.tooltip, "tool tooltip" );
+ equal( node.annotation, "tool annotation" );
+ deepEqual( node.post_job_actions, {} );
+ deepEqual( node.workflow_outputs, [ "out1" ] );
+ } );
+ } );
+
+ test( "init_field_data data", function() {
+ var test = this;
+ this.expect_workflow_node_changed( function( ) {
+ // pre-init not tool form body...
+ equal( test.$( ".output-terminal" ).length, 0 );
+ equal( test.$( ".input-terminal" ).length, 0 );
+ equal( test.$( ".rule" ).length, 0 );
+
+ test.init_field_data_simple();
+
+ // After init tool form should have three "rows"/divs - , inputs div, one output, and rule...
+ equal( test.$( ".output-terminal" ).length, 1 );
+ equal( test.$( ".input-terminal" ).length, 1 );
+ equal( test.$( ".rule" ).length, 1 );
+
+ equal( test.$( ".toolFormBody" ).children().length, 3 );
+ } );
+ } );
+
+ test( "update_field_data updated data inputs and outputs", function() {
+ var test = this;
+ this.expect_workflow_node_changed( function( ) {
+ // Call init with one input and output.
+ test.init_field_data_simple();
+
+ test.update_field_data_with_new_input();
+
+ // Now there are 2 inputs...
+ equal( test.$( ".input-terminal" ).length, 2 );
+ equal( test.$( ".output-terminal" ).length, 1 );
+ equal( test.$( ".rule" ).length, 1 );
+ } );
+ } );
+
+ test( "update_field_data preserves connectors", function() {
+ var test = this;
+ var node = this.node;
+ this.expect_workflow_node_changed( function( ) {
+ // Call init with one input and output.
+ test.init_field_data_simple();
+
+ var connector = new Connector();
+ var old_input_terminal = node.input_terminals.input1;
+ old_input_terminal.connectors.push( connector );
+
+ test.update_field_data_with_new_input();
+
+ var new_input_terminal = node.input_terminals.input1;
+ equal( old_input_terminal, old_input_terminal );
+ notEqual( old_input_terminal, new_input_terminal );
+ equal( connector, new_input_terminal.connectors[ 0 ] );
+ } );
+ } );
+
+ test( "update_field_data destroys old terminals", function() {
+ var test = this;
+ var node = this.node;
+ this.expect_workflow_node_changed( function( ) {
+ var data = {
+ data_inputs: [ { name: "input1", extensions: [ "data" ] },
+ { name: "willDisappear", extensions: [ "data" ] } ],
+ data_outputs: [ {name: "output1", extensions: [ "data" ] } ],
+ };
+ node.init_field_data( data );
+
+ var old_input_terminal = node.input_terminals.willDisappear;
+ var destroy_spy = sinon.spy( old_input_terminal, "destroy" );
+ // Update
+ test.update_field_data_with_new_input();
+
+ ok( destroy_spy.called );
+ } );
+ } );
+
+ module( "add_node" );
+
+ test( "node added to workflow", function() {
+ with_workflow_global( function( workflow ) {
+ var add_node_spy = sinon.spy( workflow, "add_node" );
+ var node = add_node( "tool", "Cat Files", "cat1" );
+ ok( add_node_spy.calledWith( node ) );
+ } );
+ } );
+
+});
\ No newline at end of file
https://bitbucket.org/galaxy/galaxy-central/commits/bacb1a3c0eaa/
Changeset: bacb1a3c0eaa
User: jmchilton
Date: 2014-04-10 20:31:48
Summary: Simplify enable_output_terminal and enable_output_terminal in workflow editor.
These functions were taking in a single element and then looping through it. I hope this is not some intententional jQuery pattern to change the value of 'this' I don't quite understand and is just a remnant of when some loop over inputs was on the inside of this function or some other such refactoring.
Affected #: 1 file
diff -r 8f577a1a390145aaab909ccbfbd31a78241f2e45 -r bacb1a3c0eaa0fd21ddc9f5099cb65bd2c826a9c static/scripts/galaxy.workflow_editor.canvas.js
--- a/static/scripts/galaxy.workflow_editor.canvas.js
+++ b/static/scripts/galaxy.workflow_editor.canvas.js
@@ -172,101 +172,98 @@
}
$.extend( Node.prototype, {
new_input_terminal : function( input ) {
- var t = $("<div class='terminal input-terminal'></div>");
+ var t = $("<div class='terminal input-terminal'></div>")[ 0 ];
this.enable_input_terminal( t, input.name, input.extensions, input.multiple );
return t;
},
- enable_input_terminal : function( elements, name, types, multiple ) {
+ enable_input_terminal : function( element, name, types, multiple ) {
var node = this;
- $(elements).each( function() {
- var terminal = this.terminal = new InputTerminal( this, types, multiple );
- terminal.node = node;
- terminal.name = name;
- $(this).bind( "dropinit", function( e, d ) {
- // Accept a dragable if it is an output terminal and has a
- // compatible type
- return $(d.drag).hasClass( "output-terminal" ) && terminal.can_accept( d.drag.terminal );
- }).bind( "dropstart", function( e, d ) {
- if (d.proxy.terminal) {
- d.proxy.terminal.connectors[0].inner_color = "#BBFFBB";
- }
- }).bind( "dropend", function ( e, d ) {
- if (d.proxy.terminal) {
- d.proxy.terminal.connectors[0].inner_color = "#FFFFFF";
- }
- }).bind( "drop", function( e, d ) {
- ( new Connector( d.drag.terminal, terminal ) ).redraw();
- }).bind( "hover", function() {
- // If connected, create a popup to allow disconnection
- if ( terminal.connectors.length > 0 ) {
- // Create callout
- var t = $("<div class='callout'></div>")
- .css( { display: 'none' } )
- .appendTo( "body" )
- .append(
- $("<div class='button'></div>").append(
- $("<div/>").addClass("fa-icon-button fa fa-times").click( function() {
- $.each( terminal.connectors, function( _, x ) {
- if (x) {
- x.destroy();
- }
- });
- t.remove();
- })))
- .bind( "mouseleave", function() {
- $(this).remove();
- });
- // Position it and show
- t.css({
- top: $(this).offset().top - 2,
- left: $(this).offset().left - t.width(),
- 'padding-right': $(this).width()
- }).show();
- }
- });
- node.input_terminals[name] = terminal;
+
+ var terminal = element.terminal = new InputTerminal( element, types, multiple );
+ terminal.node = node;
+ terminal.name = name;
+ $(element).bind( "dropinit", function( e, d ) {
+ // Accept a dragable if it is an output terminal and has a
+ // compatible type
+ return $(d.drag).hasClass( "output-terminal" ) && terminal.can_accept( d.drag.terminal );
+ }).bind( "dropstart", function( e, d ) {
+ if (d.proxy.terminal) {
+ d.proxy.terminal.connectors[0].inner_color = "#BBFFBB";
+ }
+ }).bind( "dropend", function ( e, d ) {
+ if (d.proxy.terminal) {
+ d.proxy.terminal.connectors[0].inner_color = "#FFFFFF";
+ }
+ }).bind( "drop", function( e, d ) {
+ ( new Connector( d.drag.terminal, terminal ) ).redraw();
+ }).bind( "hover", function() {
+ // If connected, create a popup to allow disconnection
+ if ( terminal.connectors.length > 0 ) {
+ // Create callout
+ var t = $("<div class='callout'></div>")
+ .css( { display: 'none' } )
+ .appendTo( "body" )
+ .append(
+ $("<div class='button'></div>").append(
+ $("<div/>").addClass("fa-icon-button fa fa-times").click( function() {
+ $.each( terminal.connectors, function( _, x ) {
+ if (x) {
+ x.destroy();
+ }
+ });
+ t.remove();
+ })))
+ .bind( "mouseleave", function() {
+ $(this).remove();
+ });
+ // Position it and show
+ t.css({
+ top: $(element).offset().top - 2,
+ left: $(element).offset().left - t.width(),
+ 'padding-right': $(element).width()
+ }).show();
+ }
});
+ node.input_terminals[name] = terminal;
},
- enable_output_terminal : function( elements, name, type ) {
+ enable_output_terminal : function( element, name, type ) {
var node = this;
- $(elements).each( function() {
- var terminal_element = this;
- var terminal = this.terminal = new OutputTerminal( this, type );
- terminal.node = node;
- terminal.name = name;
- $(this).bind( "dragstart", function( e, d ) {
- $( d.available ).addClass( "input-terminal-active" );
- // Save PJAs in the case of change datatype actions.
- workflow.check_changes_in_active_form();
- // Drag proxy div
- var h = $( '<div class="drag-terminal" style="position: absolute;"></div>' )
- .appendTo( "#canvas-container" ).get(0);
- // Terminal and connection to display noodle while dragging
- h.terminal = new OutputTerminal( h );
- var c = new Connector();
- c.dragging = true;
- c.connect( this.terminal, h.terminal );
- return h;
- }).bind( "drag", function ( e, d ) {
- var onmove = function() {
- var po = $(d.proxy).offsetParent().offset(),
- x = d.offsetX - po.left,
- y = d.offsetY - po.top;
- $(d.proxy).css( { left: x, top: y } );
- d.proxy.terminal.redraw();
- // FIXME: global
- canvas_manager.update_viewport_overlay();
- };
- onmove();
- $("#canvas-container").get(0).scroll_panel.test( e, onmove );
- }).bind( "dragend", function ( e, d ) {
- d.proxy.terminal.connectors[0].destroy();
- $(d.proxy).remove();
- $( d.available ).removeClass( "input-terminal-active" );
- $("#canvas-container").get(0).scroll_panel.stop();
- });
- node.output_terminals[name] = terminal;
+ var terminal_element = element;
+ var terminal = element.terminal = new OutputTerminal( element, type );
+ terminal.node = node;
+ terminal.name = name;
+ $(element).bind( "dragstart", function( e, d ) {
+ $( d.available ).addClass( "input-terminal-active" );
+ // Save PJAs in the case of change datatype actions.
+ workflow.check_changes_in_active_form();
+ // Drag proxy div
+ var h = $( '<div class="drag-terminal" style="position: absolute;"></div>' )
+ .appendTo( "#canvas-container" ).get(0);
+ // Terminal and connection to display noodle while dragging
+ h.terminal = new OutputTerminal( h );
+ var c = new Connector();
+ c.dragging = true;
+ c.connect( element.terminal, h.terminal );
+ return h;
+ }).bind( "drag", function ( e, d ) {
+ var onmove = function() {
+ var po = $(d.proxy).offsetParent().offset(),
+ x = d.offsetX - po.left,
+ y = d.offsetY - po.top;
+ $(d.proxy).css( { left: x, top: y } );
+ d.proxy.terminal.redraw();
+ // FIXME: global
+ canvas_manager.update_viewport_overlay();
+ };
+ onmove();
+ $("#canvas-container").get(0).scroll_panel.test( e, onmove );
+ }).bind( "dragend", function ( e, d ) {
+ d.proxy.terminal.connectors[0].destroy();
+ $(d.proxy).remove();
+ $( d.available ).removeClass( "input-terminal-active" );
+ $("#canvas-container").get(0).scroll_panel.stop();
});
+ node.output_terminals[name] = terminal;
},
redraw : function () {
$.each( this.input_terminals, function( _, t ) {
@@ -342,7 +339,7 @@
}
$.each( data.data_outputs, function( i, output ) {
var t = $( "<div class='terminal output-terminal'></div>" );
- node.enable_output_terminal( t, output.name, output.extensions );
+ node.enable_output_terminal( t[ 0 ], output.name, output.extensions );
var label = output.name;
if ( output.extensions.indexOf( 'input' ) < 0 ) {
label = label + " (" + output.extensions.join(", ") + ")";
@@ -429,8 +426,8 @@
$(this).find( ".input-terminal" ).each( function() {
var c = this.terminal.connectors[0];
if ( c ) {
- t[0].terminal.connectors[0] = c;
- c.handle2 = t[0].terminal;
+ t.terminal.connectors[0] = c;
+ c.handle2 = t.terminal;
}
});
$(this).remove();
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/5b01864ad790/
Changeset: 5b01864ad790
Branch: next-stable
User: davebgx
Date: 2014-04-10 19:59:40
Summary: Corrected version for migrated tools.
Affected #: 1 file
diff -r 7e9a2ea753bde82120de4543618f196e86bf7b04 -r 5b01864ad7902af1174478a9f440cad26927f178 scripts/migrate_tools/0010_tools.xml
--- a/scripts/migrate_tools/0010_tools.xml
+++ b/scripts/migrate_tools/0010_tools.xml
@@ -3,17 +3,17 @@
<repository owner="devteam" name="analyze_covariates" changeset_revision="738bc749f9a3" description="Analyze Covariates"><tool id="gatk_analyze_covariates" version="0.0.5" file="gatk/analyze_covariates.xml" /></repository>
- <repository owner="devteam" name="basecoverage" changeset_revision="1e6a9e97fa41" description="Base Coverage of all intervals">
- <tool id="gops_basecoverage_1" version="0.0.1" file="new_operations/basecoverage.xml" />
+ <repository owner="devteam" name="basecoverage" changeset_revision="642849141ae9" description="Base Coverage of all intervals">
+ <tool id="gops_basecoverage_1" version="1.0.0" file="new_operations/basecoverage.xml" /></repository>
- <repository owner="devteam" name="best_regression_subsets" changeset_revision="e769cde223a5" description="Perform Best-subsets Regression">
- <tool id="BestSubsetsRegression1" version="0.0.1" file="regVariation/best_regression_subsets.xml" />
+ <repository owner="devteam" name="best_regression_subsets" changeset_revision="4f33ec73e445" description="Perform Best-subsets Regression">
+ <tool id="BestSubsetsRegression1" version="1.0.0" file="regVariation/best_regression_subsets.xml" /></repository>
- <repository owner="devteam" name="cluster" changeset_revision="d5677eecbad4" description="Cluster">
- <tool id="gops_cluster_1" version="0.0.1" file="new_operations/cluster.xml" />
+ <repository owner="devteam" name="cluster" changeset_revision="9fcc3a1c3d26" description="Cluster">
+ <tool id="gops_cluster_1" version="1.0.0" file="new_operations/cluster.xml" /></repository>
- <repository owner="devteam" name="complement" changeset_revision="d958d5a0d1e8" description="Complement intervals of a dataset">
- <tool id="gops_complement_1" version="0.0.1" file="new_operations/complement.xml" />
+ <repository owner="devteam" name="complement" changeset_revision="67c4ed724bfd" description="Complement intervals of a dataset">
+ <tool id="gops_complement_1" version="1.0.0" file="new_operations/complement.xml" /></repository><repository owner="devteam" name="compute_q_values" changeset_revision="63abfc350814" description="Compute q-values based on multiple simultaneous tests p-values"><tool id="compute_q_values" version="1.0.1" file="regVariation/compute_q_values.xml" />
@@ -24,8 +24,8 @@
<repository owner="devteam" name="count_covariates" changeset_revision="14e304b70425" description="Count Covariates on BAM files"><tool id="gatk_count_covariates" version="0.0.5" file="gatk/count_covariates.xml" /></repository>
- <repository owner="devteam" name="coverage" changeset_revision="1e864693a1c0" description="Coverage of a set of intervals on second set of intervals">
- <tool id="gops_coverage_1" version="0.0.1" file="new_operations/coverage.xml" />
+ <repository owner="devteam" name="coverage" changeset_revision="16b62a897aac" description="Coverage of a set of intervals on second set of intervals">
+ <tool id="gops_coverage_1" version="1.0.0" file="new_operations/coverage.xml" /></repository><repository owner="devteam" name="depth_of_coverage" changeset_revision="c3f08370fc82" description="Depth of Coverage on BAM files"><tool id="gatk_depth_of_coverage" version="0.0.2" file="gatk/depth_of_coverage.xml" />
@@ -36,23 +36,23 @@
<repository owner="devteam" name="flanking_features" changeset_revision="90100b587723" description="Fetch closest non-overlapping feature for every interval"><tool id="flanking_features_1" version="4.0.1" file="new_operations/flanking_features.xml" /></repository>
- <repository owner="devteam" name="get_flanks" changeset_revision="a72f0decd7b3" description="Get flanks - returns flanking region/s for every gene">
- <tool id="get_flanks1" version="0.0.1" file="new_operations/get_flanks.xml" />
+ <repository owner="devteam" name="get_flanks" changeset_revision="c3b1781c6fd1" description="Get flanks - returns flanking region/s for every gene">
+ <tool id="get_flanks1" version="1.0.0" file="new_operations/get_flanks.xml" /></repository><repository owner="devteam" name="getindelrates_3way" changeset_revision="d427e5acb9ee" description="Estimate Indel Rates for 3-way alignments"><tool id="indelRates_3way" version="1.0.0" file="regVariation/getIndelRates_3way.xml" /></repository>
- <repository owner="devteam" name="getindels_2way" changeset_revision="91655316fcf0" description="Fetch Indels from pairwise alignments">
- <tool id="getIndels_2way" version="0.0.1" file="regVariation/getIndels_2way.xml" />
+ <repository owner="devteam" name="getindels_2way" changeset_revision="f1dc6f5fce6e" description="Fetch Indels from pairwise alignments">
+ <tool id="getIndels_2way" version="1.0.0" file="regVariation/getIndels_2way.xml" /></repository><repository owner="devteam" name="indel_realigner" changeset_revision="bb0beda6cf83" description="Indel Realigner - perform local realignment"><tool id="gatk_indel_realigner" version="0.0.6" file="gatk/indel_realigner.xml" /></repository>
- <repository owner="devteam" name="intersect" changeset_revision="5b3c6135a982" description="Intersect the intervals of two datasets">
- <tool id="gops_intersect_1" version="0.0.1" file="new_operations/intersect.xml" />
+ <repository owner="devteam" name="intersect" changeset_revision="81ad85f731b9" description="Intersect the intervals of two datasets">
+ <tool id="gops_intersect_1" version="1.0.0" file="new_operations/intersect.xml" /></repository>
- <repository owner="devteam" name="join" changeset_revision="e56b47dce68a" description="Join the intervals of two datasets side-by-side">
- <tool id="gops_join_1" version="0.0.1" file="new_operations/join.xml" />
+ <repository owner="devteam" name="join" changeset_revision="11a49f94d086" description="Join the intervals of two datasets side-by-side">
+ <tool id="gops_join_1" version="1.0.0" file="new_operations/join.xml" /></repository><repository owner="devteam" name="linear_regression" changeset_revision="cf431604ec3e" description="Perform Linear Regression"><tool id="LinearRegression1" version="1.0.1" file="regVariation/linear_regression.xml" />
@@ -63,11 +63,11 @@
<repository owner="devteam" name="maf_cpg_filter" changeset_revision="7f2a12cb047d" description="Mask CpG/non-CpG sites from MAF file"><tool id="cpgFilter" version="1.0.0" file="regVariation/maf_cpg_filter.xml" /></repository>
- <repository owner="devteam" name="merge" changeset_revision="b488a1fa07f6" description="Merge the overlapping intervals of a dataset">
- <tool id="gops_merge_1" version="0.0.1" file="new_operations/merge.xml" />
+ <repository owner="devteam" name="merge" changeset_revision="55e88307811d" description="Merge the overlapping intervals of a dataset">
+ <tool id="gops_merge_1" version="1.0.0" file="new_operations/merge.xml" /></repository>
- <repository owner="devteam" name="microsats_alignment_level" changeset_revision="d4368a5a3fc7" description="Extract Orthologous Microsatellites from pair-wise alignments">
- <tool id="microsats_align1" version="0.0.1" file="regVariation/microsats_alignment_level.xml" />
+ <repository owner="devteam" name="microsats_alignment_level" changeset_revision="7852385470f3" description="Extract Orthologous Microsatellites from pair-wise alignments">
+ <tool id="microsats_align1" version="1.0.0" file="regVariation/microsats_alignment_level.xml" /></repository><repository owner="devteam" name="microsats_mutability" changeset_revision="4aa1ee5d8510" description="Estimate microsatellite mutability by specified attributes"><tool id="microsats_mutability1" version="1.1.0" file="regVariation/microsats_mutability.xml" />
@@ -93,8 +93,8 @@
<repository owner="devteam" name="substitutions" changeset_revision="c54f5d0bbb58" description="Fetch substitutions from pairwise alignments"><tool id="substitutions1" version="1.0.0" file="regVariation/substitutions.xml" /></repository>
- <repository owner="devteam" name="subtract" changeset_revision="5bc2dacbe729" description="Subtract the intervals of two datasets">
- <tool id="gops_subtract_1" version="0.0.1" file="new_operations/subtract.xml" />
+ <repository owner="devteam" name="subtract" changeset_revision="7bf44b9d7a8b" description="Subtract the intervals of two datasets">
+ <tool id="gops_subtract_1" version="1.0.0" file="new_operations/subtract.xml" /></repository><repository owner="devteam" name="subtract_query" changeset_revision="5f6ebef89722" description="Subtract Whole Dataset from another dataset"><tool id="subtract_query1" version="0.1" file="new_operations/subtract_query.xml" />
@@ -135,7 +135,7 @@
<repository owner="devteam" name="weightedaverage" changeset_revision="90611e86a998" description="Assign weighted-average of the values of features overlapping an interval"><tool id="wtavg" version="1.0.0" file="regVariation/WeightedAverage.xml" /></repository>
- <repository owner="devteam" name="windowsplitter" changeset_revision="e5490ea33640" description="Make windows">
- <tool id="winSplitter" version="0.0.1" file="regVariation/windowSplitter.xml" />
+ <repository owner="devteam" name="windowsplitter" changeset_revision="75abda2290cc" description="Make windows">
+ <tool id="winSplitter" version="1.0.0" file="regVariation/windowSplitter.xml" /></repository></toolshed>
\ No newline at end of file
https://bitbucket.org/galaxy/galaxy-central/commits/2eb03ce13018/
Changeset: 2eb03ce13018
User: davebgx
Date: 2014-04-10 20:01:59
Summary: Merge with next-stable.
Affected #: 1 file
diff -r 728373009c29c371ff448383b48543296142d311 -r 2eb03ce13018bbd46ddf55b296246b355afd7ba4 scripts/migrate_tools/0010_tools.xml
--- a/scripts/migrate_tools/0010_tools.xml
+++ b/scripts/migrate_tools/0010_tools.xml
@@ -3,17 +3,17 @@
<repository owner="devteam" name="analyze_covariates" changeset_revision="738bc749f9a3" description="Analyze Covariates"><tool id="gatk_analyze_covariates" version="0.0.5" file="gatk/analyze_covariates.xml" /></repository>
- <repository owner="devteam" name="basecoverage" changeset_revision="1e6a9e97fa41" description="Base Coverage of all intervals">
- <tool id="gops_basecoverage_1" version="0.0.1" file="new_operations/basecoverage.xml" />
+ <repository owner="devteam" name="basecoverage" changeset_revision="642849141ae9" description="Base Coverage of all intervals">
+ <tool id="gops_basecoverage_1" version="1.0.0" file="new_operations/basecoverage.xml" /></repository>
- <repository owner="devteam" name="best_regression_subsets" changeset_revision="e769cde223a5" description="Perform Best-subsets Regression">
- <tool id="BestSubsetsRegression1" version="0.0.1" file="regVariation/best_regression_subsets.xml" />
+ <repository owner="devteam" name="best_regression_subsets" changeset_revision="4f33ec73e445" description="Perform Best-subsets Regression">
+ <tool id="BestSubsetsRegression1" version="1.0.0" file="regVariation/best_regression_subsets.xml" /></repository>
- <repository owner="devteam" name="cluster" changeset_revision="d5677eecbad4" description="Cluster">
- <tool id="gops_cluster_1" version="0.0.1" file="new_operations/cluster.xml" />
+ <repository owner="devteam" name="cluster" changeset_revision="9fcc3a1c3d26" description="Cluster">
+ <tool id="gops_cluster_1" version="1.0.0" file="new_operations/cluster.xml" /></repository>
- <repository owner="devteam" name="complement" changeset_revision="d958d5a0d1e8" description="Complement intervals of a dataset">
- <tool id="gops_complement_1" version="0.0.1" file="new_operations/complement.xml" />
+ <repository owner="devteam" name="complement" changeset_revision="67c4ed724bfd" description="Complement intervals of a dataset">
+ <tool id="gops_complement_1" version="1.0.0" file="new_operations/complement.xml" /></repository><repository owner="devteam" name="compute_q_values" changeset_revision="63abfc350814" description="Compute q-values based on multiple simultaneous tests p-values"><tool id="compute_q_values" version="1.0.1" file="regVariation/compute_q_values.xml" />
@@ -24,8 +24,8 @@
<repository owner="devteam" name="count_covariates" changeset_revision="14e304b70425" description="Count Covariates on BAM files"><tool id="gatk_count_covariates" version="0.0.5" file="gatk/count_covariates.xml" /></repository>
- <repository owner="devteam" name="coverage" changeset_revision="1e864693a1c0" description="Coverage of a set of intervals on second set of intervals">
- <tool id="gops_coverage_1" version="0.0.1" file="new_operations/coverage.xml" />
+ <repository owner="devteam" name="coverage" changeset_revision="16b62a897aac" description="Coverage of a set of intervals on second set of intervals">
+ <tool id="gops_coverage_1" version="1.0.0" file="new_operations/coverage.xml" /></repository><repository owner="devteam" name="depth_of_coverage" changeset_revision="c3f08370fc82" description="Depth of Coverage on BAM files"><tool id="gatk_depth_of_coverage" version="0.0.2" file="gatk/depth_of_coverage.xml" />
@@ -36,23 +36,23 @@
<repository owner="devteam" name="flanking_features" changeset_revision="90100b587723" description="Fetch closest non-overlapping feature for every interval"><tool id="flanking_features_1" version="4.0.1" file="new_operations/flanking_features.xml" /></repository>
- <repository owner="devteam" name="get_flanks" changeset_revision="a72f0decd7b3" description="Get flanks - returns flanking region/s for every gene">
- <tool id="get_flanks1" version="0.0.1" file="new_operations/get_flanks.xml" />
+ <repository owner="devteam" name="get_flanks" changeset_revision="c3b1781c6fd1" description="Get flanks - returns flanking region/s for every gene">
+ <tool id="get_flanks1" version="1.0.0" file="new_operations/get_flanks.xml" /></repository><repository owner="devteam" name="getindelrates_3way" changeset_revision="d427e5acb9ee" description="Estimate Indel Rates for 3-way alignments"><tool id="indelRates_3way" version="1.0.0" file="regVariation/getIndelRates_3way.xml" /></repository>
- <repository owner="devteam" name="getindels_2way" changeset_revision="91655316fcf0" description="Fetch Indels from pairwise alignments">
- <tool id="getIndels_2way" version="0.0.1" file="regVariation/getIndels_2way.xml" />
+ <repository owner="devteam" name="getindels_2way" changeset_revision="f1dc6f5fce6e" description="Fetch Indels from pairwise alignments">
+ <tool id="getIndels_2way" version="1.0.0" file="regVariation/getIndels_2way.xml" /></repository><repository owner="devteam" name="indel_realigner" changeset_revision="bb0beda6cf83" description="Indel Realigner - perform local realignment"><tool id="gatk_indel_realigner" version="0.0.6" file="gatk/indel_realigner.xml" /></repository>
- <repository owner="devteam" name="intersect" changeset_revision="5b3c6135a982" description="Intersect the intervals of two datasets">
- <tool id="gops_intersect_1" version="0.0.1" file="new_operations/intersect.xml" />
+ <repository owner="devteam" name="intersect" changeset_revision="81ad85f731b9" description="Intersect the intervals of two datasets">
+ <tool id="gops_intersect_1" version="1.0.0" file="new_operations/intersect.xml" /></repository>
- <repository owner="devteam" name="join" changeset_revision="e56b47dce68a" description="Join the intervals of two datasets side-by-side">
- <tool id="gops_join_1" version="0.0.1" file="new_operations/join.xml" />
+ <repository owner="devteam" name="join" changeset_revision="11a49f94d086" description="Join the intervals of two datasets side-by-side">
+ <tool id="gops_join_1" version="1.0.0" file="new_operations/join.xml" /></repository><repository owner="devteam" name="linear_regression" changeset_revision="cf431604ec3e" description="Perform Linear Regression"><tool id="LinearRegression1" version="1.0.1" file="regVariation/linear_regression.xml" />
@@ -63,11 +63,11 @@
<repository owner="devteam" name="maf_cpg_filter" changeset_revision="7f2a12cb047d" description="Mask CpG/non-CpG sites from MAF file"><tool id="cpgFilter" version="1.0.0" file="regVariation/maf_cpg_filter.xml" /></repository>
- <repository owner="devteam" name="merge" changeset_revision="b488a1fa07f6" description="Merge the overlapping intervals of a dataset">
- <tool id="gops_merge_1" version="0.0.1" file="new_operations/merge.xml" />
+ <repository owner="devteam" name="merge" changeset_revision="55e88307811d" description="Merge the overlapping intervals of a dataset">
+ <tool id="gops_merge_1" version="1.0.0" file="new_operations/merge.xml" /></repository>
- <repository owner="devteam" name="microsats_alignment_level" changeset_revision="d4368a5a3fc7" description="Extract Orthologous Microsatellites from pair-wise alignments">
- <tool id="microsats_align1" version="0.0.1" file="regVariation/microsats_alignment_level.xml" />
+ <repository owner="devteam" name="microsats_alignment_level" changeset_revision="7852385470f3" description="Extract Orthologous Microsatellites from pair-wise alignments">
+ <tool id="microsats_align1" version="1.0.0" file="regVariation/microsats_alignment_level.xml" /></repository><repository owner="devteam" name="microsats_mutability" changeset_revision="4aa1ee5d8510" description="Estimate microsatellite mutability by specified attributes"><tool id="microsats_mutability1" version="1.1.0" file="regVariation/microsats_mutability.xml" />
@@ -93,8 +93,8 @@
<repository owner="devteam" name="substitutions" changeset_revision="c54f5d0bbb58" description="Fetch substitutions from pairwise alignments"><tool id="substitutions1" version="1.0.0" file="regVariation/substitutions.xml" /></repository>
- <repository owner="devteam" name="subtract" changeset_revision="5bc2dacbe729" description="Subtract the intervals of two datasets">
- <tool id="gops_subtract_1" version="0.0.1" file="new_operations/subtract.xml" />
+ <repository owner="devteam" name="subtract" changeset_revision="7bf44b9d7a8b" description="Subtract the intervals of two datasets">
+ <tool id="gops_subtract_1" version="1.0.0" file="new_operations/subtract.xml" /></repository><repository owner="devteam" name="subtract_query" changeset_revision="5f6ebef89722" description="Subtract Whole Dataset from another dataset"><tool id="subtract_query1" version="0.1" file="new_operations/subtract_query.xml" />
@@ -135,7 +135,7 @@
<repository owner="devteam" name="weightedaverage" changeset_revision="90611e86a998" description="Assign weighted-average of the values of features overlapping an interval"><tool id="wtavg" version="1.0.0" file="regVariation/WeightedAverage.xml" /></repository>
- <repository owner="devteam" name="windowsplitter" changeset_revision="e5490ea33640" description="Make windows">
- <tool id="winSplitter" version="0.0.1" file="regVariation/windowSplitter.xml" />
+ <repository owner="devteam" name="windowsplitter" changeset_revision="75abda2290cc" description="Make windows">
+ <tool id="winSplitter" version="1.0.0" file="regVariation/windowSplitter.xml" /></repository></toolshed>
\ 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
commit/galaxy-central: dan: Change suc.get_url_from_tool_shed to common_util.get_tool_shed_url_from_tool_shed_registry.
by commits-noreply@bitbucket.org 10 Apr '14
by commits-noreply@bitbucket.org 10 Apr '14
10 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/728373009c29/
Changeset: 728373009c29
User: dan
Date: 2014-04-10 19:49:43
Summary: Change suc.get_url_from_tool_shed to common_util.get_tool_shed_url_from_tool_shed_registry.
Affected #: 1 file
diff -r 44ad9370003cfa3217f15d1ee8a2d6a114cb50bb -r 728373009c29c371ff448383b48543296142d311 lib/galaxy/model/tool_shed_install/__init__.py
--- a/lib/galaxy/model/tool_shed_install/__init__.py
+++ b/lib/galaxy/model/tool_shed_install/__init__.py
@@ -4,7 +4,6 @@
from galaxy.util.bunch import Bunch
from galaxy.util import asbool
from tool_shed.util import common_util
-from tool_shed.util.shed_util_common import get_url_from_tool_shed
from urlparse import urljoin
log = logging.getLogger( __name__ )
@@ -76,7 +75,7 @@
return self.deleted
def get_sharable_url( self, app ):
- tool_shed_url = get_url_from_tool_shed( app, self.tool_shed )
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( app, self.tool_shed )
if tool_shed_url:
return urljoin( tool_shed_url, 'view/%s/%s' % ( self.owner, self.name ) )
return tool_shed_url
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
3 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/375e0c252f6c/
Changeset: 375e0c252f6c
Branch: next-stable
User: dan
Date: 2014-04-10 19:38:44
Summary: Include tool version information in bug reports.
Affected #: 1 file
diff -r 376ffdb91bd1c1a7881e72c5cb6da8dea0e0534f -r 375e0c252f6c3448e1d7c743f1ffe408be9752ec lib/galaxy/tools/errors.py
--- a/lib/galaxy/tools/errors.py
+++ b/lib/galaxy/tools/errors.py
@@ -28,7 +28,9 @@
-----------------------------------------------------------------------------
job id: ${job_id}
tool id: ${job_tool_id}
+tool version: ${tool_version}
job pid or drm id: ${job_runner_external_id}
+job tool version: ${job_tool_version}
-----------------------------------------------------------------------------
job command line:
${job_command_line}
@@ -86,7 +88,9 @@
history_item_name=hda.get_display_name(),
history_view_link=history_view_link,
job_id=job.id,
+ tool_version=job.tool_version,
job_tool_id=job.tool_id,
+ job_tool_version=hda.tool_version,
job_runner_external_id=job.job_runner_external_id,
job_command_line=job.command_line,
job_stderr=util.unicodify( job.stderr ),
https://bitbucket.org/galaxy/galaxy-central/commits/7e9a2ea753bd/
Changeset: 7e9a2ea753bd
Branch: next-stable
User: dan
Date: 2014-04-10 19:39:41
Summary: When posting to BioStar include a ToolShed url, as applicable.
Affected #: 2 files
diff -r 375e0c252f6c3448e1d7c743f1ffe408be9752ec -r 7e9a2ea753bde82120de4543618f196e86bf7b04 lib/galaxy/model/tool_shed_install/__init__.py
--- a/lib/galaxy/model/tool_shed_install/__init__.py
+++ b/lib/galaxy/model/tool_shed_install/__init__.py
@@ -4,6 +4,8 @@
from galaxy.util.bunch import Bunch
from galaxy.util import asbool
from tool_shed.util import common_util
+from tool_shed.util.shed_util_common import get_url_from_tool_shed
+from urlparse import urljoin
log = logging.getLogger( __name__ )
@@ -73,6 +75,12 @@
def can_reinstall_or_activate( self ):
return self.deleted
+ def get_sharable_url( self, app ):
+ tool_shed_url = get_url_from_tool_shed( app, self.tool_shed )
+ if tool_shed_url:
+ return urljoin( tool_shed_url, 'view/%s/%s' % ( self.owner, self.name ) )
+ return tool_shed_url
+
def get_shed_config_filename( self ):
shed_config_filename = None
if self.metadata:
diff -r 375e0c252f6c3448e1d7c743f1ffe408be9752ec -r 7e9a2ea753bde82120de4543618f196e86bf7b04 lib/galaxy/util/biostar.py
--- a/lib/galaxy/util/biostar.py
+++ b/lib/galaxy/util/biostar.py
@@ -86,7 +86,14 @@
def populate_tool_payload( payload=None, tool=None ):
payload = populate_tag_payload( payload=payload, tool=tool )
payload[ 'title' ] = 'Need help with "%s" tool' % ( tool.name )
- payload[ 'content' ] = '<br /><hr /><p>Tool name: %s</br>Tool version: %s</br>Tool ID: %s</p>' % ( tool.name, tool.version, tool.id )
+ tool_url = None
+ if tool.tool_shed_repository:
+ tool_url = tool.tool_shed_repository.get_sharable_url( tool.app )
+ if tool_url:
+ tool_url = '</br>ToolShed URL: <a href="%s">%s</a>' % ( tool_url, tool_url )
+ if not tool_url:
+ tool_url = ''
+ payload[ 'content' ] = '<br /><hr /><p>Tool name: %s</br>Tool version: %s</br>Tool ID: %s%s</p></br>' % ( tool.name, tool.version, tool.id, tool_url )
return payload
def determine_cookie_domain( galaxy_hostname, biostar_hostname ):
https://bitbucket.org/galaxy/galaxy-central/commits/44ad9370003c/
Changeset: 44ad9370003c
User: dan
Date: 2014-04-10 19:40:00
Summary: merge next-stable
Affected #: 3 files
diff -r 165927888055c164e493a948e05d10c00d018458 -r 44ad9370003cfa3217f15d1ee8a2d6a114cb50bb lib/galaxy/model/tool_shed_install/__init__.py
--- a/lib/galaxy/model/tool_shed_install/__init__.py
+++ b/lib/galaxy/model/tool_shed_install/__init__.py
@@ -4,6 +4,8 @@
from galaxy.util.bunch import Bunch
from galaxy.util import asbool
from tool_shed.util import common_util
+from tool_shed.util.shed_util_common import get_url_from_tool_shed
+from urlparse import urljoin
log = logging.getLogger( __name__ )
@@ -73,6 +75,12 @@
def can_reinstall_or_activate( self ):
return self.deleted
+ def get_sharable_url( self, app ):
+ tool_shed_url = get_url_from_tool_shed( app, self.tool_shed )
+ if tool_shed_url:
+ return urljoin( tool_shed_url, 'view/%s/%s' % ( self.owner, self.name ) )
+ return tool_shed_url
+
def get_shed_config_filename( self ):
shed_config_filename = None
if self.metadata:
diff -r 165927888055c164e493a948e05d10c00d018458 -r 44ad9370003cfa3217f15d1ee8a2d6a114cb50bb lib/galaxy/tools/errors.py
--- a/lib/galaxy/tools/errors.py
+++ b/lib/galaxy/tools/errors.py
@@ -28,7 +28,9 @@
-----------------------------------------------------------------------------
job id: ${job_id}
tool id: ${job_tool_id}
+tool version: ${tool_version}
job pid or drm id: ${job_runner_external_id}
+job tool version: ${job_tool_version}
-----------------------------------------------------------------------------
job command line:
${job_command_line}
@@ -86,7 +88,9 @@
history_item_name=hda.get_display_name(),
history_view_link=history_view_link,
job_id=job.id,
+ tool_version=job.tool_version,
job_tool_id=job.tool_id,
+ job_tool_version=hda.tool_version,
job_runner_external_id=job.job_runner_external_id,
job_command_line=job.command_line,
job_stderr=util.unicodify( job.stderr ),
diff -r 165927888055c164e493a948e05d10c00d018458 -r 44ad9370003cfa3217f15d1ee8a2d6a114cb50bb lib/galaxy/util/biostar.py
--- a/lib/galaxy/util/biostar.py
+++ b/lib/galaxy/util/biostar.py
@@ -86,7 +86,14 @@
def populate_tool_payload( payload=None, tool=None ):
payload = populate_tag_payload( payload=payload, tool=tool )
payload[ 'title' ] = 'Need help with "%s" tool' % ( tool.name )
- payload[ 'content' ] = '<br /><hr /><p>Tool name: %s</br>Tool version: %s</br>Tool ID: %s</p>' % ( tool.name, tool.version, tool.id )
+ tool_url = None
+ if tool.tool_shed_repository:
+ tool_url = tool.tool_shed_repository.get_sharable_url( tool.app )
+ if tool_url:
+ tool_url = '</br>ToolShed URL: <a href="%s">%s</a>' % ( tool_url, tool_url )
+ if not tool_url:
+ tool_url = ''
+ payload[ 'content' ] = '<br /><hr /><p>Tool name: %s</br>Tool version: %s</br>Tool ID: %s%s</p></br>' % ( tool.name, tool.version, tool.id, tool_url )
return payload
def determine_cookie_domain( galaxy_hostname, biostar_hostname ):
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: Display repository dependency definition attributes for repositories being installed into Galaxy where the dependency hierarchy cannot be determined likely due to invalid dependency definitions.
by commits-noreply@bitbucket.org 10 Apr '14
by commits-noreply@bitbucket.org 10 Apr '14
10 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/165927888055/
Changeset: 165927888055
User: greg
Date: 2014-04-10 17:35:37
Summary: Display repository dependency definition attributes for repositories being installed into Galaxy where the dependency hierarchy cannot be determined likely due to invalid dependency definitions.
Affected #: 5 files
diff -r b3b39af86c36a4f141bbe64dfec4ad59f3facbe7 -r 165927888055c164e493a948e05d10c00d018458 lib/galaxy/webapps/tool_shed/api/repositories.py
--- a/lib/galaxy/webapps/tool_shed/api/repositories.py
+++ b/lib/galaxy/webapps/tool_shed/api/repositories.py
@@ -276,7 +276,7 @@
@web.expose_api
def repository_ids_for_setting_metadata( self, trans, my_writable=False, **kwd ):
"""
- GET /api/get_repository_ids_for_setting_metadata
+ GET /api/repository_ids_for_setting_metadata
Displays a collection (list) of repository ids ordered for setting metadata.
diff -r b3b39af86c36a4f141bbe64dfec4ad59f3facbe7 -r 165927888055c164e493a948e05d10c00d018458 lib/galaxy/webapps/tool_shed/api/repository_revisions.py
--- a/lib/galaxy/webapps/tool_shed/api/repository_revisions.py
+++ b/lib/galaxy/webapps/tool_shed/api/repository_revisions.py
@@ -26,7 +26,7 @@
Creates and saves a gzip compressed tar archive of a repository and optionally all of it's repository dependencies.
The following parameters are included in the payload.
- :param tool_shed_url (required): the base URL of the Tool Shed from which the Repository was installed
+ :param tool_shed_url (required): the base URL of the Tool Shed from which the Repository is to be exported
:param name (required): the name of the Repository
:param owner (required): the owner of the Repository
:param changeset_revision (required): the changeset_revision of the RepositoryMetadata object associated with the Repository
diff -r b3b39af86c36a4f141bbe64dfec4ad59f3facbe7 -r 165927888055c164e493a948e05d10c00d018458 lib/galaxy/webapps/tool_shed/controllers/repository.py
--- a/lib/galaxy/webapps/tool_shed/controllers/repository.py
+++ b/lib/galaxy/webapps/tool_shed/controllers/repository.py
@@ -2570,11 +2570,8 @@
invalid = True
break
if invalid:
- message += 'The repository dependency definitions for this repository are invalid and will be ignored. '
- message += 'The complete dependency hierarchy could not be determined. The cause of repository dependency '
- message += 'definition errors like this can usually be seen when viewing the repository directly from the '
- message += 'Tool Shed. The exact cause cannot be determined when visiting the Tool Shed from Galaxy to '
- message += 'install the repository.'
+ message = repository_dependency_util.generate_message_for_invalid_repository_dependencies( metadata,
+ error_from_tuple=False )
status = 'error'
else:
repository_metadata_id = None
diff -r b3b39af86c36a4f141bbe64dfec4ad59f3facbe7 -r 165927888055c164e493a948e05d10c00d018458 lib/galaxy/webapps/tool_shed/controllers/upload.py
--- a/lib/galaxy/webapps/tool_shed/controllers/upload.py
+++ b/lib/galaxy/webapps/tool_shed/controllers/upload.py
@@ -288,7 +288,8 @@
status = 'error'
# Handle messaging for invalid repository dependencies.
invalid_repository_dependencies_message = \
- repository_dependency_util.generate_message_for_invalid_repository_dependencies( metadata_dict )
+ repository_dependency_util.generate_message_for_invalid_repository_dependencies( metadata_dict,
+ error_from_tuple=True )
if invalid_repository_dependencies_message:
message += invalid_repository_dependencies_message
status = 'error'
diff -r b3b39af86c36a4f141bbe64dfec4ad59f3facbe7 -r 165927888055c164e493a948e05d10c00d018458 lib/tool_shed/util/repository_dependency_util.py
--- a/lib/tool_shed/util/repository_dependency_util.py
+++ b/lib/tool_shed/util/repository_dependency_util.py
@@ -225,18 +225,46 @@
build_repository_dependency_relationships( trans, all_repo_info_dicts, all_created_or_updated_tool_shed_repositories )
return created_or_updated_tool_shed_repositories, tool_panel_section_keys, all_repo_info_dicts, filtered_repo_info_dicts
-def generate_message_for_invalid_repository_dependencies( metadata_dict ):
- """Return the error message associated with an invalid repository dependency for display in the caller."""
+def generate_message_for_invalid_repository_dependencies( metadata_dict, error_from_tuple=False ):
+ """Get or generate and return an error message associated with an invalid repository dependency."""
message = ''
if metadata_dict:
- invalid_repository_dependencies_dict = metadata_dict.get( 'invalid_repository_dependencies', None )
- if invalid_repository_dependencies_dict:
- invalid_repository_dependencies = invalid_repository_dependencies_dict.get( 'invalid_repository_dependencies', [] )
- for repository_dependency_tup in invalid_repository_dependencies:
- toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td, error = \
- common_util.parse_repository_dependency_tuple( repository_dependency_tup, contains_error=True )
- if error:
- message = '%s ' % str( error )
+ if error_from_tuple:
+ # Return the error messages associated with a set of one or more invalid repository dependency tuples.
+ invalid_repository_dependencies_dict = metadata_dict.get( 'invalid_repository_dependencies', None )
+ if invalid_repository_dependencies_dict is not None:
+ invalid_repository_dependencies = invalid_repository_dependencies_dict.get( 'invalid_repository_dependencies', [] )
+ for repository_dependency_tup in invalid_repository_dependencies:
+ toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td, error = \
+ common_util.parse_repository_dependency_tuple( repository_dependency_tup, contains_error=True )
+ if error:
+ message += '%s ' % str( error )
+ else:
+ # The complete dependency hierarchy could not be determined for a repository being installed into
+ # Galaxy. This is likely due to invalid repository dependency definitions, so we'll get them from
+ # the metadata and parse them for display in an error message. This will hopefully communicate the
+ # problem to the user in such a way that a resolution can be determined.
+ message += 'The complete dependency hierarchy could not be determined for this repository, so no required '
+ message += 'repositories will not be installed. This is likely due to invalid repository dependency definitions. '
+ repository_dependencies_dict = metadata_dict.get( 'repository_dependencies', None )
+ if repository_dependencies_dict is not None:
+ rd_tups = repository_dependencies_dict.get( 'repository_dependencies', None )
+ if rd_tups is not None:
+ message += 'Here are the attributes of the dependencies defined for this repository to help determine the '
+ message += 'cause of this problem.<br/>'
+ message += '<table cellpadding="2" cellspacing="2">'
+ message += '<tr><th>Tool shed</th><th>Repository name</th><th>Owner</th><th>Changeset revision</th>'
+ message += '<th>Prior install required</th></tr>'
+ for rd_tup in rd_tups:
+ tool_shed, name, owner, changeset_revision, pir, oicct = \
+ common_util.parse_repository_dependency_tuple( rd_tup )
+ if asbool( pir ):
+ pir_str = 'True'
+ else:
+ pir_str = ''
+ message += '<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>' % \
+ ( tool_shed, name, owner, changeset_revision, pir_str )
+ message += '</table>'
return message
def get_key_for_repository_changeset_revision( trans, toolshed_base_url, repository, repository_metadata, all_repository_dependencies ):
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: guerler: Charts: Add label selection columns
by commits-noreply@bitbucket.org 10 Apr '14
by commits-noreply@bitbucket.org 10 Apr '14
10 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b3b39af86c36/
Changeset: b3b39af86c36
User: guerler
Date: 2014-04-10 16:00:54
Summary: Charts: Add label selection columns
Affected #: 6 files
diff -r a146d1007651d7f08240d39f0ac18a2491207bc7 -r b3b39af86c36a4f141bbe64dfec4ad59f3facbe7 config/plugins/visualizations/charts/static/app.js
--- a/config/plugins/visualizations/charts/static/app.js
+++ b/config/plugins/visualizations/charts/static/app.js
@@ -51,7 +51,6 @@
// append views
this.$el.append(this.viewer_view.$el);
this.$el.append(this.editor_view.$el);
- this.$el.css('height', 'inherit');
// pick start screen
if (!this.storage.load()) {
diff -r a146d1007651d7f08240d39f0ac18a2491207bc7 -r b3b39af86c36a4f141bbe64dfec4ad59f3facbe7 config/plugins/visualizations/charts/static/charts/nvd3/config.js
--- a/config/plugins/visualizations/charts/static/charts/nvd3/config.js
+++ b/config/plugins/visualizations/charts/static/charts/nvd3/config.js
@@ -1,15 +1,15 @@
define([], function() {
return {
- title : '',
- library : 'nvd3.js',
- element : 'svg',
+ title : '',
+ library : 'nvd3.js',
+ element : 'svg',
columns : {
y : {
title : 'Values for y-axis'
}
},
- settings : {
+ settings : {
separator_label : {
title : 'X axis',
type : 'separator'
diff -r a146d1007651d7f08240d39f0ac18a2491207bc7 -r b3b39af86c36a4f141bbe64dfec4ad59f3facbe7 config/plugins/visualizations/charts/static/charts/nvd3_piechart/config.js
--- a/config/plugins/visualizations/charts/static/charts/nvd3_piechart/config.js
+++ b/config/plugins/visualizations/charts/static/charts/nvd3_piechart/config.js
@@ -1,7 +1,18 @@
-define(['plugin/charts/nvd3/config'], function(nvd3_config) {
+define([], function() {
-return $.extend(true, {}, nvd3_config, {
- title : 'Pie chart',
-});
+return {
+ title : 'Pie chart',
+ library : 'nvd3.js',
+ element : 'svg',
+ columns : {
+ label : {
+ title : 'Labels',
+ any_type : true
+ },
+ y : {
+ title : 'Values'
+ }
+ }
+};
});
\ No newline at end of file
diff -r a146d1007651d7f08240d39f0ac18a2491207bc7 -r b3b39af86c36a4f141bbe64dfec4ad59f3facbe7 config/plugins/visualizations/charts/static/charts/nvd3_piechart/nvd3_piechart.js
--- a/config/plugins/visualizations/charts/static/charts/nvd3_piechart/nvd3_piechart.js
+++ b/config/plugins/visualizations/charts/static/charts/nvd3_piechart/nvd3_piechart.js
@@ -27,29 +27,29 @@
for (var key in group.values) {
var value = group.values[key];
pie_data.push ({
- key : value.x,
- y : value.y
+ y : value.y,
+ x : value.label
});
}
+ }
+
+ // add graph to screen
+ nv.addGraph(function() {
+ self.chart_3d = nv.models.pieChart()
+ .donut(true)
+ .showLegend(false);
- // add graph to screen
- nv.addGraph(function() {
- self.chart_3d = nv.models.pieChart()
- .donut(true)
- .showLegend(false);
-
- self.options.canvas.datum(pie_data)
- .call(self.chart_3d);
+ self.options.canvas.datum(pie_data)
+ .call(self.chart_3d);
- nv.utils.windowResize(self.chart_3d.update);
-
- // set chart state
- chart.state('ok', 'Pie chart drawn.');
-
- // unregister process
- chart.deferred.done(process_id);
- });
- }
+ nv.utils.windowResize(self.chart_3d.update);
+
+ // set chart state
+ chart.state('ok', 'Chart has been drawn.');
+
+ // unregister process
+ chart.deferred.done(process_id);
+ });
});
}
});
diff -r a146d1007651d7f08240d39f0ac18a2491207bc7 -r b3b39af86c36a4f141bbe64dfec4ad59f3facbe7 config/plugins/visualizations/charts/static/library/deferred.js
--- a/config/plugins/visualizations/charts/static/library/deferred.js
+++ b/config/plugins/visualizations/charts/static/library/deferred.js
@@ -59,17 +59,19 @@
// unregister process
done: function(id) {
- // delete tag
- delete this.process[id];
-
- // decrease process counter
- this.counter--;
-
- // log
- console.debug('Deferred:done() - Unregistering ' + id);
-
- // trigger change
- this.trigger('refresh');
+ if (this.process[id]) {
+ // delete tag
+ delete this.process[id];
+
+ // decrease process counter
+ this.counter--;
+
+ // log
+ console.debug('Deferred:done() - Unregistering ' + id);
+
+ // trigger change
+ this.trigger('refresh');
+ }
},
// ready
diff -r a146d1007651d7f08240d39f0ac18a2491207bc7 -r b3b39af86c36a4f141bbe64dfec4ad59f3facbe7 config/plugins/visualizations/charts/static/views/group.js
--- a/config/plugins/visualizations/charts/static/views/group.js
+++ b/config/plugins/visualizations/charts/static/views/group.js
@@ -5,9 +5,6 @@
// widget
return Backbone.View.extend(
{
- // columns
- columns: [],
-
// initialize
initialize: function(app, options) {
// link app
@@ -121,24 +118,29 @@
// get dataset
this.app.datasets.request({id : dataset_id}, function(dataset) {
- // configure columns
- self.columns = [];
- var meta = dataset.metadata_column_types;
- for (var key in meta) {
- // check type
- if(meta[key] == 'int' || meta[key] == 'float') {
- // add to selection
- self.columns.push({
- 'label' : 'Column: ' + (parseInt(key) + 1) + ' [' + meta[key] + ']',
- 'value' : key
- });
+ // update select fields
+ for (var id in list) {
+
+ // is a numeric number required
+ var any_type = chart_settings.columns[id].any_type;
+
+ // configure columns
+ var columns = [];
+ var meta = dataset.metadata_column_types;
+ for (var key in meta) {
+ // check type
+ if (meta[key] == 'int' || meta[key] == 'float' || any_type) {
+ // add to selection
+ columns.push({
+ 'label' : 'Column: ' + (parseInt(key) + 1) + ' [' + meta[key] + ']',
+ 'value' : key
+ });
+ }
}
- }
- // update select fields
- for (var key in list) {
- list[key].update(self.columns);
- list[key].show();
+ // list
+ list[id].update(columns);
+ list[id].show();
}
// loading
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: jmchilton: Close branch trevorw/job_directory-jobs_directory-1397077266550
by commits-noreply@bitbucket.org 10 Apr '14
by commits-noreply@bitbucket.org 10 Apr '14
10 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/11624c8dfc6c/
Changeset: 11624c8dfc6c
Branch: trevorw/job_directory-jobs_directory-1397077266550
User: jmchilton
Date: 2014-04-10 15:51:47
Summary: Close branch trevorw/job_directory-jobs_directory-1397077266550
Affected #: 0 files
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
10 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/a146d1007651/
Changeset: a146d1007651
User: jmchilton
Date: 2014-04-10 15:51:47
Summary: Thanks Trevor!
Merged in trevorw/galaxy-central-5/trevorw/job_directory-jobs_directory-1397077266550 (pull request #360)
job_directory -> jobs_directory
Affected #: 1 file
diff -r febeffc4787e625f3687c7d24298d5b2d3fa6241 -r a146d1007651d7f08240d39f0ac18a2491207bc7 job_conf.xml.sample_advanced
--- a/job_conf.xml.sample_advanced
+++ b/job_conf.xml.sample_advanced
@@ -110,7 +110,7 @@
<!-- Traditionally, the LWR client sends request to LWR
server to populate various system properties. This
extra step can be disabled and these calculated here
- on client by uncommenting job_directory and
+ on client by uncommenting jobs_directory and
specifying any additional remote_property_ of
interest. When using message queues this is nessecary
not optional.
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/7f1aa2813345/
Changeset: 7f1aa2813345
Branch: trevorw/job_directory-jobs_directory-1397077266550
User: trevorw
Date: 2014-04-09 23:02:33
Summary: job_directory -> jobs_directory
Affected #: 1 file
diff -r 63a81f21363325ebbefc321350315804b15bc79e -r 7f1aa2813345f8671948bbce0a14ca1638e57d9b job_conf.xml.sample_advanced
--- a/job_conf.xml.sample_advanced
+++ b/job_conf.xml.sample_advanced
@@ -110,7 +110,7 @@
<!-- Traditionally, the LWR client sends request to LWR
server to populate various system properties. This
extra step can be disabled and these calculated here
- on client by uncommenting job_directory and
+ on client by uncommenting jobs_directory and
specifying any additional remote_property_ of
interest. When using message queues this is nessecary
not optional.
https://bitbucket.org/galaxy/galaxy-central/commits/a146d1007651/
Changeset: a146d1007651
User: jmchilton
Date: 2014-04-10 15:51:47
Summary: Thanks Trevor!
Merged in trevorw/galaxy-central-5/trevorw/job_directory-jobs_directory-1397077266550 (pull request #360)
job_directory -> jobs_directory
Affected #: 1 file
diff -r febeffc4787e625f3687c7d24298d5b2d3fa6241 -r a146d1007651d7f08240d39f0ac18a2491207bc7 job_conf.xml.sample_advanced
--- a/job_conf.xml.sample_advanced
+++ b/job_conf.xml.sample_advanced
@@ -110,7 +110,7 @@
<!-- Traditionally, the LWR client sends request to LWR
server to populate various system properties. This
extra step can be disabled and these calculated here
- on client by uncommenting job_directory and
+ on client by uncommenting jobs_directory and
specifying any additional remote_property_ of
interest. When using message queues this is nessecary
not optional.
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 in the tool shed install and test framework for a recently relocated function.
by commits-noreply@bitbucket.org 10 Apr '14
by commits-noreply@bitbucket.org 10 Apr '14
10 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/febeffc4787e/
Changeset: febeffc4787e
User: greg
Date: 2014-04-10 13:20:27
Summary: Fix in the tool shed install and test framework for a recently relocated function.
Affected #: 1 file
diff -r b887ef428f8f99685878df3cfe61531e3b4a26a2 -r febeffc4787e625f3687c7d24298d5b2d3fa6241 test/install_and_test_tool_shed_repositories/base/util.py
--- a/test/install_and_test_tool_shed_repositories/base/util.py
+++ b/test/install_and_test_tool_shed_repositories/base/util.py
@@ -40,6 +40,7 @@
import galaxy.webapps.tool_shed.model.mapping
from nose.plugins import Plugin
+from tool_shed.util import common_util
from tool_shed.util import tool_dependency_util
from tool_shed.util.xml_util import parse_xml
@@ -1093,7 +1094,7 @@
params[ 'tool_test_results' ] = tool_test_results_dicts
# Set the time_last_tested entry so that the repository_metadata.time_last_tested will be set in the tool shed.
params[ 'time_last_tested' ] = 'This entry will result in this value being set via the Tool Shed API.'
- url = '%s' % ( suc.url_join( galaxy_tool_shed_url,'api', 'repository_revisions', str( metadata_revision_id ) ) )
+ url = '%s' % ( common_util.url_join( galaxy_tool_shed_url,'api', 'repository_revisions', str( metadata_revision_id ) ) )
print 'url: ', url
print 'params: ', params
try:
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: guerler: Charts: Allow switching chart types without reset, fix resizing
by commits-noreply@bitbucket.org 10 Apr '14
by commits-noreply@bitbucket.org 10 Apr '14
10 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b887ef428f8f/
Changeset: b887ef428f8f
User: guerler
Date: 2014-04-10 02:50:45
Summary: Charts: Allow switching chart types without reset, fix resizing
Affected #: 8 files
diff -r f0651cd048cb4ba8a472361d9e7cc8413d9dcd2b -r b887ef428f8f99685878df3cfe61531e3b4a26a2 config/plugins/visualizations/charts/static/app.js
--- a/config/plugins/visualizations/charts/static/app.js
+++ b/config/plugins/visualizations/charts/static/app.js
@@ -51,7 +51,8 @@
// append views
this.$el.append(this.viewer_view.$el);
this.$el.append(this.editor_view.$el);
-
+ this.$el.css('height', 'inherit');
+
// pick start screen
if (!this.storage.load()) {
// show editor
diff -r f0651cd048cb4ba8a472361d9e7cc8413d9dcd2b -r b887ef428f8f99685878df3cfe61531e3b4a26a2 config/plugins/visualizations/charts/static/build-app.js
--- a/config/plugins/visualizations/charts/static/build-app.js
+++ b/config/plugins/visualizations/charts/static/build-app.js
@@ -3,4 +3,4 @@
// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore may be freely distributed under the MIT license.
-(function(){var e=this,t=e._,n={},r=Array.prototype,i=Object.prototype,s=Function.prototype,o=r.push,u=r.slice,a=r.concat,f=i.toString,l=i.hasOwnProperty,c=r.forEach,h=r.map,p=r.reduce,d=r.reduceRight,v=r.filter,m=r.every,g=r.some,y=r.indexOf,b=r.lastIndexOf,w=Array.isArray,E=Object.keys,S=s.bind,x=function(e){if(e instanceof x)return e;if(!(this instanceof x))return new x(e);this._wrapped=e};typeof exports!="undefined"?(typeof module!="undefined"&&module.exports&&(exports=module.exports=x),exports._=x):e._=x,x.VERSION="1.4.4";var T=x.each=x.forEach=function(e,t,r){if(e==null)return;if(c&&e.forEach===c)e.forEach(t,r);else if(e.length===+e.length){for(var i=0,s=e.length;i<s;i++)if(t.call(r,e[i],i,e)===n)return}else for(var o in e)if(x.has(e,o)&&t.call(r,e[o],o,e)===n)return};x.map=x.collect=function(e,t,n){var r=[];return e==null?r:h&&e.map===h?e.map(t,n):(T(e,function(e,i,s){r.push(t.call(n,e,i,s))}),r)};var N="Reduce of empty array with no initial value";x.reduce=x.foldl=x.inject=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(p&&e.reduce===p)return r&&(t=x.bind(t,r)),i?e.reduce(t,n):e.reduce(t);T(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError(N);return n},x.reduceRight=x.foldr=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(d&&e.reduceRight===d)return r&&(t=x.bind(t,r)),i?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=x.keys(e);s=o.length}T(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError(N);return n},x.find=x.detect=function(e,t,n){var r;return C(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},x.filter=x.select=function(e,t,n){var r=[];return e==null?r:v&&e.filter===v?e.filter(t,n):(T(e,function(e,i,s){t.call(n,e,i,s)&&r.push(e)}),r)},x.reject=function(e,t,n){return x.filter(e,function(e,r,i){return!t.call(n,e,r,i)},n)},x.every=x.all=function(e,t,r){t||(t=x.identity);var i=!0;return e==null?i:m&&e.every===m?e.every(t,r):(T(e,function(e,s,o){if(!(i=i&&t.call(r,e,s,o)))return n}),!!i)};var C=x.some=x.any=function(e,t,r){t||(t=x.identity);var i=!1;return e==null?i:g&&e.some===g?e.some(t,r):(T(e,function(e,s,o){if(i||(i=t.call(r,e,s,o)))return n}),!!i)};x.contains=x.include=function(e,t){return e==null?!1:y&&e.indexOf===y?e.indexOf(t)!=-1:C(e,function(e){return e===t})},x.invoke=function(e,t){var n=u.call(arguments,2),r=x.isFunction(t);return x.map(e,function(e){return(r?t:e[t]).apply(e,n)})},x.pluck=function(e,t){return x.map(e,function(e){return e[t]})},x.where=function(e,t,n){return x.isEmpty(t)?n?void 0:[]:x[n?"find":"filter"](e,function(e){for(var n in t)if(t[n]!==e[n])return!1;return!0})},x.findWhere=function(e,t){return x.where(e,t,!0)},x.max=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);if(!t&&x.isEmpty(e))return-Infinity;var r={computed:-Infinity,value:-Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o>=r.computed&&(r={value:e,computed:o})}),r.value},x.min=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);if(!t&&x.isEmpty(e))return Infinity;var r={computed:Infinity,value:Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o<r.computed&&(r={value:e,computed:o})}),r.value},x.shuffle=function(e){var t,n=0,r=[];return T(e,function(e){t=x.random(n++),r[n-1]=r[t],r[t]=e}),r};var k=function(e){return x.isFunction(e)?e:function(t){return t[e]}};x.sortBy=function(e,t,n){var r=k(t);return x.pluck(x.map(e,function(e,t,i){return{value:e,index:t,criteria:r.call(n,e,t,i)}}).sort(function(e,t){var n=e.criteria,r=t.criteria;if(n!==r){if(n>r||n===void 0)return 1;if(n<r||r===void 0)return-1}return e.index<t.index?-1:1}),"value")};var L=function(e,t,n,r){var i={},s=k(t==null?x.identity:t);return T(e,function(t,o){var u=s.call(n,t,o,e);r(i,u,t)}),i};x.groupBy=function(e,t,n){return L(e,t,n,function(e,t,n){(x.has(e,t)?e[t]:e[t]=[]).push(n)})},x.countBy=function(e,t,n){return L(e,t,n,function(e,t){x.has(e,t)||(e[t]=0),e[t]++})},x.sortedIndex=function(e,t,n,r){n=n==null?x.identity:k(n);var i=n.call(r,t),s=0,o=e.length;while(s<o){var u=s+o>>>1;n.call(r,e[u])<i?s=u+1:o=u}return s},x.toArray=function(e){return e?x.isArray(e)?u.call(e):e.length===+e.length?x.map(e,x.identity):x.values(e):[]},x.size=function(e){return e==null?0:e.length===+e.length?e.length:x.keys(e).length},x.first=x.head=x.take=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,0,t):e[0]},x.initial=function(e,t,n){return u.call(e,0,e.length-(t==null||n?1:t))},x.last=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,Math.max(e.length-t,0)):e[e.length-1]},x.rest=x.tail=x.drop=function(e,t,n){return u.call(e,t==null||n?1:t)},x.compact=function(e){return x.filter(e,x.identity)};var A=function(e,t,n){return T(e,function(e){x.isArray(e)?t?o.apply(n,e):A(e,t,n):n.push(e)}),n};x.flatten=function(e,t){return A(e,t,[])},x.without=function(e){return x.difference(e,u.call(arguments,1))},x.uniq=x.unique=function(e,t,n,r){x.isFunction(t)&&(r=n,n=t,t=!1);var i=n?x.map(e,n,r):e,s=[],o=[];return T(i,function(n,r){if(t?!r||o[o.length-1]!==n:!x.contains(o,n))o.push(n),s.push(e[r])}),s},x.union=function(){return x.uniq(a.apply(r,arguments))},x.intersection=function(e){var t=u.call(arguments,1);return x.filter(x.uniq(e),function(e){return x.every(t,function(t){return x.indexOf(t,e)>=0})})},x.difference=function(e){var t=a.apply(r,u.call(arguments,1));return x.filter(e,function(e){return!x.contains(t,e)})},x.zip=function(){var e=u.call(arguments),t=x.max(x.pluck(e,"length")),n=new Array(t);for(var r=0;r<t;r++)n[r]=x.pluck(e,""+r);return n},x.unzip=function(e){var t=[];return x.each(e,function(e,n){x.each(e,function(e,r){t.length<=r&&(t[r]=[]),t[r][n]=e})}),t},x.object=function(e,t){if(e==null)return{};var n={};for(var r=0,i=e.length;r<i;r++)t?n[e[r]]=t[r]:n[e[r][0]]=e[r][1];return n},x.indexOf=function(e,t,n){if(e==null)return-1;var r=0,i=e.length;if(n){if(typeof n!="number")return r=x.sortedIndex(e,t),e[r]===t?r:-1;r=n<0?Math.max(0,i+n):n}if(y&&e.indexOf===y)return e.indexOf(t,n);for(;r<i;r++)if(e[r]===t)return r;return-1},x.lastIndexOf=function(e,t,n){if(e==null)return-1;var r=n!=null;if(b&&e.lastIndexOf===b)return r?e.lastIndexOf(t,n):e.lastIndexOf(t);var i=r?n:e.length;while(i--)if(e[i]===t)return i;return-1},x.range=function(e,t,n){arguments.length<=1&&(t=e||0,e=0),n=arguments[2]||1;var r=Math.max(Math.ceil((t-e)/n),0),i=0,s=new Array(r);while(i<r)s[i++]=e,e+=n;return s};var O=function(){};x.bind=function(e,t){var n,r;if(e.bind===S&&S)return S.apply(e,u.call(arguments,1));if(!x.isFunction(e))throw new TypeError;return n=u.call(arguments,2),r=function(){if(this instanceof r){O.prototype=e.prototype;var i=new O;O.prototype=null;var s=e.apply(i,n.concat(u.call(arguments)));return Object(s)===s?s:i}return e.apply(t,n.concat(u.call(arguments)))}},x.partial=function(e){var t=u.call(arguments,1);return function(){return e.apply(this,t.concat(u.call(arguments)))}},x.bindAll=function(e){var t=u.call(arguments,1);if(t.length===0)throw new Error("bindAll must be passed function names");return T(t,function(t){e[t]=x.bind(e[t],e)}),e},x.memoize=function(e,t){var n={};return t||(t=x.identity),function(){var r=t.apply(this,arguments);return x.has(n,r)?n[r]:n[r]=e.apply(this,arguments)}},x.delay=function(e,t){var n=u.call(arguments,2);return setTimeout(function(){return e.apply(null,n)},t)},x.defer=function(e){return x.delay.apply(x,[e,1].concat(u.call(arguments,1)))},x.throttle=function(e,t,n){var r,i,s,o,u=0,a=function(){u=new Date,s=null,o=e.apply(r,i)};return function(){var f=new Date;!u&&n===!1&&(u=f);var l=t-(f-u);return r=this,i=arguments,l<=0?(clearTimeout(s),s=null,u=f,o=e.apply(r,i)):s||(s=setTimeout(a,l)),o}},x.debounce=function(e,t,n){var r,i;return function(){var s=this,o=arguments,u=function(){r=null,n||(i=e.apply(s,o))},a=n&&!r;return clearTimeout(r),r=setTimeout(u,t),a&&(i=e.apply(s,o)),i}},x.once=function(e){var t=!1,n;return function(){return t?n:(t=!0,n=e.apply(this,arguments),e=null,n)}},x.wrap=function(e,t){return function(){var n=[e];return o.apply(n,arguments),t.apply(this,n)}},x.compose=function(){var e=arguments;return function(){var t=arguments;for(var n=e.length-1;n>=0;n--)t=[e[n].apply(this,t)];return t[0]}},x.after=function(e,t){return e<=0?t():function(){if(--e<1)return t.apply(this,arguments)}},x.keys=E||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var n in e)x.has(e,n)&&t.push(n);return t},x.values=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push(e[n]);return t},x.pairs=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push([n,e[n]]);return t},x.invert=function(e){var t={};for(var n in e)x.has(e,n)&&(t[e[n]]=n);return t},x.functions=x.methods=function(e){var t=[];for(var n in e)x.isFunction(e[n])&&t.push(n);return t.sort()},x.extend=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]=t[n]}),e},x.pick=function(e){var t={},n=a.apply(r,u.call(arguments,1));return T(n,function(n){n in e&&(t[n]=e[n])}),t},x.omit=function(e){var t={},n=a.apply(r,u.call(arguments,1));for(var i in e)x.contains(n,i)||(t[i]=e[i]);return t},x.defaults=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]===void 0&&(e[n]=t[n])}),e},x.clone=function(e){return x.isObject(e)?x.isArray(e)?e.slice():x.extend({},e):e},x.tap=function(e,t){return t(e),e};var M=function(e,t,n,r){if(e===t)return e!==0||1/e==1/t;if(e==null||t==null)return e===t;e instanceof x&&(e=e._wrapped),t instanceof x&&(t=t._wrapped);var i=f.call(e);if(i!=f.call(t))return!1;switch(i){case"[object String]":return e==String(t);case"[object Number]":return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case"[object Date]":case"[object Boolean]":return+e==+t;case"[object RegExp]":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if(typeof e!="object"||typeof t!="object")return!1;var s=n.length;while(s--)if(n[s]==e)return r[s]==t;n.push(e),r.push(t);var o=0,u=!0;if(i=="[object Array]"){o=e.length,u=o==t.length;if(u)while(o--)if(!(u=M(e[o],t[o],n,r)))break}else{var a=e.constructor,l=t.constructor;if(a!==l&&!(x.isFunction(a)&&a instanceof a&&x.isFunction(l)&&l instanceof l))return!1;for(var c in e)if(x.has(e,c)){o++;if(!(u=x.has(t,c)&&M(e[c],t[c],n,r)))break}if(u){for(c in t)if(x.has(t,c)&&!(o--))break;u=!o}}return n.pop(),r.pop(),u};x.isEqual=function(e,t){return M(e,t,[],[])},x.isEmpty=function(e){if(e==null)return!0;if(x.isArray(e)||x.isString(e))return e.length===0;for(var t in e)if(x.has(e,t))return!1;return!0},x.isElement=function(e){return!!e&&e.nodeType===1},x.isArray=w||function(e){return f.call(e)=="[object Array]"},x.isObject=function(e){return e===Object(e)},T(["Arguments","Function","String","Number","Date","RegExp"],function(e){x["is"+e]=function(t){return f.call(t)=="[object "+e+"]"}}),x.isArguments(arguments)||(x.isArguments=function(e){return!!e&&!!x.has(e,"callee")}),typeof /./!="function"&&(x.isFunction=function(e){return typeof e=="function"}),x.isFinite=function(e){return isFinite(e)&&!isNaN(parseFloat(e))},x.isNaN=function(e){return x.isNumber(e)&&e!=+e},x.isBoolean=function(e){return e===!0||e===!1||f.call(e)=="[object Boolean]"},x.isNull=function(e){return e===null},x.isUndefined=function(e){return e===void 0},x.has=function(e,t){return l.call(e,t)},x.noConflict=function(){return e._=t,this},x.identity=function(e){return e},x.times=function(e,t,n){var r=Array(e);for(var i=0;i<e;i++)r[i]=t.call(n,i);return r},x.random=function(e,t){return t==null&&(t=e,e=0),e+Math.floor(Math.random()*(t-e+1))};var _={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};_.unescape=x.invert(_.escape);var D={escape:new RegExp("["+x.keys(_.escape).join("")+"]","g"),unescape:new RegExp("("+x.keys(_.unescape).join("|")+")","g")};x.each(["escape","unescape"],function(e){x[e]=function(t){return t==null?"":(""+t).replace(D[e],function(t){return _[e][t]})}}),x.result=function(e,t){if(e==null)return void 0;var n=e[t];return x.isFunction(n)?n.call(e):n},x.mixin=function(e){T(x.functions(e),function(t){var n=x[t]=e[t];x.prototype[t]=function(){var e=[this._wrapped];return o.apply(e,arguments),F.call(this,n.apply(x,e))}})};var P=0;x.uniqueId=function(e){var t=++P+"";return e?e+t:t},x.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var H=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},j=/\\|'|\r|\n|\t|\u2028|\u2029/g;x.template=function(e,t,n){var r;n=x.defaults({},n,x.templateSettings);var i=new RegExp([(n.escape||H).source,(n.interpolate||H).source,(n.evaluate||H).source].join("|")+"|$","g"),s=0,o="__p+='";e.replace(i,function(t,n,r,i,u){return o+=e.slice(s,u).replace(j,function(e){return"\\"+B[e]}),n&&(o+="'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'"),r&&(o+="'+\n((__t=("+r+"))==null?'':__t)+\n'"),i&&(o+="';\n"+i+"\n__p+='"),s=u+t.length,t}),o+="';\n",n.variable||(o="with(obj||{}){\n"+o+"}\n"),o="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+o+"return __p;\n";try{r=new Function(n.variable||"obj","_",o)}catch(u){throw u.source=o,u}if(t)return r(t,x);var a=function(e){return r.call(this,e,x)};return a.source="function("+(n.variable||"obj")+"){\n"+o+"}",a},x.chain=function(e){return x(e).chain()};var F=function(e){return this._chain?x(e).chain():e};x.mixin(x),T(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];x.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e=="shift"||e=="splice")&&n.length===0&&delete n[0],F.call(this,n)}}),T(["concat","join","slice"],function(e){var t=r[e];x.prototype[e]=function(){return F.call(this,t.apply(this._wrapped,arguments))}}),x.extend(x.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this),define("libs/underscore",function(e){return function(){var t,n;return t||e._}}(this)),define("utils/utils",["libs/underscore"],function(e){function t(e,t,r){n("GET",e,{},t,r)}function n(e,t,n,r,i){if(e=="GET"||e=="DELETE")t.indexOf("?")==-1?t+="?":t+="&",t+=$.param(n);var s=new XMLHttpRequest;s.open(e,t,!0),s.setRequestHeader("Accept","application/json"),s.setRequestHeader("Cache-Control","no-cache"),s.setRequestHeader("X-Requested-With","XMLHttpRequest"),s.setRequestHeader("Content-Type","application/json"),s.onloadend=function(){var e=s.status;try{response=jQuery.parseJSON(s.responseText)}catch(t){response=s.responseText}e==200?r&&r(response):i&&i(response)},e=="GET"||e=="DELETE"?s.send():s.send(JSON.stringify(n))}function r(e,t){var n=$('<div class="'+e+'"></div>');n.appendTo(":eq(0)");var r=n.css(t);return n.remove(),r}function i(e){$('link[href^="'+e+'"]').length||$('<link href="'+galaxy_config.root+e+'" rel="stylesheet">').appendTo("head")}function s(t,n){return t?e.defaults(t,n):n}function o(e,t){var n="";if(e>=1e11)e/=1e11,n="TB";else if(e>=1e8)e/=1e8,n="GB";else if(e>=1e5)e/=1e5,n="MB";else if(e>=100)e/=100,n="KB";else{if(!(e>0))return"<strong>-</strong>";e*=10,n="b"}var r=Math.round(e)/10;return t?r+" "+n:"<strong>"+r+"</strong> "+n}function u(){return(new Date).getTime().toString(36)}function a(e){var t=$("<p></p>");return t.append(e),t}function f(){var e=new Date,t=(e.getHours()<10?"0":"")+e.getHours(),n=(e.getMinutes()<10?"0":"")+e.getMinutes(),r=e.getDate()+"/"+(e.getMonth()+1)+"/"+e.getFullYear()+", "+t+":"+n;return r}return{cssLoadFile:i,cssGetAttribute:r,get:t,merge:s,bytesToString:o,uuid:u,time:f,wrap:a,request:n}}),define("mvc/ui/ui-modal",["utils/utils"],function(e){var t=Backbone.View.extend({elMain:"body",optionsDefault:{title:"ui-modal",body:"",backdrop:!0,height:null,width:null,closing_events:!1},buttonList:{},initialize:function(e){e&&this._create(e)},show:function(e){this.initialize(e),this.options.height?(this.$body.css("height",this.options.height),this.$body.css("overflow","hidden")):this.$body.css("max-height",$(window).height()/2),this.options.width&&this.$dialog.css("width",this.options.width),this.visible?this.$el.show():this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.visible=!1,this.$el.fadeOut("fast")},enableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!1)},disableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!0)},showButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).show()},hideButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).hide()},getButton:function(e){var t=this.buttonList[e];return this.$buttons.find("#"+t)},scrollTop:function(){return this.$body.scrollTop()},_create:function(e){var t=this;this.options=_.defaults(e,this.optionsDefault),this.options.body=="progress"&&(this.options.body=$('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>')),this.$el&&(this.$el.remove(),$(document).off("keyup.ui-modal")),this.setElement(this._template(this.options.title)),this.$dialog=this.$el.find(".modal-dialog"),this.$body=this.$el.find(".modal-body"),this.$footer=this.$el.find(".modal-footer"),this.$buttons=this.$el.find(".buttons"),this.$backdrop=this.$el.find(".modal-backdrop"),this.$body.html(this.options.body),this.options.backdrop||this.$backdrop.removeClass("in");if(this.options.buttons){this.buttonList={};var n=0;$.each(this.options.buttons,function(e,r){var i="button-"+n++;t.$buttons.append($('<button id="'+i+'"></button>').text(e).click(r)).append(" "),t.buttonList[e]=i})}else this.$footer.hide();$(this.elMain).append($(this.el)),this.options.closing_events&&($(document).on("keyup.ui-modal",function(e){e.keyCode==27&&t.hide()}),this.$el.find(".modal-backdrop").on("click",function(){t.hide()}))},_template:function(e){return'<div class="modal"><div class="modal-backdrop fade in" style="z-index: -1;"></div><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" style="display: none;">×</button><h4 class="title">'+e+"</h4>"+"</div>"+'<div class="modal-body" style="position: static;"></div>'+'<div class="modal-footer">'+'<div class="buttons" style="float: right;"></div>'+"</div>"+"</div"+"</div>"+"</div>"}});return{View:t}}),define("mvc/ui/ui-portlet",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,optionsDefault:{title:"",icon:"",buttons:null,body:null,height:null,operations:null,placement:"bottom",overflow:"auto"},$title:null,$content:null,$buttons:null,$operations:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$content=this.$el.find("#content"),this.$title=this.$el.find("#title-text"),this.options.height&&(this.$el.find("#body").css("height",this.options.height),this.$el.find("#content").css("overflow",this.options.overflow)),this.$buttons=$(this.el).find("#buttons");if(this.options.buttons){var n=this;$.each(this.options.buttons,function(e,t){t.$el.prop("id",e),n.$buttons.append(t.$el)})}else this.$buttons.remove();this.$operations=$(this.el).find("#operations");if(this.options.operations){var n=this;$.each(this.options.operations,function(e,t){t.$el.prop("id",e),n.$operations.append(t.$el)})}this.options.body&&this.append(this.options.body)},append:function(t){this.$content.append(e.wrap(t))},content:function(){return this.$content},show:function(){this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},enableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!1)},disableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!0)},hideOperation:function(e){this.$operations.find("#"+e).hide()},showOperation:function(e){this.$operations.find("#"+e).show()},setOperation:function(e,t){var n=this.$operations.find("#"+e);n.off("click"),n.on("click",t)},title:function(e){var t=this.$title;return e&&t.html(e),t.html()},_template:function(e){var t='<div class="toolForm portlet-view no-highlight">';if(e.title||e.icon)t+='<div id="title" class="toolFormTitle portlet-title"><div id="operations" class="portlet-operations"/><div style="overflow: hidden;">',e.icon&&(t+='<div class="portlet-title-icon fa '+e.icon+'"> </div>'),t+='<div id="title-text" class="portlet-title-text">'+e.title+"</div>",t+="</div></div>";return t+='<div id="body" class="toolFormBody portlet-body">',e.placement=="top"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+='<div id="content" class="portlet-content"/>',e.placement=="bottom"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+="</div></div>",t}});return{View:t}}),define("plugin/library/ui-select",["utils/utils"],function(e){var t=Backbone.View.extend({optionsDefault:{id:"",cls:"",empty:"No data available",visible:!0,wait:!1},selected:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$select=this.$el.find("#select"),this.$icon=this.$el.find("#icon"),this.selected=this.options.value;var n=this;this.options.onchange&&this.$select.on("change",function(){n.value(n.$select.val())}),this._refresh(),this.options.visible||this.hide(),this.options.wait?this.wait():this.show()},value:function(e){var t=this.selected;e!==undefined&&(this.selected=e,this.$select.val(e));var n=this.selected;return n&&n!=t&&this.options.onchange&&this.options.onchange(n),n},text:function(){return this.$select.find("option:selected").text()},show:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-caret-down"),this.$select.show(),this.$el.show()},hide:function(){this.$el.hide()},wait:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-spinner fa-spin"),this.$select.hide()},disabled:function(){return this.$select.is(":disabled")},enable:function(){this.$select.prop("disabled",!1)},disable:function(){this.$select.prop("disabled",!0)},add:function(e){this.$select.append(this._templateOption(e)),this._refresh()},del:function(e){this.$select.find("option[value="+e+"]").remove(),this.$select.trigger("change"),this._refresh()},update:function(e){this.$select.find("option").remove();for(var t in e)this.$select.append(this._templateOption(e[t]));!this.selected&&e.length>0&&this.value(e[0].value),this._refresh()},_refresh:function(){this.$select.find("option[value=null]").remove();var e=this.$select.find("option").length;e==0?(this.$select.append(this._templateOption({value:"null",label:this.options.empty})),this.disable()):(this.enable(),this.selected&&this.$select.val(this.selected))},_exists:function(e){return 0!=this.$select.find("option[value="+e+"]").length},_templateOption:function(e){return'<option value="'+e.value+'">'+e.label+"</option>"},_template:function(e){var t='<div id="'+e.id+'" class="styled-select">'+'<div class="button">'+'<i id="icon"/>'+"</div>"+'<select id="select" class="select '+e.cls+" "+e.id+'">';for(key in e.data){var n=e.data[key],r="";if(n.value==e.value||n.value=="")r="selected";t+='<option value="'+n.value+'" '+r+">"+n.label+"</option>"}return t+="</select></div>",t}});return{View:t}}),define("plugin/library/ui",["utils/utils","plugin/library/ui-select"],function(e,t){var n=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},title:function(e){this.$el.find("b").html(e)},_template:function(e){return"<label><b>"+e.title+"</b></label>"},value:function(){return options.title}}),r=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},title:function(e){this.$el.html(e)},_template:function(e){return'<div class="'+e.cls+'">'+e.title+"</div>"},value:function(){return options.title}}),i=Backbone.View.extend({optionsDefault:{id:null,title:"","float":"right",cls:"btn-default",icon:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t='<button id="'+e.id+'" type="submit" style="margin-right: 5px; float: '+e.float+';" type="button" class="btn '+e.cls+'">';return e.icon&&(t+='<i class="icon fa '+e.icon+'"></i> '),t+=e.title+"</button>",t}}),s=Backbone.View.extend({optionsDefault:{"float":"right",icon:"",tooltip:"",placement:"bottom",title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){return'<div><span class="fa '+e.icon+'" style="font-size: 1.2em;"/> '+e.title+"</div>"}}),o=Backbone.View.extend({optionsDefault:{title:"",id:null,"float":"right",cls:"icon-btn",icon:"",tooltip:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t="";e.title&&(t="width: auto;");var n='<div id="'+e.id+'" style="margin-right: 5px; float: '+e.float+"; "+t+'" class="'+e.cls+'">';return e.title?n+='<div style="margin-right: 5px; margin-left: 5px;"><i class="icon fa '+e.icon+'"/> '+'<span style="position: relative; font-size: 0.8em; font-weight: normal; top: -1px;">'+e.title+"</span>"+"</div>":n+='<i class="icon fa '+e.icon+'"/>',n+="</div>",n}}),u=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick)},_template:function(e){return'<div><a href="javascript:void(0)">'+e.title+"</a></div>"}}),a=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:!1},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement("<div></div>")},update:function(t){this.options=e.merge(t,this.optionsDefault);if(t.message!=""){this.$el.html(this._template(this.options)),this.$el.fadeIn();if(!t.persistent){var n=this;window.setTimeout(function(){n.$el.is(":visible")?n.$el.fadeOut():n.$el.hide()},3e3)}}else this.$el.fadeOut()},_template:function(e){return'<div class="alert alert-'+e.status+'" style="padding: 2px 2px 2px 10px;">'+e.message+"</div>"}}),f=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options));var n=this;this.options.onclick&&this.$el.on("submit",function(e){var t=n.$el.find("#search");n.options.onclick(t.val())})},_template:function(e){return'<div class="search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+e.searchword+'">'+'<button type="submit" class="btn search-btn">'+'<i class="fa fa-search"></i>'+"</button>"+"</form>"+"</div>"}}),l=Backbone.View.extend({optionsDefault:{title:"Unlabeled",body:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.body&&this.$el.find(".body").append(this.options.body)},_template:function(e){return'<div id="title" class="title">'+e.title+":"+"</div>"}}),c=Backbone.View.extend({optionsDefault:{id:"",title:"",target:"",href:"",onunload:null,onclick:null,visible:!0,icon:null,tag:""},$menu:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement($(this._template(this.options)));var n=$(this.el).find(".root"),r=this;n.on("click",function(e){e.preventDefault(),r.options.onclick&&r.options.onclick()}),this.options.visible||this.hide()},show:function(){$(this.el).show()},hide:function(){$(this.el).hide()},addMenu:function(t){var n={title:"",target:"",href:"",onclick:null,divider:!1,icon:null};n=e.merge(t,n),this.$menu||($(this.el).append(this._templateMenu()),this.$menu=$(this.el).find(".menu"));var r=$(this._templateMenuItem(n));r.on("click",function(e){e.preventDefault(),n.onclick&&n.onclick()}),this.$menu.append(r),n.divider&&this.$menu.append($(this._templateDivider()))},_templateMenuItem:function(e){var t='<li><a href="'+e.href+'" target="'+e.target+'">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),t+=" "+e.title+"</a>"+"</li>",t},_templateMenu:function(){return'<ul class="menu dropdown-menu pull-right" role="menu"></ul>'},_templateDivider:function(){return'<li class="divider"></li>'},_template:function(e){var t='<div id="'+e.id+'" class="button-menu btn-group">'+'<button type="button" class="root btn btn-default dropdown-toggle" data-toggle="dropdown">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),"</button></div>",t}}),h=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:!1,visible:!0},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.disabled&&this.$el.prop("disabled",!0),this.options.visible||this.$el.hide();var n=this;this.options.onchange&&this.$el.on("input",function(){n.options.onchange()})},value:function(e){return e!==undefined&&this.$el.val(e),this.$el.val()},_template:function(e){return'<input id="'+e.id+'" type="'+e.type+'" value="'+e.value+'" placeholder="'+e.placeholder+'" class="form-control">'}});return{Label:n,Button:i,Icon:s,ButtonIcon:o,Input:h,Anchor:u,Message:a,Searchbox:f,Title:l,Text:r,Select:t,ButtonMenu:c}}),define("plugin/library/jobs",["utils/utils"],function(e){return Backbone.Model.extend({initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},cleanup:function(t){var n=t.get("dataset_id_job");if(n!=""){var r=this;e.request("PUT",config.root+"api/histories/none/contents/"+n,{deleted:!0},function(){r._refreshHdas()}),t.set("dataset_id_job","")}},submit:function(t,n,r,i,s){var o=this,u=t.id,a=t.get("type"),f=this.app.types.get(a);data={tool_id:"chartskit",inputs:{input:{id:t.get("dataset_id"),src:"hda"},module:f.execute,columns:r,settings:n}},t.state("wait","Sending job request..."),e.request("POST",config.root+"api/tools",data,function(e){if(!e.outputs||e.outputs.length==0)t.state("failed","Job submission failed. No response."),s&&s();else{o._refreshHdas();var n=e.outputs[0];t.state("wait","Job has been queued..."),t.set("dataset_id_job",n.id),this.app.storage.save(),o._loop(n.id,function(e){switch(e.state){case"ok":return t.state("wait","Job completed successfully..."),i(e),!0;case"error":return t.state("failed","Job has failed. Please check the history for details."),s&&s(),!0;case"running":return t.state("wait","Job is running..."),!1}})}},function(e){var n="";e&&e.message&&e.message.data&&e.message.data.input&&(n=e.message.data.input+"."),t.state("failed","This visualization requires the Charts-Kit. Please make sure it is installed. "+n),s&&s()})},_loop:function(t,n){var r=this;e.request("GET",config.root+"api/datasets/"+t,{},function(e){n(e)||setTimeout(function(){r._loop(t,n)},r.app.config.get("query_timeout"))})},_refreshHdas:function(){Galaxy&&Galaxy.currHistoryPanel&&Galaxy.currHistoryPanel.refreshHdas()}})}),define("plugin/library/datasets",["utils/utils"],function(e){return Backbone.Collection.extend({list:{},initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},request:function(t,n,r){var i=this;if(t.groups)this._fetch(t,n);else{var s=this.list[t.id];if(s){n(s);return}e.request("GET",config.root+"api/datasets/"+t.id,{},function(e){switch(e.state){case"error":r&&r(e);break;default:i.list[t.id]=e,n(e)}})}},_fetch:function(t,n){var r=t.start?t.start:0,i=Math.abs(t.end-t.start),s=this.app.config.get("query_limit");if(!i||i>s)i=s;var o="",u={},a=0;for(var f in t.groups){var l=t.groups[f];for(var c in l.columns){var h=l.columns[c];o+=h+",",u[h]=a,a++}}if(a==0){n({});return}o=o.substring(0,o.length-1);var p=t.groups;for(var f in p)p[f].values=[];var d=this;e.request("GET",config.root+"api/datasets/"+t.id,{data_type:"raw_data",provider:"dataset-column",limit:i,offset:r,indeces:o},function(e){for(var i in e.data){var s=e.data[i];for(var o in t.groups){var a=t.groups[o],f={x:parseInt(i)+r};for(var l in a.columns){var c=a.columns[l],h=u[c],d=s[h];if(isNaN(d)||!d)d=0;f[l]=d}p[o].values.push(f)}}n(t)})}})}),define("plugin/models/group",[],function(){return Backbone.Model.extend({defaults:{key:"Data label",date:""},reset:function(){this.clear({silent:!0}).set(this.defaults),this.trigger("reset",this)}})}),define("plugin/models/groups",["plugin/models/group"],function(e){return Backbone.Collection.extend({model:e})}),define("plugin/library/deferred",["utils/utils"],function(e){return Backbone.Model.extend({queue:[],process:{},counter:0,initialize:function(){this.on("refresh",function(){if(this.counter==0)for(var e in this.queue)this.queue[e](),this.queue.splice(e,1)})},execute:function(e){this.queue.push(e),this.trigger("refresh")},register:function(){var t=e.uuid();return this.process[t]=!0,this.counter++,console.debug("Deferred:register() - Registering "+t),t},done:function(e){delete this.process[e],this.counter--,console.debug("Deferred:done() - Unregistering "+e),this.trigger("refresh")},ready:function(){return this.counter==0?!0:!1}})});var Visualization=Backbone.Model.extend({defaults:{config:{}},urlRoot:function(){var e="/api/visualizations";return window.galaxy_config&&galaxy_config.root?galaxy_config.root+e:e},initialize:function(e){_.isObject(e.config)&&_.isObject(this.defaults.config)&&_.defaults(e.config,this.defaults.config),this._setUpListeners()},_setUpListeners:function(){},set:function(e,t){if(e==="config"){var n=this.get("config");_.isObject(n)&&(t=_.extend(_.clone(n),t))}return Backbone.Model.prototype.set.call(this,e,t),this},toString:function(){var e=this.get("id")||"";return this.get("title")&&(e+=":"+this.get("title")),"Visualization("+e+")"}}),VisualizationCollection=Backbone.Collection.extend({model:Visualization,url:function(){return galaxy_config.root+"api/visualizations"},initialize:function(e,t){t=t||{}},set:function(e,t){var n=this;e=_.map(e,function(e){var t=n.get(e.id);if(!t)return e;var r=t.toJSON();return _.extend(r,e),r}),Backbone.Collection.prototype.set.call(this,e,t)},toString:function(){return["VisualizationCollection(",[this.historyId,this.length].join(),")"].join("")}});define("mvc/visualization/visualization-model",function(){}),define("plugin/models/chart",["plugin/models/groups","plugin/library/deferred","mvc/visualization/visualization-model"],function(e,t){return Backbone.Model.extend({defaults:{id:null,title:"",type:"",date:null,state:"",state_info:"",modified:!1,dataset_id:"",dataset_id_job:""},initialize:function(n){this.groups=new e,this.settings=new Backbone.Model,this.deferred=new t},reset:function(){this.clear({silent:!0}).set(this.defaults),this.groups.reset(),this.settings.clear(),this.trigger("reset",this)},copy:function(e){var t=this;t.clear({silent:!0}).set(this.defaults),t.set(e.attributes),t.settings=e.settings.clone(),t.groups.reset(),e.groups.each(function(e){t.groups.add(e.clone())}),t.trigger("change",t)},state:function(e,t){this.set("state",e),this.set("state_info",t),this.trigger("set:state"),console.debug("Chart:state() - "+t+" ("+e+")")}})}),define("plugin/library/storage",["utils/utils","plugin/models/chart","plugin/models/group"],function(e,t,n){return Backbone.Model.extend({vis:null,initialize:function(e){this.app=e,this.chart=this.app.chart,this.options=this.app.options,this.id=this.options.id,this.vis=new Visualization({type:"charts",config:{dataset_id:this.options.config.dataset_id,chart_dict:{}}}),this.id&&(this.vis.id=this.id);var t=this.options.config.chart_dict;t&&(this.vis.get("config").chart_dict=t)},save:function(){var e=this.app.chart;this.vis.get("config").chart_dict={};var t=e.get("title");t!=""&&this.vis.set("title",t);var n={attributes:e.attributes,settings:e.settings.attributes,groups:[]};e.groups.each(function(e){n.groups.push(e.attributes)}),this.vis.get("config").chart_dict=n;var r=this;this.vis.save().fail(function(e,t,n){console.error(e,t,n)}).then(function(e){e&&e.id&&(r.id=e.id)})},load:function(){var e=this.vis.get("config").chart_dict;if(!e.attributes)return!1;this.chart.set(e.attributes),this.chart.state("ok","Loading saved visualization..."),this.chart.settings.set(e.settings);for(var t in e.groups)this.chart.groups.add(new n(e.groups[t]));return this.chart.set("modified",!1),!0}})}),define("plugin/views/viewport",["mvc/ui/ui-portlet","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(e,t){this.app=e,this.chart=this.app.chart,this.options=n.merge(t,this.optionsDefault),this.setElement($(this._template())),this._create_canvas("div");var r=this;this.chart.on("redraw",function(){r._draw(r.chart)}),this.chart.on("set:state",function(){var e=r.$el.find("#info"),t=e.find("#icon");t.removeClass(),e.show(),e.find("#text").html(r.chart.get("state_info"));var n=r.chart.get("state");switch(n){case"ok":e.hide();break;case"failed":t.addClass("fa fa-warning");break;default:t.addClass("fa fa-spinner fa-spin")}})},show:function(){this.$el.show()},hide:function(){this.$el.hide()},_create_canvas:function(e){this.canvas&&this.canvas.remove(),this.$el.append($(this._template_canvas(e)));var t=this.$el.find(".canvas");e=="svg"?this.canvas=d3.select(t[0]):this.canvas=t},_draw:function(e){var t=this,n=e.deferred.register(),r=e.get("type");this.chart_settings=this.app.types.get(r),this._create_canvas(this.chart_settings.element),e.state("wait","Please wait...");if(!this.chart_settings.execute||this.chart_settings.execute&&e.get("modified"))this.app.jobs.cleanup(e),e.set("modified",!1);var t=this;require(["plugin/charts/"+r+"/"+r],function(r){var i=new r(t.app,{canvas:t.canvas});t.chart_settings.execute?e.get("dataset_id_job")==""?t.app.jobs.submit(e,t._defaultSettingsString(e),t._defaultRequestString(e),function(){i.draw(n,e,t._defaultRequestDictionary(e))},function(){e.deferred.done(n)}):i.draw(n,e,t._defaultRequestDictionary(e)):i.draw(n,e,t._defaultRequestDictionary(e))})},_defaultRequestString:function(e){var t="",n=0,r=this;return e.groups.each(function(e){for(var i in r.chart_settings.columns)t+=i+"_"+ ++n+":"+(parseInt(e.get(i))+1)+", "}),t.substring(0,t.length-2)},_defaultSettingsString:function(e){var t="";for(key in e.settings.attributes)t+=key+":"+e.settings.get(key)+", ";return t.substring(0,t.length-2)},_defaultRequestDictionary:function(e){var t={groups:[]};this.chart_settings.execute?t.id=e.get("dataset_id_job"):t.id=e.get("dataset_id");var n=0,r=this;return e.groups.each(function(e){var i={};for(var s in r.chart_settings.columns)i[s]=e.get(s);t.groups.push({key:++n+":"+e.get("key"),columns:i})}),t},_template:function(){return'<div style="height: 100%; min-height: 50px;"><div id="info" style="position: absolute; margin-left: 10px; margin-top: 10px; margin-bottom: 50px;"><span id="icon" style="font-size: 1.2em; display: inline-block;"/><span id="text" style="position: relative; margin-left: 5px; top: -1px; font-size: 1.0em;"/></div></div>'},_template_canvas:function(e){return"<"+e+' class="canvas" style="height: calc(100% - 80px)"/>'}})}),define("plugin/views/viewer",["utils/utils","plugin/library/ui","mvc/ui/ui-portlet","plugin/models/group","plugin/views/viewport"],function(e,t,n,r,i){return Backbone.View.extend({initialize:function(e,r){this.app=e,this.chart=this.app.chart,this.viewport_view=new i(e);var s=this;this.portlet=new n.View({icon:"fa-bar-chart-o",title:"Viewport",operations:{edit_button:new t.ButtonIcon({icon:"fa-edit",tooltip:"Customize this chart",title:"Customize",onclick:function(){s._wait(s.chart,function(){s.app.go("editor")})}})}}),this.portlet.append(this.viewport_view.$el),this.setElement(this.portlet.$el);var s=this;this.chart.on("change:title",function(){s._refreshTitle()})},show:function(){this.$el.show(),$(window).trigger("resize")},hide:function(){this.$el.hide()},_refreshTitle:function(){var e=this.chart.get("title");this.portlet.title(e)},_screenshot:function(){var e=new XMLSerializer,t=e.serializeToString(this.viewport_view.svg.node()),n="data:image/svg+xml;base64,"+btoa(t);window.location.href="data:application/x-download/;charset=utf-8,"+encodeURIComponent(t)},_wait:function(e,t){if(e.deferred.ready())t();else{var n=this;this.app.modal.show({title:"Please wait!",body:"Your chart is currently being processed. Please wait and try again.",buttons:{Close:function(){n.app.modal.hide()},Retry:function(){n.app.modal.hide(),setTimeout(function(){n._wait(e,t)},n.app.config.get("query_timeout"))}}})}}})}),define("mvc/ui/ui-tabs",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,list:{},$nav:null,$content:null,first_tab:null,optionsDefault:{title_new:"",operations:null,onnew:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(this.options));this.$nav=n.find(".tab-navigation"),this.$content=n.find(".tab-content"),this.setElement(n),this.list={};var r=this;this.options.operations&&$.each(this.options.operations,function(e,t){t.$el.prop("id",e),r.$nav.find(".operations").append(t.$el)});if(this.options.onnew){var i=$(this._template_tab_new(this.options));this.$nav.append(i),i.tooltip({title:"Add a new tab",placement:"bottom",container:r.$el}),i.on("click",function(e){i.tooltip("hide"),r.options.onnew()})}},add:function(e){var t=e.id,n={$title:$(this._template_tab(e)),$content:$(this._template_tab_content(e)),removable:e.ondel?!0:!1};this.list[t]=n,this.options.onnew?this.$nav.find("#new-tab").before(n.$title):this.$nav.append(n.$title),n.$content.append(e.$el),this.$content.append(n.$content),_.size(this.list)==1&&(n.$title.addClass("active"),n.$content.addClass("active"),this.first_tab=t);if(e.ondel){var r=this,i=n.$title.find("#delete");i.tooltip({title:"Delete this tab",placement:"bottom",container:r.$el}),i.on("click",function(){return i.tooltip("destroy"),r.$el.find(".tooltip").remove(),e.ondel(),!1})}e.onclick&&n.$title.on("click",function(){e.onclick()})},del:function(e){var t=this.list[e];t.$title.remove(),t.$content.remove(),delete t,this.first_tab==e&&(this.first_tab=null),this.first_tab!=null&&this.show(this.first_tab)},delRemovable:function(){for(var e in this.list){var t=this.list[e];t.removable&&this.del(e)}},show:function(e){this.$el.fadeIn("fast"),this.visible=!0,e&&this.list[e].$title.find("a").tab("show")},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},hideOperation:function(e){this.$nav.find("#"+e).hide()},showOperation:function(e){this.$nav.find("#"+e).show()},setOperation:function(e,t){var n=this.$nav.find("#"+e);n.off("click"),n.on("click",t)},title:function(e,t){var n=this.list[e].$title.find("#text");return t&&n.html(t),n.html()},_template:function(e){return'<div class="tabbable tabs-left"><ul class="tab-navigation nav nav-tabs"><div class="operations" style="float: right; margin-bottom: 4px;"></div></ul><div class="tab-content"/></div>'},_template_tab_new:function(e){return'<li id="new-tab"><a href="javascript:void(0);"><i style="font-size: 0.8em; margin-right: 5px;" class="fa fa-plus-circle"/>'+e.title_new+"</a>"+"</li>"},_template_tab:function(e){var t='<li id="title-'+e.id+'">'+'<a title="" href="#tab-'+e.id+'" data-toggle="tab" data-original-title="">'+'<span id="text">'+e.title+"</span>";return e.ondel&&(t+='<i id="delete" style="font-size: 0.8em; margin-left: 5px; cursor: pointer;" class="fa fa-minus-circle"/>'),t+="</a></li>",t},_template_tab_content:function(e){return'<div id="tab-'+e.id+'" class="tab-pane"/>'}});return{View:t}}),define("plugin/library/ui-table",["utils/utils"],function(e){var t=Backbone.View.extend({row:null,row_count:0,optionsDefault:{content:"No content available.",onchange:null,ondblclick:null,onconfirm:null},events:{click:"_onclick",dblclick:"_ondblclick"},first:!0,initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(t));this.$thead=n.find("thead"),this.$tbody=n.find("tbody"),this.$tmessage=n.find("tmessage"),this.setElement(n),this.row=$("<tr></tr>")},addHeader:function(e){var t=$("<th></th>");t.append(e),this.row.append(t)},appendHeader:function(){this.$thead.append(this.row),this.row=$("<tr></tr>")},add:function(e,t,n){var r=$("<td></td>");t&&r.css("width",t),n&&r.css("text-align",n),r.append(e),this.row.append(r)},append:function(e){this._commit(e)},prepend:function(e){this._commit(e,!0)},remove:function(e){var t=this.$tbody.find("#"+e);t.length>0&&(t.remove(),this.row_count--,this._refresh())},removeAll:function(){this.$tbody.html(""),this.row_count=0,this._refresh()},value:function(e){this.before=this.$tbody.find(".current").attr("id"),e!==undefined&&(this.$tbody.find("tr").removeClass("current"),e&&this.$tbody.find("#"+e).addClass("current"));var t=this.$tbody.find(".current").attr("id");return t===undefined?null:(t!=this.before&&this.options.onchange&&this.options.onchange(e),t)},size:function(){return this.$tbody.find("tr").length},_commit:function(e,t){this.remove(e),this.row.attr("id",e),t?this.$tbody.prepend(this.row):this.$tbody.append(this.row),this.row=$("<tr></tr>"),this.row_count++,this._refresh()},_onclick:function(e){var t=this.value(),n=$(e.target).closest("tr").attr("id");n&&t!=n&&(this.options.onconfirm?this.options.onconfirm(n):this.value(n))},_ondblclick:function(e){var t=this.value();t&&this.options.ondblclick&&this.options.ondblclick(t)},_refresh:function(){this.row_count==0?this.$tmessage.show():this.$tmessage.hide()},_template:function(e){return'<div><table class="grid"><thead></thead><tbody style="cursor: pointer;"></tbody></table><tmessage>'+e.content+"</tmessage>"+"<div>"}});return{View:t}}),define("plugin/views/group",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({columns:[],initialize:function(r,i){this.app=r;var s=this;this.chart=this.app.chart,this.group=i.group,this.group_key=new t.Input({placeholder:"Data label",onchange:function(){s.group.set("key",s.group_key.value())}}),this.table=new e.View({content:"No data column."});var o=$("<div/>");o.append(n.wrap((new t.Label({title:"Provide a label:"})).$el)),o.append(n.wrap(this.group_key.$el)),o.append(n.wrap((new t.Label({title:"Select columns:"})).$el)),o.append(n.wrap(this.table.$el)),this.setElement(o);var s=this;this.chart.on("change:dataset_id",function(){s._refreshTable()}),this.chart.on("change:type",function(){s._refreshTable()}),this.group.on("change:key",function(){s._refreshGroupKey()}),this.group.on("change",function(){s._refreshGroup()}),this._refreshTable(),this._refreshGroupKey(),this._refreshGroup()},_refreshTable:function(){var e=this.chart.get("dataset_id"),n=this.chart.get("type");if(!e||!n)return;var r=this,i=this.app.types.get(n);this.table.removeAll();var s={};for(var o in i.columns){var u=this.group.get(o);u||this.group.set(o,0);var a=i.columns[o],f=new t.Select.View({id:"select_"+o,gid:o,onchange:function(e){r.group.set(this.gid,e),r.chart.set("modified",!0)},value:u,wait:!0});this.table.add(a.title,"25%"),this.table.add(f.$el),this.table.append(o),s[o]=f}this.chart.state("wait","Loading metadata...");var l=this.chart.deferred.register();this.app.datasets.request({id:e},function(e){r.columns=[];var t=e.metadata_column_types;for(var n in t)(t[n]=="int"||t[n]=="float")&&r.columns.push({label:"Column: "+(parseInt(n)+1)+" ["+t[n]+"]",value:n});for(var n in s)s[n].update(r.columns),s[n].show();r.chart.state("wait","Metadata initialized..."),r.chart.deferred.done(l)})},_refreshGroup:function(){this.group.set("date",n.time())},_refreshGroupKey:function(){var e=this.group.get("key");e===undefined&&(e=""),this.group_key.value(e)}})}),define("plugin/library/ui-table-form",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){var r=Backbone.View.extend({list:[],initialize:function(r){this.table_title=new t.Label({title:r.title}),this.table=new e.View({content:r.content});var i=$("<div/>");i.append(n.wrap(this.table_title.$el)),i.append(n.wrap(this.table.$el)),this.setElement(i)},title:function(e){this.table_title.title(e)},update:function(e,t){this.table.removeAll(),this.list=[];for(var n in e)this._add(n,e[n],t);for(var n in this.list){var r=this.list[n].options.onchange;r&&r()}},_add:function(e,n,r){var i=this,s=null,o=n.type;switch(o){case"text":s=new t.Input({id:e,placeholder:n.placeholder,onchange:function(){r.set(e,s.value())}});break;case"select":s=new t.Select.View({id:e,data:n.data,onchange:function(){var t=s.value();r.set(e,t);var o=_.findWhere(n.data,{value:t});o&&(o.show&&i.$el.find("#"+o.show).fadeIn("fast"),o.hide&&i.$el.find("#"+o.hide).fadeOut("fast"))}});break;case"separator":s=$("<div/>");break;default:console.log("ui-table-form:_add","Unknown setting type ("+n.type+")");return}if(o!="separator"){r.get(e)||r.set(e,n.init),s.value(r.get(e)),this.list[e]=s;var u=$("<div/>");u.append(s.$el),u.append('<div class="toolParamHelp" style="font-size: 0.9em;">'+n.info+"</div>"),this.table.add('<span style="white-space: nowrap;">'+n.title+"</span>","25%"),this.table.add(u)}else this.table.add('<h6 style="white-space: nowrap;">'+n.title+":<h6/>"),this.table.add($("<div/>"));this.table.append(e)}});return{View:r}}),define("plugin/views/settings",["plugin/library/ui","plugin/library/ui-table-form","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(e,n){this.app=e;var r=this;this.chart=this.app.chart,this.form=new t.View({title:"Chart options:",content:"This chart type does not provide any options."}),this.setElement(this.form.$el);var r=this;this.chart.on("change",function(){r._refreshTable()})},_refreshTable:function(){var e=this.chart.get("type");if(!e)return;var t=this.app.types.get(e);this.form.title(t.title+":"),this.form.update(t.settings,this.chart.settings)}})}),define("plugin/views/editor",["mvc/ui/ui-tabs","plugin/library/ui-table","plugin/library/ui","mvc/ui/ui-portlet","utils/utils","plugin/models/chart","plugin/models/group","plugin/views/group","plugin/views/settings"],function(e,t,n,r,i,s,o,u,a){return Backbone.View.extend({optionsDefault:{header:!0,content:"No content available."},initialize:function(s,o){var u=this;this.app=s,this.chart=this.app.chart,this.options=i.merge(o,this.optionsDefault),this.portlet=new r.View({icon:"fa-bar-chart-o",title:"Editor",operations:{save:new n.ButtonIcon({icon:"fa-save",tooltip:"Draw Chart",title:"Draw",onclick:function(){u.app.go("viewer"),u._saveChart()}}),back:new n.ButtonIcon({icon:"fa-caret-left",tooltip:"Return to Viewer",title:"Return",onclick:function(){u.app.go("viewer"),u.app.storage.load()}})}}),this.table=new t.View({header:!1,onconfirm:function(e){u.chart.groups.length>0?u.app.modal.show({title:"Switching to another chart type?",body:"If you continue your settings and selections will be cleared.",buttons:{Cancel:function(){u.app.modal.hide()},Continue:function(){u.app.modal.hide(),u.table.value(e)}}}):u.table.value(e)},onchange:function(e){u.chart.groups.reset(),u.chart.settings.clear(),u.chart.set({type:e})},ondblclick:function(e){u.tabs.show("settings")},content:"No chart types available"}),this.table.addHeader("No."),this.table.addHeader("Type"),this.table.addHeader("Library"),this.table.addHeader("Processing*"),this.table.appendHeader();var f=0,l=s.types.attributes;for(var c in l){var h=l[c];this.table.add(++f+"."),this.table.add(h.title),this.table.add(h.library,"10%"),h.execute?this.table.add((new n.Icon({icon:"fa-check"})).$el,"10%","center"):this.table.add(""),this.table.append(c)}this.tabs=new e.View({title_new:"Add Data",onnew:function(){var e=u._addGroupModel();u.tabs.show(e.id)}}),this.title=new n.Input({placeholder:"Chart title",onchange:function(){u.chart.set("title",u.title.value())}});var p=$("<div/>");p.append(i.wrap((new n.Label({title:"Provide a chart title:"})).$el)),p.append(i.wrap(this.title.$el)),p.append(i.wrap((new n.Label({title:"Select a chart type:"})).$el)),p.append(i.wrap(this.table.$el)),p.append((new n.Text({title:"*Certain chart types pre-process data before rendering the visualization. The pre-processing is done using the chartskit available in the Toolshed.",cls:"toolParamHelp"})).$el),this.tabs.add({id:"main",title:"Start",$el:p}),this.settings=new a(this.app),this.tabs.add({id:"settings",title:"Configuration",$el:this.settings.$el}),this.portlet.append(this.tabs.$el),this.setElement(this.portlet.$el),this.tabs.hideOperation("back");var u=this;this.chart.on("change:title",function(e){u._refreshTitle()}),this.chart.on("change:type",function(e){u.table.value(e.get("type"))}),this.chart.on("reset",function(e){u._resetChart()}),this.app.chart.on("redraw",function(e){u.portlet.showOperation("back")}),this.app.chart.groups.on("add",function(e){u._addGroup(e)}),this.app.chart.groups.on("remove",function(e){u._removeGroup(e)}),this.app.chart.groups.on("reset",function(e){u._removeAllGroups()}),this.app.chart.groups.on("change:key",function(e){u._refreshGroupKey()}),this._resetChart()},show:function(){this.$el.show()},hide:function(){this.$el.hide()},_refreshTitle:function(){var e=this.chart.get("title");this.portlet.title(e),this.title.value(e)},_refreshGroupKey:function(){var e=this,t=0;this.chart.groups.each(function(n){var r=n.get("key","");r==""&&(r="Chart data"),e.tabs.title(n.id,++t+": "+r)})},_addGroupModel:function(){var e=new o({id:i.uuid()});return this.chart.groups.add(e),e},_addGroup:function(e){var t=this,n=new u(this.app,{group:e}),r=t.chart.groups.length;this.tabs.add({id:e.id,$el:n.$el,ondel:function(){t.chart.groups.remove(e.id)}}),this._refreshGroupKey()},_removeGroup:function(e){this.tabs.del(e.id),this._refreshGroupKey(),this.chart.set("modified",!0)},_removeAllGroups:function(e){this.tabs.delRemovable()},_resetChart:function(){this.chart.set("id",i.uuid()),this.chart.set("type","nvd3_bardiagram"),this.chart.set("dataset_id",this.app.options.config.dataset_id),this.chart.set("title","New Chart"),this.portlet.hideOperation("back")},_saveChart:function(){this.chart.set({type:this.table.value(),title:this.title.value(),date:i.time()}),this.chart.groups.length==0&&this._addGroupModel();var e=this;this.chart.deferred.execute(function(){e.app.storage.save(),e.chart.trigger("redraw")})}})}),define("plugin/models/config",[],function(){return Backbone.Model.extend({defaults:{query_limit:1e3,query_timeout:500}})}),define("plugin/charts/nvd3/config",[],function(){return{title:"",library:"nvd3.js",element:"svg",columns:{y:{title:"Values for y-axis"}},settings:{separator_label:{title:"X axis",type:"separator"},x_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"X-axis",placeholder:"Axis label"},x_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"auto",data:[{label:"-- Do not show values --",value:"hide",hide:"x_axis_tick"},{label:"Auto",value:"auto",hide:"x_axis_tick"},{label:"Float",value:"f",show:"x_axis_tick"},{label:"Exponent",value:"e",show:"x_axis_tick"},{label:"Integer",value:"d",hide:"x_axis_tick"},{label:"Percentage",value:"p",show:"x_axis_tick"},{label:"Rounded",value:"r",show:"x_axis_tick"},{label:"SI-prefix",value:"s",show:"x_axis_tick"}]},x_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_tick:{title:"Y axis",type:"separator"},y_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"Y-axis",placeholder:"Axis label"},y_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"auto",data:[{label:"-- Do not show values --",value:"hide",hide:"y_axis_tick"},{label:"Auto",value:"auto",hide:"y_axis_tick"},{label:"Float",value:"f",show:"y_axis_tick"},{label:"Exponent",value:"e",show:"y_axis_tick"},{label:"Integer",value:"d",hide:"y_axis_tick"},{label:"Percentage",value:"p",show:"y_axis_tick"},{label:"Rounded",value:"r",show:"y_axis_tick"},{label:"SI-prefix",value:"s",show:"y_axis_tick"}]},y_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_legend:{title:"Others",type:"separator"},show_legend:{title:"Show legend",info:"Would you like to add a legend?",type:"select",init:"true",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]}}}}),define("plugin/charts/nvd3_bardiagram/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram"})}),define("plugin/charts/nvd3_histogram/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Histogram",execute:"histogram",columns:{y:{title:"Observations"}},settings:{x_axis_label:{init:"Breaks"},y_axis_label:{init:"Density"}}})}),define("plugin/charts/nvd3_horizontal/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram (horizontal)",settings:{x_axis_type:{init:"hide"}}})}),define("plugin/charts/nvd3_line/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line chart"})}),define("plugin/charts/nvd3_linewithfocus/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line with focus"})}),define("plugin/charts/nvd3_piechart/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Pie chart"})}),define("plugin/charts/nvd3_scatterplot/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Scatter plot",columns:{x:{title:"Values for x-axis"}}})}),define("plugin/charts/nvd3_stackedarea/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Stacked area"})}),define("plugin/charts/highcharts_boxplot/config",[],function(){return{title:"Box plot",library:"highcharts.js",element:"div",execute:"boxplot",columns:{y:{title:"Observations"}},settings:{separator_label:{title:"X axis",type:"separator"},x_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"X-axis",placeholder:"Axis label"},separator_tick:{title:"Y axis",type:"separator"},y_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"Y-axis",placeholder:"Axis label"}}}}),define("plugin/charts/types",["plugin/charts/nvd3_bardiagram/config","plugin/charts/nvd3_histogram/config","plugin/charts/nvd3_horizontal/config","plugin/charts/nvd3_line/config","plugin/charts/nvd3_linewithfocus/config","plugin/charts/nvd3_piechart/config","plugin/charts/nvd3_scatterplot/config","plugin/charts/nvd3_stackedarea/config","plugin/charts/highcharts_boxplot/config"],function(e,t,n,r,i,s,o,u,a){return Backbone.Model.extend({defaults:{nvd3_bardiagram:e,nvd3_horizontal:n,nvd3_histogram:t,nvd3_line:r,nvd3_linewithfocus:i,nvd3_piechart:s,nvd3_scatterplot:o,nvd3_stackedarea:u,highcharts_boxplot:a}})}),define("plugin/app",["mvc/ui/ui-modal","mvc/ui/ui-portlet","plugin/library/ui","utils/utils","plugin/library/jobs","plugin/library/datasets","plugin/library/storage","plugin/views/viewer","plugin/views/editor","plugin/models/config","plugin/models/chart","plugin/charts/types"],function(e,t,n,r,i,s,o,u,a,f,l,c){return Backbone.View.extend({initialize:function(t){this.options=t,Galaxy&&Galaxy.modal?this.modal=Galaxy.modal:this.modal=new e.View,this.config=new f,this.types=new c,this.chart=new l,this.jobs=new i(this),this.datasets=new s(this),this.storage=new o(this),this.viewer_view=new u(this),this.editor_view=new a(this),this.$el.append(this.viewer_view.$el),this.$el.append(this.editor_view.$el);if(!this.storage.load())this.go("editor");else{this.go("viewer");var n=this;this.chart.deferred.execute(function(){n.chart.trigger("redraw")})}},go:function(e){$(".tooltip").hide();switch(e){case"editor":this.editor_view.show(),this.viewer_view.hide();break;case"viewer":this.editor_view.hide(),this.viewer_view.show()}},execute:function(e){},onunload:function(){},log:function(e,t){console.log(e+" "+t)}})});
\ No newline at end of file
+(function(){var e=this,t=e._,n={},r=Array.prototype,i=Object.prototype,s=Function.prototype,o=r.push,u=r.slice,a=r.concat,f=i.toString,l=i.hasOwnProperty,c=r.forEach,h=r.map,p=r.reduce,d=r.reduceRight,v=r.filter,m=r.every,g=r.some,y=r.indexOf,b=r.lastIndexOf,w=Array.isArray,E=Object.keys,S=s.bind,x=function(e){if(e instanceof x)return e;if(!(this instanceof x))return new x(e);this._wrapped=e};typeof exports!="undefined"?(typeof module!="undefined"&&module.exports&&(exports=module.exports=x),exports._=x):e._=x,x.VERSION="1.4.4";var T=x.each=x.forEach=function(e,t,r){if(e==null)return;if(c&&e.forEach===c)e.forEach(t,r);else if(e.length===+e.length){for(var i=0,s=e.length;i<s;i++)if(t.call(r,e[i],i,e)===n)return}else for(var o in e)if(x.has(e,o)&&t.call(r,e[o],o,e)===n)return};x.map=x.collect=function(e,t,n){var r=[];return e==null?r:h&&e.map===h?e.map(t,n):(T(e,function(e,i,s){r.push(t.call(n,e,i,s))}),r)};var N="Reduce of empty array with no initial value";x.reduce=x.foldl=x.inject=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(p&&e.reduce===p)return r&&(t=x.bind(t,r)),i?e.reduce(t,n):e.reduce(t);T(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError(N);return n},x.reduceRight=x.foldr=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(d&&e.reduceRight===d)return r&&(t=x.bind(t,r)),i?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=x.keys(e);s=o.length}T(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError(N);return n},x.find=x.detect=function(e,t,n){var r;return C(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},x.filter=x.select=function(e,t,n){var r=[];return e==null?r:v&&e.filter===v?e.filter(t,n):(T(e,function(e,i,s){t.call(n,e,i,s)&&r.push(e)}),r)},x.reject=function(e,t,n){return x.filter(e,function(e,r,i){return!t.call(n,e,r,i)},n)},x.every=x.all=function(e,t,r){t||(t=x.identity);var i=!0;return e==null?i:m&&e.every===m?e.every(t,r):(T(e,function(e,s,o){if(!(i=i&&t.call(r,e,s,o)))return n}),!!i)};var C=x.some=x.any=function(e,t,r){t||(t=x.identity);var i=!1;return e==null?i:g&&e.some===g?e.some(t,r):(T(e,function(e,s,o){if(i||(i=t.call(r,e,s,o)))return n}),!!i)};x.contains=x.include=function(e,t){return e==null?!1:y&&e.indexOf===y?e.indexOf(t)!=-1:C(e,function(e){return e===t})},x.invoke=function(e,t){var n=u.call(arguments,2),r=x.isFunction(t);return x.map(e,function(e){return(r?t:e[t]).apply(e,n)})},x.pluck=function(e,t){return x.map(e,function(e){return e[t]})},x.where=function(e,t,n){return x.isEmpty(t)?n?void 0:[]:x[n?"find":"filter"](e,function(e){for(var n in t)if(t[n]!==e[n])return!1;return!0})},x.findWhere=function(e,t){return x.where(e,t,!0)},x.max=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);if(!t&&x.isEmpty(e))return-Infinity;var r={computed:-Infinity,value:-Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o>=r.computed&&(r={value:e,computed:o})}),r.value},x.min=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);if(!t&&x.isEmpty(e))return Infinity;var r={computed:Infinity,value:Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o<r.computed&&(r={value:e,computed:o})}),r.value},x.shuffle=function(e){var t,n=0,r=[];return T(e,function(e){t=x.random(n++),r[n-1]=r[t],r[t]=e}),r};var k=function(e){return x.isFunction(e)?e:function(t){return t[e]}};x.sortBy=function(e,t,n){var r=k(t);return x.pluck(x.map(e,function(e,t,i){return{value:e,index:t,criteria:r.call(n,e,t,i)}}).sort(function(e,t){var n=e.criteria,r=t.criteria;if(n!==r){if(n>r||n===void 0)return 1;if(n<r||r===void 0)return-1}return e.index<t.index?-1:1}),"value")};var L=function(e,t,n,r){var i={},s=k(t==null?x.identity:t);return T(e,function(t,o){var u=s.call(n,t,o,e);r(i,u,t)}),i};x.groupBy=function(e,t,n){return L(e,t,n,function(e,t,n){(x.has(e,t)?e[t]:e[t]=[]).push(n)})},x.countBy=function(e,t,n){return L(e,t,n,function(e,t){x.has(e,t)||(e[t]=0),e[t]++})},x.sortedIndex=function(e,t,n,r){n=n==null?x.identity:k(n);var i=n.call(r,t),s=0,o=e.length;while(s<o){var u=s+o>>>1;n.call(r,e[u])<i?s=u+1:o=u}return s},x.toArray=function(e){return e?x.isArray(e)?u.call(e):e.length===+e.length?x.map(e,x.identity):x.values(e):[]},x.size=function(e){return e==null?0:e.length===+e.length?e.length:x.keys(e).length},x.first=x.head=x.take=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,0,t):e[0]},x.initial=function(e,t,n){return u.call(e,0,e.length-(t==null||n?1:t))},x.last=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,Math.max(e.length-t,0)):e[e.length-1]},x.rest=x.tail=x.drop=function(e,t,n){return u.call(e,t==null||n?1:t)},x.compact=function(e){return x.filter(e,x.identity)};var A=function(e,t,n){return T(e,function(e){x.isArray(e)?t?o.apply(n,e):A(e,t,n):n.push(e)}),n};x.flatten=function(e,t){return A(e,t,[])},x.without=function(e){return x.difference(e,u.call(arguments,1))},x.uniq=x.unique=function(e,t,n,r){x.isFunction(t)&&(r=n,n=t,t=!1);var i=n?x.map(e,n,r):e,s=[],o=[];return T(i,function(n,r){if(t?!r||o[o.length-1]!==n:!x.contains(o,n))o.push(n),s.push(e[r])}),s},x.union=function(){return x.uniq(a.apply(r,arguments))},x.intersection=function(e){var t=u.call(arguments,1);return x.filter(x.uniq(e),function(e){return x.every(t,function(t){return x.indexOf(t,e)>=0})})},x.difference=function(e){var t=a.apply(r,u.call(arguments,1));return x.filter(e,function(e){return!x.contains(t,e)})},x.zip=function(){var e=u.call(arguments),t=x.max(x.pluck(e,"length")),n=new Array(t);for(var r=0;r<t;r++)n[r]=x.pluck(e,""+r);return n},x.unzip=function(e){var t=[];return x.each(e,function(e,n){x.each(e,function(e,r){t.length<=r&&(t[r]=[]),t[r][n]=e})}),t},x.object=function(e,t){if(e==null)return{};var n={};for(var r=0,i=e.length;r<i;r++)t?n[e[r]]=t[r]:n[e[r][0]]=e[r][1];return n},x.indexOf=function(e,t,n){if(e==null)return-1;var r=0,i=e.length;if(n){if(typeof n!="number")return r=x.sortedIndex(e,t),e[r]===t?r:-1;r=n<0?Math.max(0,i+n):n}if(y&&e.indexOf===y)return e.indexOf(t,n);for(;r<i;r++)if(e[r]===t)return r;return-1},x.lastIndexOf=function(e,t,n){if(e==null)return-1;var r=n!=null;if(b&&e.lastIndexOf===b)return r?e.lastIndexOf(t,n):e.lastIndexOf(t);var i=r?n:e.length;while(i--)if(e[i]===t)return i;return-1},x.range=function(e,t,n){arguments.length<=1&&(t=e||0,e=0),n=arguments[2]||1;var r=Math.max(Math.ceil((t-e)/n),0),i=0,s=new Array(r);while(i<r)s[i++]=e,e+=n;return s};var O=function(){};x.bind=function(e,t){var n,r;if(e.bind===S&&S)return S.apply(e,u.call(arguments,1));if(!x.isFunction(e))throw new TypeError;return n=u.call(arguments,2),r=function(){if(this instanceof r){O.prototype=e.prototype;var i=new O;O.prototype=null;var s=e.apply(i,n.concat(u.call(arguments)));return Object(s)===s?s:i}return e.apply(t,n.concat(u.call(arguments)))}},x.partial=function(e){var t=u.call(arguments,1);return function(){return e.apply(this,t.concat(u.call(arguments)))}},x.bindAll=function(e){var t=u.call(arguments,1);if(t.length===0)throw new Error("bindAll must be passed function names");return T(t,function(t){e[t]=x.bind(e[t],e)}),e},x.memoize=function(e,t){var n={};return t||(t=x.identity),function(){var r=t.apply(this,arguments);return x.has(n,r)?n[r]:n[r]=e.apply(this,arguments)}},x.delay=function(e,t){var n=u.call(arguments,2);return setTimeout(function(){return e.apply(null,n)},t)},x.defer=function(e){return x.delay.apply(x,[e,1].concat(u.call(arguments,1)))},x.throttle=function(e,t,n){var r,i,s,o,u=0,a=function(){u=new Date,s=null,o=e.apply(r,i)};return function(){var f=new Date;!u&&n===!1&&(u=f);var l=t-(f-u);return r=this,i=arguments,l<=0?(clearTimeout(s),s=null,u=f,o=e.apply(r,i)):s||(s=setTimeout(a,l)),o}},x.debounce=function(e,t,n){var r,i;return function(){var s=this,o=arguments,u=function(){r=null,n||(i=e.apply(s,o))},a=n&&!r;return clearTimeout(r),r=setTimeout(u,t),a&&(i=e.apply(s,o)),i}},x.once=function(e){var t=!1,n;return function(){return t?n:(t=!0,n=e.apply(this,arguments),e=null,n)}},x.wrap=function(e,t){return function(){var n=[e];return o.apply(n,arguments),t.apply(this,n)}},x.compose=function(){var e=arguments;return function(){var t=arguments;for(var n=e.length-1;n>=0;n--)t=[e[n].apply(this,t)];return t[0]}},x.after=function(e,t){return e<=0?t():function(){if(--e<1)return t.apply(this,arguments)}},x.keys=E||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var n in e)x.has(e,n)&&t.push(n);return t},x.values=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push(e[n]);return t},x.pairs=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push([n,e[n]]);return t},x.invert=function(e){var t={};for(var n in e)x.has(e,n)&&(t[e[n]]=n);return t},x.functions=x.methods=function(e){var t=[];for(var n in e)x.isFunction(e[n])&&t.push(n);return t.sort()},x.extend=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]=t[n]}),e},x.pick=function(e){var t={},n=a.apply(r,u.call(arguments,1));return T(n,function(n){n in e&&(t[n]=e[n])}),t},x.omit=function(e){var t={},n=a.apply(r,u.call(arguments,1));for(var i in e)x.contains(n,i)||(t[i]=e[i]);return t},x.defaults=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]===void 0&&(e[n]=t[n])}),e},x.clone=function(e){return x.isObject(e)?x.isArray(e)?e.slice():x.extend({},e):e},x.tap=function(e,t){return t(e),e};var M=function(e,t,n,r){if(e===t)return e!==0||1/e==1/t;if(e==null||t==null)return e===t;e instanceof x&&(e=e._wrapped),t instanceof x&&(t=t._wrapped);var i=f.call(e);if(i!=f.call(t))return!1;switch(i){case"[object String]":return e==String(t);case"[object Number]":return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case"[object Date]":case"[object Boolean]":return+e==+t;case"[object RegExp]":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if(typeof e!="object"||typeof t!="object")return!1;var s=n.length;while(s--)if(n[s]==e)return r[s]==t;n.push(e),r.push(t);var o=0,u=!0;if(i=="[object Array]"){o=e.length,u=o==t.length;if(u)while(o--)if(!(u=M(e[o],t[o],n,r)))break}else{var a=e.constructor,l=t.constructor;if(a!==l&&!(x.isFunction(a)&&a instanceof a&&x.isFunction(l)&&l instanceof l))return!1;for(var c in e)if(x.has(e,c)){o++;if(!(u=x.has(t,c)&&M(e[c],t[c],n,r)))break}if(u){for(c in t)if(x.has(t,c)&&!(o--))break;u=!o}}return n.pop(),r.pop(),u};x.isEqual=function(e,t){return M(e,t,[],[])},x.isEmpty=function(e){if(e==null)return!0;if(x.isArray(e)||x.isString(e))return e.length===0;for(var t in e)if(x.has(e,t))return!1;return!0},x.isElement=function(e){return!!e&&e.nodeType===1},x.isArray=w||function(e){return f.call(e)=="[object Array]"},x.isObject=function(e){return e===Object(e)},T(["Arguments","Function","String","Number","Date","RegExp"],function(e){x["is"+e]=function(t){return f.call(t)=="[object "+e+"]"}}),x.isArguments(arguments)||(x.isArguments=function(e){return!!e&&!!x.has(e,"callee")}),typeof /./!="function"&&(x.isFunction=function(e){return typeof e=="function"}),x.isFinite=function(e){return isFinite(e)&&!isNaN(parseFloat(e))},x.isNaN=function(e){return x.isNumber(e)&&e!=+e},x.isBoolean=function(e){return e===!0||e===!1||f.call(e)=="[object Boolean]"},x.isNull=function(e){return e===null},x.isUndefined=function(e){return e===void 0},x.has=function(e,t){return l.call(e,t)},x.noConflict=function(){return e._=t,this},x.identity=function(e){return e},x.times=function(e,t,n){var r=Array(e);for(var i=0;i<e;i++)r[i]=t.call(n,i);return r},x.random=function(e,t){return t==null&&(t=e,e=0),e+Math.floor(Math.random()*(t-e+1))};var _={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};_.unescape=x.invert(_.escape);var D={escape:new RegExp("["+x.keys(_.escape).join("")+"]","g"),unescape:new RegExp("("+x.keys(_.unescape).join("|")+")","g")};x.each(["escape","unescape"],function(e){x[e]=function(t){return t==null?"":(""+t).replace(D[e],function(t){return _[e][t]})}}),x.result=function(e,t){if(e==null)return void 0;var n=e[t];return x.isFunction(n)?n.call(e):n},x.mixin=function(e){T(x.functions(e),function(t){var n=x[t]=e[t];x.prototype[t]=function(){var e=[this._wrapped];return o.apply(e,arguments),F.call(this,n.apply(x,e))}})};var P=0;x.uniqueId=function(e){var t=++P+"";return e?e+t:t},x.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var H=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},j=/\\|'|\r|\n|\t|\u2028|\u2029/g;x.template=function(e,t,n){var r;n=x.defaults({},n,x.templateSettings);var i=new RegExp([(n.escape||H).source,(n.interpolate||H).source,(n.evaluate||H).source].join("|")+"|$","g"),s=0,o="__p+='";e.replace(i,function(t,n,r,i,u){return o+=e.slice(s,u).replace(j,function(e){return"\\"+B[e]}),n&&(o+="'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'"),r&&(o+="'+\n((__t=("+r+"))==null?'':__t)+\n'"),i&&(o+="';\n"+i+"\n__p+='"),s=u+t.length,t}),o+="';\n",n.variable||(o="with(obj||{}){\n"+o+"}\n"),o="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+o+"return __p;\n";try{r=new Function(n.variable||"obj","_",o)}catch(u){throw u.source=o,u}if(t)return r(t,x);var a=function(e){return r.call(this,e,x)};return a.source="function("+(n.variable||"obj")+"){\n"+o+"}",a},x.chain=function(e){return x(e).chain()};var F=function(e){return this._chain?x(e).chain():e};x.mixin(x),T(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];x.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e=="shift"||e=="splice")&&n.length===0&&delete n[0],F.call(this,n)}}),T(["concat","join","slice"],function(e){var t=r[e];x.prototype[e]=function(){return F.call(this,t.apply(this._wrapped,arguments))}}),x.extend(x.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this),define("libs/underscore",function(e){return function(){var t,n;return t||e._}}(this)),define("utils/utils",["libs/underscore"],function(e){function t(e,t,r){n("GET",e,{},t,r)}function n(e,t,n,r,i){if(e=="GET"||e=="DELETE")t.indexOf("?")==-1?t+="?":t+="&",t+=$.param(n);var s=new XMLHttpRequest;s.open(e,t,!0),s.setRequestHeader("Accept","application/json"),s.setRequestHeader("Cache-Control","no-cache"),s.setRequestHeader("X-Requested-With","XMLHttpRequest"),s.setRequestHeader("Content-Type","application/json"),s.onloadend=function(){var e=s.status;try{response=jQuery.parseJSON(s.responseText)}catch(t){response=s.responseText}e==200?r&&r(response):i&&i(response)},e=="GET"||e=="DELETE"?s.send():s.send(JSON.stringify(n))}function r(e,t){var n=$('<div class="'+e+'"></div>');n.appendTo(":eq(0)");var r=n.css(t);return n.remove(),r}function i(e){$('link[href^="'+e+'"]').length||$('<link href="'+galaxy_config.root+e+'" rel="stylesheet">').appendTo("head")}function s(t,n){return t?e.defaults(t,n):n}function o(e,t){var n="";if(e>=1e11)e/=1e11,n="TB";else if(e>=1e8)e/=1e8,n="GB";else if(e>=1e5)e/=1e5,n="MB";else if(e>=100)e/=100,n="KB";else{if(!(e>0))return"<strong>-</strong>";e*=10,n="b"}var r=Math.round(e)/10;return t?r+" "+n:"<strong>"+r+"</strong> "+n}function u(){return(new Date).getTime().toString(36)}function a(e){var t=$("<p></p>");return t.append(e),t}function f(){var e=new Date,t=(e.getHours()<10?"0":"")+e.getHours(),n=(e.getMinutes()<10?"0":"")+e.getMinutes(),r=e.getDate()+"/"+(e.getMonth()+1)+"/"+e.getFullYear()+", "+t+":"+n;return r}return{cssLoadFile:i,cssGetAttribute:r,get:t,merge:s,bytesToString:o,uuid:u,time:f,wrap:a,request:n}}),define("mvc/ui/ui-modal",["utils/utils"],function(e){var t=Backbone.View.extend({elMain:"body",optionsDefault:{title:"ui-modal",body:"",backdrop:!0,height:null,width:null,closing_events:!1},buttonList:{},initialize:function(e){e&&this._create(e)},show:function(e){this.initialize(e),this.options.height?(this.$body.css("height",this.options.height),this.$body.css("overflow","hidden")):this.$body.css("max-height",$(window).height()/2),this.options.width&&this.$dialog.css("width",this.options.width),this.visible?this.$el.show():this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.visible=!1,this.$el.fadeOut("fast")},enableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!1)},disableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!0)},showButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).show()},hideButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).hide()},getButton:function(e){var t=this.buttonList[e];return this.$buttons.find("#"+t)},scrollTop:function(){return this.$body.scrollTop()},_create:function(e){var t=this;this.options=_.defaults(e,this.optionsDefault),this.options.body=="progress"&&(this.options.body=$('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>')),this.$el&&(this.$el.remove(),$(document).off("keyup.ui-modal")),this.setElement(this._template(this.options.title)),this.$dialog=this.$el.find(".modal-dialog"),this.$body=this.$el.find(".modal-body"),this.$footer=this.$el.find(".modal-footer"),this.$buttons=this.$el.find(".buttons"),this.$backdrop=this.$el.find(".modal-backdrop"),this.$body.html(this.options.body),this.options.backdrop||this.$backdrop.removeClass("in");if(this.options.buttons){this.buttonList={};var n=0;$.each(this.options.buttons,function(e,r){var i="button-"+n++;t.$buttons.append($('<button id="'+i+'"></button>').text(e).click(r)).append(" "),t.buttonList[e]=i})}else this.$footer.hide();$(this.elMain).append($(this.el)),this.options.closing_events&&($(document).on("keyup.ui-modal",function(e){e.keyCode==27&&t.hide()}),this.$el.find(".modal-backdrop").on("click",function(){t.hide()}))},_template:function(e){return'<div class="modal"><div class="modal-backdrop fade in" style="z-index: -1;"></div><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" style="display: none;">×</button><h4 class="title">'+e+"</h4>"+"</div>"+'<div class="modal-body" style="position: static;"></div>'+'<div class="modal-footer">'+'<div class="buttons" style="float: right;"></div>'+"</div>"+"</div"+"</div>"+"</div>"}});return{View:t}}),define("mvc/ui/ui-portlet",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,optionsDefault:{title:"",icon:"",buttons:null,body:null,height:null,operations:null,placement:"bottom",overflow:"auto"},$title:null,$content:null,$buttons:null,$operations:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$content=this.$el.find("#content"),this.$title=this.$el.find("#title-text"),this.options.height&&(this.$el.find("#body").css("height",this.options.height),this.$el.find("#content").css("overflow",this.options.overflow)),this.$buttons=$(this.el).find("#buttons");if(this.options.buttons){var n=this;$.each(this.options.buttons,function(e,t){t.$el.prop("id",e),n.$buttons.append(t.$el)})}else this.$buttons.remove();this.$operations=$(this.el).find("#operations");if(this.options.operations){var n=this;$.each(this.options.operations,function(e,t){t.$el.prop("id",e),n.$operations.append(t.$el)})}this.options.body&&this.append(this.options.body)},append:function(t){this.$content.append(e.wrap(t))},content:function(){return this.$content},show:function(){this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},enableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!1)},disableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!0)},hideOperation:function(e){this.$operations.find("#"+e).hide()},showOperation:function(e){this.$operations.find("#"+e).show()},setOperation:function(e,t){var n=this.$operations.find("#"+e);n.off("click"),n.on("click",t)},title:function(e){var t=this.$title;return e&&t.html(e),t.html()},_template:function(e){var t='<div class="toolForm portlet-view no-highlight">';if(e.title||e.icon)t+='<div id="title" class="toolFormTitle portlet-title"><div id="operations" class="portlet-operations"/><div style="overflow: hidden;">',e.icon&&(t+='<div class="portlet-title-icon fa '+e.icon+'"> </div>'),t+='<div id="title-text" class="portlet-title-text">'+e.title+"</div>",t+="</div></div>";return t+='<div id="body" class="toolFormBody portlet-body">',e.placement=="top"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+='<div id="content" class="portlet-content"/>',e.placement=="bottom"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+="</div></div>",t}});return{View:t}}),define("plugin/library/ui-select",["utils/utils"],function(e){var t=Backbone.View.extend({optionsDefault:{id:"",cls:"",empty:"No data available",visible:!0,wait:!1},selected:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$select=this.$el.find("#select"),this.$icon=this.$el.find("#icon"),this.selected=this.options.value;var n=this;this.options.onchange&&this.$select.on("change",function(){n.value(n.$select.val())}),this._refresh(),this.options.visible||this.hide(),this.options.wait?this.wait():this.show()},value:function(e){var t=this.selected;e!==undefined&&(this.selected=e,this.$select.val(e));var n=this.selected;return n&&n!=t&&this.options.onchange&&this.options.onchange(n),n},text:function(){return this.$select.find("option:selected").text()},show:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-caret-down"),this.$select.show(),this.$el.show()},hide:function(){this.$el.hide()},wait:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-spinner fa-spin"),this.$select.hide()},disabled:function(){return this.$select.is(":disabled")},enable:function(){this.$select.prop("disabled",!1)},disable:function(){this.$select.prop("disabled",!0)},add:function(e){this.$select.append(this._templateOption(e)),this._refresh()},del:function(e){this.$select.find("option[value="+e+"]").remove(),this.$select.trigger("change"),this._refresh()},update:function(e){this.$select.find("option").remove();for(var t in e)this.$select.append(this._templateOption(e[t]));!this.selected&&e.length>0&&this.value(e[0].value),this._refresh()},_refresh:function(){this.$select.find("option[value=null]").remove();var e=this.$select.find("option").length;e==0?(this.$select.append(this._templateOption({value:"null",label:this.options.empty})),this.disable()):(this.enable(),this.selected&&this.$select.val(this.selected))},_exists:function(e){return 0!=this.$select.find("option[value="+e+"]").length},_templateOption:function(e){return'<option value="'+e.value+'">'+e.label+"</option>"},_template:function(e){var t='<div id="'+e.id+'" class="styled-select">'+'<div class="button">'+'<i id="icon"/>'+"</div>"+'<select id="select" class="select '+e.cls+" "+e.id+'">';for(key in e.data){var n=e.data[key],r="";if(n.value==e.value||n.value=="")r="selected";t+='<option value="'+n.value+'" '+r+">"+n.label+"</option>"}return t+="</select></div>",t}});return{View:t}}),define("plugin/library/ui",["utils/utils","plugin/library/ui-select"],function(e,t){var n=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},title:function(e){this.$el.find("b").html(e)},_template:function(e){return"<label><b>"+e.title+"</b></label>"},value:function(){return options.title}}),r=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},title:function(e){this.$el.html(e)},_template:function(e){return'<div class="'+e.cls+'">'+e.title+"</div>"},value:function(){return options.title}}),i=Backbone.View.extend({optionsDefault:{id:null,title:"","float":"right",cls:"btn-default",icon:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t='<button id="'+e.id+'" type="submit" style="margin-right: 5px; float: '+e.float+';" type="button" class="btn '+e.cls+'">';return e.icon&&(t+='<i class="icon fa '+e.icon+'"></i> '),t+=e.title+"</button>",t}}),s=Backbone.View.extend({optionsDefault:{"float":"right",icon:"",tooltip:"",placement:"bottom",title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){return'<div><span class="fa '+e.icon+'" style="font-size: 1.2em;"/> '+e.title+"</div>"}}),o=Backbone.View.extend({optionsDefault:{title:"",id:null,"float":"right",cls:"icon-btn",icon:"",tooltip:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t="";e.title&&(t="width: auto;");var n='<div id="'+e.id+'" style="margin-right: 5px; float: '+e.float+"; "+t+'" class="'+e.cls+'">';return e.title?n+='<div style="margin-right: 5px; margin-left: 5px;"><i class="icon fa '+e.icon+'"/> '+'<span style="position: relative; font-size: 0.8em; font-weight: normal; top: -1px;">'+e.title+"</span>"+"</div>":n+='<i class="icon fa '+e.icon+'"/>',n+="</div>",n}}),u=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick)},_template:function(e){return'<div><a href="javascript:void(0)">'+e.title+"</a></div>"}}),a=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:!1},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement("<div></div>")},update:function(t){this.options=e.merge(t,this.optionsDefault);if(t.message!=""){this.$el.html(this._template(this.options)),this.$el.fadeIn();if(!t.persistent){var n=this;window.setTimeout(function(){n.$el.is(":visible")?n.$el.fadeOut():n.$el.hide()},3e3)}}else this.$el.fadeOut()},_template:function(e){return'<div class="alert alert-'+e.status+'" style="padding: 2px 2px 2px 10px;">'+e.message+"</div>"}}),f=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options));var n=this;this.options.onclick&&this.$el.on("submit",function(e){var t=n.$el.find("#search");n.options.onclick(t.val())})},_template:function(e){return'<div class="search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+e.searchword+'">'+'<button type="submit" class="btn search-btn">'+'<i class="fa fa-search"></i>'+"</button>"+"</form>"+"</div>"}}),l=Backbone.View.extend({optionsDefault:{title:"Unlabeled",body:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.body&&this.$el.find(".body").append(this.options.body)},_template:function(e){return'<div id="title" class="title">'+e.title+":"+"</div>"}}),c=Backbone.View.extend({optionsDefault:{id:"",title:"",target:"",href:"",onunload:null,onclick:null,visible:!0,icon:null,tag:""},$menu:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement($(this._template(this.options)));var n=$(this.el).find(".root"),r=this;n.on("click",function(e){e.preventDefault(),r.options.onclick&&r.options.onclick()}),this.options.visible||this.hide()},show:function(){$(this.el).show()},hide:function(){$(this.el).hide()},addMenu:function(t){var n={title:"",target:"",href:"",onclick:null,divider:!1,icon:null};n=e.merge(t,n),this.$menu||($(this.el).append(this._templateMenu()),this.$menu=$(this.el).find(".menu"));var r=$(this._templateMenuItem(n));r.on("click",function(e){e.preventDefault(),n.onclick&&n.onclick()}),this.$menu.append(r),n.divider&&this.$menu.append($(this._templateDivider()))},_templateMenuItem:function(e){var t='<li><a href="'+e.href+'" target="'+e.target+'">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),t+=" "+e.title+"</a>"+"</li>",t},_templateMenu:function(){return'<ul class="menu dropdown-menu pull-right" role="menu"></ul>'},_templateDivider:function(){return'<li class="divider"></li>'},_template:function(e){var t='<div id="'+e.id+'" class="button-menu btn-group">'+'<button type="button" class="root btn btn-default dropdown-toggle" data-toggle="dropdown">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),"</button></div>",t}}),h=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:!1,visible:!0},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.disabled&&this.$el.prop("disabled",!0),this.options.visible||this.$el.hide();var n=this;this.options.onchange&&this.$el.on("input",function(){n.options.onchange()})},value:function(e){return e!==undefined&&this.$el.val(e),this.$el.val()},_template:function(e){return'<input id="'+e.id+'" type="'+e.type+'" value="'+e.value+'" placeholder="'+e.placeholder+'" class="form-control">'}});return{Label:n,Button:i,Icon:s,ButtonIcon:o,Input:h,Anchor:u,Message:a,Searchbox:f,Title:l,Text:r,Select:t,ButtonMenu:c}}),define("plugin/library/jobs",["utils/utils"],function(e){return Backbone.Model.extend({initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},cleanup:function(t){var n=t.get("dataset_id_job");if(n!=""){var r=this;e.request("PUT",config.root+"api/histories/none/contents/"+n,{deleted:!0},function(){r._refreshHdas()}),t.set("dataset_id_job","")}},submit:function(t,n,r,i,s){var o=this,u=t.id,a=t.get("type"),f=this.app.types.get(a);data={tool_id:"chartskit",inputs:{input:{id:t.get("dataset_id"),src:"hda"},module:f.execute,columns:r,settings:n}},t.state("wait","Sending job request..."),e.request("POST",config.root+"api/tools",data,function(e){if(!e.outputs||e.outputs.length==0)t.state("failed","Job submission failed. No response."),s&&s();else{o._refreshHdas();var n=e.outputs[0];t.state("wait","Job has been queued..."),t.set("dataset_id_job",n.id),this.app.storage.save(),o._loop(n.id,function(e){switch(e.state){case"ok":return t.state("wait","Job completed successfully..."),i(e),!0;case"error":return t.state("failed","Job has failed. Please check the history for details."),s&&s(),!0;case"running":return t.state("wait","Job is running..."),!1}})}},function(e){var n="";e&&e.message&&e.message.data&&e.message.data.input&&(n=e.message.data.input+"."),t.state("failed","This visualization requires the Charts-Kit. Please make sure it is installed. "+n),s&&s()})},_loop:function(t,n){var r=this;e.request("GET",config.root+"api/datasets/"+t,{},function(e){n(e)||setTimeout(function(){r._loop(t,n)},r.app.config.get("query_timeout"))})},_refreshHdas:function(){Galaxy&&Galaxy.currHistoryPanel&&Galaxy.currHistoryPanel.refreshHdas()}})}),define("plugin/library/datasets",["utils/utils"],function(e){return Backbone.Collection.extend({list:{},initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},request:function(t,n,r){var i=this;if(t.groups)this._fetch(t,n);else{var s=this.list[t.id];if(s){n(s);return}e.request("GET",config.root+"api/datasets/"+t.id,{},function(e){switch(e.state){case"error":r&&r(e);break;default:i.list[t.id]=e,n(e)}})}},_fetch:function(t,n){var r=t.start?t.start:0,i=Math.abs(t.end-t.start),s=this.app.config.get("query_limit");if(!i||i>s)i=s;var o="",u={},a=0;for(var f in t.groups){var l=t.groups[f];for(var c in l.columns){var h=l.columns[c];o+=h+",",u[h]=a,a++}}if(a==0){n({});return}o=o.substring(0,o.length-1);var p=t.groups;for(var f in p)p[f].values=[];var d=this;e.request("GET",config.root+"api/datasets/"+t.id,{data_type:"raw_data",provider:"dataset-column",limit:i,offset:r,indeces:o},function(e){for(var i in e.data){var s=e.data[i];for(var o in t.groups){var a=t.groups[o],f={x:parseInt(i)+r},l=!1;for(var c in a.columns){var h=a.columns[c],d=u[h],v=s[d];isNaN(v)&&(l=!0),f[c]=v}l||p[o].values.push(f)}}n(t)})}})}),define("plugin/models/group",[],function(){return Backbone.Model.extend({defaults:{key:"Data label",date:""},reset:function(){this.clear({silent:!0}).set(this.defaults),this.trigger("reset",this)}})}),define("plugin/models/groups",["plugin/models/group"],function(e){return Backbone.Collection.extend({model:e})}),define("plugin/library/deferred",["utils/utils"],function(e){return Backbone.Model.extend({queue:[],process:{},counter:0,initialize:function(){this.on("refresh",function(){if(this.counter==0)for(var e in this.queue)this.queue[e](),this.queue.splice(e,1)})},execute:function(e){this.queue.push(e),this.trigger("refresh")},register:function(){var t=e.uuid();return this.process[t]=!0,this.counter++,console.debug("Deferred:register() - Registering "+t),t},done:function(e){delete this.process[e],this.counter--,console.debug("Deferred:done() - Unregistering "+e),this.trigger("refresh")},ready:function(){return this.counter==0?!0:!1}})});var Visualization=Backbone.Model.extend({defaults:{config:{}},urlRoot:function(){var e="/api/visualizations";return window.galaxy_config&&galaxy_config.root?galaxy_config.root+e:e},initialize:function(e){_.isObject(e.config)&&_.isObject(this.defaults.config)&&_.defaults(e.config,this.defaults.config),this._setUpListeners()},_setUpListeners:function(){},set:function(e,t){if(e==="config"){var n=this.get("config");_.isObject(n)&&(t=_.extend(_.clone(n),t))}return Backbone.Model.prototype.set.call(this,e,t),this},toString:function(){var e=this.get("id")||"";return this.get("title")&&(e+=":"+this.get("title")),"Visualization("+e+")"}}),VisualizationCollection=Backbone.Collection.extend({model:Visualization,url:function(){return galaxy_config.root+"api/visualizations"},initialize:function(e,t){t=t||{}},set:function(e,t){var n=this;e=_.map(e,function(e){var t=n.get(e.id);if(!t)return e;var r=t.toJSON();return _.extend(r,e),r}),Backbone.Collection.prototype.set.call(this,e,t)},toString:function(){return["VisualizationCollection(",[this.historyId,this.length].join(),")"].join("")}});define("mvc/visualization/visualization-model",function(){}),define("plugin/models/chart",["plugin/models/groups","plugin/library/deferred","mvc/visualization/visualization-model"],function(e,t){return Backbone.Model.extend({defaults:{id:null,title:"",type:"",date:null,state:"",state_info:"",modified:!1,dataset_id:"",dataset_id_job:""},initialize:function(n){this.groups=new e,this.settings=new Backbone.Model,this.deferred=new t},reset:function(){this.clear({silent:!0}).set(this.defaults),this.groups.reset(),this.settings.clear(),this.trigger("reset",this)},copy:function(e){var t=this;t.clear({silent:!0}).set(this.defaults),t.set(e.attributes),t.settings=e.settings.clone(),t.groups.reset(),e.groups.each(function(e){t.groups.add(e.clone())}),t.trigger("change",t)},state:function(e,t){this.set("state",e),this.set("state_info",t),this.trigger("set:state"),console.debug("Chart:state() - "+t+" ("+e+")")}})}),define("plugin/library/storage",["utils/utils","plugin/models/chart","plugin/models/group"],function(e,t,n){return Backbone.Model.extend({vis:null,initialize:function(e){this.app=e,this.chart=this.app.chart,this.options=this.app.options,this.id=this.options.id,this.vis=new Visualization({type:"charts",config:{dataset_id:this.options.config.dataset_id,chart_dict:{}}}),this.id&&(this.vis.id=this.id);var t=this.options.config.chart_dict;t&&(this.vis.get("config").chart_dict=t)},save:function(){var e=this.app.chart;this.vis.get("config").chart_dict={};var t=e.get("title");t!=""&&this.vis.set("title",t);var n={attributes:e.attributes,settings:e.settings.attributes,groups:[]};e.groups.each(function(e){n.groups.push(e.attributes)}),this.vis.get("config").chart_dict=n;var r=this;this.vis.save().fail(function(e,t,n){console.error(e,t,n)}).then(function(e){e&&e.id&&(r.id=e.id)})},load:function(){var e=this.vis.get("config").chart_dict;if(!e.attributes)return!1;this.chart.set(e.attributes),this.chart.state("ok","Loading saved visualization..."),this.chart.settings.set(e.settings);for(var t in e.groups)this.chart.groups.add(new n(e.groups[t]));return this.chart.set("modified",!1),!0}})}),define("plugin/views/viewport",["mvc/ui/ui-portlet","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(e,t){this.app=e,this.chart=this.app.chart,this.options=n.merge(t,this.optionsDefault),this.setElement($(this._template())),this._fullscreen(this.$el,80),this._create_canvas("div");var r=this;this.chart.on("redraw",function(){r._draw(r.chart)}),this.chart.on("set:state",function(){var e=r.$el.find("#info"),t=e.find("#icon");t.removeClass(),e.show(),e.find("#text").html(r.chart.get("state_info"));var n=r.chart.get("state");switch(n){case"ok":e.hide();break;case"failed":t.addClass("fa fa-warning");break;default:t.addClass("fa fa-spinner fa-spin")}})},show:function(){this.$el.show()},hide:function(){this.$el.hide()},_fullscreen:function(e,t){e.css("height",$(window).height()-t),$(window).resize(function(){e.css("height",$(window).height()-t)})},_create_canvas:function(e){this.canvas&&this.canvas.remove(),this.$el.append($(this._template_canvas(e)));var t=this.$el.find(".canvas");e=="svg"?this.canvas=d3.select(t[0]):this.canvas=t},_draw:function(e){var t=this,n=e.deferred.register(),r=e.get("type");this.chart_settings=this.app.types.get(r),this._create_canvas(this.chart_settings.element),e.state("wait","Please wait...");if(!this.chart_settings.execute||this.chart_settings.execute&&e.get("modified"))this.app.jobs.cleanup(e),e.set("modified",!1);var t=this;require(["plugin/charts/"+r+"/"+r],function(r){var i=new r(t.app,{canvas:t.canvas});t.chart_settings.execute?e.get("dataset_id_job")==""?t.app.jobs.submit(e,t._defaultSettingsString(e),t._defaultRequestString(e),function(){i.draw(n,e,t._defaultRequestDictionary(e))},function(){e.deferred.done(n)}):i.draw(n,e,t._defaultRequestDictionary(e)):i.draw(n,e,t._defaultRequestDictionary(e))})},_defaultRequestString:function(e){var t="",n=0,r=this;return e.groups.each(function(e){for(var i in r.chart_settings.columns)t+=i+"_"+ ++n+":"+(parseInt(e.get(i))+1)+", "}),t.substring(0,t.length-2)},_defaultSettingsString:function(e){var t="";for(key in e.settings.attributes)t+=key+":"+e.settings.get(key)+", ";return t.substring(0,t.length-2)},_defaultRequestDictionary:function(e){var t={groups:[]};this.chart_settings.execute?t.id=e.get("dataset_id_job"):t.id=e.get("dataset_id");var n=0,r=this;return e.groups.each(function(e){var i={};for(var s in r.chart_settings.columns)i[s]=e.get(s);t.groups.push({key:++n+":"+e.get("key"),columns:i})}),t},_template:function(){return'<div style="height: inherit; min-height: 50px;"><div id="info" style="position: absolute; margin-left: 10px; margin-top: 10px; margin-bottom: 50px;"><span id="icon" style="font-size: 1.2em; display: inline-block;"/><span id="text" style="position: relative; margin-left: 5px; top: -1px; font-size: 1.0em;"/></div></div>'},_template_canvas:function(e){return"<"+e+' class="canvas" style="height: 100%;"/>'}})}),define("plugin/views/viewer",["utils/utils","plugin/library/ui","mvc/ui/ui-portlet","plugin/models/group","plugin/views/viewport"],function(e,t,n,r,i){return Backbone.View.extend({initialize:function(e,r){this.app=e,this.chart=this.app.chart,this.viewport_view=new i(e);var s=this;this.portlet=new n.View({icon:"fa-bar-chart-o",title:"Viewport",operations:{edit_button:new t.ButtonIcon({icon:"fa-edit",tooltip:"Customize this chart",title:"Editor",onclick:function(){s._wait(s.chart,function(){s.app.go("editor")})}})}}),this.portlet.append(this.viewport_view.$el),this.setElement(this.portlet.$el);var s=this;this.chart.on("change:title",function(){s._refreshTitle()})},show:function(){this.$el.show(),$(window).trigger("resize")},hide:function(){this.$el.hide()},_refreshTitle:function(){var e=this.chart.get("title");this.portlet.title(e)},_screenshot:function(){var e=new XMLSerializer,t=e.serializeToString(this.viewport_view.svg.node()),n="data:image/svg+xml;base64,"+btoa(t);window.location.href="data:application/x-download/;charset=utf-8,"+encodeURIComponent(t)},_wait:function(e,t){if(e.deferred.ready())t();else{var n=this;this.app.modal.show({title:"Please wait!",body:"Your chart is currently being processed. Please wait and try again.",buttons:{Close:function(){n.app.modal.hide()},Retry:function(){n.app.modal.hide(),setTimeout(function(){n._wait(e,t)},n.app.config.get("query_timeout"))}}})}}})}),define("mvc/ui/ui-tabs",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,list:{},$nav:null,$content:null,first_tab:null,optionsDefault:{title_new:"",operations:null,onnew:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(this.options));this.$nav=n.find(".tab-navigation"),this.$content=n.find(".tab-content"),this.setElement(n),this.list={};var r=this;this.options.operations&&$.each(this.options.operations,function(e,t){t.$el.prop("id",e),r.$nav.find(".operations").append(t.$el)});if(this.options.onnew){var i=$(this._template_tab_new(this.options));this.$nav.append(i),i.tooltip({title:"Add a new tab",placement:"bottom",container:r.$el}),i.on("click",function(e){i.tooltip("hide"),r.options.onnew()})}},add:function(e){var t=e.id,n={$title:$(this._template_tab(e)),$content:$(this._template_tab_content(e)),removable:e.ondel?!0:!1};this.list[t]=n,this.options.onnew?this.$nav.find("#new-tab").before(n.$title):this.$nav.append(n.$title),n.$content.append(e.$el),this.$content.append(n.$content),_.size(this.list)==1&&(n.$title.addClass("active"),n.$content.addClass("active"),this.first_tab=t);if(e.ondel){var r=this,i=n.$title.find("#delete");i.tooltip({title:"Delete this tab",placement:"bottom",container:r.$el}),i.on("click",function(){return i.tooltip("destroy"),r.$el.find(".tooltip").remove(),e.ondel(),!1})}e.onclick&&n.$title.on("click",function(){e.onclick()})},del:function(e){var t=this.list[e];t.$title.remove(),t.$content.remove(),delete t,this.first_tab==e&&(this.first_tab=null),this.first_tab!=null&&this.show(this.first_tab)},delRemovable:function(){for(var e in this.list){var t=this.list[e];t.removable&&this.del(e)}},show:function(e){this.$el.fadeIn("fast"),this.visible=!0,e&&this.list[e].$title.find("a").tab("show")},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},hideOperation:function(e){this.$nav.find("#"+e).hide()},showOperation:function(e){this.$nav.find("#"+e).show()},setOperation:function(e,t){var n=this.$nav.find("#"+e);n.off("click"),n.on("click",t)},title:function(e,t){var n=this.list[e].$title.find("#text");return t&&n.html(t),n.html()},_template:function(e){return'<div class="tabbable tabs-left"><ul class="tab-navigation nav nav-tabs"><div class="operations" style="float: right; margin-bottom: 4px;"></div></ul><div class="tab-content"/></div>'},_template_tab_new:function(e){return'<li id="new-tab"><a href="javascript:void(0);"><i style="font-size: 0.8em; margin-right: 5px;" class="fa fa-plus-circle"/>'+e.title_new+"</a>"+"</li>"},_template_tab:function(e){var t='<li id="title-'+e.id+'">'+'<a title="" href="#tab-'+e.id+'" data-toggle="tab" data-original-title="">'+'<span id="text">'+e.title+"</span>";return e.ondel&&(t+='<i id="delete" style="font-size: 0.8em; margin-left: 5px; cursor: pointer;" class="fa fa-minus-circle"/>'),t+="</a></li>",t},_template_tab_content:function(e){return'<div id="tab-'+e.id+'" class="tab-pane"/>'}});return{View:t}}),define("plugin/library/ui-table",["utils/utils"],function(e){var t=Backbone.View.extend({row:null,row_count:0,optionsDefault:{content:"No content available.",onchange:null,ondblclick:null,onconfirm:null},events:{click:"_onclick",dblclick:"_ondblclick"},first:!0,initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(t));this.$thead=n.find("thead"),this.$tbody=n.find("tbody"),this.$tmessage=n.find("tmessage"),this.setElement(n),this.row=$("<tr></tr>")},addHeader:function(e){var t=$("<th></th>");t.append(e),this.row.append(t)},appendHeader:function(){this.$thead.append(this.row),this.row=$("<tr></tr>")},add:function(e,t,n){var r=$("<td></td>");t&&r.css("width",t),n&&r.css("text-align",n),r.append(e),this.row.append(r)},append:function(e){this._commit(e)},prepend:function(e){this._commit(e,!0)},remove:function(e){var t=this.$tbody.find("#"+e);t.length>0&&(t.remove(),this.row_count--,this._refresh())},removeAll:function(){this.$tbody.html(""),this.row_count=0,this._refresh()},value:function(e){this.before=this.$tbody.find(".current").attr("id"),e!==undefined&&(this.$tbody.find("tr").removeClass("current"),e&&this.$tbody.find("#"+e).addClass("current"));var t=this.$tbody.find(".current").attr("id");return t===undefined?null:(t!=this.before&&this.options.onchange&&this.options.onchange(e),t)},size:function(){return this.$tbody.find("tr").length},_commit:function(e,t){this.remove(e),this.row.attr("id",e),t?this.$tbody.prepend(this.row):this.$tbody.append(this.row),this.row=$("<tr></tr>"),this.row_count++,this._refresh()},_onclick:function(e){var t=this.value(),n=$(e.target).closest("tr").attr("id");n&&t!=n&&(this.options.onconfirm?this.options.onconfirm(n):this.value(n))},_ondblclick:function(e){var t=this.value();t&&this.options.ondblclick&&this.options.ondblclick(t)},_refresh:function(){this.row_count==0?this.$tmessage.show():this.$tmessage.hide()},_template:function(e){return'<div><table class="grid"><thead></thead><tbody style="cursor: pointer;"></tbody></table><tmessage>'+e.content+"</tmessage>"+"<div>"}});return{View:t}}),define("plugin/views/group",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({columns:[],initialize:function(r,i){this.app=r;var s=this;this.chart=this.app.chart,this.group=i.group,this.group_key=new t.Input({placeholder:"Data label",onchange:function(){s.group.set("key",s.group_key.value())}}),this.table=new e.View({content:"No data column."});var o=$("<div/>");o.append(n.wrap((new t.Label({title:"Provide a label:"})).$el)),o.append(n.wrap(this.group_key.$el)),o.append(n.wrap((new t.Label({title:"Select columns:"})).$el)),o.append(n.wrap(this.table.$el)),this.setElement(o);var s=this;this.chart.on("change:dataset_id",function(){s._refreshTable()}),this.chart.on("change:type",function(){s._refreshTable()}),this.group.on("change:key",function(){s._refreshGroupKey()}),this.group.on("change",function(){s._refreshGroup()}),this._refreshTable(),this._refreshGroupKey(),this._refreshGroup()},_refreshTable:function(){var e=this.chart.get("dataset_id"),n=this.chart.get("type");if(!e||!n)return;var r=this,i=this.app.types.get(n);this.table.removeAll();var s={};for(var o in i.columns){var u=this.group.get(o);u||this.group.set(o,0);var a=i.columns[o],f=new t.Select.View({id:"select_"+o,gid:o,onchange:function(e){r.group.set(this.gid,e),r.chart.set("modified",!0)},value:u,wait:!0});this.table.add(a.title,"25%"),this.table.add(f.$el),this.table.append(o),s[o]=f}this.chart.state("wait","Loading metadata...");var l=this.chart.deferred.register();this.app.datasets.request({id:e},function(e){r.columns=[];var t=e.metadata_column_types;for(var n in t)(t[n]=="int"||t[n]=="float")&&r.columns.push({label:"Column: "+(parseInt(n)+1)+" ["+t[n]+"]",value:n});for(var n in s)s[n].update(r.columns),s[n].show();r.chart.state("wait","Metadata initialized..."),r.chart.deferred.done(l)})},_refreshGroup:function(){this.group.set("date",n.time())},_refreshGroupKey:function(){var e=this.group.get("key");e===undefined&&(e=""),this.group_key.value(e)}})}),define("plugin/library/ui-table-form",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){var r=Backbone.View.extend({list:[],initialize:function(r){this.table_title=new t.Label({title:r.title}),this.table=new e.View({content:r.content});var i=$("<div/>");i.append(n.wrap(this.table_title.$el)),i.append(n.wrap(this.table.$el)),this.setElement(i)},title:function(e){this.table_title.title(e)},update:function(e,t){this.table.removeAll(),this.list=[];for(var n in e)this._add(n,e[n],t);for(var n in this.list){var r=this.list[n].options.onchange;r&&r()}},_add:function(e,n,r){var i=this,s=null,o=n.type;switch(o){case"text":s=new t.Input({id:e,placeholder:n.placeholder,onchange:function(){r.set(e,s.value())}});break;case"select":s=new t.Select.View({id:e,data:n.data,onchange:function(){var t=s.value();r.set(e,t);var o=_.findWhere(n.data,{value:t});o&&(o.show&&i.$el.find("#"+o.show).fadeIn("fast"),o.hide&&i.$el.find("#"+o.hide).fadeOut("fast"))}});break;case"separator":s=$("<div/>");break;default:console.log("ui-table-form:_add","Unknown setting type ("+n.type+")");return}if(o!="separator"){r.get(e)||r.set(e,n.init),s.value(r.get(e)),this.list[e]=s;var u=$("<div/>");u.append(s.$el),u.append('<div class="toolParamHelp" style="font-size: 0.9em;">'+n.info+"</div>"),this.table.add('<span style="white-space: nowrap;">'+n.title+"</span>","25%"),this.table.add(u)}else this.table.add('<h6 style="white-space: nowrap;">'+n.title+":<h6/>"),this.table.add($("<div/>"));this.table.append(e)}});return{View:r}}),define("plugin/views/settings",["plugin/library/ui","plugin/library/ui-table-form","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(e,n){this.app=e;var r=this;this.chart=this.app.chart,this.form=new t.View({title:"Chart options:",content:"This chart type does not provide any options."}),this.setElement(this.form.$el);var r=this;this.chart.on("change",function(){r._refreshTable()})},_refreshTable:function(){var e=this.chart.get("type");if(!e)return;var t=this.app.types.get(e);this.form.title(t.title+":"),this.form.update(t.settings,this.chart.settings)}})}),define("plugin/views/editor",["mvc/ui/ui-tabs","plugin/library/ui-table","plugin/library/ui","mvc/ui/ui-portlet","utils/utils","plugin/models/chart","plugin/models/group","plugin/views/group","plugin/views/settings"],function(e,t,n,r,i,s,o,u,a){return Backbone.View.extend({optionsDefault:{header:!0,content:"No content available."},initialize:function(s,o){var u=this;this.app=s,this.chart=this.app.chart,this.options=i.merge(o,this.optionsDefault),this.portlet=new r.View({icon:"fa-bar-chart-o",title:"Editor",operations:{save:new n.ButtonIcon({icon:"fa-save",tooltip:"Draw Chart",title:"Draw",onclick:function(){u.app.go("viewer"),u._saveChart()}}),back:new n.ButtonIcon({icon:"fa-caret-left",tooltip:"Return to Viewer",title:"Return",onclick:function(){u.app.go("viewer"),u.app.storage.load()}})}}),this.table=new t.View({header:!1,onchange:function(e){u.chart.settings.clear(),u.chart.set({type:e}),u.chart.set("modified",!0)},ondblclick:function(e){u.tabs.show("settings")},content:"No chart types available"}),this.table.addHeader("No."),this.table.addHeader("Type"),this.table.addHeader("Library"),this.table.addHeader("Processing*"),this.table.appendHeader();var f=0,l=s.types.attributes;for(var c in l){var h=l[c];this.table.add(++f+"."),this.table.add(h.title),this.table.add(h.library,"10%"),h.execute?this.table.add((new n.Icon({icon:"fa-check"})).$el,"10%","center"):this.table.add(""),this.table.append(c)}this.tabs=new e.View({title_new:"Add Data",onnew:function(){var e=u._addGroupModel();u.tabs.show(e.id)}}),this.title=new n.Input({placeholder:"Chart title",onchange:function(){u.chart.set("title",u.title.value())}});var p=$("<div/>");p.append(i.wrap((new n.Label({title:"Provide a chart title:"})).$el)),p.append(i.wrap(this.title.$el)),p.append(i.wrap((new n.Label({title:"Select a chart type:"})).$el)),p.append(i.wrap(this.table.$el)),p.append((new n.Text({title:"*Certain chart types pre-process data before rendering the visualization. The pre-processing is done using the chartskit available in the Toolshed.",cls:"toolParamHelp"})).$el),this.tabs.add({id:"main",title:"Start",$el:p}),this.settings=new a(this.app),this.tabs.add({id:"settings",title:"Configuration",$el:this.settings.$el}),this.portlet.append(this.tabs.$el),this.setElement(this.portlet.$el),this.tabs.hideOperation("back");var u=this;this.chart.on("change:title",function(e){u._refreshTitle()}),this.chart.on("change:type",function(e){u.table.value(e.get("type"))}),this.chart.on("reset",function(e){u._resetChart()}),this.app.chart.on("redraw",function(e){u.portlet.showOperation("back")}),this.app.chart.groups.on("add",function(e){u._addGroup(e)}),this.app.chart.groups.on("remove",function(e){u._removeGroup(e)}),this.app.chart.groups.on("reset",function(e){u._removeAllGroups()}),this.app.chart.groups.on("change:key",function(e){u._refreshGroupKey()}),this._resetChart()},show:function(){this.$el.show()},hide:function(){this.$el.hide()},_refreshTitle:function(){var e=this.chart.get("title");this.portlet.title(e),this.title.value(e)},_refreshGroupKey:function(){var e=this,t=0;this.chart.groups.each(function(n){var r=n.get("key","");r==""&&(r="Chart data"),e.tabs.title(n.id,++t+": "+r)})},_addGroupModel:function(){var e=new o({id:i.uuid()});return this.chart.groups.add(e),e},_addGroup:function(e){var t=this,n=new u(this.app,{group:e}),r=t.chart.groups.length;this.tabs.add({id:e.id,$el:n.$el,ondel:function(){t.chart.groups.remove(e.id)}}),this._refreshGroupKey()},_removeGroup:function(e){this.tabs.del(e.id),this._refreshGroupKey(),this.chart.set("modified",!0)},_removeAllGroups:function(e){this.tabs.delRemovable()},_resetChart:function(){this.chart.set("id",i.uuid()),this.chart.set("type","nvd3_bardiagram"),this.chart.set("dataset_id",this.app.options.config.dataset_id),this.chart.set("title","New Chart"),this.portlet.hideOperation("back")},_saveChart:function(){this.chart.set({type:this.table.value(),title:this.title.value(),date:i.time()}),this.chart.groups.length==0&&this._addGroupModel();var e=this;this.chart.deferred.execute(function(){e.app.storage.save(),e.chart.trigger("redraw")})}})}),define("plugin/models/config",[],function(){return Backbone.Model.extend({defaults:{query_limit:1e3,query_timeout:500}})}),define("plugin/charts/nvd3/config",[],function(){return{title:"",library:"nvd3.js",element:"svg",columns:{y:{title:"Values for y-axis"}},settings:{separator_label:{title:"X axis",type:"separator"},x_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"X-axis",placeholder:"Axis label"},x_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"auto",data:[{label:"-- Do not show values --",value:"hide",hide:"x_axis_tick"},{label:"Auto",value:"auto",hide:"x_axis_tick"},{label:"Float",value:"f",show:"x_axis_tick"},{label:"Exponent",value:"e",show:"x_axis_tick"},{label:"Integer",value:"d",hide:"x_axis_tick"},{label:"Percentage",value:"p",show:"x_axis_tick"},{label:"Rounded",value:"r",show:"x_axis_tick"},{label:"SI-prefix",value:"s",show:"x_axis_tick"}]},x_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_tick:{title:"Y axis",type:"separator"},y_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"Y-axis",placeholder:"Axis label"},y_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"auto",data:[{label:"-- Do not show values --",value:"hide",hide:"y_axis_tick"},{label:"Auto",value:"auto",hide:"y_axis_tick"},{label:"Float",value:"f",show:"y_axis_tick"},{label:"Exponent",value:"e",show:"y_axis_tick"},{label:"Integer",value:"d",hide:"y_axis_tick"},{label:"Percentage",value:"p",show:"y_axis_tick"},{label:"Rounded",value:"r",show:"y_axis_tick"},{label:"SI-prefix",value:"s",show:"y_axis_tick"}]},y_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_legend:{title:"Others",type:"separator"},show_legend:{title:"Show legend",info:"Would you like to add a legend?",type:"select",init:"true",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]}}}}),define("plugin/charts/nvd3_bardiagram/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram"})}),define("plugin/charts/nvd3_histogram/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Histogram",execute:"histogram",columns:{y:{title:"Observations"}},settings:{x_axis_label:{init:"Breaks"},y_axis_label:{init:"Density"}}})}),define("plugin/charts/nvd3_horizontal/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram (horizontal)",settings:{x_axis_type:{init:"hide"}}})}),define("plugin/charts/nvd3_line/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line chart"})}),define("plugin/charts/nvd3_linewithfocus/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line with focus"})}),define("plugin/charts/nvd3_piechart/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Pie chart"})}),define("plugin/charts/nvd3_scatterplot/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Scatter plot",columns:{x:{title:"Values for x-axis"}}})}),define("plugin/charts/nvd3_stackedarea/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Stacked area"})}),define("plugin/charts/highcharts_boxplot/config",[],function(){return{title:"Box plot",library:"highcharts.js",element:"div",execute:"boxplot",columns:{y:{title:"Observations"}},settings:{separator_label:{title:"X axis",type:"separator"},x_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"X-axis",placeholder:"Axis label"},separator_tick:{title:"Y axis",type:"separator"},y_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"Y-axis",placeholder:"Axis label"}}}}),define("plugin/charts/types",["plugin/charts/nvd3_bardiagram/config","plugin/charts/nvd3_histogram/config","plugin/charts/nvd3_horizontal/config","plugin/charts/nvd3_line/config","plugin/charts/nvd3_linewithfocus/config","plugin/charts/nvd3_piechart/config","plugin/charts/nvd3_scatterplot/config","plugin/charts/nvd3_stackedarea/config","plugin/charts/highcharts_boxplot/config"],function(e,t,n,r,i,s,o,u,a){return Backbone.Model.extend({defaults:{nvd3_bardiagram:e,nvd3_horizontal:n,nvd3_histogram:t,nvd3_line:r,nvd3_linewithfocus:i,nvd3_piechart:s,nvd3_scatterplot:o,nvd3_stackedarea:u,highcharts_boxplot:a}})}),define("plugin/app",["mvc/ui/ui-modal","mvc/ui/ui-portlet","plugin/library/ui","utils/utils","plugin/library/jobs","plugin/library/datasets","plugin/library/storage","plugin/views/viewer","plugin/views/editor","plugin/models/config","plugin/models/chart","plugin/charts/types"],function(e,t,n,r,i,s,o,u,a,f,l,c){return Backbone.View.extend({initialize:function(t){this.options=t,Galaxy&&Galaxy.modal?this.modal=Galaxy.modal:this.modal=new e.View,this.config=new f,this.types=new c,this.chart=new l,this.jobs=new i(this),this.datasets=new s(this),this.storage=new o(this),this.viewer_view=new u(this),this.editor_view=new a(this),this.$el.append(this.viewer_view.$el),this.$el.append(this.editor_view.$el),this.$el.css("height","inherit");if(!this.storage.load())this.go("editor");else{this.go("viewer");var n=this;this.chart.deferred.execute(function(){n.chart.trigger("redraw")})}},go:function(e){$(".tooltip").hide();switch(e){case"editor":this.editor_view.show(),this.viewer_view.hide();break;case"viewer":this.editor_view.hide(),this.viewer_view.show()}},execute:function(e){},onunload:function(){},log:function(e,t){console.log(e+" "+t)}})});
\ No newline at end of file
diff -r f0651cd048cb4ba8a472361d9e7cc8413d9dcd2b -r b887ef428f8f99685878df3cfe61531e3b4a26a2 config/plugins/visualizations/charts/static/charts/highcharts_boxplot/highcharts_boxplot.js
--- a/config/plugins/visualizations/charts/static/charts/highcharts_boxplot/highcharts_boxplot.js
+++ b/config/plugins/visualizations/charts/static/charts/highcharts_boxplot/highcharts_boxplot.js
@@ -104,7 +104,7 @@
// update data
self.hc_config.series[0].data = data;
-
+
// draw plot
self.options.canvas.highcharts(self.hc_config);
diff -r f0651cd048cb4ba8a472361d9e7cc8413d9dcd2b -r b887ef428f8f99685878df3cfe61531e3b4a26a2 config/plugins/visualizations/charts/static/library/datasets.js
--- a/config/plugins/visualizations/charts/static/library/datasets.js
+++ b/config/plugins/visualizations/charts/static/library/datasets.js
@@ -118,6 +118,7 @@
};
// fill value
+ var skip = false;
for (var key in group.columns) {
// get column
var column = group.columns[key];
@@ -127,8 +128,8 @@
// read value from row
var v = row[index];
- if(isNaN(v) || !v) {
- v = 0;
+ if(isNaN(v)) {
+ skip = true;
}
// add value to dictionary
@@ -136,7 +137,9 @@
}
// add to result
- result[j].values.push(value);
+ if (!skip) {
+ result[j].values.push(value);
+ }
}
}
diff -r f0651cd048cb4ba8a472361d9e7cc8413d9dcd2b -r b887ef428f8f99685878df3cfe61531e3b4a26a2 config/plugins/visualizations/charts/static/library/jobs.js
--- a/config/plugins/visualizations/charts/static/library/jobs.js
+++ b/config/plugins/visualizations/charts/static/library/jobs.js
@@ -120,6 +120,7 @@
if (response && response.message && response.message.data && response.message.data.input) {
message = response.message.data.input + '.';
}
+
// update state
chart.state('failed', 'This visualization requires the Charts-Kit. Please make sure it is installed. ' + message);
diff -r f0651cd048cb4ba8a472361d9e7cc8413d9dcd2b -r b887ef428f8f99685878df3cfe61531e3b4a26a2 config/plugins/visualizations/charts/static/views/editor.js
--- a/config/plugins/visualizations/charts/static/views/editor.js
+++ b/config/plugins/visualizations/charts/static/views/editor.js
@@ -65,38 +65,15 @@
//
this.table = new Table.View({
header : false,
- onconfirm : function(type) {
- if (self.chart.groups.length > 0) {
- // show modal
- self.app.modal.show({
- title : 'Switching to another chart type?',
- body : 'If you continue your settings and selections will be cleared.',
- buttons : {
- 'Cancel' : function() {
- // hide modal
- self.app.modal.hide();
- },
- 'Continue' : function() {
- // hide modal
- self.app.modal.hide();
-
- // confirm
- self.table.value(type);
- }
- }
- });
- } else {
- // confirm
- self.table.value(type);
- }
- },
onchange : function(type) {
// reset type relevant chart content
- self.chart.groups.reset();
self.chart.settings.clear();
// update chart type
self.chart.set({type: type});
+
+ // set modified flag
+ self.chart.set('modified', true);
},
ondblclick : function(chart_id) {
self.tabs.show('settings');
diff -r f0651cd048cb4ba8a472361d9e7cc8413d9dcd2b -r b887ef428f8f99685878df3cfe61531e3b4a26a2 config/plugins/visualizations/charts/static/views/viewer.js
--- a/config/plugins/visualizations/charts/static/views/viewer.js
+++ b/config/plugins/visualizations/charts/static/views/viewer.js
@@ -29,7 +29,7 @@
edit_button: new Ui.ButtonIcon({
icon : 'fa-edit',
tooltip : 'Customize this chart',
- title : 'Customize',
+ title : 'Editor',
onclick : function() {
// attempt to load chart editor
self._wait (self.chart, function() {
diff -r f0651cd048cb4ba8a472361d9e7cc8413d9dcd2b -r b887ef428f8f99685878df3cfe61531e3b4a26a2 config/plugins/visualizations/charts/static/views/viewport.js
--- a/config/plugins/visualizations/charts/static/views/viewport.js
+++ b/config/plugins/visualizations/charts/static/views/viewport.js
@@ -3,11 +3,9 @@
function(Portlet, Ui, Utils) {
// widget
-return Backbone.View.extend(
-{
+return Backbone.View.extend({
// initialize
- initialize: function(app, options)
- {
+ initialize: function(app, options) {
// link app
this.app = app;
@@ -20,6 +18,9 @@
// create element
this.setElement($(this._template()));
+ // use full screen for viewer
+ this._fullscreen(this.$el, 80);
+
// create canvas element
this._create_canvas('div');
@@ -69,6 +70,17 @@
this.$el.hide();
},
+ // resize to fullscreen
+ _fullscreen: function($el, margin) {
+ // fix size
+ $el.css('height', $(window).height() - margin);
+
+ // catch window resize event
+ $(window).resize(function () {
+ $el.css('height', $(window).height() - margin);
+ });
+ },
+
// create
_create_canvas: function(element) {
// clear canvas
@@ -219,7 +231,7 @@
// template
_template: function() {
- return '<div style="height: 100%; min-height: 50px;">' +
+ return '<div style="height: inherit; min-height: 50px;">' +
'<div id="info" style="position: absolute; margin-left: 10px; margin-top: 10px; margin-bottom: 50px;">' +
'<span id="icon" style="font-size: 1.2em; display: inline-block;"/>' +
'<span id="text" style="position: relative; margin-left: 5px; top: -1px; font-size: 1.0em;"/>' +
@@ -229,7 +241,7 @@
// template svg/div element
_template_canvas: function(element) {
- return '<' + element + ' class="canvas" style="height: calc(100% - 80px)"/>';
+ return '<' + element + ' class="canvas" style="height: 100%;"/>';
}
});
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: dan: Improve handling of invalid/expired GenomeSpace tokens in GenomeSpace export tool.
by commits-noreply@bitbucket.org 09 Apr '14
by commits-noreply@bitbucket.org 09 Apr '14
09 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/f0651cd048cb/
Changeset: f0651cd048cb
User: dan
Date: 2014-04-09 23:24:56
Summary: Improve handling of invalid/expired GenomeSpace tokens in GenomeSpace export tool.
Affected #: 2 files
diff -r 63a81f21363325ebbefc321350315804b15bc79e -r f0651cd048cb4ba8a472361d9e7cc8413d9dcd2b tools/genomespace/genomespace_exporter.py
--- a/tools/genomespace/genomespace_exporter.py
+++ b/tools/genomespace/genomespace_exporter.py
@@ -11,6 +11,7 @@
import os
import urllib
import urllib2
+from urlparse import urljoin
log = logging.getLogger( "tools.genomespace.genomespace_exporter" )#( __name__ )
@@ -117,7 +118,7 @@
break
return webtools
-def galaxy_code_get_genomespace_folders( genomespace_site='prod', trans=None, value=None, **kwd ):
+def galaxy_code_get_genomespace_folders( genomespace_site='prod', trans=None, value=None, base_url=None, **kwd ):
if value:
value = value[0]#single select, only 1 value
def recurse_directory_dict( url_opener, cur_options, url ):
@@ -142,19 +143,19 @@
if trans and trans.user:
username = trans.user.preferences.get( 'genomespace_username', None )
token = trans.user.preferences.get( 'genomespace_token', None )
- if None in ( username, token ):
- return []
- url_opener = get_cookie_opener( username, token )
- genomespace_site_dict = get_genomespace_site_urls()[ genomespace_site ]
- dm_url = genomespace_site_dict['dmServer']
- #get export root directory
- #directory_dict = get_default_directory( url_opener, dm_url ).get( 'directory', None ) #This directory contains shares and other items outside of the users home
- directory_dict = get_personal_directory( url_opener, dm_url ).get( 'directory', None ) #Limit export list to only user's home dir
- if directory_dict is None:
- return []
- #what directory to stuff this in
- recurse_directory_dict( url_opener, rval, directory_dict.get( 'url' ) )
-
+ if None not in ( username, token ):
+ url_opener = get_cookie_opener( username, token )
+ genomespace_site_dict = get_genomespace_site_urls()[ genomespace_site ]
+ dm_url = genomespace_site_dict['dmServer']
+ #get export root directory
+ #directory_dict = get_default_directory( url_opener, dm_url ).get( 'directory', None ) #This directory contains shares and other items outside of the users home
+ directory_dict = get_personal_directory( url_opener, dm_url ).get( 'directory', None ) #Limit export list to only user's home dir
+ if directory_dict is not None:
+ recurse_directory_dict( url_opener, rval, directory_dict.get( 'url' ) )
+ if not rval:
+ if not base_url:
+ base_url = '..'
+ rval = [ { 'name':'Your GenomeSpace token appears to be <strong>expired</strong>, please <a href="%s">reauthenticate</a>.' % ( urljoin( base_url, 'user/openid_auth?openid_provider=genomespace&auto_associate=True' ) ), 'value': '', 'options':[], 'selected': False } ]
return rval
diff -r 63a81f21363325ebbefc321350315804b15bc79e -r f0651cd048cb4ba8a472361d9e7cc8413d9dcd2b tools/genomespace/genomespace_exporter.xml
--- a/tools/genomespace/genomespace_exporter.xml
+++ b/tools/genomespace/genomespace_exporter.xml
@@ -35,14 +35,18 @@
<inputs><param format="data" name="input1" type="data" label="Send this dataset to GenomeSpace" /><param name="base_url" type="baseurl" />
- <param name="subdirectory" type="drill_down" display="radio" hierarchy="exact" multiple="False" optional="True" label="Choose Target Directory" dynamic_options="galaxy_code_get_genomespace_folders( genomespace_site = 'prod', trans=__trans__, value=__value__, input_dataset=input1 )" help="Leave blank to generate automatically"/>
+ <param name="subdirectory" type="drill_down" display="radio" hierarchy="exact" multiple="False" optional="True" label="Choose Target Directory" dynamic_options="galaxy_code_get_genomespace_folders( genomespace_site = 'prod', trans=__trans__, value=__value__, input_dataset=input1, base_url=base_url )" help="Leave blank to generate automatically"/><param name="filename" type="text" size="80" help="Leave blank to generate automatically" /></inputs><outputs><data format="html" name="output_log" /></outputs><help>
- This Tool allows you to export data to GenomeSpace. You must have logged in using your GenomeSpace OpenID. You can associate your OpenID credentials under the User Preferences panel.
+This Tool allows you to export data to GenomeSpace. You must have logged in using your GenomeSpace OpenID. You can associate your OpenID credentials under the User Preferences panel.
+
+If you are having trouble with this tool, click here_ to refresh your GenomeSpace token before reporting errors.
+
+.. _here: ${static_path}/../user/openid_auth?openid_provider=genomespace&auto_associate=True
</help><options refresh="True"/><code file="genomespace_exporter.py" />
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: Metrics API: allow posting of metrics sending to app.trace_logger.log if available
by commits-noreply@bitbucket.org 09 Apr '14
by commits-noreply@bitbucket.org 09 Apr '14
09 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/63a81f213633/
Changeset: 63a81f213633
User: carlfeberhard
Date: 2014-04-09 22:15:00
Summary: Metrics API: allow posting of metrics sending to app.trace_logger.log if available
Affected #: 2 files
diff -r fbe5f3970ac2f1fe32710a4962a175de7264c2be -r 63a81f21363325ebbefc321350315804b15bc79e lib/galaxy/webapps/galaxy/api/metrics.py
--- /dev/null
+++ b/lib/galaxy/webapps/galaxy/api/metrics.py
@@ -0,0 +1,131 @@
+"""
+API operations for for querying and recording user metrics from some client
+(typically a user's browser).
+"""
+#TODO: facade or adapter to fluentd
+
+import datetime
+
+from galaxy import exceptions
+from galaxy import web
+from galaxy.web import require_admin
+from galaxy.web import _future_expose_api as expose_api
+from galaxy.web import _future_expose_api_anonymous as expose_api_anonymous
+
+from galaxy.web.base.controller import BaseAPIController
+
+from galaxy.util import json
+
+import logging
+log = logging.getLogger( __name__ )
+
+
+class MetricsController( BaseAPIController ):
+
+ def __init__( self, app ):
+ super( MetricsController, self ).__init__( app )
+ #: set to true to send additional debugging info to the log
+ self.debugging = True
+
+ #def _decode_id( self, trans, id ):
+ # try:
+ # return trans.security.decode_id( id )
+ # except:
+ # raise exceptions.MalformedId( "Malformed id ( %s ) specified, unable to decode"
+ # % ( str( id ) ), type='error' )
+
+ def _deserialize_isoformat_date( self, datestring ):
+ """
+ Convert ISO formatted date string into python datetime.
+ """
+ return datetime.datetime.strptime( datestring, "%Y-%m-%dT%H:%M:%S.%fZ" )
+
+ #@expose_api
+ #@require_admin
+ #def index( self, trans, **kwd ):
+ # """
+ # """
+ # returned = []
+ # return returned
+
+ #@expose_api
+ #@require_admin
+ #def show( self, trans, id, **kwd ):
+ # """
+ # """
+ # returned = {}
+ # return returned
+
+ @expose_api_anonymous
+ def create( self, trans, payload, **kwd ):
+ """
+ create( trans, payload )
+ * POST /api/metrics:
+ record any metrics sent and return some status object
+
+ .. note:: Anonymous users can post metrics
+
+ :type payload: dict
+ :param payload: (optional) dictionary structure containing:
+ * metrics: a list containing dictionaries of the form:
+ ** namespace: label indicating the source of the metric
+ ** time: isoformat datetime when the metric was recorded
+ ** level: an integer representing the metric's log level
+ ** args: a json string containing an array of extra data
+
+ :rtype: dict
+ :returns: status object
+ """
+ user_id = trans.user.id if trans.user else None
+ session_id = trans.galaxy_session.id if trans.galaxy_session else None
+ parsed_gen = self._parse_metrics( payload.get( 'metrics', None ), user_id, session_id )
+ self._send_metrics( trans, parsed_gen )
+ response = self._get_server_pong( trans )
+ return response
+
+ #TODO: move the following to DAO/Manager object
+ def _parse_metrics( self, metrics, user_id=None, session_id=None ):
+ """
+ Return a generator yielding the each given metric as a tuple:
+ * label: the namespace of the metric
+ * time: datetime of the metric's creation
+ * kwargs: a dictionary containing:
+ ** level: the log level of the metric
+ ** user: the user associated with the metric
+ (will be None if anonymous user)
+ ** session: the session of the current user
+ """
+ metrics = metrics or []
+ for metric in metrics:
+ label = metric[ 'namespace' ]
+ time = self._deserialize_isoformat_date( metric[ 'time' ] )
+ kwargs = {
+ 'level' : metric[ 'level' ],
+ 'args' : json.from_json_string( metric[ 'args' ] ),
+ 'user' : user_id,
+ 'session' : session_id
+ }
+ yield ( label, time, kwargs )
+
+ def _send_metrics( self, trans, metrics ):
+ """
+ Send metrics to the app's `trace_logger` if set and
+ send to `log.debug` if this controller if `self.debugging`.
+
+ Precondition: metrics are parsed and in proper format.
+ """
+ if trans.app.trace_logger:
+ for label, time, kwargs in metrics:
+ trans.app.trace_logger.log( label, time=int( time ), **kwargs )
+ elif self.debugging:
+ for label, time, kwargs in metrics:
+ log.debug( '%s %s %s', label, time, kwargs )
+
+ def _get_server_pong( self, trans ):
+ """
+ Return some status message or object.
+
+ For future use.
+ """
+ return {}
+
diff -r fbe5f3970ac2f1fe32710a4962a175de7264c2be -r 63a81f21363325ebbefc321350315804b15bc79e lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -304,10 +304,22 @@
new={ 'install_repository_revision' : 'POST' },
parent_resources=dict( member_name='tool_shed_repository', collection_name='tool_shed_repositories' ) )
+
+ # ==== Trace/Metrics Logger
# Connect logger from app
if app.trace_logger:
webapp.trace_logger = app.trace_logger
+ # metrics logging API
+ #webapp.mapper.connect( "index", "/api/metrics",
+ # controller="metrics", action="index", conditions=dict( method=["GET"] ) )
+ #webapp.mapper.connect( "show", "/api/metrics/{id}",
+ # controller="metrics", action="show", conditions=dict( method=["GET"] ) )
+ webapp.mapper.connect( "create", "/api/metrics",
+ controller="metrics", action="create", conditions=dict( method=["POST"] ) )
+
+
+ # ==== Done
# Indicate that all configuration settings have been provided
webapp.finalize_config()
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
3 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/6a85e1496b98/
Changeset: 6a85e1496b98
Branch: next-stable
User: Jeremy Goecks
Date: 2014-04-09 16:47:22
Summary: Genome data provider: (a) handle regions with no mapped reads and (b) clean up trailing whitespace.
Affected #: 1 file
diff -r 44f5b4a2091bc6e552e0c79a0a761cfc8759a36f -r 6a85e1496b98ac05cdfff0b6940877c19bc37cd8 lib/galaxy/visualization/data_providers/genome.py
--- a/lib/galaxy/visualization/data_providers/genome.py
+++ b/lib/galaxy/visualization/data_providers/genome.py
@@ -965,18 +965,23 @@
# -- Choose iterator. --
# Calculate threshold for non-sequential iterators based on mean_depth and read length.
- first_read = next( iterator )
+ try:
+ first_read = next( iterator )
+ except StopIteration:
+ # no reads.
+ return { 'data': [], 'message': None, 'max_low': start, 'max_high': start }
+
read_len = len( first_read.seq )
num_reads = ( end - start ) * mean_depth / float ( read_len )
threshold = float( max_vals )/ num_reads
iterator = itertools.chain( iter( [ first_read ] ), iterator )
# Use specified iterator type, save for when threshold is >= 1.
- # A threshold of >= 1 indicates all reads are to be returned, so no
+ # A threshold of >= 1 indicates all reads are to be returned, so no
# sampling needed and seqential iterator will be used.
if iterator_type == 'sequential' or threshold >= 1:
read_iterator = iterator
- elif iterator_type == 'random':
+ elif iterator_type == 'random':
read_iterator = _random_read_iterator( iterator, threshold )
elif iterator_type == 'nth':
read_iterator = _nth_read_iterator( iterator, threshold )
https://bitbucket.org/galaxy/galaxy-central/commits/376ffdb91bd1/
Changeset: 376ffdb91bd1
Branch: next-stable
User: Jeremy Goecks
Date: 2014-04-09 18:53:34
Summary: SAM/BAM data provider: fix bug and streamline code to support both genomes with reference data and those without.
Affected #: 1 file
diff -r 6a85e1496b98ac05cdfff0b6940877c19bc37cd8 -r 376ffdb91bd1c1a7881e72c5cb6da8dea0e0534f lib/galaxy/visualization/data_providers/genome.py
--- a/lib/galaxy/visualization/data_providers/genome.py
+++ b/lib/galaxy/visualization/data_providers/genome.py
@@ -1063,45 +1063,48 @@
# Clean up. TODO: is this needed? If so, we'll need a cleanup function after processing the data.
# bamfile.close()
- # If there are results and reference data, transform read sequence and cigar.
- if len( results ) != 0 and ref_seq:
- def process_read( read, start_field, cigar_field, seq_field ):
- '''
- Process a read using the designated fields.
- '''
- read_seq, read_cigar = get_ref_based_read_seq_and_cigar( read[ seq_field ].upper(),
- read[ start_field ],
- ref_seq,
- start,
- read[ cigar_field ] )
- read[ seq_field ] = read_seq
- read[ cigar_field ] = read_cigar
+ def compress_seq_and_cigar( read, start_field, cigar_field, seq_field ):
+ '''
+ Use reference-based compression to compress read sequence and cigar.
+ '''
+ read_seq, read_cigar = get_ref_based_read_seq_and_cigar( read[ seq_field ].upper(),
+ read[ start_field ],
+ ref_seq,
+ start,
+ read[ cigar_field ] )
+ read[ seq_field ] = read_seq
+ read[ cigar_field ] = read_cigar
- def process_se_read( read ):
- '''
- Process single-end read.
- '''
- process_read( read, 1, 4, 6)
+ def convert_cigar( read, start_field, cigar_field, seq_field ):
+ '''
+ Convert read cigar from pysam format to string format.
+ '''
+ cigar_ops = 'MIDNSHP=X'
+ read_cigar = ''
+ for op_tuple in read[ cigar_field ]:
+ read_cigar += '%i%s' % ( op_tuple[1], cigar_ops[ op_tuple[0] ] )
+ read[ cigar_field ] = read_cigar
- def process_pe_read( read ):
- '''
- Process paired-end read.
- '''
+ # Choose method for processing reads. Use reference-based compression
+ # if possible. Otherwise, convert cigar.
+ if ref_seq:
+ # Uppercase for easy comparison.
+ ref_seq = ref_seq.upper()
+ process_read = compress_seq_and_cigar
+ else:
+ process_read = convert_cigar
+
+ # Process reads.
+ for read in results:
+ if isinstance( read[ 5 ], list ):
+ # Paired-end read.
if len( read[4] ) > 2:
process_read( read[4], 0, 2, 4 )
if len( read[5] ) > 2:
process_read( read[5], 0, 2, 4 )
-
- # Uppercase for easy comparison.
- ref_seq = ref_seq.upper()
-
- # Process reads.
- for read in results:
- # Use correct function for processing reads.
- if isinstance( read[ 5 ], list ):
- process_pe_read( read )
- else:
- process_se_read( read )
+ else:
+ # Single-end read.
+ process_read( read, 1, 4, 6)
max_low, max_high = get_bounds( results, 1, 2 )
https://bitbucket.org/galaxy/galaxy-central/commits/fbe5f3970ac2/
Changeset: fbe5f3970ac2
User: Jeremy Goecks
Date: 2014-04-09 18:53:57
Summary: Automated merge of next-stable to default.
Affected #: 1 file
diff -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 -r fbe5f3970ac2f1fe32710a4962a175de7264c2be lib/galaxy/visualization/data_providers/genome.py
--- a/lib/galaxy/visualization/data_providers/genome.py
+++ b/lib/galaxy/visualization/data_providers/genome.py
@@ -965,18 +965,23 @@
# -- Choose iterator. --
# Calculate threshold for non-sequential iterators based on mean_depth and read length.
- first_read = next( iterator )
+ try:
+ first_read = next( iterator )
+ except StopIteration:
+ # no reads.
+ return { 'data': [], 'message': None, 'max_low': start, 'max_high': start }
+
read_len = len( first_read.seq )
num_reads = ( end - start ) * mean_depth / float ( read_len )
threshold = float( max_vals )/ num_reads
iterator = itertools.chain( iter( [ first_read ] ), iterator )
# Use specified iterator type, save for when threshold is >= 1.
- # A threshold of >= 1 indicates all reads are to be returned, so no
+ # A threshold of >= 1 indicates all reads are to be returned, so no
# sampling needed and seqential iterator will be used.
if iterator_type == 'sequential' or threshold >= 1:
read_iterator = iterator
- elif iterator_type == 'random':
+ elif iterator_type == 'random':
read_iterator = _random_read_iterator( iterator, threshold )
elif iterator_type == 'nth':
read_iterator = _nth_read_iterator( iterator, threshold )
@@ -1058,45 +1063,48 @@
# Clean up. TODO: is this needed? If so, we'll need a cleanup function after processing the data.
# bamfile.close()
- # If there are results and reference data, transform read sequence and cigar.
- if len( results ) != 0 and ref_seq:
- def process_read( read, start_field, cigar_field, seq_field ):
- '''
- Process a read using the designated fields.
- '''
- read_seq, read_cigar = get_ref_based_read_seq_and_cigar( read[ seq_field ].upper(),
- read[ start_field ],
- ref_seq,
- start,
- read[ cigar_field ] )
- read[ seq_field ] = read_seq
- read[ cigar_field ] = read_cigar
+ def compress_seq_and_cigar( read, start_field, cigar_field, seq_field ):
+ '''
+ Use reference-based compression to compress read sequence and cigar.
+ '''
+ read_seq, read_cigar = get_ref_based_read_seq_and_cigar( read[ seq_field ].upper(),
+ read[ start_field ],
+ ref_seq,
+ start,
+ read[ cigar_field ] )
+ read[ seq_field ] = read_seq
+ read[ cigar_field ] = read_cigar
- def process_se_read( read ):
- '''
- Process single-end read.
- '''
- process_read( read, 1, 4, 6)
+ def convert_cigar( read, start_field, cigar_field, seq_field ):
+ '''
+ Convert read cigar from pysam format to string format.
+ '''
+ cigar_ops = 'MIDNSHP=X'
+ read_cigar = ''
+ for op_tuple in read[ cigar_field ]:
+ read_cigar += '%i%s' % ( op_tuple[1], cigar_ops[ op_tuple[0] ] )
+ read[ cigar_field ] = read_cigar
- def process_pe_read( read ):
- '''
- Process paired-end read.
- '''
+ # Choose method for processing reads. Use reference-based compression
+ # if possible. Otherwise, convert cigar.
+ if ref_seq:
+ # Uppercase for easy comparison.
+ ref_seq = ref_seq.upper()
+ process_read = compress_seq_and_cigar
+ else:
+ process_read = convert_cigar
+
+ # Process reads.
+ for read in results:
+ if isinstance( read[ 5 ], list ):
+ # Paired-end read.
if len( read[4] ) > 2:
process_read( read[4], 0, 2, 4 )
if len( read[5] ) > 2:
process_read( read[5], 0, 2, 4 )
-
- # Uppercase for easy comparison.
- ref_seq = ref_seq.upper()
-
- # Process reads.
- for read in results:
- # Use correct function for processing reads.
- if isinstance( read[ 5 ], list ):
- process_pe_read( read )
- else:
- process_se_read( read )
+ else:
+ # Single-end read.
+ process_read( read, 1, 4, 6)
max_low, max_high = get_bounds( results, 1, 2 )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
09 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/4aee689e69da/
Changeset: 4aee689e69da
User: greg
Date: 2014-04-09 16:11:48
Summary: The basis of this change set is to provide some fixes to certain Tool Shed functions for supporting changing HTTP protocols over time (ie.e, https <-> http). In doing this, I've refactored several functions and moved most of the Tool Shed <-> Galaxy URL munging functions to the Tool Shed's common_util.py module. Ive renamed the munging functions to clarify what each of them does. Several duplicate functions have been eliminated from the code as well.
Affected #: 28 files
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 lib/galaxy/model/tool_shed_install/__init__.py
--- a/lib/galaxy/model/tool_shed_install/__init__.py
+++ b/lib/galaxy/model/tool_shed_install/__init__.py
@@ -123,12 +123,8 @@
self.shed_config_filename = name
return shed_tool_conf_dict
if self.includes_datatypes:
- #we need to search by filepaths here, which is less desirable
- tool_shed_url = self.tool_shed
- if tool_shed_url.find( ':' ) > 0:
- # Eliminate the port, if any, since it will result in an invalid directory name.
- tool_shed_url = tool_shed_url.split( ':' )[ 0 ]
- tool_shed = tool_shed_url.rstrip( '/' )
+ # We need to search by file paths here, which is less desirable.
+ tool_shed = common_util.remove_protocol_and_port_from_tool_shed_url( self.tool_shed )
for shed_tool_conf_dict in app.toolbox.shed_tool_confs:
tool_path = shed_tool_conf_dict[ 'tool_path' ]
relative_path = os.path.join( tool_path, tool_shed, 'repos', self.owner, self.name, self.installed_changeset_revision )
@@ -271,11 +267,7 @@
return None
def repo_path( self, app ):
- tool_shed_url = self.tool_shed
- if tool_shed_url.find( ':' ) > 0:
- # Eliminate the port, if any, since it will result in an invalid directory name.
- tool_shed_url = tool_shed_url.split( ':' )[ 0 ]
- tool_shed = tool_shed_url.rstrip( '/' )
+ tool_shed = common_util.remove_protocol_and_port_from_tool_shed_url( self.tool_shed )
for index, shed_tool_conf_dict in enumerate( app.toolbox.shed_tool_confs ):
tool_path = shed_tool_conf_dict[ 'tool_path' ]
relative_path = os.path.join( tool_path, tool_shed, 'repos', self.owner, self.name, self.installed_changeset_revision )
@@ -339,7 +331,7 @@
be installed in order for this repository to function correctly. However, those repository dependencies that are defined for this
repository with prior_installation_required set to True place them in a special category in that the required repositories must be
installed before this repository is installed. Among other things, this enables these "special" repository dependencies to include
- information that enables the successful intallation of this repository. This method is not used during the initial installation of
+ information that enables the successful installation of this repository. This method is not used during the initial installation of
this repository, but only after it has been installed (metadata must be set for this repository in order for this method to be useful).
"""
required_rd_tups_that_must_be_installed = []
@@ -347,12 +339,14 @@
rd_tups = self.metadata[ 'repository_dependencies' ][ 'repository_dependencies' ]
for rd_tup in rd_tups:
if len( rd_tup ) == 5:
- tool_shed, name, owner, changeset_revision, prior_installation_required = rd_tup
+ tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \
+ common_util.parse_repository_dependency_tuple( rd_tup, contains_error=False )
if asbool( prior_installation_required ):
required_rd_tups_that_must_be_installed.append( ( tool_shed, name, owner, changeset_revision, 'True', 'False' ) )
elif len( rd_tup ) == 6:
- tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = rd_tup
- # The repository dependency will only be required to be previsously installed if it does not fall into the category of
+ tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \
+ common_util.parse_repository_dependency_tuple( rd_tup, contains_error=False )
+ # The repository dependency will only be required to be previously installed if it does not fall into the category of
# a repository that must be installed only so that it's contained tool dependency can be used for compiling the tool
# dependency of the dependent repository.
if not asbool( only_if_compiling_contained_td ):
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -63,6 +63,7 @@
from galaxy.web.form_builder import SelectField
from galaxy.model.item_attrs import Dictifiable
from galaxy.model import Workflow
+from tool_shed.util import common_util
from tool_shed.util import shed_util_common as suc
from .loader import load_tool, template_macro_params
from .wrappers import (
@@ -467,6 +468,8 @@
.first()
def __get_tool_shed_repository( self, tool_shed, name, owner, installed_changeset_revision ):
+ # We store only the port, if one exists, in the database.
+ tool_shed = common_util.remove_protocol_from_tool_shed_url( tool_shed )
return self.app.install_model.context.query( self.app.install_model.ToolShedRepository ) \
.filter( and_( self.app.install_model.ToolShedRepository.table.c.tool_shed == tool_shed,
self.app.install_model.ToolShedRepository.table.c.name == name,
@@ -532,7 +535,10 @@
# Backward compatibility issue - the tag used to be named 'changeset_revision'.
installed_changeset_revision_elem = elem.find( "changeset_revision" )
installed_changeset_revision = installed_changeset_revision_elem.text
- tool_shed_repository = self.__get_tool_shed_repository( tool_shed, repository_name, repository_owner, installed_changeset_revision )
+ tool_shed_repository = self.__get_tool_shed_repository( tool_shed,
+ repository_name,
+ repository_owner,
+ installed_changeset_revision )
if tool_shed_repository:
# Only load tools if the repository is not deactivated or uninstalled.
can_load_into_panel_dict = not tool_shed_repository.deleted
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 lib/galaxy/tools/data_manager/manager.py
--- a/lib/galaxy/tools/data_manager/manager.py
+++ b/lib/galaxy/tools/data_manager/manager.py
@@ -6,6 +6,7 @@
from galaxy.util.odict import odict
from galaxy.util.template import fill_template
from galaxy.tools.data import TabularToolDataTable
+from tool_shed.util import common_util
import tool_shed.util.shed_util_common as suc
#set up logger
@@ -16,6 +17,7 @@
VALUE_TRANSLATION_FUNCTIONS = dict( abspath=os.path.abspath )
DEFAULT_VALUE_TRANSLATION_TYPE = 'template'
+
class DataManagers( object ):
def __init__( self, app, xml_filename=None ):
self.app = app
@@ -26,6 +28,7 @@
self.load_from_xml( self.filename )
if self.app.config.shed_data_manager_config_file:
self.load_from_xml( self.app.config.shed_data_manager_config_file, store_tool_path=False, replace_existing=True )
+
def load_from_xml( self, xml_filename, store_tool_path=True, replace_existing=False ):
try:
tree = util.parse_xml( xml_filename )
@@ -45,6 +48,7 @@
self.tool_path = tool_path
for data_manager_elem in root.findall( 'data_manager' ):
self.load_manager_from_elem( data_manager_elem, replace_existing=replace_existing )
+
def load_manager_from_elem( self, data_manager_elem, tool_path=None, add_manager=True, replace_existing=False ):
try:
data_manager = DataManager( self, data_manager_elem, tool_path=tool_path )
@@ -55,6 +59,7 @@
self.add_manager( data_manager, replace_existing=replace_existing )
log.debug( 'Loaded Data Manager: %s' % ( data_manager.id ) )
return data_manager
+
def add_manager( self, data_manager, replace_existing=False ):
if not replace_existing:
assert data_manager.id not in self.data_managers, "A data manager has been defined twice: %s" % ( data_manager.id )
@@ -67,8 +72,10 @@
if data_table_name not in self.managed_data_tables:
self.managed_data_tables[ data_table_name ] = []
self.managed_data_tables[ data_table_name ].append( data_manager )
+
def get_manager( self, *args, **kwds ):
return self.data_managers.get( *args, **kwds )
+
def remove_manager( self, manager_ids ):
if not isinstance( manager_ids, list ):
manager_ids = [ manager_ids ]
@@ -89,6 +96,7 @@
if remove_data_table_tracking and data_table_name in self.managed_data_tables:
del self.managed_data_tables[ data_table_name ]
+
class DataManager( object ):
GUID_TYPE = 'data_manager'
DEFAULT_VERSION = "0.0.1"
@@ -108,6 +116,7 @@
self.tool_shed_repository_info_dict = None
if elem is not None:
self.load_from_element( elem, tool_path or self.data_managers.tool_path )
+
def load_from_element( self, elem, tool_path ):
assert elem.tag == 'data_manager', 'A data manager configuration must have a "data_manager" tag as the root. "%s" is present' % ( elem.tag )
self.declared_id = elem.get( 'id', None )
@@ -122,14 +131,24 @@
path = tool_elem.get( "file", None )
tool_guid = tool_elem.get( "guid", None )
#need to determine repository info so that dependencies will work correctly
- tool_shed = tool_elem.find( 'tool_shed' ).text
+ tool_shed_url = tool_elem.find( 'tool_shed' ).text
+ # Handle protocol changes.
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( self.data_managers.app, tool_shed_url )
repository_name = tool_elem.find( 'repository_name' ).text
repository_owner = tool_elem.find( 'repository_owner' ).text
installed_changeset_revision = tool_elem.find( 'installed_changeset_revision' ).text
- #save repository info here
- self.tool_shed_repository_info_dict = dict( tool_shed=tool_shed, name=repository_name, owner=repository_owner, installed_changeset_revision=installed_changeset_revision )
- #get tool_shed repo id
- tool_shed_repository = suc.get_tool_shed_repository_by_shed_name_owner_installed_changeset_revision( self.data_managers.app, tool_shed, repository_name, repository_owner, installed_changeset_revision )
+ self.tool_shed_repository_info_dict = dict( tool_shed_url=tool_shed_url,
+ name=repository_name,
+ owner=repository_owner,
+ installed_changeset_revision=installed_changeset_revision )
+ # The protocol is not stored in the database.
+ tool_shed = common_util.remove_protocol_from_tool_shed_url( tool_shed_url )
+ tool_shed_repository = \
+ suc.get_tool_shed_repository_by_shed_name_owner_installed_changeset_revision( self.data_managers.app,
+ tool_shed,
+ repository_name,
+ repository_owner,
+ installed_changeset_revision )
if tool_shed_repository is None:
log.warning( 'Could not determine tool shed repository from database. This should only ever happen when running tests.' )
#we'll set tool_path manually here from shed_conf_file
@@ -147,7 +166,10 @@
if shed_conf:
tool_path = shed_conf.get( "tool_path", tool_path )
assert path is not None, "A tool file path could not be determined:\n%s" % ( util.xml_to_string( elem ) )
- self.load_tool( os.path.join( tool_path, path ), guid=tool_guid, data_manager_id=self.id, tool_shed_repository_id=tool_shed_repository_id )
+ self.load_tool( os.path.join( tool_path, path ),
+ guid=tool_guid,
+ data_manager_id=self.id,
+ tool_shed_repository_id=tool_shed_repository_id )
self.name = elem.get( 'name', self.tool.name )
self.description = elem.get( 'description', self.tool.description )
@@ -206,12 +228,23 @@
target_value = target_elem.text
if data_table_name not in self.move_by_data_table_column:
self.move_by_data_table_column[ data_table_name ] = {}
- self.move_by_data_table_column[ data_table_name ][ data_table_coumn_name ] = dict( type=move_type, source_base=source_base, source_value=source_value, target_base=target_base, target_value=target_value, relativize_symlinks=relativize_symlinks )
+ self.move_by_data_table_column[ data_table_name ][ data_table_coumn_name ] = \
+ dict( type=move_type,
+ source_base=source_base,
+ source_value=source_value,
+ target_base=target_base,
+ target_value=target_value,
+ relativize_symlinks=relativize_symlinks )
+
@property
def id( self ):
return self.guid or self.declared_id #if we have a guid, we will use that as the data_manager id
+
def load_tool( self, tool_filename, guid=None, data_manager_id=None, tool_shed_repository_id=None ):
- tool = self.data_managers.app.toolbox.load_tool( tool_filename, guid=guid, data_manager_id=data_manager_id, repository_id=tool_shed_repository_id )
+ tool = self.data_managers.app.toolbox.load_tool( tool_filename,
+ guid=guid,
+ data_manager_id=data_manager_id,
+ repository_id=tool_shed_repository_id )
self.data_managers.app.toolbox.data_manager_tools[ tool.id ] = tool
self.data_managers.app.toolbox.tools_by_id[ tool.id ] = tool
self.tool = tool
@@ -294,7 +327,6 @@
except OSError, e:
if e.errno != errno.EEXIST:
raise e
- #log.debug( 'Error creating directory "%s": %s' % ( dirs, e ) )
#moving a directory and the target already exists, we move the contents instead
util.move_merge( source, target )
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 lib/galaxy/webapps/galaxy/api/tool_shed_repositories.py
--- a/lib/galaxy/webapps/galaxy/api/tool_shed_repositories.py
+++ b/lib/galaxy/webapps/galaxy/api/tool_shed_repositories.py
@@ -207,9 +207,9 @@
# Keep track of all repositories that are installed - there may be more than one if repository dependencies are installed.
installed_tool_shed_repositories = []
# Get all of the information necessary for installing the repository from the specified tool shed.
- url = suc.url_join( tool_shed_url,
- 'api/repositories/get_repository_revision_install_info?name=%s&owner=%s&changeset_revision=%s' % \
- ( name, owner, changeset_revision ) )
+ params = '?name=%s&owner=%s&changeset_revision=%s' % ( name, owner, changeset_revision )
+ url = common_util.url_join( tool_shed_url,
+ 'api/repositories/get_repository_revision_install_info%s' % params )
try:
raw_text = common_util.tool_shed_get( trans.app, tool_shed_url, url )
except Exception, e:
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 lib/galaxy/webapps/galaxy/controllers/admin.py
--- a/lib/galaxy/webapps/galaxy/controllers/admin.py
+++ b/lib/galaxy/webapps/galaxy/controllers/admin.py
@@ -20,46 +20,74 @@
log = logging.getLogger( __name__ )
+
class UserListGrid( grids.Grid ):
+
+
class EmailColumn( grids.TextColumn ):
+
def get_value( self, trans, grid, user ):
return user.email
+
+
class UserNameColumn( grids.TextColumn ):
+
def get_value( self, trans, grid, user ):
if user.username:
return user.username
return 'not set'
+
+
class StatusColumn( grids.GridColumn ):
+
def get_value( self, trans, grid, user ):
if user.purged:
return "purged"
elif user.deleted:
return "deleted"
return ""
+
+
class GroupsColumn( grids.GridColumn ):
+
def get_value( self, trans, grid, user ):
if user.groups:
return len( user.groups )
return 0
+
+
class RolesColumn( grids.GridColumn ):
+
def get_value( self, trans, grid, user ):
if user.roles:
return len( user.roles )
return 0
+
+
class ExternalColumn( grids.GridColumn ):
+
def get_value( self, trans, grid, user ):
if user.external:
return 'yes'
return 'no'
+
+
class LastLoginColumn( grids.GridColumn ):
+
def get_value( self, trans, grid, user ):
if user.galaxy_sessions:
return self.format( user.galaxy_sessions[ 0 ].update_time )
return 'never'
+
+
class TimeCreatedColumn( grids.GridColumn ):
+
def get_value( self, trans, grid, user ):
return user.create_time.strftime('%x')
+
+
class ActivatedColumn( grids.GridColumn ):
+
def get_value( self, trans, grid, user ):
if user.active:
return 'Y'
@@ -121,32 +149,53 @@
num_rows_per_page = 50
preserve_state = False
use_paging = True
+
def get_current_item( self, trans, **kwargs ):
return trans.user
+
class RoleListGrid( grids.Grid ):
+
+
class NameColumn( grids.TextColumn ):
+
def get_value( self, trans, grid, role ):
return role.name
+
+
class DescriptionColumn( grids.TextColumn ):
+
def get_value( self, trans, grid, role ):
if role.description:
return role.description
return ''
+
+
class TypeColumn( grids.TextColumn ):
+
def get_value( self, trans, grid, role ):
return role.type
+
+
class StatusColumn( grids.GridColumn ):
+
def get_value( self, trans, grid, role ):
if role.deleted:
return "deleted"
return ""
+
+
class GroupsColumn( grids.GridColumn ):
+
def get_value( self, trans, grid, role ):
if role.groups:
return len( role.groups )
return 0
+
+
class UsersColumn( grids.GridColumn ):
+
+
def get_value( self, trans, grid, role ):
if role.users:
return len( role.users )
@@ -212,24 +261,38 @@
num_rows_per_page = 50
preserve_state = False
use_paging = True
+
def apply_query_filter( self, trans, query, **kwargs ):
return query.filter( model.Role.type != model.Role.types.PRIVATE )
+
class GroupListGrid( grids.Grid ):
+
+
class NameColumn( grids.TextColumn ):
+
def get_value( self, trans, grid, group ):
return group.name
+
+
class StatusColumn( grids.GridColumn ):
+
def get_value( self, trans, grid, group ):
if group.deleted:
return "deleted"
return ""
+
+
class RolesColumn( grids.GridColumn ):
+
def get_value( self, trans, grid, group ):
if group.roles:
return len( group.roles )
return 0
+
+
class UsersColumn( grids.GridColumn ):
+
def get_value( self, trans, grid, group ):
if group.members:
return len( group.members )
@@ -287,30 +350,48 @@
use_paging = True
class QuotaListGrid( grids.Grid ):
+
+
class NameColumn( grids.TextColumn ):
+
def get_value( self, trans, grid, quota ):
return quota.name
+
+
class DescriptionColumn( grids.TextColumn ):
+
def get_value( self, trans, grid, quota ):
if quota.description:
return quota.description
return ''
+
+
class AmountColumn( grids.TextColumn ):
+
def get_value( self, trans, grid, quota ):
return quota.operation + quota.display_amount
+
+
class StatusColumn( grids.GridColumn ):
+
def get_value( self, trans, grid, quota ):
if quota.deleted:
return "deleted"
elif quota.default:
return "<strong>default for %s users</strong>" % quota.default[0].type
return ""
+
+
class UsersColumn( grids.GridColumn ):
+
def get_value( self, trans, grid, quota ):
if quota.users:
return len( quota.users )
return 0
+
+
class GroupsColumn( grids.GridColumn ):
+
def get_value( self, trans, grid, quota ):
if quota.groups:
return len( quota.groups )
@@ -397,15 +478,22 @@
preserve_state = False
use_paging = True
+
class ToolVersionListGrid( grids.Grid ):
+
+
class ToolIdColumn( grids.TextColumn ):
+
def get_value( self, trans, grid, tool_version ):
if tool_version.tool_id in trans.app.toolbox.tools_by_id:
link = url_for( controller='tool_runner', tool_id=tool_version.tool_id )
link_str = '<a href="%s">' % link
return '<div class="count-box state-color-ok">%s%s</a></div>' % ( link_str, tool_version.tool_id )
return tool_version.tool_id
+
+
class ToolVersionsColumn( grids.TextColumn ):
+
def get_value( self, trans, grid, tool_version ):
tool_ids_str = ''
for tool_id in tool_version.get_version_ids( trans.app ):
@@ -443,6 +531,7 @@
def build_initial_query( self, trans, **kwd ):
return trans.install_model.context.query( self.model_class )
+
class AdminGalaxy( BaseUIController, Admin, AdminActions, UsesQuotaMixin, QuotaParamParser ):
user_list_grid = UserListGrid()
@@ -479,6 +568,7 @@
return self.edit_quota( trans, **kwargs )
# Render the list view
return self.quota_list_grid( trans, **kwargs )
+
@web.expose
@web.require_admin
def create_quota( self, trans, **kwd ):
@@ -525,6 +615,7 @@
out_groups=params.out_groups,
message=params.message,
status=params.status )
+
@web.expose
@web.require_admin
def rename_quota( self, trans, **kwd ):
@@ -538,6 +629,7 @@
webapp=params.webapp,
message=params.message,
status=params.status )
+
@web.expose
@web.require_admin
def manage_users_and_groups_for_quota( self, trans, **kwd ):
@@ -572,6 +664,7 @@
webapp=params.webapp,
message=params.message,
status=params.status )
+
@web.expose
@web.require_admin
def edit_quota( self, trans, **kwd ):
@@ -585,6 +678,7 @@
webapp=params.webapp,
message=params.message,
status=params.status )
+
@web.expose
@web.require_admin
def set_quota_default( self, trans, **kwd ):
@@ -603,6 +697,7 @@
webapp=params.webapp,
message=params.message,
status=params.status )
+
@web.expose
@web.require_admin
def unset_quota_default( self, trans, **kwd ):
@@ -614,6 +709,7 @@
webapp=params.webapp,
message=sanitize_text( params.message ),
status='error' ) )
+
@web.expose
@web.require_admin
def mark_quota_deleted( self, trans, **kwd ):
@@ -625,6 +721,7 @@
webapp=params.webapp,
message=sanitize_text( params.message ),
status='error' ) )
+
@web.expose
@web.require_admin
def undelete_quota( self, trans, **kwd ):
@@ -636,6 +733,7 @@
webapp=params.webapp,
message=sanitize_text( params.message ),
status='error' ) )
+
@web.expose
@web.require_admin
def purge_quota( self, trans, **kwd ):
@@ -647,6 +745,7 @@
webapp=params.webapp,
message=sanitize_text( params.message ),
status='error' ) )
+
def _quota_op( self, trans, do_op, op_method, kwd, listify=False ):
params = self.get_quota_params( kwd )
if listify:
@@ -684,6 +783,7 @@
params.message = e.err_msg
params.status = e.type
return quota, params
+
@web.expose
@web.require_admin
def impersonate( self, trans, email=None, **kwd ):
@@ -705,21 +805,14 @@
if emails is None:
emails = [ u.email for u in trans.sa_session.query( trans.app.model.User ).enable_eagerloads( False ).all() ]
return trans.fill_template( 'admin/impersonate.mako', emails=emails, message=message, status=status )
- def get_tool_shed_url_from_tools_xml_file_path( self, trans, tool_shed ):
- search_str = '://%s' % tool_shed
- for shed_name, shed_url in trans.app.tool_shed_registry.tool_sheds.items():
- if shed_url.find( search_str ) >= 0:
- if shed_url.endswith( '/' ):
- shed_url = shed_url.rstrip( '/' )
- return shed_url
- return None
+
def check_for_tool_dependencies( self, trans, migration_stage ):
# Get the 000x_tools.xml file associated with migration_stage.
tools_xml_file_path = os.path.abspath( os.path.join( trans.app.config.root, 'scripts', 'migrate_tools', '%04d_tools.xml' % migration_stage ) )
tree = galaxy.util.parse_xml( tools_xml_file_path )
root = tree.getroot()
tool_shed = root.get( 'name' )
- tool_shed_url = self.get_tool_shed_url_from_tools_xml_file_path( trans, tool_shed )
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, tool_shed )
repo_name_dependency_tups = []
if tool_shed_url:
for elem in root:
@@ -741,6 +834,7 @@
tool_dependencies.append( ( tool_dependency_name, tool_dependency_version, tool_dependency_type, tool_dependency_readme ) )
repo_name_dependency_tups.append( ( repository_name, tool_dependencies ) )
return repo_name_dependency_tups
+
@web.expose
@web.require_admin
def review_tool_migration_stages( self, trans, **kwd ):
@@ -772,12 +866,14 @@
migration_stages_dict=migration_stages_dict,
message=message,
status=status )
+
@web.expose
@web.require_admin
def view_datatypes_registry( self, trans, **kwd ):
message = galaxy.util.restore_text( kwd.get( 'message', '' ) )
status = galaxy.util.restore_text( kwd.get( 'status', 'done' ) )
return trans.fill_template( 'admin/view_datatypes_registry.mako', message=message, status=status )
+
@web.expose
@web.require_admin
def view_tool_data_tables( self, trans, **kwd ):
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 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
@@ -180,9 +180,10 @@
@web.expose
@web.require_admin
def browse_tool_shed( self, trans, **kwd ):
- tool_shed_url = kwd[ 'tool_shed_url' ]
+ tool_shed_url = kwd.get( 'tool_shed_url', '' )
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, tool_shed_url )
galaxy_url = web.url_for( '/', qualified=True )
- url = suc.url_join( tool_shed_url, 'repository/browse_valid_categories?galaxy_url=%s' % ( galaxy_url ) )
+ url = common_util.url_join( tool_shed_url, 'repository/browse_valid_categories?galaxy_url=%s' % ( galaxy_url ) )
return trans.response.send_redirect( url )
@web.expose
@@ -200,13 +201,13 @@
"""Send a request to the relevant tool shed to see if there are any updates."""
repository_id = kwd.get( 'id', None )
repository = suc.get_installed_tool_shed_repository( trans, repository_id )
- tool_shed_url = suc.get_url_from_tool_shed( trans.app, repository.tool_shed )
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, str( repository.tool_shed ) )
params = '?galaxy_url=%s&name=%s&owner=%s&changeset_revision=%s' % \
( web.url_for( '/', qualified=True ),
str( repository.name ),
str( repository.owner ),
str( repository.changeset_revision ) )
- url = suc.url_join( tool_shed_url,
+ url = common_util.url_join( tool_shed_url,
'repository/check_for_updates%s' % params )
return trans.response.send_redirect( url )
@@ -340,17 +341,19 @@
@web.expose
@web.require_admin
def find_tools_in_tool_shed( self, trans, **kwd ):
- tool_shed_url = kwd[ 'tool_shed_url' ]
+ tool_shed_url = kwd.get( 'tool_shed_url', '' )
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, tool_shed_url )
galaxy_url = web.url_for( '/', qualified=True )
- url = suc.url_join( tool_shed_url, 'repository/find_tools?galaxy_url=%s' % galaxy_url )
+ url = common_util.url_join( tool_shed_url, 'repository/find_tools?galaxy_url=%s' % galaxy_url )
return trans.response.send_redirect( url )
@web.expose
@web.require_admin
def find_workflows_in_tool_shed( self, trans, **kwd ):
- tool_shed_url = kwd[ 'tool_shed_url' ]
+ tool_shed_url = kwd.get( 'tool_shed_url', '' )
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, tool_shed_url )
galaxy_url = web.url_for( '/', qualified=True )
- url = suc.url_join( tool_shed_url, 'repository/find_workflows?galaxy_url=%s' % galaxy_url )
+ url = common_util.url_join( tool_shed_url, 'repository/find_workflows?galaxy_url=%s' % galaxy_url )
return trans.response.send_redirect( url )
@web.expose
@@ -377,10 +380,10 @@
it was installed.
"""
repository = suc.get_installed_tool_shed_repository( trans, repository_id )
- tool_shed_url = suc.get_url_from_tool_shed( trans.app, repository.tool_shed )
- url = suc.url_join( tool_shed_url,
- 'repository/get_tool_dependencies?name=%s&owner=%s&changeset_revision=%s' % \
- ( repository_name, repository_owner, changeset_revision ) )
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, str( repository.tool_shed ) )
+ params = '?name=%s&owner=%s&changeset_revision=%s' % ( repository_name, repository_owner, changeset_revision )
+ url = common_util.url_join( tool_shed_url,
+ 'repository/get_tool_dependencies%s' % params )
raw_text = common_util.tool_shed_get( trans.app, tool_shed_url, url )
if len( raw_text ) > 2:
encoded_text = json.from_json_string( raw_text )
@@ -397,10 +400,12 @@
an updated revision of an uninstalled tool shed repository.
"""
repository = suc.get_installed_tool_shed_repository( trans, repository_id )
- tool_shed_url = suc.get_url_from_tool_shed( trans.app, repository.tool_shed )
- url = suc.url_join( tool_shed_url,
- 'repository/get_updated_repository_information?name=%s&owner=%s&changeset_revision=%s' % \
- ( repository_name, repository_owner, changeset_revision ) )
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, str( repository.tool_shed ) )
+ params = '?name=%s&owner=%s&changeset_revision=%s' % ( str( repository_name ),
+ str( repository_owner ),
+ changeset_revision )
+ url = common_util.url_join( tool_shed_url,
+ 'repository/get_updated_repository_information%s' % params )
raw_text = common_util.tool_shed_get( trans.app, tool_shed_url, url )
repo_information_dict = json.from_json_string( raw_text )
return repo_information_dict
@@ -479,12 +484,12 @@
if repository_id is not None:
repository = suc.get_installed_tool_shed_repository( trans, repository_id )
if repository is not None:
- tool_shed_url = suc.get_url_from_tool_shed( trans.app, repository.tool_shed )
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, str( repository.tool_shed ) )
name = str( repository.name )
owner = str( repository.owner )
- url = suc.url_join( tool_shed_url,
- 'repository/get_latest_downloadable_changeset_revision?galaxy_url=%s&name=%s&owner=%s' % \
- ( web.url_for( '/', qualified=True ), name, owner ) )
+ params = '?galaxy_url=%s&name=%s&owner=%s' % ( web.url_for( '/', qualified=True ), name, owner )
+ url = common_util.url_join( tool_shed_url,
+ 'repository/get_latest_downloadable_changeset_revision%s' % params )
raw_text = common_util.tool_shed_get( trans.app, tool_shed_url, url )
latest_downloadable_revision = json.from_json_string( raw_text )
if latest_downloadable_revision == suc.INITIAL_CHANGELOG_HASH:
@@ -496,7 +501,7 @@
# appropriate repository revision if one exists. We need to create a temporary repo_info_tuple
# with the following entries to handle this.
# ( description, clone_url, changeset_revision, ctx_rev, owner, repository_dependencies, tool_dependencies )
- tmp_clone_url = suc.url_join( tool_shed_url, 'repos', owner, name )
+ tmp_clone_url = common_util.url_join( tool_shed_url, 'repos', owner, name )
tmp_repo_info_tuple = ( None, tmp_clone_url, latest_downloadable_revision, None, owner, None, None )
installed_repository, installed_changeset_revision = \
suc.repository_was_previously_installed( trans, tool_shed_url, name, tmp_repo_info_tuple )
@@ -509,10 +514,12 @@
status = 'error'
else:
# Install the latest downloadable revision of the repository.
- params = '?name=%s&owner=%s&changeset_revisions=%s&galaxy_url=%s' % \
- ( name, owner, str( latest_downloadable_revision ), web.url_for( '/', qualified=True ) )
- url = suc.url_join( tool_shed_url,
- 'repository/install_repositories_by_revision%s' % params )
+ params = '?name=%s&owner=%s&changeset_revisions=%s&galaxy_url=%s' % ( name,
+ owner,
+ str( latest_downloadable_revision ),
+ web.url_for( '/', qualified=True ) )
+ url = common_util.url_join( tool_shed_url,
+ 'repository/install_repositories_by_revision%s' % params )
return trans.response.send_redirect( url )
else:
message = 'Cannot locate installed tool shed repository with encoded id <b>%s</b>.' % str( repository_id )
@@ -713,7 +720,7 @@
repository = suc.get_installed_tool_shed_repository( trans, repository_id )
if repository is None:
return trans.show_error_message( 'Invalid repository specified.' )
- tool_shed_url = suc.get_url_from_tool_shed( trans.app, repository.tool_shed )
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, str( repository.tool_shed ) )
name = str( repository.name )
owner = str( repository.owner )
installed_changeset_revision = str( repository.installed_changeset_revision )
@@ -724,9 +731,12 @@
tool_shed_repository_ids=tool_shed_repository_ids ) )
if repository.can_install and operation == 'install':
# Send a request to the tool shed to install the repository.
- url = suc.url_join( tool_shed_url,
- 'repository/install_repositories_by_revision?name=%s&owner=%s&changeset_revisions=%s&galaxy_url=%s' % \
- ( name, owner, installed_changeset_revision, ( web.url_for( '/', qualified=True ) ) ) )
+ params = '?name=%s&owner=%s&changeset_revisions=%s&galaxy_url=%s' % ( name,
+ owner,
+ installed_changeset_revision,
+ web.url_for( '/', qualified=True ) )
+ url = common_util.url_join( tool_shed_url,
+ 'repository/install_repositories_by_revision%s' % params )
return trans.response.send_redirect( url )
description = kwd.get( 'description', repository.description )
shed_tool_conf, tool_path, relative_install_dir = suc.get_tool_panel_config_tool_path_install_dir( trans.app, repository )
@@ -938,7 +948,8 @@
message = kwd.get( 'message', '' )
status = kwd.get( 'status', 'done' )
shed_tool_conf = kwd.get( 'shed_tool_conf', None )
- tool_shed_url = kwd.get( 'tool_shed_url', None )
+ tool_shed_url = kwd.get( 'tool_shed_url', '' )
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, tool_shed_url )
# Handle repository dependencies, which do not include those that are required only for compiling a dependent
# repository's tool dependencies.
has_repository_dependencies = util.string_as_bool( kwd.get( 'has_repository_dependencies', False ) )
@@ -978,9 +989,9 @@
repository = suc.get_tool_shed_repository_by_id( trans, updating_repository_id )
# For backward compatibility to the 12/20/12 Galaxy release.
try:
- url = suc.url_join( tool_shed_url,
- 'repository/get_repository_id?name=%s&owner=%s' % \
- ( str( repository.name ), str( repository.owner ) ) )
+ params = '?name=%s&owner=%s' % ( str( repository.name ), str( repository.owner ) )
+ url = common_util.url_join( tool_shed_url,
+ 'repository/get_repository_id%s' % params )
repository_ids = common_util.tool_shed_get( trans.app, tool_shed_url, url )
except Exception, e:
# The Tool Shed cannot handle the get_repository_id request, so the code must be older than the
@@ -999,9 +1010,9 @@
else:
changeset_revisions = kwd.get( 'changeset_revisions', None )
# Get the information necessary to install each repository.
- url = suc.url_join( tool_shed_url,
- 'repository/get_repository_information?repository_ids=%s&changeset_revisions=%s' % \
- ( str( repository_ids ), str( changeset_revisions ) ) )
+ params = '?repository_ids=%s&changeset_revisions=%s' % ( str( repository_ids ), str( changeset_revisions ) )
+ url = common_util.url_join( tool_shed_url,
+ 'repository/get_repository_information%s' % params )
raw_text = common_util.tool_shed_get( trans.app, tool_shed_url, url )
repo_information_dict = json.from_json_string( raw_text )
for encoded_repo_info_dict in repo_information_dict.get( 'repo_info_dicts', [] ):
@@ -1245,12 +1256,12 @@
install_tool_dependencies = CheckboxField.is_checked( kwd.get( 'install_tool_dependencies', '' ) )
shed_tool_conf, tool_path, relative_install_dir = \
suc.get_tool_panel_config_tool_path_install_dir( trans.app, tool_shed_repository )
- repository_clone_url = suc.generate_clone_url_for_installed_repository( trans.app, tool_shed_repository )
+ repository_clone_url = common_util.generate_clone_url_for_installed_repository( trans.app, tool_shed_repository )
clone_dir = os.path.join( tool_path,
suc.generate_tool_shed_repository_install_dir( repository_clone_url,
tool_shed_repository.installed_changeset_revision ) )
relative_install_dir = os.path.join( clone_dir, tool_shed_repository.name )
- tool_shed_url = suc.get_url_from_tool_shed( trans.app, tool_shed_repository.tool_shed )
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, tool_shed_repository.tool_shed )
tool_section = None
tool_panel_section_id = kwd.get( 'tool_panel_section_id', '' )
new_tool_panel_section_label = kwd.get( 'new_tool_panel_section_label', '' )
@@ -1328,8 +1339,8 @@
install_repository_dependencies=install_repository_dependencies,
no_changes_checked=no_changes_checked,
tool_panel_section_id=tool_panel_section_id )
- # Default the selected tool panel location for loading tools included in each newly installed required tool shed repository to the location
- # selected for the repository selected for reinstallation.
+ # Default the selected tool panel location for loading tools included in each newly installed required
+ # tool shed repository to the location selected for the repository selected for re-installation.
for index, tps_key in enumerate( tool_panel_section_keys ):
if tps_key is None:
tool_panel_section_keys[ index ] = tool_panel_section_key
@@ -1463,9 +1474,9 @@
latest_changeset_revision = kwd.get( 'latest_changeset_revision', None )
latest_ctx_rev = kwd.get( 'latest_ctx_rev', None )
tool_shed_repository = suc.get_installed_tool_shed_repository( trans, repository_id )
- repository_clone_url = suc.generate_clone_url_for_installed_repository( trans.app, tool_shed_repository )
+ repository_clone_url = common_util.generate_clone_url_for_installed_repository( trans.app, tool_shed_repository )
metadata = tool_shed_repository.metadata
- tool_shed_url = suc.get_url_from_tool_shed( trans.app, tool_shed_repository.tool_shed )
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, str( tool_shed_repository.tool_shed ) )
tool_path, relative_install_dir = tool_shed_repository.get_tool_relative_path( trans.app )
if latest_changeset_revision and latest_ctx_rev:
# There are updates available in the tool shed for the repository, so use the receieved dependency information which was retrieved from
@@ -1510,9 +1521,11 @@
if 'workflows' in metadata:
includes_workflows = True
# Since we're reinstalling, we need to send a request to the tool shed to get the README files.
- url = suc.url_join( tool_shed_url,
- 'repository/get_readme_files?name=%s&owner=%s&changeset_revision=%s' % \
- ( tool_shed_repository.name, tool_shed_repository.owner, tool_shed_repository.installed_changeset_revision ) )
+ params = '?name=%s&owner=%s&changeset_revision=%s' % ( str( tool_shed_repository.name ),
+ str( tool_shed_repository.owner ),
+ str( tool_shed_repository.installed_changeset_revision ) )
+ url = common_util.url_join( tool_shed_url,
+ 'repository/get_readme_files%s' % params )
raw_text = common_util.tool_shed_get( trans.app, tool_shed_url, url )
readme_files_dict = json.from_json_string( raw_text )
tool_dependencies = metadata.get( 'tool_dependencies', None )
@@ -1647,8 +1660,7 @@
def reset_repository_metadata( self, trans, id ):
"""Reset all metadata on a single installed tool shed repository."""
repository = suc.get_installed_tool_shed_repository( trans, id )
- tool_shed_url = suc.get_url_from_tool_shed( trans.app, repository.tool_shed )
- repository_clone_url = suc.generate_clone_url_for_installed_repository( trans.app, repository )
+ repository_clone_url = common_util.generate_clone_url_for_installed_repository( trans.app, repository )
tool_path, relative_install_dir = repository.get_tool_relative_path( trans.app )
if relative_install_dir:
original_metadata_dict = repository.metadata
@@ -1713,10 +1725,12 @@
repository and update the metadata for the repository's revision in the Galaxy database.
"""
repository = suc.get_installed_tool_shed_repository( trans, kwd[ 'id' ] )
- tool_shed_url = suc.get_url_from_tool_shed( trans.app, repository.tool_shed )
- url = suc.url_join( tool_shed_url,
- 'repository/get_tool_versions?name=%s&owner=%s&changeset_revision=%s' % \
- ( repository.name, repository.owner, repository.changeset_revision ) )
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, str( repository.tool_shed ) )
+ params = '?name=%s&owner=%s&changeset_revision=%s' % ( str( repository.name ),
+ str( repository.owner ),
+ str( repository.changeset_revision ) )
+ url = common_util.url_join( tool_shed_url,
+ 'repository/get_tool_versions%s' % params )
text = common_util.tool_shed_get( trans.app, tool_shed_url, url )
if text:
tool_version_dicts = json.from_json_string( text )
@@ -1814,7 +1828,9 @@
"""Update a cloned repository to the latest revision possible."""
message = kwd.get( 'message', '' )
status = kwd.get( 'status', 'done' )
- tool_shed_url = kwd.get( 'tool_shed_url', None )
+ tool_shed_url = kwd.get( 'tool_shed_url', '' )
+ # Handle protocol changes over time.
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, tool_shed_url )
name = kwd.get( 'name', None )
owner = kwd.get( 'owner', None )
changeset_revision = kwd.get( 'changeset_revision', None )
@@ -1839,7 +1855,6 @@
repository_clone_url = os.path.join( tool_shed_url, 'repos', owner, name )
repository_util.pull_repository( repo, repository_clone_url, latest_ctx_rev )
suc.update_repository( repo, latest_ctx_rev )
- tool_shed = suc.clean_tool_shed_url( tool_shed_url )
# Remove old Data Manager entries
if repository.includes_data_managers:
data_manager_util.remove_from_data_manager( trans.app, repository )
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 lib/galaxy/webapps/tool_shed/controllers/repository.py
--- a/lib/galaxy/webapps/tool_shed/controllers/repository.py
+++ b/lib/galaxy/webapps/tool_shed/controllers/repository.py
@@ -793,7 +793,7 @@
def browse_valid_categories( self, trans, **kwd ):
"""Filter repositories per category by those that are valid for installing into Galaxy."""
# The request came from Galaxy, so restrict category links to display only valid repository changeset revisions.
- galaxy_url = suc.handle_galaxy_url( trans, **kwd )
+ galaxy_url = common_util.handle_galaxy_url( trans, **kwd )
if galaxy_url:
kwd[ 'galaxy_url' ] = galaxy_url
if 'f-free-text-search' in kwd:
@@ -831,7 +831,7 @@
@web.expose
def browse_valid_repositories( self, trans, **kwd ):
"""Filter repositories to those that are installable into Galaxy."""
- galaxy_url = suc.handle_galaxy_url( trans, **kwd )
+ galaxy_url = common_util.handle_galaxy_url( trans, **kwd )
if galaxy_url:
kwd[ 'galaxy_url' ] = galaxy_url
repository_id = kwd.get( 'id', None )
@@ -885,7 +885,7 @@
message = kwd.get( 'message', '' )
status = kwd.get( 'status', 'done' )
# If the request originated with the UpdateManager, it will not include a galaxy_url.
- galaxy_url = suc.handle_galaxy_url( trans, **kwd )
+ galaxy_url = common_util.handle_galaxy_url( trans, **kwd )
name = kwd.get( 'name', None )
owner = kwd.get( 'owner', None )
changeset_revision = kwd.get( 'changeset_revision', None )
@@ -902,9 +902,12 @@
elif galaxy_url:
# Start building up the url to redirect back to the calling Galaxy instance.
params = '?tool_shed_url=%s&name=%s&owner=%s&changeset_revision=%s&latest_changeset_revision=' % \
- ( web.url_for( '/', qualified=True ), repository.name, repository.user.username, changeset_revision )
- url = suc.url_join( galaxy_url,
- 'admin_toolshed/update_to_changeset_revision%s' % params )
+ ( web.url_for( '/', qualified=True ),
+ str( repository.name ),
+ str( repository.user.username ),
+ changeset_revision )
+ url = common_util.url_join( galaxy_url,
+ 'admin_toolshed/update_to_changeset_revision%s' % params )
else:
message = 'Unable to check for updates due to an invalid Galaxy URL: <b>%s</b>. ' % galaxy_url
message += 'You may need to enable third-party cookies in your browser. '
@@ -1145,7 +1148,12 @@
repository.times_downloaded += 1
trans.sa_session.add( repository )
trans.sa_session.flush()
- download_url = suc.url_join( '/', 'repos', repository.user.username, repository.name, 'archive', file_type_str )
+ download_url = common_util.url_join( '/',
+ 'repos',
+ str( repository.user.username ),
+ str( repository.name ),
+ 'archive',
+ file_type_str )
return trans.response.send_redirect( download_url )
@web.expose
@@ -1233,7 +1241,7 @@
def find_tools( self, trans, **kwd ):
message = kwd.get( 'message', '' )
status = kwd.get( 'status', 'done' )
- galaxy_url = suc.handle_galaxy_url( trans, **kwd )
+ galaxy_url = common_util.handle_galaxy_url( trans, **kwd )
if 'operation' in kwd:
item_id = kwd.get( 'id', '' )
if item_id:
@@ -1321,7 +1329,7 @@
def find_workflows( self, trans, **kwd ):
message = kwd.get( 'message', '' )
status = kwd.get( 'status', 'done' )
- galaxy_url = suc.handle_galaxy_url( trans, **kwd )
+ galaxy_url = common_util.handle_galaxy_url( trans, **kwd )
if 'operation' in kwd:
item_id = kwd.get( 'id', '' )
if item_id:
@@ -1615,7 +1623,11 @@
# section 5.1, e.g. Sat, 07 Sep 2002 00:00:01 UT
time_tested = repository_metadata.time_last_tested.strftime( '%a, %d %b %Y %H:%M:%S UT' )
# Generate a citable URL for this repository with owner and changeset revision.
- repository_citable_url = suc.url_join( tool_shed_url, 'view', user.username, repository.name, repository_metadata.changeset_revision )
+ repository_citable_url = common_util.url_join( tool_shed_url,
+ 'view',
+ str( user.username ),
+ str( repository.name ),
+ str( repository_metadata.changeset_revision ) )
passed_tests = len( tool_test_results.get( 'passed_tests', [] ) )
failed_tests = len( tool_test_results.get( 'failed_tests', [] ) )
missing_test_components = len( tool_test_results.get( 'missing_test_components', [] ) )
@@ -1866,7 +1878,7 @@
"""
repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
repository_id = trans.security.encode_id( repository.id )
- repository_clone_url = suc.generate_clone_url_for_repository_in_tool_shed( trans, repository )
+ repository_clone_url = common_util.generate_clone_url_for_repository_in_tool_shed( trans, repository )
repo_dir = repository.repo_path( trans.app )
repo = hg.repository( suc.get_configured_ui(), repo_dir )
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, repository_id, changeset_revision )
@@ -2051,15 +2063,15 @@
if not repository_ids:
repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
repository_ids = trans.security.encode_id( repository.id )
- galaxy_url = suc.handle_galaxy_url( trans, **kwd )
+ galaxy_url = common_util.handle_galaxy_url( trans, **kwd )
if galaxy_url:
# Redirect back to local Galaxy to perform install.
params = '?tool_shed_url=%s&repository_ids=%s&changeset_revisions=%s' % \
( web.url_for( '/', qualified=True ),
','.join( util.listify( repository_ids ) ),
','.join( util.listify( changeset_revisions ) ) )
- url = suc.url_join( galaxy_url,
- 'admin_toolshed/prepare_for_install%s' % params )
+ url = common_util.url_join( galaxy_url,
+ 'admin_toolshed/prepare_for_install%s' % params )
return trans.response.send_redirect( url )
else:
message = 'Repository installation is not possible due to an invalid Galaxy URL: <b>%s</b>. ' % galaxy_url
@@ -2560,8 +2572,8 @@
if invalid:
message += 'The repository dependency definitions for this repository are invalid and will be ignored. '
message += 'The complete dependency hierarchy could not be determined. The cause of repository dependency '
- message += 'definition errors like this can usually be seen when viewing the repository directly from the'
- message += 'Tool Shed. The exact cause cannot be determined when visiting the Tool Shed from Galaxy to'
+ message += 'definition errors like this can usually be seen when viewing the repository directly from the '
+ message += 'Tool Shed. The exact cause cannot be determined when visiting the Tool Shed from Galaxy to '
message += 'install the repository.'
status = 'error'
else:
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 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
@@ -58,8 +58,8 @@
else:
root = tree.getroot()
defined_tool_shed_url = root.get( 'name' )
- self.tool_shed_url = suc.get_url_from_tool_shed( self.app, defined_tool_shed_url )
- self.tool_shed = suc.clean_tool_shed_url( defined_tool_shed_url )
+ self.tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( self.app, defined_tool_shed_url )
+ self.tool_shed = common_util.remove_protocol_and_port_from_tool_shed_url( self.tool_shed_url )
self.repository_owner = common_util.REPOSITORY_OWNER
index, self.shed_config_dict = suc.get_shed_tool_conf_dict( app, self.migrated_tools_config )
# Since tool migration scripts can be executed any number of times, we need to make sure the appropriate tools are defined in
@@ -101,7 +101,11 @@
name = repository_elem.get( 'name' )
changeset_revision = repository_elem.get( 'changeset_revision' )
tool_shed_accessible, repository_dependencies_dict = \
- common_util.get_repository_dependencies( app, self.tool_shed_url, name, self.repository_owner, changeset_revision )
+ common_util.get_repository_dependencies( app,
+ self.tool_shed_url,
+ name,
+ self.repository_owner,
+ changeset_revision )
# Make sure all repository dependency records exist (as tool_shed_repository table rows) in the Galaxy database.
created_tool_shed_repositories = self.create_or_update_tool_shed_repository_records( name,
changeset_revision,
@@ -155,12 +159,15 @@
def create_or_update_tool_shed_repository_records( self, name, changeset_revision, repository_dependencies_dict ):
"""
- Make sure the repository defined by name and changeset_revision and all of it's repository dependencies have associated tool_shed_repository
- table rows in the Galaxy database.
+ Make sure the repository defined by name and changeset_revision and all of it's repository dependencies have
+ associated tool_shed_repository table rows in the Galaxy database.
"""
created_tool_shed_repositories = []
description = repository_dependencies_dict.get( 'description', None )
- tool_shed_repository = self.create_or_update_tool_shed_repository_record( name, self.repository_owner, changeset_revision, description=description )
+ tool_shed_repository = self.create_or_update_tool_shed_repository_record( name,
+ self.repository_owner,
+ changeset_revision,
+ description=description )
if tool_shed_repository:
created_tool_shed_repositories.append( tool_shed_repository )
for rd_key, rd_tups in repository_dependencies_dict.items():
@@ -170,7 +177,10 @@
parsed_rd_tup = common_util.parse_repository_dependency_tuple( rd_tup )
rd_tool_shed, rd_name, rd_owner, rd_changeset_revision = parsed_rd_tup[ 0:4 ]
# TODO: Make sure the repository description is applied to the new repository record during installation.
- tool_shed_repository = self.create_or_update_tool_shed_repository_record( rd_name, rd_owner, rd_changeset_revision, description=None )
+ tool_shed_repository = self.create_or_update_tool_shed_repository_record( rd_name,
+ rd_owner,
+ rd_changeset_revision,
+ description=None )
if tool_shed_repository:
created_tool_shed_repositories.append( tool_shed_repository )
return created_tool_shed_repositories
@@ -451,7 +461,7 @@
converter_path, display_path = datatype_util.alter_config_and_load_prorietary_datatypes( self.app, datatypes_config, repo_install_dir, override=False ) #repo_install_dir was relative_install_dir
if converter_path or display_path:
# Create a dictionary of tool shed repository related information.
- repository_dict = datatype_util.create_repository_dict_for_proprietary_datatypes( tool_shed=self.tool_shed,
+ repository_dict = datatype_util.create_repository_dict_for_proprietary_datatypes( tool_shed=self.tool_shed_url,
name=tool_shed_repository.name,
owner=self.repository_owner,
installed_changeset_revision=tool_shed_repository.installed_changeset_revision,
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 lib/tool_shed/galaxy_install/installed_repository_manager.py
--- a/lib/tool_shed/galaxy_install/installed_repository_manager.py
+++ b/lib/tool_shed/galaxy_install/installed_repository_manager.py
@@ -3,7 +3,7 @@
"""
import logging
import os
-import tool_shed.util.shed_util_common as suc
+from tool_shed.util import common_util
from tool_shed.util import datatype_util
from tool_shed.util import repository_dependency_util
from tool_shed.util import tool_dependency_util
@@ -175,7 +175,7 @@
root = tree.getroot()
tool_path = root.get( 'tool_path', None )
if tool_path:
- ts = suc.clean_tool_shed_url( tool_shed_repository.tool_shed )
+ ts = common_util.remove_port_from_tool_shed_url( str( tool_shed_repository.tool_shed ) )
relative_path = os.path.join( tool_path,
ts,
'repos',
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 lib/tool_shed/galaxy_install/repository_util.py
--- a/lib/tool_shed/galaxy_install/repository_util.py
+++ b/lib/tool_shed/galaxy_install/repository_util.py
@@ -64,13 +64,13 @@
if repository_metadata:
metadata = repository_metadata.metadata
if metadata:
- toolshed_url = str( web.url_for( '/', qualified=True ) ).rstrip( '/' )
+ tool_shed_url = str( web.url_for( '/', qualified=True ) ).rstrip( '/' )
# Get a dictionary of all repositories upon which the contents of the received repository depends.
repository_dependencies = \
repository_dependency_util.get_repository_dependencies_for_changeset_revision( trans=trans,
repository=repository,
repository_metadata=repository_metadata,
- toolshed_base_url=toolshed_url,
+ toolshed_base_url=tool_shed_url,
key_rd_dicts_to_be_processed=None,
all_repository_dependencies=None,
handled_key_rd_dicts=None,
@@ -187,7 +187,7 @@
repository = suc.get_repository_in_tool_shed( trans, repository_id )
repo_dir = repository.repo_path( trans.app )
repo = hg.repository( suc.get_configured_ui(), repo_dir )
- repository_clone_url = suc.generate_clone_url_for_repository_in_tool_shed( trans, repository )
+ repository_clone_url = common_util.generate_clone_url_for_repository_in_tool_shed( trans, repository )
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans,
repository_id,
changeset_revision )
@@ -241,20 +241,23 @@
def get_repo_info_dict_for_repair( trans, repository ):
tool_panel_section_key = None
- repository_clone_url = suc.generate_clone_url_for_installed_repository( trans.app, repository )
- repository_dependencies = repository_dependency_util.get_repository_dependencies_for_installed_tool_shed_repository( trans, repository )
+ repository_clone_url = common_util.generate_clone_url_for_installed_repository( trans.app, repository )
+ repository_dependencies = \
+ repository_dependency_util.get_repository_dependencies_for_installed_tool_shed_repository( trans, repository )
metadata = repository.metadata
if metadata:
tool_dependencies = metadata.get( 'tool_dependencies', None )
tool_panel_section_dict = metadata.get( 'tool_panel_section', None )
if tool_panel_section_dict:
# The repository must be in the uninstalled state. The structure of tool_panel_section_dict is:
- # {<tool guid> : [{ 'id':<section id>, 'name':<section name>, 'version':<section version>, 'tool_config':<tool config file name> }]}
+ # {<tool guid> :
+ # [{ 'id':<section id>, 'name':<section name>, 'version':<section version>, 'tool_config':<tool config file name> }]}
# Here is an example:
# {"localhost:9009/repos/test/filter/Filter1/1.1.0":
- # [{"id": "filter_and_sort", "name": "Filter and Sort", "tool_config": "filtering.xml", "version": ""}]}
- # Currently all tools contained within an installed tool shed repository must be loaded into the same section in the tool panel, so we can
- # get the section id of the first guid in the tool_panel_section_dict. In the future, we'll have to handle different sections per guid.
+ # [{"id": "filter_and_sort", "name": "Filter and Sort", "tool_config": "filtering.xml", "version": ""}]}
+ # Currently all tools contained within an installed tool shed repository must be loaded into the same
+ # section in the tool panel, so we can get the section id of the first guid in the tool_panel_section_dict.
+ # In the future, we'll have to handle different sections per guid.
guid = tool_panel_section_dict.keys()[ 0 ]
section_dicts = tool_panel_section_dict[ guid ]
section_dict = section_dicts[ 0 ]
@@ -315,9 +318,11 @@
def get_update_to_changeset_revision_and_ctx_rev( trans, repository ):
"""Return the changeset revision hash to which the repository can be updated."""
changeset_revision_dict = {}
- tool_shed_url = suc.get_url_from_tool_shed( trans.app, repository.tool_shed )
- url = suc.url_join( tool_shed_url, 'repository/get_changeset_revision_and_ctx_rev?name=%s&owner=%s&changeset_revision=%s' % \
- ( repository.name, repository.owner, repository.installed_changeset_revision ) )
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, str( repository.tool_shed ) )
+ params = '?name=%s&owner=%s&changeset_revision=%s' % ( str( repository.name ),
+ str( repository.owner ),
+ str( repository.installed_changeset_revision ) )
+ url = common_util.url_join( tool_shed_url, 'repository/get_changeset_revision_and_ctx_rev%s' % params )
try:
encoded_update_dict = common_util.tool_shed_get( trans.app, tool_shed_url, url )
if encoded_update_dict:
@@ -588,10 +593,12 @@
suc.update_tool_shed_repository_status( trans.app,
tool_shed_repository,
trans.install_model.ToolShedRepository.installation_status.SETTING_TOOL_VERSIONS )
- tool_shed_url = suc.get_url_from_tool_shed( trans.app, tool_shed_repository.tool_shed )
- url = suc.url_join( tool_shed_url,
- '/repository/get_tool_versions?name=%s&owner=%s&changeset_revision=%s' %
- ( tool_shed_repository.name, tool_shed_repository.owner, tool_shed_repository.changeset_revision ) )
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, str( tool_shed_repository.tool_shed ) )
+ params = '?name=%s&owner=%s&changeset_revision=%s' % ( str( tool_shed_repository.name ),
+ str( tool_shed_repository.owner ),
+ str( tool_shed_repository.changeset_revision ) )
+ url = common_util.url_join( tool_shed_url,
+ '/repository/get_tool_versions%s' % params )
text = common_util.tool_shed_get( trans.app, tool_shed_url, url )
if text:
tool_version_dicts = json.from_json_string( text )
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 lib/tool_shed/galaxy_install/tool_dependencies/install_util.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/install_util.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/install_util.py
@@ -22,8 +22,10 @@
def create_temporary_tool_dependencies_config( app, tool_shed_url, name, owner, changeset_revision ):
"""Make a call to the tool shed to get the required repository's tool_dependencies.xml file."""
- url = url_join( tool_shed_url,
- 'repository/get_tool_dependencies_config_contents?name=%s&owner=%s&changeset_revision=%s' % ( name, owner, changeset_revision ) )
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( app, tool_shed_url )
+ params = '?name=%s&owner=%s&changeset_revision=%s' % ( name, owner, changeset_revision )
+ url = common_util.url_join( tool_shed_url,
+ 'repository/get_tool_dependencies_config_contents%s' % params )
text = common_util.tool_shed_get( app, tool_shed_url, url )
if text:
# Write the contents to a temporary file on disk so it can be reloaded and parsed.
@@ -132,7 +134,8 @@
def get_tool_shed_repository_by_tool_shed_name_owner_changeset_revision( app, tool_shed_url, name, owner, changeset_revision ):
sa_session = app.install_model.context
- tool_shed = td_common_util.clean_tool_shed_url( tool_shed_url )
+ # The protocol is not stored, but the port is if it exists.
+ tool_shed = common_util.remove_protocol_from_tool_shed_url( tool_shed_url )
tool_shed_repository = sa_session.query( app.install_model.ToolShedRepository ) \
.filter( and_( app.install_model.ToolShedRepository.table.c.tool_shed == tool_shed,
app.install_model.ToolShedRepository.table.c.name == name,
@@ -165,8 +168,10 @@
Get all appropriate newer changeset revisions for the repository defined by
the received tool_shed_url / name / owner combination.
"""
- url = suc.url_join( tool_shed_url,
- 'repository/updated_changeset_revisions?name=%s&owner=%s&changeset_revision=%s' % ( name, owner, changeset_revision ) )
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( app, tool_shed_url )
+ params = '?name=%s&owner=%s&changeset_revision=%s' % ( name, owner, changeset_revision )
+ url = common_util.url_join( tool_shed_url,
+ 'repository/updated_changeset_revisions%s' % params )
text = common_util.tool_shed_get( app, tool_shed_url, url )
return text
@@ -180,6 +185,8 @@
"""
handled_tool_dependencies = []
tool_shed = elem.attrib[ 'toolshed' ]
+ # The protocol is not stored, but the port is if it exists.
+ tool_shed = common_util.remove_protocol_from_tool_shed_url( tool_shed )
required_repository_name = elem.attrib[ 'name' ]
required_repository_owner = elem.attrib[ 'owner' ]
default_required_repository_changeset_revision = elem.attrib[ 'changeset_revision' ]
@@ -950,9 +957,3 @@
except:
file_name = fpath
return file_name
-
-def url_join( *args ):
- parts = []
- for arg in args:
- parts.append( arg.strip( '/' ) )
- return '/'.join( parts )
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 lib/tool_shed/galaxy_install/tool_dependencies/td_common_util.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/td_common_util.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/td_common_util.py
@@ -9,6 +9,7 @@
import urllib2
import zipfile
from string import Template
+from tool_shed.util import common_util
import tool_shed.util.shed_util_common as suc
from galaxy.datatypes import checkers
@@ -108,19 +109,6 @@
def open_zip( self, filepath, mode ):
return zipfile.ZipFile( filepath, mode )
-def clean_tool_shed_url( base_url ):
- if base_url:
- if base_url.find( '://' ) > -1:
- try:
- protocol, base = base_url.split( '://' )
- except ValueError, e:
- # The received base_url must be an invalid url.
- log.debug( "Returning unchanged invalid base_url from td_common_util.clean_tool_shed_url: %s" % str( base_url ) )
- return base_url
- return base.rstrip( '/' )
- return base_url.rstrip( '/' )
- return base_url
-
def create_env_var_dict( elem, tool_dependency_install_dir=None, tool_shed_repository_install_dir=None ):
env_var_name = elem.get( 'name', 'PATH' )
env_var_action = elem.get( 'action', 'prepend_to' )
@@ -192,7 +180,8 @@
repository_owner = elem.get( 'owner', None )
changeset_revision = elem.get( 'changeset_revision', None )
if toolshed and repository_name and repository_owner and changeset_revision:
- toolshed = clean_tool_shed_url( toolshed )
+ # The protocol is not stored, but the port is if it exists.
+ toolshed = common_util.remove_protocol_from_tool_shed_url( toolshed )
repository = suc.get_repository_for_dependency_relationship( app, toolshed, repository_name, repository_owner, changeset_revision )
if repository:
for sub_elem in elem:
@@ -203,7 +192,9 @@
# Get the tool_dependency so we can get it's installation directory.
tool_dependency = None
for tool_dependency in repository.tool_dependencies:
- if tool_dependency.type == tool_dependency_type and tool_dependency.name == tool_dependency_name and tool_dependency.version == tool_dependency_version:
+ if tool_dependency.type == tool_dependency_type and \
+ tool_dependency.name == tool_dependency_name and \
+ tool_dependency.version == tool_dependency_version:
break
if tool_dependency:
tool_dependency_key = '%s/%s' % ( tool_dependency_name, tool_dependency_version )
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 lib/tool_shed/scripts/api/common.py
--- a/lib/tool_shed/scripts/api/common.py
+++ b/lib/tool_shed/scripts/api/common.py
@@ -9,6 +9,7 @@
sys.path = new_path
import tool_shed.util.shed_util_common as suc
+from tool_shed.util import common_util
from galaxy import eggs
import pkg_resources
@@ -90,7 +91,7 @@
parts.insert( 0, 'api' )
elif 'api' not in parts:
parts.insert( 0, 'api' )
- url = suc.url_join( base, *parts )
+ url = common_util.url_join( base, *parts )
if params is not None:
try:
query_string = urllib.urlencode( params )
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 lib/tool_shed/scripts/deprecate_repositories_without_metadata.py
--- a/lib/tool_shed/scripts/deprecate_repositories_without_metadata.py
+++ b/lib/tool_shed/scripts/deprecate_repositories_without_metadata.py
@@ -20,7 +20,7 @@
from optparse import OptionParser
from galaxy.tools import parameters
-from tool_shed.util.shed_util_common import url_join
+from tool_shed.util.common_util import url_join
import galaxy.webapps.tool_shed.config as tool_shed_config
import galaxy.webapps.tool_shed.model.mapping
import sqlalchemy as sa
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 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
@@ -24,7 +24,7 @@
def activate_repository( trans, repository ):
"""Activate an installed tool shed repository that has been marked as deactivated."""
- repository_clone_url = suc.generate_clone_url_for_installed_repository( trans.app, repository )
+ repository_clone_url = common_util.generate_clone_url_for_installed_repository( trans.app, repository )
shed_tool_conf, tool_path, relative_install_dir = suc.get_tool_panel_config_tool_path_install_dir( trans.app, repository )
repository.deleted = False
repository.status = trans.install_model.ToolShedRepository.installation_status.INSTALLED
@@ -90,7 +90,7 @@
# Inspect the tool_dependencies dictionary to separate the installed and missing tool dependencies.
# We don't add to installed_td and missing_td here because at this point they are empty.
installed_td, missing_td = \
- get_installed_and_missing_tool_dependencies_for_repository( trans, tool_shed_url, tool_dependencies )
+ get_installed_and_missing_tool_dependencies_for_repository( trans, tool_dependencies )
# In cases where a repository dependency is required only for compiling a dependent repository's
# tool dependency, the value of repository_dependencies will be an empty dictionary here.
if repository_dependencies:
@@ -130,9 +130,7 @@
if required_tool_dependencies:
# Discover and categorize all tool dependencies defined for this repository's repository dependencies.
required_installed_td, required_missing_td = \
- get_installed_and_missing_tool_dependencies_for_repository( trans,
- tool_shed_url,
- required_tool_dependencies )
+ get_installed_and_missing_tool_dependencies_for_repository( trans, required_tool_dependencies )
if required_installed_td:
if not includes_tool_dependencies:
includes_tool_dependencies = True
@@ -189,7 +187,7 @@
installed_rd_tups = []
missing_rd_tups = []
for tsr in repository.repository_dependencies:
- prior_installation_required = suc.set_prior_installation_required( repository, tsr )
+ prior_installation_required = suc.set_prior_installation_required( trans.app, repository, tsr )
only_if_compiling_contained_td = suc.set_only_if_compiling_contained_td( repository, tsr )
rd_tup = [ tsr.tool_shed,
tsr.name,
@@ -261,7 +259,7 @@
# that includes the correct repository owner which we get from the current rd_tup. The current
# tuple looks like: ( description, repository_clone_url, changeset_revision, ctx_rev, repository_owner,
# repository_dependencies, installed_td )
- tmp_clone_url = suc.generate_clone_url_from_repo_info_tup( rd_tup )
+ tmp_clone_url = common_util.generate_clone_url_from_repo_info_tup( trans, rd_tup )
tmp_repo_info_tuple = ( None, tmp_clone_url, changeset_revision, None, owner, None, None )
repository, installed_changeset_revision = suc.repository_was_previously_installed( trans,
tool_shed,
@@ -312,7 +310,7 @@
missing_repository_dependencies[ 'description' ] = description
return installed_repository_dependencies, missing_repository_dependencies
-def get_installed_and_missing_tool_dependencies_for_repository( trans, tool_shed_url, tool_dependencies_dict ):
+def get_installed_and_missing_tool_dependencies_for_repository( trans, tool_dependencies_dict ):
"""
Return the lists of installed tool dependencies and missing tool dependencies for a set of repositories
being installed into Galaxy.
@@ -439,7 +437,10 @@
encoded_required_repository_tups.append( encoding_util.encoding_sep.join( required_repository_tup ) )
encoded_required_repository_str = encoding_util.encoding_sep2.join( encoded_required_repository_tups )
encoded_required_repository_str = encoding_util.tool_shed_encode( encoded_required_repository_str )
- url = suc.url_join( tool_shed_url, '/repository/get_required_repo_info_dict' )
+ if trans.webapp.name == 'galaxy':
+ # Handle secure / insecure Tool Shed URL protocol changes and port changes.
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, tool_shed_url )
+ url = common_util.url_join( tool_shed_url, '/repository/get_required_repo_info_dict' )
request = urllib2.Request( url, data=urllib.urlencode( dict( encoded_str=encoded_required_repository_str ) ) )
response = urllib2.urlopen( request ).read()
if response:
@@ -569,7 +570,10 @@
tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = rd_tup
# TODO: we may discover that we need to check more than just installed_changeset_revision and changeset_revision here, in which
# case we'll need to contact the tool shed to get the list of all possible changeset_revisions.
- if repository_dependency.tool_shed == tool_shed and \
+ cleaned_tool_shed = common_util.remove_protocol_and_port_from_tool_shed_url( tool_shed )
+ cleaned_repository_dependency_tool_shed = \
+ common_util.remove_protocol_and_port_from_tool_shed_url( str( repository_dependency.tool_shed ) )
+ if cleaned_repository_dependency_tool_shed == cleaned_tool_shed and \
repository_dependency.name == name and \
repository_dependency.owner == owner and \
( repository_dependency.installed_changeset_revision == changeset_revision or \
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 lib/tool_shed/util/common_util.py
--- a/lib/tool_shed/util/common_util.py
+++ b/lib/tool_shed/util/common_util.py
@@ -3,6 +3,7 @@
import urllib2
from galaxy.util import json
from galaxy.util.odict import odict
+from galaxy.web import url_for
from tool_shed.util import encoding_util
from tool_shed.util import xml_util
@@ -28,7 +29,7 @@
return False, odict()
root = tree.getroot()
tool_shed = root.get( 'name' )
- tool_shed_url = get_tool_shed_url_from_tools_xml_file_path( app, tool_shed )
+ tool_shed_url = get_tool_shed_url_from_tool_shed_registry( app, tool_shed )
# The default behavior is that the tool shed is down.
tool_shed_accessible = False
missing_tool_configs_dict = odict()
@@ -52,7 +53,7 @@
tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \
parse_repository_dependency_tuple( rd_tup )
tool_shed_accessible, tool_dependencies = get_tool_dependencies( app,
- tool_shed,
+ tool_shed_url,
name,
owner,
changeset_revision )
@@ -96,6 +97,30 @@
missing_tool_configs_dict[ name ] = migrated_tool_configs_dict[ migrated_tool_config ]
return missing_tool_configs_dict
+def generate_clone_url_for_installed_repository( app, repository ):
+ """Generate the URL for cloning a repository that has been installed into a Galaxy instance."""
+ tool_shed_url = get_tool_shed_url_from_tool_shed_registry( app, str( repository.tool_shed ) )
+ return url_join( tool_shed_url, 'repos', repository.owner, repository.name )
+
+def generate_clone_url_for_repository_in_tool_shed( trans, repository ):
+ """Generate the URL for cloning a repository that is in the tool shed."""
+ base_url = url_for( '/', qualified=True ).rstrip( '/' )
+ if trans and trans.user:
+ protocol, base = base_url.split( '://' )
+ username = '%s@' % trans.user.username
+ return '%s://%s%s/repos/%s/%s' % ( protocol, username, base, repository.user.username, repository.name )
+ else:
+ return '%s/repos/%s/%s' % ( base_url, repository.user.username, repository.name )
+
+def generate_clone_url_from_repo_info_tup( trans, repo_info_tup ):
+ """Generate the URL for cloning a repository given a tuple of toolshed, name, owner, changeset_revision."""
+ # Example tuple: ['http://localhost:9009', 'blast_datatypes', 'test', '461a4216e8ab', False]
+ toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \
+ parse_repository_dependency_tuple( repo_info_tup )
+ tool_shed_url = get_tool_shed_url_from_tool_shed_registry( trans.app, toolshed )
+ # Don't include the changeset_revision in clone urls.
+ return url_join( tool_shed_url, 'repos', owner, name )
+
def get_non_shed_tool_panel_configs( app ):
"""Get the non-shed related tool panel configs - there can be more than one, and the default is tool_conf.xml."""
config_filenames = []
@@ -149,15 +174,44 @@
tool_dependencies.append( ( tool_dependency_name, tool_dependency_version, tool_dependency_type ) )
return tool_shed_accessible, tool_dependencies
-def get_tool_shed_url_from_tools_xml_file_path( app, tool_shed ):
- search_str = '://%s' % tool_shed
+def get_tool_shed_url_from_tool_shed_registry( app, tool_shed ):
+ """
+ The value of tool_shed is something like: toolshed.g2.bx.psu.edu. We need the URL to this tool shed, which is
+ something like: http://toolshed.g2.bx.psu.edu/
+ """
+ cleaned_tool_shed = remove_protocol_from_tool_shed_url( tool_shed )
for shed_name, shed_url in app.tool_shed_registry.tool_sheds.items():
- if shed_url.find( search_str ) >= 0:
+ if shed_url.find( cleaned_tool_shed ) >= 0:
if shed_url.endswith( '/' ):
shed_url = shed_url.rstrip( '/' )
return shed_url
+ # The tool shed from which the repository was originally installed must no longer be configured in tool_sheds_conf.xml.
return None
+def handle_galaxy_url( trans, **kwd ):
+ galaxy_url = kwd.get( 'galaxy_url', None )
+ if galaxy_url:
+ trans.set_cookie( galaxy_url, name='toolshedgalaxyurl' )
+ else:
+ galaxy_url = trans.get_cookie( name='toolshedgalaxyurl' )
+ return galaxy_url
+
+def handle_tool_shed_url_protocol( app, shed_url ):
+ """Handle secure and insecure HTTP protocol since they may change over time."""
+ try:
+ if app.name == 'galaxy':
+ url = remove_protocol_from_tool_shed_url( shed_url )
+ tool_shed_url = get_tool_shed_url_from_tool_shed_registry( app, url )
+ else:
+ tool_shed_url = str( url_for( '/', qualified=True ) ).rstrip( '/' )
+ return tool_shed_url
+ except Exception, e:
+ # We receive a lot of calls here where the tool_shed_url is None. The container_util uses
+ # that value when creating a header row. If the tool_shed_url is not None, we have a problem.
+ if shed_url is not None:
+ log.exception( "Handled exception removing protocol from URL %s:\n%s" % ( str( shed_url ), str( e ) ) )
+ return shed_url
+
def parse_repository_dependency_tuple( repository_dependency_tuple, contains_error=False ):
# Default both prior_installation_required and only_if_compiling_contained_td to False in cases where metadata should be reset on the
# repository containing the repository_dependency definition.
@@ -167,10 +221,11 @@
if len( repository_dependency_tuple ) == 5:
tool_shed, name, owner, changeset_revision, error = repository_dependency_tuple
elif len( repository_dependency_tuple ) == 6:
- toolshed, name, owner, changeset_revision, prior_installation_required, error = repository_dependency_tuple
+ tool_shed, name, owner, changeset_revision, prior_installation_required, error = repository_dependency_tuple
elif len( repository_dependency_tuple ) == 7:
- toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td, error = repository_dependency_tuple
- return toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td, error
+ tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td, error = \
+ repository_dependency_tuple
+ return tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td, error
else:
if len( repository_dependency_tuple ) == 4:
tool_shed, name, owner, changeset_revision = repository_dependency_tuple
@@ -180,6 +235,59 @@
tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = repository_dependency_tuple
return tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td
+def remove_port_from_tool_shed_url( tool_shed_url ):
+ """Return a partial Tool Shed URL, eliminating the port if it exists."""
+ try:
+ if tool_shed_url.find( ':' ) > 0:
+ # Eliminate the port, if any, since it will result in an invalid directory name.
+ new_tool_shed_url = tool_shed_url.split( ':' )[ 0 ]
+ else:
+ new_tool_shed_url = tool_shed_url
+ return new_tool_shed_url.rstrip( '/' )
+ except Exception, e:
+ # We receive a lot of calls here where the tool_shed_url is None. The container_util uses
+ # that value when creating a header row. If the tool_shed_url is not None, we have a problem.
+ if tool_shed_url is not None:
+ log.exception( "Handled exception removing the port from Tool Shed URL %s:\n%s" % ( str( tool_shed_url ), str( e ) ) )
+ return tool_shed_url
+
+def remove_protocol_and_port_from_tool_shed_url( tool_shed_url ):
+ """Return a partial Tool Shed URL, eliminating the protocol and/or port if either exists."""
+ tool_shed = remove_protocol_from_tool_shed_url( tool_shed_url )
+ tool_shed = remove_port_from_tool_shed_url( tool_shed )
+ return tool_shed
+
+def remove_protocol_and_user_from_clone_url( repository_clone_url ):
+ """Return a URL that can be used to clone a repository, eliminating the protocol and user if either exists."""
+ if repository_clone_url.find( '@' ) > 0:
+ # We have an url that includes an authenticated user, something like:
+ # http://test@bx.psu.edu:9009/repos/some_username/column
+ items = repository_clone_url.split( '@' )
+ tmp_url = items[ 1 ]
+ elif repository_clone_url.find( '//' ) > 0:
+ # We have an url that includes only a protocol, something like:
+ # http://bx.psu.edu:9009/repos/some_username/column
+ items = repository_clone_url.split( '//' )
+ tmp_url = items[ 1 ]
+ else:
+ tmp_url = repository_clone_url
+ return tmp_url.rstrip( '/' )
+
+def remove_protocol_from_tool_shed_url( tool_shed_url ):
+ """Return a partial Tool Shed URL, eliminating the protocol if it exists."""
+ try:
+ if tool_shed_url.find( '://' ) > 0:
+ new_tool_shed_url = tool_shed_url.split( '://' )[1]
+ else:
+ new_tool_shed_url = tool_shed_url
+ return new_tool_shed_url.rstrip( '/' )
+ except Exception, e:
+ # We receive a lot of calls here where the tool_shed_url is None. The container_util uses
+ # that value when creating a header row. If the tool_shed_url is not None, we have a problem.
+ if tool_shed_url is not None:
+ log.exception( "Handled exception removing the protocol from Tool Shed URL %s:\n%s" % ( str( tool_shed_url ), str( e ) ) )
+ return tool_shed_url
+
def tool_shed_get( app, tool_shed_url, uri ):
"""Make contact with the tool shed via the uri provided."""
registry = app.tool_shed_registry
@@ -196,3 +304,10 @@
content = response.read()
response.close()
return content
+
+def url_join( *args ):
+ """Return a valid URL produced by appending a base URL and a set of request parameters."""
+ parts = []
+ for arg in args:
+ parts.append( arg.strip( '/' ) )
+ return '/'.join( parts )
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 lib/tool_shed/util/container_util.py
--- a/lib/tool_shed/util/container_util.py
+++ b/lib/tool_shed/util/container_util.py
@@ -65,17 +65,6 @@
if contained_repository_dependency.listify == listified_repository_dependency:
self.repository_dependencies.remove( contained_repository_dependency )
- def to_repository_dependency( self, repository_dependency_id ):
- toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \
- common_util.parse_repository_dependency_tuple( self.key.split( STRSEP ) )
- return RepositoryDependency( id=repository_dependency_id,
- toolshed=toolshed,
- repository_name=name,
- repository_owner=owner,
- changeset_revision=changeset_revision,
- prior_installation_required=galaxy.util.asbool( prior_installation_required ),
- only_if_compiling_contained_td=galaxy.util.asbool( only_if_compiling_contained_td ) )
-
class DataManager( object ):
"""Data Manager object"""
@@ -1525,22 +1514,6 @@
return True
return False
-def cast_empty_repository_dependency_folders( folder, repository_dependency_id ):
- """
- Change any empty folders contained within the repository dependencies container into a repository dependency
- since it has no repository dependencies of it's own. This method is not used (and may not be needed), but here
- it is just in case.
- """
- if not folder.folders and not folder.repository_dependencies:
- repository_dependency_id += 1
- repository_dependency = folder.to_repository_dependency( repository_dependency_id )
- if not folder.parent.contains_repository_dependency( repository_dependency ):
- folder.parent.repository_dependencies.append( repository_dependency )
- folder.parent.folders.remove( folder )
- for sub_folder in folder.folders:
- return cast_empty_repository_dependency_folders( sub_folder, repository_dependency_id )
- return folder, repository_dependency_id
-
def generate_repository_dependencies_folder_label_from_key( repository_name, repository_owner, changeset_revision,
prior_installation_required, only_if_compiling_contained_td, key ):
"""Return a repository dependency label based on the repository dependency key."""
@@ -1562,17 +1535,21 @@
def generate_repository_dependencies_key_for_repository( toolshed_base_url, repository_name, repository_owner, changeset_revision,
prior_installation_required, only_if_compiling_contained_td ):
"""Assumes tool shed is current tool shed since repository dependencies across tool sheds is not yet supported."""
- return '%s%s%s%s%s%s%s%s%s%s%s' % ( str( toolshed_base_url ).rstrip( '/' ),
- STRSEP,
- str( repository_name ),
- STRSEP,
- str( repository_owner ),
- STRSEP,
- str( changeset_revision ),
- STRSEP,
- str( prior_installation_required ),
- STRSEP,
- str( only_if_compiling_contained_td ) )
+ # The tool_shed portion of the key must be the value that is stored in the tool_shed_repository.tool_shed column
+ # of the Galaxy database for an installed repository. This value does not include the protocol, but does include
+ # the port if there is one.
+ tool_shed = common_util.remove_protocol_from_tool_shed_url( toolshed_base_url )
+ return '%s%s%s%s%s%s%s%s%s%s%s' % ( tool_shed,
+ STRSEP,
+ str( repository_name ),
+ STRSEP,
+ str( repository_owner ),
+ STRSEP,
+ str( changeset_revision ),
+ STRSEP,
+ str( prior_installation_required ),
+ STRSEP,
+ str( only_if_compiling_contained_td ) )
def generate_tool_dependencies_key( name, version, type ):
return '%s%s%s%s%s' % ( str( name ), STRSEP, str( version ), STRSEP, str( type ) )
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 lib/tool_shed/util/export_util.py
--- a/lib/tool_shed/util/export_util.py
+++ b/lib/tool_shed/util/export_util.py
@@ -12,6 +12,7 @@
from galaxy.util.odict import odict
from tool_shed.util import commit_util
from tool_shed.util import common_install_util
+from tool_shed.util import common_util
from tool_shed.util import encoding_util
from tool_shed.util import repository_dependency_util
from tool_shed.util import xml_util
@@ -49,12 +50,6 @@
log.exception( error_message )
return return_code, error_message
-def clean_tool_shed_url( base_url ):
- protocol, base = base_url.split( '://' )
- base = base.replace( ':', '_colon_' )
- base = base.rstrip( '/' )
- return base
-
def export_repository( trans, tool_shed_url, repository_id, repository_name, changeset_revision, file_type,
export_repository_dependencies, api=False ):
repository = suc.get_repository_in_tool_shed( trans, repository_id )
@@ -124,8 +119,9 @@
repositories_archive.close()
if api:
encoded_repositories_archive_name = encoding_util.tool_shed_encode( repositories_archive_filename )
- download_url = suc.url_join( web.url_for( '/', qualified=True ),
- 'repository/export_via_api?encoded_repositories_archive_name=%s' % encoded_repositories_archive_name )
+ params = '?encoded_repositories_archive_name=%s' % encoded_repositories_archive_name
+ download_url = common_util.url_join( web.url_for( '/', qualified=True ),
+ 'repository/export_via_api%s' % params )
return dict( download_url=download_url, error_messages=error_messages )
return repositories_archive, error_messages
@@ -171,7 +167,7 @@
return repository_archive, error_message
def generate_repository_archive_filename( tool_shed_url, name, owner, changeset_revision, file_type, export_repository_dependencies=False, use_tmp_archive_dir=False ):
- tool_shed = clean_tool_shed_url( tool_shed_url )
+ tool_shed = remove_protocol_from_tool_shed_url( tool_shed_url )
file_type_str = suc.get_file_type_str( changeset_revision, file_type )
if export_repository_dependencies:
repositories_archive_filename = '%s_%s_%s_%s_%s' % ( CAPSULE_WITH_DEPENDENCIES_FILENAME, tool_shed, name, owner, file_type_str )
@@ -242,7 +238,7 @@
repo_info_dict = {}
# Cast unicode to string.
repo_info_dict[ str( repository.name ) ] = ( str( repository.description ),
- suc.generate_clone_url_for_repository_in_tool_shed( trans, repository ),
+ common_util.generate_clone_url_for_repository_in_tool_shed( trans, repository ),
str( changeset_revision ),
str( ctx.rev() ),
str( repository.user.username ),
@@ -343,3 +339,9 @@
ordered_repositories.append( repository )
ordered_changeset_revisions.append( changeset_revision )
return ordered_repository_ids, ordered_repositories, ordered_changeset_revisions
+
+def remove_protocol_from_tool_shed_url( base_url ):
+ protocol, base = base_url.split( '://' )
+ base = base.replace( ':', '_colon_' )
+ base = base.rstrip( '/' )
+ return base
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 lib/tool_shed/util/import_util.py
--- a/lib/tool_shed/util/import_util.py
+++ b/lib/tool_shed/util/import_util.py
@@ -343,7 +343,6 @@
return_dict[ 'error_message' ] = error_message
return_dict[ 'status' ] = 'error'
uploaded_file.close()
- tar_archive.close()
return return_dict
return_dict[ 'tar_archive' ] = tar_archive
return_dict[ 'capsule_file_name' ] = uploaded_file_filename
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 lib/tool_shed/util/metadata_util.py
--- a/lib/tool_shed/util/metadata_util.py
+++ b/lib/tool_shed/util/metadata_util.py
@@ -206,11 +206,13 @@
for ancestor_tup in ancestor_repository_dependencies:
a_tool_shed, a_repo_name, a_repo_owner, a_changeset_revision, a_prior_installation_required, a_only_if_compiling_contained_td = \
ancestor_tup
+ cleaned_a_tool_shed = common_util.remove_protocol_from_tool_shed_url( a_tool_shed )
found_in_current = False
for current_tup in current_repository_dependencies:
c_tool_shed, c_repo_name, c_repo_owner, c_changeset_revision, c_prior_installation_required, c_only_if_compiling_contained_td = \
current_tup
- if c_tool_shed == a_tool_shed and \
+ cleaned_c_tool_shed = common_util.remove_protocol_from_tool_shed_url( c_tool_shed )
+ if cleaned_c_tool_shed == cleaned_a_tool_shed and \
c_repo_name == a_repo_name and \
c_repo_owner == a_repo_owner and \
c_changeset_revision == a_changeset_revision and \
@@ -369,15 +371,18 @@
def different_revision_defines_tip_only_repository_dependency( trans, rd_tup, repository_dependencies ):
"""
- Determine if the only difference between rd_tup and a dependency definition in the list of repository_dependencies is the changeset_revision value.
+ Determine if the only difference between rd_tup and a dependency definition in the list of
+ repository_dependencies is the changeset_revision value.
"""
new_metadata_required = False
rd_tool_shed, rd_name, rd_owner, rd_changeset_revision, rd_prior_installation_required, rd_only_if_compiling_contained_td = \
common_util.parse_repository_dependency_tuple( rd_tup )
+ cleaned_rd_tool_shed = common_util.remove_protocol_from_tool_shed_url( rd_tool_shed )
for repository_dependency in repository_dependencies:
tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \
common_util.parse_repository_dependency_tuple( repository_dependency )
- if rd_tool_shed == tool_shed and rd_name == name and rd_owner == owner:
+ cleaned_tool_shed = common_util.remove_protocol_from_tool_shed_url( tool_shed )
+ if cleaned_rd_tool_shed == cleaned_tool_shed and rd_name == name and rd_owner == owner:
# Determine if the repository represented by the dependency tuple is an instance of the repository type TipOnly.
required_repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
repository_type_class = trans.app.repository_types_registry.get_class_by_label( required_repository.type )
@@ -393,11 +398,11 @@
# Galaxy Side.
repo_files_directory = repository.repo_files_directory( app )
repo_dir = repo_files_directory
- repository_clone_url = suc.generate_clone_url_for_installed_repository( app, repository )
+ repository_clone_url = common_util.generate_clone_url_for_installed_repository( app, repository )
except AttributeError:
# Tool Shed side.
repo_files_directory = repo_path
- repository_clone_url = suc.generate_clone_url_for_repository_in_tool_shed( None, repository )
+ repository_clone_url = common_util.generate_clone_url_for_repository_in_tool_shed( None, repository )
relative_data_manager_dir = util.relpath( os.path.split( data_manager_config_filename )[0], repo_dir )
rel_data_manager_config_filename = os.path.join( relative_data_manager_dir, os.path.split( data_manager_config_filename )[1] )
data_managers = {}
@@ -572,7 +577,7 @@
return valid_tool_dependencies_dict
def generate_guid_for_object( repository_clone_url, guid_type, obj_id, version ):
- tmp_url = suc.clean_repository_clone_url( repository_clone_url )
+ tmp_url = common_util.remove_protocol_and_user_from_clone_url( repository_clone_url )
return '%s/%s/%s/%s' % ( tmp_url, guid_type, obj_id, version )
def generate_metadata_for_changeset_revision( app, repository, changeset_revision, repository_clone_url,
@@ -1217,16 +1222,16 @@
changeset_revision,
prior_installation_required,
str( only_if_compiling_contained_td ) ]
- cleaned_toolshed = td_common_util.clean_tool_shed_url( toolshed )
user = None
repository = None
+ toolshed = common_util.remove_protocol_from_tool_shed_url( toolshed )
if app.name == 'galaxy':
# We're in Galaxy. We reach here when we're generating the metadata for a tool dependencies package defined
# for a repository or when we're generating metadata for an installed repository. See if we can locate the
# installed repository via the changeset_revision defined in the repository_elem (it may be outdated). If we're
# successful in locating an installed repository with the attributes defined in the repository_elem, we know it
# is valid.
- repository = suc.get_repository_for_dependency_relationship( app, cleaned_toolshed, name, owner, changeset_revision )
+ repository = suc.get_repository_for_dependency_relationship( app, toolshed, name, owner, changeset_revision )
if repository:
return repository_dependency_tup, is_valid, error_message
else:
@@ -1237,7 +1242,7 @@
updated_changeset_revisions = util.listify( text )
for updated_changeset_revision in updated_changeset_revisions:
repository = suc.get_repository_for_dependency_relationship( app,
- cleaned_toolshed,
+ toolshed,
name,
owner,
updated_changeset_revision )
@@ -1648,9 +1653,12 @@
if reinstalling or repository.status not in [ trans.install_model.ToolShedRepository.installation_status.DEACTIVATED,
trans.install_model.ToolShedRepository.installation_status.INSTALLED ]:
# Since we're reinstalling, we need to send a request to the tool shed to get the README files.
- url = suc.url_join( tool_shed_url,
- 'repository/get_readme_files?name=%s&owner=%s&changeset_revision=%s' % \
- ( repository.name, repository.owner, repository.installed_changeset_revision ) )
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, tool_shed_url )
+ params = '?name=%s&owner=%s&changeset_revision=%s' % ( str( repository.name ),
+ str( repository.owner ),
+ str( repository.installed_changeset_revision ) )
+ url = common_util.url_join( tool_shed_url,
+ 'repository/get_readme_files%s' % params )
raw_text = common_util.tool_shed_get( trans.app, tool_shed_url, url )
readme_files_dict = json.from_json_string( raw_text )
else:
@@ -1722,8 +1730,7 @@
def reset_all_metadata_on_installed_repository( trans, id ):
"""Reset all metadata on a single tool shed repository installed into a Galaxy instance."""
repository = suc.get_installed_tool_shed_repository( trans, id )
- tool_shed_url = suc.get_url_from_tool_shed( trans.app, repository.tool_shed )
- repository_clone_url = suc.generate_clone_url_for_installed_repository( trans.app, repository )
+ repository_clone_url = common_util.generate_clone_url_for_installed_repository( trans.app, repository )
tool_path, relative_install_dir = repository.get_tool_relative_path( trans.app )
if relative_install_dir:
original_metadata_dict = repository.metadata
@@ -1791,7 +1798,7 @@
log.debug( "Resetting all metadata on repository: %s" % repository.name )
repo_dir = repository.repo_path( trans.app )
repo = hg.repository( suc.get_configured_ui(), repo_dir )
- repository_clone_url = suc.generate_clone_url_for_repository_in_tool_shed( trans, repository )
+ repository_clone_url = common_util.generate_clone_url_for_repository_in_tool_shed( trans, repository )
# The list of changeset_revisions refers to repository_metadata records that have been created or updated. When the following loop
# completes, we'll delete all repository_metadata records for this repository that do not have a changeset_revision value in this list.
changeset_revisions = []
@@ -1969,7 +1976,7 @@
message = ''
status = 'done'
encoded_id = trans.security.encode_id( repository.id )
- repository_clone_url = suc.generate_clone_url_for_repository_in_tool_shed( trans, repository )
+ repository_clone_url = common_util.generate_clone_url_for_repository_in_tool_shed( trans, repository )
repo_dir = repository.repo_path( trans.app )
repo = hg.repository( suc.get_configured_ui(), repo_dir )
metadata_dict, invalid_file_tups = generate_metadata_for_changeset_revision( app=trans.app,
diff -r 47b3011ebe653f7218c70e0b458252783ef6f255 -r 4aee689e69dac57676de7f9ceb0a31f227bc0dd2 lib/tool_shed/util/readme_util.py
--- a/lib/tool_shed/util/readme_util.py
+++ b/lib/tool_shed/util/readme_util.py
@@ -95,9 +95,11 @@
repo_info_tuple = repo_info_dict[ name ]
description, repository_clone_url, changeset_revision, ctx_rev, repository_owner, repository_dependencies, installed_td = \
suc.get_repo_info_tuple_contents( repo_info_tuple )
- # Handle README files.
- url = suc.url_join( tool_shed_url,
- 'repository/get_readme_files?name=%s&owner=%s&changeset_revision=%s' % ( name, repository_owner, changeset_revision ) )
+ # Handle changing HTTP protocols over time.
+ tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, tool_shed_url )
+ params = '?name=%s&owner=%s&changeset_revision=%s' % ( name, repository_owner, changeset_revision )
+ url = common_util.url_join( tool_shed_url,
+ 'repository/get_readme_files%s' % params )
raw_text = common_util.tool_shed_get( trans.app, tool_shed_url, url )
readme_files_dict = json.from_json_string( raw_text )
return readme_files_dict
This diff is so big that we needed to truncate the remainder.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/44f5b4a2091b/
Changeset: 44f5b4a2091b
Branch: next-stable
User: dan
Date: 2014-04-08 23:05:09
Summary: fix tab spaces in javascript
Affected #: 1 file
diff -r dbfcb1b570763f3e1617ed493d9f1c44e108360e -r 44f5b4a2091bc6e552e0c79a0a761cfc8759a36f templates/webapps/galaxy/dataset/errors.mako
--- a/templates/webapps/galaxy/dataset/errors.mako
+++ b/templates/webapps/galaxy/dataset/errors.mako
@@ -35,10 +35,10 @@
}
var hiddenInput = document.createElement('input');
- hiddenInput.type = 'hidden';
- hiddenInput.name = button.name;
- hiddenInput.value = button.value;
- form.appendChild( hiddenInput );
+ hiddenInput.type = 'hidden';
+ hiddenInput.name = button.name;
+ hiddenInput.value = button.value;
+ form.appendChild( hiddenInput );
return true;
}
return false;
https://bitbucket.org/galaxy/galaxy-central/commits/47b3011ebe65/
Changeset: 47b3011ebe65
User: dan
Date: 2014-04-08 23:05:21
Summary: merge next-stable
Affected #: 1 file
diff -r 2a7447a1d3a23571eb390a0c7cf8a035428ce42b -r 47b3011ebe653f7218c70e0b458252783ef6f255 templates/webapps/galaxy/dataset/errors.mako
--- a/templates/webapps/galaxy/dataset/errors.mako
+++ b/templates/webapps/galaxy/dataset/errors.mako
@@ -35,10 +35,10 @@
}
var hiddenInput = document.createElement('input');
- hiddenInput.type = 'hidden';
- hiddenInput.name = button.name;
- hiddenInput.value = button.value;
- form.appendChild( hiddenInput );
+ hiddenInput.type = 'hidden';
+ hiddenInput.name = button.name;
+ hiddenInput.value = button.value;
+ form.appendChild( hiddenInput );
return true;
}
return false;
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/dbfcb1b57076/
Changeset: dbfcb1b57076
Branch: next-stable
User: dan
Date: 2014-04-08 23:03:19
Summary: When submiting bug reports disable submit buttons while form is being submitted. When submiting bug report to Biostar, have user confirm that they are posting to a public forum.
Affected #: 1 file
diff -r 6eb680d500b14753d7db2efd552613e531541495 -r dbfcb1b570763f3e1617ed493d9f1c44e108360e templates/webapps/galaxy/dataset/errors.mako
--- a/templates/webapps/galaxy/dataset/errors.mako
+++ b/templates/webapps/galaxy/dataset/errors.mako
@@ -14,6 +14,36 @@
padding: 10px;
}
</style>
+
+ <script type="text/javascript">
+ function sendReport( button, form, target, doConfirm )
+ {
+ var doIt = true;
+ if ( doConfirm==true )
+ {
+ doIt = confirm( 'You are about to submit to a public forum, do you want to continue?' );
+ }
+ if ( doIt==true )
+ {
+ form.setAttribute( 'target', target );
+ for( i=0; i<form.elements.length; i++ )
+ {
+ if ( form.elements[i].type == 'submit' )
+ {
+ form.elements[i].disabled = true;
+ }
+
+ }
+ var hiddenInput = document.createElement('input');
+ hiddenInput.type = 'hidden';
+ hiddenInput.name = button.name;
+ hiddenInput.value = button.value;
+ form.appendChild( hiddenInput );
+ return true;
+ }
+ return false;
+ }
+ </script></head><body>
@@ -71,9 +101,9 @@
<textarea name="message" rows="10" cols="40"></textarea></div><div class="form-row">
- <input type="submit" name="submit_error_report" value="Report" onclick="form.setAttribute('target', '_self');"/>
+ <input type="submit" name="submit_error_report" value="Report" onclick="return sendReport( this, this.form, '_self' );"/>
%if trans.app.config.biostar_url:
- <input type="submit" name="submit_error_report" value="Post on Biostar" onclick="form.setAttribute('target', '_blank');"/>
+ <input type="submit" name="submit_error_report" value="Post on Biostar" onclick="return sendReport( this, this.form, '_blank', true );"/>
%endif
</div></form>
https://bitbucket.org/galaxy/galaxy-central/commits/2a7447a1d3a2/
Changeset: 2a7447a1d3a2
User: dan
Date: 2014-04-08 23:03:38
Summary: merge next-stable
Affected #: 1 file
diff -r d79eccd2d0beae713abe1f44b6d2584c8528b03e -r 2a7447a1d3a23571eb390a0c7cf8a035428ce42b templates/webapps/galaxy/dataset/errors.mako
--- a/templates/webapps/galaxy/dataset/errors.mako
+++ b/templates/webapps/galaxy/dataset/errors.mako
@@ -14,6 +14,36 @@
padding: 10px;
}
</style>
+
+ <script type="text/javascript">
+ function sendReport( button, form, target, doConfirm )
+ {
+ var doIt = true;
+ if ( doConfirm==true )
+ {
+ doIt = confirm( 'You are about to submit to a public forum, do you want to continue?' );
+ }
+ if ( doIt==true )
+ {
+ form.setAttribute( 'target', target );
+ for( i=0; i<form.elements.length; i++ )
+ {
+ if ( form.elements[i].type == 'submit' )
+ {
+ form.elements[i].disabled = true;
+ }
+
+ }
+ var hiddenInput = document.createElement('input');
+ hiddenInput.type = 'hidden';
+ hiddenInput.name = button.name;
+ hiddenInput.value = button.value;
+ form.appendChild( hiddenInput );
+ return true;
+ }
+ return false;
+ }
+ </script></head><body>
@@ -71,9 +101,9 @@
<textarea name="message" rows="10" cols="40"></textarea></div><div class="form-row">
- <input type="submit" name="submit_error_report" value="Report" onclick="form.setAttribute('target', '_self');"/>
+ <input type="submit" name="submit_error_report" value="Report" onclick="return sendReport( this, this.form, '_self' );"/>
%if trans.app.config.biostar_url:
- <input type="submit" name="submit_error_report" value="Post on Biostar" onclick="form.setAttribute('target', '_blank');"/>
+ <input type="submit" name="submit_error_report" value="Post on Biostar" onclick="return sendReport( this, this.form, '_blank', true );"/>
%endif
</div></form>
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/6eb680d500b1/
Changeset: 6eb680d500b1
Branch: next-stable
User: carlfeberhard
Date: 2014-04-08 20:14:17
Summary: Remove debugging statements
Affected #: 4 files
diff -r a4d225dbfc8f2d3e7384ab206ecc30c4368b7c94 -r 6eb680d500b14753d7db2efd552613e531541495 static/scripts/galaxy.pages.js
--- a/static/scripts/galaxy.pages.js
+++ b/static/scripts/galaxy.pages.js
@@ -462,7 +462,6 @@
item_info.singular.toLowerCase(), " when it is displayed.]",
"</p>",
"</div>" ].join( '' );
- console.debug( item_embed_html );
// Insert embedded item into document.
//wym.insert(" "); // Needed to prevent insertion from occurring in child element in webkit browsers.
diff -r a4d225dbfc8f2d3e7384ab206ecc30c4368b7c94 -r 6eb680d500b14753d7db2efd552613e531541495 static/scripts/mvc/dataset/hda-base.js
--- a/static/scripts/mvc/dataset/hda-base.js
+++ b/static/scripts/mvc/dataset/hda-base.js
@@ -194,7 +194,6 @@
// add frame manager option onclick event
var self = this;
displayBtnData.onclick = function( ev ){
- console.debug( 'displayBtn onclick', ev );
if( Galaxy.frame && Galaxy.frame.active ){
Galaxy.frame.add({
title : "Data Viewer: " + self.model.get('name'),
diff -r a4d225dbfc8f2d3e7384ab206ecc30c4368b7c94 -r 6eb680d500b14753d7db2efd552613e531541495 static/scripts/packed/galaxy.pages.js
--- a/static/scripts/packed/galaxy.pages.js
+++ b/static/scripts/packed/galaxy.pages.js
@@ -1,1 +1,1 @@
-var Galaxy={ITEM_HISTORY:"item_history",ITEM_DATASET:"item_dataset",ITEM_WORKFLOW:"item_workflow",ITEM_PAGE:"item_page",ITEM_VISUALIZATION:"item_visualization",DIALOG_HISTORY_LINK:"link_history",DIALOG_DATASET_LINK:"link_dataset",DIALOG_WORKFLOW_LINK:"link_workflow",DIALOG_PAGE_LINK:"link_page",DIALOG_VISUALIZATION_LINK:"link_visualization",DIALOG_EMBED_HISTORY:"embed_history",DIALOG_EMBED_DATASET:"embed_dataset",DIALOG_EMBED_WORKFLOW:"embed_workflow",DIALOG_EMBED_PAGE:"embed_page",DIALOG_EMBED_VISUALIZATION:"embed_visualization",DIALOG_HISTORY_ANNOTATE:"history_annotate",};function init_galaxy_elts(a){$(".annotation",a._doc.body).each(function(){$(this).click(function(){var b=a._doc.createRange();b.selectNodeContents(this);var d=window.getSelection();d.removeAllRanges();d.addRange(b);var c=""})})}function get_item_info(d){var f,c,b;switch(d){case (Galaxy.ITEM_HISTORY):f="History";c="Histories";b="history";item_class="History";break;case (Galaxy.ITEM_DATASET):f="Dataset";c="Datasets";b="dataset";item_class="HistoryDatasetAssociation";break;case (Galaxy.ITEM_WORKFLOW):f="Workflow";c="Workflows";b="workflow";item_class="StoredWorkflow";break;case (Galaxy.ITEM_PAGE):f="Page";c="Pages";b="page";item_class="Page";break;case (Galaxy.ITEM_VISUALIZATION):f="Visualization";c="Visualizations";b="visualization";item_class="Visualization";break}var e="list_"+c.toLowerCase()+"_for_selection";var a=list_objects_url.replace("LIST_ACTION",e);return{singular:f,plural:c,controller:b,iclass:item_class,list_ajax_url:a}}function make_item_importable(a,c,b){ajax_url=set_accessible_url.replace("ITEM_CONTROLLER",a);$.ajax({type:"POST",url:ajax_url,data:{id:c,accessible:"True"},error:function(){alert("Making "+b+" accessible failed")}})}WYMeditor.editor.prototype.dialog=function(i,e,g){var a=this;var b=a.uniqueStamp();var f=a.selected();function h(){$("#set_link_id").click(function(){$("#link_attribute_label").text("ID/Name");var k=$(".wym_href");k.addClass("wym_id").removeClass("wym_href");if(f){k.val($(f).attr("id"))}$(this).remove()})}if(i==WYMeditor.DIALOG_LINK){if(f){$(a._options.hrefSelector).val($(f).attr(WYMeditor.HREF));$(a._options.srcSelector).val($(f).attr(WYMeditor.SRC));$(a._options.titleSelector).val($(f).attr(WYMeditor.TITLE));$(a._options.altSelector).val($(f).attr(WYMeditor.ALT))}var c,d;if(f){c=$(f).attr("href");if(c==undefined){c=""}d=$(f).attr("title");if(d==undefined){d=""}}show_modal("Create Link","<div><div><label id='link_attribute_label'>URL <span style='float: right; font-size: 90%'><a href='#' id='set_link_id'>Create in-page anchor</a></span></label><br><input type='text' class='wym_href' value='"+c+"' size='40' /></div><div><label>Title</label><br><input type='text' class='wym_title' value='"+d+"' size='40' /></div><div>",{"Make link":function(){var m=$(a._options.hrefSelector).val()||"",k=$(".wym_id").val()||"",n=$(a._options.titleSelector).val()||"";if(m||k){a._exec(WYMeditor.CREATE_LINK,b);var l=$("a[href="+b+"]",a._doc.body);l.attr(WYMeditor.HREF,m).attr(WYMeditor.TITLE,n).attr("id",k);if(l.text().indexOf("wym-")===0){l.text(n)}}hide_modal()},Cancel:function(){hide_modal()}},{},h)}if(i==WYMeditor.DIALOG_IMAGE){if(a._selected_image){$(a._options.dialogImageSelector+" "+a._options.srcSelector).val($(a._selected_image).attr(WYMeditor.SRC));$(a._options.dialogImageSelector+" "+a._options.titleSelector).val($(a._selected_image).attr(WYMeditor.TITLE));$(a._options.dialogImageSelector+" "+a._options.altSelector).val($(a._selected_image).attr(WYMeditor.ALT))}show_modal("Image","<div class='row'><label>URL</label><br><input type='text' class='wym_src' value='' size='40' /></div><div class='row'><label>Alt text</label><br><input type='text' class='wym_alt' value='' size='40' /></div><div class='row'><label>Title</label><br><input type='text' class='wym_title' value='' size='40' /></div>",{Insert:function(){var k=$(a._options.srcSelector).val();if(k.length>0){a._exec(WYMeditor.INSERT_IMAGE,b);$("img[src$="+b+"]",a._doc.body).attr(WYMeditor.SRC,k).attr(WYMeditor.TITLE,$(a._options.titleSelector).val()).attr(WYMeditor.ALT,$(a._options.altSelector).val())}hide_modal()},Cancel:function(){hide_modal()}});return}if(i==WYMeditor.DIALOG_TABLE){show_modal("Table","<div class='row'><label>Caption</label><br><input type='text' class='wym_caption' value='' size='40' /></div><div class='row'><label>Summary</label><br><input type='text' class='wym_summary' value='' size='40' /></div><div class='row'><label>Number Of Rows<br></label><input type='text' class='wym_rows' value='3' size='3' /></div><div class='row'><label>Number Of Cols<br></label><input type='text' class='wym_cols' value='2' size='3' /></div>",{Insert:function(){var o=$(a._options.rowsSelector).val();var r=$(a._options.colsSelector).val();if(o>0&&r>0){var n=a._doc.createElement(WYMeditor.TABLE);var l=null;var q=null;var k=$(a._options.captionSelector).val();var p=n.createCaption();p.innerHTML=k;for(x=0;x<o;x++){l=n.insertRow(x);for(y=0;y<r;y++){l.insertCell(y)}}$(n).attr("summary",$(a._options.summarySelector).val());var m=$(a.findUp(a.container(),WYMeditor.MAIN_CONTAINERS)).get(0);if(!m||!m.parentNode){$(a._doc.body).append(n)}else{$(m).after(n)}}hide_modal()},Cancel:function(){hide_modal()}})}if(i==Galaxy.DIALOG_HISTORY_LINK||i==Galaxy.DIALOG_DATASET_LINK||i==Galaxy.DIALOG_WORKFLOW_LINK||i==Galaxy.DIALOG_PAGE_LINK||i==Galaxy.DIALOG_VISUALIZATION_LINK){var j;switch(i){case (Galaxy.DIALOG_HISTORY_LINK):j=get_item_info(Galaxy.ITEM_HISTORY);break;case (Galaxy.DIALOG_DATASET_LINK):j=get_item_info(Galaxy.ITEM_DATASET);break;case (Galaxy.DIALOG_WORKFLOW_LINK):j=get_item_info(Galaxy.ITEM_WORKFLOW);break;case (Galaxy.DIALOG_PAGE_LINK):j=get_item_info(Galaxy.ITEM_PAGE);break;case (Galaxy.DIALOG_VISUALIZATION_LINK):j=get_item_info(Galaxy.ITEM_VISUALIZATION);break}$.ajax({url:j.list_ajax_url,data:{},error:function(){alert("Failed to list "+j.plural.toLowerCase()+" for selection")},success:function(k){show_modal("Insert Link to "+j.singular,k+"<div><input id='make-importable' type='checkbox' checked/>Make the selected "+j.plural.toLowerCase()+" accessible so that they can viewed by everyone.</div>",{Insert:function(){var m=false;if($("#make-importable:checked").val()!==null){m=true}var l=new Array();$("input[name=id]:checked").each(function(){var n=$(this).val();if(m){make_item_importable(j.controller,n,j.singular)}url_template=get_name_and_link_url+n;ajax_url=url_template.replace("ITEM_CONTROLLER",j.controller);$.getJSON(ajax_url,function(p){a._exec(WYMeditor.CREATE_LINK,b);var o=$("a[href="+b+"]",a._doc.body).text();if(o==""||o==b){a.insert("<a href='"+p.link+"'>"+j.singular+" '"+p.name+"'</a>")}else{$("a[href="+b+"]",a._doc.body).attr(WYMeditor.HREF,p.link).attr(WYMeditor.TITLE,j.singular+n)}})});hide_modal()},Cancel:function(){hide_modal()}})}})}if(i==Galaxy.DIALOG_EMBED_HISTORY||i==Galaxy.DIALOG_EMBED_DATASET||i==Galaxy.DIALOG_EMBED_WORKFLOW||i==Galaxy.DIALOG_EMBED_PAGE||i==Galaxy.DIALOG_EMBED_VISUALIZATION){var j;switch(i){case (Galaxy.DIALOG_EMBED_HISTORY):j=get_item_info(Galaxy.ITEM_HISTORY);break;case (Galaxy.DIALOG_EMBED_DATASET):j=get_item_info(Galaxy.ITEM_DATASET);break;case (Galaxy.DIALOG_EMBED_WORKFLOW):j=get_item_info(Galaxy.ITEM_WORKFLOW);break;case (Galaxy.DIALOG_EMBED_PAGE):j=get_item_info(Galaxy.ITEM_PAGE);break;case (Galaxy.DIALOG_EMBED_VISUALIZATION):j=get_item_info(Galaxy.ITEM_VISUALIZATION);break}$.ajax({url:j.list_ajax_url,data:{},error:function(){alert("Failed to list "+j.plural.toLowerCase()+" for selection")},success:function(k){if(i==Galaxy.DIALOG_EMBED_HISTORY||i==Galaxy.DIALOG_EMBED_WORKFLOW||i==Galaxy.DIALOG_EMBED_VISUALIZATION){k=k+"<div><input id='make-importable' type='checkbox' checked/>Make the selected "+j.plural.toLowerCase()+" accessible so that they can viewed by everyone.</div>"}show_modal("Embed "+j.plural,k,{Embed:function(){var l=false;if($("#make-importable:checked").val()!=null){l=true}$("input[name=id]:checked").each(function(){var m=$(this).val();var p=$("label[for='"+m+"']:first").text();if(l){make_item_importable(j.controller,m,j.singular)}var n=j.iclass+"-"+m;var o=["<div id='",n,"' class='embedded-item ",j.singular.toLowerCase()," placeholder'>","<p class='title'>","Embedded Galaxy ",j.singular," '",p,"'","</p>","<p class='content'>","[Do not edit this block; Galaxy will fill it in with the annotated ",j.singular.toLowerCase()," when it is displayed.]","</p>","</div>"].join("");console.debug(o);a.insert(o)});hide_modal()},Cancel:function(){hide_modal()}})}})}if(i==Galaxy.DIALOG_ANNOTATE_HISTORY){$.ajax({url:list_histories_for_selection_url,data:{},error:function(){alert("Grid refresh failed")},success:function(k){show_modal("Insert Link to History",k,{Annotate:function(){var l=new Array();$("input[name=id]:checked").each(function(){var m=$(this).val();$.ajax({url:get_history_annotation_table_url,data:{id:m},error:function(){alert("Grid refresh failed")},success:function(n){a.insert(n);init_galaxy_elts(a)}})});hide_modal()},Cancel:function(){hide_modal()}})}})}};$(function(){$(document).ajaxError(function(i,g){var h=g.responseText||g.statusText||"Could not connect to server";show_modal("Server error",h,{"Ignore error":hide_modal});return false});$("[name=page_content]").wymeditor({skin:"galaxy",basePath:editor_base_path,iframeBasePath:iframe_base_path,boxHtml:"<table class='wym_box' width='100%' height='100%'><tr><td><div class='wym_area_top'>"+WYMeditor.TOOLS+"</div></td></tr><tr height='100%'><td><div class='wym_area_main' style='height: 100%;'>"+WYMeditor.IFRAME+WYMeditor.STATUS+"</div></div></td></tr></table>",toolsItems:[{name:"Bold",title:"Strong",css:"wym_tools_strong"},{name:"Italic",title:"Emphasis",css:"wym_tools_emphasis"},{name:"Superscript",title:"Superscript",css:"wym_tools_superscript"},{name:"Subscript",title:"Subscript",css:"wym_tools_subscript"},{name:"InsertOrderedList",title:"Ordered_List",css:"wym_tools_ordered_list"},{name:"InsertUnorderedList",title:"Unordered_List",css:"wym_tools_unordered_list"},{name:"Indent",title:"Indent",css:"wym_tools_indent"},{name:"Outdent",title:"Outdent",css:"wym_tools_outdent"},{name:"Undo",title:"Undo",css:"wym_tools_undo"},{name:"Redo",title:"Redo",css:"wym_tools_redo"},{name:"CreateLink",title:"Link",css:"wym_tools_link"},{name:"Unlink",title:"Unlink",css:"wym_tools_unlink"},{name:"InsertImage",title:"Image",css:"wym_tools_image"},{name:"InsertTable",title:"Table",css:"wym_tools_table"},]});var d=$.wymeditors(0);var f=function(g){show_modal("Saving page","progress");$.ajax({url:save_url,type:"POST",data:{id:page_id,content:d.xhtml(),annotations:JSON.stringify(new Object()),_:"true"},success:function(){g()}})};$("#save-button").click(function(){f(function(){hide_modal()})});$("#close-button").click(function(){var h=false;if(h){var g=function(){window.onbeforeunload=undefined;window.document.location=page_list_url};show_modal("Close editor","There are unsaved changes to your page which will be lost.",{Cancel:hide_modal,"Save Changes":function(){f(g)}},{"Don't Save":g})}else{window.document.location=page_list_url}});var a=$("<div class='galaxy-page-editor-button'><a id='insert-galaxy-link' class='action-button popup' href='#'>Paragraph type</a></div>");$(".wym_area_top").append(a);var b={};$.each(d._options.containersItems,function(h,g){var i=g.name;b[g.title.replace("_"," ")]=function(){d.container(i)}});make_popupmenu(a,b);var c=$("<div><a id='insert-galaxy-link' class='action-button popup' href='#'>Insert Link to Galaxy Object</a></div>").addClass("galaxy-page-editor-button");$(".wym_area_top").append(c);make_popupmenu(c,{"Insert History Link":function(){d.dialog(Galaxy.DIALOG_HISTORY_LINK)},"Insert Dataset Link":function(){d.dialog(Galaxy.DIALOG_DATASET_LINK)},"Insert Workflow Link":function(){d.dialog(Galaxy.DIALOG_WORKFLOW_LINK)},"Insert Page Link":function(){d.dialog(Galaxy.DIALOG_PAGE_LINK)},"Insert Visualization Link":function(){d.dialog(Galaxy.DIALOG_VISUALIZATION_LINK)},});var e=$("<div><a id='embed-galaxy-object' class='action-button popup' href='#'>Embed Galaxy Object</a></div>").addClass("galaxy-page-editor-button");$(".wym_area_top").append(e);make_popupmenu(e,{"Embed History":function(){d.dialog(Galaxy.DIALOG_EMBED_HISTORY)},"Embed Dataset":function(){d.dialog(Galaxy.DIALOG_EMBED_DATASET)},"Embed Workflow":function(){d.dialog(Galaxy.DIALOG_EMBED_WORKFLOW)},"Embed Visualization":function(){d.dialog(Galaxy.DIALOG_EMBED_VISUALIZATION)},})});
\ No newline at end of file
+var Galaxy={ITEM_HISTORY:"item_history",ITEM_DATASET:"item_dataset",ITEM_WORKFLOW:"item_workflow",ITEM_PAGE:"item_page",ITEM_VISUALIZATION:"item_visualization",DIALOG_HISTORY_LINK:"link_history",DIALOG_DATASET_LINK:"link_dataset",DIALOG_WORKFLOW_LINK:"link_workflow",DIALOG_PAGE_LINK:"link_page",DIALOG_VISUALIZATION_LINK:"link_visualization",DIALOG_EMBED_HISTORY:"embed_history",DIALOG_EMBED_DATASET:"embed_dataset",DIALOG_EMBED_WORKFLOW:"embed_workflow",DIALOG_EMBED_PAGE:"embed_page",DIALOG_EMBED_VISUALIZATION:"embed_visualization",DIALOG_HISTORY_ANNOTATE:"history_annotate",};function init_galaxy_elts(a){$(".annotation",a._doc.body).each(function(){$(this).click(function(){var b=a._doc.createRange();b.selectNodeContents(this);var d=window.getSelection();d.removeAllRanges();d.addRange(b);var c=""})})}function get_item_info(d){var f,c,b;switch(d){case (Galaxy.ITEM_HISTORY):f="History";c="Histories";b="history";item_class="History";break;case (Galaxy.ITEM_DATASET):f="Dataset";c="Datasets";b="dataset";item_class="HistoryDatasetAssociation";break;case (Galaxy.ITEM_WORKFLOW):f="Workflow";c="Workflows";b="workflow";item_class="StoredWorkflow";break;case (Galaxy.ITEM_PAGE):f="Page";c="Pages";b="page";item_class="Page";break;case (Galaxy.ITEM_VISUALIZATION):f="Visualization";c="Visualizations";b="visualization";item_class="Visualization";break}var e="list_"+c.toLowerCase()+"_for_selection";var a=list_objects_url.replace("LIST_ACTION",e);return{singular:f,plural:c,controller:b,iclass:item_class,list_ajax_url:a}}function make_item_importable(a,c,b){ajax_url=set_accessible_url.replace("ITEM_CONTROLLER",a);$.ajax({type:"POST",url:ajax_url,data:{id:c,accessible:"True"},error:function(){alert("Making "+b+" accessible failed")}})}WYMeditor.editor.prototype.dialog=function(i,e,g){var a=this;var b=a.uniqueStamp();var f=a.selected();function h(){$("#set_link_id").click(function(){$("#link_attribute_label").text("ID/Name");var k=$(".wym_href");k.addClass("wym_id").removeClass("wym_href");if(f){k.val($(f).attr("id"))}$(this).remove()})}if(i==WYMeditor.DIALOG_LINK){if(f){$(a._options.hrefSelector).val($(f).attr(WYMeditor.HREF));$(a._options.srcSelector).val($(f).attr(WYMeditor.SRC));$(a._options.titleSelector).val($(f).attr(WYMeditor.TITLE));$(a._options.altSelector).val($(f).attr(WYMeditor.ALT))}var c,d;if(f){c=$(f).attr("href");if(c==undefined){c=""}d=$(f).attr("title");if(d==undefined){d=""}}show_modal("Create Link","<div><div><label id='link_attribute_label'>URL <span style='float: right; font-size: 90%'><a href='#' id='set_link_id'>Create in-page anchor</a></span></label><br><input type='text' class='wym_href' value='"+c+"' size='40' /></div><div><label>Title</label><br><input type='text' class='wym_title' value='"+d+"' size='40' /></div><div>",{"Make link":function(){var m=$(a._options.hrefSelector).val()||"",k=$(".wym_id").val()||"",n=$(a._options.titleSelector).val()||"";if(m||k){a._exec(WYMeditor.CREATE_LINK,b);var l=$("a[href="+b+"]",a._doc.body);l.attr(WYMeditor.HREF,m).attr(WYMeditor.TITLE,n).attr("id",k);if(l.text().indexOf("wym-")===0){l.text(n)}}hide_modal()},Cancel:function(){hide_modal()}},{},h)}if(i==WYMeditor.DIALOG_IMAGE){if(a._selected_image){$(a._options.dialogImageSelector+" "+a._options.srcSelector).val($(a._selected_image).attr(WYMeditor.SRC));$(a._options.dialogImageSelector+" "+a._options.titleSelector).val($(a._selected_image).attr(WYMeditor.TITLE));$(a._options.dialogImageSelector+" "+a._options.altSelector).val($(a._selected_image).attr(WYMeditor.ALT))}show_modal("Image","<div class='row'><label>URL</label><br><input type='text' class='wym_src' value='' size='40' /></div><div class='row'><label>Alt text</label><br><input type='text' class='wym_alt' value='' size='40' /></div><div class='row'><label>Title</label><br><input type='text' class='wym_title' value='' size='40' /></div>",{Insert:function(){var k=$(a._options.srcSelector).val();if(k.length>0){a._exec(WYMeditor.INSERT_IMAGE,b);$("img[src$="+b+"]",a._doc.body).attr(WYMeditor.SRC,k).attr(WYMeditor.TITLE,$(a._options.titleSelector).val()).attr(WYMeditor.ALT,$(a._options.altSelector).val())}hide_modal()},Cancel:function(){hide_modal()}});return}if(i==WYMeditor.DIALOG_TABLE){show_modal("Table","<div class='row'><label>Caption</label><br><input type='text' class='wym_caption' value='' size='40' /></div><div class='row'><label>Summary</label><br><input type='text' class='wym_summary' value='' size='40' /></div><div class='row'><label>Number Of Rows<br></label><input type='text' class='wym_rows' value='3' size='3' /></div><div class='row'><label>Number Of Cols<br></label><input type='text' class='wym_cols' value='2' size='3' /></div>",{Insert:function(){var o=$(a._options.rowsSelector).val();var r=$(a._options.colsSelector).val();if(o>0&&r>0){var n=a._doc.createElement(WYMeditor.TABLE);var l=null;var q=null;var k=$(a._options.captionSelector).val();var p=n.createCaption();p.innerHTML=k;for(x=0;x<o;x++){l=n.insertRow(x);for(y=0;y<r;y++){l.insertCell(y)}}$(n).attr("summary",$(a._options.summarySelector).val());var m=$(a.findUp(a.container(),WYMeditor.MAIN_CONTAINERS)).get(0);if(!m||!m.parentNode){$(a._doc.body).append(n)}else{$(m).after(n)}}hide_modal()},Cancel:function(){hide_modal()}})}if(i==Galaxy.DIALOG_HISTORY_LINK||i==Galaxy.DIALOG_DATASET_LINK||i==Galaxy.DIALOG_WORKFLOW_LINK||i==Galaxy.DIALOG_PAGE_LINK||i==Galaxy.DIALOG_VISUALIZATION_LINK){var j;switch(i){case (Galaxy.DIALOG_HISTORY_LINK):j=get_item_info(Galaxy.ITEM_HISTORY);break;case (Galaxy.DIALOG_DATASET_LINK):j=get_item_info(Galaxy.ITEM_DATASET);break;case (Galaxy.DIALOG_WORKFLOW_LINK):j=get_item_info(Galaxy.ITEM_WORKFLOW);break;case (Galaxy.DIALOG_PAGE_LINK):j=get_item_info(Galaxy.ITEM_PAGE);break;case (Galaxy.DIALOG_VISUALIZATION_LINK):j=get_item_info(Galaxy.ITEM_VISUALIZATION);break}$.ajax({url:j.list_ajax_url,data:{},error:function(){alert("Failed to list "+j.plural.toLowerCase()+" for selection")},success:function(k){show_modal("Insert Link to "+j.singular,k+"<div><input id='make-importable' type='checkbox' checked/>Make the selected "+j.plural.toLowerCase()+" accessible so that they can viewed by everyone.</div>",{Insert:function(){var m=false;if($("#make-importable:checked").val()!==null){m=true}var l=new Array();$("input[name=id]:checked").each(function(){var n=$(this).val();if(m){make_item_importable(j.controller,n,j.singular)}url_template=get_name_and_link_url+n;ajax_url=url_template.replace("ITEM_CONTROLLER",j.controller);$.getJSON(ajax_url,function(p){a._exec(WYMeditor.CREATE_LINK,b);var o=$("a[href="+b+"]",a._doc.body).text();if(o==""||o==b){a.insert("<a href='"+p.link+"'>"+j.singular+" '"+p.name+"'</a>")}else{$("a[href="+b+"]",a._doc.body).attr(WYMeditor.HREF,p.link).attr(WYMeditor.TITLE,j.singular+n)}})});hide_modal()},Cancel:function(){hide_modal()}})}})}if(i==Galaxy.DIALOG_EMBED_HISTORY||i==Galaxy.DIALOG_EMBED_DATASET||i==Galaxy.DIALOG_EMBED_WORKFLOW||i==Galaxy.DIALOG_EMBED_PAGE||i==Galaxy.DIALOG_EMBED_VISUALIZATION){var j;switch(i){case (Galaxy.DIALOG_EMBED_HISTORY):j=get_item_info(Galaxy.ITEM_HISTORY);break;case (Galaxy.DIALOG_EMBED_DATASET):j=get_item_info(Galaxy.ITEM_DATASET);break;case (Galaxy.DIALOG_EMBED_WORKFLOW):j=get_item_info(Galaxy.ITEM_WORKFLOW);break;case (Galaxy.DIALOG_EMBED_PAGE):j=get_item_info(Galaxy.ITEM_PAGE);break;case (Galaxy.DIALOG_EMBED_VISUALIZATION):j=get_item_info(Galaxy.ITEM_VISUALIZATION);break}$.ajax({url:j.list_ajax_url,data:{},error:function(){alert("Failed to list "+j.plural.toLowerCase()+" for selection")},success:function(k){if(i==Galaxy.DIALOG_EMBED_HISTORY||i==Galaxy.DIALOG_EMBED_WORKFLOW||i==Galaxy.DIALOG_EMBED_VISUALIZATION){k=k+"<div><input id='make-importable' type='checkbox' checked/>Make the selected "+j.plural.toLowerCase()+" accessible so that they can viewed by everyone.</div>"}show_modal("Embed "+j.plural,k,{Embed:function(){var l=false;if($("#make-importable:checked").val()!=null){l=true}$("input[name=id]:checked").each(function(){var m=$(this).val();var p=$("label[for='"+m+"']:first").text();if(l){make_item_importable(j.controller,m,j.singular)}var n=j.iclass+"-"+m;var o=["<div id='",n,"' class='embedded-item ",j.singular.toLowerCase()," placeholder'>","<p class='title'>","Embedded Galaxy ",j.singular," '",p,"'","</p>","<p class='content'>","[Do not edit this block; Galaxy will fill it in with the annotated ",j.singular.toLowerCase()," when it is displayed.]","</p>","</div>"].join("");a.insert(o)});hide_modal()},Cancel:function(){hide_modal()}})}})}if(i==Galaxy.DIALOG_ANNOTATE_HISTORY){$.ajax({url:list_histories_for_selection_url,data:{},error:function(){alert("Grid refresh failed")},success:function(k){show_modal("Insert Link to History",k,{Annotate:function(){var l=new Array();$("input[name=id]:checked").each(function(){var m=$(this).val();$.ajax({url:get_history_annotation_table_url,data:{id:m},error:function(){alert("Grid refresh failed")},success:function(n){a.insert(n);init_galaxy_elts(a)}})});hide_modal()},Cancel:function(){hide_modal()}})}})}};$(function(){$(document).ajaxError(function(i,g){var h=g.responseText||g.statusText||"Could not connect to server";show_modal("Server error",h,{"Ignore error":hide_modal});return false});$("[name=page_content]").wymeditor({skin:"galaxy",basePath:editor_base_path,iframeBasePath:iframe_base_path,boxHtml:"<table class='wym_box' width='100%' height='100%'><tr><td><div class='wym_area_top'>"+WYMeditor.TOOLS+"</div></td></tr><tr height='100%'><td><div class='wym_area_main' style='height: 100%;'>"+WYMeditor.IFRAME+WYMeditor.STATUS+"</div></div></td></tr></table>",toolsItems:[{name:"Bold",title:"Strong",css:"wym_tools_strong"},{name:"Italic",title:"Emphasis",css:"wym_tools_emphasis"},{name:"Superscript",title:"Superscript",css:"wym_tools_superscript"},{name:"Subscript",title:"Subscript",css:"wym_tools_subscript"},{name:"InsertOrderedList",title:"Ordered_List",css:"wym_tools_ordered_list"},{name:"InsertUnorderedList",title:"Unordered_List",css:"wym_tools_unordered_list"},{name:"Indent",title:"Indent",css:"wym_tools_indent"},{name:"Outdent",title:"Outdent",css:"wym_tools_outdent"},{name:"Undo",title:"Undo",css:"wym_tools_undo"},{name:"Redo",title:"Redo",css:"wym_tools_redo"},{name:"CreateLink",title:"Link",css:"wym_tools_link"},{name:"Unlink",title:"Unlink",css:"wym_tools_unlink"},{name:"InsertImage",title:"Image",css:"wym_tools_image"},{name:"InsertTable",title:"Table",css:"wym_tools_table"},]});var d=$.wymeditors(0);var f=function(g){show_modal("Saving page","progress");$.ajax({url:save_url,type:"POST",data:{id:page_id,content:d.xhtml(),annotations:JSON.stringify(new Object()),_:"true"},success:function(){g()}})};$("#save-button").click(function(){f(function(){hide_modal()})});$("#close-button").click(function(){var h=false;if(h){var g=function(){window.onbeforeunload=undefined;window.document.location=page_list_url};show_modal("Close editor","There are unsaved changes to your page which will be lost.",{Cancel:hide_modal,"Save Changes":function(){f(g)}},{"Don't Save":g})}else{window.document.location=page_list_url}});var a=$("<div class='galaxy-page-editor-button'><a id='insert-galaxy-link' class='action-button popup' href='#'>Paragraph type</a></div>");$(".wym_area_top").append(a);var b={};$.each(d._options.containersItems,function(h,g){var i=g.name;b[g.title.replace("_"," ")]=function(){d.container(i)}});make_popupmenu(a,b);var c=$("<div><a id='insert-galaxy-link' class='action-button popup' href='#'>Insert Link to Galaxy Object</a></div>").addClass("galaxy-page-editor-button");$(".wym_area_top").append(c);make_popupmenu(c,{"Insert History Link":function(){d.dialog(Galaxy.DIALOG_HISTORY_LINK)},"Insert Dataset Link":function(){d.dialog(Galaxy.DIALOG_DATASET_LINK)},"Insert Workflow Link":function(){d.dialog(Galaxy.DIALOG_WORKFLOW_LINK)},"Insert Page Link":function(){d.dialog(Galaxy.DIALOG_PAGE_LINK)},"Insert Visualization Link":function(){d.dialog(Galaxy.DIALOG_VISUALIZATION_LINK)},});var e=$("<div><a id='embed-galaxy-object' class='action-button popup' href='#'>Embed Galaxy Object</a></div>").addClass("galaxy-page-editor-button");$(".wym_area_top").append(e);make_popupmenu(e,{"Embed History":function(){d.dialog(Galaxy.DIALOG_EMBED_HISTORY)},"Embed Dataset":function(){d.dialog(Galaxy.DIALOG_EMBED_DATASET)},"Embed Workflow":function(){d.dialog(Galaxy.DIALOG_EMBED_WORKFLOW)},"Embed Visualization":function(){d.dialog(Galaxy.DIALOG_EMBED_VISUALIZATION)},})});
\ No newline at end of file
diff -r a4d225dbfc8f2d3e7384ab206ecc30c4368b7c94 -r 6eb680d500b14753d7db2efd552613e531541495 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"],function(d,b){var c=Backbone.View.extend(b.LoggableMixin).extend({tagName:"div",className:"dataset hda history-panel-hda",id:function(){return"hda-"+this.model.get("id")},fxSpeed:"fast",initialize:function(f){if(f.logger){this.logger=this.model.logger=f.logger}this.log(this+".initialize:",f);this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton];this.linkTarget=f.linkTarget||"_blank";this.selectable=f.selectable||false;this.selected=f.selected||false;this.expanded=f.expanded||false;this.draggable=f.draggable||false;this._setUpListeners()},_setUpListeners:function(){this.model.on("change",function(g,f){if(this.model.changedAttributes().state&&this.model.inReadyState()&&this.expanded&&!this.model.hasDetails()){this.model.fetch()}else{this.render()}},this)},render:function(h){h=(h===undefined)?(true):(h);var f=this;this.$el.find("[title]").tooltip("destroy");this.urls=this.model.urls();var g=this._buildNewRender();if(h){$(f).queue(function(i){this.$el.fadeOut(f.fxSpeed,i)})}$(f).queue(function(i){this.$el.empty().attr("class",f.className).addClass("state-"+f.model.get("state")).append(g.children());if(this.selectable){this.showSelector(0)}i()});if(h){$(f).queue(function(i){this.$el.fadeIn(f.fxSpeed,i)})}$(f).queue(function(i){this.trigger("rendered",f);if(this.model.inReadyState()){this.trigger("rendered:ready",f)}if(this.draggable){this.draggableOn()}i()});return this},_buildNewRender:function(){var f=$(c.templates.skeleton(this.model.toJSON()));f.find(".dataset-primary-actions").append(this._render_titleButtons());f.children(".dataset-body").replaceWith(this._render_body());this._setUpBehaviors(f);return f},_setUpBehaviors:function(f){f=f||this.$el;make_popup_menus(f);f.find("[title]").tooltip({placement:"bottom"})},_render_titleButtons:function(){return[this._render_displayButton()]},_render_displayButton:function(){if((this.model.get("state")===d.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.DISCARDED)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.NEW)||(!this.model.get("accessible"))){return null}var g={target:this.linkTarget,classes:"dataset-display"};if(this.model.get("purged")){g.disabled=true;g.title=_l("Cannot display datasets removed from disk")}else{if(this.model.get("state")===d.HistoryDatasetAssociation.STATES.UPLOAD){g.disabled=true;g.title=_l("This dataset must finish uploading before it can be viewed")}else{g.title=_l("View data");g.href=this.urls.display;var f=this;g.onclick=function(h){console.debug("displayBtn onclick",h);if(Galaxy.frame&&Galaxy.frame.active){Galaxy.frame.add({title:"Data Viewer: "+f.model.get("name"),type:"url",content:f.urls.display});h.preventDefault()}}}}g.faIcon="fa-eye";return faIconButton(g)},_render_downloadButton:function(){if(this.model.get("purged")||!this.model.hasData()){return null}var g=this.urls,h=this.model.get("meta_files");if(_.isEmpty(h)){return $(['<a href="'+g.download+'" title="'+_l("Download")+'" ','class="icon-btn dataset-download-btn">','<span class="fa fa-floppy-o"></span>',"</a>"].join(""))}var i="dataset-"+this.model.get("id")+"-popup",f=['<div popupmenu="'+i+'">','<a href="'+g.download+'">',_l("Download Dataset"),"</a>","<a>"+_l("Additional Files")+"</a>",_.map(h,function(j){return['<a class="action-button" href="',g.meta_download+j.file_type,'">',_l("Download")," ",j.file_type,"</a>"].join("")}).join("\n"),"</div>",'<div class="icon-btn-group">','<a href="'+g.download+'" title="'+_l("Download")+'" ','class="icon-btn dataset-download-btn">','<span class="fa fa-floppy-o"></span>','</a><a class="icon-btn popup" id="'+i+'">','<span class="fa fa-caret-down"></span>',"</a>","</div>"].join("\n");return $(f)},_render_showParamsButton:function(){return faIconButton({title:_l("View details"),classes:"dataset-params-btn",href:this.urls.show_params,target:this.linkTarget,faIcon:"fa-info-circle"})},_render_body:function(){var g=$('<div>Error: unknown dataset state "'+this.model.get("state")+'".</div>'),f=this["_render_body_"+this.model.get("state")];if(_.isFunction(f)){g=f.call(this)}this._setUpBehaviors(g);if(this.expanded){g.show()}return g},_render_stateBodyHelper:function(f,i){i=i||[];var g=this,h=$(c.templates.body(_.extend(this.model.toJSON(),{body:f})));h.find(".dataset-actions .left").append(_.map(i,function(j){return j.call(g)}));return h},_render_body_new:function(){return this._render_stateBodyHelper("<div>"+_l("This is a new dataset and not all of its data are available yet")+"</div>")},_render_body_noPermission:function(){return this._render_stateBodyHelper("<div>"+_l("You do not have permission to view this dataset")+"</div>")},_render_body_discarded:function(){return this._render_stateBodyHelper("<div>"+_l("The job creating this dataset was cancelled before completion")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_queued:function(){return this._render_stateBodyHelper("<div>"+_l("This job is waiting to run")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_upload:function(){return this._render_stateBodyHelper("<div>"+_l("This dataset is currently uploading")+"</div>")},_render_body_setting_metadata:function(){return this._render_stateBodyHelper("<div>"+_l("Metadata is being auto-detected")+"</div>")},_render_body_running:function(){return this._render_stateBodyHelper("<div>"+_l("This job is currently running")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_paused:function(){return this._render_stateBodyHelper("<div>"+_l('This job is paused. Use the "Resume Paused Jobs" in the history menu to resume')+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_error:function(){var f=['<span class="help-text">',_l("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")){f="<div>"+this.model.get("misc_blurb")+"</div>"+f}return this._render_stateBodyHelper(f,[this._render_downloadButton].concat(this.defaultPrimaryActionButtonRenderers))},_render_body_empty:function(){return this._render_stateBodyHelper("<div>"+_l("No data")+": <i>"+this.model.get("misc_blurb")+"</i></div>",this.defaultPrimaryActionButtonRenderers)},_render_body_failed_metadata:function(){var f=$('<div class="warningmessagesmall"></div>').append($("<strong/>").text(_l("An error occurred setting the metadata for this dataset"))),g=this._render_body_ok();g.prepend(f);return g},_render_body_ok:function(){var f=this,h=$(c.templates.body(this.model.toJSON())),g=[this._render_downloadButton].concat(this.defaultPrimaryActionButtonRenderers);h.find(".dataset-actions .left").append(_.map(g,function(i){return i.call(f)}));if(this.model.isDeletedOrPurged()){return h}return h},events:{"click .dataset-title-bar":"toggleBodyVisibility","keydown .dataset-title-bar":"toggleBodyVisibility","click .dataset-selector":"toggleSelect"},toggleBodyVisibility:function(i,g){var f=32,h=13;if(i&&(i.type==="keydown")&&!(i.keyCode===f||i.keyCode===h)){return true}var j=this.$el.find(".dataset-body");g=(g===undefined)?(!j.is(":visible")):(g);if(g){this.expandBody()}else{this.collapseBody()}return false},expandBody:function(){var f=this;function g(){f.$el.children(".dataset-body").replaceWith(f._render_body());f.$el.children(".dataset-body").slideDown(f.fxSpeed,function(){f.expanded=true;f.trigger("body-expanded",f.model.get("id"))})}if(this.model.inReadyState()&&!this.model.hasDetails()){this.model.fetch({silent:true}).always(function(h){f.urls=f.model.urls();g()})}else{g()}},collapseBody:function(){var f=this;this.$el.children(".dataset-body").slideUp(f.fxSpeed,function(){f.expanded=false;f.trigger("body-collapsed",f.model.get("id"))})},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(f){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(f){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(f){if(this.selected){this.deselect(f)}else{this.select(f)}},draggableOn:function(){this.draggable=true;this.dragStartHandler=_.bind(this._dragStartHandler,this);this.dragEndHandler=_.bind(this._dragEndHandler,this);var f=this.$el.find(".dataset-title-bar").attr("draggable",true).get(0);f.addEventListener("dragstart",this.dragStartHandler,false);f.addEventListener("dragend",this.dragEndHandler,false)},draggableOff:function(){this.draggable=false;var f=this.$el.find(".dataset-title-bar").attr("draggable",false).get(0);f.removeEventListener("dragstart",this.dragStartHandler,false);f.removeEventListener("dragend",this.dragEndHandler,false)},toggleDraggable:function(){if(this.draggable){this.draggableOff()}else{this.draggableOn()}},_dragStartHandler:function(f){this.trigger("dragstart",this);f.dataTransfer.effectAllowed="move";f.dataTransfer.setData("text",JSON.stringify(this.model.toJSON()));return false},_dragEndHandler:function(f){this.trigger("dragend",this);return false},remove:function(g){var f=this;this.$el.fadeOut(f.fxSpeed,function(){f.$el.remove();f.off();if(g){g()}})},toString:function(){var f=(this.model)?(this.model+""):("(no model)");return"HDABaseView("+f+")"}});var a=['<div class="dataset hda">','<div class="dataset-warnings">',"<% if( hda.error ){ %>",'<div class="errormessagesmall">',_l("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>',_l("This dataset has been deleted and removed from disk."),"</strong></div>","<% } else { %>",'<div class="dataset-deleted-msg warningmessagesmall"><strong>',_l("This dataset has been deleted."),"</strong></div>","<% } %>","<% } %>","<% if( !hda.visible ){ %>",'<div class="dataset-hidden-msg warningmessagesmall"><strong>',_l("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 e=['<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">',_l("format"),"</label>",'<span class="value"><%- hda.data_type %></span>',"</div>","<% } %>","<% if( hda.metadata_dbkey ){ %>",'<div class="dataset-dbkey">','<label class="prompt">',_l("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(f){return _.template(a,f,{variable:"hda"})},body:function(f){return _.template(e,f,{variable:"hda"})}};return{HDABaseView:c}});
\ No newline at end of file
+define(["mvc/dataset/hda-model","mvc/base-mvc"],function(d,b){var c=Backbone.View.extend(b.LoggableMixin).extend({tagName:"div",className:"dataset hda history-panel-hda",id:function(){return"hda-"+this.model.get("id")},fxSpeed:"fast",initialize:function(f){if(f.logger){this.logger=this.model.logger=f.logger}this.log(this+".initialize:",f);this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton];this.linkTarget=f.linkTarget||"_blank";this.selectable=f.selectable||false;this.selected=f.selected||false;this.expanded=f.expanded||false;this.draggable=f.draggable||false;this._setUpListeners()},_setUpListeners:function(){this.model.on("change",function(g,f){if(this.model.changedAttributes().state&&this.model.inReadyState()&&this.expanded&&!this.model.hasDetails()){this.model.fetch()}else{this.render()}},this)},render:function(h){h=(h===undefined)?(true):(h);var f=this;this.$el.find("[title]").tooltip("destroy");this.urls=this.model.urls();var g=this._buildNewRender();if(h){$(f).queue(function(i){this.$el.fadeOut(f.fxSpeed,i)})}$(f).queue(function(i){this.$el.empty().attr("class",f.className).addClass("state-"+f.model.get("state")).append(g.children());if(this.selectable){this.showSelector(0)}i()});if(h){$(f).queue(function(i){this.$el.fadeIn(f.fxSpeed,i)})}$(f).queue(function(i){this.trigger("rendered",f);if(this.model.inReadyState()){this.trigger("rendered:ready",f)}if(this.draggable){this.draggableOn()}i()});return this},_buildNewRender:function(){var f=$(c.templates.skeleton(this.model.toJSON()));f.find(".dataset-primary-actions").append(this._render_titleButtons());f.children(".dataset-body").replaceWith(this._render_body());this._setUpBehaviors(f);return f},_setUpBehaviors:function(f){f=f||this.$el;make_popup_menus(f);f.find("[title]").tooltip({placement:"bottom"})},_render_titleButtons:function(){return[this._render_displayButton()]},_render_displayButton:function(){if((this.model.get("state")===d.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.DISCARDED)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.NEW)||(!this.model.get("accessible"))){return null}var g={target:this.linkTarget,classes:"dataset-display"};if(this.model.get("purged")){g.disabled=true;g.title=_l("Cannot display datasets removed from disk")}else{if(this.model.get("state")===d.HistoryDatasetAssociation.STATES.UPLOAD){g.disabled=true;g.title=_l("This dataset must finish uploading before it can be viewed")}else{g.title=_l("View data");g.href=this.urls.display;var f=this;g.onclick=function(h){if(Galaxy.frame&&Galaxy.frame.active){Galaxy.frame.add({title:"Data Viewer: "+f.model.get("name"),type:"url",content:f.urls.display});h.preventDefault()}}}}g.faIcon="fa-eye";return faIconButton(g)},_render_downloadButton:function(){if(this.model.get("purged")||!this.model.hasData()){return null}var g=this.urls,h=this.model.get("meta_files");if(_.isEmpty(h)){return $(['<a href="'+g.download+'" title="'+_l("Download")+'" ','class="icon-btn dataset-download-btn">','<span class="fa fa-floppy-o"></span>',"</a>"].join(""))}var i="dataset-"+this.model.get("id")+"-popup",f=['<div popupmenu="'+i+'">','<a href="'+g.download+'">',_l("Download Dataset"),"</a>","<a>"+_l("Additional Files")+"</a>",_.map(h,function(j){return['<a class="action-button" href="',g.meta_download+j.file_type,'">',_l("Download")," ",j.file_type,"</a>"].join("")}).join("\n"),"</div>",'<div class="icon-btn-group">','<a href="'+g.download+'" title="'+_l("Download")+'" ','class="icon-btn dataset-download-btn">','<span class="fa fa-floppy-o"></span>','</a><a class="icon-btn popup" id="'+i+'">','<span class="fa fa-caret-down"></span>',"</a>","</div>"].join("\n");return $(f)},_render_showParamsButton:function(){return faIconButton({title:_l("View details"),classes:"dataset-params-btn",href:this.urls.show_params,target:this.linkTarget,faIcon:"fa-info-circle"})},_render_body:function(){var g=$('<div>Error: unknown dataset state "'+this.model.get("state")+'".</div>'),f=this["_render_body_"+this.model.get("state")];if(_.isFunction(f)){g=f.call(this)}this._setUpBehaviors(g);if(this.expanded){g.show()}return g},_render_stateBodyHelper:function(f,i){i=i||[];var g=this,h=$(c.templates.body(_.extend(this.model.toJSON(),{body:f})));h.find(".dataset-actions .left").append(_.map(i,function(j){return j.call(g)}));return h},_render_body_new:function(){return this._render_stateBodyHelper("<div>"+_l("This is a new dataset and not all of its data are available yet")+"</div>")},_render_body_noPermission:function(){return this._render_stateBodyHelper("<div>"+_l("You do not have permission to view this dataset")+"</div>")},_render_body_discarded:function(){return this._render_stateBodyHelper("<div>"+_l("The job creating this dataset was cancelled before completion")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_queued:function(){return this._render_stateBodyHelper("<div>"+_l("This job is waiting to run")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_upload:function(){return this._render_stateBodyHelper("<div>"+_l("This dataset is currently uploading")+"</div>")},_render_body_setting_metadata:function(){return this._render_stateBodyHelper("<div>"+_l("Metadata is being auto-detected")+"</div>")},_render_body_running:function(){return this._render_stateBodyHelper("<div>"+_l("This job is currently running")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_paused:function(){return this._render_stateBodyHelper("<div>"+_l('This job is paused. Use the "Resume Paused Jobs" in the history menu to resume')+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_error:function(){var f=['<span class="help-text">',_l("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")){f="<div>"+this.model.get("misc_blurb")+"</div>"+f}return this._render_stateBodyHelper(f,[this._render_downloadButton].concat(this.defaultPrimaryActionButtonRenderers))},_render_body_empty:function(){return this._render_stateBodyHelper("<div>"+_l("No data")+": <i>"+this.model.get("misc_blurb")+"</i></div>",this.defaultPrimaryActionButtonRenderers)},_render_body_failed_metadata:function(){var f=$('<div class="warningmessagesmall"></div>').append($("<strong/>").text(_l("An error occurred setting the metadata for this dataset"))),g=this._render_body_ok();g.prepend(f);return g},_render_body_ok:function(){var f=this,h=$(c.templates.body(this.model.toJSON())),g=[this._render_downloadButton].concat(this.defaultPrimaryActionButtonRenderers);h.find(".dataset-actions .left").append(_.map(g,function(i){return i.call(f)}));if(this.model.isDeletedOrPurged()){return h}return h},events:{"click .dataset-title-bar":"toggleBodyVisibility","keydown .dataset-title-bar":"toggleBodyVisibility","click .dataset-selector":"toggleSelect"},toggleBodyVisibility:function(i,g){var f=32,h=13;if(i&&(i.type==="keydown")&&!(i.keyCode===f||i.keyCode===h)){return true}var j=this.$el.find(".dataset-body");g=(g===undefined)?(!j.is(":visible")):(g);if(g){this.expandBody()}else{this.collapseBody()}return false},expandBody:function(){var f=this;function g(){f.$el.children(".dataset-body").replaceWith(f._render_body());f.$el.children(".dataset-body").slideDown(f.fxSpeed,function(){f.expanded=true;f.trigger("body-expanded",f.model.get("id"))})}if(this.model.inReadyState()&&!this.model.hasDetails()){this.model.fetch({silent:true}).always(function(h){f.urls=f.model.urls();g()})}else{g()}},collapseBody:function(){var f=this;this.$el.children(".dataset-body").slideUp(f.fxSpeed,function(){f.expanded=false;f.trigger("body-collapsed",f.model.get("id"))})},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(f){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(f){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(f){if(this.selected){this.deselect(f)}else{this.select(f)}},draggableOn:function(){this.draggable=true;this.dragStartHandler=_.bind(this._dragStartHandler,this);this.dragEndHandler=_.bind(this._dragEndHandler,this);var f=this.$el.find(".dataset-title-bar").attr("draggable",true).get(0);f.addEventListener("dragstart",this.dragStartHandler,false);f.addEventListener("dragend",this.dragEndHandler,false)},draggableOff:function(){this.draggable=false;var f=this.$el.find(".dataset-title-bar").attr("draggable",false).get(0);f.removeEventListener("dragstart",this.dragStartHandler,false);f.removeEventListener("dragend",this.dragEndHandler,false)},toggleDraggable:function(){if(this.draggable){this.draggableOff()}else{this.draggableOn()}},_dragStartHandler:function(f){this.trigger("dragstart",this);f.dataTransfer.effectAllowed="move";f.dataTransfer.setData("text",JSON.stringify(this.model.toJSON()));return false},_dragEndHandler:function(f){this.trigger("dragend",this);return false},remove:function(g){var f=this;this.$el.fadeOut(f.fxSpeed,function(){f.$el.remove();f.off();if(g){g()}})},toString:function(){var f=(this.model)?(this.model+""):("(no model)");return"HDABaseView("+f+")"}});var a=['<div class="dataset hda">','<div class="dataset-warnings">',"<% if( hda.error ){ %>",'<div class="errormessagesmall">',_l("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>',_l("This dataset has been deleted and removed from disk."),"</strong></div>","<% } else { %>",'<div class="dataset-deleted-msg warningmessagesmall"><strong>',_l("This dataset has been deleted."),"</strong></div>","<% } %>","<% } %>","<% if( !hda.visible ){ %>",'<div class="dataset-hidden-msg warningmessagesmall"><strong>',_l("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 e=['<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">',_l("format"),"</label>",'<span class="value"><%- hda.data_type %></span>',"</div>","<% } %>","<% if( hda.metadata_dbkey ){ %>",'<div class="dataset-dbkey">','<label class="prompt">',_l("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(f){return _.template(a,f,{variable:"hda"})},body:function(f){return _.template(e,f,{variable:"hda"})}};return{HDABaseView:c}});
\ No newline at end of file
https://bitbucket.org/galaxy/galaxy-central/commits/d79eccd2d0be/
Changeset: d79eccd2d0be
User: carlfeberhard
Date: 2014-04-08 20:14:58
Summary: merge next-stable
Affected #: 4 files
diff -r 121e69653f7728fddfadeb720f93e168a2fc8227 -r d79eccd2d0beae713abe1f44b6d2584c8528b03e static/scripts/galaxy.pages.js
--- a/static/scripts/galaxy.pages.js
+++ b/static/scripts/galaxy.pages.js
@@ -462,7 +462,6 @@
item_info.singular.toLowerCase(), " when it is displayed.]",
"</p>",
"</div>" ].join( '' );
- console.debug( item_embed_html );
// Insert embedded item into document.
//wym.insert(" "); // Needed to prevent insertion from occurring in child element in webkit browsers.
diff -r 121e69653f7728fddfadeb720f93e168a2fc8227 -r d79eccd2d0beae713abe1f44b6d2584c8528b03e static/scripts/mvc/dataset/hda-base.js
--- a/static/scripts/mvc/dataset/hda-base.js
+++ b/static/scripts/mvc/dataset/hda-base.js
@@ -194,7 +194,6 @@
// add frame manager option onclick event
var self = this;
displayBtnData.onclick = function( ev ){
- console.debug( 'displayBtn onclick', ev );
if( Galaxy.frame && Galaxy.frame.active ){
Galaxy.frame.add({
title : "Data Viewer: " + self.model.get('name'),
diff -r 121e69653f7728fddfadeb720f93e168a2fc8227 -r d79eccd2d0beae713abe1f44b6d2584c8528b03e static/scripts/packed/galaxy.pages.js
--- a/static/scripts/packed/galaxy.pages.js
+++ b/static/scripts/packed/galaxy.pages.js
@@ -1,1 +1,1 @@
-var Galaxy={ITEM_HISTORY:"item_history",ITEM_DATASET:"item_dataset",ITEM_WORKFLOW:"item_workflow",ITEM_PAGE:"item_page",ITEM_VISUALIZATION:"item_visualization",DIALOG_HISTORY_LINK:"link_history",DIALOG_DATASET_LINK:"link_dataset",DIALOG_WORKFLOW_LINK:"link_workflow",DIALOG_PAGE_LINK:"link_page",DIALOG_VISUALIZATION_LINK:"link_visualization",DIALOG_EMBED_HISTORY:"embed_history",DIALOG_EMBED_DATASET:"embed_dataset",DIALOG_EMBED_WORKFLOW:"embed_workflow",DIALOG_EMBED_PAGE:"embed_page",DIALOG_EMBED_VISUALIZATION:"embed_visualization",DIALOG_HISTORY_ANNOTATE:"history_annotate",};function init_galaxy_elts(a){$(".annotation",a._doc.body).each(function(){$(this).click(function(){var b=a._doc.createRange();b.selectNodeContents(this);var d=window.getSelection();d.removeAllRanges();d.addRange(b);var c=""})})}function get_item_info(d){var f,c,b;switch(d){case (Galaxy.ITEM_HISTORY):f="History";c="Histories";b="history";item_class="History";break;case (Galaxy.ITEM_DATASET):f="Dataset";c="Datasets";b="dataset";item_class="HistoryDatasetAssociation";break;case (Galaxy.ITEM_WORKFLOW):f="Workflow";c="Workflows";b="workflow";item_class="StoredWorkflow";break;case (Galaxy.ITEM_PAGE):f="Page";c="Pages";b="page";item_class="Page";break;case (Galaxy.ITEM_VISUALIZATION):f="Visualization";c="Visualizations";b="visualization";item_class="Visualization";break}var e="list_"+c.toLowerCase()+"_for_selection";var a=list_objects_url.replace("LIST_ACTION",e);return{singular:f,plural:c,controller:b,iclass:item_class,list_ajax_url:a}}function make_item_importable(a,c,b){ajax_url=set_accessible_url.replace("ITEM_CONTROLLER",a);$.ajax({type:"POST",url:ajax_url,data:{id:c,accessible:"True"},error:function(){alert("Making "+b+" accessible failed")}})}WYMeditor.editor.prototype.dialog=function(i,e,g){var a=this;var b=a.uniqueStamp();var f=a.selected();function h(){$("#set_link_id").click(function(){$("#link_attribute_label").text("ID/Name");var k=$(".wym_href");k.addClass("wym_id").removeClass("wym_href");if(f){k.val($(f).attr("id"))}$(this).remove()})}if(i==WYMeditor.DIALOG_LINK){if(f){$(a._options.hrefSelector).val($(f).attr(WYMeditor.HREF));$(a._options.srcSelector).val($(f).attr(WYMeditor.SRC));$(a._options.titleSelector).val($(f).attr(WYMeditor.TITLE));$(a._options.altSelector).val($(f).attr(WYMeditor.ALT))}var c,d;if(f){c=$(f).attr("href");if(c==undefined){c=""}d=$(f).attr("title");if(d==undefined){d=""}}show_modal("Create Link","<div><div><label id='link_attribute_label'>URL <span style='float: right; font-size: 90%'><a href='#' id='set_link_id'>Create in-page anchor</a></span></label><br><input type='text' class='wym_href' value='"+c+"' size='40' /></div><div><label>Title</label><br><input type='text' class='wym_title' value='"+d+"' size='40' /></div><div>",{"Make link":function(){var m=$(a._options.hrefSelector).val()||"",k=$(".wym_id").val()||"",n=$(a._options.titleSelector).val()||"";if(m||k){a._exec(WYMeditor.CREATE_LINK,b);var l=$("a[href="+b+"]",a._doc.body);l.attr(WYMeditor.HREF,m).attr(WYMeditor.TITLE,n).attr("id",k);if(l.text().indexOf("wym-")===0){l.text(n)}}hide_modal()},Cancel:function(){hide_modal()}},{},h)}if(i==WYMeditor.DIALOG_IMAGE){if(a._selected_image){$(a._options.dialogImageSelector+" "+a._options.srcSelector).val($(a._selected_image).attr(WYMeditor.SRC));$(a._options.dialogImageSelector+" "+a._options.titleSelector).val($(a._selected_image).attr(WYMeditor.TITLE));$(a._options.dialogImageSelector+" "+a._options.altSelector).val($(a._selected_image).attr(WYMeditor.ALT))}show_modal("Image","<div class='row'><label>URL</label><br><input type='text' class='wym_src' value='' size='40' /></div><div class='row'><label>Alt text</label><br><input type='text' class='wym_alt' value='' size='40' /></div><div class='row'><label>Title</label><br><input type='text' class='wym_title' value='' size='40' /></div>",{Insert:function(){var k=$(a._options.srcSelector).val();if(k.length>0){a._exec(WYMeditor.INSERT_IMAGE,b);$("img[src$="+b+"]",a._doc.body).attr(WYMeditor.SRC,k).attr(WYMeditor.TITLE,$(a._options.titleSelector).val()).attr(WYMeditor.ALT,$(a._options.altSelector).val())}hide_modal()},Cancel:function(){hide_modal()}});return}if(i==WYMeditor.DIALOG_TABLE){show_modal("Table","<div class='row'><label>Caption</label><br><input type='text' class='wym_caption' value='' size='40' /></div><div class='row'><label>Summary</label><br><input type='text' class='wym_summary' value='' size='40' /></div><div class='row'><label>Number Of Rows<br></label><input type='text' class='wym_rows' value='3' size='3' /></div><div class='row'><label>Number Of Cols<br></label><input type='text' class='wym_cols' value='2' size='3' /></div>",{Insert:function(){var o=$(a._options.rowsSelector).val();var r=$(a._options.colsSelector).val();if(o>0&&r>0){var n=a._doc.createElement(WYMeditor.TABLE);var l=null;var q=null;var k=$(a._options.captionSelector).val();var p=n.createCaption();p.innerHTML=k;for(x=0;x<o;x++){l=n.insertRow(x);for(y=0;y<r;y++){l.insertCell(y)}}$(n).attr("summary",$(a._options.summarySelector).val());var m=$(a.findUp(a.container(),WYMeditor.MAIN_CONTAINERS)).get(0);if(!m||!m.parentNode){$(a._doc.body).append(n)}else{$(m).after(n)}}hide_modal()},Cancel:function(){hide_modal()}})}if(i==Galaxy.DIALOG_HISTORY_LINK||i==Galaxy.DIALOG_DATASET_LINK||i==Galaxy.DIALOG_WORKFLOW_LINK||i==Galaxy.DIALOG_PAGE_LINK||i==Galaxy.DIALOG_VISUALIZATION_LINK){var j;switch(i){case (Galaxy.DIALOG_HISTORY_LINK):j=get_item_info(Galaxy.ITEM_HISTORY);break;case (Galaxy.DIALOG_DATASET_LINK):j=get_item_info(Galaxy.ITEM_DATASET);break;case (Galaxy.DIALOG_WORKFLOW_LINK):j=get_item_info(Galaxy.ITEM_WORKFLOW);break;case (Galaxy.DIALOG_PAGE_LINK):j=get_item_info(Galaxy.ITEM_PAGE);break;case (Galaxy.DIALOG_VISUALIZATION_LINK):j=get_item_info(Galaxy.ITEM_VISUALIZATION);break}$.ajax({url:j.list_ajax_url,data:{},error:function(){alert("Failed to list "+j.plural.toLowerCase()+" for selection")},success:function(k){show_modal("Insert Link to "+j.singular,k+"<div><input id='make-importable' type='checkbox' checked/>Make the selected "+j.plural.toLowerCase()+" accessible so that they can viewed by everyone.</div>",{Insert:function(){var m=false;if($("#make-importable:checked").val()!==null){m=true}var l=new Array();$("input[name=id]:checked").each(function(){var n=$(this).val();if(m){make_item_importable(j.controller,n,j.singular)}url_template=get_name_and_link_url+n;ajax_url=url_template.replace("ITEM_CONTROLLER",j.controller);$.getJSON(ajax_url,function(p){a._exec(WYMeditor.CREATE_LINK,b);var o=$("a[href="+b+"]",a._doc.body).text();if(o==""||o==b){a.insert("<a href='"+p.link+"'>"+j.singular+" '"+p.name+"'</a>")}else{$("a[href="+b+"]",a._doc.body).attr(WYMeditor.HREF,p.link).attr(WYMeditor.TITLE,j.singular+n)}})});hide_modal()},Cancel:function(){hide_modal()}})}})}if(i==Galaxy.DIALOG_EMBED_HISTORY||i==Galaxy.DIALOG_EMBED_DATASET||i==Galaxy.DIALOG_EMBED_WORKFLOW||i==Galaxy.DIALOG_EMBED_PAGE||i==Galaxy.DIALOG_EMBED_VISUALIZATION){var j;switch(i){case (Galaxy.DIALOG_EMBED_HISTORY):j=get_item_info(Galaxy.ITEM_HISTORY);break;case (Galaxy.DIALOG_EMBED_DATASET):j=get_item_info(Galaxy.ITEM_DATASET);break;case (Galaxy.DIALOG_EMBED_WORKFLOW):j=get_item_info(Galaxy.ITEM_WORKFLOW);break;case (Galaxy.DIALOG_EMBED_PAGE):j=get_item_info(Galaxy.ITEM_PAGE);break;case (Galaxy.DIALOG_EMBED_VISUALIZATION):j=get_item_info(Galaxy.ITEM_VISUALIZATION);break}$.ajax({url:j.list_ajax_url,data:{},error:function(){alert("Failed to list "+j.plural.toLowerCase()+" for selection")},success:function(k){if(i==Galaxy.DIALOG_EMBED_HISTORY||i==Galaxy.DIALOG_EMBED_WORKFLOW||i==Galaxy.DIALOG_EMBED_VISUALIZATION){k=k+"<div><input id='make-importable' type='checkbox' checked/>Make the selected "+j.plural.toLowerCase()+" accessible so that they can viewed by everyone.</div>"}show_modal("Embed "+j.plural,k,{Embed:function(){var l=false;if($("#make-importable:checked").val()!=null){l=true}$("input[name=id]:checked").each(function(){var m=$(this).val();var p=$("label[for='"+m+"']:first").text();if(l){make_item_importable(j.controller,m,j.singular)}var n=j.iclass+"-"+m;var o=["<div id='",n,"' class='embedded-item ",j.singular.toLowerCase()," placeholder'>","<p class='title'>","Embedded Galaxy ",j.singular," '",p,"'","</p>","<p class='content'>","[Do not edit this block; Galaxy will fill it in with the annotated ",j.singular.toLowerCase()," when it is displayed.]","</p>","</div>"].join("");console.debug(o);a.insert(o)});hide_modal()},Cancel:function(){hide_modal()}})}})}if(i==Galaxy.DIALOG_ANNOTATE_HISTORY){$.ajax({url:list_histories_for_selection_url,data:{},error:function(){alert("Grid refresh failed")},success:function(k){show_modal("Insert Link to History",k,{Annotate:function(){var l=new Array();$("input[name=id]:checked").each(function(){var m=$(this).val();$.ajax({url:get_history_annotation_table_url,data:{id:m},error:function(){alert("Grid refresh failed")},success:function(n){a.insert(n);init_galaxy_elts(a)}})});hide_modal()},Cancel:function(){hide_modal()}})}})}};$(function(){$(document).ajaxError(function(i,g){var h=g.responseText||g.statusText||"Could not connect to server";show_modal("Server error",h,{"Ignore error":hide_modal});return false});$("[name=page_content]").wymeditor({skin:"galaxy",basePath:editor_base_path,iframeBasePath:iframe_base_path,boxHtml:"<table class='wym_box' width='100%' height='100%'><tr><td><div class='wym_area_top'>"+WYMeditor.TOOLS+"</div></td></tr><tr height='100%'><td><div class='wym_area_main' style='height: 100%;'>"+WYMeditor.IFRAME+WYMeditor.STATUS+"</div></div></td></tr></table>",toolsItems:[{name:"Bold",title:"Strong",css:"wym_tools_strong"},{name:"Italic",title:"Emphasis",css:"wym_tools_emphasis"},{name:"Superscript",title:"Superscript",css:"wym_tools_superscript"},{name:"Subscript",title:"Subscript",css:"wym_tools_subscript"},{name:"InsertOrderedList",title:"Ordered_List",css:"wym_tools_ordered_list"},{name:"InsertUnorderedList",title:"Unordered_List",css:"wym_tools_unordered_list"},{name:"Indent",title:"Indent",css:"wym_tools_indent"},{name:"Outdent",title:"Outdent",css:"wym_tools_outdent"},{name:"Undo",title:"Undo",css:"wym_tools_undo"},{name:"Redo",title:"Redo",css:"wym_tools_redo"},{name:"CreateLink",title:"Link",css:"wym_tools_link"},{name:"Unlink",title:"Unlink",css:"wym_tools_unlink"},{name:"InsertImage",title:"Image",css:"wym_tools_image"},{name:"InsertTable",title:"Table",css:"wym_tools_table"},]});var d=$.wymeditors(0);var f=function(g){show_modal("Saving page","progress");$.ajax({url:save_url,type:"POST",data:{id:page_id,content:d.xhtml(),annotations:JSON.stringify(new Object()),_:"true"},success:function(){g()}})};$("#save-button").click(function(){f(function(){hide_modal()})});$("#close-button").click(function(){var h=false;if(h){var g=function(){window.onbeforeunload=undefined;window.document.location=page_list_url};show_modal("Close editor","There are unsaved changes to your page which will be lost.",{Cancel:hide_modal,"Save Changes":function(){f(g)}},{"Don't Save":g})}else{window.document.location=page_list_url}});var a=$("<div class='galaxy-page-editor-button'><a id='insert-galaxy-link' class='action-button popup' href='#'>Paragraph type</a></div>");$(".wym_area_top").append(a);var b={};$.each(d._options.containersItems,function(h,g){var i=g.name;b[g.title.replace("_"," ")]=function(){d.container(i)}});make_popupmenu(a,b);var c=$("<div><a id='insert-galaxy-link' class='action-button popup' href='#'>Insert Link to Galaxy Object</a></div>").addClass("galaxy-page-editor-button");$(".wym_area_top").append(c);make_popupmenu(c,{"Insert History Link":function(){d.dialog(Galaxy.DIALOG_HISTORY_LINK)},"Insert Dataset Link":function(){d.dialog(Galaxy.DIALOG_DATASET_LINK)},"Insert Workflow Link":function(){d.dialog(Galaxy.DIALOG_WORKFLOW_LINK)},"Insert Page Link":function(){d.dialog(Galaxy.DIALOG_PAGE_LINK)},"Insert Visualization Link":function(){d.dialog(Galaxy.DIALOG_VISUALIZATION_LINK)},});var e=$("<div><a id='embed-galaxy-object' class='action-button popup' href='#'>Embed Galaxy Object</a></div>").addClass("galaxy-page-editor-button");$(".wym_area_top").append(e);make_popupmenu(e,{"Embed History":function(){d.dialog(Galaxy.DIALOG_EMBED_HISTORY)},"Embed Dataset":function(){d.dialog(Galaxy.DIALOG_EMBED_DATASET)},"Embed Workflow":function(){d.dialog(Galaxy.DIALOG_EMBED_WORKFLOW)},"Embed Visualization":function(){d.dialog(Galaxy.DIALOG_EMBED_VISUALIZATION)},})});
\ No newline at end of file
+var Galaxy={ITEM_HISTORY:"item_history",ITEM_DATASET:"item_dataset",ITEM_WORKFLOW:"item_workflow",ITEM_PAGE:"item_page",ITEM_VISUALIZATION:"item_visualization",DIALOG_HISTORY_LINK:"link_history",DIALOG_DATASET_LINK:"link_dataset",DIALOG_WORKFLOW_LINK:"link_workflow",DIALOG_PAGE_LINK:"link_page",DIALOG_VISUALIZATION_LINK:"link_visualization",DIALOG_EMBED_HISTORY:"embed_history",DIALOG_EMBED_DATASET:"embed_dataset",DIALOG_EMBED_WORKFLOW:"embed_workflow",DIALOG_EMBED_PAGE:"embed_page",DIALOG_EMBED_VISUALIZATION:"embed_visualization",DIALOG_HISTORY_ANNOTATE:"history_annotate",};function init_galaxy_elts(a){$(".annotation",a._doc.body).each(function(){$(this).click(function(){var b=a._doc.createRange();b.selectNodeContents(this);var d=window.getSelection();d.removeAllRanges();d.addRange(b);var c=""})})}function get_item_info(d){var f,c,b;switch(d){case (Galaxy.ITEM_HISTORY):f="History";c="Histories";b="history";item_class="History";break;case (Galaxy.ITEM_DATASET):f="Dataset";c="Datasets";b="dataset";item_class="HistoryDatasetAssociation";break;case (Galaxy.ITEM_WORKFLOW):f="Workflow";c="Workflows";b="workflow";item_class="StoredWorkflow";break;case (Galaxy.ITEM_PAGE):f="Page";c="Pages";b="page";item_class="Page";break;case (Galaxy.ITEM_VISUALIZATION):f="Visualization";c="Visualizations";b="visualization";item_class="Visualization";break}var e="list_"+c.toLowerCase()+"_for_selection";var a=list_objects_url.replace("LIST_ACTION",e);return{singular:f,plural:c,controller:b,iclass:item_class,list_ajax_url:a}}function make_item_importable(a,c,b){ajax_url=set_accessible_url.replace("ITEM_CONTROLLER",a);$.ajax({type:"POST",url:ajax_url,data:{id:c,accessible:"True"},error:function(){alert("Making "+b+" accessible failed")}})}WYMeditor.editor.prototype.dialog=function(i,e,g){var a=this;var b=a.uniqueStamp();var f=a.selected();function h(){$("#set_link_id").click(function(){$("#link_attribute_label").text("ID/Name");var k=$(".wym_href");k.addClass("wym_id").removeClass("wym_href");if(f){k.val($(f).attr("id"))}$(this).remove()})}if(i==WYMeditor.DIALOG_LINK){if(f){$(a._options.hrefSelector).val($(f).attr(WYMeditor.HREF));$(a._options.srcSelector).val($(f).attr(WYMeditor.SRC));$(a._options.titleSelector).val($(f).attr(WYMeditor.TITLE));$(a._options.altSelector).val($(f).attr(WYMeditor.ALT))}var c,d;if(f){c=$(f).attr("href");if(c==undefined){c=""}d=$(f).attr("title");if(d==undefined){d=""}}show_modal("Create Link","<div><div><label id='link_attribute_label'>URL <span style='float: right; font-size: 90%'><a href='#' id='set_link_id'>Create in-page anchor</a></span></label><br><input type='text' class='wym_href' value='"+c+"' size='40' /></div><div><label>Title</label><br><input type='text' class='wym_title' value='"+d+"' size='40' /></div><div>",{"Make link":function(){var m=$(a._options.hrefSelector).val()||"",k=$(".wym_id").val()||"",n=$(a._options.titleSelector).val()||"";if(m||k){a._exec(WYMeditor.CREATE_LINK,b);var l=$("a[href="+b+"]",a._doc.body);l.attr(WYMeditor.HREF,m).attr(WYMeditor.TITLE,n).attr("id",k);if(l.text().indexOf("wym-")===0){l.text(n)}}hide_modal()},Cancel:function(){hide_modal()}},{},h)}if(i==WYMeditor.DIALOG_IMAGE){if(a._selected_image){$(a._options.dialogImageSelector+" "+a._options.srcSelector).val($(a._selected_image).attr(WYMeditor.SRC));$(a._options.dialogImageSelector+" "+a._options.titleSelector).val($(a._selected_image).attr(WYMeditor.TITLE));$(a._options.dialogImageSelector+" "+a._options.altSelector).val($(a._selected_image).attr(WYMeditor.ALT))}show_modal("Image","<div class='row'><label>URL</label><br><input type='text' class='wym_src' value='' size='40' /></div><div class='row'><label>Alt text</label><br><input type='text' class='wym_alt' value='' size='40' /></div><div class='row'><label>Title</label><br><input type='text' class='wym_title' value='' size='40' /></div>",{Insert:function(){var k=$(a._options.srcSelector).val();if(k.length>0){a._exec(WYMeditor.INSERT_IMAGE,b);$("img[src$="+b+"]",a._doc.body).attr(WYMeditor.SRC,k).attr(WYMeditor.TITLE,$(a._options.titleSelector).val()).attr(WYMeditor.ALT,$(a._options.altSelector).val())}hide_modal()},Cancel:function(){hide_modal()}});return}if(i==WYMeditor.DIALOG_TABLE){show_modal("Table","<div class='row'><label>Caption</label><br><input type='text' class='wym_caption' value='' size='40' /></div><div class='row'><label>Summary</label><br><input type='text' class='wym_summary' value='' size='40' /></div><div class='row'><label>Number Of Rows<br></label><input type='text' class='wym_rows' value='3' size='3' /></div><div class='row'><label>Number Of Cols<br></label><input type='text' class='wym_cols' value='2' size='3' /></div>",{Insert:function(){var o=$(a._options.rowsSelector).val();var r=$(a._options.colsSelector).val();if(o>0&&r>0){var n=a._doc.createElement(WYMeditor.TABLE);var l=null;var q=null;var k=$(a._options.captionSelector).val();var p=n.createCaption();p.innerHTML=k;for(x=0;x<o;x++){l=n.insertRow(x);for(y=0;y<r;y++){l.insertCell(y)}}$(n).attr("summary",$(a._options.summarySelector).val());var m=$(a.findUp(a.container(),WYMeditor.MAIN_CONTAINERS)).get(0);if(!m||!m.parentNode){$(a._doc.body).append(n)}else{$(m).after(n)}}hide_modal()},Cancel:function(){hide_modal()}})}if(i==Galaxy.DIALOG_HISTORY_LINK||i==Galaxy.DIALOG_DATASET_LINK||i==Galaxy.DIALOG_WORKFLOW_LINK||i==Galaxy.DIALOG_PAGE_LINK||i==Galaxy.DIALOG_VISUALIZATION_LINK){var j;switch(i){case (Galaxy.DIALOG_HISTORY_LINK):j=get_item_info(Galaxy.ITEM_HISTORY);break;case (Galaxy.DIALOG_DATASET_LINK):j=get_item_info(Galaxy.ITEM_DATASET);break;case (Galaxy.DIALOG_WORKFLOW_LINK):j=get_item_info(Galaxy.ITEM_WORKFLOW);break;case (Galaxy.DIALOG_PAGE_LINK):j=get_item_info(Galaxy.ITEM_PAGE);break;case (Galaxy.DIALOG_VISUALIZATION_LINK):j=get_item_info(Galaxy.ITEM_VISUALIZATION);break}$.ajax({url:j.list_ajax_url,data:{},error:function(){alert("Failed to list "+j.plural.toLowerCase()+" for selection")},success:function(k){show_modal("Insert Link to "+j.singular,k+"<div><input id='make-importable' type='checkbox' checked/>Make the selected "+j.plural.toLowerCase()+" accessible so that they can viewed by everyone.</div>",{Insert:function(){var m=false;if($("#make-importable:checked").val()!==null){m=true}var l=new Array();$("input[name=id]:checked").each(function(){var n=$(this).val();if(m){make_item_importable(j.controller,n,j.singular)}url_template=get_name_and_link_url+n;ajax_url=url_template.replace("ITEM_CONTROLLER",j.controller);$.getJSON(ajax_url,function(p){a._exec(WYMeditor.CREATE_LINK,b);var o=$("a[href="+b+"]",a._doc.body).text();if(o==""||o==b){a.insert("<a href='"+p.link+"'>"+j.singular+" '"+p.name+"'</a>")}else{$("a[href="+b+"]",a._doc.body).attr(WYMeditor.HREF,p.link).attr(WYMeditor.TITLE,j.singular+n)}})});hide_modal()},Cancel:function(){hide_modal()}})}})}if(i==Galaxy.DIALOG_EMBED_HISTORY||i==Galaxy.DIALOG_EMBED_DATASET||i==Galaxy.DIALOG_EMBED_WORKFLOW||i==Galaxy.DIALOG_EMBED_PAGE||i==Galaxy.DIALOG_EMBED_VISUALIZATION){var j;switch(i){case (Galaxy.DIALOG_EMBED_HISTORY):j=get_item_info(Galaxy.ITEM_HISTORY);break;case (Galaxy.DIALOG_EMBED_DATASET):j=get_item_info(Galaxy.ITEM_DATASET);break;case (Galaxy.DIALOG_EMBED_WORKFLOW):j=get_item_info(Galaxy.ITEM_WORKFLOW);break;case (Galaxy.DIALOG_EMBED_PAGE):j=get_item_info(Galaxy.ITEM_PAGE);break;case (Galaxy.DIALOG_EMBED_VISUALIZATION):j=get_item_info(Galaxy.ITEM_VISUALIZATION);break}$.ajax({url:j.list_ajax_url,data:{},error:function(){alert("Failed to list "+j.plural.toLowerCase()+" for selection")},success:function(k){if(i==Galaxy.DIALOG_EMBED_HISTORY||i==Galaxy.DIALOG_EMBED_WORKFLOW||i==Galaxy.DIALOG_EMBED_VISUALIZATION){k=k+"<div><input id='make-importable' type='checkbox' checked/>Make the selected "+j.plural.toLowerCase()+" accessible so that they can viewed by everyone.</div>"}show_modal("Embed "+j.plural,k,{Embed:function(){var l=false;if($("#make-importable:checked").val()!=null){l=true}$("input[name=id]:checked").each(function(){var m=$(this).val();var p=$("label[for='"+m+"']:first").text();if(l){make_item_importable(j.controller,m,j.singular)}var n=j.iclass+"-"+m;var o=["<div id='",n,"' class='embedded-item ",j.singular.toLowerCase()," placeholder'>","<p class='title'>","Embedded Galaxy ",j.singular," '",p,"'","</p>","<p class='content'>","[Do not edit this block; Galaxy will fill it in with the annotated ",j.singular.toLowerCase()," when it is displayed.]","</p>","</div>"].join("");a.insert(o)});hide_modal()},Cancel:function(){hide_modal()}})}})}if(i==Galaxy.DIALOG_ANNOTATE_HISTORY){$.ajax({url:list_histories_for_selection_url,data:{},error:function(){alert("Grid refresh failed")},success:function(k){show_modal("Insert Link to History",k,{Annotate:function(){var l=new Array();$("input[name=id]:checked").each(function(){var m=$(this).val();$.ajax({url:get_history_annotation_table_url,data:{id:m},error:function(){alert("Grid refresh failed")},success:function(n){a.insert(n);init_galaxy_elts(a)}})});hide_modal()},Cancel:function(){hide_modal()}})}})}};$(function(){$(document).ajaxError(function(i,g){var h=g.responseText||g.statusText||"Could not connect to server";show_modal("Server error",h,{"Ignore error":hide_modal});return false});$("[name=page_content]").wymeditor({skin:"galaxy",basePath:editor_base_path,iframeBasePath:iframe_base_path,boxHtml:"<table class='wym_box' width='100%' height='100%'><tr><td><div class='wym_area_top'>"+WYMeditor.TOOLS+"</div></td></tr><tr height='100%'><td><div class='wym_area_main' style='height: 100%;'>"+WYMeditor.IFRAME+WYMeditor.STATUS+"</div></div></td></tr></table>",toolsItems:[{name:"Bold",title:"Strong",css:"wym_tools_strong"},{name:"Italic",title:"Emphasis",css:"wym_tools_emphasis"},{name:"Superscript",title:"Superscript",css:"wym_tools_superscript"},{name:"Subscript",title:"Subscript",css:"wym_tools_subscript"},{name:"InsertOrderedList",title:"Ordered_List",css:"wym_tools_ordered_list"},{name:"InsertUnorderedList",title:"Unordered_List",css:"wym_tools_unordered_list"},{name:"Indent",title:"Indent",css:"wym_tools_indent"},{name:"Outdent",title:"Outdent",css:"wym_tools_outdent"},{name:"Undo",title:"Undo",css:"wym_tools_undo"},{name:"Redo",title:"Redo",css:"wym_tools_redo"},{name:"CreateLink",title:"Link",css:"wym_tools_link"},{name:"Unlink",title:"Unlink",css:"wym_tools_unlink"},{name:"InsertImage",title:"Image",css:"wym_tools_image"},{name:"InsertTable",title:"Table",css:"wym_tools_table"},]});var d=$.wymeditors(0);var f=function(g){show_modal("Saving page","progress");$.ajax({url:save_url,type:"POST",data:{id:page_id,content:d.xhtml(),annotations:JSON.stringify(new Object()),_:"true"},success:function(){g()}})};$("#save-button").click(function(){f(function(){hide_modal()})});$("#close-button").click(function(){var h=false;if(h){var g=function(){window.onbeforeunload=undefined;window.document.location=page_list_url};show_modal("Close editor","There are unsaved changes to your page which will be lost.",{Cancel:hide_modal,"Save Changes":function(){f(g)}},{"Don't Save":g})}else{window.document.location=page_list_url}});var a=$("<div class='galaxy-page-editor-button'><a id='insert-galaxy-link' class='action-button popup' href='#'>Paragraph type</a></div>");$(".wym_area_top").append(a);var b={};$.each(d._options.containersItems,function(h,g){var i=g.name;b[g.title.replace("_"," ")]=function(){d.container(i)}});make_popupmenu(a,b);var c=$("<div><a id='insert-galaxy-link' class='action-button popup' href='#'>Insert Link to Galaxy Object</a></div>").addClass("galaxy-page-editor-button");$(".wym_area_top").append(c);make_popupmenu(c,{"Insert History Link":function(){d.dialog(Galaxy.DIALOG_HISTORY_LINK)},"Insert Dataset Link":function(){d.dialog(Galaxy.DIALOG_DATASET_LINK)},"Insert Workflow Link":function(){d.dialog(Galaxy.DIALOG_WORKFLOW_LINK)},"Insert Page Link":function(){d.dialog(Galaxy.DIALOG_PAGE_LINK)},"Insert Visualization Link":function(){d.dialog(Galaxy.DIALOG_VISUALIZATION_LINK)},});var e=$("<div><a id='embed-galaxy-object' class='action-button popup' href='#'>Embed Galaxy Object</a></div>").addClass("galaxy-page-editor-button");$(".wym_area_top").append(e);make_popupmenu(e,{"Embed History":function(){d.dialog(Galaxy.DIALOG_EMBED_HISTORY)},"Embed Dataset":function(){d.dialog(Galaxy.DIALOG_EMBED_DATASET)},"Embed Workflow":function(){d.dialog(Galaxy.DIALOG_EMBED_WORKFLOW)},"Embed Visualization":function(){d.dialog(Galaxy.DIALOG_EMBED_VISUALIZATION)},})});
\ No newline at end of file
diff -r 121e69653f7728fddfadeb720f93e168a2fc8227 -r d79eccd2d0beae713abe1f44b6d2584c8528b03e 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"],function(d,b){var c=Backbone.View.extend(b.LoggableMixin).extend({tagName:"div",className:"dataset hda history-panel-hda",id:function(){return"hda-"+this.model.get("id")},fxSpeed:"fast",initialize:function(f){if(f.logger){this.logger=this.model.logger=f.logger}this.log(this+".initialize:",f);this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton];this.linkTarget=f.linkTarget||"_blank";this.selectable=f.selectable||false;this.selected=f.selected||false;this.expanded=f.expanded||false;this.draggable=f.draggable||false;this._setUpListeners()},_setUpListeners:function(){this.model.on("change",function(g,f){if(this.model.changedAttributes().state&&this.model.inReadyState()&&this.expanded&&!this.model.hasDetails()){this.model.fetch()}else{this.render()}},this)},render:function(h){h=(h===undefined)?(true):(h);var f=this;this.$el.find("[title]").tooltip("destroy");this.urls=this.model.urls();var g=this._buildNewRender();if(h){$(f).queue(function(i){this.$el.fadeOut(f.fxSpeed,i)})}$(f).queue(function(i){this.$el.empty().attr("class",f.className).addClass("state-"+f.model.get("state")).append(g.children());if(this.selectable){this.showSelector(0)}i()});if(h){$(f).queue(function(i){this.$el.fadeIn(f.fxSpeed,i)})}$(f).queue(function(i){this.trigger("rendered",f);if(this.model.inReadyState()){this.trigger("rendered:ready",f)}if(this.draggable){this.draggableOn()}i()});return this},_buildNewRender:function(){var f=$(c.templates.skeleton(this.model.toJSON()));f.find(".dataset-primary-actions").append(this._render_titleButtons());f.children(".dataset-body").replaceWith(this._render_body());this._setUpBehaviors(f);return f},_setUpBehaviors:function(f){f=f||this.$el;make_popup_menus(f);f.find("[title]").tooltip({placement:"bottom"})},_render_titleButtons:function(){return[this._render_displayButton()]},_render_displayButton:function(){if((this.model.get("state")===d.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.DISCARDED)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.NEW)||(!this.model.get("accessible"))){return null}var g={target:this.linkTarget,classes:"dataset-display"};if(this.model.get("purged")){g.disabled=true;g.title=_l("Cannot display datasets removed from disk")}else{if(this.model.get("state")===d.HistoryDatasetAssociation.STATES.UPLOAD){g.disabled=true;g.title=_l("This dataset must finish uploading before it can be viewed")}else{g.title=_l("View data");g.href=this.urls.display;var f=this;g.onclick=function(h){console.debug("displayBtn onclick",h);if(Galaxy.frame&&Galaxy.frame.active){Galaxy.frame.add({title:"Data Viewer: "+f.model.get("name"),type:"url",content:f.urls.display});h.preventDefault()}}}}g.faIcon="fa-eye";return faIconButton(g)},_render_downloadButton:function(){if(this.model.get("purged")||!this.model.hasData()){return null}var g=this.urls,h=this.model.get("meta_files");if(_.isEmpty(h)){return $(['<a href="'+g.download+'" title="'+_l("Download")+'" ','class="icon-btn dataset-download-btn">','<span class="fa fa-floppy-o"></span>',"</a>"].join(""))}var i="dataset-"+this.model.get("id")+"-popup",f=['<div popupmenu="'+i+'">','<a href="'+g.download+'">',_l("Download Dataset"),"</a>","<a>"+_l("Additional Files")+"</a>",_.map(h,function(j){return['<a class="action-button" href="',g.meta_download+j.file_type,'">',_l("Download")," ",j.file_type,"</a>"].join("")}).join("\n"),"</div>",'<div class="icon-btn-group">','<a href="'+g.download+'" title="'+_l("Download")+'" ','class="icon-btn dataset-download-btn">','<span class="fa fa-floppy-o"></span>','</a><a class="icon-btn popup" id="'+i+'">','<span class="fa fa-caret-down"></span>',"</a>","</div>"].join("\n");return $(f)},_render_showParamsButton:function(){return faIconButton({title:_l("View details"),classes:"dataset-params-btn",href:this.urls.show_params,target:this.linkTarget,faIcon:"fa-info-circle"})},_render_body:function(){var g=$('<div>Error: unknown dataset state "'+this.model.get("state")+'".</div>'),f=this["_render_body_"+this.model.get("state")];if(_.isFunction(f)){g=f.call(this)}this._setUpBehaviors(g);if(this.expanded){g.show()}return g},_render_stateBodyHelper:function(f,i){i=i||[];var g=this,h=$(c.templates.body(_.extend(this.model.toJSON(),{body:f})));h.find(".dataset-actions .left").append(_.map(i,function(j){return j.call(g)}));return h},_render_body_new:function(){return this._render_stateBodyHelper("<div>"+_l("This is a new dataset and not all of its data are available yet")+"</div>")},_render_body_noPermission:function(){return this._render_stateBodyHelper("<div>"+_l("You do not have permission to view this dataset")+"</div>")},_render_body_discarded:function(){return this._render_stateBodyHelper("<div>"+_l("The job creating this dataset was cancelled before completion")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_queued:function(){return this._render_stateBodyHelper("<div>"+_l("This job is waiting to run")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_upload:function(){return this._render_stateBodyHelper("<div>"+_l("This dataset is currently uploading")+"</div>")},_render_body_setting_metadata:function(){return this._render_stateBodyHelper("<div>"+_l("Metadata is being auto-detected")+"</div>")},_render_body_running:function(){return this._render_stateBodyHelper("<div>"+_l("This job is currently running")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_paused:function(){return this._render_stateBodyHelper("<div>"+_l('This job is paused. Use the "Resume Paused Jobs" in the history menu to resume')+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_error:function(){var f=['<span class="help-text">',_l("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")){f="<div>"+this.model.get("misc_blurb")+"</div>"+f}return this._render_stateBodyHelper(f,[this._render_downloadButton].concat(this.defaultPrimaryActionButtonRenderers))},_render_body_empty:function(){return this._render_stateBodyHelper("<div>"+_l("No data")+": <i>"+this.model.get("misc_blurb")+"</i></div>",this.defaultPrimaryActionButtonRenderers)},_render_body_failed_metadata:function(){var f=$('<div class="warningmessagesmall"></div>').append($("<strong/>").text(_l("An error occurred setting the metadata for this dataset"))),g=this._render_body_ok();g.prepend(f);return g},_render_body_ok:function(){var f=this,h=$(c.templates.body(this.model.toJSON())),g=[this._render_downloadButton].concat(this.defaultPrimaryActionButtonRenderers);h.find(".dataset-actions .left").append(_.map(g,function(i){return i.call(f)}));if(this.model.isDeletedOrPurged()){return h}return h},events:{"click .dataset-title-bar":"toggleBodyVisibility","keydown .dataset-title-bar":"toggleBodyVisibility","click .dataset-selector":"toggleSelect"},toggleBodyVisibility:function(i,g){var f=32,h=13;if(i&&(i.type==="keydown")&&!(i.keyCode===f||i.keyCode===h)){return true}var j=this.$el.find(".dataset-body");g=(g===undefined)?(!j.is(":visible")):(g);if(g){this.expandBody()}else{this.collapseBody()}return false},expandBody:function(){var f=this;function g(){f.$el.children(".dataset-body").replaceWith(f._render_body());f.$el.children(".dataset-body").slideDown(f.fxSpeed,function(){f.expanded=true;f.trigger("body-expanded",f.model.get("id"))})}if(this.model.inReadyState()&&!this.model.hasDetails()){this.model.fetch({silent:true}).always(function(h){f.urls=f.model.urls();g()})}else{g()}},collapseBody:function(){var f=this;this.$el.children(".dataset-body").slideUp(f.fxSpeed,function(){f.expanded=false;f.trigger("body-collapsed",f.model.get("id"))})},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(f){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(f){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(f){if(this.selected){this.deselect(f)}else{this.select(f)}},draggableOn:function(){this.draggable=true;this.dragStartHandler=_.bind(this._dragStartHandler,this);this.dragEndHandler=_.bind(this._dragEndHandler,this);var f=this.$el.find(".dataset-title-bar").attr("draggable",true).get(0);f.addEventListener("dragstart",this.dragStartHandler,false);f.addEventListener("dragend",this.dragEndHandler,false)},draggableOff:function(){this.draggable=false;var f=this.$el.find(".dataset-title-bar").attr("draggable",false).get(0);f.removeEventListener("dragstart",this.dragStartHandler,false);f.removeEventListener("dragend",this.dragEndHandler,false)},toggleDraggable:function(){if(this.draggable){this.draggableOff()}else{this.draggableOn()}},_dragStartHandler:function(f){this.trigger("dragstart",this);f.dataTransfer.effectAllowed="move";f.dataTransfer.setData("text",JSON.stringify(this.model.toJSON()));return false},_dragEndHandler:function(f){this.trigger("dragend",this);return false},remove:function(g){var f=this;this.$el.fadeOut(f.fxSpeed,function(){f.$el.remove();f.off();if(g){g()}})},toString:function(){var f=(this.model)?(this.model+""):("(no model)");return"HDABaseView("+f+")"}});var a=['<div class="dataset hda">','<div class="dataset-warnings">',"<% if( hda.error ){ %>",'<div class="errormessagesmall">',_l("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>',_l("This dataset has been deleted and removed from disk."),"</strong></div>","<% } else { %>",'<div class="dataset-deleted-msg warningmessagesmall"><strong>',_l("This dataset has been deleted."),"</strong></div>","<% } %>","<% } %>","<% if( !hda.visible ){ %>",'<div class="dataset-hidden-msg warningmessagesmall"><strong>',_l("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 e=['<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">',_l("format"),"</label>",'<span class="value"><%- hda.data_type %></span>',"</div>","<% } %>","<% if( hda.metadata_dbkey ){ %>",'<div class="dataset-dbkey">','<label class="prompt">',_l("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(f){return _.template(a,f,{variable:"hda"})},body:function(f){return _.template(e,f,{variable:"hda"})}};return{HDABaseView:c}});
\ No newline at end of file
+define(["mvc/dataset/hda-model","mvc/base-mvc"],function(d,b){var c=Backbone.View.extend(b.LoggableMixin).extend({tagName:"div",className:"dataset hda history-panel-hda",id:function(){return"hda-"+this.model.get("id")},fxSpeed:"fast",initialize:function(f){if(f.logger){this.logger=this.model.logger=f.logger}this.log(this+".initialize:",f);this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton];this.linkTarget=f.linkTarget||"_blank";this.selectable=f.selectable||false;this.selected=f.selected||false;this.expanded=f.expanded||false;this.draggable=f.draggable||false;this._setUpListeners()},_setUpListeners:function(){this.model.on("change",function(g,f){if(this.model.changedAttributes().state&&this.model.inReadyState()&&this.expanded&&!this.model.hasDetails()){this.model.fetch()}else{this.render()}},this)},render:function(h){h=(h===undefined)?(true):(h);var f=this;this.$el.find("[title]").tooltip("destroy");this.urls=this.model.urls();var g=this._buildNewRender();if(h){$(f).queue(function(i){this.$el.fadeOut(f.fxSpeed,i)})}$(f).queue(function(i){this.$el.empty().attr("class",f.className).addClass("state-"+f.model.get("state")).append(g.children());if(this.selectable){this.showSelector(0)}i()});if(h){$(f).queue(function(i){this.$el.fadeIn(f.fxSpeed,i)})}$(f).queue(function(i){this.trigger("rendered",f);if(this.model.inReadyState()){this.trigger("rendered:ready",f)}if(this.draggable){this.draggableOn()}i()});return this},_buildNewRender:function(){var f=$(c.templates.skeleton(this.model.toJSON()));f.find(".dataset-primary-actions").append(this._render_titleButtons());f.children(".dataset-body").replaceWith(this._render_body());this._setUpBehaviors(f);return f},_setUpBehaviors:function(f){f=f||this.$el;make_popup_menus(f);f.find("[title]").tooltip({placement:"bottom"})},_render_titleButtons:function(){return[this._render_displayButton()]},_render_displayButton:function(){if((this.model.get("state")===d.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.DISCARDED)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.NEW)||(!this.model.get("accessible"))){return null}var g={target:this.linkTarget,classes:"dataset-display"};if(this.model.get("purged")){g.disabled=true;g.title=_l("Cannot display datasets removed from disk")}else{if(this.model.get("state")===d.HistoryDatasetAssociation.STATES.UPLOAD){g.disabled=true;g.title=_l("This dataset must finish uploading before it can be viewed")}else{g.title=_l("View data");g.href=this.urls.display;var f=this;g.onclick=function(h){if(Galaxy.frame&&Galaxy.frame.active){Galaxy.frame.add({title:"Data Viewer: "+f.model.get("name"),type:"url",content:f.urls.display});h.preventDefault()}}}}g.faIcon="fa-eye";return faIconButton(g)},_render_downloadButton:function(){if(this.model.get("purged")||!this.model.hasData()){return null}var g=this.urls,h=this.model.get("meta_files");if(_.isEmpty(h)){return $(['<a href="'+g.download+'" title="'+_l("Download")+'" ','class="icon-btn dataset-download-btn">','<span class="fa fa-floppy-o"></span>',"</a>"].join(""))}var i="dataset-"+this.model.get("id")+"-popup",f=['<div popupmenu="'+i+'">','<a href="'+g.download+'">',_l("Download Dataset"),"</a>","<a>"+_l("Additional Files")+"</a>",_.map(h,function(j){return['<a class="action-button" href="',g.meta_download+j.file_type,'">',_l("Download")," ",j.file_type,"</a>"].join("")}).join("\n"),"</div>",'<div class="icon-btn-group">','<a href="'+g.download+'" title="'+_l("Download")+'" ','class="icon-btn dataset-download-btn">','<span class="fa fa-floppy-o"></span>','</a><a class="icon-btn popup" id="'+i+'">','<span class="fa fa-caret-down"></span>',"</a>","</div>"].join("\n");return $(f)},_render_showParamsButton:function(){return faIconButton({title:_l("View details"),classes:"dataset-params-btn",href:this.urls.show_params,target:this.linkTarget,faIcon:"fa-info-circle"})},_render_body:function(){var g=$('<div>Error: unknown dataset state "'+this.model.get("state")+'".</div>'),f=this["_render_body_"+this.model.get("state")];if(_.isFunction(f)){g=f.call(this)}this._setUpBehaviors(g);if(this.expanded){g.show()}return g},_render_stateBodyHelper:function(f,i){i=i||[];var g=this,h=$(c.templates.body(_.extend(this.model.toJSON(),{body:f})));h.find(".dataset-actions .left").append(_.map(i,function(j){return j.call(g)}));return h},_render_body_new:function(){return this._render_stateBodyHelper("<div>"+_l("This is a new dataset and not all of its data are available yet")+"</div>")},_render_body_noPermission:function(){return this._render_stateBodyHelper("<div>"+_l("You do not have permission to view this dataset")+"</div>")},_render_body_discarded:function(){return this._render_stateBodyHelper("<div>"+_l("The job creating this dataset was cancelled before completion")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_queued:function(){return this._render_stateBodyHelper("<div>"+_l("This job is waiting to run")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_upload:function(){return this._render_stateBodyHelper("<div>"+_l("This dataset is currently uploading")+"</div>")},_render_body_setting_metadata:function(){return this._render_stateBodyHelper("<div>"+_l("Metadata is being auto-detected")+"</div>")},_render_body_running:function(){return this._render_stateBodyHelper("<div>"+_l("This job is currently running")+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_paused:function(){return this._render_stateBodyHelper("<div>"+_l('This job is paused. Use the "Resume Paused Jobs" in the history menu to resume')+"</div>",this.defaultPrimaryActionButtonRenderers)},_render_body_error:function(){var f=['<span class="help-text">',_l("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")){f="<div>"+this.model.get("misc_blurb")+"</div>"+f}return this._render_stateBodyHelper(f,[this._render_downloadButton].concat(this.defaultPrimaryActionButtonRenderers))},_render_body_empty:function(){return this._render_stateBodyHelper("<div>"+_l("No data")+": <i>"+this.model.get("misc_blurb")+"</i></div>",this.defaultPrimaryActionButtonRenderers)},_render_body_failed_metadata:function(){var f=$('<div class="warningmessagesmall"></div>').append($("<strong/>").text(_l("An error occurred setting the metadata for this dataset"))),g=this._render_body_ok();g.prepend(f);return g},_render_body_ok:function(){var f=this,h=$(c.templates.body(this.model.toJSON())),g=[this._render_downloadButton].concat(this.defaultPrimaryActionButtonRenderers);h.find(".dataset-actions .left").append(_.map(g,function(i){return i.call(f)}));if(this.model.isDeletedOrPurged()){return h}return h},events:{"click .dataset-title-bar":"toggleBodyVisibility","keydown .dataset-title-bar":"toggleBodyVisibility","click .dataset-selector":"toggleSelect"},toggleBodyVisibility:function(i,g){var f=32,h=13;if(i&&(i.type==="keydown")&&!(i.keyCode===f||i.keyCode===h)){return true}var j=this.$el.find(".dataset-body");g=(g===undefined)?(!j.is(":visible")):(g);if(g){this.expandBody()}else{this.collapseBody()}return false},expandBody:function(){var f=this;function g(){f.$el.children(".dataset-body").replaceWith(f._render_body());f.$el.children(".dataset-body").slideDown(f.fxSpeed,function(){f.expanded=true;f.trigger("body-expanded",f.model.get("id"))})}if(this.model.inReadyState()&&!this.model.hasDetails()){this.model.fetch({silent:true}).always(function(h){f.urls=f.model.urls();g()})}else{g()}},collapseBody:function(){var f=this;this.$el.children(".dataset-body").slideUp(f.fxSpeed,function(){f.expanded=false;f.trigger("body-collapsed",f.model.get("id"))})},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(f){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(f){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(f){if(this.selected){this.deselect(f)}else{this.select(f)}},draggableOn:function(){this.draggable=true;this.dragStartHandler=_.bind(this._dragStartHandler,this);this.dragEndHandler=_.bind(this._dragEndHandler,this);var f=this.$el.find(".dataset-title-bar").attr("draggable",true).get(0);f.addEventListener("dragstart",this.dragStartHandler,false);f.addEventListener("dragend",this.dragEndHandler,false)},draggableOff:function(){this.draggable=false;var f=this.$el.find(".dataset-title-bar").attr("draggable",false).get(0);f.removeEventListener("dragstart",this.dragStartHandler,false);f.removeEventListener("dragend",this.dragEndHandler,false)},toggleDraggable:function(){if(this.draggable){this.draggableOff()}else{this.draggableOn()}},_dragStartHandler:function(f){this.trigger("dragstart",this);f.dataTransfer.effectAllowed="move";f.dataTransfer.setData("text",JSON.stringify(this.model.toJSON()));return false},_dragEndHandler:function(f){this.trigger("dragend",this);return false},remove:function(g){var f=this;this.$el.fadeOut(f.fxSpeed,function(){f.$el.remove();f.off();if(g){g()}})},toString:function(){var f=(this.model)?(this.model+""):("(no model)");return"HDABaseView("+f+")"}});var a=['<div class="dataset hda">','<div class="dataset-warnings">',"<% if( hda.error ){ %>",'<div class="errormessagesmall">',_l("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>',_l("This dataset has been deleted and removed from disk."),"</strong></div>","<% } else { %>",'<div class="dataset-deleted-msg warningmessagesmall"><strong>',_l("This dataset has been deleted."),"</strong></div>","<% } %>","<% } %>","<% if( !hda.visible ){ %>",'<div class="dataset-hidden-msg warningmessagesmall"><strong>',_l("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 e=['<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">',_l("format"),"</label>",'<span class="value"><%- hda.data_type %></span>',"</div>","<% } %>","<% if( hda.metadata_dbkey ){ %>",'<div class="dataset-dbkey">','<label class="prompt">',_l("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(f){return _.template(a,f,{variable:"hda"})},body:function(f){return _.template(e,f,{variable:"hda"})}};return{HDABaseView:c}});
\ 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