From 06cc5f58288fbd6e3762a91fdd8e76b715f7c4e6 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 27 Dec 2016 15:11:03 -0500 Subject: [PATCH 1/5] Fix implicit conversion for sessionless tool API calls. Also fixes it for backgrounded workflow invocations (fixes #3268 reported by @guerler). Includes a new test tool w/test definition that exercises this functionality. This tool fails without these changes. --- lib/galaxy/datatypes/data.py | 4 ++-- lib/galaxy/model/__init__.py | 4 ++-- lib/galaxy/tools/actions/__init__.py | 6 ++--- test/functional/tools/implicit_conversion.xml | 23 +++++++++++++++++++ .../tools/sample_datatypes_conf.xml | 4 +++- test/functional/tools/samples_tool_conf.xml | 1 + 6 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 test/functional/tools/implicit_conversion.xml diff --git a/lib/galaxy/datatypes/data.py b/lib/galaxy/datatypes/data.py index 2c6ff80ce84..7d5ccc813e9 100644 --- a/lib/galaxy/datatypes/data.py +++ b/lib/galaxy/datatypes/data.py @@ -502,7 +502,7 @@ class Data( object ): """Returns ( target_ext, existing converted dataset )""" return datatypes_registry.find_conversion_destination_for_dataset_by_extensions( dataset, accepted_formats, **kwd ) - def convert_dataset(self, trans, original_dataset, target_type, return_output=False, visible=True, deps=None, target_context=None): + def convert_dataset(self, trans, original_dataset, target_type, return_output=False, visible=True, deps=None, target_context=None, history=None): """This function adds a job to the queue to convert a dataset to another type. Returns a message about success/failure.""" converter = trans.app.datatypes_registry.get_converter_by_target_type( original_dataset.ext, target_type ) @@ -525,7 +525,7 @@ class Data( object ): params[input_name] = original_dataset # Run converter, job is dispatched through Queue - converted_dataset = converter.execute( trans, incoming=params, set_output_hid=visible )[1] + converted_dataset = converter.execute( trans, incoming=params, set_output_hid=visible, history=history )[1] if len(params) > 0: trans.log_event( "Converter params: %s" % (str(params)), tool_id=converter.id ) if not visible: diff --git a/lib/galaxy/model/__init__.py b/lib/galaxy/model/__init__.py index 4794ce037f6..a1918759ba3 100644 --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -2041,7 +2041,7 @@ class DatasetInstance( object ): depends_list = [] return dict([ (dep, self.get_converted_dataset(trans, dep)) for dep in depends_list ]) - def get_converted_dataset(self, trans, target_ext, target_context=None): + def get_converted_dataset(self, trans, target_ext, target_context=None, history=None): """ Return converted dataset(s) if they exist, along with a dict of dependencies. If not converted yet, do so and return None (the first time). If unconvertible, raise exception. @@ -2080,7 +2080,7 @@ class DatasetInstance( object ): raise NoConverterException("A dependency (%s) is missing a converter." % dependency) except KeyError: pass # No deps - new_dataset = next(iter(self.datatype.convert_dataset( trans, self, target_ext, return_output=True, visible=False, deps=deps, target_context=target_context ).values())) + new_dataset = next(iter(self.datatype.convert_dataset( trans, self, target_ext, return_output=True, visible=False, deps=deps, target_context=target_context, history=history ).values())) new_dataset.name = self.name self.copy_attributes( new_dataset ) assoc = ImplicitlyConvertedDatasetAssociation( parent=self, file_type=target_ext, dataset=new_dataset, metadata_safe=False ) diff --git a/lib/galaxy/tools/actions/__init__.py b/lib/galaxy/tools/actions/__init__.py index e4ff04a46c2..349e94a43f9 100644 --- a/lib/galaxy/tools/actions/__init__.py +++ b/lib/galaxy/tools/actions/__init__.py @@ -41,7 +41,7 @@ class ToolAction( object ): class DefaultToolAction( object ): """Default tool action is to run an external command""" - def collect_input_datasets( self, tool, param_values, trans, current_user_roles=None ): + def _collect_input_datasets( self, tool, param_values, trans, history, current_user_roles=None ): """ Collect any dataset inputs from incoming. Returns a mapping from parameter name to Dataset instance for each tool parameter that is @@ -66,7 +66,7 @@ class DefaultToolAction( object ): if converted_dataset: data = converted_dataset else: - data = data.get_converted_dataset( trans, target_ext, target_context=parent ) + data = data.get_converted_dataset( trans, target_ext, target_context=parent, history=history ) if not trans.app.security_agent.can_access_dataset( current_user_roles, data.dataset ): raise Exception( "User does not have permission to use a dataset (%s) provided for input." % data.id ) @@ -189,7 +189,7 @@ class DefaultToolAction( object ): # input datasets can process these normally. inp_dataset_collections = self.collect_input_dataset_collections( tool, incoming ) # Collect any input datasets from the incoming parameters - inp_data = self.collect_input_datasets( tool, incoming, trans, current_user_roles=current_user_roles ) + inp_data = self._collect_input_datasets( tool, incoming, trans, history=history, current_user_roles=current_user_roles ) return history, inp_data, inp_dataset_collections diff --git a/test/functional/tools/implicit_conversion.xml b/test/functional/tools/implicit_conversion.xml new file mode 100644 index 00000000000..8a7044cebd3 --- /dev/null +++ b/test/functional/tools/implicit_conversion.xml @@ -0,0 +1,23 @@ + + + cut -f 1 '$input1' > 'col_output' + + + + + + + + + + + + + + + + + + + + diff --git a/test/functional/tools/sample_datatypes_conf.xml b/test/functional/tools/sample_datatypes_conf.xml index 3891cad99c4..f18a2da3a99 100644 --- a/test/functional/tools/sample_datatypes_conf.xml +++ b/test/functional/tools/sample_datatypes_conf.xml @@ -4,7 +4,9 @@ - + + + diff --git a/test/functional/tools/samples_tool_conf.xml b/test/functional/tools/samples_tool_conf.xml index 54e6ad0fc30..71857bc8f68 100644 --- a/test/functional/tools/samples_tool_conf.xml +++ b/test/functional/tools/samples_tool_conf.xml @@ -72,6 +72,7 @@ + From b6e9f4a6eefb53d2f3b8b415b80e1a674bd7cc8d Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 27 Dec 2016 15:45:51 -0500 Subject: [PATCH 2/5] Fix workflow extraction of dataset/collections name. It works fine if multiple names are chosen, but if only one input is selected and named it doesn't work. This is a temporary workaround until that page is replaced by API calls with superior typing. Fixes #3247 reported by @peterjc. --- lib/galaxy/webapps/galaxy/controllers/workflow.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/galaxy/webapps/galaxy/controllers/workflow.py b/lib/galaxy/webapps/galaxy/controllers/workflow.py index 7d1e742b2d3..37150705caa 100644 --- a/lib/galaxy/webapps/galaxy/controllers/workflow.py +++ b/lib/galaxy/webapps/galaxy/controllers/workflow.py @@ -1052,6 +1052,10 @@ class WorkflowController( BaseUIController, SharableMixin, UsesStoredWorkflowMix history=history ) else: + # If there is just one dataset name selected or one dataset collection, these + # come through as string types instead of lists. xref #3247. + dataset_names = util.listify(dataset_names) + dataset_collection_names = util.listify(dataset_collection_names) stored_workflow = extract_workflow( trans, user=user, From 79752b5b4a0e80a6cd4b02aed8cfd93d8d61208a Mon Sep 17 00:00:00 2001 From: John Chilton Date: Mon, 9 Jan 2017 15:11:34 -0500 Subject: [PATCH 3/5] Do not allow recursive replacements in PJA. May result in infinite loops in workflow scheduling threads. --- lib/galaxy/jobs/actions/post.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/galaxy/jobs/actions/post.py b/lib/galaxy/jobs/actions/post.py index 834fc9c6c42..f8cb6a5ce86 100644 --- a/lib/galaxy/jobs/actions/post.py +++ b/lib/galaxy/jobs/actions/post.py @@ -110,11 +110,12 @@ class RenameDatasetAction(DefaultJobAction): # "replace" option so you can replace a portion of the name, # support multiple #{name} in one rename action... - while new_name.find("#{") > -1: + start_pos = 0 + while new_name.find("#{", start_pos) > -1: to_be_replaced = "" # This assumes a single instance of #{variable} will exist - start_pos = new_name.find("#{") + 2 - end_pos = new_name.find("}") + start_pos = new_name.find("#{", start_pos) + 2 + end_pos = new_name.find("}", start_pos) to_be_replaced = new_name[start_pos:end_pos] input_file_var = to_be_replaced # Pull out the piped controls and store them for later From 2d991bba073a9e1f40b18f6c927e4adf6ca1ddb9 Mon Sep 17 00:00:00 2001 From: yhoogstrate Date: Mon, 2 Jan 2017 16:43:23 +0100 Subject: [PATCH 4/5] Escapes some variables --- config/plugins/visualizations/charts/templates/charts.mako | 2 +- config/plugins/visualizations/csg/templates/csg.mako | 2 +- config/plugins/visualizations/graphviz/templates/graphviz.mako | 2 +- .../visualizations/scatterplot/templates/scatterplot.mako | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/plugins/visualizations/charts/templates/charts.mako b/config/plugins/visualizations/charts/templates/charts.mako index a65ede31819..7bdaa6c0140 100644 --- a/config/plugins/visualizations/charts/templates/charts.mako +++ b/config/plugins/visualizations/charts/templates/charts.mako @@ -8,7 +8,7 @@ - ${hda.name} | ${visualization_name} + ${hda.name | h} | ${visualization_name} ${h.js( 'libs/jquery/jquery', 'libs/jquery/jquery-ui', 'libs/jquery/select2', diff --git a/config/plugins/visualizations/csg/templates/csg.mako b/config/plugins/visualizations/csg/templates/csg.mako index d986a7f4b6a..9320a0f7130 100644 --- a/config/plugins/visualizations/csg/templates/csg.mako +++ b/config/plugins/visualizations/csg/templates/csg.mako @@ -7,7 +7,7 @@ - ${hda.name} | ${visualization_name} + ${hda.name | h} | ${visualization_name} ${h.javascript_link( app_root + 'dat.gui.min.js' )} ${h.javascript_link( app_root + 'three.min.js' )} ${h.javascript_link( app_root + 'Detector.js' )} diff --git a/config/plugins/visualizations/graphviz/templates/graphviz.mako b/config/plugins/visualizations/graphviz/templates/graphviz.mako index 6f6d689eb43..17cb63a86d4 100644 --- a/config/plugins/visualizations/graphviz/templates/graphviz.mako +++ b/config/plugins/visualizations/graphviz/templates/graphviz.mako @@ -5,7 +5,7 @@ - ${hda.name} | ${visualization_name} + ${hda.name | h} | ${visualization_name} <% root = h.url_for( '/' ) %> diff --git a/config/plugins/visualizations/scatterplot/templates/scatterplot.mako b/config/plugins/visualizations/scatterplot/templates/scatterplot.mako index 036ffc19037..e8a5bcabecd 100644 --- a/config/plugins/visualizations/scatterplot/templates/scatterplot.mako +++ b/config/plugins/visualizations/scatterplot/templates/scatterplot.mako @@ -16,7 +16,7 @@ -${title or default_title} | ${visualization_display_name} +${title or default_title | h} | ${visualization_display_name} ## ---------------------------------------------------------------------------- ${h.css( 'base', 'jquery-ui/smoothness/jquery-ui')} From d49e014a63641db37814ab0b31b7aa4d1eded786 Mon Sep 17 00:00:00 2001 From: Dannon Baker Date: Wed, 11 Jan 2017 10:58:37 -0500 Subject: [PATCH 5/5] The /user/logout endpoint is now used for both remote and internal users to handle logout logic, and should be accessible here. --- lib/galaxy/web/framework/middleware/remoteuser.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/galaxy/web/framework/middleware/remoteuser.py b/lib/galaxy/web/framework/middleware/remoteuser.py index 5446718b068..b2188f0aaaf 100644 --- a/lib/galaxy/web/framework/middleware/remoteuser.py +++ b/lib/galaxy/web/framework/middleware/remoteuser.py @@ -150,6 +150,7 @@ class RemoteUser( object ): '/user/api_keys', '/user/edit_username', '/user/dbkeys', + '/user/logout', '/user/toolbox_filters', '/user/set_default_permissions', '/user/change_communication',