details:
http://www.bx.psu.edu/hg/galaxy/rev/dae0313bf5bb
changeset: 2381:dae0313bf5bb
user: James Taylor <james(a)jamestaylor.org>
date: Wed Apr 29 13:46:02 2009 -0400
description:
Handle the addition of new tool parameters better in the workflow editor. Default values
will be filled in and a message displayed to the user
7 file(s) affected in this change:
lib/galaxy/tools/__init__.py
lib/galaxy/tools/parameters/grouping.py
lib/galaxy/web/controllers/workflow.py
lib/galaxy/workflow/modules.py
static/scripts/galaxy.workflow_editor.canvas.js
templates/workflow/editor.mako
tools/maf/interval2maf.xml
diffs (252 lines):
diff -r 22b08d47f7ba -r dae0313bf5bb lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py Wed Apr 29 11:53:22 2009 -0400
+++ b/lib/galaxy/tools/__init__.py Wed Apr 29 13:46:02 2009 -0400
@@ -676,25 +676,7 @@
"""
context = ExpressionContext( state, context )
for input in inputs.itervalues():
- if isinstance( input, Repeat ):
- # Repeat elements are always initialized to have 0 units.
- state[ input.name ] = []
- elif isinstance( input, Conditional ):
- # State for a conditional is a plain dictionary.
- s = state[ input.name ] = {}
- # Get the default value for the 'test element' and use it
- # to determine the current case
- test_value = input.test_param.get_initial_value( trans, context )
- current_case = input.get_current_case( test_value, trans )
- # Store the current case in a special value
- s['__current_case__'] = current_case
- # Store the value of the test element
- s[ input.test_param.name ] = test_value
- # Recursively fill in state for selected case
- self.fill_in_new_state( trans, input.cases[current_case].inputs, s,
context )
- else:
- # `input` is just a plain parameter, get its default value
- state[ input.name ] = input.get_initial_value( trans, context )
+ state[ input.name ] = input.get_initial_value( trans, context )
def get_param_html_map( self, trans, page=0, other_values={} ):
"""
@@ -1057,6 +1039,41 @@
def params_from_strings( self, params, app, ignore_errors=False ):
return params_from_strings( self.inputs, params, app, ignore_errors )
+
+
+ def check_and_update_param_values( self, values, trans ):
+ """
+ Check that all parameters have values, and fill in with default
+ values where neccesary. This could be called after loading values
+ from a database in case new parameters have been added.
+ """
+ messages = []
+ self.check_and_update_param_values_helper( self.inputs, values, trans, messages
)
+ return messages
+
+ def check_and_update_param_values_helper( self, inputs, values, trans, messages,
context=None, prefix="" ):
+ """
+ Recursive helper for `check_and_update_param_values_helper`
+ """
+ context = ExpressionContext( values, context )
+ for input in inputs.itervalues():
+ # No value, insert the default
+ if input.name not in values:
+ messages.append( prefix + input.label )
+ values[input.name] = input.get_initial_value( trans, context )
+ # Value, visit recursively as usual
+ else:
+ if isinstance( input, Repeat ):
+ for i, d in enumerate( values[ input.name ] ):
+ rep_prefix = prefix + "%s %d > " % ( input.title, i
+ 1 )
+ self.check_and_update_param_values_helper( input.inputs, d,
trans, messages, context, rep_prefix )
+ elif isinstance( input, Conditional ):
+ group_values = values[ input.name ]
+ current = group_values["__current_case__"]
+ self.check_and_update_param_values_helper(
input.cases[current].inputs, group_values, trans, messages, context, prefix )
+ else:
+ # Regular tool parameter, no recursion needed
+ pass
def handle_unvalidated_param_values( self, input_values, app ):
"""
diff -r 22b08d47f7ba -r dae0313bf5bb lib/galaxy/tools/parameters/grouping.py
--- a/lib/galaxy/tools/parameters/grouping.py Wed Apr 29 11:53:22 2009 -0400
+++ b/lib/galaxy/tools/parameters/grouping.py Wed Apr 29 13:46:02 2009 -0400
@@ -3,6 +3,7 @@
"""
from basic import ToolParameter
+from galaxy.util.expressions import ExpressionContext
class Group( object ):
def __init__( self ):
@@ -19,6 +20,11 @@
into the preferred value form.
"""
return value
+ def get_initial_value( self, trans, context ):
+ """
+ Return the initial state/value for this group
+ """
+ raise TypeError( "Not implemented" )
class Repeat( Group ):
type = "repeat"
@@ -65,7 +71,9 @@
if isinstance( input, ToolParameter ):
callback( new_prefix, input, d[input.name], parent = d )
else:
- input.visit_inputs( new_prefix, d[input.name], callback )
+ input.visit_inputs( new_prefix, d[input.name], callback )
+ def get_initial_value( self, trans, context ):
+ return []
class Conditional( Group ):
type = "conditional"
@@ -109,6 +117,22 @@
callback( prefix, input, value[input.name], parent = value )
else:
input.visit_inputs( prefix, value[input.name], callback )
+ def get_initial_value( self, trans, context ):
+ # State for a conditional is a plain dictionary.
+ rval = {}
+ # Get the default value for the 'test element' and use it
+ # to determine the current case
+ test_value = self.test_param.get_initial_value( trans, context )
+ current_case = self.get_current_case( test_value, trans )
+ # Store the current case in a special value
+ rval['__current_case__'] = current_case
+ # Store the value of the test element
+ rval[ self.test_param.name ] = test_value
+ # Fill in state for selected case
+ child_context = ExpressionContext( rval, context )
+ for child_input in self.cases[current_case].inputs.itervalues():
+ rval[ child_input.name ] = child_input.get_initial_value( trans,
child_context )
+ return rval
class ConditionalWhen( object ):
def __init__( self ):
diff -r 22b08d47f7ba -r dae0313bf5bb lib/galaxy/web/controllers/workflow.py
--- a/lib/galaxy/web/controllers/workflow.py Wed Apr 29 11:53:22 2009 -0400
+++ b/lib/galaxy/web/controllers/workflow.py Wed Apr 29 13:46:02 2009 -0400
@@ -300,9 +300,16 @@
data = {}
data['name'] = workflow.name
data['steps'] = {}
+ data['upgrade_messages'] = {}
# For each step, rebuild the form and encode the state
for step in workflow.steps:
+ # Load from database representation
module = module_factory.from_workflow_step( trans, step )
+ # Fix any missing parameters
+ upgrade_message = module.check_and_update_state()
+ if upgrade_message:
+ data['upgrade_messages'][step.order_index] = upgrade_message
+ # Pack atrributes into plain dictionary
step_dict = {
'id': step.order_index,
'type': module.type,
@@ -312,7 +319,7 @@
'tool_errors': module.get_errors(),
'data_inputs': module.get_data_inputs(),
'data_outputs': module.get_data_outputs(),
- 'form_html': module.get_config_form()
+ 'form_html': module.get_config_form(),
}
# Connections
input_conn_dict = {}
@@ -324,6 +331,7 @@
step_dict['position'] = step.position
# Add to return value
data['steps'][step.order_index] = step_dict
+ print data['upgrade_messages']
return data
@web.json
diff -r 22b08d47f7ba -r dae0313bf5bb lib/galaxy/workflow/modules.py
--- a/lib/galaxy/workflow/modules.py Wed Apr 29 11:53:22 2009 -0400
+++ b/lib/galaxy/workflow/modules.py Wed Apr 29 13:46:02 2009 -0400
@@ -60,6 +60,13 @@
pass
def get_config_form( self ):
raise TypeError( "Abstract method" )
+
+ def check_and_update_state( self ):
+ """
+ If the state is not in sync with the current implementation of the
+ module, try to update. Returns a list of messages to be displayed
+ """
+ pass
## ---- Run time ---------------------------------------------------------
@@ -236,7 +243,11 @@
return value, error
# Update state using incoming values
errors = self.tool.update_state( self.trans, self.tool.inputs, self.state.inputs,
incoming, item_callback=item_callback )
- self.errors = errors or None
+ self.errors = errors or None
+
+ def check_and_update_state( self ):
+ return self.tool.check_and_update_param_values( self.state.inputs, self.trans )
+
def add_dummy_datasets( self, connections=None):
if connections:
# Store onnections by input name
diff -r 22b08d47f7ba -r dae0313bf5bb static/scripts/galaxy.workflow_editor.canvas.js
--- a/static/scripts/galaxy.workflow_editor.canvas.js Wed Apr 29 11:53:22 2009 -0400
+++ b/static/scripts/galaxy.workflow_editor.canvas.js Wed Apr 29 13:46:02 2009 -0400
@@ -255,6 +255,7 @@
if ( data.type ) {
this.type = data.type;
}
+ this.name = data.name;
this.form_html = data.form_html;
this.tool_state = data.tool_state;
this.tool_errors = data.tool_errors;
diff -r 22b08d47f7ba -r dae0313bf5bb templates/workflow/editor.mako
--- a/templates/workflow/editor.mako Wed Apr 29 11:53:22 2009 -0400
+++ b/templates/workflow/editor.mako Wed Apr 29 13:46:02 2009 -0400
@@ -78,7 +78,18 @@
workflow.fit_canvas_to_nodes();
scroll_to_nodes();
canvas_manager.draw_overview();
- hide_modal();
+ // Determine if any parameters were 'upgraded' and
provide message
+ upgrade_message = ""
+ $.each( data['upgrade_messages'], function( k, v ) {
+ upgrade_message += ( "<li>Step " + (
parseInt(k) + 1 ) + ": " + workflow.nodes[k].name + " -- " + v.join(
", " ) );
+ });
+ if ( upgrade_message ) {
+ show_modal( "Workflow loaded with changes",
+ "Values were not found for the following
parameters (possibly a result of tool upgrades), <br/> default values have been
used. Please review the following parameters and then save.<ul>" +
upgrade_message + "</ul>",
+ { "Continue" : hide_modal } );
+ } else {
+ hide_modal();
+ }
},
beforeSubmit: function( data ) {
show_modal( "Loading workflow", "progress"
);
@@ -88,7 +99,9 @@
});
$(document).ajaxError( function ( e, x ) {
- show_modal( "Server error", x.responseText, { "Ignore
error" : hide_modal } );
+ console.log( e, x );
+ var message = x.responseText || x.statusText || "Could not connect to
server";
+ show_modal( "Server error", message, { "Ignore error" :
hide_modal } );
return false;
});
diff -r 22b08d47f7ba -r dae0313bf5bb tools/maf/interval2maf.xml
--- a/tools/maf/interval2maf.xml Wed Apr 29 11:53:22 2009 -0400
+++ b/tools/maf/interval2maf.xml Wed Apr 29 13:46:02 2009 -0400
@@ -6,6 +6,7 @@
#end if
</command>
<inputs>
+ <param type="text" name="TEST" label="Test" />
<param format="interval" name="input1" type="data"
label="Choose intervals">
<validator type="unspecified_build" />
</param>