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
commit/galaxy-central: dan: Display line errors in data table registry display encountered when loading a location file.
by commits-noreply@bitbucket.org 14 May '14
by commits-noreply@bitbucket.org 14 May '14
14 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/d963b05c497c/
Changeset: d963b05c497c
User: dan
Date: 2014-05-13 22:10:27
Summary: Display line errors in data table registry display encountered when loading a location file.
Affected #: 2 files
diff -r d0ab4f31e0e0178f58bd2bafb0b38d7a0fee9913 -r d963b05c497cc17d36a16696077e5a0f3158e52b lib/galaxy/tools/data/__init__.py
--- a/lib/galaxy/tools/data/__init__.py
+++ b/lib/galaxy/tools/data/__init__.py
@@ -285,8 +285,9 @@
filename = corrected_filename
found = True
+ errors = []
if found:
- self.data.extend( self.parse_file_fields( open( filename ) ) )
+ self.data.extend( self.parse_file_fields( open( filename ), errors=errors ) )
self._update_version()
else:
self.missing_index_file = filename
@@ -294,7 +295,7 @@
if filename not in self.filenames or not self.filenames[ filename ][ 'found' ]:
self.filenames[ filename ] = dict( found=found, filename=filename, from_shed_config=from_shed_config, tool_data_path=tool_data_path,
- config_element=config_element, tool_shed_repository=repo_info )
+ config_element=config_element, tool_shed_repository=repo_info, errors=errors )
else:
log.debug( "Filename '%s' already exists in filenames (%s), not adding", filename, self.filenames.keys() )
@@ -353,7 +354,7 @@
if 'name' not in self.columns:
self.columns['name'] = self.columns['value']
- def parse_file_fields( self, reader ):
+ def parse_file_fields( self, reader, errors=None ):
"""
Parse separated lines from file and return a list of tuples.
@@ -371,9 +372,10 @@
if self.largest_index < len( fields ):
rval.append( fields )
else:
- log.warn( "Line %i in tool data table '%s' is invalid (HINT: "
- "'%s' characters must be used to separate fields):\n%s"
- % ( ( i + 1 ), self.name, separator_char, line ) )
+ line_error = "Line %i in tool data table '%s' is invalid (HINT: '%s' characters must be used to separate fields):\n%s" % ( ( i + 1 ), self.name, separator_char, line )
+ if errors is not None:
+ errors.append( line_error )
+ log.warn( line_error )
return rval
def get_column_name_list( self ):
diff -r d0ab4f31e0e0178f58bd2bafb0b38d7a0fee9913 -r d963b05c497cc17d36a16696077e5a0f3158e52b templates/admin/view_data_tables_registry.mako
--- a/templates/admin/view_data_tables_registry.mako
+++ b/templates/admin/view_data_tables_registry.mako
@@ -18,7 +18,7 @@
<th bgcolor="#D8D8D8">Name</th><th bgcolor="#D8D8D8">Filename</th><th bgcolor="#D8D8D8">Tool data path</th>
- <th bgcolor="#D8D8D8">Missing index file</th>
+ <th bgcolor="#D8D8D8">Errors</th></tr>
%for data_table_elem_name, data_table in sorted_data_tables:
%if ctr % 2 == 1:
@@ -35,8 +35,11 @@
<td>${ file_dict.get( 'tool_data_path' ) | h }</td><td>
%if not file_dict.get( 'found' ):
- missing
+ file missing
%endif
+ %for error in file_dict.get( 'errors', [] ):
+ ${ error | h } <br/>
+ %endfor
</td></tr>
%endfor
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: More Data Manager UI fixes. Fix for viewing data manager job info when dataset has been deleted.
by commits-noreply@bitbucket.org 14 May '14
by commits-noreply@bitbucket.org 14 May '14
14 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/d0ab4f31e0e0/
Changeset: d0ab4f31e0e0
User: dan
Date: 2014-05-13 21:47:54
Summary: More Data Manager UI fixes. Fix for viewing data manager job info when dataset has been deleted.
Affected #: 5 files
diff -r dc74a95853b6ebe05f811b78b9a6cfbe43211fc8 -r d0ab4f31e0e0178f58bd2bafb0b38d7a0fee9913 lib/galaxy/webapps/galaxy/controllers/data_manager.py
--- a/lib/galaxy/webapps/galaxy/controllers/data_manager.py
+++ b/lib/galaxy/webapps/galaxy/controllers/data_manager.py
@@ -55,13 +55,18 @@
data_manager = trans.app.data_managers.get_manager( data_manager_id )
hdas = [ assoc.dataset for assoc in job.get_output_datasets() ]
data_manager_output = []
+ error_messages = []
for hda in hdas:
- data_manager_json = from_json_string( open( hda.get_file_name() ).read() )
+ try:
+ data_manager_json = from_json_string( open( hda.get_file_name() ).read() )
+ except Exception, e:
+ data_manager_json = {}
+ error_messages.append( "Unable to obtain data_table info for hda (%s): %s" % ( hda.id, e ) )
values = []
for key, value in data_manager_json.get( 'data_tables', {} ).iteritems():
values.append( ( key, value ) )
data_manager_output.append( values )
- return trans.fill_template( "data_manager/view_job.mako", data_manager=data_manager, job=job, view_only=not_is_admin, hdas=hdas, data_manager_output=data_manager_output, message=message, status=status )
+ return trans.fill_template( "data_manager/view_job.mako", data_manager=data_manager, job=job, view_only=not_is_admin, hdas=hdas, data_manager_output=data_manager_output, message=message, status=status, error_messages=error_messages )
@web.expose
def manage_data_table( self, trans, **kwd ):
diff -r dc74a95853b6ebe05f811b78b9a6cfbe43211fc8 -r d0ab4f31e0e0178f58bd2bafb0b38d7a0fee9913 templates/webapps/galaxy/data_manager/index.mako
--- a/templates/webapps/galaxy/data_manager/index.mako
+++ b/templates/webapps/galaxy/data_manager/index.mako
@@ -51,11 +51,10 @@
<li><a href="${h.url_for( controller='data_manager', action='manage_data_table', table_name=table_name)}" target="galaxy_main">
%if table_name in managed_table_names:
- <strong>${ table_name | h }</strong>
+ </span><strong>${ table_name | h }</strong></a><span class="fa fa-exchange">
%else:
- ${ table_name | h }
+ ${ table_name | h }</a>
%endif
- </a></li><p/>
%endfor
diff -r dc74a95853b6ebe05f811b78b9a6cfbe43211fc8 -r d0ab4f31e0e0178f58bd2bafb0b38d7a0fee9913 templates/webapps/galaxy/data_manager/manage_data_manager.mako
--- a/templates/webapps/galaxy/data_manager/manage_data_manager.mako
+++ b/templates/webapps/galaxy/data_manager/manage_data_manager.mako
@@ -28,7 +28,11 @@
<td>PID/Cluster ID</td></tr>
%for job in jobs:
- <td><a class="icon-btn" href="${ h.url_for( controller="data_manager", action="view_job", id=trans.security.encode_id( job.id ) ) }" title="View info"><span class="fa fa-info"></span></a></td>
+ <td>
+ <div class="icon-btn-group">
+ <a class="icon-btn" href="${ h.url_for( controller="data_manager", action="view_job", id=trans.security.encode_id( job.id ) ) }" title="View info"><span class="fa fa-info-circle"></span></a><a class="icon-btn" href="${ h.url_for( controller="tool_runner", action="rerun", job_id=trans.security.encode_id( job.id ) ) }" title="Rerun"><span class="fa fa-refresh"></span></a>
+ </div>
+ </td><td>${ job.id | h }</td>
%if job.history and job.history.user:
<td>${job.history.user.email | h}</td>
diff -r dc74a95853b6ebe05f811b78b9a6cfbe43211fc8 -r d0ab4f31e0e0178f58bd2bafb0b38d7a0fee9913 templates/webapps/galaxy/data_manager/manage_data_table.mako
--- a/templates/webapps/galaxy/data_manager/manage_data_table.mako
+++ b/templates/webapps/galaxy/data_manager/manage_data_table.mako
@@ -1,7 +1,7 @@
<%inherit file="/base.mako"/><%namespace file="/message.mako" import="render_msg" />
-<%def name="title()">Data Table Manager: ${ data_table.name | h }</%def>
+<%def name="title()">Tool Data Table: ${ data_table.name | h }</%def>
%if message:
${render_msg( message, status )}
diff -r dc74a95853b6ebe05f811b78b9a6cfbe43211fc8 -r d0ab4f31e0e0178f58bd2bafb0b38d7a0fee9913 templates/webapps/galaxy/data_manager/view_job.mako
--- a/templates/webapps/galaxy/data_manager/view_job.mako
+++ b/templates/webapps/galaxy/data_manager/view_job.mako
@@ -8,6 +8,12 @@
${render_msg( message, status )}
%endif
+%if error_messages:
+ %for error_message in error_messages:
+ ${ render_msg( error_message, 'error' ) }
+ %endfor
+%endif
+
%if view_only:
<p>Not implemented</p>
%else:
@@ -15,7 +21,7 @@
<table class="tabletip"><thead><tr><th colspan="2" style="font-size: 120%;">
- Data Manager: ${ data_manager.name | h } - ${ data_manager.description | h }
+ Data Manager: <a href="${ h.url_for( controller='tool_runner', action='index', tool_id=data_manager.tool.id ) }">${ data_manager.name | h }</a> - ${ data_manager.description | h } <a class="icon-btn" href="${ h.url_for( controller="tool_runner", action="rerun", job_id=trans.security.encode_id( job.id ) ) }" title="Rerun" data-placement="bottom"><span class="fa fa-refresh"></span></a></th></tr></thead><tbody>
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: Allow tool_runner rerun to accept a job_id instead of a dataset_id.
by commits-noreply@bitbucket.org 14 May '14
by commits-noreply@bitbucket.org 14 May '14
14 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/dc74a95853b6/
Changeset: dc74a95853b6
User: dan
Date: 2014-05-13 21:12:25
Summary: Allow tool_runner rerun to accept a job_id instead of a dataset_id.
Affected #: 1 file
diff -r f7de39159497fbcffb3f0ed785f26ecf56b40155 -r dc74a95853b6ebe05f811b78b9a6cfbe43211fc8 lib/galaxy/webapps/galaxy/controllers/tool_runner.py
--- a/lib/galaxy/webapps/galaxy/controllers/tool_runner.py
+++ b/lib/galaxy/webapps/galaxy/controllers/tool_runner.py
@@ -106,33 +106,41 @@
**vars )
@web.expose
- def rerun( self, trans, id=None, from_noframe=None, **kwd ):
+ def rerun( self, trans, id=None, from_noframe=None, job_id=None, **kwd ):
"""
Given a HistoryDatasetAssociation id, find the job and that created
the dataset, extract the parameters, and display the appropriate tool
form with parameters already filled in.
"""
- if not id:
- error( "'id' parameter is required" );
- try:
- id = int( id )
-
- except:
- # it's not an un-encoded id, try to parse as encoded
+ if job_id:
try:
- id = trans.security.decode_id( id )
+ job_id = trans.security.decode_id( job_id )
+ job = trans.sa_session.query( trans.app.model.Job ).get( job_id )
except:
- error( "Invalid value for 'id' parameter" )
-
- # Get the dataset object
- data = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( id )
- #only allow rerunning if user is allowed access to the dataset.
- if not ( trans.user_is_admin() or trans.app.security_agent.can_access_dataset( trans.get_current_user_roles(), data.dataset ) ):
- error( "You are not allowed to access this dataset" )
- # Get the associated job, if any.
- job = data.creating_job
- if not job:
- raise Exception("Failed to get job information for dataset hid %d" % data.hid)
+ error( "Invalid value for 'job_id' parameter" )
+ param_error_text = "Failed to get parameters for job id %d " % job_id
+ else:
+ if not id:
+ error( "'id' parameter is required" );
+ try:
+ id = int( id )
+ except:
+ # it's not an un-encoded id, try to parse as encoded
+ try:
+ id = trans.security.decode_id( id )
+ except:
+ error( "Invalid value for 'id' parameter" )
+
+ # Get the dataset object
+ data = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( id )
+ #only allow rerunning if user is allowed access to the dataset.
+ if not ( trans.user_is_admin() or trans.app.security_agent.can_access_dataset( trans.get_current_user_roles(), data.dataset ) ):
+ error( "You are not allowed to access this dataset" )
+ # Get the associated job, if any.
+ job = data.creating_job
+ if not job:
+ raise Exception("Failed to get job information for dataset hid %d" % data.hid)
+ param_error_text = "Failed to get parameters for dataset id %d " % data.id
# Get the tool object
tool_id = job.tool_id
tool_version = job.tool_version
@@ -172,7 +180,7 @@
try:
params_objects = job.get_param_values( trans.app, ignore_errors = True )
except:
- raise Exception( "Failed to get parameters for dataset id %d " % data.id )
+ raise Exception( param_error_text )
upgrade_messages = tool.check_and_update_param_values( params_objects, trans, update_values=False )
# Need to remap dataset parameters. Job parameters point to original
# dataset used; parameter should be the analygous dataset in the
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dan: More Data Manager UI tweaks.
by commits-noreply@bitbucket.org 14 May '14
by commits-noreply@bitbucket.org 14 May '14
14 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/f7de39159497/
Changeset: f7de39159497
User: dan
Date: 2014-05-13 20:34:57
Summary: More Data Manager UI tweaks.
Affected #: 1 file
diff -r 1c913c980053c4ce2dc6425cdf102298488242ec -r f7de39159497fbcffb3f0ed785f26ecf56b40155 templates/webapps/galaxy/data_manager/index.mako
--- a/templates/webapps/galaxy/data_manager/index.mako
+++ b/templates/webapps/galaxy/data_manager/index.mako
@@ -12,11 +12,11 @@
%if view_only:
<p>Not implemented</p>
%elif not data_managers.data_managers:
- ${render_msg( "You do not currently have any Data Managers installed.", "warning" ) }
+ ${ render_msg( 'You do not currently have any Data Managers installed. You can install some from a <a href="%s">ToolShed</a>.' % ( h.url_for( controller="admin_toolshed", action="browse_tool_sheds" ) ), "warning" ) }
%else:
- <p>Choose your data managing option from below.</p>
+ <p>Choose your data managing option from below. You may install additional Data Managers from a <a href="${ h.url_for( controller='admin_toolshed', action='browse_tool_sheds' ) }">ToolShed</a>.</p><ul>
- <li><strong>Run Data Manager Tools</strong>
+ <li><h3>Run Data Manager Tools</h3><div style="margin-left:1em"><ul>
%for data_manager_id, data_manager in sorted( data_managers.data_managers.iteritems(), key=lambda x:x[1].name ):
@@ -29,12 +29,12 @@
</div></li><p/>
- <li><strong>View Data Manager Jobs</strong>
+ <li><h3>View Data Manager Jobs</h3><div style="margin-left:1em"><ul>
%for data_manager_id, data_manager in sorted( data_managers.data_managers.iteritems(), key=lambda x:x[1].name ):
<li>
- <a href="${h.url_for( controller='data_manager', action='manage_data_manager', id=data_manager_id)}" target="galaxy_main"><strong>${ data_manager.name | h }</strong></a> - ${ data_manager.description | h }</a>
+ <a href="${ h.url_for( controller='data_manager', action='manage_data_manager', id=data_manager_id)}" target="galaxy_main"><strong>${ data_manager.name | h }</strong></a> - ${ data_manager.description | h }</a></li><p/>
%endfor
@@ -43,7 +43,7 @@
</li><p/><p/>
- <li><strong>View Tool Data Table Entries</strong>
+ <li><h3>View Tool Data Table Entries</h3><div style="margin-left:1em"><ul><% managed_table_names = data_managers.managed_data_tables.keys() %>
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: Alphabetize lists of Data Manager elements on index page.
by commits-noreply@bitbucket.org 13 May '14
by commits-noreply@bitbucket.org 13 May '14
13 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/1c913c980053/
Changeset: 1c913c980053
User: dan
Date: 2014-05-13 20:21:08
Summary: Alphabetize lists of Data Manager elements on index page.
Affected #: 1 file
diff -r a5a7edbe49055c328960eaa5c622a62ecf83b27d -r 1c913c980053c4ce2dc6425cdf102298488242ec templates/webapps/galaxy/data_manager/index.mako
--- a/templates/webapps/galaxy/data_manager/index.mako
+++ b/templates/webapps/galaxy/data_manager/index.mako
@@ -19,7 +19,7 @@
<li><strong>Run Data Manager Tools</strong><div style="margin-left:1em"><ul>
- %for data_manager_id, data_manager in data_managers.data_managers.iteritems():
+ %for data_manager_id, data_manager in sorted( data_managers.data_managers.iteritems(), key=lambda x:x[1].name ):
<li><a href="${ h.url_for( controller='tool_runner', action='index', tool_id=data_manager.tool.id ) }"><strong>${ data_manager.name | h }</strong></a> - ${ data_manager.description | h }
</li>
@@ -32,7 +32,7 @@
<li><strong>View Data Manager Jobs</strong><div style="margin-left:1em"><ul>
- %for data_manager_id, data_manager in data_managers.data_managers.iteritems():
+ %for data_manager_id, data_manager in sorted( data_managers.data_managers.iteritems(), key=lambda x:x[1].name ):
<li><a href="${h.url_for( controller='data_manager', action='manage_data_manager', id=data_manager_id)}" target="galaxy_main"><strong>${ data_manager.name | h }</strong></a> - ${ data_manager.description | h }</a></li>
@@ -46,20 +46,19 @@
<li><strong>View Tool Data Table Entries</strong><div style="margin-left:1em"><ul>
- %for table_name, managers in data_managers.managed_data_tables.iteritems():
+ <% managed_table_names = data_managers.managed_data_tables.keys() %>
+ %for table_name in sorted( tool_data_tables.get_tables().keys() ):
<li>
- <a href="${h.url_for( controller='data_manager', action='manage_data_table', table_name=table_name)}" target="galaxy_main"><strong>${ table_name | h }</strong></a>
+ <a href="${h.url_for( controller='data_manager', action='manage_data_table', table_name=table_name)}" target="galaxy_main">
+ %if table_name in managed_table_names:
+ <strong>${ table_name | h }</strong>
+ %else:
+ ${ table_name | h }
+ %endif
+ </a></li><p/>
%endfor
- %for table_name in tool_data_tables.get_tables():
- %if table_name not in data_managers.managed_data_tables:
- <li>
- <a href="${h.url_for( controller='data_manager', action='manage_data_table', table_name=table_name)}" target="galaxy_main">${ table_name | h }</a>
- </li>
- <p/>
- %endif
- %endfor
</ul></div></li>
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: Data Manager UI enhancements.
by commits-noreply@bitbucket.org 13 May '14
by commits-noreply@bitbucket.org 13 May '14
13 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/a5a7edbe4905/
Changeset: a5a7edbe4905
User: dan
Date: 2014-05-13 20:07:07
Summary: Data Manager UI enhancements.
Affected #: 5 files
diff -r e5b545b85b836b6f1be76164543d7e4613f25d87 -r a5a7edbe49055c328960eaa5c622a62ecf83b27d lib/galaxy/webapps/galaxy/controllers/data_manager.py
--- a/lib/galaxy/webapps/galaxy/controllers/data_manager.py
+++ b/lib/galaxy/webapps/galaxy/controllers/data_manager.py
@@ -19,7 +19,7 @@
raise paste.httpexceptions.HTTPUnauthorized( "This Galaxy instance is not configured to allow non-admins to view the data manager." )
message = kwd.get( 'message' )
status = kwd.get( 'status', 'info' )
- return trans.fill_template( "data_manager/index.mako", data_managers=trans.app.data_managers, view_only=not_is_admin, message=message, status=status )
+ return trans.fill_template( "data_manager/index.mako", data_managers=trans.app.data_managers, tool_data_tables=trans.app.tool_data_tables, view_only=not_is_admin, message=message, status=status )
@web.expose
def manage_data_manager( self, trans, **kwd ):
@@ -32,7 +32,7 @@
data_manager = trans.app.data_managers.get_manager( data_manager_id )
if data_manager is None:
return trans.response.send_redirect( web.url_for( controller="data_manager", action="index", message="Invalid Data Manager (%s) was requested" % data_manager_id, status="error" ) )
- jobs = reversed( [ assoc.job for assoc in trans.sa_session.query( trans.app.model.DataManagerJobAssociation ).filter_by( data_manager_id=data_manager_id ) ] )
+ jobs = list( reversed( [ assoc.job for assoc in trans.sa_session.query( trans.app.model.DataManagerJobAssociation ).filter_by( data_manager_id=data_manager_id ) ] ) )
return trans.fill_template( "data_manager/manage_data_manager.mako", data_manager=data_manager, jobs=jobs, view_only=not_is_admin, message=message, status=status )
@web.expose
diff -r e5b545b85b836b6f1be76164543d7e4613f25d87 -r a5a7edbe49055c328960eaa5c622a62ecf83b27d templates/webapps/galaxy/data_manager/index.mako
--- a/templates/webapps/galaxy/data_manager/index.mako
+++ b/templates/webapps/galaxy/data_manager/index.mako
@@ -11,11 +11,13 @@
%if view_only:
<p>Not implemented</p>
+%elif not data_managers.data_managers:
+ ${render_msg( "You do not currently have any Data Managers installed.", "warning" ) }
%else:
<p>Choose your data managing option from below.</p><ul>
- <li><strong>Access data managers</strong> - get data, build indexes, etc
- <p/>
+ <li><strong>Run Data Manager Tools</strong>
+ <div style="margin-left:1em"><ul>
%for data_manager_id, data_manager in data_managers.data_managers.iteritems():
<li>
@@ -24,10 +26,11 @@
<p/>
%endfor
</ul>
+ </div></li><p/>
- <li><strong>View managed data by manager</strong>
- <p/>
+ <li><strong>View Data Manager Jobs</strong>
+ <div style="margin-left:1em"><ul>
%for data_manager_id, data_manager in data_managers.data_managers.iteritems():
<li>
@@ -36,11 +39,12 @@
<p/>
%endfor
</ul>
+ </div></li><p/><p/>
- <li><strong>View managed data by Tool Data Table</strong>
- <p/>
+ <li><strong>View Tool Data Table Entries</strong>
+ <div style="margin-left:1em"><ul>
%for table_name, managers in data_managers.managed_data_tables.iteritems():
<li>
@@ -48,10 +52,21 @@
</li><p/>
%endfor
+ %for table_name in tool_data_tables.get_tables():
+ %if table_name not in data_managers.managed_data_tables:
+ <li>
+ <a href="${h.url_for( controller='data_manager', action='manage_data_table', table_name=table_name)}" target="galaxy_main">${ table_name | h }</a>
+ </li>
+ <p/>
+ %endif
+ %endfor
</ul>
+ </div></li><p/></ul><p/><br/>
%endif
+
+${render_msg( 'To find out more information about Data Managers, please visit the <a href="https://wiki.galaxyproject.org/Admin/Tools/DataManagers" target="_blank">wiki.</a>', "info" ) }
diff -r e5b545b85b836b6f1be76164543d7e4613f25d87 -r a5a7edbe49055c328960eaa5c622a62ecf83b27d templates/webapps/galaxy/data_manager/manage_data_manager.mako
--- a/templates/webapps/galaxy/data_manager/manage_data_manager.mako
+++ b/templates/webapps/galaxy/data_manager/manage_data_manager.mako
@@ -18,6 +18,7 @@
<div><table class="manage-table colored" border="0" cellspacing="0" cellpadding="0" width="100%"><tr class="header">
+ <td>Actions</td><td>Job ID</td><td>User</td><td>Last Update</td>
@@ -27,7 +28,8 @@
<td>PID/Cluster ID</td></tr>
%for job in jobs:
- <td><a href="${ h.url_for( controller="data_manager", action="view_job", id=trans.security.encode_id( job.id ) ) }">${ job.id | h }</a></td>
+ <td><a class="icon-btn" href="${ h.url_for( controller="data_manager", action="view_job", id=trans.security.encode_id( job.id ) ) }" title="View info"><span class="fa fa-info"></span></a></td>
+ <td>${ job.id | h }</td>
%if job.history and job.history.user:
<td>${job.history.user.email | h}</td>
%else:
diff -r e5b545b85b836b6f1be76164543d7e4613f25d87 -r a5a7edbe49055c328960eaa5c622a62ecf83b27d templates/webapps/galaxy/data_manager/manage_data_table.mako
--- a/templates/webapps/galaxy/data_manager/manage_data_table.mako
+++ b/templates/webapps/galaxy/data_manager/manage_data_table.mako
@@ -10,30 +10,36 @@
%if view_only:
<p>Not implemented</p>
%else:
-<% column_name_list = data_table.get_column_name_list() %>
-<table class="tabletip">
- <thead>
- <tr><th colspan="${len (column_name_list) }" style="font-size: 120%;">
- Data Manager: ${ data_table.name | h }
- <a class="icon-btn" href="${ h.url_for( controller="data_manager", action="reload_tool_data_tables", table_name=data_table.name ) }" title="Reload ${data_table.name} tool data table" data-placement="bottom">
- <span class="fa fa-refresh"></span>
- </a>
- </th></tr>
- <tr>
-
- %for name in column_name_list:
- <th>${name | h}</th>
- %endfor
- </tr>
- </thead>
- <tbody>
- %for table_row in data_table.data:
- <tr>
- %for field in table_row:
- <td>${field | h}</td>
- %endfor
- </tr>
- %endfor
-</table>
+ <p>
+ <% column_name_list = data_table.get_column_name_list() %>
+ <table class="tabletip">
+ <thead>
+ <tr><th colspan="${len (column_name_list) }" style="font-size: 120%;">
+ Data Manager: ${ data_table.name | h }
+ <a class="icon-btn" href="${ h.url_for( controller="data_manager", action="reload_tool_data_tables", table_name=data_table.name ) }" title="Reload ${data_table.name} tool data table" data-placement="bottom">
+ <span class="fa fa-refresh"></span>
+ </a>
+ </th></tr>
+ <tr>
+
+ %for name in column_name_list:
+ <th>${name | h}</th>
+ %endfor
+ </tr>
+ </thead>
+ <tbody>
+ %for table_row in data_table.data:
+ <tr>
+ %for field in table_row:
+ <td>${field | h}</td>
+ %endfor
+ </tr>
+ %endfor
+ </tbody>
+ </table>
+ </p>
+ %if not data_table.data:
+ ${render_msg( "There are currently no entries in this Tool Data Table.", "warning" ) }
+ %endif
%endif
diff -r e5b545b85b836b6f1be76164543d7e4613f25d87 -r a5a7edbe49055c328960eaa5c622a62ecf83b27d templates/webapps/galaxy/data_manager/view_job.mako
--- a/templates/webapps/galaxy/data_manager/view_job.mako
+++ b/templates/webapps/galaxy/data_manager/view_job.mako
@@ -34,7 +34,7 @@
<table class="tabletip"><thead><tr><th colspan="2" style="font-size: 120%;">
- Data Table: ${ table_name | h }
+ Data Table: <a href="${h.url_for( controller='data_manager', action='manage_data_table', table_name=table_name)}">${ table_name | h }</a></th></tr></thead><% len_json_table = len( json_table ) %>
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 the ability for Admins to reload tool data table entries from disk without restarting the Galaxy server. This does not look for new <table> entries or contained new <file>s within XML files, but will e.g. make any changes to a .loc file become live immediately without restart.
by commits-noreply@bitbucket.org 13 May '14
by commits-noreply@bitbucket.org 13 May '14
13 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/e5b545b85b83/
Changeset: e5b545b85b83
User: dan
Date: 2014-05-13 19:01:47
Summary: Add the ability for Admins to reload tool data table entries from disk without restarting the Galaxy server. This does not look for new <table> entries or contained new <file>s within XML files, but will e.g. make any changes to a .loc file become live immediately without restart.
Affected #: 3 files
diff -r c74989f7cafe0605af12af8dc2303689fa674bde -r e5b545b85b836b6f1be76164543d7e4613f25d87 lib/galaxy/tools/data/__init__.py
--- a/lib/galaxy/tools/data/__init__.py
+++ b/lib/galaxy/tools/data/__init__.py
@@ -141,6 +141,18 @@
out.write( '</tables>\n' )
os.chmod( full_path, 0644 )
+ def reload_tables( self, table_names=None ):
+ tables = self.get_tables()
+ if not table_names:
+ table_names = tables.keys()
+ elif not isinstance( table_names, list ):
+ table_names = [ table_names ]
+ for table_name in table_names:
+ tables[ table_name ].reload_from_files()
+ log.debug( "Reloaded tool data table '%s' from files.", table_name )
+ return table_names
+
+
class ToolDataTable( object ):
@classmethod
@@ -160,9 +172,14 @@
# increment this variable any time a new entry is added, or when the table is totally reloaded
# This value has no external meaning, and does not represent an abstract version of the underlying data
self._loaded_content_version = 1
+ self._load_info = ( [ config_element, tool_data_path ], { 'from_shed_config':from_shed_config } )
+ self._merged_load_info = []
- def _update_version( self ):
- self._loaded_content_version += 1
+ def _update_version( self, version=None ):
+ if version is not None:
+ self._loaded_content_version = version
+ else:
+ self._loaded_content_version += 1
return self._loaded_content_version
def get_empty_field_by_name( self, name ):
@@ -187,6 +204,16 @@
def merge_tool_data_table( self, other_table, allow_duplicates=True, persist=False, persist_on_error=False, entry_source=None, **kwd ):
raise NotImplementedError( "Abstract method" )
+ def reload_from_files( self ):
+ new_version = self._update_version()
+ merged_info = self._merged_load_info
+ self.__init__( *self._load_info[0], **self._load_info[1] )
+ self._update_version( version=new_version )
+ for ( tool_data_table_class, load_info ) in merged_info:
+ self.merge_tool_data_table( tool_data_table_class( *load_info[0], **load_info[1] ), allow_duplicates=False )
+ return self._update_version()
+
+
class TabularToolDataTable( ToolDataTable ):
"""
Data stored in a tabular / separated value format on disk, allows multiple
@@ -278,6 +305,8 @@
for filename, info in other_table.filenames.iteritems():
if filename not in self.filenames:
self.filenames[ filename ] = info
+ #save info about table
+ self._merged_load_info.append( ( other_table.__class__, other_table._load_info ) )
#add data entries and return current data table version
return self.add_entries( other_table.data, allow_duplicates=allow_duplicates, persist=persist, persist_on_error=persist_on_error, entry_source=entry_source, **kwd )
diff -r c74989f7cafe0605af12af8dc2303689fa674bde -r e5b545b85b836b6f1be76164543d7e4613f25d87 lib/galaxy/webapps/galaxy/controllers/data_manager.py
--- a/lib/galaxy/webapps/galaxy/controllers/data_manager.py
+++ b/lib/galaxy/webapps/galaxy/controllers/data_manager.py
@@ -77,3 +77,33 @@
if data_table is None:
return trans.response.send_redirect( web.url_for( controller="data_manager", action="index", message="Invalid Data table (%s) was requested" % data_table_name, status="error" ) )
return trans.fill_template( "data_manager/manage_data_table.mako", data_table=data_table, view_only=not_is_admin, message=message, status=status )
+
+ @web.expose
+ @web.require_admin
+ def reload_tool_data_tables( self, trans, table_name=None, **kwd ):
+ if table_name and isinstance( table_name, basestring ):
+ table_name = table_name.split( "," )
+ # Reload the tool data tables
+ table_names = self.app.tool_data_tables.reload_tables( table_names=table_name )
+ redirect_url = None
+ if table_names:
+ status = 'done'
+ if len( table_names ) == 1:
+ message = "The data table '%s' has been reloaded." % table_names[0]
+ redirect_url = web.url_for( controller='data_manager',
+ action='manage_data_table',
+ table_name=table_names[0],
+ message=message,
+ status=status )
+ else:
+ message = "The data tables '%s' have been reloaded." % ', '.join( table_names )
+ else:
+ message = "No data tables have been reloaded."
+ status = 'error'
+ if redirect_url is None:
+ redirect_url = web.url_for( controller='admin',
+ action='view_tool_data_tables',
+ message=message,
+ status=status )
+ return trans.response.send_redirect( redirect_url )
+
diff -r c74989f7cafe0605af12af8dc2303689fa674bde -r e5b545b85b836b6f1be76164543d7e4613f25d87 templates/webapps/galaxy/data_manager/manage_data_table.mako
--- a/templates/webapps/galaxy/data_manager/manage_data_table.mako
+++ b/templates/webapps/galaxy/data_manager/manage_data_table.mako
@@ -15,6 +15,9 @@
<thead><tr><th colspan="${len (column_name_list) }" style="font-size: 120%;">
Data Manager: ${ data_table.name | h }
+ <a class="icon-btn" href="${ h.url_for( controller="data_manager", action="reload_tool_data_tables", table_name=data_table.name ) }" title="Reload ${data_table.name} tool data table" data-placement="bottom">
+ <span class="fa fa-refresh"></span>
+ </a></th></tr><tr>
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: When viewing tool data table registry in admin interface, provide link to manage data table interface for each tool data table.
by commits-noreply@bitbucket.org 13 May '14
by commits-noreply@bitbucket.org 13 May '14
13 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/c74989f7cafe/
Changeset: c74989f7cafe
User: dan
Date: 2014-05-13 18:35:35
Summary: When viewing tool data table registry in admin interface, provide link to manage data table interface for each tool data table.
Affected #: 1 file
diff -r a4bdf116d532cf18560ed2a4f1b94e84d7d9cc8b -r c74989f7cafe0605af12af8dc2303689fa674bde templates/admin/view_data_tables_registry.mako
--- a/templates/admin/view_data_tables_registry.mako
+++ b/templates/admin/view_data_tables_registry.mako
@@ -26,7 +26,7 @@
%else:
<tr class="tr">
%endif
- <td>${data_table.name}</td>
+ <td><a href="${ h.url_for( controller="data_manager", action="manage_data_table", table_name=data_table.name ) }">${data_table.name}</a></td>
%for i, ( filename, file_dict ) in enumerate( data_table.filenames.iteritems() ):
%if i > 0:
<tr><td></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
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/e13610643216/
Changeset: e13610643216
User: jmchilton
Date: 2014-05-13 17:20:06
Summary: Remove no longer valid log message.
Affected #: 1 file
diff -r 953baebbd9d9f7757691b73eee3bc954570b2bbd -r e13610643216c4d59b41722516e9d4aa9b4466b8 lib/galaxy/jobs/runners/__init__.py
--- a/lib/galaxy/jobs/runners/__init__.py
+++ b/lib/galaxy/jobs/runners/__init__.py
@@ -210,7 +210,6 @@
destination = job_wrapper.get_output_destination( output_paths[ dataset.dataset_id ] )
if in_directory( source_file, job_working_directory ):
output_pairs.append( ( source_file, destination ) )
- log.debug( "Copying %s to %s as directed by from_work_dir" % ( source_file, destination ) )
else:
# Security violation.
log.exception( "from_work_dir specified a location not in the working directory: %s, %s" % ( source_file, job_wrapper.working_directory ) )
https://bitbucket.org/galaxy/galaxy-central/commits/a4bdf116d532/
Changeset: a4bdf116d532
User: jmchilton
Date: 2014-05-13 17:20:06
Summary: Optimize/correct LWR remote metadata generation for working directory outputs.
Previously I was attempting to mimic Galaxy's behavior of copying these files to a fixed output location after execution on the remote server before setting metadata. This was an un-needed copy since it appears to easier to just send the metadata generation code the expected path on the working directory.
Affected #: 1 file
diff -r e13610643216c4d59b41722516e9d4aa9b4466b8 -r a4bdf116d532cf18560ed2a4f1b94e84d7d9cc8b lib/galaxy/jobs/runners/lwr.py
--- a/lib/galaxy/jobs/runners/lwr.py
+++ b/lib/galaxy/jobs/runners/lwr.py
@@ -172,7 +172,6 @@
job_wrapper.prepare( **prepare_kwds )
self.__prepare_input_files_locally(job_wrapper)
remote_metadata = LwrJobRunner.__remote_metadata( client )
- remote_work_dir_copy = LwrJobRunner.__remote_work_dir_copy( client )
dependency_resolution = LwrJobRunner.__dependency_resolution( client )
metadata_kwds = self.__build_metadata_configuration(client, job_wrapper, remote_metadata, remote_job_config)
remote_command_params = dict(
@@ -184,7 +183,7 @@
self,
job_wrapper=job_wrapper,
include_metadata=remote_metadata,
- include_work_dir_outputs=remote_work_dir_copy,
+ include_work_dir_outputs=False,
remote_command_params=remote_command_params,
)
except Exception:
@@ -358,13 +357,7 @@
self.client_manager.shutdown()
def __client_outputs( self, client, job_wrapper ):
- remote_work_dir_copy = LwrJobRunner.__remote_work_dir_copy( client )
- if not remote_work_dir_copy:
- work_dir_outputs = self.get_work_dir_outputs( job_wrapper )
- else:
- # They have already been copied over to look like regular outputs remotely,
- # no need to handle them differently here.
- work_dir_outputs = []
+ work_dir_outputs = self.get_work_dir_outputs( job_wrapper )
output_files = self.get_output_files( job_wrapper )
client_outputs = ClientOutputs(
working_directory=job_wrapper.working_directory,
@@ -400,16 +393,6 @@
return remote_metadata
@staticmethod
- def __remote_work_dir_copy( lwr_client ):
- # Right now remote metadata handling assumes from_work_dir outputs
- # have been copied over before it runs. So do that remotely. This is
- # not the default though because adding it to the command line is not
- # cross-platform (no cp on Windows) and it's un-needed work outside
- # the context of metadata settting (just as easy to download from
- # either place.)
- return LwrJobRunner.__remote_metadata( lwr_client )
-
- @staticmethod
def __use_remote_datatypes_conf( lwr_client ):
""" When setting remote metadata, use integrated datatypes from this
Galaxy instance or use the datatypes config configured via the remote
@@ -440,7 +423,21 @@
outputs_directory = remote_job_config['outputs_directory']
configs_directory = remote_job_config['configs_directory']
working_directory = remote_job_config['working_directory']
+ # For metadata calculation, we need to build a list of of output
+ # file objects with real path indicating location on Galaxy server
+ # and false path indicating location on compute server. Since the
+ # LWR disables from_work_dir copying as part of the job command
+ # line we need to take the list of output locations on the LWR
+ # server (produced by self.get_output_files(job_wrapper)) and for
+ # each work_dir output substitute the effective path on the LWR
+ # server relative to the remote working directory as the
+ # false_path to send the metadata command generation module.
+ work_dir_outputs = self.get_work_dir_outputs(job_wrapper, job_working_directory=working_directory)
outputs = [Bunch(false_path=os.path.join(outputs_directory, os.path.basename(path)), real_path=path) for path in self.get_output_files(job_wrapper)]
+ for output in outputs:
+ for lwr_workdir_path, real_path in work_dir_outputs:
+ if real_path == output.real_path:
+ output.false_path = lwr_workdir_path
metadata_kwds['output_fnames'] = outputs
metadata_kwds['compute_tmp_dir'] = working_directory
metadata_kwds['config_root'] = remote_galaxy_home
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: Ensure new_file_path exists before set_metadata.py generates metadata.
by commits-noreply@bitbucket.org 13 May '14
by commits-noreply@bitbucket.org 13 May '14
13 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/953baebbd9d9/
Changeset: 953baebbd9d9
User: jmchilton
Date: 2014-05-13 16:29:41
Summary: Ensure new_file_path exists before set_metadata.py generates metadata.
This directory is required to exist but usually unneeded because Galaxy creates this directory on startup. However, when setting metadata remotely with the LWR that remote Galaxy instance may have never been started and this directory may not exist.
Affected #: 2 files
diff -r f5f6cd1e938304094c9491da10824f93cbfb2d27 -r 953baebbd9d9f7757691b73eee3bc954570b2bbd lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -417,6 +417,16 @@
else:
return default
+ def ensure_tempdir( self ):
+ self._ensure_directory( self.new_file_path )
+
+ def _ensure_directory( self, path ):
+ if path not in [ None, False ] and not os.path.isdir( path ):
+ try:
+ os.makedirs( path )
+ except Exception, e:
+ raise ConfigurationError( "Unable to create missing directory: %s\n%s" % ( path, e ) )
+
def check( self ):
paths_to_check = [ self.root, self.tool_path, self.tool_data_path, self.template_path ]
# Check that required directories exist
@@ -440,11 +450,7 @@
self.whoosh_index_dir, \
self.object_store_cache_path, \
os.path.join( self.tool_data_path, 'shared', 'jars' ):
- if path not in [ None, False ] and not os.path.isdir( path ):
- try:
- os.makedirs( path )
- except Exception, e:
- raise ConfigurationError( "Unable to create missing directory: %s\n%s" % ( path, e ) )
+ self._ensure_directory( path )
# Check that required files exist
tool_configs = self.tool_configs
if self.migrated_tools_config not in tool_configs:
diff -r f5f6cd1e938304094c9491da10824f93cbfb2d27 -r 953baebbd9d9f7757691b73eee3bc954570b2bbd scripts/set_metadata.py
--- a/scripts/set_metadata.py
+++ b/scripts/set_metadata.py
@@ -66,6 +66,7 @@
log.debug("Did not load option %s from %s" % (option, config_file_name))
# config object is required by ObjectStore class so create it now
universe_config = config.Configuration(**conf_dict)
+ universe_config.ensure_tempdir()
object_store = build_object_store_from_config(universe_config)
galaxy.model.Dataset.object_store = object_store
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: Improvements to LWR documentation.
by commits-noreply@bitbucket.org 13 May '14
by commits-noreply@bitbucket.org 13 May '14
13 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/f5f6cd1e9383/
Changeset: f5f6cd1e9383
User: jmchilton
Date: 2014-05-13 07:46:41
Summary: Improvements to LWR documentation.
Add separate examples for MQ driven stuff - this should clear up things and make it clear which new parameters are required when using message queue and which are no longer required. Add more documentation for remote dependency resolution. Document rewrite_parameters.
Affected #: 1 file
diff -r 24b5759f33f87879e945a2f14ef5e8abfce488c1 -r f5f6cd1e938304094c9491da10824f93cbfb2d27 job_conf.xml.sample_advanced
--- a/job_conf.xml.sample_advanced
+++ b/job_conf.xml.sample_advanced
@@ -23,11 +23,6 @@
<!-- More information on LWR can be found at https://lwr.readthedocs.org --><!-- Uncomment following line to use libcurl to perform HTTP calls (defaults to urllib) --><!-- <param id="transport">curl</param> -->
- <!-- Uncomment following parameters (second optional) to target a message
- queue, ensure jobs_directory is specified on destinations and all
- file actions are remote executable. -->
- <!-- <param id="url">amqp://guest:guest@localhost:5672//</param> -->
- <!-- <param id="manager">_default_</param> --><!-- *Experimental Caching*: Uncomment next parameters to enable
caching and specify the number of caching threads to enable on Galaxy
side. Likely will not work with newer features such as MQ support.
@@ -37,6 +32,16 @@
<!-- <param id="cache">True</param> --><!-- <param id="transfer_threads">2</param> --></plugin>
+ <plugin id="amqp_lwr" type="runner" load="galaxy.jobs.runners.lwr:LwrJobRunner">
+ <param id="url">amqp://guest:guest@localhost:5672//</param>
+ <!-- If using message queue driven LWR - the LWR will generally
+ initiate file transfers so a the URL of this Galaxy instance
+ must be configured. -->
+ <param id="galaxy_url">http://localhost:8080/</param>
+ <!-- If multiple managers configured on the LWR, specify which one
+ this plugin targets. -->
+ <!-- <param id="manager">_default_</param> -->
+ </plugin><plugin id="cli" type="runner" load="galaxy.jobs.runners.cli:ShellJobRunner" /><plugin id="condor" type="runner" load="galaxy.jobs.runners.condor:CondorJobRunner" /><plugin id="slurm" type="runner" load="galaxy.jobs.runners.slurm:SlurmJobRunner" />
@@ -116,7 +121,11 @@
<!-- Uncomment the following statement to disable file staging (e.g.
if there is a shared file system between Galaxy and the LWR
server). Alternatively action can be set to 'copy' - to replace
- http transfers with file system copies. -->
+ http transfers with file system copies, 'remote_transfer' to cause
+ the lwr to initiate HTTP transfers instead of Galaxy, or
+ 'remote_copy' to cause lwr to initiate file system copies.
+ If setting this to 'remote_transfer' be sure to specify a
+ 'galaxy_url' attribute on the runner plugin above. --><!-- <param id="default_file_action">none</param> --><!-- The above option is just the default, the transfer behavior
none|copy|http can be configured on a per path basis via the
@@ -128,24 +137,29 @@
<!-- Uncomment following option to disable Galaxy tool dependency
resolution and utilize remote LWR's configuraiton of tool
dependency resolution instead (same options as Galaxy for
- dependency resolution are available in LWR).
+ dependency resolution are available in LWR). At a minimum
+ the remote LWR server should define a tool_dependencies_dir in
+ its `server.ini` configuration. The LWR will not attempt to
+ stage dependencies - so ensure the the required galaxy or tool
+ shed packages are available remotely (exact same tool shed
+ installed changesets are required).
--><!-- <param id="dependency_resolution">remote</params> -->
+ <!-- Traditionally, the LWR allow Galaxy to generate a command line
+ as if it were going to run the command locally and then the
+ LWR client rewrites it after the fact using regular
+ expressions. Setting the following value to true causes the
+ LWR runner to insert itself into the command line generation
+ process and generate the correct command line from the get go.
+ This will likely be the default someday - but requires a newer
+ LWR version and is less well tested. -->
+ <!-- <param id="rewrite_parameters">true</params> --><!-- Uncomment following option to enable setting metadata on remote
LWR server. The 'use_remote_datatypes' option is available for
determining whether to use remotely configured datatypes or local
ones (both alternatives are a little brittle). --><!-- <param id="remote_metadata">true</param> --><!-- <param id="use_remote_datatypes">false</param> -->
- <!-- 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 jobs_directory and
- specifying any additional remote_property_ of
- interest. When using message queues this is nessecary
- not optional.
- -->
- <!-- <param id="jobs_directory">/path/to/remote/lwr/lwr_staging/</param> --><!-- <param id="remote_property_galaxy_home">/path/to/remote/galaxy-central</param> --><!-- If remote LWR server is configured to run jobs as the real user,
uncomment the following line to pass the current Galaxy user
@@ -157,6 +171,27 @@
--><!-- <param id="submit_native_specification">-P bignodes -R y -pe threads 8</param> --></destination>
+ <destination id="amqp_lwr_dest" runner="amqp_lwr" >
+ <!-- url and private_token are not valid when using MQ driven LWR. The plugin above
+ determines which queue/manager to target and the underlying MQ server should be
+ used to configure security.
+ -->
+ <!-- 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 jobs_directory and
+ specifying any additional remote_property_ of
+ interest, this is not optional when using message
+ queues.
+ -->
+ <param id="jobs_directory">/path/to/remote/lwr/lwr_staging/</param>
+ <!-- Default the LWR send files to and pull files from Galaxy when
+ using message queues (in the more traditional mode Galaxy sends
+ files to and pull files from the LWR - this is obviously less
+ appropriate when using a message queue).
+ -->
+ <param id="default_file_action">remote_transfer</param>
+ </destination><destination id="ssh_torque" runner="cli"><param id="shell_plugin">SecureShell</param><param id="job_plugin">Torque</param>
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/48ee04030f89/
Changeset: 48ee04030f89
User: jmchilton
Date: 2014-05-13 07:13:02
Summary: Implement serializable class that can describe full dependency context for remote dependency resolution.
Previously LWR jut serialized tool requirements, by transitioning to this class LWR should be able to resolve tool shed installed packages as well - requiring the additional repository and tool dependency context.
Affected #: 2 files
diff -r 3b29b6f83d17ed07d2c3ea49d839b29d66cad580 -r 48ee04030f893a9a9657b639bb38819fb4404388 lib/galaxy/tools/deps/dependencies.py
--- /dev/null
+++ b/lib/galaxy/tools/deps/dependencies.py
@@ -0,0 +1,68 @@
+from galaxy.tools.deps.requirements import ToolRequirement
+from galaxy.util import bunch
+
+
+class DependenciesDescription(object):
+ """ Capture (in a readily serializable way) context related a tool
+ dependencies - both the tool's listed requirements and the tool shed
+ related context required to resolve dependencies via the
+ ToolShedPackageDependencyResolver.
+
+ This is meant to enable remote resolution of dependencies, by the LWR or
+ other potential remote execution mechanisms.
+ """
+
+ def __init__(self, requirements=[], installed_tool_dependencies=[]):
+ self.requirements = requirements
+ # tool shed installed tool dependencies...
+ self.installed_tool_dependencies = installed_tool_dependencies
+
+ def to_dict(self):
+ return dict(
+ requirements=[r.to_dict() for r in self.requirements],
+ installed_tool_dependencies=[DependenciesDescription._toolshed_install_dependency_to_dict(d) for d in self.installed_tool_dependencies]
+ )
+
+ @staticmethod
+ def from_dict(as_dict):
+ if as_dict is None:
+ return None
+
+ requirements_dicts = as_dict.get('requirements', [])
+ requirements = [ToolRequirement.from_dict(r) for r in requirements_dicts]
+ installed_tool_dependencies_dicts = as_dict.get('installed_tool_dependencies', [])
+ installed_tool_dependencies = map(DependenciesDescription._toolshed_install_dependency_from_dict, installed_tool_dependencies_dicts)
+ return DependenciesDescription(
+ requirements=requirements,
+ installed_tool_dependencies=installed_tool_dependencies
+ )
+
+ @staticmethod
+ def _toolshed_install_dependency_from_dict(as_dict):
+ # Rather than requiring full models in LWR, just use simple objects
+ # containing only properties and associations used to resolve
+ # dependencies for tool execution.
+ repository_object = bunch.Bunch(
+ name=as_dict['repository_name'],
+ owner=as_dict['repository_owner'],
+ installed_changeset_revision=as_dict['repository_installed_changeset'],
+ )
+ dependency_object = bunch.Bunch(
+ name=as_dict['dependency_name'],
+ version=as_dict['dependency_version'],
+ type=as_dict['dependency_type'],
+ tool_shed_repository=repository_object,
+ )
+ return dependency_object
+
+ @staticmethod
+ def _toolshed_install_dependency_to_dict(tool_dependency):
+ tool_shed_repository = tool_dependency.tool_shed_repository
+ return dict(
+ dependency_name=tool_dependency.name,
+ dependency_version=tool_dependency.version,
+ dependency_type=tool_dependency.type,
+ repository_name=tool_shed_repository.name,
+ repository_owner=tool_shed_repository.owner,
+ repository_installed_changeset=tool_shed_repository.installed_changeset_revision,
+ )
diff -r 3b29b6f83d17ed07d2c3ea49d839b29d66cad580 -r 48ee04030f893a9a9657b639bb38819fb4404388 test/unit/tools/test_tool_dependency_description.py
--- /dev/null
+++ b/test/unit/tools/test_tool_dependency_description.py
@@ -0,0 +1,44 @@
+from galaxy.model import tool_shed_install
+from galaxy.tools.deps import requirements
+from galaxy.tools.deps import dependencies
+
+
+def test_serialization():
+ repository = tool_shed_install.ToolShedRepository(
+ owner="devteam",
+ name="tophat",
+ installed_changeset_revision="abcdefghijk",
+ )
+ dependency = tool_shed_install.ToolDependency(
+ name="tophat",
+ version="2.0",
+ type="package",
+ status=tool_shed_install.ToolDependency.installation_status.INSTALLED,
+ )
+ dependency.tool_shed_repository = repository
+ tool_requirement = requirements.ToolRequirement(
+ name="tophat",
+ version="2.0",
+ type="package",
+ )
+ descript = dependencies.DependenciesDescription(
+ requirements=[tool_requirement],
+ installed_tool_dependencies=[dependency],
+ )
+ result_descript = dependencies.DependenciesDescription.from_dict(
+ descript.to_dict()
+ )
+ result_requirement = result_descript.requirements[0]
+ assert result_requirement.name == "tophat"
+ assert result_requirement.version == "2.0"
+ assert result_requirement.type == "package"
+
+ result_tool_shed_dependency = result_descript.installed_tool_dependencies[0]
+ result_tool_shed_dependency.name = "tophat"
+ result_tool_shed_dependency.version = "2.0"
+ result_tool_shed_dependency.type = "package"
+ result_tool_shed_repository = result_tool_shed_dependency.tool_shed_repository
+ result_tool_shed_repository.name = "tophat"
+ result_tool_shed_repository.owner = "devteam"
+ result_tool_shed_repository.installed_changeset_revision = "abcdefghijk"
+
https://bitbucket.org/galaxy/galaxy-central/commits/24b5759f33f8/
Changeset: 24b5759f33f8
User: jmchilton
Date: 2014-05-13 07:13:02
Summary: Update LWR client through LWR changeset 9fb7fcb.
Among other smaller fixes, this update causes the LWR client/runner to pass more tool dependency context through to the remote LWR server when `dependency_resolution` is set to `remote`. This additional context allows tool shed packages to be resolved remotely (i.e. allows proper use of ToolShedPackageDependencyResolver on the remote LWR server).
It remains the responsibility of the deployer to ensure identical versions of tool shed packages are installed on the remote LWR server and the local Galaxy instance.
Affected #: 11 files
diff -r 48ee04030f893a9a9657b639bb38819fb4404388 -r 24b5759f33f87879e945a2f14ef5e8abfce488c1 lib/galaxy/jobs/runners/lwr.py
--- a/lib/galaxy/jobs/runners/lwr.py
+++ b/lib/galaxy/jobs/runners/lwr.py
@@ -5,6 +5,7 @@
from galaxy.jobs import ComputeEnvironment
from galaxy.jobs import JobDestination
from galaxy.jobs.command_factory import build_command
+from galaxy.tools.deps import dependencies
from galaxy.util import string_as_bool_or_none
from galaxy.util.bunch import Bunch
@@ -118,9 +119,7 @@
return
try:
- dependency_resolution = LwrJobRunner.__dependency_resolution( client )
- remote_dependency_resolution = dependency_resolution == "remote"
- requirements = job_wrapper.tool.requirements if remote_dependency_resolution else []
+ dependencies_description = LwrJobRunner.__dependencies_description( client, job_wrapper )
rewrite_paths = not LwrJobRunner.__rewrite_parameters( client )
unstructured_path_rewrites = {}
if compute_environment:
@@ -133,7 +132,7 @@
working_directory=job_wrapper.working_directory,
tool=job_wrapper.tool,
config_files=job_wrapper.extra_filenames,
- requirements=requirements,
+ dependencies_description=dependencies_description,
env=client.env,
rewrite_paths=rewrite_paths,
arbitrary_files=unstructured_path_rewrites,
@@ -376,6 +375,19 @@
return client_outputs
@staticmethod
+ def __dependencies_description( lwr_client, job_wrapper ):
+ dependency_resolution = LwrJobRunner.__dependency_resolution( lwr_client )
+ remote_dependency_resolution = dependency_resolution == "remote"
+ if not remote_dependency_resolution:
+ return None
+ requirements = job_wrapper.tool.requirements or []
+ installed_tool_dependencies = job_wrapper.tool.installed_tool_dependencies or []
+ return dependencies.DependenciesDescription(
+ requirements=requirements,
+ installed_tool_dependencies=installed_tool_dependencies,
+ )
+
+ @staticmethod
def __dependency_resolution( lwr_client ):
dependency_resolution = lwr_client.destination_params.get( "dependency_resolution", "local" )
if dependency_resolution not in ["none", "local", "remote"]:
diff -r 48ee04030f893a9a9657b639bb38819fb4404388 -r 24b5759f33f87879e945a2f14ef5e8abfce488c1 lib/galaxy/jobs/runners/lwr_client/__init__.py
--- a/lib/galaxy/jobs/runners/lwr_client/__init__.py
+++ b/lib/galaxy/jobs/runners/lwr_client/__init__.py
@@ -4,6 +4,39 @@
This module contains logic for interfacing with an external LWR server.
+------------------
+Configuring Galaxy
+------------------
+
+Galaxy job runners are configured in Galaxy's ``job_conf.xml`` file. See ``job_conf.xml.sample_advanced``
+in your Galaxy code base or on
+`Bitbucket <https://bitbucket.org/galaxy/galaxy-dist/src/tip/job_conf.xml.sample_advanc…>`_
+for information on how to configure Galaxy to interact with the LWR.
+
+Galaxy also supports an older, less rich configuration of job runners directly
+in its main ``universe_wsgi.ini`` file. The following section describes how to
+configure Galaxy to communicate with the LWR in this legacy mode.
+
+Legacy
+------
+
+A Galaxy tool can be configured to be executed remotely via LWR by
+adding a line to the ``universe_wsgi.ini`` file under the
+``galaxy:tool_runners`` section with the format::
+
+ <tool_id> = lwr://http://<lwr_host>:<lwr_port>
+
+As an example, if a host named remotehost is running the LWR server
+application on port ``8913``, then the tool with id ``test_tool`` can
+be configured to run remotely on remotehost by adding the following
+line to ``universe.ini``::
+
+ test_tool = lwr://http://remotehost:8913
+
+Remember this must be added after the ``[galaxy:tool_runners]`` header
+in the ``universe.ini`` file.
+
+
"""
from .staging.down import finish_job
diff -r 48ee04030f893a9a9657b639bb38819fb4404388 -r 24b5759f33f87879e945a2f14ef5e8abfce488c1 lib/galaxy/jobs/runners/lwr_client/action_mapper.py
--- a/lib/galaxy/jobs/runners/lwr_client/action_mapper.py
+++ b/lib/galaxy/jobs/runners/lwr_client/action_mapper.py
@@ -166,8 +166,8 @@
action_type = mapper.action_type
file_lister = mapper.file_lister
if type in ["workdir", "output_workdir"] and action_type == "none":
- ## We are changing the working_directory relative to what
- ## Galaxy would use, these need to be copied over.
+ # We are changing the working_directory relative to what
+ # Galaxy would use, these need to be copied over.
action_type = "copy"
action_class = actions.get(action_type, None)
if action_class is None:
diff -r 48ee04030f893a9a9657b639bb38819fb4404388 -r 24b5759f33f87879e945a2f14ef5e8abfce488c1 lib/galaxy/jobs/runners/lwr_client/amqp_exchange.py
--- a/lib/galaxy/jobs/runners/lwr_client/amqp_exchange.py
+++ b/lib/galaxy/jobs/runners/lwr_client/amqp_exchange.py
@@ -13,8 +13,8 @@
DEFAULT_EXCHANGE_NAME = "lwr"
DEFAULT_EXCHANGE_TYPE = "direct"
-DEFAULT_TIMEOUT = 0.2 # Set timeout to periodically give up looking and check
- # if polling should end.
+# Set timeout to periodically give up looking and check if polling should end.
+DEFAULT_TIMEOUT = 0.2
class LwrExchange(object):
@@ -48,7 +48,6 @@
queue = self.__queue(queue_name)
with self.connection(self.__url, **connection_kwargs) as connection:
with kombu.Consumer(connection, queues=[queue], callbacks=[callback], accept=['json']):
- log.debug("Consuming queue %s" % queue)
while check:
try:
connection.drain_events(timeout=self.__timeout)
@@ -59,7 +58,6 @@
with self.connection(self.__url) as connection:
with pools.producers[connection].acquire() as producer:
key = self.__queue_name(name)
- log.debug("Publishing with key %s and payload %s" % (key, payload))
producer.publish(
payload,
serializer='json',
diff -r 48ee04030f893a9a9657b639bb38819fb4404388 -r 24b5759f33f87879e945a2f14ef5e8abfce488c1 lib/galaxy/jobs/runners/lwr_client/client.py
--- a/lib/galaxy/jobs/runners/lwr_client/client.py
+++ b/lib/galaxy/jobs/runners/lwr_client/client.py
@@ -39,9 +39,8 @@
)
else:
job_directory = None
- self.env = destination_params.get( "env", [] )
+ self.env = destination_params.get("env", [])
self.files_endpoint = destination_params.get("files_endpoint", None)
- self.env = destination_params.get("env", [])
self.job_directory = job_directory
self.default_file_action = self.destination_params.get("default_file_action", "transfer")
@@ -83,7 +82,7 @@
super(JobClient, self).__init__(destination_params, job_id)
self.job_manager_interface = job_manager_interface
- def launch(self, command_line, requirements=[], env=[], remote_staging=[], job_config=None):
+ def launch(self, command_line, dependencies_description=None, env=[], remote_staging=[], job_config=None):
"""
Queue up the execution of the supplied `command_line` on the remote
server. Called launch for historical reasons, should be renamed to
@@ -98,8 +97,8 @@
submit_params_dict = submit_params(self.destination_params)
if submit_params_dict:
launch_params['params'] = dumps(submit_params_dict)
- if requirements:
- launch_params['requirements'] = dumps([requirement.to_dict() for requirement in requirements])
+ if dependencies_description:
+ launch_params['dependencies_description'] = dumps(dependencies_description.to_dict())
if env:
launch_params['env'] = dumps(env)
if remote_staging:
@@ -248,8 +247,8 @@
return self._raw_execute(self._upload_file_action(args), args, contents, input_path)
def _upload_file_action(self, args):
- ## Hack for backward compatibility, instead of using new upload_file
- ## path. Use old paths.
+ # Hack for backward compatibility, instead of using new upload_file
+ # path. Use old paths.
input_type = args['input_type']
action = {
# For backward compatibility just target upload_input_extra for all
@@ -295,15 +294,15 @@
raise Exception(error_message)
self.client_manager = client_manager
- def launch(self, command_line, requirements=[], env=[], remote_staging=[], job_config=None):
+ def launch(self, command_line, dependencies_description=None, env=[], remote_staging=[], job_config=None):
"""
"""
launch_params = dict(command_line=command_line, job_id=self.job_id)
submit_params_dict = submit_params(self.destination_params)
if submit_params_dict:
launch_params['params'] = submit_params_dict
- if requirements:
- launch_params['requirements'] = [requirement.to_dict() for requirement in requirements]
+ if dependencies_description:
+ launch_params['dependencies_description'] = dependencies_description.to_dict()
if env:
launch_params['env'] = env
if remote_staging:
diff -r 48ee04030f893a9a9657b639bb38819fb4404388 -r 24b5759f33f87879e945a2f14ef5e8abfce488c1 lib/galaxy/jobs/runners/lwr_client/destination.py
--- a/lib/galaxy/jobs/runners/lwr_client/destination.py
+++ b/lib/galaxy/jobs/runners/lwr_client/destination.py
@@ -31,9 +31,9 @@
if not url.endswith("/"):
url += "/"
- ## Check for private token embedded in the URL. A URL of the form
- ## https://moo@cow:8913 will try to contact https://cow:8913
- ## with a private key of moo
+ # Check for private token embedded in the URL. A URL of the form
+ # https://moo@cow:8913 will try to contact https://cow:8913
+ # with a private key of moo
private_token_format = "https?://(.*)@.*/?"
private_token_match = match(private_token_format, url)
private_token = None
diff -r 48ee04030f893a9a9657b639bb38819fb4404388 -r 24b5759f33f87879e945a2f14ef5e8abfce488c1 lib/galaxy/jobs/runners/lwr_client/interface.py
--- a/lib/galaxy/jobs/runners/lwr_client/interface.py
+++ b/lib/galaxy/jobs/runners/lwr_client/interface.py
@@ -67,8 +67,8 @@
self.object_store = object_store
def __app_args(self):
- ## Arguments that would be specified from LwrApp if running
- ## in web server.
+ # Arguments that would be specified from LwrApp if running
+ # in web server.
return {
'manager': self.job_manager,
'file_cache': self.file_cache,
diff -r 48ee04030f893a9a9657b639bb38819fb4404388 -r 24b5759f33f87879e945a2f14ef5e8abfce488c1 lib/galaxy/jobs/runners/lwr_client/staging/__init__.py
--- a/lib/galaxy/jobs/runners/lwr_client/staging/__init__.py
+++ b/lib/galaxy/jobs/runners/lwr_client/staging/__init__.py
@@ -30,8 +30,9 @@
be transferred to remote server).
working_directory : str
Local path created by Galaxy for running this job.
- requirements : list
- List of requirements for tool execution.
+ dependencies_description : list
+ galaxy.tools.deps.dependencies.DependencyDescription object describing
+ tool dependency context for remote depenency resolution.
env: list
List of dict object describing environment variables to populate.
version_file : str
@@ -55,7 +56,7 @@
input_files,
client_outputs,
working_directory,
- requirements,
+ dependencies_description=None,
env=[],
arbitrary_files=None,
rewrite_paths=True,
@@ -66,7 +67,7 @@
self.input_files = input_files
self.client_outputs = client_outputs
self.working_directory = working_directory
- self.requirements = requirements
+ self.dependencies_description = dependencies_description
self.env = env
self.rewrite_paths = rewrite_paths
self.arbitrary_files = arbitrary_files or {}
@@ -79,6 +80,15 @@
def version_file(self):
return self.client_outputs.version_file
+ @property
+ def tool_dependencies(self):
+ if not self.remote_dependency_resolution:
+ return None
+ return dict(
+ requirements=(self.tool.requirements or []),
+ installed_tool_dependencies=(self.tool.installed_tool_dependencies or [])
+ )
+
class ClientOutputs(object):
""" Abstraction describing the output datasets EXPECTED by the Galaxy job
diff -r 48ee04030f893a9a9657b639bb38819fb4404388 -r 24b5759f33f87879e945a2f14ef5e8abfce488c1 lib/galaxy/jobs/runners/lwr_client/staging/up.py
--- a/lib/galaxy/jobs/runners/lwr_client/staging/up.py
+++ b/lib/galaxy/jobs/runners/lwr_client/staging/up.py
@@ -24,7 +24,7 @@
job_id = file_stager.job_id
launch_kwds = dict(
command_line=rebuilt_command_line,
- requirements=client_job_description.requirements,
+ dependencies_description=client_job_description.dependencies_description,
env=client_job_description.env,
)
if file_stager.job_config:
diff -r 48ee04030f893a9a9657b639bb38819fb4404388 -r 24b5759f33f87879e945a2f14ef5e8abfce488c1 lib/galaxy/jobs/runners/lwr_client/transport/__init__.py
--- a/lib/galaxy/jobs/runners/lwr_client/transport/__init__.py
+++ b/lib/galaxy/jobs/runners/lwr_client/transport/__init__.py
@@ -15,8 +15,8 @@
def __get_transport_type(transport_type, os_module):
if not transport_type:
use_curl = os_module.getenv('LWR_CURL_TRANSPORT', "0")
- ## If LWR_CURL_TRANSPORT is unset or set to 0, use default,
- ## else use curl.
+ # If LWR_CURL_TRANSPORT is unset or set to 0, use default,
+ # else use curl.
if use_curl.isdigit() and not int(use_curl):
transport_type = 'urllib'
else:
diff -r 48ee04030f893a9a9657b639bb38819fb4404388 -r 24b5759f33f87879e945a2f14ef5e8abfce488c1 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -2673,12 +2673,18 @@
def build_dependency_shell_commands( self ):
"""Return a list of commands to be run to populate the current environment to include this tools requirements."""
+ return self.app.toolbox.dependency_manager.dependency_shell_commands(
+ self.requirements,
+ installed_tool_dependencies=self.installed_tool_dependencies
+ )
+
+ @property
+ def installed_tool_dependencies(self):
if self.tool_shed_repository:
installed_tool_dependencies = self.tool_shed_repository.tool_dependencies_installed_or_in_error
else:
installed_tool_dependencies = None
- return self.app.toolbox.dependency_manager.dependency_shell_commands( self.requirements,
- installed_tool_dependencies=installed_tool_dependencies )
+ return installed_tool_dependencies
def build_redirect_url_params( self, param_dict ):
"""
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: davebgx: Fix for retrieving job streams with the twill interactor.
by commits-noreply@bitbucket.org 13 May '14
by commits-noreply@bitbucket.org 13 May '14
13 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/3b29b6f83d17/
Changeset: 3b29b6f83d17
User: davebgx
Date: 2014-05-12 22:27:49
Summary: Fix for retrieving job streams with the twill interactor.
Affected #: 1 file
diff -r 246b419fc92a91f31eb7cdd5e2de4a4c15a4b631 -r 3b29b6f83d17ed07d2c3ea49d839b29d66cad580 test/base/interactor.py
--- a/test/base/interactor.py
+++ b/test/base/interactor.py
@@ -386,7 +386,8 @@
self.twill_test_case.verify_dataset_correctness( outfile, hid=hid, attributes=attributes, shed_tool_id=shed_tool_id, maxseconds=maxseconds )
def get_job_stream( self, history_id, output_data, stream ):
- return self.twill_test_case._get_job_stream_output( output_data.get( 'id' ), stream=stream, format=False )
+ encoded_id = self.twill_test_case.security.encode_id( output_data.get( 'id' ) )
+ return self.twill_test_case._get_job_stream_output( encoded_id, stream=stream, format=False )
def stage_data_async( self, test_data, history, shed_tool_id, async=True ):
name = test_data.get( 'name', 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: dan: When working with <conversions> in DataToolParameters, have the parsed conv_types be a list, as is now expected in subsequent usage.
by commits-noreply@bitbucket.org 13 May '14
by commits-noreply@bitbucket.org 13 May '14
13 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/246b419fc92a/
Changeset: 246b419fc92a
User: dan
Date: 2014-05-12 21:27:36
Summary: When working with <conversions> in DataToolParameters, have the parsed conv_types be a list, as is now expected in subsequent usage.
Affected #: 1 file
diff -r 2b7e97a34afa6b33e9950df9213b3cb9be9026a3 -r 246b419fc92a91f31eb7cdd5e2de4a4c15a4b631 lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -1659,7 +1659,7 @@
conv_extensions = conv_elem.get( "type" ) # target datatype extension
# FIXME: conv_extensions should be able to be an ordered list
assert None not in [ name, type ], 'A name (%s) and type (%s) are required for explicit conversion' % ( name, type )
- conv_types = tool.app.datatypes_registry.get_datatype_by_extension( conv_extensions.lower() )
+ conv_types = [ tool.app.datatypes_registry.get_datatype_by_extension( conv_extensions.lower() ) ]
self.conversions.append( ( name, conv_extensions, conv_types ) )
def get_html_field( self, trans=None, value=None, other_values={} ):
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: martenson: important docs for select2 backbone view
by commits-noreply@bitbucket.org 13 May '14
by commits-noreply@bitbucket.org 13 May '14
13 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/2b7e97a34afa/
Changeset: 2b7e97a34afa
User: martenson
Date: 2014-05-12 20:56:06
Summary: important docs for select2 backbone view
Affected #: 2 files
diff -r 8e2135ee278aa44eb5a8da04a392bfa44efc0279 -r 2b7e97a34afa6b33e9950df9213b3cb9be9026a3 static/scripts/mvc/ui/ui-select.js
--- a/static/scripts/mvc/ui/ui-select.js
+++ b/static/scripts/mvc/ui/ui-select.js
@@ -1,7 +1,12 @@
// dependencies
define(['utils/utils'], function(Utils) {
-// plugin
+/**
+ * A plugin for initializing select2 input items.
+ * Make sure the select2 library itself is loaded beforehand.
+ * Also the element to which select2 will be appended has to
+ * be created before select2 initialization (and passed as option).
+ */
var View = Backbone.View.extend(
{
// options
@@ -181,13 +186,13 @@
},
// element
- _template: function(options) {
+ _template: function() {
return '<input type="hidden"/>';
}
});
return {
View : View
-}
+};
});
diff -r 8e2135ee278aa44eb5a8da04a392bfa44efc0279 -r 2b7e97a34afa6b33e9950df9213b3cb9be9026a3 static/scripts/packed/mvc/ui/ui-select.js
--- a/static/scripts/packed/mvc/ui/ui-select.js
+++ b/static/scripts/packed/mvc/ui/ui-select.js
@@ -1,1 +1,1 @@
-define(["utils/utils"],function(a){var b=Backbone.View.extend({optionsDefault:{css:"",placeholder:"No data available",data:[],value:null},initialize:function(d){this.options=a.merge(d,this.optionsDefault);this.setElement(this._template(this.options));if(!this.options.container){console.log("ui-select::initialize() : container not specified.");return}this.options.container.append(this.$el);this.select_data=this.options.data;this._refresh();if(this.options.value){this._setValue(this.options.value)}var c=this;if(this.options.onchange){this.$el.on("change",function(){c.options.onchange(c.value())})}},value:function(c){var d=this._getValue();if(c!==undefined){this._setValue(c)}var e=this._getValue();if((e!=d&&this.options.onchange)){this.options.onchange(e)}return e},text:function(){return this.$el.select2("data").text},disabled:function(){return !this.$el.select2("enable")},enable:function(){this.$el.select2("enable",true)},disable:function(){this.$el.select2("enable",false)},add:function(c){this.select_data.push({id:c.id,text:c.text});this._refresh()},del:function(d){var c=this._getIndex(d);if(c!=-1){this.select_data.splice(c,1);this._refresh()}},remove:function(){this.$el.select2("destroy")},update:function(c){this.select_data=[];for(var d in c.data){this.select_data.push(c.data[d])}this._refresh()},_refresh:function(){var c=this._getValue();this.$el.select2({data:this.select_data,containerCssClass:this.options.css,placeholder:this.options.placeholder});this._setValue(c)},_getIndex:function(d){for(var c in this.select_data){if(this.select_data[c].id==d){return c}}return -1},_getValue:function(){return this.$el.select2("val")},_setValue:function(d){var c=this._getIndex(d);if(c==-1){if(this.select_data.length>0){d=this.select_data[0].id}}this.$el.select2("val",d)},_template:function(c){return'<input type="hidden"/>'}});return{View:b}});
\ No newline at end of file
+define(["utils/utils"],function(a){var b=Backbone.View.extend({optionsDefault:{css:"",placeholder:"No data available",data:[],value:null},initialize:function(d){this.options=a.merge(d,this.optionsDefault);this.setElement(this._template(this.options));if(!this.options.container){console.log("ui-select::initialize() : container not specified.");return}this.options.container.append(this.$el);this.select_data=this.options.data;this._refresh();if(this.options.value){this._setValue(this.options.value)}var c=this;if(this.options.onchange){this.$el.on("change",function(){c.options.onchange(c.value())})}},value:function(c){var d=this._getValue();if(c!==undefined){this._setValue(c)}var e=this._getValue();if((e!=d&&this.options.onchange)){this.options.onchange(e)}return e},text:function(){return this.$el.select2("data").text},disabled:function(){return !this.$el.select2("enable")},enable:function(){this.$el.select2("enable",true)},disable:function(){this.$el.select2("enable",false)},add:function(c){this.select_data.push({id:c.id,text:c.text});this._refresh()},del:function(d){var c=this._getIndex(d);if(c!=-1){this.select_data.splice(c,1);this._refresh()}},remove:function(){this.$el.select2("destroy")},update:function(c){this.select_data=[];for(var d in c.data){this.select_data.push(c.data[d])}this._refresh()},_refresh:function(){var c=this._getValue();this.$el.select2({data:this.select_data,containerCssClass:this.options.css,placeholder:this.options.placeholder});this._setValue(c)},_getIndex:function(d){for(var c in this.select_data){if(this.select_data[c].id==d){return c}}return -1},_getValue:function(){return this.$el.select2("val")},_setValue:function(d){var c=this._getIndex(d);if(c==-1){if(this.select_data.length>0){d=this.select_data[0].id}}this.$el.select2("val",d)},_template:function(){return'<input type="hidden"/>'}});return{View:b}});
\ 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: greg: Fix typo in the Tool Shed's package recipe install step handler - thanks Bjoren Gruning.
by commits-noreply@bitbucket.org 12 May '14
by commits-noreply@bitbucket.org 12 May '14
12 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/8e2135ee278a/
Changeset: 8e2135ee278a
User: greg
Date: 2014-05-12 18:47:57
Summary: Fix typo in the Tool Shed's package recipe install step handler - thanks Bjoren Gruning.
Affected #: 1 file
diff -r 7950ab309ad1cb06cf3af973adcca1e3209c9241 -r 8e2135ee278aa44eb5a8da04a392bfa44efc0279 lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
@@ -1337,7 +1337,7 @@
"""
env_vars = dict()
env_vars = install_environment.environment_dict()
- tool_shed_repository = tool_depenedncy.tool_shed_repository
+ tool_shed_repository = tool_dependency.tool_shed_repository
env_vars.update( td_common_util.get_env_var_values( install_environment ) )
language = action_dict[ 'language' ]
with settings( warn_only=True, **env_vars ):
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: Small improvements to collection creation API.
by commits-noreply@bitbucket.org 12 May '14
by commits-noreply@bitbucket.org 12 May '14
12 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/7950ab309ad1/
Changeset: 7950ab309ad1
User: jmchilton
Date: 2014-05-12 16:54:02
Summary: Small improvements to collection creation API.
Return full collection when creating collection and improved error handling during creation.
Affected #: 2 files
diff -r 4af4aad0ce3a47407298e05bab4729091361ac47 -r 7950ab309ad1cb06cf3af973adcca1e3209c9241 lib/galaxy/dataset_collections/__init__.py
--- a/lib/galaxy/dataset_collections/__init__.py
+++ b/lib/galaxy/dataset_collections/__init__.py
@@ -202,6 +202,10 @@
def __load_elements( self, trans, element_identifiers ):
elements = odict.odict()
for element_identifier in element_identifiers:
+ if "name" not in element_identifier:
+ raise RequestParameterInvalidException(
+ "Cannot load invalid dataset identifier - missing name - %s" % element_identifier
+ )
elements[ element_identifier[ "name" ] ] = self.__load_element( trans, element_identifier )
return elements
diff -r 4af4aad0ce3a47407298e05bab4729091361ac47 -r 7950ab309ad1cb06cf3af973adcca1e3209c9241 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
@@ -295,7 +295,7 @@
create_params = api_payload_to_create_params( payload )
service = trans.app.dataset_collections_service
dataset_collection_instance = service.create( trans, parent=history, **create_params )
- return self.__collection_dict( trans, dataset_collection_instance )
+ return self.__collection_dict( trans, dataset_collection_instance, view="element" )
@expose_api_anonymous
def update( self, trans, history_id, id, payload, **kwd ):
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/2d08e99be908/
Changeset: 2d08e99be908
User: jmchilton
Date: 2014-05-11 20:56:49
Summary: Allow more typical expanded HDCA value with src when mapping over collection via API.
Flat ID still used by GUI - but when coming through API this is probably the better choice.
Affected #: 2 files
diff -r a74fd6395843cb384928ad367fd6f5f6d5eff65c -r 2d08e99be908216de8897b1c545896fedaa84379 lib/galaxy/tools/parameters/meta.py
--- a/lib/galaxy/tools/parameters/meta.py
+++ b/lib/galaxy/tools/parameters/meta.py
@@ -40,7 +40,13 @@
if "|" in incoming_val:
encoded_hdc_id, subcollection_type = incoming_val.split( "|", 1 )
else:
- encoded_hdc_id = incoming_val
+ try:
+ src = incoming_val[ "src" ]
+ if src != "hdca":
+ raise exceptions.ToolMetaParameterException( "Invalid dataset collection source type %s" % src )
+ encoded_hdc_id = incoming_val[ "id" ]
+ except TypeError:
+ encoded_hdc_id = incoming_val
subcollection_type = None
hdc_id = trans.app.security.decode_id( encoded_hdc_id )
hdc = trans.sa_session.query( model.HistoryDatasetCollectionAssociation ).get( hdc_id )
diff -r a74fd6395843cb384928ad367fd6f5f6d5eff65c -r 2d08e99be908216de8897b1c545896fedaa84379 test/api/test_tools.py
--- a/test/api/test_tools.py
+++ b/test/api/test_tools.py
@@ -159,6 +159,9 @@
history_id = self.dataset_populator.new_history()
hdca_id = self.__build_pair( history_id, [ "123", "456" ] )
inputs = {
+ # Such inputs can be simple hdca ids (for GUI) or
+ # {src: "hdca", id: <hdca_id>} for API. This tests the
+ # first, next test method tests other.
"input1|__collection_multirun__": hdca_id,
}
create = self._run_cat1( history_id, inputs=inputs, assert_ok=True )
@@ -181,7 +184,7 @@
history_id = self.dataset_populator.new_history()
hdca_id = self.__build_nested_list( history_id )
inputs = {
- "input1|__collection_multirun__": hdca_id,
+ "input1|__collection_multirun__": dict( src="hdca", id=hdca_id ),
}
create = self._run_cat1( history_id, inputs=inputs, assert_ok=True )
outputs = create[ 'outputs' ]
https://bitbucket.org/galaxy/galaxy-central/commits/4af4aad0ce3a/
Changeset: 4af4aad0ce3a
User: jmchilton
Date: 2014-05-11 20:56:49
Summary: Add API functional test for workflow extraction of collection reductions.
Affected #: 1 file
diff -r 2d08e99be908216de8897b1c545896fedaa84379 -r 4af4aad0ce3a47407298e05bab4729091361ac47 test/api/test_workflows.py
--- a/test/api/test_workflows.py
+++ b/test/api/test_workflows.py
@@ -142,38 +142,22 @@
"input|__collection_multirun__": hdca_id,
"num_lines": 2
}
- run_output1 = self.dataset_populator.run_tool(
- tool_id="random_lines1",
- inputs=inputs1,
- history_id=history_id,
- )
- implicit_hdca1 = run_output1[ "implicit_collections" ][ 0 ]
- job_id1 = run_output1[ "jobs" ][ 0 ][ "id" ]
- self.dataset_populator.wait_for_history( history_id, assert_ok=True, timeout=20 )
+ implicit_hdca1, job_id1 = self._run_tool_get_collection_and_job_id( history_id, "random_lines1", inputs1 )
inputs2 = {
"input|__collection_multirun__": implicit_hdca1[ "id" ],
"num_lines": 1
}
- run_output2 = self.dataset_populator.run_tool(
- tool_id="random_lines1",
- inputs=inputs2,
- history_id=history_id,
- )
- # implicit_hdca2 = run_output2[ "implicit_collections" ][ 0 ]
- job_id2 = run_output2[ "jobs" ][ 0 ][ "id" ]
- self.dataset_populator.wait_for_history( history_id, assert_ok=True, timeout=20 )
+ _, job_id2 = self._run_tool_get_collection_and_job_id( history_id, "random_lines1", inputs2 )
downloaded_workflow = self._extract_and_download_workflow(
from_history_id=history_id,
dataset_collection_ids=dumps( [ hdca[ "hid" ] ] ),
job_ids=dumps( [ job_id1, job_id2 ] ),
workflow_name="test import from mapping history",
)
+ # Assert workflow is input connected to a tool step with one output
+ # connected to another tool step.
assert len( downloaded_workflow[ "steps" ] ) == 3
- collection_steps = self._get_steps_of_type( downloaded_workflow, "data_collection_input", expected_len=1 )
- collection_step = collection_steps[ 0 ]
- collection_step_state = loads( collection_step[ "tool_state" ] )
- self.assertEquals( collection_step_state[ "collection_type" ], u"paired" )
- collect_step_idx = collection_step[ "id" ]
+ collect_step_idx = self._assert_first_step_is_paired_input( downloaded_workflow )
tool_steps = self._get_steps_of_type( downloaded_workflow, "tool", expected_len=2 )
tool_step_idxs = []
tool_input_step_idxs = []
@@ -187,6 +171,63 @@
assert tool_input_step_idxs[ 0 ] == collect_step_idx
assert tool_input_step_idxs[ 1 ] == tool_step_idxs[ 0 ]
+ @skip_without_tool( "random_lines1" )
+ @skip_without_tool( "multi_data_param" )
+ def test_extract_reduction_from_history( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca = self.dataset_collection_populator.create_pair_in_history( history_id, contents=["1 2 3\n4 5 6", "7 8 9\n10 11 10"] ).json()
+ hdca_id = hdca[ "id" ]
+ inputs1 = {
+ "input|__collection_multirun__": hdca_id,
+ "num_lines": 2
+ }
+ implicit_hdca1, job_id1 = self._run_tool_get_collection_and_job_id( history_id, "random_lines1", inputs1 )
+ inputs2 = {
+ "f1": "__collection_reduce__|%s" % ( implicit_hdca1[ "id" ] ),
+ "f2": "__collection_reduce__|%s" % ( implicit_hdca1[ "id" ] )
+ }
+ reduction_run_output = self.dataset_populator.run_tool(
+ tool_id="multi_data_param",
+ inputs=inputs2,
+ history_id=history_id,
+ )
+ job_id2 = reduction_run_output[ "jobs" ][ 0 ][ "id" ]
+ self.dataset_populator.wait_for_history( history_id, assert_ok=True, timeout=20 )
+ downloaded_workflow = self._extract_and_download_workflow(
+ from_history_id=history_id,
+ dataset_collection_ids=dumps( [ hdca[ "hid" ] ] ),
+ job_ids=dumps( [ job_id1, job_id2 ] ),
+ workflow_name="test import reduction",
+ )
+ assert len( downloaded_workflow[ "steps" ] ) == 3
+ collect_step_idx = self._assert_first_step_is_paired_input( downloaded_workflow )
+ tool_steps = self._get_steps_of_type( downloaded_workflow, "tool", expected_len=2 )
+ random_lines_map_step = tool_steps[ 0 ]
+ reduction_step = tool_steps[ 1 ]
+ random_lines_input = random_lines_map_step[ "input_connections" ][ "input" ]
+ assert random_lines_input[ "id" ] == collect_step_idx
+ reduction_step_input = reduction_step[ "input_connections" ][ "f1" ]
+ assert reduction_step_input[ "id"] == random_lines_map_step[ "id" ]
+
+ def _run_tool_get_collection_and_job_id( self, history_id, tool_id, inputs ):
+ run_output1 = self.dataset_populator.run_tool(
+ tool_id=tool_id,
+ inputs=inputs,
+ history_id=history_id,
+ )
+ implicit_hdca = run_output1[ "implicit_collections" ][ 0 ]
+ job_id = run_output1[ "jobs" ][ 0 ][ "id" ]
+ self.dataset_populator.wait_for_history( history_id, assert_ok=True, timeout=20 )
+ return implicit_hdca, job_id
+
+ def _assert_first_step_is_paired_input( self, downloaded_workflow ):
+ collection_steps = self._get_steps_of_type( downloaded_workflow, "data_collection_input", expected_len=1 )
+ collection_step = collection_steps[ 0 ]
+ collection_step_state = loads( collection_step[ "tool_state" ] )
+ self.assertEquals( collection_step_state[ "collection_type" ], u"paired" )
+ collect_step_idx = collection_step[ "id" ]
+ return collect_step_idx
+
def _extract_and_download_workflow( self, **extract_payload ):
create_workflow_response = self._post( "workflows", data=extract_payload )
self._assert_status_code_is( create_workflow_response, 200 )
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: Jeremy Goecks: Add example configuration for CLI Slurm runner.
by commits-noreply@bitbucket.org 10 May '14
by commits-noreply@bitbucket.org 10 May '14
10 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/a74fd6395843/
Changeset: a74fd6395843
User: Jeremy Goecks
Date: 2014-05-09 22:20:33
Summary: Add example configuration for CLI Slurm runner.
Affected #: 1 file
diff -r ae7da2ebe7737d6e6ba142d1ac24a24b467285ad -r a74fd6395843cb384928ad367fd6f5f6d5eff65c job_conf.xml.sample_advanced
--- a/job_conf.xml.sample_advanced
+++ b/job_conf.xml.sample_advanced
@@ -164,6 +164,18 @@
<param id="shell_hostname">foo.example.org</param><param id="job_Resource_List">walltime=24:00:00,ncpus=4</param></destination>
+
+ <!-- Example CLI Slurm runner. -->
+ <destination id="ssh_slurm" runner="cli">
+ <param id="shell_plugin">SecureShell</param>
+ <param id="job_plugin">Slurm</param>
+ <param id="shell_username">foo</param>
+ <param id="shell_hostname">my_host</param>
+ <param id="job_time">2:00:00</param>
+ <param id="job_ncpus">4</param>
+ <param id="job_partition">my_partition</param>
+ </destination>
+
<destination id="condor" runner="condor"><!-- With no params, jobs are submitted to the 'vanilla' universe with:
notification = NEVER
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: Jeremy Goecks: Add a CLI-driven Slurm runner so that Galaxy can be run on non-submit hosts with a Slurm cluster. Add some flexibility for obtaining the external job ID in the CLI runner as well.
by commits-noreply@bitbucket.org 10 May '14
by commits-noreply@bitbucket.org 10 May '14
10 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/ae7da2ebe773/
Changeset: ae7da2ebe773
User: Jeremy Goecks
Date: 2014-05-09 22:15:27
Summary: Add a CLI-driven Slurm runner so that Galaxy can be run on non-submit hosts with a Slurm cluster. Add some flexibility for obtaining the external job ID in the CLI runner as well.
Affected #: 2 files
diff -r 3210eaa1db6cb6af4e5c4846c1fec39585405cd9 -r ae7da2ebe7737d6e6ba142d1ac24a24b467285ad lib/galaxy/jobs/runners/cli.py
--- a/lib/galaxy/jobs/runners/cli.py
+++ b/lib/galaxy/jobs/runners/cli.py
@@ -99,7 +99,9 @@
log.error('(%s) submission failed (stderr): %s' % (galaxy_id_tag, cmd_out.stderr))
job_wrapper.fail("failure submitting job")
return
- external_job_id = cmd_out.stdout.strip()
+ # Some job runners return something like 'Submitted batch job XXXX'
+ # Strip and split to get job ID.
+ external_job_id = cmd_out.stdout.strip().split()[-1]
if not external_job_id:
log.error('(%s) submission did not return a job identifier, failing job' % galaxy_id_tag)
job_wrapper.fail("failure submitting job")
diff -r 3210eaa1db6cb6af4e5c4846c1fec39585405cd9 -r ae7da2ebe7737d6e6ba142d1ac24a24b467285ad lib/galaxy/jobs/runners/util/cli/job/slurm.py
--- /dev/null
+++ b/lib/galaxy/jobs/runners/util/cli/job/slurm.py
@@ -0,0 +1,94 @@
+# A simple CLI runner for slurm that can be used when running Galaxy from a
+# non-submit host and using a Slurm cluster.
+
+try:
+ from galaxy.model import Job
+ job_states = Job.states
+except ImportError:
+ # Not in Galaxy, map Galaxy job states to LWR ones.
+ from galaxy.util import enum
+ job_states = enum(RUNNING='running', OK='complete', QUEUED='queued')
+
+from ..job import BaseJobExec
+
+__all__ = ('Slurm',)
+
+from logging import getLogger
+log = getLogger(__name__)
+
+argmap = {
+ 'time': '-t',
+ 'ncpus': '-c',
+ 'partition': '-p'
+}
+
+class Slurm(BaseJobExec):
+
+ def __init__(self, **params):
+ self.params = {}
+ for k, v in params.items():
+ self.params[k] = v
+
+ def job_script_kwargs(self, ofile, efile, job_name):
+ scriptargs = {'-o': ofile,
+ '-e': efile,
+ '-J': job_name}
+
+ # Map arguments using argmap.
+ for k, v in self.params.items():
+ if k == 'plugin':
+ continue
+ try:
+ if not k.startswith('-'):
+ k = argmap[k]
+ scriptargs[k] = v
+ except:
+ log.warning('Unrecognized long argument passed to Slurm CLI plugin: %s' % k)
+
+ # Generated template.
+ template_scriptargs = ''
+ for k, v in scriptargs.items():
+ template_scriptargs += '#SBATCH %s %s\n' % (k, v)
+ return dict(headers=template_scriptargs)
+
+ def submit(self, script_file):
+ return 'sbatch %s' % script_file
+
+ def delete(self, job_id):
+ return 'scancel %s' % job_id
+
+ def get_status(self, job_ids=None):
+ return 'squeue -a -o \\"%A %t\\"'
+
+ def get_single_status(self, job_id):
+ return 'squeue -a -o \\"%A %t\\" -j ' + job_id
+
+ def parse_status(self, status, job_ids):
+ # Get status for each job, skipping header.
+ rval = {}
+ for line in status.splitlines()[ 1: ]:
+ id, state = line.split()
+ if id in job_ids:
+ # map job states to Galaxy job states.
+ rval[id] = self._get_job_state(state)
+ return rval
+
+ def parse_single_status(self, status, job_id):
+ status = status.splitlines()
+ if len( status ) > 1:
+ # Job still on cluster and has state.
+ id, state = status[1].split()
+ return self._get_job_state(state)
+ return job_states.OK
+
+ def _get_job_state(self, state):
+ try:
+ return {
+ 'F': job_states.ERROR,
+ 'R': job_states.RUNNING,
+ 'CG': job_states.RUNNING,
+ 'PD': job_states.QUEUED,
+ 'CD': job_states.OK
+ }.get(state)
+ except KeyError:
+ raise KeyError("Failed to map slurm status code [%s] to job state." % state)
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: davebgx: Fix functional test dataset error reporting.
by commits-noreply@bitbucket.org 09 May '14
by commits-noreply@bitbucket.org 09 May '14
09 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/3210eaa1db6c/
Changeset: 3210eaa1db6c
User: davebgx
Date: 2014-05-09 18:35:23
Summary: Fix functional test dataset error reporting.
Affected #: 1 file
diff -r c0af07ce3b0beb686cee26428dfcc229ebe34334 -r 3210eaa1db6cb6af4e5c4846c1fec39585405cd9 test/base/twilltestcase.py
--- a/test/base/twilltestcase.py
+++ b/test/base/twilltestcase.py
@@ -2244,7 +2244,6 @@
if wait:
self.wait( maxseconds=maxseconds ) # wait for job to finish
data_list = self.get_history_from_api( encoded_history_id=None, show_deleted=False, show_details=False )
- log.debug( data_list )
self.assertTrue( data_list )
if hid is None: # take last hid
dataset = data_list[-1]
@@ -2254,6 +2253,7 @@
self.assertTrue( len( datasets ) == 1 )
dataset = datasets[0]
self.assertTrue( hid )
+ dataset = self.json_from_url( dataset[ 'url' ] )
self._assert_dataset_state( dataset, 'ok' )
if filename is not None and self.is_zipped( filename ):
errmsg = 'History item %s is a zip archive which includes invalid files:\n' % hid
@@ -2466,10 +2466,11 @@
f.close()
return fname
- def _assert_dataset_state( self, elem, state ):
- if elem.get( 'state' ) != state:
- errmsg = "Expecting dataset state '%s', but state is '%s'. Dataset blurb: %s\n\n" % ( state, elem.get('state'), elem.text.strip() )
- errmsg += self.get_job_stderr( elem.get( 'id' ), format=True )
+ def _assert_dataset_state( self, dataset, state ):
+ if dataset.get( 'state' ) != state:
+ blurb = dataset.get( 'misc_blurb' )
+ errmsg = "Expecting dataset state '%s', but state is '%s'. Dataset blurb: %s\n\n" % ( state, dataset.get('state'), blurb.strip() )
+ errmsg += self.get_job_stderr( dataset.get( 'id' ), format=True )
raise AssertionError( errmsg )
def _bam_to_sam( self, local_name, temp_name ):
@@ -2504,7 +2505,6 @@
page_url = "/display?encoded_id=%s" % hda_id
else:
page_url = "/datasets/%s/display/%s" % ( hda_id, filename )
- log.debug( page_url )
self.visit_url( page_url )
data = self.last_page()
return data
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: davebgx: Clean up twilltestcase.py, fix functional tests for tools with spaces in the tool ID.
by commits-noreply@bitbucket.org 09 May '14
by commits-noreply@bitbucket.org 09 May '14
09 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/c0af07ce3b0b/
Changeset: c0af07ce3b0b
User: davebgx
Date: 2014-05-09 15:57:26
Summary: Clean up twilltestcase.py, fix functional tests for tools with spaces in the tool ID.
Affected #: 3 files
diff -r f6bf49aca8da9707937ebaebbfa869d10735dc81 -r c0af07ce3b0beb686cee26428dfcc229ebe34334 test/base/interactor.py
--- a/test/base/interactor.py
+++ b/test/base/interactor.py
@@ -474,8 +474,8 @@
.order_by( desc( galaxy.model.History.table.c.create_time ) ) \
.first()
assert latest_history is not None, "Problem retrieving latest_history from database"
- if len( self.twill_test_case.get_history_as_data_list() ) > 0:
- raise AssertionError("ToolTestCase.do_it failed")
+ if len( self.twill_test_case.get_hids_in_history( self.twill_test_case.get_latest_history()[ 'id' ] ) ) > 0:
+ raise AssertionError("ToolTestCase.do_it failed to create a new empty history")
return latest_history
def delete_history( self, latest_history ):
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
09 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/f6bf49aca8da/
Changeset: f6bf49aca8da
User: guerler
Date: 2014-05-09 13:58:26
Summary: Charts: Pack scripts
Affected #: 3 files
diff -r 7c9b64b44298ceef9d5d9935ce5cd3736f9b36f6 -r f6bf49aca8da9707937ebaebbfa869d10735dc81 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:"charts",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' tool. 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:{},cache:{},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._get(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)}})}},_block_id:function(e,t){return e.id+"_"+e.start+"_"+e.end+"_"+t},_get:function(e,t){e.start||(e.start=0),e.end||(e.end=this.app.config.get("query_limit"));var n=[],r={},i=0;for(var s in e.groups){var o=e.groups[s];for(var u in o.columns){var a=o.columns[u].index,f=this._block_id(e,a);if(this.cache[f])continue;!r[a]&&a!==undefined&&(r[a]=i,n.push(a),i++)}}if(n.length==0){this._fill_from_cache(e),t(e);return}var l={dataset_id:e.id,start:e.start,end:e.end,columns:n},c=this;this._fetch(l,function(r){for(var i in r){var s=n[i],o=c._block_id(e,s);c.cache[o]=r[i]}c._fill_from_cache(e),t(e)})},_fill_from_cache:function(e){console.debug("Datasets::_fill_from_cache() - Filling request from cache.");for(var t in e.groups){var n=e.groups[t];n.values=[];for(var r in n.columns){var i=n.columns[r],s=this._block_id(e,i.index),o=this.cache[s];for(k in o){var u=n.values[k];u===undefined&&(u={x:parseInt(k)+e.start},n.values[k]=u);var a=o[k];isNaN(a)&&!i.is_label&&(a=0),u[r]=a}}}},_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=0;t.columns&&(o=t.columns.length,console.debug("Datasets::_fetch() - Fetching "+o+" column(s)")),o==0&&console.debug("Datasets::_fetch() - No columns requested");var u="";for(var a in t.columns)u+=t.columns[a]+",";u=u.substring(0,u.length-1);var f=this;e.request("GET",config.root+"api/datasets/"+t.dataset_id,{data_type:"raw_data",provider:"dataset-column",limit:i,offset:r,indeces:u},function(e){var t=new Array(o);for(var r=0;r<o;r++)t[r]=[];for(var r in e.data){var i=e.data[r];for(var s in i){var u=i[s];u!==undefined&&u!=2147483647&&t[s].push(u)}}console.debug("Datasets::_fetch() - Fetching complete."),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){this.process[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({canvas:[],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,t){t=t||1;for(var n in this.canvas)this.canvas[n].remove(),this.canvas.slice(n,0);for(var n=0;n<t;n++){var r=$(this._template_canvas(e,parseInt(100/t)));this.$el.append(r),e=="svg"?this.canvas[n]=d3.select(r[0]):this.canvas[n]=r}},_draw:function(e){var t=this,n=e.deferred.register(),r=e.get("type");this.chart_settings=this.app.types.get(r);var i=this.chart_settings.use_panels,s=1;i&&(s=e.groups.length),this._create_canvas(this.chart_settings.tag,s),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){var o=r.chart_settings.columns[s];i[s]={index:e.get(s),is_label:o.is_label}}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,t){return"<"+e+' class="canvas" style="float: left; display: block; width:'+t+'%; 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({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){for(var t in s){var n=i.columns[t].is_label,o=[],u=e.metadata_column_types;for(var a in u)(!n&&(u[a]=="int"||u[a]=="float")||n)&&o.push({label:"Column: "+(parseInt(a)+1)+" ["+u[a]+"]",value:a});s[t].update(o),s[t].show()}r.chart.state("ok","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",tag:"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"},y_axis_type:{init:"f"},y_axis_tick:{init:".2"}}})}),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",[],function(){return{title:"Pie chart",library:"nvd3.js",tag:"svg",use_panels:!0,columns:{label:{title:"Labels",is_label:!0},y:{title:"Values"}},settings:{show_legend:{title:"Show legend",info:"Would you like to add a legend?",type:"select",init:"false",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]},donut_ratio:{title:"Donut ratio",info:"Determine how large the donut hole will be.",type:"select",init:"0.5",data:[{label:"50%",value:"0.5"},{label:"25%",value:"0.25"},{label:"10%",value:"0.10"},{label:"0%",value:"0"}]},label_separator:{type:"separator",title:"Label settings"},label_type:{title:"Donut label",info:"What would you like to show for each slice?",type:"select",init:"percent",data:[{label:"-- Nothing --",value:"hide",hide:"label_outside"},{label:"Label column",value:"key",show:"label_outside"},{label:"Value column",value:"value",show:"label_outside"},{label:"Percentage",value:"percent",show:"label_outside"}]},label_outside:{title:"Show outside",info:"Would you like to show labels outside the donut?",type:"select",init:"false",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]}}}}),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
+define("mvc/ui/ui-modal",[],function(){var e=Backbone.View.extend({elMain:"body",optionsDefault:{title:"ui-modal",body:"",backdrop:!0,height:null,width:null,closing_events:!1,closing_callback:null},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"),this.options.closing_callback&&this.options.closing_callback()},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:e}}),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-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)},request:function(e,t,n,r,i){var s=this;e.state("wait","Requesting job results...");var o=e.get("dataset_id_job");o!=""?s._wait(e,r,i):s._submit(e,t,n,r,i)},cleanup:function(t){var n=this,r=t.get("dataset_id_job");r!=""&&(e.request("PUT",config.root+"api/histories/none/contents/"+r,{deleted:!0},function(){n._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:"charts",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","Your job has been queued. You may close the browser window. The job will run in the background."),t.set("dataset_id_job",n.id),this.app.storage.save(),o._wait(t,i,s)}},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' tool. Please make sure it is installed. "+n),s&&s()})},_wait:function(t,n,r){var i=this;e.request("GET",config.root+"api/datasets/"+t.get("dataset_id_job"),{},function(e){var s=!1;switch(e.state){case"ok":t.state("wait","Job completed successfully..."),n&&n(e),s=!0;break;case"error":t.state("failed","Job has failed. Please check the history for details."),r&&r(e),s=!0;break;case"running":t.state("wait","Your job is running. You may close the browser window. The job will continue in the background.")}s||setTimeout(function(){i._wait(t,n,r)},i.app.config.get("query_timeout"))})},_refreshHdas:function(){Galaxy&&Galaxy.currHistoryPanel&&Galaxy.currHistoryPanel.refreshContents()}})}),define("plugin/library/datasets",["utils/utils"],function(e){return Backbone.Collection.extend({list:{},cache:{},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._get(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)}})}},_block_id:function(e,t){return e.id+"_"+e.start+"_"+e.end+"_"+t},_get:function(e,t){e.start||(e.start=0),e.end||(e.end=this.app.config.get("query_limit"));var n=[],r={},i=0;for(var s in e.groups){var o=e.groups[s];for(var u in o.columns){var a=o.columns[u].index,f=this._block_id(e,a);if(this.cache[f])continue;!r[a]&&a!==undefined&&(r[a]=i,n.push(a),i++)}}if(n.length==0){this._fill_from_cache(e),t(e);return}var l={dataset_id:e.id,start:e.start,end:e.end,columns:n},c=this;this._fetch(l,function(r){for(var i in r){var s=n[i],o=c._block_id(e,s);c.cache[o]=r[i]}c._fill_from_cache(e),t(e)})},_fill_from_cache:function(e){console.debug("Datasets::_fill_from_cache() - Filling request from cache.");for(var t in e.groups){var n=e.groups[t];n.values=[];for(var r in n.columns){var i=n.columns[r],s=this._block_id(e,i.index),o=this.cache[s];for(k in o){var u=n.values[k];u===undefined&&(u={x:parseInt(k)+e.start},n.values[k]=u);var a=o[k];isNaN(a)&&!i.is_label&&(a=0),u[r]=a}}}},_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=0;t.columns&&(o=t.columns.length,console.debug("Datasets::_fetch() - Fetching "+o+" column(s)")),o==0&&console.debug("Datasets::_fetch() - No columns requested");var u="";for(var a in t.columns)u+=t.columns[a]+",";u=u.substring(0,u.length-1);var f=this;e.request("GET",config.root+"api/datasets/"+t.dataset_id,{data_type:"raw_data",provider:"dataset-column",limit:i,offset:r,indeces:u},function(e){var t=new Array(o);for(var r=0;r<o;r++)t[r]=[];for(var r in e.data){var i=e.data[r];for(var s in i){var u=i[s];u!==undefined&&u!=2147483647&&t[s].push(u)}}console.debug("Datasets::_fetch() - Fetching complete."),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){this.process[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({container_list:[],canvas_list:[],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._createContainer("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=r.$el.find("container"),n=e.find("#icon");n.removeClass(),e.show(),e.find("#text").html(r.chart.get("state_info")),t.hide();var i=r.chart.get("state");switch(i){case"ok":e.hide(),t.show();break;case"failed":n.addClass("fa fa-warning");break;default:n.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)})},_createContainer:function(e,t){t=t||1;for(var n in this.container_list)this.container_list[n].remove();this.container_list=[],this.canvas_list=[];for(var n=0;n<t;n++){var r=$(this._templateContainer(e,parseInt(100/t)));this.$el.append(r),this.container_list[n]=r,e=="svg"?this.canvas_list[n]=d3.select(r.find("#canvas")[0]):this.canvas_list[n]=r.find("#canvas")}},_draw:function(e){var t=this,n=e.deferred.register(),r=e.get("type");this.chart_settings=this.app.types.get(r);var i=this.chart_settings.use_panels,s=1;i&&(s=e.groups.length),this._createContainer(this.chart_settings.tag,s),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_list});t.chart_settings.execute?t.app.jobs.request(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))})},_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){var o=r.chart_settings.columns[s];i[s]={index:e.get(s),is_label:o.is_label}}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>'},_templateContainer:function(e,t){return'<div class="container" style="float: left; display: block; width:'+t+'%; height: 100%;">'+'<div id="menu"/>'+"<"+e+' id="canvas" class="canvas" style="display: block; width:100%; height: inherit;">'+"</div>"}})}),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({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){for(var t in s){var n=i.columns[t].is_label,o=[],u=e.metadata_column_types;for(var a in u)(!n&&(u[a]=="int"||u[a]=="float")||n)&&o.push({label:"Column: "+(parseInt(a)+1)+" ["+u[a]+"]",value:a});s[t].update(o),s[t].show()}r.chart.state("ok","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("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),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 charts tool 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:5e3,query_timeout:500}})}),define("plugin/charts/nvd3/config",[],function(){return{title:"",library:"nvd3.js",tag:"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"},y_axis_type:{init:"f"},y_axis_tick:{init:".2"}}})}),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",[],function(){return{title:"Pie chart",library:"nvd3.js",tag:"svg",use_panels:!0,columns:{label:{title:"Labels",is_label:!0},y:{title:"Values"}},settings:{show_legend:{title:"Show legend",info:"Would you like to add a legend?",type:"select",init:"false",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]},donut_ratio:{title:"Donut ratio",info:"Determine how large the donut hole will be.",type:"select",init:"0.5",data:[{label:"50%",value:"0.5"},{label:"25%",value:"0.25"},{label:"10%",value:"0.10"},{label:"0%",value:"0"}]},label_separator:{type:"separator",title:"Label settings"},label_type:{title:"Donut label",info:"What would you like to show for each slice?",type:"select",init:"percent",data:[{label:"-- Nothing --",value:"hide",hide:"label_outside"},{label:"Label column",value:"key",show:"label_outside"},{label:"Value column",value:"value",show:"label_outside"},{label:"Percentage",value:"percent",show:"label_outside"}]},label_outside:{title:"Show outside",info:"Would you like to show labels outside the donut?",type:"select",init:"false",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]}}}}),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",tag:"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/heatmap/config",[],function(){return{title:"Heatmap",library:"",tag:"div",use_panels:!0,execute:"heatmap",columns:{row_label:{title:"Row labels",is_label:!0},col_label:{title:"Column labels",is_label:!0},value:{title:"Observations"}},settings:{color_set:{title:"Color scheme",info:"Select a color scheme for your heatmap",type:"select",init:"ocean",data:[{label:"Cold-to-Hot",value:"hot"},{label:"Cool",value:"cool"},{label:"Copper",value:"copper"},{label:"Gebco",value:"gebco"},{label:"Globe",value:"globe"},{label:"Gray scale",value:"gray"},{label:"Haxby",value:"haxby"},{label:"Jet",value:"jet"},{label:"No-Green",value:"no_green"},{label:"Ocean",value:"ocean"},{label:"Polar",value:"polar"},{label:"Rainbow",value:"rainbow"},{label:"Red-to-Green",value:"redgreen"},{label:"Red-to-green (saturated)",value:"red2green"},{label:"Relief",value:"relief"},{label:"Seismograph",value:"seis"},{label:"Sealand",value:"sealand"},{label:"Split",value:"split"},{label:"Topo",value:"topo"},{label:"Wysiwyg",value:"wysiwyg"}]},sorting:{title:"Sorting",info:"How should the columns be clustered?",type:"select",init:"hclust",data:[{label:"Read from dataset",value:"hclust"},{label:"Sort column and row labels",value:"byboth"},{label:"Sort column labels",value:"bycolumns"},{label:"Sort by rows",value:"byrow"}]}},menu:function(){return{color_set:this.settings.color_set}}}}),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","plugin/charts/heatmap/config"],function(e,t,n,r,i,s,o,u,a,f){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
diff -r 7c9b64b44298ceef9d5d9935ce5cd3736f9b36f6 -r f6bf49aca8da9707937ebaebbfa869d10735dc81 config/plugins/visualizations/charts/static/charts/types.js
--- a/config/plugins/visualizations/charts/static/charts/types.js
+++ b/config/plugins/visualizations/charts/static/charts/types.js
@@ -28,7 +28,7 @@
defaults: {
'nvd3_bardiagram' : nvd3_bardiagram,
'nvd3_horizontal' : nvd3_horizontal,
- 'heatmap' : heatmap,
+ //'heatmap' : heatmap,
'nvd3_histogram' : nvd3_histogram,
'nvd3_line' : nvd3_line,
'nvd3_linewithfocus' : nvd3_linewithfocus,
diff -r 7c9b64b44298ceef9d5d9935ce5cd3736f9b36f6 -r f6bf49aca8da9707937ebaebbfa869d10735dc81 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
@@ -170,7 +170,7 @@
_refreshHdas: function() {
// update galaxy history
if (Galaxy && Galaxy.currHistoryPanel) {
- Galaxy.currHistoryPanel.refreshHdas();
+ Galaxy.currHistoryPanel.refreshContents();
}
}
});
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: Improve job handling and heatmaps
by commits-noreply@bitbucket.org 09 May '14
by commits-noreply@bitbucket.org 09 May '14
09 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/7c9b64b44298/
Changeset: 7c9b64b44298
User: guerler
Date: 2014-05-09 07:09:54
Summary: Charts: Improve job handling and heatmaps
Affected #: 5 files
diff -r 96242495c567a287bdb4bc26e05b70403c732f24 -r 7c9b64b44298ceef9d5d9935ce5cd3736f9b36f6 config/plugins/visualizations/charts/static/charts/heatmap/config.js
--- a/config/plugins/visualizations/charts/static/charts/heatmap/config.js
+++ b/config/plugins/visualizations/charts/static/charts/heatmap/config.js
@@ -5,15 +5,16 @@
library : '',
tag : 'div',
use_panels : true,
+ execute : 'heatmap',
// columns
columns : {
- col_label : {
- title : 'Columns',
+ row_label : {
+ title : 'Row labels',
is_label : true
},
- row_label : {
- title : 'Rows',
+ col_label : {
+ title : 'Column labels',
is_label : true
},
value : {
@@ -23,6 +24,50 @@
// settings
settings: {
+ /*limit : {
+ title : 'Limit',
+ info : 'Which to ranked clusters would you like to visualize',
+ type : 'select',
+ init : '20',
+ data : [
+ {
+ label : '20',
+ value : '20'
+ },
+ {
+ label : '30',
+ value : '30'
+ },
+ {
+ label : '40',
+ value : '40'
+ },
+ {
+ label : '50',
+ value : '50'
+ },
+ {
+ label : '60',
+ value : '60'
+ },
+ {
+ label : '70',
+ value : '70'
+ },
+ {
+ label : '80',
+ value : '80'
+ },
+ {
+ label : '90',
+ value : '90'
+ },
+ {
+ label : '100',
+ value : '100'
+ }
+ ]
+ },*/
color_set : {
title : 'Color scheme',
info : 'Select a color scheme for your heatmap',
diff -r 96242495c567a287bdb4bc26e05b70403c732f24 -r 7c9b64b44298ceef9d5d9935ce5cd3736f9b36f6 config/plugins/visualizations/charts/static/charts/heatmap/heatmap.js
--- a/config/plugins/visualizations/charts/static/charts/heatmap/heatmap.js
+++ b/config/plugins/visualizations/charts/static/charts/heatmap/heatmap.js
@@ -14,12 +14,35 @@
// render
draw : function(process_id, chart, request_dictionary)
{
- // request data
+ // link this
var self = this;
- this.app.datasets.request(request_dictionary, function() {
+
+ // loop through data groups
+ var index = 0;
+ for (var group_index in request_dictionary.groups) {
- // loop through data groups
- for (var group_index in request_dictionary.groups) {
+ // configure request
+ for (var i in request_dictionary.groups) {
+ var group = request_dictionary.groups[i];
+ group.columns = null;
+ group.columns = {
+ row_label: {
+ index : index++,
+ is_label : true
+ },
+ col_label: {
+ index : index++,
+ is_label : true
+ },
+ value: {
+ index : index++
+ }
+ }
+ }
+
+ // request data
+ this.app.datasets.request(request_dictionary, function() {
+
// get group
var group = request_dictionary.groups[group_index];
var div = self.options.canvas[group_index];
@@ -31,14 +54,17 @@
'data' : group.values,
'div' : div
});
- }
-
- // set chart state
- chart.state('ok', 'Heat map drawn.');
- // unregister process
- chart.deferred.done(process_id);
- });
+ // check if done
+ if (group_index == request_dictionary.groups.length - 1) {
+ // set chart state
+ chart.state('ok', 'Heat map drawn.');
+
+ // unregister process
+ chart.deferred.done(process_id);
+ }
+ });
+ }
}
});
diff -r 96242495c567a287bdb4bc26e05b70403c732f24 -r 7c9b64b44298ceef9d5d9935ce5cd3736f9b36f6 config/plugins/visualizations/charts/static/charts/types.js
--- a/config/plugins/visualizations/charts/static/charts/types.js
+++ b/config/plugins/visualizations/charts/static/charts/types.js
@@ -27,8 +27,8 @@
// types
defaults: {
'nvd3_bardiagram' : nvd3_bardiagram,
+ 'nvd3_horizontal' : nvd3_horizontal,
'heatmap' : heatmap,
- 'nvd3_horizontal' : nvd3_horizontal,
'nvd3_histogram' : nvd3_histogram,
'nvd3_line' : nvd3_line,
'nvd3_linewithfocus' : nvd3_linewithfocus,
diff -r 96242495c567a287bdb4bc26e05b70403c732f24 -r 7c9b64b44298ceef9d5d9935ce5cd3736f9b36f6 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
@@ -13,12 +13,33 @@
this.options = Utils.merge(options, this.optionsDefault);
},
+ // request job results
+ request: function(chart, settings_string, columns_string, success, error) {
+ // link this
+ var self = this;
+
+ // set chart state
+ chart.state('wait', 'Requesting job results...');
+
+ // get dataset job id if already set
+ var dataset_id_job = chart.get('dataset_id_job');
+ if (dataset_id_job != '') {
+ // wait for job completion
+ self._wait(chart, success, error);
+ } else {
+ // post job
+ self._submit(chart, settings_string, columns_string, success, error);
+ }
+ },
+
// clean
cleanup: function(chart) {
+ // link this
+ var self = this;
+
// cleanup previous dataset file
var previous = chart.get('dataset_id_job');
if (previous != '') {
- var self = this;
Utils.request('PUT', config.root + 'api/histories/none/contents/' + previous, { deleted: true }, function() {
// update galaxy history
self._refreshHdas();
@@ -30,13 +51,13 @@
},
// create job
- submit: function(chart, settings_string, columns_string, success, error) {
+ _submit: function(chart, settings_string, columns_string, success, error) {
// link this
var self = this;
// backup chart details
- var chart_id = chart.id;
- var chart_type = chart.get('type');
+ var chart_id = chart.id;
+ var chart_type = chart.get('type');
// get chart settings
var chart_settings = this.app.types.get(chart_type);
@@ -75,7 +96,7 @@
var job = response.outputs[0];
// check dataset
- chart.state('wait', 'Job has been queued...');
+ chart.state('wait', 'Your job has been queued. You may close the browser window. The job will run in the background.');
// backup resulting dataset id
chart.set('dataset_id_job', job.id);
@@ -84,34 +105,7 @@
this.app.storage.save();
// wait for job completion
- self._loop(job.id, function(job) {
- switch (job.state) {
- case 'ok':
- // update state
- chart.state('wait', 'Job completed successfully...');
-
- // execute success
- success(job);
-
- // stop loop
- return true;
- case 'error':
- // update state
- chart.state('failed', 'Job has failed. Please check the history for details.');
-
- // call error
- error && error();
-
- // stop loop
- return true;
- case 'running':
- // wait
- chart.state('wait', 'Job is running...');
-
- // continue loop
- return false;
- }
- });
+ self._wait(chart, success, error);
}
},
// error handler
@@ -132,11 +126,42 @@
},
// request job details
- _loop: function(id, callback) {
+ _wait: function(chart, success, error) {
var self = this;
- Utils.request('GET', config.root + 'api/datasets/' + id, {}, function(job) {
- if (!callback(job)) {
- setTimeout(function() { self._loop(id, callback); }, self.app.config.get('query_timeout'));
+ Utils.request('GET', config.root + 'api/datasets/' + chart.get('dataset_id_job'), {}, function(dataset) {
+ // check dataset state
+ var ready = false;
+ switch (dataset.state) {
+ case 'ok':
+ // update state
+ chart.state('wait', 'Job completed successfully...');
+
+ // execute success
+ success && success(dataset);
+
+ // stop loop
+ ready = true;
+ break;
+ case 'error':
+ // update state
+ chart.state('failed', 'Job has failed. Please check the history for details.');
+
+ // call error
+ error && error(dataset);
+
+ // stop loop
+ ready = true;
+ break;
+ case 'running':
+ // wait
+ chart.state('wait', 'Your job is running. You may close the browser window. The job will continue in the background.');
+ }
+
+ // wait and try again
+ if (!ready) {
+ setTimeout(function() {
+ self._wait(chart, success, error);
+ }, self.app.config.get('query_timeout'));
}
});
},
diff -r 96242495c567a287bdb4bc26e05b70403c732f24 -r 7c9b64b44298ceef9d5d9935ce5cd3736f9b36f6 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
@@ -173,19 +173,14 @@
// request data
if (self.chart_settings.execute) {
- if (chart.get('dataset_id_job') == '') {
- // submit job
- self.app.jobs.submit(chart, self._defaultSettingsString(chart), self._defaultRequestString(chart),
- function() {
- view.draw(process_id, chart, self._defaultRequestDictionary(chart));
- },
- function() {
- chart.deferred.done(process_id);
- });
- } else {
- // load data into view
- view.draw(process_id, chart, self._defaultRequestDictionary(chart));
- }
+ self.app.jobs.request(chart, self._defaultSettingsString(chart), self._defaultRequestString(chart),
+ function() {
+ view.draw(process_id, chart, self._defaultRequestDictionary(chart));
+ },
+ function() {
+ chart.deferred.done(process_id);
+ }
+ );
} else {
// load data into view
view.draw(process_id, chart, self._defaultRequestDictionary(chart));
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: pep 8, fixed decoding of folders again
by commits-noreply@bitbucket.org 09 May '14
by commits-noreply@bitbucket.org 09 May '14
09 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/96242495c567/
Changeset: 96242495c567
User: martenson
Date: 2014-05-09 00:55:57
Summary: pep 8, fixed decoding of folders again
Affected #: 2 files
diff -r f2f32d8b8a06ff370145360b5c75c90e2e2447a9 -r 96242495c567a287bdb4bc26e05b70403c732f24 lib/galaxy/webapps/galaxy/api/folders.py
--- a/lib/galaxy/webapps/galaxy/api/folders.py
+++ b/lib/galaxy/webapps/galaxy/api/folders.py
@@ -136,7 +136,7 @@
def __cut_the_prefix(self, encoded_id):
- if ( ( len( encoded_id ) % 2 == 1 ) and encoded_id.startswith( 'F' ) ):
+ if ( ( len( encoded_id ) % 16 == 1 ) and encoded_id.startswith( 'F' ) ):
return encoded_id[ 1: ]
else:
raise exceptions.MalformedId( 'Malformed folder id ( %s ) specified, unable to decode.' % str( encoded_id ) )
diff -r f2f32d8b8a06ff370145360b5c75c90e2e2447a9 -r 96242495c567a287bdb4bc26e05b70403c732f24 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,6 +17,7 @@
import logging
log = logging.getLogger( __name__ )
+
class LibraryContentsController( BaseAPIController, UsesLibraryMixin, UsesLibraryMixinItems, UsesHistoryDatasetAssociationMixin ):
@expose_api
@@ -26,7 +27,7 @@
* GET /api/libraries/{library_id}/contents:
Returns a list of library files and folders.
- .. note:: May be slow! Returns all content traversing recursively through all folders.
+ .. note:: May be slow! Returns all content traversing recursively through all folders.
.. seealso:: :class:`galaxy.webapps.galaxy.api.FolderContentsController.index` for a non-recursive solution
:param library_id: encoded id string of the library
@@ -78,7 +79,7 @@
except NoResultFound:
raise exceptions.RequestParameterInvalidException( 'No library found with the id provided.' )
except Exception, e:
- raise exceptions.InternalServerError( 'Error loading from the database.' + str(e))
+ raise exceptions.InternalServerError( 'Error loading from the database.' + str(e))
if not ( trans.user_is_admin() or trans.app.security_agent.can_access_library( current_user_roles, library ) ):
raise exceptions.RequestParameterInvalidException( 'No library found with the id provided.' )
encoded_id = 'F' + trans.security.encode_id( library.root_folder.id )
@@ -122,7 +123,7 @@
class_name, content_id = self.__decode_library_content_id( trans, id )
if class_name == 'LibraryFolder':
content = self.get_library_folder( trans, content_id, check_ownership=False, check_accessible=True )
- rval = content.to_dict( view='element', value_mapper={ 'id' : trans.security.encode_id } )
+ rval = content.to_dict( view='element', value_mapper={ 'id': trans.security.encode_id } )
rval[ 'id' ] = 'F' + str( rval[ 'id' ] )
rval[ 'parent_id' ] = 'F' + str( trans.security.encode_id( rval[ 'parent_id' ] ) )
rval[ 'parent_library_id' ] = trans.security.encode_id( rval[ 'parent_library_id' ] )
@@ -236,9 +237,9 @@
encoded_id = trans.security.encode_id( v.id )
if create_type == 'folder':
encoded_id = 'F' + encoded_id
- rval.append( dict( id = encoded_id,
- name = v.name,
- url = url_for( 'library_content', library_id=library_id, id=encoded_id ) ) )
+ rval.append( dict( id=encoded_id,
+ name=v.name,
+ url=url_for( 'library_content', library_id=library_id, id=encoded_id ) ) )
return rval
def _scan_json_block(self, meta, prefix=""):
@@ -276,7 +277,7 @@
``library_contents.create`` will branch to this if called with 'from_hda_id'
in its payload.
"""
- log.debug( '_copy_hda_to_library_folder: %s' %( str(( from_hda_id, library_id, folder_id, ldda_message )) ) )
+ log.debug( '_copy_hda_to_library_folder: %s' % ( str(( from_hda_id, library_id, folder_id, ldda_message )) ) )
#PRECONDITION: folder_id has already been altered to remove the folder prefix ('F')
#TODO: allow name and other, editable ldda attrs?
if ldda_message:
@@ -287,14 +288,14 @@
# check permissions on (all three?) resources: hda, library, folder
#TODO: do we really need the library??
hda = self.get_dataset( trans, from_hda_id, check_ownership=True, check_accessible=True, check_state=True )
- library = self.get_library( trans, library_id, check_accessible=True )
+ # library = self.get_library( trans, library_id, check_accessible=True )
folder = self.get_library_folder( trans, folder_id, check_accessible=True )
# TOOD: refactor to use check_user_can_add_to_library_item, eliminate boolean
# can_current_user_add_to_library_item.
if not self.can_current_user_add_to_library_item( trans, folder ):
trans.response.status = 403
- return { 'error' : 'user has no permission to add to library folder (%s)' %( folder_id ) }
+ return { 'error': 'user has no permission to add to library folder (%s)' % ( folder_id ) }
ldda = self.copy_hda_to_library_folder( trans, hda, folder, ldda_message=ldda_message )
ldda_dict = ldda.to_dict()
@@ -304,11 +305,11 @@
#TODO: grrr...
if 'not accessible to the current user' in str( exc ):
trans.response.status = 403
- return { 'error' : str( exc ) }
+ return { 'error': str( exc ) }
else:
log.exception( exc )
trans.response.status = 500
- return { 'error' : str( exc ) }
+ return { 'error': str( exc ) }
return rval
@@ -335,10 +336,10 @@
converted_id = payload.pop( 'converted_dataset_id' )
content = self.get_library_dataset( trans, id, check_ownership=False, check_accessible=False )
content_conv = self.get_library_dataset( trans, converted_id, check_ownership=False, check_accessible=False )
- assoc = trans.app.model.ImplicitlyConvertedDatasetAssociation( parent = content.library_dataset_dataset_association,
- dataset = content_conv.library_dataset_dataset_association,
- file_type = content_conv.library_dataset_dataset_association.extension,
- metadata_safe = True )
+ assoc = trans.app.model.ImplicitlyConvertedDatasetAssociation( parent=content.library_dataset_dataset_association,
+ dataset=content_conv.library_dataset_dataset_association,
+ file_type=content_conv.library_dataset_dataset_association.extension,
+ metadata_safe=True )
trans.sa_session.add( assoc )
trans.sa_session.flush()
@@ -346,11 +347,10 @@
if ( len( content_id ) % 16 == 0 ):
return 'LibraryDataset', content_id
elif ( content_id.startswith( 'F' ) ):
- return 'LibraryFolder', content_id[1:]
+ return 'LibraryFolder', content_id[ 1: ]
else:
raise HTTPBadRequest( 'Malformed library content id ( %s ) specified, unable to decode.' % str( content_id ) )
-
@web.expose_api
def delete( self, trans, library_id, id, **kwd ):
"""
@@ -377,7 +377,7 @@
if kwd.get( 'payload', None ):
purge = util.string_as_bool( kwd['payload'].get( 'purge', False ) )
- rval = { 'id' : id }
+ rval = { 'id': id }
try:
ld = self.get_library_dataset( trans, id, check_ownership=False, check_accessible=True )
user_is_admin = trans.user_is_admin()
@@ -424,5 +424,3 @@
trans.response.status = 500
rval.update({ 'error': str( exc ) })
return rval
-
-
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