diff --git a/lib/galaxy/tool_util/xsd/galaxy.xsd b/lib/galaxy/tool_util/xsd/galaxy.xsd index 4e99440dc70..7dc2cf01deb 100644 --- a/lib/galaxy/tool_util/xsd/galaxy.xsd +++ b/lib/galaxy/tool_util/xsd/galaxy.xsd @@ -3566,7 +3566,7 @@ is the ``none`` preset. `` tag set - filter out values obtained from a locally stored file (e.g. +```` tag set - modify (e.g. remove, add, sort, ...) the list of values obtained from a locally stored file (e.g. a tool data table) or a dataset in the current history. ### Examples @@ -3669,19 +3669,39 @@ demonstrates splitting up strings into multiple values. +in the ``filter_types`` dictionary. + +Deprecated filter types: + +* ``attribute_value_splitter`` + ]]> - Column targeted by this filter - this -attribute is unused and invalid if ``type`` is ``add_value`` or ``remove_value``. -This can be a column index or a column name. + Column targeted by this filter given as column index or a column name. Invalid if ``type`` is ``add_value`` or ``remove_value``. + @@ -3723,7 +3743,7 @@ only used if ``multiple`` is set to ``true``.]]> If ``true``, keep columns matching the value, if ``false`` discard columns matching the value. Used when ``type`` is -either ``static_value`` or ``param_value``. +either ``static_value``, ``regexp`` or ``param_value``. @@ -3731,7 +3751,7 @@ either ``static_value`` or ``param_value``. Target value of the operations - has slightly different meanings depending on ``type``. For instance when ``type`` is ``add_value`` it is the value to add to the list and when ``type`` is -``static_value`` it is the value compared against. +``static_value`` or ``regexp`` it is the value compared against. @@ -5509,6 +5529,7 @@ and ``bibtex`` are the only supported options. + diff --git a/lib/galaxy/tools/parameters/dynamic_options.py b/lib/galaxy/tools/parameters/dynamic_options.py index 6f6acb5b8b8..5f449300fac 100644 --- a/lib/galaxy/tools/parameters/dynamic_options.py +++ b/lib/galaxy/tools/parameters/dynamic_options.py @@ -4,6 +4,7 @@ on the values of other parameters or other aspects of the current state) """ import logging import os +import re from six import StringIO @@ -74,7 +75,44 @@ class StaticValueFilter(Filter): except Exception: pass for fields in options: - if (self.keep and fields[self.column] == filter_value) or (not self.keep and fields[self.column] != filter_value): + if self.keep == (filter_value == fields[self.column]): + rval.append(fields) + return rval + + +class RegexpFilter(Filter): + """ + Filters a list of options on a column by a regular expression. + + Type: regexp + + Required Attributes: + value: regular expression to compare to + column: column in options to compare with + Optional Attributes: + keep: Keep columns matching the regexp (True) + Discard columns matching the regexp (False) + """ + + def __init__(self, d_option, elem): + Filter.__init__(self, d_option, elem) + self.value = elem.get("value", None) + assert self.value is not None, "Required 'value' attribute missing from filter" + column = elem.get("column", None) + assert column is not None, "Required 'column' attribute missing from filter, when loading from file" + self.column = d_option.column_spec_to_index(column) + self.keep = string_as_bool(elem.get("keep", 'True')) + + def filter_options(self, options, trans, other_values): + rval = [] + filter_value = self.value + try: + filter_value = User.expand_user_properties(trans.user, filter_value) + except Exception: + pass + filter_pattern = re.compile(filter_value) + for fields in options: + if self.keep == (not filter_pattern.match(fields[self.column]) is None): rval.append(fields) return rval @@ -141,6 +179,9 @@ class DataMetaFilter(Filter): if not isinstance(ref, HistoryDatasetAssociation) and not is_data_or_data_list: return [] # not a valid dataset + # get the metadata value. for lists (of data sets) and collections + # the meta data value of all elements is determined if its the same + # for all, if different are found the filter returns an empty list if is_data_list: meta_value = None for single_ref in ref: @@ -155,6 +196,8 @@ class DataMetaFilter(Filter): else: meta_value = ref.metadata.get(self.key, None) + # if no meta data value could be determined just return a copy + # of the original options if meta_value is None: return [(disp_name, optval, selected) for disp_name, optval, selected in options] @@ -226,7 +269,7 @@ class ParamValueFilter(Filter): ref = str(ref) rval = [] for fields in options: - if (self.keep and fields[self.column] == ref) or (not self.keep and fields[self.column] != ref): + if self.keep == (fields[self.column] == ref): rval.append(fields) return rval @@ -292,6 +335,8 @@ class AttributeValueSplitterFilter(Filter): """ Filters a list of attribute-value pairs to be unique attribute names. + DEPRECATED: just replace with 2 rounds of MultipleSplitterFilter + Type: attribute_value_splitter Required Attributes: @@ -442,20 +487,13 @@ class SortByColumnFilter(Filter): self.column = d_option.column_spec_to_index(column) def filter_options(self, options, trans, other_values): - rval = [] - for fields in options: - for j in range(0, len(rval)): - if fields[self.column] < rval[j][self.column]: - rval.insert(j, fields) - break - else: - rval.append(fields) - return rval + return sorted(options, key=lambda x: x[self.column]) filter_types = dict(data_meta=DataMetaFilter, param_value=ParamValueFilter, static_value=StaticValueFilter, + regexp=RegexpFilter, unique_value=UniqueValueFilter, multiple_splitter=MultipleSplitterFilter, attribute_value_splitter=AttributeValueSplitterFilter, diff --git a/test/functional/tools/dbkey_filter_multi_input.xml b/test/functional/tools/dbkey_filter_multi_input.xml index 7ecaeaaf943..e26bec1febe 100644 --- a/test/functional/tools/dbkey_filter_multi_input.xml +++ b/test/functional/tools/dbkey_filter_multi_input.xml @@ -1,5 +1,5 @@ - Filter select on dbkey of multiple inputs + Filter select on dbkey of multiple inputs and use of named column > $output; @@ -10,7 +10,7 @@ - + @@ -31,4 +31,4 @@ - \ No newline at end of file + diff --git a/test/functional/tools/filter_static_regexp.xml b/test/functional/tools/filter_static_regexp.xml new file mode 100644 index 00000000000..367a16f2484 --- /dev/null +++ b/test/functional/tools/filter_static_regexp.xml @@ -0,0 +1,94 @@ + + Filter by static value and regexp + + echo $index_static > '$output' + echo $index_static_keep >> '$output' + echo $index_regexp >> '$output' + echo $index_regexp_keep >> '$output' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/functional/tools/samples_tool_conf.xml b/test/functional/tools/samples_tool_conf.xml index f1e9bca3d20..55de00692c1 100644 --- a/test/functional/tools/samples_tool_conf.xml +++ b/test/functional/tools/samples_tool_conf.xml @@ -34,6 +34,7 @@ +