From b30192c206da384a06a1589c1ec29542f1c38bae Mon Sep 17 00:00:00 2001 From: a bretaud Date: Thu, 27 Nov 2014 14:18:18 +0100 Subject: [PATCH 1/2] Add an API to remove items from tool data tables --- lib/galaxy/tools/data/__init__.py | 43 ++++++++++++++++++++++ lib/galaxy/webapps/galaxy/api/tool_data.py | 41 +++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/lib/galaxy/tools/data/__init__.py b/lib/galaxy/tools/data/__init__.py index 190a9c18fd5..1638ab6e8f0 100644 --- a/lib/galaxy/tools/data/__init__.py +++ b/lib/galaxy/tools/data/__init__.py @@ -211,6 +211,13 @@ class ToolDataTable( object ): self.add_entry( entry, allow_duplicates=allow_duplicates, persist=persist, persist_on_error=persist_on_error, entry_source=entry_source, **kwd ) return self._loaded_content_version + def _remove_entry(self, values, **kwd): + raise NotImplementedError( "Abstract method" ) + + def remove_entry(self, values, **kwd): + self._remove_entry_and_reload( values,**kwd ) + return self._update_version() + def is_current_version( self, other_version ): return self._loaded_content_version == other_version @@ -506,6 +513,42 @@ class TabularToolDataTable( ToolDataTable, Dictifiable ): data_table_fh.write( "%s\n" % ( self.separator.join( fields ) ) ) return not is_error + def _remove_entry_and_reload( self, values): + + # update every file + for filename in self.filenames: + + if os.path.exists( filename ): + values = self._replace_field_separators( values ) + self.filter_file_fields( filename, values ) + else: + log.warn( "Cannot find index file '%s' for tool data table '%s'" % ( filename, self.name ) ) + + self.reload_from_files() + + def filter_file_fields( self, loc_file, values ): + """ + Reads separated lines from file and print back only the lines that pass a filter. + """ + separator_char = (lambda c: '' if c == '\t' else c)(self.separator) + + with open(loc_file) as reader: + rval = "" + for i, line in enumerate( reader ): + if line.lstrip().startswith( self.comment_char ): + rval += line + else: + line_s = line.rstrip( "\n\r" ) + if line_s: + fields = line_s.split( self.separator ) + if fields != values: + rval += line + + with open(loc_file, 'wb') as writer: + writer.write(rval) + + return rval + def _replace_field_separators( self, fields, separator=None, replace=None, comment_char=None ): #make sure none of the fields contain separator #make sure separator replace is different from comment_char, diff --git a/lib/galaxy/webapps/galaxy/api/tool_data.py b/lib/galaxy/webapps/galaxy/api/tool_data.py index 191c547ae5b..f6aa21f7a0c 100644 --- a/lib/galaxy/webapps/galaxy/api/tool_data.py +++ b/lib/galaxy/webapps/galaxy/api/tool_data.py @@ -20,3 +20,44 @@ class ToolData( BaseAPIController ): @web.expose_api def show( self, trans, id, **kwds ): return trans.app.tool_data_tables.data_tables[id].to_dict(view='element') + + @web.require_admin + @web.expose_api + def delete( self, trans, id, **kwd ): + """ + DELETE /api/tool_data/{id} + Removes a role from a group + + :type id: str + :param id: the encoded id of the history to delete + :type kwd: dict + :param kwd: (required) dictionary structure containing: + + * payload: a dictionary itself containing: + * values: separated list of column contents, there must be a value for all the columns of the data table + """ + decoded_tool_data_id = id + + try: + data_table = trans.app.tool_data_tables.data_tables.get(decoded_tool_data_id) + except: + data_table = None + if not data_table: + trans.response.status = 400 + return "Invalid data table id ( %s ) specified." % str( decoded_tool_data_id ) + + values = None + if kwd.get( 'payload', None ): + values = kwd['payload'].get( 'values', '' ) + + if not values: + trans.response.status = 400 + return "Invalid data table item ( %s ) specified." % str( values ) + + split_values = values.split("\t") + + if len(split_values) != len(data_table.get_column_name_list()): + trans.response.status = 400 + return "Invalid data table item ( %s ) specified. Wrong number of columns (%s given, %s required)." % ( str( values ), str(len(split_values)), str(len(data_table.get_column_name_list()))) + + return data_table.remove_entry(split_values) From ecb165157e7b3f59564bdc3d73f021f56e6f8283 Mon Sep 17 00:00:00 2001 From: a bretaud Date: Thu, 11 Dec 2014 17:02:05 +0100 Subject: [PATCH 2/2] fix method names and api doc --- lib/galaxy/tools/data/__init__.py | 8 ++++---- lib/galaxy/webapps/galaxy/api/tool_data.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/galaxy/tools/data/__init__.py b/lib/galaxy/tools/data/__init__.py index 1638ab6e8f0..f4a97c3cab9 100644 --- a/lib/galaxy/tools/data/__init__.py +++ b/lib/galaxy/tools/data/__init__.py @@ -211,11 +211,11 @@ class ToolDataTable( object ): self.add_entry( entry, allow_duplicates=allow_duplicates, persist=persist, persist_on_error=persist_on_error, entry_source=entry_source, **kwd ) return self._loaded_content_version - def _remove_entry(self, values, **kwd): + def _remove_entry(self, values): raise NotImplementedError( "Abstract method" ) - def remove_entry(self, values, **kwd): - self._remove_entry_and_reload( values,**kwd ) + def remove_entry(self, values): + self._remove_entry( values ) return self._update_version() def is_current_version( self, other_version ): @@ -513,7 +513,7 @@ class TabularToolDataTable( ToolDataTable, Dictifiable ): data_table_fh.write( "%s\n" % ( self.separator.join( fields ) ) ) return not is_error - def _remove_entry_and_reload( self, values): + def _remove_entry( self, values): # update every file for filename in self.filenames: diff --git a/lib/galaxy/webapps/galaxy/api/tool_data.py b/lib/galaxy/webapps/galaxy/api/tool_data.py index f6aa21f7a0c..9ecc92a6182 100644 --- a/lib/galaxy/webapps/galaxy/api/tool_data.py +++ b/lib/galaxy/webapps/galaxy/api/tool_data.py @@ -26,10 +26,10 @@ class ToolData( BaseAPIController ): def delete( self, trans, id, **kwd ): """ DELETE /api/tool_data/{id} - Removes a role from a group + Removes an item from a data table :type id: str - :param id: the encoded id of the history to delete + :param id: the id of the data table containing the item to delete :type kwd: dict :param kwd: (required) dictionary structure containing: