mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-10-24 12:13:33 +08:00
Merge pull request #829 from guerler/tool_execution_000
Reduce handle inputs and remove update state from tools
This commit is contained in:
@@ -91,13 +91,6 @@ define(['utils/utils', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc',
|
||||
}
|
||||
},
|
||||
|
||||
/** Shows the final message (usually upon successful job submission)
|
||||
*/
|
||||
reciept: function($el) {
|
||||
this.$el.empty();
|
||||
this.$el.append($el);
|
||||
},
|
||||
|
||||
/** Highlight and scroll to input element (currently only used for error notifications)
|
||||
*/
|
||||
highlight: function (input_id, message, silent) {
|
||||
|
||||
@@ -118,7 +118,7 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view',
|
||||
console.debug(response);
|
||||
|
||||
// show error
|
||||
var error_message = response.error || response.err_msg || 'Uncaught error.';
|
||||
var error_message = ( response && response.error ) || ( response && response.err_msg ) || 'Uncaught error.';
|
||||
if ( self.$el.is(':empty') ) {
|
||||
self.$el.prepend((new Ui.Message({
|
||||
message : error_message,
|
||||
|
||||
@@ -34,24 +34,23 @@ return {
|
||||
data : job_def,
|
||||
success : function(response) {
|
||||
callback && callback();
|
||||
form.reciept(ToolTemplate.success(response));
|
||||
form.$el.replaceWith( ToolTemplate.success( response ) );
|
||||
// begin checking the history for updates
|
||||
self._refreshHdas();
|
||||
},
|
||||
error : function(response, response_full) {
|
||||
error : function(response) {
|
||||
callback && callback();
|
||||
if (response && response.message && response.message.data) {
|
||||
var error_messages = form.data.matchResponse(response.message.data);
|
||||
console.debug(response);
|
||||
if (response && response.err_data) {
|
||||
var error_messages = form.data.matchResponse(response.err_data);
|
||||
for (var input_id in error_messages) {
|
||||
form.highlight(input_id, error_messages[input_id]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// show error message with details
|
||||
console.debug(response);
|
||||
response && form.modal.show({
|
||||
form.modal.show({
|
||||
title : 'Job submission failed',
|
||||
body : ToolTemplate.error(job_def),
|
||||
body : ( response && response.err_msg ) || ToolTemplate.error( job_def ),
|
||||
buttons : {
|
||||
'Close' : function() {
|
||||
form.modal.hide();
|
||||
|
||||
+39
-447
@@ -45,7 +45,7 @@ from galaxy.tools.test import parse_tests
|
||||
from galaxy.tools.parser import get_tool_source
|
||||
from galaxy.tools.parser.xml import XmlPageSource
|
||||
from galaxy.tools.toolbox import AbstractToolBox
|
||||
from galaxy.util import rst_to_html, string_as_bool, string_to_object
|
||||
from galaxy.util import rst_to_html, string_as_bool
|
||||
from galaxy.tools.parameters.meta import expand_meta_parameters
|
||||
from galaxy.util.bunch import Bunch
|
||||
from galaxy.util.expressions import ExpressionContext
|
||||
@@ -451,7 +451,6 @@ class Tool( object, Dictifiable ):
|
||||
requires_setting_metadata = True
|
||||
default_tool_action = DefaultToolAction
|
||||
dict_collection_visible_keys = ( 'id', 'name', 'version', 'description' )
|
||||
default_template = ''
|
||||
|
||||
def __init__( self, config_file, tool_source, app, guid=None, repository_id=None, allow_code_files=True ):
|
||||
"""Load a tool from the config named by `config_file`"""
|
||||
@@ -1195,21 +1194,14 @@ class Tool( object, Dictifiable ):
|
||||
# outputs?
|
||||
return True
|
||||
|
||||
def new_state( self, trans, all_pages=False, history=None ):
|
||||
def new_state( self, trans, history=None ):
|
||||
"""
|
||||
Create a new `DefaultToolState` for this tool. It will be initialized
|
||||
with default values for inputs.
|
||||
|
||||
Only inputs on the first page will be initialized unless `all_pages` is
|
||||
True, in which case all inputs regardless of page are initialized.
|
||||
"""
|
||||
state = DefaultToolState()
|
||||
state.inputs = {}
|
||||
if all_pages:
|
||||
inputs = self.inputs
|
||||
else:
|
||||
inputs = self.inputs_by_page[ 0 ]
|
||||
self.fill_in_new_state( trans, inputs, state.inputs, history=history )
|
||||
self.fill_in_new_state( trans, self.inputs, state.inputs, history=history )
|
||||
return state
|
||||
|
||||
def fill_in_new_state( self, trans, inputs, state, context=None, history=None ):
|
||||
@@ -1274,101 +1266,70 @@ class Tool( object, Dictifiable ):
|
||||
else:
|
||||
input.visit_inputs( "", value[input.name], callback )
|
||||
|
||||
def handle_input( self, trans, incoming, history=None, old_errors=None, process_state='update', source='html' ):
|
||||
def handle_input( self, trans, incoming, history=None, source='html' ):
|
||||
"""
|
||||
Process incoming parameters for this tool from the dict `incoming`,
|
||||
update the tool state (or create if none existed), and either return
|
||||
to the form or execute the tool (only if 'execute' was clicked and
|
||||
there were no errors).
|
||||
|
||||
process_state can be either 'update' (to incrementally build up the state
|
||||
over several calls - one repeat per handle for instance) or 'populate'
|
||||
force a complete build of the state and submission all at once (like
|
||||
from API). May want an incremental version of the API also at some point,
|
||||
that is why this is not just called for_api.
|
||||
"""
|
||||
all_pages = ( process_state == "populate" ) # If process_state = update, handle all pages at once.
|
||||
rerun_remap_job_id = None
|
||||
if 'rerun_remap_job_id' in incoming:
|
||||
try:
|
||||
rerun_remap_job_id = trans.app.security.decode_id( incoming[ 'rerun_remap_job_id' ] )
|
||||
except Exception, exception:
|
||||
log.error( str( exception ) )
|
||||
message = 'Failure executing tool (attempting to rerun invalid job).'
|
||||
return 'message.mako', dict( status='error', message=message, refresh_frames=[] )
|
||||
raise exceptions.MessageException( 'Failure executing tool (attempting to rerun invalid job).' )
|
||||
|
||||
# Fixed set of input parameters may correspond to any number of jobs.
|
||||
# Expand these out to individual parameters for given jobs (tool
|
||||
# executions).
|
||||
# Expand these out to individual parameters for given jobs (tool executions).
|
||||
expanded_incomings, collection_info = expand_meta_parameters( trans, self, incoming )
|
||||
|
||||
if not expanded_incomings:
|
||||
raise exceptions.MessageException( "Tool execution failed, trying to run a tool over an empty collection." )
|
||||
raise exceptions.MessageException( 'Tool execution failed, trying to run a tool over an empty collection.' )
|
||||
|
||||
# Remapping a single job to many jobs doesn't make sense, so disable
|
||||
# remap if multi-runs of tools are being used.
|
||||
if rerun_remap_job_id and len( expanded_incomings ) > 1:
|
||||
message = 'Failure executing tool (cannot create multiple jobs when remapping existing job).'
|
||||
return 'message.mako', dict( status='error', message=message, refresh_frames=[] )
|
||||
|
||||
all_states = []
|
||||
for expanded_incoming in expanded_incomings:
|
||||
state, state_new = self.__fetch_state( trans, expanded_incoming, history, all_pages=all_pages )
|
||||
all_states.append( state )
|
||||
if state_new:
|
||||
# This feels a bit like a hack. It allows forcing full processing
|
||||
# of inputs even when there is no state in the incoming dictionary
|
||||
# by providing either 'runtool_btn' (the name of the submit button
|
||||
# on the standard run form) or "URL" (a parameter provided by
|
||||
# external data source tools).
|
||||
if "runtool_btn" not in incoming and "URL" not in incoming:
|
||||
if not self.display_interface:
|
||||
return self.__no_display_interface_response()
|
||||
if len(incoming):
|
||||
self.update_state( trans, self.inputs_by_page[state.page], state.inputs, incoming, old_errors=old_errors or {}, source=source )
|
||||
return self.default_template, dict( errors={}, tool_state=state, param_values={}, incoming={} )
|
||||
raise exceptions.MessageException( 'Failure executing tool (cannot create multiple jobs when remapping existing job).' )
|
||||
|
||||
all_errors = []
|
||||
all_params = []
|
||||
for expanded_incoming, expanded_state in zip(expanded_incomings, all_states):
|
||||
errors, params = self.__check_param_values( trans, expanded_incoming, expanded_state, old_errors, process_state, history=history, source=source )
|
||||
for expanded_incoming in expanded_incomings:
|
||||
expanded_state = self.new_state( trans, history=history )
|
||||
# Process incoming data
|
||||
if not self.check_values:
|
||||
# If `self.check_values` is false we don't do any checking or
|
||||
# processing on input This is used to pass raw values
|
||||
# through to/from external sites.
|
||||
errors = {}
|
||||
params = expanded_incoming
|
||||
else:
|
||||
# Update state for all inputs on the current page taking new
|
||||
# values from `incoming`.
|
||||
errors = self.populate_state( trans, self.inputs, expanded_state.inputs, expanded_incoming, history, source=source )
|
||||
# If the tool provides a `validate_input` hook, call it.
|
||||
validate_input = self.get_hook( 'validate_input' )
|
||||
if validate_input:
|
||||
validate_input( trans, errors, expanded_state.inputs, self.inputs )
|
||||
params = expanded_state.inputs
|
||||
all_errors.append( errors )
|
||||
all_params.append( params )
|
||||
|
||||
if self.__should_refresh_state( incoming ):
|
||||
template, template_vars = self.__handle_state_refresh( trans, state, errors )
|
||||
# If there were errors, we stay on the same page and display
|
||||
# error messages
|
||||
if any( all_errors ):
|
||||
raise exceptions.MessageException( err_data=all_errors[ 0 ] )
|
||||
else:
|
||||
# User actually clicked next or execute.
|
||||
|
||||
# If there were errors, we stay on the same page and display
|
||||
# error messages
|
||||
if any( all_errors ):
|
||||
error_message = "One or more errors were found in the input you provided. The specific errors are marked below."
|
||||
template = self.default_template
|
||||
template_vars = dict( errors=errors, tool_state=state, incoming=incoming, error_message=error_message )
|
||||
# If we've completed the last page we can execute the tool
|
||||
elif all_pages or state.page == self.last_page:
|
||||
execution_tracker = execute_job( trans, self, all_params, history=history, rerun_remap_job_id=rerun_remap_job_id, collection_info=collection_info )
|
||||
if execution_tracker.successful_jobs:
|
||||
template = 'tool_executed.mako'
|
||||
template_vars = dict(
|
||||
out_data=execution_tracker.output_datasets,
|
||||
num_jobs=len( execution_tracker.successful_jobs ),
|
||||
job_errors=execution_tracker.execution_errors,
|
||||
jobs=execution_tracker.successful_jobs,
|
||||
output_collections=execution_tracker.output_collections,
|
||||
implicit_collections=execution_tracker.implicit_collections,
|
||||
)
|
||||
else:
|
||||
template = 'message.mako'
|
||||
template_vars = dict( status='error', message=execution_tracker.execution_errors[0], refresh_frames=[] )
|
||||
# Otherwise move on to the next page
|
||||
execution_tracker = execute_job( trans, self, all_params, history=history, rerun_remap_job_id=rerun_remap_job_id, collection_info=collection_info )
|
||||
if execution_tracker.successful_jobs:
|
||||
return dict( out_data=execution_tracker.output_datasets,
|
||||
num_jobs=len( execution_tracker.successful_jobs ),
|
||||
job_errors=execution_tracker.execution_errors,
|
||||
jobs=execution_tracker.successful_jobs,
|
||||
output_collections=execution_tracker.output_collections,
|
||||
implicit_collections=execution_tracker.implicit_collections )
|
||||
else:
|
||||
template, template_vars = self.__handle_page_advance( trans, state, errors )
|
||||
return template, template_vars
|
||||
|
||||
def __should_refresh_state( self, incoming ):
|
||||
return not( 'runtool_btn' in incoming or 'URL' in incoming or 'ajax_upload' in incoming )
|
||||
raise exceptions.MessageException( execution_tracker.execution_errors[ 0 ] )
|
||||
|
||||
def handle_single_execution( self, trans, rerun_remap_job_id, params, history, mapping_over_collection ):
|
||||
"""
|
||||
@@ -1394,72 +1355,6 @@ class Tool( object, Dictifiable ):
|
||||
message = 'Failure executing tool (invalid data returned from tool execution)'
|
||||
return False, message
|
||||
|
||||
def __handle_state_refresh( self, trans, state, errors ):
|
||||
try:
|
||||
self.find_fieldstorage( state.inputs )
|
||||
except InterruptedUpload:
|
||||
# If inputs contain a file it won't persist. Most likely this
|
||||
# is an interrupted upload. We should probably find a more
|
||||
# standard method of determining an incomplete POST.
|
||||
return self.handle_interrupted( trans, state.inputs )
|
||||
except:
|
||||
pass
|
||||
# Just a refresh, render the form with updated state and errors.
|
||||
if not self.display_interface:
|
||||
return self.__no_display_interface_response()
|
||||
return self.default_template, dict( errors=errors, tool_state=state )
|
||||
|
||||
def __handle_page_advance( self, trans, state, errors ):
|
||||
state.page += 1
|
||||
# Fill in the default values for the next page
|
||||
self.fill_in_new_state( trans, self.inputs_by_page[ state.page ], state.inputs )
|
||||
if not self.display_interface:
|
||||
return self.__no_display_interface_response()
|
||||
return self.default_template, dict( errors=errors, tool_state=state )
|
||||
|
||||
def __no_display_interface_response( self ):
|
||||
return 'message.mako', dict( status='info', message="The interface for this tool cannot be displayed", refresh_frames=['everything'] )
|
||||
|
||||
def __fetch_state( self, trans, incoming, history, all_pages ):
|
||||
# Get the state or create if not found
|
||||
if "tool_state" in incoming:
|
||||
encoded_state = string_to_object( incoming["tool_state"] )
|
||||
state = DefaultToolState()
|
||||
state.decode( encoded_state, self, trans.app )
|
||||
new = False
|
||||
else:
|
||||
state = self.new_state( trans, history=history, all_pages=all_pages )
|
||||
new = True
|
||||
return state, new
|
||||
|
||||
def __check_param_values( self, trans, incoming, state, old_errors, process_state, history, source ):
|
||||
# Process incoming data
|
||||
if not self.check_values:
|
||||
# If `self.check_values` is false we don't do any checking or
|
||||
# processing on input This is used to pass raw values
|
||||
# through to/from external sites. FIXME: This should be handled
|
||||
# more cleanly, there is no reason why external sites need to
|
||||
# post back to the same URL that the tool interface uses.
|
||||
errors = {}
|
||||
params = incoming
|
||||
else:
|
||||
# Update state for all inputs on the current page taking new
|
||||
# values from `incoming`.
|
||||
if process_state == "update":
|
||||
inputs = self.inputs_by_page[state.page]
|
||||
errors = self.update_state( trans, inputs, state.inputs, incoming, old_errors=old_errors or {}, source=source )
|
||||
elif process_state == "populate":
|
||||
inputs = self.inputs
|
||||
errors = self.populate_state( trans, inputs, state.inputs, incoming, history, source=source )
|
||||
else:
|
||||
raise Exception("Unknown process_state type %s" % process_state)
|
||||
# If the tool provides a `validate_input` hook, call it.
|
||||
validate_input = self.get_hook( 'validate_input' )
|
||||
if validate_input:
|
||||
validate_input( trans, errors, state.inputs, inputs )
|
||||
params = state.inputs
|
||||
return errors, params
|
||||
|
||||
def find_fieldstorage( self, x ):
|
||||
if isinstance( x, FieldStorage ):
|
||||
raise InterruptedUpload( None )
|
||||
@@ -1468,37 +1363,6 @@ class Tool( object, Dictifiable ):
|
||||
elif isinstance(x, list):
|
||||
[ self.find_fieldstorage( y ) for y in x ]
|
||||
|
||||
def handle_interrupted( self, trans, inputs ):
|
||||
"""
|
||||
Upon handling inputs, if it appears that we have received an incomplete
|
||||
form, do some cleanup or anything else deemed necessary. Currently
|
||||
this is only likely during file uploads, but this method could be
|
||||
generalized and a method standardized for handling other tools.
|
||||
"""
|
||||
# If the async upload tool has uploading datasets, we need to error them.
|
||||
if 'async_datasets' in inputs and inputs['async_datasets'] not in [ 'None', '', None ]:
|
||||
for id in inputs['async_datasets'].split(','):
|
||||
try:
|
||||
data = self.sa_session.query( trans.model.HistoryDatasetAssociation ).get( int( id ) )
|
||||
except:
|
||||
log.exception( 'Unable to load precreated dataset (%s) sent in upload form' % id )
|
||||
continue
|
||||
if trans.user is None and trans.galaxy_session.current_history != data.history:
|
||||
log.error( 'Got a precreated dataset (%s) but it does not belong to anonymous user\'s current session (%s)'
|
||||
% ( data.id, trans.galaxy_session.id ) )
|
||||
elif data.history.user != trans.user:
|
||||
log.error( 'Got a precreated dataset (%s) but it does not belong to current user (%s)'
|
||||
% ( data.id, trans.user.id ) )
|
||||
else:
|
||||
data.state = data.states.ERROR
|
||||
data.info = 'Upload of this dataset was interrupted. Please try uploading again or'
|
||||
self.sa_session.add( data )
|
||||
self.sa_session.flush()
|
||||
# It's unlikely the user will ever see this.
|
||||
return 'message.mako', dict( status='error',
|
||||
message='Your upload was interrupted. If this was uninentional, please retry it.',
|
||||
refresh_frames=[], cont=None )
|
||||
|
||||
def populate_state( self, trans, inputs, state, incoming, history=None, source="html", prefix="", context=None ):
|
||||
errors = dict()
|
||||
# Push this level onto the context stack
|
||||
@@ -1643,260 +1507,6 @@ class Tool( object, Dictifiable ):
|
||||
state[ input.name ] = value
|
||||
return errors
|
||||
|
||||
def update_state( self, trans, inputs, state, incoming, source='html', prefix="", context=None,
|
||||
update_only=False, old_errors={}, item_callback=None ):
|
||||
"""
|
||||
Update the tool state in `state` using the user input in `incoming`.
|
||||
This is designed to be called recursively: `inputs` contains the
|
||||
set of inputs being processed, and `prefix` specifies a prefix to
|
||||
add to the name of each input to extract its value from `incoming`.
|
||||
|
||||
If `update_only` is True, values that are not in `incoming` will
|
||||
not be modified. In this case `old_errors` can be provided, and any
|
||||
errors for parameters which were *not* updated will be preserved.
|
||||
"""
|
||||
errors = dict()
|
||||
# Push this level onto the context stack
|
||||
context = ExpressionContext( state, context )
|
||||
# Iterate inputs and update (recursively)
|
||||
for input in inputs.itervalues():
|
||||
key = prefix + input.name
|
||||
if isinstance( input, Repeat ):
|
||||
group_state = state[input.name]
|
||||
# Create list of empty errors for each previously existing state
|
||||
group_errors = [ {} for i in range( len( group_state ) ) ]
|
||||
group_old_errors = old_errors.get( input.name, None )
|
||||
any_group_errors = False
|
||||
# Check any removals before updating state -- only one
|
||||
# removal can be performed, others will be ignored
|
||||
for i, rep_state in enumerate( group_state ):
|
||||
rep_index = rep_state['__index__']
|
||||
if key + "_" + str(rep_index) + "_remove" in incoming:
|
||||
if len( group_state ) > input.min:
|
||||
del group_state[i]
|
||||
del group_errors[i]
|
||||
if group_old_errors:
|
||||
del group_old_errors[i]
|
||||
break
|
||||
else:
|
||||
group_errors[i] = { '__index__': 'Cannot remove repeat (min size=%i).' % input.min }
|
||||
any_group_errors = True
|
||||
# Only need to find one that can't be removed due to size, since only
|
||||
# one removal is processed at # a time anyway
|
||||
break
|
||||
elif group_old_errors and group_old_errors[i]:
|
||||
group_errors[i] = group_old_errors[i]
|
||||
any_group_errors = True
|
||||
# Update state
|
||||
max_index = -1
|
||||
for i, rep_state in enumerate( group_state ):
|
||||
rep_index = rep_state['__index__']
|
||||
max_index = max( max_index, rep_index )
|
||||
rep_prefix = "%s_%d|" % ( key, rep_index )
|
||||
if group_old_errors:
|
||||
rep_old_errors = group_old_errors[i]
|
||||
else:
|
||||
rep_old_errors = {}
|
||||
rep_errors = self.update_state( trans,
|
||||
input.inputs,
|
||||
rep_state,
|
||||
incoming,
|
||||
source=source,
|
||||
prefix=rep_prefix,
|
||||
context=context,
|
||||
update_only=update_only,
|
||||
old_errors=rep_old_errors,
|
||||
item_callback=item_callback )
|
||||
if rep_errors:
|
||||
any_group_errors = True
|
||||
group_errors[i].update( rep_errors )
|
||||
# Check for addition
|
||||
if key + "_add" in incoming:
|
||||
if len( group_state ) < input.max:
|
||||
new_state = {}
|
||||
new_state['__index__'] = max_index + 1
|
||||
self.fill_in_new_state( trans, input.inputs, new_state, context )
|
||||
group_state.append( new_state )
|
||||
group_errors.append( {} )
|
||||
else:
|
||||
group_errors[-1] = { '__index__': 'Cannot add repeat (max size=%i).' % input.max }
|
||||
any_group_errors = True
|
||||
# Were there *any* errors for any repetition?
|
||||
if any_group_errors:
|
||||
errors[input.name] = group_errors
|
||||
elif isinstance( input, Conditional ):
|
||||
group_state = state[input.name]
|
||||
group_old_errors = old_errors.get( input.name, {} )
|
||||
old_current_case = group_state['__current_case__']
|
||||
group_prefix = "%s|" % ( key )
|
||||
# Deal with the 'test' element and see if its value changed
|
||||
if input.value_ref and not input.value_ref_in_group:
|
||||
# We are referencing an existent parameter, which is not
|
||||
# part of this group
|
||||
test_param_key = prefix + input.test_param.name
|
||||
else:
|
||||
test_param_key = group_prefix + input.test_param.name
|
||||
test_param_error = None
|
||||
test_incoming = get_incoming_value( incoming, test_param_key, None )
|
||||
if test_param_key not in incoming \
|
||||
and "__force_update__" + test_param_key not in incoming \
|
||||
and update_only:
|
||||
# Update only, keep previous value and state, but still
|
||||
# recurse in case there are nested changes
|
||||
value = group_state[ input.test_param.name ]
|
||||
current_case = old_current_case
|
||||
if input.test_param.name in old_errors:
|
||||
errors[ input.test_param.name ] = old_errors[ input.test_param.name ]
|
||||
else:
|
||||
# Get value of test param and determine current case
|
||||
value, test_param_error = \
|
||||
check_param( trans, input.test_param, test_incoming, context, source=source )
|
||||
try:
|
||||
current_case = input.get_current_case( value, trans )
|
||||
except ValueError, e:
|
||||
if input.is_job_resource_conditional:
|
||||
# Unless explicitly given job resource parameters
|
||||
# (e.g. from the run tool form) don't populate the
|
||||
# state. Along with other hacks prevents workflow
|
||||
# saving from populating resource defaults - which
|
||||
# are meant to be much more transient than the rest
|
||||
# of tool state.
|
||||
continue
|
||||
# load default initial value
|
||||
if not test_param_error:
|
||||
test_param_error = str( e )
|
||||
if trans is not None:
|
||||
history = trans.get_history()
|
||||
else:
|
||||
history = None
|
||||
value = input.test_param.get_initial_value( trans, context, history=history )
|
||||
current_case = input.get_current_case( value, trans )
|
||||
case_changed = current_case != old_current_case
|
||||
if case_changed:
|
||||
# Current case has changed, throw away old state
|
||||
group_state = state[input.name] = {}
|
||||
# TODO: we should try to preserve values if we can
|
||||
self.fill_in_new_state( trans, input.cases[current_case].inputs, group_state, context )
|
||||
group_errors = dict()
|
||||
group_old_errors = dict()
|
||||
|
||||
# If we didn't just change the current case and are coming from HTML - the values
|
||||
# in incoming represent the old values and should not be replaced. If being updated
|
||||
# from the API (json) instead of HTML - form values below the current case
|
||||
# may also be supplied and incoming should be preferred to case defaults.
|
||||
if (not case_changed) or (source != "html"):
|
||||
# Current case has not changed, update children
|
||||
group_errors = self.update_state( trans,
|
||||
input.cases[current_case].inputs,
|
||||
group_state,
|
||||
incoming,
|
||||
prefix=group_prefix,
|
||||
context=context,
|
||||
source=source,
|
||||
update_only=update_only,
|
||||
old_errors=group_old_errors,
|
||||
item_callback=item_callback )
|
||||
if input.test_param.name in group_old_errors and not test_param_error:
|
||||
test_param_error = group_old_errors[ input.test_param.name ]
|
||||
if test_param_error:
|
||||
group_errors[ input.test_param.name ] = test_param_error
|
||||
if group_errors:
|
||||
errors[ input.name ] = group_errors
|
||||
# Store the current case in a special value
|
||||
group_state['__current_case__'] = current_case
|
||||
# Store the value of the test element
|
||||
group_state[ input.test_param.name ] = value
|
||||
elif isinstance( input, Section ):
|
||||
group_state = state[input.name]
|
||||
group_old_errors = old_errors.get( input.name, {} )
|
||||
group_prefix = "%s|" % ( key )
|
||||
group_errors = self.update_state( trans,
|
||||
input.inputs,
|
||||
group_state,
|
||||
incoming,
|
||||
prefix=group_prefix,
|
||||
context=context,
|
||||
source=source,
|
||||
update_only=update_only,
|
||||
old_errors=group_old_errors,
|
||||
item_callback=item_callback )
|
||||
if group_errors:
|
||||
errors[ input.name ] = group_errors
|
||||
elif isinstance( input, UploadDataset ):
|
||||
group_state = state[input.name]
|
||||
group_errors = []
|
||||
group_old_errors = old_errors.get( input.name, None )
|
||||
any_group_errors = False
|
||||
d_type = input.get_datatype( trans, context )
|
||||
writable_files = d_type.writable_files
|
||||
# remove extra files
|
||||
while len( group_state ) > len( writable_files ):
|
||||
del group_state[-1]
|
||||
if group_old_errors:
|
||||
del group_old_errors[-1]
|
||||
# Update state
|
||||
max_index = -1
|
||||
for i, rep_state in enumerate( group_state ):
|
||||
rep_index = rep_state['__index__']
|
||||
max_index = max( max_index, rep_index )
|
||||
rep_prefix = "%s_%d|" % ( key, rep_index )
|
||||
if group_old_errors:
|
||||
rep_old_errors = group_old_errors[i]
|
||||
else:
|
||||
rep_old_errors = {}
|
||||
rep_errors = self.update_state( trans,
|
||||
input.inputs,
|
||||
rep_state,
|
||||
incoming,
|
||||
prefix=rep_prefix,
|
||||
context=context,
|
||||
source=source,
|
||||
update_only=update_only,
|
||||
old_errors=rep_old_errors,
|
||||
item_callback=item_callback )
|
||||
if rep_errors:
|
||||
any_group_errors = True
|
||||
group_errors.append( rep_errors )
|
||||
else:
|
||||
group_errors.append( {} )
|
||||
# Add new fileupload as needed
|
||||
offset = 1
|
||||
while len( writable_files ) > len( group_state ):
|
||||
new_state = {}
|
||||
new_state['__index__'] = max_index + offset
|
||||
offset += 1
|
||||
self.fill_in_new_state( trans, input.inputs, new_state, context )
|
||||
group_state.append( new_state )
|
||||
if any_group_errors:
|
||||
group_errors.append( {} )
|
||||
# Were there *any* errors for any repetition?
|
||||
if any_group_errors:
|
||||
errors[input.name] = group_errors
|
||||
else:
|
||||
if key not in incoming \
|
||||
and "__force_update__" + key not in incoming \
|
||||
and update_only:
|
||||
# No new value provided, and we are only updating, so keep
|
||||
# the old value (which should already be in the state) and
|
||||
# preserve the old error message.
|
||||
if input.name in old_errors:
|
||||
errors[ input.name ] = old_errors[ input.name ]
|
||||
else:
|
||||
incoming_value = get_incoming_value( incoming, key, None )
|
||||
value, error = check_param( trans, input, incoming_value, context, source=source )
|
||||
# If a callback was provided, allow it to process the value
|
||||
input_name = input.name
|
||||
if item_callback:
|
||||
old_value = state.get( input_name, None )
|
||||
value, error = item_callback( trans, key, input, value, error, old_value, context )
|
||||
if error:
|
||||
errors[ input_name ] = error
|
||||
|
||||
state[ input_name ] = value
|
||||
meta_properties = self.__meta_properties_for_state( key, incoming, incoming_value, value, input_name )
|
||||
state.update( meta_properties )
|
||||
return errors
|
||||
|
||||
def __remove_meta_properties( self, incoming ):
|
||||
result = incoming.copy()
|
||||
meta_property_suffixes = [
|
||||
@@ -1908,19 +1518,6 @@ class Tool( object, Dictifiable ):
|
||||
del result[ key ]
|
||||
return result
|
||||
|
||||
def __meta_properties_for_state( self, key, incoming, incoming_val, state_val, input_name ):
|
||||
meta_properties = {}
|
||||
meta_property_suffixes = [
|
||||
"__multirun__",
|
||||
"__collection_multirun__",
|
||||
]
|
||||
for meta_property_suffix in meta_property_suffixes:
|
||||
multirun_key = "%s|%s" % ( key, meta_property_suffix )
|
||||
if multirun_key in incoming:
|
||||
multi_value = incoming[ multirun_key ]
|
||||
meta_properties[ "%s|%s" % ( input_name, meta_property_suffix ) ] = multi_value
|
||||
return meta_properties
|
||||
|
||||
@property
|
||||
def params_with_missing_data_table_entry( self ):
|
||||
"""
|
||||
@@ -2762,11 +2359,6 @@ class Tool( object, Dictifiable ):
|
||||
except Exception, error:
|
||||
trans.response.status = 500
|
||||
return { 'error': str(error) }
|
||||
|
||||
# can't rerun upload, external data sources, et cetera. workflow compatible will proxy this for now
|
||||
# if not self.is_workflow_compatible:
|
||||
# trans.response.status = 500
|
||||
# return { 'error': 'The \'%s\' tool does currently not support re-running.' % self.name }
|
||||
return message
|
||||
|
||||
def get_default_history_by_trans( self, trans, create=False ):
|
||||
|
||||
@@ -477,7 +477,7 @@ class LibraryDatasetsController( BaseAPIController, UsesVisualizationMixin ):
|
||||
tool_id = 'upload1'
|
||||
tool = trans.app.toolbox.get_tool( tool_id )
|
||||
state = tool.new_state( trans )
|
||||
tool.update_state( trans, tool.inputs_by_page[ 0 ], state.inputs, kwd )
|
||||
tool.populate_state( trans, tool.inputs, state.inputs, kwd )
|
||||
tool_params = state.inputs
|
||||
dataset_upload_inputs = []
|
||||
for input in tool.inputs.itervalues():
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import urllib
|
||||
|
||||
from galaxy.exceptions import ObjectNotFound
|
||||
from galaxy.exceptions import InternalServerError
|
||||
from galaxy import exceptions
|
||||
from galaxy import web, util
|
||||
from galaxy import managers
|
||||
from galaxy.web import _future_expose_api_anonymous_and_sessionless as expose_api_anonymous_and_sessionless
|
||||
@@ -72,7 +71,7 @@ class ToolsController( BaseAPIController, UsesVisualizationMixin ):
|
||||
try:
|
||||
return self.app.toolbox.to_dict( trans, in_panel=in_panel, trackster=trackster)
|
||||
except Exception:
|
||||
raise InternalServerError( "Error: Could not convert toolbox to dictionary" )
|
||||
raise exceptions.InternalServerError( "Error: Could not convert toolbox to dictionary" )
|
||||
|
||||
@expose_api_anonymous_and_sessionless
|
||||
def show( self, trans, id, **kwd ):
|
||||
@@ -206,7 +205,7 @@ class ToolsController( BaseAPIController, UsesVisualizationMixin ):
|
||||
trans.response.headers[ "Content-Disposition" ] = 'attachment; filename="%s.tgz"' % ( id )
|
||||
return download_file
|
||||
|
||||
@web.expose_api_anonymous
|
||||
@expose_api_anonymous
|
||||
def create( self, trans, payload, **kwd ):
|
||||
"""
|
||||
POST /api/tools
|
||||
@@ -223,13 +222,12 @@ class ToolsController( BaseAPIController, UsesVisualizationMixin ):
|
||||
tool_version = payload.get( 'tool_version', None )
|
||||
tool = trans.app.toolbox.get_tool( payload[ 'tool_id' ] , tool_version ) if 'tool_id' in payload else None
|
||||
if not tool or not tool.allow_user_access( trans.user ):
|
||||
trans.response.status = 404
|
||||
return { "message": { "type": "error", "text" : trans.app.model.Dataset.conversion_messages.NO_TOOL } }
|
||||
raise exceptions.MessageException( 'Tool not found or not accessible.' )
|
||||
|
||||
# Set running history from payload parameters.
|
||||
# History not set correctly as part of this API call for
|
||||
# dataset upload.
|
||||
history_id = payload.get("history_id", None)
|
||||
history_id = payload.get('history_id', None)
|
||||
if history_id:
|
||||
decoded_id = self.decode_id( history_id )
|
||||
target_history = self.history_manager.get_owned( decoded_id, trans.user, current_history=trans.history )
|
||||
@@ -240,7 +238,7 @@ class ToolsController( BaseAPIController, UsesVisualizationMixin ):
|
||||
inputs = payload.get( 'inputs', {} )
|
||||
# Find files coming in as multipart file data and add to inputs.
|
||||
for k, v in payload.iteritems():
|
||||
if k.startswith("files_") or k.startswith("__files_"):
|
||||
if k.startswith('files_') or k.startswith('__files_'):
|
||||
inputs[k] = v
|
||||
|
||||
# for inputs that are coming from the Library, copy them into the history
|
||||
@@ -254,43 +252,22 @@ class ToolsController( BaseAPIController, UsesVisualizationMixin ):
|
||||
for k, v in input_patch.iteritems():
|
||||
inputs[k] = v
|
||||
|
||||
# HACK: add run button so that tool.handle_input will run tool.
|
||||
inputs['runtool_btn'] = 'Execute'
|
||||
# TODO: encode data ids and decode ids.
|
||||
# TODO: handle dbkeys
|
||||
params = util.Params( inputs, sanitize=False )
|
||||
# process_state will be 'populate' or 'update'. When no tool
|
||||
# state is specified in input - it will be 'populate', and
|
||||
# tool will fully expand repeat and conditionals when building
|
||||
# up state. If tool state is found in input
|
||||
# parameters,process_state will be 'update' and complex
|
||||
# submissions (with repeats and conditionals) must be built up
|
||||
# over several iterative calls to the API - mimicing behavior
|
||||
# of web controller (though frankly API never returns
|
||||
# tool_state so this "legacy" behavior is probably impossible
|
||||
# through API currently).
|
||||
incoming = params.__dict__
|
||||
process_state = "update" if "tool_state" in incoming else "populate"
|
||||
template, vars = tool.handle_input( trans, incoming, history=target_history, process_state=process_state, source="json" )
|
||||
if 'errors' in vars:
|
||||
trans.response.status = 400
|
||||
return { "message": { "type": "error", "data" : vars[ 'errors' ] } }
|
||||
vars = tool.handle_input( trans, incoming, history=target_history, source='json' )
|
||||
|
||||
# TODO: check for errors and ensure that output dataset(s) are available.
|
||||
output_datasets = vars.get( 'out_data', [] )
|
||||
rval = {
|
||||
"outputs": [],
|
||||
"output_collections": [],
|
||||
"jobs": [],
|
||||
"implicit_collections": [],
|
||||
}
|
||||
rval = { 'outputs': [], 'output_collections': [], 'jobs': [], 'implicit_collections': [] }
|
||||
|
||||
job_errors = vars.get( 'job_errors', [] )
|
||||
if job_errors:
|
||||
# If we are here - some jobs were successfully executed but some failed.
|
||||
rval[ "errors" ] = job_errors
|
||||
rval[ 'errors' ] = job_errors
|
||||
|
||||
outputs = rval[ "outputs" ]
|
||||
outputs = rval[ 'outputs' ]
|
||||
# TODO:?? poss. only return ids?
|
||||
for output_name, output in output_datasets:
|
||||
output_dict = output.to_dict()
|
||||
@@ -324,7 +301,7 @@ class ToolsController( BaseAPIController, UsesVisualizationMixin ):
|
||||
id = urllib.unquote_plus( id )
|
||||
tool = self.app.toolbox.get_tool( id, tool_version )
|
||||
if not tool or not tool.allow_user_access( user ):
|
||||
raise ObjectNotFound("Could not find tool with id '%s'" % id)
|
||||
raise exceptions.ObjectNotFound("Could not find tool with id '%s'" % id)
|
||||
return tool
|
||||
|
||||
def _rerun_tool( self, trans, payload, **kwargs ):
|
||||
|
||||
@@ -5,7 +5,7 @@ Upload class
|
||||
import logging
|
||||
import urllib
|
||||
|
||||
from galaxy import jobs, util, web
|
||||
from galaxy import jobs, web
|
||||
from galaxy.util import Params
|
||||
from galaxy.util.hash_util import hmac_new
|
||||
from galaxy.web.base.controller import BaseUIController
|
||||
@@ -32,7 +32,6 @@ class ASync( BaseUIController ):
|
||||
if not kwd:
|
||||
return trans.response.send_redirect( "/index" )
|
||||
|
||||
history = trans.get_history( create=True )
|
||||
params = Params(kwd, sanitize=False)
|
||||
STATUS = params.STATUS
|
||||
URL = params.URL
|
||||
@@ -143,4 +142,4 @@ class ASync( BaseUIController ):
|
||||
|
||||
trans.sa_session.flush()
|
||||
|
||||
return trans.fill_template( 'tool_executed.mako', history=history, toolbox=toolbox, tool=tool, util=util, out_data={}, num_jobs=1, job_errors=[] )
|
||||
return trans.fill_template( 'root/tool_runner.mako', out_data={}, num_jobs=1, job_errors=[] )
|
||||
|
||||
@@ -1044,7 +1044,7 @@ class LibraryCommon( BaseUIController, UsesFormDefinitionsMixin, UsesExtendedMet
|
||||
tool_id = 'upload1'
|
||||
tool = trans.app.toolbox.get_tool( tool_id )
|
||||
state = tool.new_state( trans )
|
||||
tool.update_state( trans, tool.inputs_by_page[0], state.inputs, kwd )
|
||||
tool.populate_state( trans, tool.inputs, state.inputs, kwd )
|
||||
tool_params = state.inputs
|
||||
dataset_upload_inputs = []
|
||||
for input_name, input in tool.inputs.iteritems():
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
Upload class
|
||||
Controller handles external tool related requests
|
||||
"""
|
||||
import logging
|
||||
|
||||
@@ -9,23 +9,13 @@ from markupsafe import escape
|
||||
|
||||
import galaxy.util
|
||||
from galaxy import web
|
||||
from galaxy.tools import DefaultToolState
|
||||
from galaxy.tools import DataSourceTool
|
||||
from galaxy.tools.actions import upload_common
|
||||
from galaxy.util.bunch import Bunch
|
||||
from galaxy.web import error, url_for
|
||||
from galaxy.web.base.controller import BaseUIController
|
||||
|
||||
log = logging.getLogger( __name__ )
|
||||
|
||||
|
||||
class AddFrameData:
|
||||
def __init__( self ):
|
||||
self.wiki_url = None
|
||||
self.debug = None
|
||||
self.from_noframe = None
|
||||
|
||||
|
||||
class ToolRunner( BaseUIController ):
|
||||
|
||||
# Hack to get biomart to work, ideally, we could pass tool_id to biomart and receive it back
|
||||
@@ -45,71 +35,48 @@ class ToolRunner( BaseUIController ):
|
||||
"""Catches the tool id and redirects as needed"""
|
||||
return self.index(trans, tool_id=tool_id, **kwd)
|
||||
|
||||
def __get_tool_components( self, tool_id, tool_version=None, get_loaded_tools_by_lineage=False, set_selected=False ):
|
||||
return self.get_toolbox().get_tool_components( tool_id, tool_version, get_loaded_tools_by_lineage, set_selected )
|
||||
def __get_tool( self, tool_id, tool_version=None, get_loaded_tools_by_lineage=False, set_selected=False ):
|
||||
tool_version_select_field, tools, tool = self.get_toolbox().get_tool_components( tool_id, tool_version, get_loaded_tools_by_lineage, set_selected )
|
||||
return tool
|
||||
|
||||
@web.expose
|
||||
def index( self, trans, tool_id=None, from_noframe=None, **kwd ):
|
||||
# No tool id passed, redirect to main page
|
||||
# tool id not available, redirect to main page
|
||||
if tool_id is None:
|
||||
return trans.response.send_redirect( url_for( controller="root", action="welcome" ) )
|
||||
tool_version_select_field, tools, tool = self.__get_tool_components( tool_id )
|
||||
# No tool matching the tool id, display an error (shouldn't happen)
|
||||
return trans.response.send_redirect( url_for( controller='root', action='welcome' ) )
|
||||
tool = self.__get_tool( tool_id )
|
||||
# tool id is not matching, display an error
|
||||
if not tool or not tool.allow_user_access( trans.user ):
|
||||
log.error( "index called with tool id '%s' but no such tool exists", tool_id )
|
||||
trans.log_event( "Tool id '%s' does not exist" % tool_id )
|
||||
log.error( 'index called with tool id \'%s\' but no such tool exists', tool_id )
|
||||
trans.log_event( 'Tool id \'%s\' does not exist' % tool_id )
|
||||
trans.response.status = 404
|
||||
return trans.show_error_message("Tool '%s' does not exist." % ( escape(tool_id) ))
|
||||
return trans.show_error_message('Tool \'%s\' does not exist.' % ( escape(tool_id) ))
|
||||
if tool.require_login and not trans.user:
|
||||
message = "You must be logged in to use this tool."
|
||||
status = "info"
|
||||
redirect = url_for( controller='tool_runner', action='index', tool_id=tool_id, **kwd )
|
||||
return trans.response.send_redirect( url_for( controller='user',
|
||||
action='login',
|
||||
cntrller='user',
|
||||
message=message,
|
||||
status=status,
|
||||
status='info',
|
||||
message='You must be logged in to use this tool.',
|
||||
redirect=redirect ) )
|
||||
if tool.tool_type == 'default':
|
||||
return trans.response.send_redirect( url_for( controller="root", tool_id=tool_id ) )
|
||||
return trans.response.send_redirect( url_for( controller='root', tool_id=tool_id ) )
|
||||
|
||||
def _validated_params_for( kwd ):
|
||||
params = galaxy.util.Params( kwd, sanitize=False ) # Sanitize parameters when substituting into command line via input wrappers
|
||||
# do param translation here, used by datasource tools
|
||||
if tool.input_translator:
|
||||
tool.input_translator.translate( params )
|
||||
return params
|
||||
|
||||
params = _validated_params_for( kwd )
|
||||
# execute tool without displaying form (used for datasource tools)
|
||||
params = galaxy.util.Params( kwd, sanitize=False )
|
||||
# do param translation here, used by datasource tools
|
||||
if tool.input_translator:
|
||||
tool.input_translator.translate( params )
|
||||
# We may be visiting Galaxy for the first time ( e.g., sending data from UCSC ),
|
||||
# so make sure to create a new history if we've never had one before.
|
||||
history = tool.get_default_history_by_trans( trans, create=True )
|
||||
try:
|
||||
template, vars = tool.handle_input( trans, params.__dict__ )
|
||||
except KeyError:
|
||||
# This error indicates (or at least can indicate) there was a
|
||||
# problem with the stored tool_state - it is incompatible with
|
||||
# this variant of the tool - possibly because the tool changed
|
||||
# or because the tool version changed.
|
||||
del kwd[ "tool_state" ]
|
||||
params = _validated_params_for( kwd )
|
||||
template, vars = tool.handle_input( trans, params.__dict__ )
|
||||
vars = tool.handle_input( trans, params.__dict__, history=history )
|
||||
except Exception, e:
|
||||
error( str( e ) )
|
||||
if len( params ) > 0:
|
||||
trans.log_event( "Tool params: %s" % ( str( params ) ), tool_id=tool_id )
|
||||
add_frame = AddFrameData()
|
||||
add_frame.debug = trans.debug
|
||||
if from_noframe is not None:
|
||||
add_frame.wiki_url = trans.app.config.wiki_url
|
||||
add_frame.from_noframe = True
|
||||
return trans.fill_template( template,
|
||||
history=history,
|
||||
toolbox=self.get_toolbox(),
|
||||
tool_version_select_field=tool_version_select_field,
|
||||
tool=tool,
|
||||
util=galaxy.util,
|
||||
add_frame=add_frame,
|
||||
form_input_auto_focus=True,
|
||||
**vars )
|
||||
trans.log_event( 'Tool params: %s' % ( str( params ) ), tool_id=tool_id )
|
||||
return trans.fill_template( 'root/tool_runner.mako', **vars )
|
||||
|
||||
@web.expose
|
||||
def rerun( self, trans, id=None, job_id=None, **kwd ):
|
||||
@@ -118,7 +85,6 @@ class ToolRunner( BaseUIController ):
|
||||
the dataset, extract the parameters, and display the appropriate tool
|
||||
form with parameters already filled in.
|
||||
"""
|
||||
|
||||
if job_id is None:
|
||||
if not id:
|
||||
error( "'id' parameter is required" )
|
||||
@@ -155,10 +121,7 @@ class ToolRunner( BaseUIController ):
|
||||
"""
|
||||
if tool_id is None:
|
||||
return trans.response.send_redirect( url_for( controller="root", action="welcome" ) )
|
||||
tool_version_select_field, tools, tool = self.__get_tool_components( tool_id,
|
||||
tool_version=None,
|
||||
get_loaded_tools_by_lineage=False,
|
||||
set_selected=False )
|
||||
tool = self.__get_tool( tool_id )
|
||||
# No tool matching the tool id, display an error (shouldn't happen)
|
||||
if not tool:
|
||||
log.error( "data_source_redirect called with tool id '%s' but no such tool exists", tool_id )
|
||||
@@ -178,95 +141,3 @@ class ToolRunner( BaseUIController ):
|
||||
return trans.show_error_message( "Required URL for redirection missing" )
|
||||
trans.log_event( "Redirecting to: %s" % redirect_url )
|
||||
return trans.fill_template( 'root/redirect.mako', redirect_url=redirect_url )
|
||||
|
||||
@web.json
|
||||
def upload_async_create( self, trans, tool_id=None, **kwd ):
|
||||
"""
|
||||
Precreate datasets for asynchronous uploading.
|
||||
"""
|
||||
cntrller = kwd.get( 'cntrller', '' )
|
||||
roles = kwd.get( 'roles', False )
|
||||
if roles:
|
||||
# The user associated the DATASET_ACCESS permission on the uploaded datasets with 1 or more roles.
|
||||
# We need to ensure that the roles are legitimately derived from the roles associated with the LIBRARY_ACCESS
|
||||
# permission if the library is not public ( this should always be the case since any ill-legitimate roles
|
||||
# were filtered out of the roles displayed on the upload form. In addition, we need to ensure that the user
|
||||
# did not associated roles that would make the dataset in-accessible by everyone.
|
||||
library_id = trans.app.security.decode_id( kwd.get( 'library_id', '' ) )
|
||||
vars = dict( DATASET_ACCESS_in=roles )
|
||||
permissions, in_roles, error, msg = trans.app.security_agent.derive_roles_from_access( trans, library_id, cntrller, library=True, **vars )
|
||||
if error:
|
||||
return [ 'error', msg ]
|
||||
|
||||
def create_dataset( name ):
|
||||
ud = Bunch( name=name, file_type=None, dbkey=None )
|
||||
if nonfile_params.get( 'folder_id', False ):
|
||||
replace_id = nonfile_params.get( 'replace_id', None )
|
||||
if replace_id not in [ None, 'None' ]:
|
||||
replace_dataset = trans.sa_session.query( trans.app.model.LibraryDataset ).get( trans.security.decode_id( replace_id ) )
|
||||
else:
|
||||
replace_dataset = None
|
||||
# FIXME: instead of passing params here ( chiech have been process by util.Params(), the original kwd
|
||||
# should be passed so that complex objects that may have been included in the initial request remain.
|
||||
library_bunch = upload_common.handle_library_params( trans, nonfile_params, nonfile_params.folder_id, replace_dataset )
|
||||
else:
|
||||
library_bunch = None
|
||||
return upload_common.new_upload( trans, cntrller, ud, library_bunch=library_bunch, state=trans.app.model.HistoryDatasetAssociation.states.UPLOAD )
|
||||
tool = self.get_toolbox().get_tool( tool_id )
|
||||
if not tool:
|
||||
return False # bad tool_id
|
||||
nonfile_params = galaxy.util.Params( kwd, sanitize=False )
|
||||
if kwd.get( 'tool_state', None ) not in ( None, 'None' ):
|
||||
encoded_state = galaxy.util.string_to_object( kwd["tool_state"] )
|
||||
tool_state = DefaultToolState()
|
||||
tool_state.decode( encoded_state, tool, trans.app )
|
||||
else:
|
||||
tool_state = tool.new_state( trans )
|
||||
tool.update_state( trans, tool.inputs, tool_state.inputs, kwd, update_only=True )
|
||||
datasets = []
|
||||
dataset_upload_inputs = []
|
||||
for input_name, input in tool.inputs.iteritems():
|
||||
if input.type == "upload_dataset":
|
||||
dataset_upload_inputs.append( input )
|
||||
assert dataset_upload_inputs, Exception( "No dataset upload groups were found." )
|
||||
for dataset_upload_input in dataset_upload_inputs:
|
||||
d_type = dataset_upload_input.get_datatype( trans, kwd )
|
||||
if d_type.composite_type is not None:
|
||||
datasets.append( create_dataset( dataset_upload_input.get_composite_dataset_name( kwd ) ) )
|
||||
else:
|
||||
params = Bunch( ** tool_state.inputs[dataset_upload_input.name][0] )
|
||||
if params.file_data not in [ None, "" ]:
|
||||
name = params.file_data
|
||||
if name.count('/'):
|
||||
name = name.rsplit('/', 1)[1]
|
||||
if name.count('\\'):
|
||||
name = name.rsplit('\\', 1)[1]
|
||||
datasets.append( create_dataset( name ) )
|
||||
if params.url_paste not in [ None, "" ]:
|
||||
url_paste = params.url_paste.replace( '\r', '' ).split( '\n' )
|
||||
url = False
|
||||
for line in url_paste:
|
||||
line = line.rstrip( '\r\n' ).strip()
|
||||
if not line:
|
||||
continue
|
||||
elif line.lower().startswith( 'http://' ) or line.lower().startswith( 'ftp://' ) or line.lower().startswith( 'https://' ):
|
||||
url = True
|
||||
datasets.append( create_dataset( line ) )
|
||||
else:
|
||||
if url:
|
||||
continue # non-url when we've already processed some urls
|
||||
else:
|
||||
# pasted data
|
||||
datasets.append( create_dataset( 'Pasted Entry' ) )
|
||||
break
|
||||
return [ d.id for d in datasets ]
|
||||
|
||||
@web.expose
|
||||
def upload_async_message( self, trans, **kwd ):
|
||||
# might be more appropriate in a different controller
|
||||
msg = """<p>Your upload has been queued. History entries that are still uploading will be blue, and turn green upon completion.</p>
|
||||
<p><b>Please do not use your browser\'s "stop" or "reload" buttons until the upload is complete, or it may be interrupted.</b></p>
|
||||
<p>You may safely continue to use Galaxy while the upload is in progress. Using "stop" and "reload" on pages other than Galaxy is also safe.</p>
|
||||
"""
|
||||
# return trans.show_message( msg, refresh_frames=[ 'history' ] )
|
||||
return trans.show_message( msg )
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"form-view.js","sources":["../../../src/mvc/form/form-view.js"],"names":["define","Utils","Portlet","Ui","FormSection","FormData","Backbone","View","extend","initialize","options","this","optionsDefault","is_workflow","initial_errors","cls","merge","console","debug","galaxy","parent","Galaxy","modal","Modal","setElement","_build","update","new_model","self","data","matchModel","input_id","node","input","input_list","_","isEqual","field","field_list","new_options","indexOf","type","i","opt","length","push","label","value","trigger","wait","active","is_dynamic","unwait","reciept","$el","empty","append","highlight","message","silent","input_element","element_list","error","top","$panel","parents","filter","$","css","first","animate","scrollTop","offset","errors","error_messages","matchResponse","off","_renderForm","create","current_check","checksum","on","new_check","onchange","reset","Message","section","inputs","remove","portlet","icon","title","operations","buttons","addClass","persistent","status"],"mappings":"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"}
|
||||
{"version":3,"file":"form-view.js","sources":["../../../src/mvc/form/form-view.js"],"names":["define","Utils","Portlet","Ui","FormSection","FormData","Backbone","View","extend","initialize","options","this","optionsDefault","is_workflow","initial_errors","cls","merge","console","debug","galaxy","parent","Galaxy","modal","Modal","setElement","_build","update","new_model","self","data","matchModel","input_id","node","input","input_list","_","isEqual","field","field_list","new_options","indexOf","type","i","opt","length","push","label","value","trigger","wait","active","is_dynamic","unwait","highlight","message","silent","input_element","element_list","error","top","$panel","$el","parents","filter","$","css","first","animate","scrollTop","offset","errors","error_messages","matchResponse","off","_renderForm","create","current_check","checksum","on","new_check","onchange","reset","Message","section","inputs","remove","portlet","icon","title","operations","buttons","append","addClass","empty","persistent","status"],"mappings":"AAGAA,QAAQ,cAAe,oBAAqB,iBACpC,wBAAyB,sBAC7B,SAASC,EAAOC,EAASC,EAAIC,EAAaC,GAG1C,MAAOC,UAASC,KAAKC,QAEjBC,WAAY,SAASC,GAEjBC,KAAKC,gBAEDC,aAAkB,EAElBC,gBAAkB,EAElBC,IAAkB,sBAItBJ,KAAKD,QAAUT,EAAMe,MAAMN,EAASC,KAAKC,gBAGzCK,QAAQC,MAAMP,KAAKD,QAGnB,IAAIS,GAASC,OAAOC,MAEhBV,MAAKW,MADLH,GAAUA,EAAOG,MACJH,EAAOG,MAEP,GAAInB,GAAGoB,MAAMhB,KAI9BI,KAAKa,WAAW,UAGhBb,KAAKc,UAITC,OAAQ,SAASC,GACb,GAAIC,GAAOjB,IACXA,MAAKkB,KAAKC,WAAWH,EAAW,SAASI,EAAUC,GAC/C,GAAIC,GAAQL,EAAKM,WAAWH,EAC5B,IAAIE,GAASA,EAAMvB,UACVyB,EAAEC,QAAQH,EAAMvB,QAASsB,EAAKtB,SAAU,CAEzCuB,EAAMvB,QAAUsB,EAAKtB,OAGrB,IAAI2B,GAAQT,EAAKU,WAAWP,EAC5B,IAAIM,EAAMX,OAAQ,CACd,GAAIa,KACJ,IAAuE,KAAjE,OAAQ,kBAAmB,cAAeC,QAAQP,EAAMQ,MAC1DF,EAAcN,EAAMvB,YAEpB,KAAK,GAAIgC,KAAKV,GAAKtB,QAAS,CACxB,GAAIiC,GAAMX,EAAKtB,QAAQgC,EACnBC,GAAIC,OAAS,GACbL,EAAYM,MACRC,MAASH,EAAI,GACbI,MAASJ,EAAI,KAK7BN,EAAMX,OAAOa,GACbF,EAAMW,QAAQ,UACd/B,QAAQC,MAAM,wBAA0Ba,QAQ5DkB,KAAM,SAASC,GACX,IAAK,GAAIR,KAAK/B,MAAKuB,WAAY,CAC3B,GAAIG,GAAQ1B,KAAK2B,WAAWI,GACxBT,EAAQtB,KAAKuB,WAAWQ,EACxBT,GAAMkB,YAAcd,EAAMY,MAAQZ,EAAMe,SACpCF,EACAb,EAAMY,OAENZ,EAAMe,YAQtBC,UAAW,SAAUtB,EAAUuB,EAASC,GAEpC,GAAIC,GAAgB7C,KAAK8C,aAAa1B,EAGtC,IAAIyB,IAEAA,EAAcE,MAAMJ,GAAW,iCAG/B3C,KAAKqC,QAAQ,SAAUjB,IAGlBwB,GACD,GAAI3B,MAAM+B,IAAK,CACX,GAAIC,GAASjD,KAAKkD,IAAIC,UAAUC,OAAO,WACnC,MAAkC,QAA3BC,EAAErD,MAAMsD,IAAI,cACpBC,OACHN,GAAOO,SAAUC,UAAYR,EAAOQ,YAAcZ,EAAcK,IAAIQ,SAASV,IAAM,IAAM,SAEzFK,GAAE,cAAcG,SAAUC,UAAYZ,EAAcK,IAAIQ,SAASV,IAAM,IAAM,MAQ7FW,OAAQ,SAAS5D,GAKb,GAHAC,KAAKqC,QAAQ,SAGTtC,GAAWA,EAAQ4D,OAAQ,CAC3B,GAAIC,GAAiB5D,KAAKkB,KAAK2C,cAAc9D,EAAQ4D,OACrD,KAAK,GAAIvC,KAAYpB,MAAK8C,aAAc,CACpC,CAAY9C,KAAK8C,aAAa1B,GAC1BwC,EAAexC,IACfpB,KAAK0C,UAAUtB,EAAUwC,EAAexC,IAAW,MAQnEN,OAAQ,WAEJ,GAAIG,GAAOjB,IAGXA,MAAK8D,IAAI,UACT9D,KAAK8D,IAAI,SAGT9D,KAAK2B,cAGL3B,KAAKuB,cAGLvB,KAAK8C,gBAGL9C,KAAKkB,KAAO,GAAIxB,GAASM,MAGzBA,KAAK+D,cAGL/D,KAAKkB,KAAK8C,SAGNhE,KAAKD,QAAQI,gBACbH,KAAK2D,OAAO3D,KAAKD,QAIrB,IAAIkE,GAAgBjE,KAAKkB,KAAKgD,UAC9BlE,MAAKmE,GAAG,SAAU,WACd,GAAIC,GAAYnD,EAAKC,KAAKgD,UACtBE,IAAaH,IACbA,EAAgBG,EAChBnD,EAAKlB,QAAQsE,UAAYpD,EAAKlB,QAAQsE,cAK9CrE,KAAKmE,GAAG,QAAS,WACb,IAAK,GAAIpC,KAAK/B,MAAK8C,aACf9C,KAAK8C,aAAaf,GAAGuC,WAOjCP,YAAa,WAET/D,KAAK2C,QAAU,GAAInD,GAAG+E,QAGtBvE,KAAKwE,QAAU,GAAI/E,GAAYG,KAAKI,MAChCyE,OAASzE,KAAKD,QAAQ0E,SAI1BpB,EAAG,YAAaqB,SAGhB1E,KAAK2E,QAAU,GAAIpF,GAAQK,MACvBgF,KAAc,YACdC,MAAc7E,KAAKD,QAAQ8E,MAC3BzE,IAAcJ,KAAKD,QAAQK,IAC3B0E,WAAc9E,KAAKD,QAAQ+E,WAC3BC,QAAc/E,KAAKD,QAAQgF,UAI/B/E,KAAK2E,QAAQK,OAAOhF,KAAK2C,QAAQO,IAAI+B,SAAS,kBAG9CjF,KAAK2E,QAAQK,OAAOhF,KAAKwE,QAAQtB,KAGjClD,KAAKkD,IAAIgC,QACTlF,KAAKkD,IAAI8B,OAAOhF,KAAK2E,QAAQzB,KAGzBlD,KAAKD,QAAQ4C,SACb3C,KAAK2C,QAAQ5B,QACToE,YAAc,EACdC,OAAc,UACdzC,QAAc3C,KAAKD,QAAQ4C,UAKnCrC,QAAQC,MAAM"}
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
{"version":3,"file":"tools-jobs.js","sources":["../../../src/mvc/tools/tools-jobs.js"],"names":["define","Utils","ToolTemplate","submit","form","options","callback","self","this","job_def","tool_id","id","tool_version","version","inputs","data","create","trigger","_validation","console","debug","request","type","url","galaxy_config","root","success","response","reciept","_refreshHdas","error","message","error_messages","matchResponse","input_id","highlight","modal","show","title","body","buttons","Close","hide","job_inputs","batch_n","batch_src","job_input_id","input_value","match","input_field","field_list","input_def","input_list","optional","batch","n","values","length","src","detailIds","parent","Galaxy","currHistoryPanel","refreshContents"],"mappings":"AAGAA,QAAQ,cAAe,4BAA6B,SAASC,EAAOC,GACpE,OACIC,OAAQ,SAASC,EAAMC,EAASC,GAE5B,GAAIC,GAAOC,KAGPC,GACAC,QAAkBL,EAAQM,GAC1BC,aAAkBP,EAAQQ,QAC1BC,OAAkBV,EAAKW,KAAKC,SAOhC,OAHAZ,GAAKa,QAAQ,SAGRT,KAAKU,YAAYd,EAAMK,IAO5BU,QAAQC,MAAMX,OAGdR,GAAMoB,SACFC,KAAU,OACVC,IAAUC,cAAcC,KAAO,YAC/BV,KAAUN,EACViB,QAAU,SAASC,GACfrB,GAAYA,IACZF,EAAKwB,QAAQ1B,EAAawB,QAAQC,IAElCpB,EAAKsB,gBAETC,MAAU,SAASH,GAEf,GADArB,GAAYA,IACRqB,GAAYA,EAASI,SAAWJ,EAASI,QAAQhB,KAAM,CACvD,GAAIiB,GAAiB5B,EAAKW,KAAKkB,cAAcN,EAASI,QAAQhB,KAC9D,KAAK,GAAImB,KAAYF,GAAgB,CACjC5B,EAAK+B,UAAUD,EAAUF,EAAeE,GACxC,YAIJf,SAAQC,MAAMO,GACdA,GAAYvB,EAAKgC,MAAMC,MACnBC,MAAU,wBACVC,KAAUrC,EAAa4B,MAAMrB,GAC7B+B,SACIC,MAAU,WACNrC,EAAKgC,MAAMM,gBAnC/BvB,QAAQC,MAAM,qEACdd,GAAYA,OA6CpBY,YAAa,SAASd,EAAMK,GAExB,GAAIkC,GAAalC,EAAQK,OAGrB8B,EAAU,GACVC,EAAY,IAGhB,KAAK,GAAIC,KAAgBH,GAAY,CAEjC,GAAII,GAAcJ,EAAWG,GAGzBZ,EAAW9B,EAAKW,KAAKiC,MAAMF,GAC3BG,EAAc7C,EAAK8C,WAAWhB,GAC9BiB,EAAY/C,EAAKgD,WAAWlB,EAGhC,IAAKA,GAAaiB,GAAcF,EAAhC,CAMA,IAAKE,EAAUE,UAA2B,MAAfN,EAEvB,MADA3C,GAAK+B,UAAUD,IACR,CAIX,IAAIa,GAAeA,EAAYO,MAAO,CAElC,GAAIC,GAAIR,EAAYS,OAAOC,OAGvBC,EAAM,IAMV,IALIH,EAAI,IACJG,EAAMX,EAAYS,OAAO,IAAMT,EAAYS,OAAO,GAAGE,KAIrDA,EACA,GAAkB,OAAdb,EACAA,EAAYa,MAEZ,IAAIb,IAAca,EAEd,MADAtD,GAAK+B,UAAUD,EAAU,mFAClB,CAMnB,IAAgB,KAAZU,EACAA,EAAUW,MAEV,IAAIX,IAAYW,EAEZ,MADAnD,GAAK+B,UAAUD,EAAU,gHAAkHqB,EAAI,wDAA0DX,EAAU,UAC5M,OAvCfzB,SAAQC,MAAM,8DA8CtB,OAAO,GAKXS,aAAc,SAAS8B,EAAWtD,GAC1BuD,OAAOC,QAAUD,OAAOC,OAAOC,kBAC/BF,OAAOC,OAAOC,iBAAiBC,gBAAgBJ,EAAWtD"}
|
||||
{"version":3,"file":"tools-jobs.js","sources":["../../../src/mvc/tools/tools-jobs.js"],"names":["define","Utils","ToolTemplate","submit","form","options","callback","self","this","job_def","tool_id","id","tool_version","version","inputs","data","create","trigger","_validation","console","debug","request","type","url","galaxy_config","root","success","response","$el","replaceWith","_refreshHdas","error","err_data","error_messages","matchResponse","input_id","highlight","modal","show","title","body","err_msg","buttons","Close","hide","job_inputs","batch_n","batch_src","job_input_id","input_value","match","input_field","field_list","input_def","input_list","optional","batch","n","values","length","src","detailIds","parent","Galaxy","currHistoryPanel","refreshContents"],"mappings":"AAGAA,QAAQ,cAAe,4BAA6B,SAASC,EAAOC,GACpE,OACIC,OAAQ,SAASC,EAAMC,EAASC,GAE5B,GAAIC,GAAOC,KAGPC,GACAC,QAAkBL,EAAQM,GAC1BC,aAAkBP,EAAQQ,QAC1BC,OAAkBV,EAAKW,KAAKC,SAOhC,OAHAZ,GAAKa,QAAQ,SAGRT,KAAKU,YAAYd,EAAMK,IAO5BU,QAAQC,MAAMX,OAGdR,GAAMoB,SACFC,KAAU,OACVC,IAAUC,cAAcC,KAAO,YAC/BV,KAAUN,EACViB,QAAU,SAASC,GACfrB,GAAYA,IACZF,EAAKwB,IAAIC,YAAa3B,EAAawB,QAASC,IAE5CpB,EAAKuB,gBAETC,MAAU,SAASJ,GAGf,GAFArB,GAAYA,IACZa,QAAQC,MAAMO,GACVA,GAAYA,EAASK,SAAU,CAC/B,GAAIC,GAAiB7B,EAAKW,KAAKmB,cAAcP,EAASK,SACtD,KAAK,GAAIG,KAAYF,GAAgB,CACjC7B,EAAKgC,UAAUD,EAAUF,EAAeE,GACxC,YAGJ/B,GAAKiC,MAAMC,MACPC,MAAU,wBACVC,KAAYb,GAAYA,EAASc,SAAavC,EAAa6B,MAAOtB,GAClEiC,SACIC,MAAU,WACNvC,EAAKiC,MAAMO,gBAlC/BzB,QAAQC,MAAM,qEACdd,GAAYA,OA4CpBY,YAAa,SAASd,EAAMK,GAExB,GAAIoC,GAAapC,EAAQK,OAGrBgC,EAAU,GACVC,EAAY,IAGhB,KAAK,GAAIC,KAAgBH,GAAY,CAEjC,GAAII,GAAcJ,EAAWG,GAGzBb,EAAW/B,EAAKW,KAAKmC,MAAMF,GAC3BG,EAAc/C,EAAKgD,WAAWjB,GAC9BkB,EAAYjD,EAAKkD,WAAWnB,EAGhC,IAAKA,GAAakB,GAAcF,EAAhC,CAMA,IAAKE,EAAUE,UAA2B,MAAfN,EAEvB,MADA7C,GAAKgC,UAAUD,IACR,CAIX,IAAIc,GAAeA,EAAYO,MAAO,CAElC,GAAIC,GAAIR,EAAYS,OAAOC,OAGvBC,EAAM,IAMV,IALIH,EAAI,IACJG,EAAMX,EAAYS,OAAO,IAAMT,EAAYS,OAAO,GAAGE,KAIrDA,EACA,GAAkB,OAAdb,EACAA,EAAYa,MAEZ,IAAIb,IAAca,EAEd,MADAxD,GAAKgC,UAAUD,EAAU,mFAClB,CAMnB,IAAgB,KAAZW,EACAA,EAAUW,MAEV,IAAIX,IAAYW,EAEZ,MADArD,GAAKgC,UAAUD,EAAU,gHAAkHsB,EAAI,wDAA0DX,EAAU,UAC5M,OAvCf3B,SAAQC,MAAM,8DA8CtB,OAAO,GAKXU,aAAc,SAAS+B,EAAWxD,GAC1ByD,OAAOC,QAAUD,OAAOC,OAAOC,kBAC/BF,OAAOC,OAAOC,iBAAiBC,gBAAgBJ,EAAWxD"}
|
||||
@@ -1,2 +1,2 @@
|
||||
define(["utils/utils","mvc/ui/ui-portlet","mvc/ui/ui-misc","mvc/form/form-section","mvc/form/form-data"],function(a,b,c,d,e){return Backbone.View.extend({initialize:function(b){this.optionsDefault={is_workflow:!1,initial_errors:!1,cls:"ui-portlet-limited"},this.options=a.merge(b,this.optionsDefault),console.debug(this.options);var d=parent.Galaxy;this.modal=d&&d.modal?d.modal:new c.Modal.View,this.setElement("<div/>"),this._build()},update:function(a){var b=this;this.data.matchModel(a,function(a,c){var d=b.input_list[a];if(d&&d.options&&!_.isEqual(d.options,c.options)){d.options=c.options;var e=b.field_list[a];if(e.update){var f=[];if(-1!=["data","data_collection","drill_down"].indexOf(d.type))f=d.options;else for(var g in c.options){var h=c.options[g];h.length>2&&f.push({label:h[0],value:h[1]})}e.update(f),e.trigger("change"),console.debug("Updating options for "+a)}}})},wait:function(a){for(var b in this.input_list){var c=this.field_list[b],d=this.input_list[b];d.is_dynamic&&c.wait&&c.unwait&&(a?c.wait():c.unwait())}},reciept:function(a){this.$el.empty(),this.$el.append(a)},highlight:function(a,b,c){var d=this.element_list[a];if(d&&(d.error(b||"Please verify this parameter."),this.trigger("expand",a),!c))if(self==top){var e=this.$el.parents().filter(function(){return"auto"==$(this).css("overflow")}).first();e.animate({scrollTop:e.scrollTop()+d.$el.offset().top-50},500)}else $("html, body").animate({scrollTop:d.$el.offset().top-20},500)},errors:function(a){if(this.trigger("reset"),a&&a.errors){var b=this.data.matchResponse(a.errors);for(var c in this.element_list){{this.element_list[c]}b[c]&&this.highlight(c,b[c],!0)}}},_build:function(){var a=this;this.off("change"),this.off("reset"),this.field_list={},this.input_list={},this.element_list={},this.data=new e(this),this._renderForm(),this.data.create(),this.options.initial_errors&&this.errors(this.options);var b=this.data.checksum();this.on("change",function(){var c=a.data.checksum();c!=b&&(b=c,a.options.onchange&&a.options.onchange())}),this.on("reset",function(){for(var a in this.element_list)this.element_list[a].reset()})},_renderForm:function(){this.message=new c.Message,this.section=new d.View(this,{inputs:this.options.inputs}),$(".tooltip").remove(),this.portlet=new b.View({icon:"fa-wrench",title:this.options.title,cls:this.options.cls,operations:this.options.operations,buttons:this.options.buttons}),this.portlet.append(this.message.$el.addClass("ui-margin-top")),this.portlet.append(this.section.$el),this.$el.empty(),this.$el.append(this.portlet.$el),this.options.message&&this.message.update({persistent:!0,status:"warning",message:this.options.message}),console.debug("tools-form-base::initialize() - Completed.")}})});
|
||||
define(["utils/utils","mvc/ui/ui-portlet","mvc/ui/ui-misc","mvc/form/form-section","mvc/form/form-data"],function(a,b,c,d,e){return Backbone.View.extend({initialize:function(b){this.optionsDefault={is_workflow:!1,initial_errors:!1,cls:"ui-portlet-limited"},this.options=a.merge(b,this.optionsDefault),console.debug(this.options);var d=parent.Galaxy;this.modal=d&&d.modal?d.modal:new c.Modal.View,this.setElement("<div/>"),this._build()},update:function(a){var b=this;this.data.matchModel(a,function(a,c){var d=b.input_list[a];if(d&&d.options&&!_.isEqual(d.options,c.options)){d.options=c.options;var e=b.field_list[a];if(e.update){var f=[];if(-1!=["data","data_collection","drill_down"].indexOf(d.type))f=d.options;else for(var g in c.options){var h=c.options[g];h.length>2&&f.push({label:h[0],value:h[1]})}e.update(f),e.trigger("change"),console.debug("Updating options for "+a)}}})},wait:function(a){for(var b in this.input_list){var c=this.field_list[b],d=this.input_list[b];d.is_dynamic&&c.wait&&c.unwait&&(a?c.wait():c.unwait())}},highlight:function(a,b,c){var d=this.element_list[a];if(d&&(d.error(b||"Please verify this parameter."),this.trigger("expand",a),!c))if(self==top){var e=this.$el.parents().filter(function(){return"auto"==$(this).css("overflow")}).first();e.animate({scrollTop:e.scrollTop()+d.$el.offset().top-50},500)}else $("html, body").animate({scrollTop:d.$el.offset().top-20},500)},errors:function(a){if(this.trigger("reset"),a&&a.errors){var b=this.data.matchResponse(a.errors);for(var c in this.element_list){{this.element_list[c]}b[c]&&this.highlight(c,b[c],!0)}}},_build:function(){var a=this;this.off("change"),this.off("reset"),this.field_list={},this.input_list={},this.element_list={},this.data=new e(this),this._renderForm(),this.data.create(),this.options.initial_errors&&this.errors(this.options);var b=this.data.checksum();this.on("change",function(){var c=a.data.checksum();c!=b&&(b=c,a.options.onchange&&a.options.onchange())}),this.on("reset",function(){for(var a in this.element_list)this.element_list[a].reset()})},_renderForm:function(){this.message=new c.Message,this.section=new d.View(this,{inputs:this.options.inputs}),$(".tooltip").remove(),this.portlet=new b.View({icon:"fa-wrench",title:this.options.title,cls:this.options.cls,operations:this.options.operations,buttons:this.options.buttons}),this.portlet.append(this.message.$el.addClass("ui-margin-top")),this.portlet.append(this.section.$el),this.$el.empty(),this.$el.append(this.portlet.$el),this.options.message&&this.message.update({persistent:!0,status:"warning",message:this.options.message}),console.debug("tools-form-base::initialize() - Completed.")}})});
|
||||
//# sourceMappingURL=../../../maps/mvc/form/form-view.js.map
|
||||
@@ -1,2 +1,2 @@
|
||||
define(["utils/utils","utils/deferred","mvc/ui/ui-misc","mvc/form/form-view","mvc/tools/tools-template","mvc/citation/citation-model","mvc/citation/citation-view"],function(a,b,c,d,e,f,g){return Backbone.View.extend({initialize:function(c){this.options=a.merge(c,{}),this.setElement("<div/>"),this.deferred=new b,c.inputs?this._buildForm(c):this._buildModel(c,!0)},_buildForm:function(b){var c=this;this.options=a.merge(b,this.options),this.options=a.merge({icon:"fa-wrench",title:"<b>"+b.name+"</b> "+b.description+" (Galaxy Tool Version "+b.version+")",operations:this._operations(),onchange:function(){c.deferred.reset(),c.deferred.execute(function(){c._updateModel()})}},this.options),this.options.customize&&this.options.customize(this.options),this.form=new d(this.options),this._footer(),this.$el.empty(),this.$el.append(this.form.$el)},_buildModel:function(b,d){var e=this;if(this.options.id=b.id,this.options.version=b.version,b.job_id)f=Galaxy.root+"api/jobs/"+b.job_id+"/build_for_rerun";else{var f=Galaxy.root+"api/tools/"+b.id+"/build?";b.version&&(f+="tool_version="+b.version+"&"),Galaxy.params&&Galaxy.params.tool_id==b.id&&_.each(Galaxy.params,function(a,b){-1==["tool_version","tool_id"].indexOf(b)&&(f+=b+"="+a+"&")})}var g=this.deferred.register();a.request({type:"GET",url:f,success:function(a){e._buildForm(a.tool_model||a),!d&&e.form.message.update({status:"success",message:"Now you are using '"+e.options.name+"' version "+e.options.version+".",persistent:!1}),e.deferred.done(g),console.debug("tools-form::initialize() - Initial tool model ready."),console.debug(a)},error:function(a){e.deferred.done(g),console.debug("tools-form::initialize() - Initial tool model request failed."),console.debug(a);var b=a.error||a.err_msg||"Uncaught error.";e.$el.is(":empty")?e.$el.prepend(new c.Message({message:b,status:"danger",persistent:!0,large:!0}).$el):Galaxy.modal.show({title:"Tool request failed",body:b,buttons:{Close:function(){Galaxy.modal.hide()}}})}})},_updateModel:function(){var b=this.options.update_url||Galaxy.root+"api/tools/"+this.options.id+"/build",c=this,d=this.form,e={tool_id:this.options.id,tool_version:this.options.version,inputs:$.extend(!0,{},c.form.data.create())};d.wait(!0);var f=this.deferred.register();console.debug("tools-form-base::_updateModel() - Sending current state (see below)."),console.debug(e),a.request({type:"POST",url:b,data:e,success:function(a){c.form.update(a.tool_model||a),c.options.update&&c.options.update(a),d.wait(!1),console.debug("tools-form-base::_updateModel() - Received new model (see below)."),console.debug(a),c.deferred.done(f)},error:function(a){c.deferred.done(f),console.debug("tools-form-base::_updateModel() - Refresh request failed."),console.debug(a)}})},_operations:function(){var a=this,b=this.options,d=new c.ButtonMenu({icon:"fa-cubes",title:!b.narrow&&"Versions"||null,tooltip:"Select another tool version"});if(!b.is_workflow&&b.versions&&b.versions.length>1)for(var f in b.versions){var g=b.versions[f];g!=b.version&&d.addMenu({title:"Switch to "+g,version:g,icon:"fa-cube",onclick:function(){var c=b.id.replace(b.version,this.version),d=this.version;a.deferred.reset(),a.deferred.execute(function(){a._buildModel({id:c,version:d})})}})}else d.$el.hide();var h=new c.ButtonMenu({icon:"fa-caret-down",title:!b.narrow&&"Options"||null,tooltip:"View available options"});return b.biostar_url&&(h.addMenu({icon:"fa-question-circle",title:"Question?",tooltip:"Ask a question about this tool (Biostar)",onclick:function(){window.open(b.biostar_url+"/p/new/post/")}}),h.addMenu({icon:"fa-search",title:"Search",tooltip:"Search help for this tool (Biostar)",onclick:function(){window.open(b.biostar_url+"/local/search/page/?q="+b.name)}})),h.addMenu({icon:"fa-share",title:"Share",tooltip:"Share this tool",onclick:function(){prompt("Copy to clipboard: Ctrl+C, Enter",window.location.origin+Galaxy.root+"root?tool_id="+b.id)}}),Galaxy.user&&Galaxy.user.get("is_admin")&&h.addMenu({icon:"fa-download",title:"Download",tooltip:"Download this tool",onclick:function(){window.location.href=Galaxy.root+"api/tools/"+b.id+"/download"}}),b.requirements&&b.requirements.length>0&&h.addMenu({icon:"fa-info-circle",title:"Requirements",tooltip:"Display tool requirements",onclick:function(){this.visible?(this.visible=!1,a.form.message.update({message:""})):(this.visible=!0,a.form.message.update({persistent:!0,message:e.requirements(b),status:"info"}))}}),b.sharable_url&&h.addMenu({icon:"fa-external-link",title:"See in Tool Shed",tooltip:"Access the repository",onclick:function(){window.open(b.sharable_url)}}),{menu:h,versions:d}},_footer:function(){var a=this.options;if(""!=a.help&&this.form.$el.append(e.help(a)),a.citations){var b=$("<div/>"),c=new f.ToolCitationCollection;c.tool_id=a.id;var d=new g.CitationListView({el:b,collection:c});d.render(),c.fetch(),this.form.$el.append(b)}}})});
|
||||
define(["utils/utils","utils/deferred","mvc/ui/ui-misc","mvc/form/form-view","mvc/tools/tools-template","mvc/citation/citation-model","mvc/citation/citation-view"],function(a,b,c,d,e,f,g){return Backbone.View.extend({initialize:function(c){this.options=a.merge(c,{}),this.setElement("<div/>"),this.deferred=new b,c.inputs?this._buildForm(c):this._buildModel(c,!0)},_buildForm:function(b){var c=this;this.options=a.merge(b,this.options),this.options=a.merge({icon:"fa-wrench",title:"<b>"+b.name+"</b> "+b.description+" (Galaxy Tool Version "+b.version+")",operations:this._operations(),onchange:function(){c.deferred.reset(),c.deferred.execute(function(){c._updateModel()})}},this.options),this.options.customize&&this.options.customize(this.options),this.form=new d(this.options),this._footer(),this.$el.empty(),this.$el.append(this.form.$el)},_buildModel:function(b,d){var e=this;if(this.options.id=b.id,this.options.version=b.version,b.job_id)f=Galaxy.root+"api/jobs/"+b.job_id+"/build_for_rerun";else{var f=Galaxy.root+"api/tools/"+b.id+"/build?";b.version&&(f+="tool_version="+b.version+"&"),Galaxy.params&&Galaxy.params.tool_id==b.id&&_.each(Galaxy.params,function(a,b){-1==["tool_version","tool_id"].indexOf(b)&&(f+=b+"="+a+"&")})}var g=this.deferred.register();a.request({type:"GET",url:f,success:function(a){e._buildForm(a.tool_model||a),!d&&e.form.message.update({status:"success",message:"Now you are using '"+e.options.name+"' version "+e.options.version+".",persistent:!1}),e.deferred.done(g),console.debug("tools-form::initialize() - Initial tool model ready."),console.debug(a)},error:function(a){e.deferred.done(g),console.debug("tools-form::initialize() - Initial tool model request failed."),console.debug(a);var b=a&&a.error||a&&a.err_msg||"Uncaught error.";e.$el.is(":empty")?e.$el.prepend(new c.Message({message:b,status:"danger",persistent:!0,large:!0}).$el):Galaxy.modal.show({title:"Tool request failed",body:b,buttons:{Close:function(){Galaxy.modal.hide()}}})}})},_updateModel:function(){var b=this.options.update_url||Galaxy.root+"api/tools/"+this.options.id+"/build",c=this,d=this.form,e={tool_id:this.options.id,tool_version:this.options.version,inputs:$.extend(!0,{},c.form.data.create())};d.wait(!0);var f=this.deferred.register();console.debug("tools-form-base::_updateModel() - Sending current state (see below)."),console.debug(e),a.request({type:"POST",url:b,data:e,success:function(a){c.form.update(a.tool_model||a),c.options.update&&c.options.update(a),d.wait(!1),console.debug("tools-form-base::_updateModel() - Received new model (see below)."),console.debug(a),c.deferred.done(f)},error:function(a){c.deferred.done(f),console.debug("tools-form-base::_updateModel() - Refresh request failed."),console.debug(a)}})},_operations:function(){var a=this,b=this.options,d=new c.ButtonMenu({icon:"fa-cubes",title:!b.narrow&&"Versions"||null,tooltip:"Select another tool version"});if(!b.is_workflow&&b.versions&&b.versions.length>1)for(var f in b.versions){var g=b.versions[f];g!=b.version&&d.addMenu({title:"Switch to "+g,version:g,icon:"fa-cube",onclick:function(){var c=b.id.replace(b.version,this.version),d=this.version;a.deferred.reset(),a.deferred.execute(function(){a._buildModel({id:c,version:d})})}})}else d.$el.hide();var h=new c.ButtonMenu({icon:"fa-caret-down",title:!b.narrow&&"Options"||null,tooltip:"View available options"});return b.biostar_url&&(h.addMenu({icon:"fa-question-circle",title:"Question?",tooltip:"Ask a question about this tool (Biostar)",onclick:function(){window.open(b.biostar_url+"/p/new/post/")}}),h.addMenu({icon:"fa-search",title:"Search",tooltip:"Search help for this tool (Biostar)",onclick:function(){window.open(b.biostar_url+"/local/search/page/?q="+b.name)}})),h.addMenu({icon:"fa-share",title:"Share",tooltip:"Share this tool",onclick:function(){prompt("Copy to clipboard: Ctrl+C, Enter",window.location.origin+Galaxy.root+"root?tool_id="+b.id)}}),Galaxy.user&&Galaxy.user.get("is_admin")&&h.addMenu({icon:"fa-download",title:"Download",tooltip:"Download this tool",onclick:function(){window.location.href=Galaxy.root+"api/tools/"+b.id+"/download"}}),b.requirements&&b.requirements.length>0&&h.addMenu({icon:"fa-info-circle",title:"Requirements",tooltip:"Display tool requirements",onclick:function(){this.visible?(this.visible=!1,a.form.message.update({message:""})):(this.visible=!0,a.form.message.update({persistent:!0,message:e.requirements(b),status:"info"}))}}),b.sharable_url&&h.addMenu({icon:"fa-external-link",title:"See in Tool Shed",tooltip:"Access the repository",onclick:function(){window.open(b.sharable_url)}}),{menu:h,versions:d}},_footer:function(){var a=this.options;if(""!=a.help&&this.form.$el.append(e.help(a)),a.citations){var b=$("<div/>"),c=new f.ToolCitationCollection;c.tool_id=a.id;var d=new g.CitationListView({el:b,collection:c});d.render(),c.fetch(),this.form.$el.append(b)}}})});
|
||||
//# sourceMappingURL=../../../maps/mvc/tools/tools-form-base.js.map
|
||||
@@ -1,2 +1,2 @@
|
||||
define(["utils/utils","mvc/tools/tools-template"],function(a,b){return{submit:function(c,d,e){var f=this,g={tool_id:d.id,tool_version:d.version,inputs:c.data.create()};return c.trigger("reset"),this._validation(c,g)?(console.debug(g),void a.request({type:"POST",url:galaxy_config.root+"api/tools",data:g,success:function(a){e&&e(),c.reciept(b.success(a)),f._refreshHdas()},error:function(a){if(e&&e(),a&&a.message&&a.message.data){var d=c.data.matchResponse(a.message.data);for(var f in d){c.highlight(f,d[f]);break}}else console.debug(a),a&&c.modal.show({title:"Job submission failed",body:b.error(g),buttons:{Close:function(){c.modal.hide()}}})}})):(console.debug("tools-jobs::submit - Submission canceled. Validation failed."),void(e&&e()))},_validation:function(a,b){var c=b.inputs,d=-1,e=null;for(var f in c){var g=c[f],h=a.data.match(f),i=a.field_list[h],j=a.input_list[h];if(h&&j&&i){if(!j.optional&&null==g)return a.highlight(h),!1;if(g&&g.batch){var k=g.values.length,l=null;if(k>0&&(l=g.values[0]&&g.values[0].src),l)if(null===e)e=l;else if(e!==l)return a.highlight(h,"Please select either dataset or dataset list fields for all batch mode fields."),!1;if(-1===d)d=k;else if(d!==k)return a.highlight(h,"Please make sure that you select the same number of inputs for all batch mode fields. This field contains <b>"+k+"</b> selection(s) while a previous field contains <b>"+d+"</b>."),!1}}else console.debug("tools-jobs::_validation - Retrieving input objects failed.")}return!0},_refreshHdas:function(a,b){parent.Galaxy&&parent.Galaxy.currHistoryPanel&&parent.Galaxy.currHistoryPanel.refreshContents(a,b)}}});
|
||||
define(["utils/utils","mvc/tools/tools-template"],function(a,b){return{submit:function(c,d,e){var f=this,g={tool_id:d.id,tool_version:d.version,inputs:c.data.create()};return c.trigger("reset"),this._validation(c,g)?(console.debug(g),void a.request({type:"POST",url:galaxy_config.root+"api/tools",data:g,success:function(a){e&&e(),c.$el.replaceWith(b.success(a)),f._refreshHdas()},error:function(a){if(e&&e(),console.debug(a),a&&a.err_data){var d=c.data.matchResponse(a.err_data);for(var f in d){c.highlight(f,d[f]);break}}else c.modal.show({title:"Job submission failed",body:a&&a.err_msg||b.error(g),buttons:{Close:function(){c.modal.hide()}}})}})):(console.debug("tools-jobs::submit - Submission canceled. Validation failed."),void(e&&e()))},_validation:function(a,b){var c=b.inputs,d=-1,e=null;for(var f in c){var g=c[f],h=a.data.match(f),i=a.field_list[h],j=a.input_list[h];if(h&&j&&i){if(!j.optional&&null==g)return a.highlight(h),!1;if(g&&g.batch){var k=g.values.length,l=null;if(k>0&&(l=g.values[0]&&g.values[0].src),l)if(null===e)e=l;else if(e!==l)return a.highlight(h,"Please select either dataset or dataset list fields for all batch mode fields."),!1;if(-1===d)d=k;else if(d!==k)return a.highlight(h,"Please make sure that you select the same number of inputs for all batch mode fields. This field contains <b>"+k+"</b> selection(s) while a previous field contains <b>"+d+"</b>."),!1}}else console.debug("tools-jobs::_validation - Retrieving input objects failed.")}return!0},_refreshHdas:function(a,b){parent.Galaxy&&parent.Galaxy.currHistoryPanel&&parent.Galaxy.currHistoryPanel.refreshContents(a,b)}}});
|
||||
//# sourceMappingURL=../../../maps/mvc/tools/tools-jobs.js.map
|
||||
@@ -136,128 +136,6 @@
|
||||
%endif
|
||||
|
||||
</script>
|
||||
## Handle AJAX (actually hidden iframe) upload tool
|
||||
<script type="text/javascript">
|
||||
var upload_form_error = function( msg ) {
|
||||
var $galaxy_mainBody = $("iframe#galaxy_main").contents().find("body"),
|
||||
$errMsg = $galaxy_mainBody.find( 'div.errormessage' );
|
||||
if ( !$errMsg.size() ){
|
||||
$errMsg = $( '<div/>' ).addClass( 'errormessage' ).prependTo( $galaxy_mainBody );
|
||||
}
|
||||
$errMsg.text( msg );
|
||||
}
|
||||
|
||||
var uploads_in_progress = 0;
|
||||
function decrementUploadsInProgress(){
|
||||
uploads_in_progress -= 1;
|
||||
if( uploads_in_progress === 0 ){
|
||||
window.onbeforeunload = null;
|
||||
}
|
||||
}
|
||||
jQuery( function() {
|
||||
$("iframe#galaxy_main").load( function() {
|
||||
$(this).contents().find("form").each( function() {
|
||||
if ( $(this).find("input[galaxy-ajax-upload]").length > 0 ){
|
||||
var $form = $( this );
|
||||
|
||||
$(this).submit( function( event ) {
|
||||
// Only bother using a hidden iframe if there's a file (e.g. big data) upload
|
||||
var file_upload = false;
|
||||
$(this).find("input[galaxy-ajax-upload]").each( function() {
|
||||
if ( $(this).val() != '' ) {
|
||||
file_upload = true;
|
||||
}
|
||||
});
|
||||
if ( ! file_upload ) {
|
||||
return true;
|
||||
}
|
||||
// Make a synchronous request to create the datasets first
|
||||
var async_datasets;
|
||||
var upload_error = false;
|
||||
|
||||
//NOTE: in order for upload.py to match the datasets created below, we'll move the js File
|
||||
// object's name into the file_data field (not in the form only for what we send to
|
||||
// upload_async_create)
|
||||
var formData = $( this ).serializeArray();
|
||||
var name = function(){
|
||||
var $fileInput = $form.find( 'input[name="files_0|file_data"]' );
|
||||
if( /msie/.test( navigator.userAgent.toLowerCase() ) ){
|
||||
return $fileInput.val().replace( 'C:\\fakepath\\', '' );
|
||||
} else {
|
||||
return $fileInput.get( 0 ).files[0].name;
|
||||
}
|
||||
}
|
||||
formData.push({ name: "files_0|file_data", value: name });
|
||||
|
||||
$.ajax( {
|
||||
async: false,
|
||||
type: "POST",
|
||||
url: "${h.url_for(controller='/tool_runner', action='upload_async_create')}",
|
||||
data: formData,
|
||||
dataType: "json",
|
||||
success: function(array_obj, status) {
|
||||
if (array_obj.length > 0) {
|
||||
if (array_obj[0] == 'error') {
|
||||
upload_error = true;
|
||||
upload_form_error(array_obj[1]);
|
||||
} else {
|
||||
async_datasets = array_obj.join();
|
||||
}
|
||||
} else {
|
||||
// ( gvk 1/22/10 ) FIXME: this block is never entered, so there may be a bug somewhere
|
||||
// I've done some debugging like checking to see if array_obj is undefined, but have not
|
||||
// tracked down the behavior that will result in this block being entered. I believe the
|
||||
// intent was to have this block entered if the upload button is clicked on the upload
|
||||
// form but no file was selected.
|
||||
upload_error = true;
|
||||
upload_form_error( 'No data was entered in the upload form. You may choose to upload a file, paste some data directly in the data box, or enter URL(s) to fetch data.' );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
// show the dataset we created above in the history panel
|
||||
Galaxy && Galaxy.currHistoryPanel && Galaxy.currHistoryPanel.refreshContents();
|
||||
|
||||
if (upload_error == true) {
|
||||
return false;
|
||||
} else {
|
||||
$(this).find("input[name=async_datasets]").val( async_datasets );
|
||||
$(this).append("<input type='hidden' name='ajax_upload' value='true'>");
|
||||
}
|
||||
// iframe submit is required for nginx (otherwise the encoding is wrong)
|
||||
$(this).ajaxSubmit({
|
||||
//iframe: true,
|
||||
error: function( xhr, msg, status ){
|
||||
decrementUploadsInProgress();
|
||||
},
|
||||
success: function ( response, x, y, z ) {
|
||||
decrementUploadsInProgress();
|
||||
}
|
||||
});
|
||||
uploads_in_progress++;
|
||||
window.onbeforeunload = function() {
|
||||
return "Navigating away from the Galaxy analysis interface will interrupt the "
|
||||
+ "file upload(s) currently in progress. Do you really want to do this?";
|
||||
}
|
||||
if ( $(this).find("input[name='folder_id']").val() != undefined ) {
|
||||
var library_id = $(this).find("input[name='library_id']").val();
|
||||
var show_deleted = $(this).find("input[name='show_deleted']").val();
|
||||
if ( location.pathname.indexOf( 'admin' ) != -1 ) {
|
||||
$("iframe#galaxy_main").attr("src","${h.url_for( controller='library_common', action='browse_library' )}?cntrller=library_admin&id=" + library_id + "&created_ldda_ids=" + async_datasets + "&show_deleted=" + show_deleted);
|
||||
} else {
|
||||
$("iframe#galaxy_main").attr("src","${h.url_for( controller='library_common', action='browse_library' )}?cntrller=library&id=" + library_id + "&created_ldda_ids=" + async_datasets + "&show_deleted=" + show_deleted);
|
||||
}
|
||||
} else {
|
||||
$("iframe#galaxy_main").attr("src","${h.url_for(controller='tool_runner', action='upload_async_message')}");
|
||||
}
|
||||
event.preventDefault();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</%def>
|
||||
|
||||
## Masthead
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Galaxy</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<link href="${h.url_for('/static/style/base.css')}" rel="stylesheet" type="text/css" />
|
||||
<script type="text/javascript">
|
||||
setTimeout( function() { top.location.href = '${h.url_for( "/" )}'; }, 1000 );
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="donemessagelarge">
|
||||
%if num_jobs > 1:
|
||||
<% jobs_str = "%d jobs have" % num_jobs %>
|
||||
%else:
|
||||
<% jobs_str = "A job has" %>
|
||||
%endif
|
||||
%if len(out_data) == 1:
|
||||
<% datasets_str = "dataset" %>
|
||||
%else:
|
||||
<% datasets_str = "datasets" %>
|
||||
%endif
|
||||
<p>
|
||||
${jobs_str} been successfully added to the queue - resulting in the following ${datasets_str}:
|
||||
</p>
|
||||
%for _, data in out_data:
|
||||
<div style="padding: 10px"><b> ${data.hid}: ${data.name | h}</b></div>
|
||||
%endfor
|
||||
<p> You can check the status of queued jobs and view the resulting data by refreshing the <b>History</b> pane. When the job has been run the status will change from 'running' to 'finished' if completed successfully or 'error' if problems were encountered. You are now being redirected back to <a href="${h.url_for( '/' )}">Galaxy</a>.</p>
|
||||
</div>
|
||||
%if job_errors:
|
||||
<div class="errormessagelarge">
|
||||
There were errors setting up ${len(job_errors)} submitted job(s):
|
||||
<ul>
|
||||
%for job_error in job_errors:
|
||||
<li><b>${job_error | h}</b></li>
|
||||
%endfor
|
||||
</ul>
|
||||
</div>
|
||||
%endif
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,94 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Galaxy</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<link href="${h.url_for('/static/style/base.css')}" rel="stylesheet" type="text/css" />
|
||||
<script type="text/javascript">
|
||||
var inside_galaxy_frameset = false;
|
||||
|
||||
// refresh the history panel to include any new datasets created by the tool
|
||||
if( top.Galaxy && top.Galaxy.currHistoryPanel ){
|
||||
top.Galaxy.currHistoryPanel.refreshContents();
|
||||
}
|
||||
|
||||
%if trans.user:
|
||||
if (inside_galaxy_frameset)
|
||||
{
|
||||
//parent.frames.galaxy_tools.update_recently_used();
|
||||
}
|
||||
%endif
|
||||
|
||||
if ( parent.handle_minwidth_hint ) {
|
||||
parent.handle_minwidth_hint( -1 );
|
||||
}
|
||||
|
||||
function main() {
|
||||
// If called from outside the galaxy frameset, redirect there
|
||||
%if tool.options.refresh:
|
||||
if ( ! inside_galaxy_frameset ) {
|
||||
setTimeout( "refresh()", 1000 );
|
||||
document.getElementById( "refresh_message" ).style.display = "block";
|
||||
}
|
||||
%endif
|
||||
}
|
||||
|
||||
function refresh() {
|
||||
top.location.href = '${h.url_for( "/" )}';
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onLoad="main()">
|
||||
|
||||
<div class="donemessagelarge">
|
||||
|
||||
%if num_jobs > 1:
|
||||
<% jobs_str = "%d jobs have" % num_jobs %>
|
||||
%else:
|
||||
<% jobs_str = "A job has" %>
|
||||
%endif
|
||||
%if len(out_data) == 1:
|
||||
<% datasets_str = "dataset" %>
|
||||
%else:
|
||||
<% datasets_str = "datasets" %>
|
||||
%endif
|
||||
|
||||
<p>
|
||||
${jobs_str} been successfully added to the queue - resulting in the following ${datasets_str}:
|
||||
</p>
|
||||
%for _, data in out_data:
|
||||
<div style="padding: 10px"><b> ${data.hid}: ${data.name | h}</b></div>
|
||||
%endfor
|
||||
|
||||
<p>
|
||||
You can check the status of queued jobs and view the resulting
|
||||
data by refreshing the <b>History</b> pane. When the job has been run
|
||||
the status will change from 'running' to 'finished' if completed
|
||||
successfully or 'error' if problems were encountered.
|
||||
</p>
|
||||
|
||||
%if tool.options.refresh:
|
||||
<p id="refresh_message" style="display: none;">You are now being redirected back to <a href="${h.url_for( '/' )}">Galaxy</a></div>
|
||||
%endif
|
||||
|
||||
</div>
|
||||
|
||||
%if job_errors:
|
||||
<div class="errormessagelarge">
|
||||
There were errors setting up ${len(job_errors)} submitted job(s):
|
||||
<ul>
|
||||
<!-- Styling on this list is a little flat. Consider identing these error messages. -->
|
||||
%for job_error in job_errors:
|
||||
<li><b>${job_error | h}</b></li>
|
||||
%endfor
|
||||
</ul>
|
||||
</div>
|
||||
%endif
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -219,7 +219,7 @@ class GalaxyInteractorApi( object ):
|
||||
jobs=submit_response_object[ 'jobs' ],
|
||||
)
|
||||
except KeyError:
|
||||
message = "Error creating a job for these tool inputs - %s" % submit_response_object[ 'message' ]
|
||||
message = "Error creating a job for these tool inputs - %s" % submit_response_object[ 'err_msg' ]
|
||||
raise RunToolException( message, inputs_tree )
|
||||
|
||||
def _create_collection( self, history_id, collection_def ):
|
||||
|
||||
@@ -4,11 +4,8 @@
|
||||
from unittest import TestCase
|
||||
|
||||
import galaxy.model
|
||||
from galaxy.tools import DefaultToolState
|
||||
from galaxy.tools.parameters import params_to_incoming
|
||||
from galaxy.util.bunch import Bunch
|
||||
from galaxy.util import string_to_object
|
||||
from galaxy.util import object_to_string
|
||||
from galaxy.util.odict import odict
|
||||
import tools_support
|
||||
|
||||
@@ -49,118 +46,62 @@ class ToolExecutionTestCase( TestCase, tools_support.UsesApp, tools_support.Uses
|
||||
|
||||
def test_state_new( self ):
|
||||
self._init_tool( tools_support.SIMPLE_TOOL_CONTENTS )
|
||||
template, template_vars = self.__handle_with_incoming(
|
||||
param1="moo",
|
||||
# no runtool_btn, just rerenders the form mako with tool
|
||||
# state populated.
|
||||
)
|
||||
state = self.__assert_rerenders_tool_without_errors( template, template_vars )
|
||||
assert state.inputs[ "param1" ] == "moo"
|
||||
vars = self.__handle_with_incoming( param1="moo" )
|
||||
state = self.__assert_rerenders_tool_without_errors( vars )
|
||||
assert state[ "param1" ] == "moo"
|
||||
|
||||
def test_execute( self ):
|
||||
self._init_tool( tools_support.SIMPLE_TOOL_CONTENTS )
|
||||
template, template_vars = self.__handle_with_incoming(
|
||||
param1="moo",
|
||||
runtool_btn="dummy",
|
||||
)
|
||||
self.__assert_exeuted( template, template_vars )
|
||||
vars = self.__handle_with_incoming( param1="moo" )
|
||||
self.__assert_executed( vars )
|
||||
# Didn't specify a rerun_remap_id so this should be None
|
||||
assert self.tool_action.execution_call_args[ 0 ][ "rerun_remap_job_id" ] is None
|
||||
|
||||
def test_execute_exception( self ):
|
||||
self._init_tool( tools_support.SIMPLE_TOOL_CONTENTS )
|
||||
self.tool_action.raise_exception( )
|
||||
template, template_vars = self.__handle_with_incoming(
|
||||
param1="moo",
|
||||
runtool_btn="dummy",
|
||||
)
|
||||
assert template == "message.mako"
|
||||
assert template_vars[ "status" ] == "error"
|
||||
assert "Error executing tool" in template_vars[ "message" ]
|
||||
try:
|
||||
self.__handle_with_incoming( param1="moo" )
|
||||
except Exception, e:
|
||||
assert 'Error executing tool' in str( e )
|
||||
|
||||
def test_execute_errors( self ):
|
||||
self._init_tool( tools_support.SIMPLE_TOOL_CONTENTS )
|
||||
self.tool_action.return_error( )
|
||||
template, template_vars = self.__handle_with_incoming(
|
||||
param1="moo",
|
||||
runtool_btn="dummy",
|
||||
)
|
||||
assert template == "message.mako"
|
||||
assert template_vars[ "status" ] == "error"
|
||||
assert "Test Error Message" in template_vars[ "message" ], template_vars
|
||||
try:
|
||||
self.__handle_with_incoming( param1="moo" )
|
||||
except Exception, e:
|
||||
assert 'Test Error Message' in str( e )
|
||||
|
||||
def test_redirect( self ):
|
||||
self._init_tool( tools_support.SIMPLE_TOOL_CONTENTS )
|
||||
self.tool_action.expect_redirect = True
|
||||
redirect_raised = False
|
||||
try:
|
||||
template, template_vars = self.__handle_with_incoming(
|
||||
param1="moo",
|
||||
runtool_btn="dummy",
|
||||
)
|
||||
self.__handle_with_incoming( param1="moo" )
|
||||
except httpexceptions.HTTPFound:
|
||||
redirect_raised = True
|
||||
assert redirect_raised
|
||||
|
||||
def test_remap_job( self ):
|
||||
self._init_tool( tools_support.SIMPLE_TOOL_CONTENTS )
|
||||
template, template_vars = self.__handle_with_incoming(
|
||||
param1="moo",
|
||||
rerun_remap_job_id=self.app.security.encode_id(123),
|
||||
runtool_btn="dummy",
|
||||
)
|
||||
self.__assert_exeuted( template, template_vars )
|
||||
vars = self.__handle_with_incoming( param1="moo", rerun_remap_job_id=self.app.security.encode_id(123) )
|
||||
self.__assert_executed( vars )
|
||||
assert self.tool_action.execution_call_args[ 0 ][ "rerun_remap_job_id" ] == 123
|
||||
|
||||
def test_invalid_remap_job( self ):
|
||||
self._init_tool( tools_support.SIMPLE_TOOL_CONTENTS )
|
||||
template, template_vars = self.__handle_with_incoming(
|
||||
param1="moo",
|
||||
rerun_remap_job_id='123', # Not encoded
|
||||
runtool_btn="dummy",
|
||||
)
|
||||
assert template == "message.mako"
|
||||
assert template_vars[ "status" ] == "error"
|
||||
assert "invalid job" in template_vars[ "message" ]
|
||||
|
||||
def test_repeat_state_updates( self ):
|
||||
self._init_tool( REPEAT_TOOL_CONTENTS )
|
||||
|
||||
# Fresh state contains no repeat elements
|
||||
template, template_vars = self.__handle_with_incoming()
|
||||
state = self.__assert_rerenders_tool_without_errors( template, template_vars )
|
||||
assert len( state.inputs[ "repeat1" ] ) == 0
|
||||
|
||||
# Hitting add button adds repeat element
|
||||
template, template_vars = self.__handle_with_incoming(
|
||||
repeat1_add="dummy",
|
||||
)
|
||||
state = self.__assert_rerenders_tool_without_errors( template, template_vars )
|
||||
assert len( state.inputs[ "repeat1" ] ) == 1
|
||||
|
||||
# Hitting add button again adds another repeat element
|
||||
template, template_vars = self.__handle_with_incoming( state, **{
|
||||
"repeat1_add": "dummy",
|
||||
"repeat1_0|param2": "moo2",
|
||||
} )
|
||||
state = self.__assert_rerenders_tool_without_errors( template, template_vars )
|
||||
assert len( state.inputs[ "repeat1" ] ) == 2
|
||||
assert state.inputs[ "repeat1" ][ 0 ][ "param2" ] == "moo2"
|
||||
|
||||
# Hitting remove drops a repeat element
|
||||
template, template_vars = self.__handle_with_incoming( state, repeat1_1_remove="dummy" )
|
||||
state = self.__assert_rerenders_tool_without_errors( template, template_vars )
|
||||
assert len( state.inputs[ "repeat1" ] ) == 1
|
||||
try:
|
||||
self.__handle_with_incoming( param1="moo", rerun_remap_job_id='123' )
|
||||
except Exception, e:
|
||||
assert 'invalid job' in str( e )
|
||||
|
||||
def test_data_param_execute( self ):
|
||||
self._init_tool( tools_support.SIMPLE_CAT_TOOL_CONTENTS )
|
||||
hda = self.__add_dataset(1)
|
||||
hda = self.__add_dataset( 1 )
|
||||
# Execute tool action
|
||||
template, template_vars = self.__handle_with_incoming(
|
||||
param1=1,
|
||||
runtool_btn="dummy",
|
||||
)
|
||||
self.__assert_exeuted( template, template_vars )
|
||||
vars = self.__handle_with_incoming( param1=1 )
|
||||
self.__assert_executed( vars )
|
||||
# Tool 'executed' once, with hda as param1
|
||||
assert len( self.tool_action.execution_call_args ) == 1
|
||||
assert self.tool_action.execution_call_args[ 0 ][ "incoming" ][ "param1" ] == hda
|
||||
@@ -169,113 +110,27 @@ class ToolExecutionTestCase( TestCase, tools_support.UsesApp, tools_support.Uses
|
||||
self._init_tool( tools_support.SIMPLE_CAT_TOOL_CONTENTS )
|
||||
hda = self.__add_dataset( 1 )
|
||||
# Update state
|
||||
template, template_vars = self.__handle_with_incoming(
|
||||
param1=1,
|
||||
)
|
||||
state = self.__assert_rerenders_tool_without_errors( template, template_vars )
|
||||
assert hda == state.inputs[ "param1" ]
|
||||
vars = self.__handle_with_incoming( param1=1 )
|
||||
state = self.__assert_rerenders_tool_without_errors( vars )
|
||||
assert hda == state[ "param1" ]
|
||||
|
||||
def test_simple_multirun_state_update( self ):
|
||||
hda1, hda2 = self.__setup_multirun_job()
|
||||
template, template_vars = self.__handle_with_incoming( **{
|
||||
"param1|__multirun__": [ 1, 2 ],
|
||||
vars = self.__handle_with_incoming( **{
|
||||
"param1|__multirun__": [ 1, 2 ]
|
||||
} )
|
||||
state = self.__assert_rerenders_tool_without_errors( template, template_vars )
|
||||
self.__assert_state_serializable( state )
|
||||
self.assertEquals( state.inputs[ "param1|__multirun__" ], [ 1, 2 ] )
|
||||
|
||||
def test_simple_collection_multirun_state_update( self ):
|
||||
hdca = self.__setup_collection_multirun_job()
|
||||
encoded_id = self.app.security.encode_id(hdca.id)
|
||||
template, template_vars = self.__handle_with_incoming( **{
|
||||
"param1|__collection_multirun__": encoded_id,
|
||||
} )
|
||||
state = self.__assert_rerenders_tool_without_errors( template, template_vars )
|
||||
self.__assert_state_serializable( state )
|
||||
self.assertEquals( state.inputs[ "param1|__collection_multirun__" ], encoded_id )
|
||||
|
||||
def test_repeat_multirun_state_updates( self ):
|
||||
self._init_tool( REPEAT_TOOL_CONTENTS )
|
||||
|
||||
# Fresh state contains no repeat elements
|
||||
self.__handle_with_incoming()
|
||||
# Hitting add button adds repeat element
|
||||
template, template_vars = self.__handle_with_incoming(**{
|
||||
"param1|__multirun__": [ 1, 2 ],
|
||||
"repeat1_add": "dummy",
|
||||
})
|
||||
state = self.__assert_rerenders_tool_without_errors( template, template_vars )
|
||||
self.assertEquals( state.inputs[ "param1|__multirun__" ], [ 1, 2 ] )
|
||||
assert len( state.inputs[ "repeat1" ] ) == 1
|
||||
|
||||
# Hitting add button again adds another repeat element
|
||||
template, template_vars = self.__handle_with_incoming( state, **{
|
||||
"repeat1_0|param2|__multirun__": [ 1, 2 ],
|
||||
"repeat1_add": "dummy",
|
||||
} )
|
||||
state = self.__assert_rerenders_tool_without_errors( template, template_vars )
|
||||
self.assertEquals( state.inputs[ "param1|__multirun__" ], [ 1, 2 ] )
|
||||
self.assertEquals( state.inputs[ "repeat1" ][0][ "param2|__multirun__" ], [ 1, 2 ] )
|
||||
|
||||
def test_simple_multirun_execution( self ):
|
||||
hda1, hda2 = self.__setup_multirun_job()
|
||||
template, template_vars = self.__handle_with_incoming( **{
|
||||
"param1|__multirun__": [ 1, 2 ],
|
||||
"runtool_btn": "dummy",
|
||||
} )
|
||||
self.__assert_exeuted( template, template_vars )
|
||||
# Tool 'executed' twice, with param1 as hda1 and hda2 respectively.
|
||||
assert len( self.tool_action.execution_call_args ) == 2
|
||||
self.assertEquals( self.tool_action.execution_call_args[ 0 ][ "incoming" ][ "param1" ], hda1 )
|
||||
self.assertEquals( self.tool_action.execution_call_args[ 1 ][ "incoming" ][ "param1" ], hda2 )
|
||||
self.assertEquals( len( template_vars[ "jobs" ] ), 2 )
|
||||
self.__assert_rerenders_tool_without_errors( vars )
|
||||
assert vars[ 'num_jobs' ] == 2
|
||||
|
||||
def test_cannot_multirun_and_remap( self ):
|
||||
hda1, hda2 = self.__setup_multirun_job()
|
||||
template, template_vars = self.__handle_with_incoming( **{
|
||||
"param1|__multirun__": [ 1, 2 ],
|
||||
"rerun_remap_job_id": self.app.security.encode_id(123), # Not encoded
|
||||
"runtool_btn": "dummy",
|
||||
} )
|
||||
self.assertEquals( template, "message.mako" )
|
||||
assert template_vars[ "status" ] == "error"
|
||||
assert "multiple jobs" in template_vars[ "message" ]
|
||||
|
||||
def test_multirun_with_state_updates( self ):
|
||||
hda1, hda2 = self.__setup_multirun_job()
|
||||
|
||||
# Fresh state contains no repeat elements
|
||||
template, template_vars = self.__handle_with_incoming()
|
||||
state = self.__assert_rerenders_tool_without_errors( template, template_vars )
|
||||
assert len( state.inputs[ "repeat1" ] ) == 0
|
||||
self.__assert_state_serializable( state )
|
||||
|
||||
# Hitting add button adds repeat element
|
||||
template, template_vars = self.__handle_with_incoming( **{
|
||||
"param1|__multirun__": [ 1, 2 ],
|
||||
"repeat1_add": "dummy",
|
||||
} )
|
||||
state = self.__assert_rerenders_tool_without_errors( template, template_vars )
|
||||
assert len( state.inputs[ "repeat1" ] ) == 1
|
||||
self.assertEquals( state.inputs[ "param1|__multirun__" ], [ 1, 2 ] )
|
||||
self.__assert_state_serializable( state )
|
||||
|
||||
# Hitting add button again adds another repeat element
|
||||
template, template_vars = self.__handle_with_incoming( state, **{
|
||||
"repeat1_add": "dummy",
|
||||
"repeat1_0|param2": 1,
|
||||
} )
|
||||
state = self.__assert_rerenders_tool_without_errors( template, template_vars )
|
||||
self.assertEquals( state.inputs[ "param1|__multirun__" ], [ 1, 2 ] )
|
||||
assert len( state.inputs[ "repeat1" ] ) == 2
|
||||
assert state.inputs[ "repeat1" ][ 0 ][ "param2" ] == hda1
|
||||
self.__assert_state_serializable( state )
|
||||
|
||||
# Hitting remove drops a repeat element
|
||||
template, template_vars = self.__handle_with_incoming( state, repeat1_1_remove="dummy" )
|
||||
state = self.__assert_rerenders_tool_without_errors( template, template_vars )
|
||||
assert len( state.inputs[ "repeat1" ] ) == 1
|
||||
self.__assert_state_serializable( state )
|
||||
try:
|
||||
self.__handle_with_incoming( **{
|
||||
"param1|__multirun__": [ 1, 2 ],
|
||||
"rerun_remap_job_id": self.app.security.encode_id( 123 )
|
||||
} )
|
||||
except Exception, e:
|
||||
assert 'multiple jobs' in str( e )
|
||||
|
||||
def test_collection_multirun_with_state_updates( self ):
|
||||
hda1, hda2 = self.__setup_multirun_job()
|
||||
@@ -284,31 +139,10 @@ class ToolExecutionTestCase( TestCase, tools_support.UsesApp, tools_support.Uses
|
||||
self.app.dataset_collections_service = Bunch(
|
||||
match_collections=lambda collections: None
|
||||
)
|
||||
template, template_vars = self.__handle_with_incoming( **{
|
||||
"param1|__collection_multirun__": collection_id,
|
||||
"runtool_btn": "dummy",
|
||||
vars = self.__handle_with_incoming( **{
|
||||
"param1|__collection_multirun__": collection_id
|
||||
} )
|
||||
self.__assert_exeuted( template, template_vars )
|
||||
|
||||
def test_subcollection_multirun_with_state_updates( self ):
|
||||
self._init_tool( REPEAT_COLLECTION_PARAM_CONTENTS )
|
||||
hda1, hda2 = self.__add_dataset( 1 ), self.__add_dataset( 2 )
|
||||
collection = self.__history_dataset_collection_for( [ hda1, hda2 ], collection_type="list:paired" )
|
||||
collection_id = self.app.security.encode_id( collection.id )
|
||||
self.app.dataset_collections_service = Bunch(
|
||||
match_collections=lambda collections: None
|
||||
)
|
||||
template, template_vars = self.__handle_with_incoming(
|
||||
repeat1_add="dummy",
|
||||
)
|
||||
state = self.__assert_rerenders_tool_without_errors( template, template_vars )
|
||||
assert len( state.inputs[ "repeat1" ] ) == 1
|
||||
template, template_vars = self.__handle_with_incoming( state, **{
|
||||
"repeat1_0|param2|__collection_multirun__": "%s|paired" % collection_id,
|
||||
"repeat1_add": "dummy",
|
||||
} )
|
||||
state = self.__assert_rerenders_tool_without_errors( template, template_vars )
|
||||
assert state.inputs[ "repeat1" ][ 0 ][ "param2|__collection_multirun__" ] == "%s|paired" % collection_id
|
||||
self.__assert_executed( vars )
|
||||
|
||||
def __history_dataset_collection_for( self, hdas, collection_type="list", id=1234 ):
|
||||
collection = galaxy.model.DatasetCollection(
|
||||
@@ -340,19 +174,11 @@ class ToolExecutionTestCase( TestCase, tools_support.UsesApp, tools_support.Uses
|
||||
hdcas[ id ] = history_dataset_collection_association
|
||||
return history_dataset_collection_association
|
||||
|
||||
def __assert_state_serializable( self, state ):
|
||||
self.__state_to_string( state ) # Will thrown exception if there is a problem...
|
||||
|
||||
def __setup_multirun_job( self ):
|
||||
self._init_tool( tools_support.SIMPLE_CAT_TOOL_CONTENTS )
|
||||
hda1, hda2 = self.__add_dataset( 1 ), self.__add_dataset( 2 )
|
||||
return hda1, hda2
|
||||
|
||||
def __setup_collection_multirun_job( self ):
|
||||
self._init_tool( tools_support.SIMPLE_CAT_TOOL_CONTENTS )
|
||||
hdca = self.__add_collection_dataset( 1 )
|
||||
return hdca
|
||||
|
||||
def __handle_with_incoming( self, previous_state=None, **kwds ):
|
||||
""" Execute tool.handle_input with incoming specified by kwds
|
||||
(optionally extending a previous state).
|
||||
@@ -361,10 +187,7 @@ class ToolExecutionTestCase( TestCase, tools_support.UsesApp, tools_support.Uses
|
||||
incoming = self.__to_incoming( previous_state, **kwds)
|
||||
else:
|
||||
incoming = kwds
|
||||
return self.tool.handle_input(
|
||||
trans=self.trans,
|
||||
incoming=incoming,
|
||||
)
|
||||
return self.tool.handle_input( trans=self.trans, incoming=incoming )
|
||||
|
||||
def __to_incoming( self, state, **kwds ):
|
||||
new_incoming = {}
|
||||
@@ -398,43 +221,17 @@ class ToolExecutionTestCase( TestCase, tools_support.UsesApp, tools_support.Uses
|
||||
self.history.dataset_collections.append( hdca )
|
||||
return hdca
|
||||
|
||||
def __assert_rerenders_tool_without_errors( self, template, template_vars ):
|
||||
assert template == ""
|
||||
self.__assert_no_errors( template_vars )
|
||||
state = template_vars[ "tool_state" ]
|
||||
return state
|
||||
def __assert_rerenders_tool_without_errors( self, vars ):
|
||||
self.__assert_no_errors( vars )
|
||||
return self.tool_action.execution_call_args[ 0 ][ "incoming" ]
|
||||
|
||||
def __assert_exeuted( self, template, template_vars ):
|
||||
if template == "":
|
||||
self.__assert_no_errors( template_vars )
|
||||
self.assertEquals(
|
||||
template,
|
||||
"tool_executed.mako",
|
||||
"Expected tools_execute template - got template %s with vars %s" % ( template, template_vars)
|
||||
)
|
||||
def __assert_executed( self, vars ):
|
||||
self.__assert_no_errors( vars )
|
||||
assert len( vars[ 'jobs' ] ) > 0
|
||||
|
||||
def __assert_no_errors( self, template_vars ):
|
||||
assert "errors" in template_vars, "Tool form rendered without error definition."
|
||||
errors = template_vars[ "errors" ]
|
||||
assert not errors, "Template rendered unexpected errors - %s" % errors
|
||||
|
||||
def __string_to_state( self, state_string ):
|
||||
encoded_state = string_to_object( state_string )
|
||||
state = DefaultToolState()
|
||||
state.decode( encoded_state, self.tool, self.app )
|
||||
return state
|
||||
|
||||
def __inputs_to_state( self, inputs ):
|
||||
tool_state = DefaultToolState()
|
||||
tool_state.inputs = inputs
|
||||
return tool_state
|
||||
|
||||
def __state_to_string( self, tool_state ):
|
||||
return object_to_string( tool_state.encode( self.tool, self.app ) )
|
||||
|
||||
def __inputs_to_state_string( self, inputs ):
|
||||
tool_state = self.__inputs_to_state( inputs )
|
||||
return self.__state_to_string( tool_state )
|
||||
def __assert_no_errors( self, vars ):
|
||||
assert "job_errors" in vars
|
||||
assert not vars[ "job_errors" ]
|
||||
|
||||
|
||||
class MockAction( object ):
|
||||
|
||||
Reference in New Issue
Block a user