commit/galaxy-central: 4 new changesets
4 new commits in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/dcc40b6cdb65/ Changeset: dcc40b6cdb65 User: dannon Date: 2015-01-06 21:09:47+00:00 Summary: Initial commit of TagManager refactor. Affected #: 5 files diff -r d50ee9520583c225e48c577ab977f18fd6cb7d6a -r dcc40b6cdb65043fa0800c2852b60059b81bab91 lib/galaxy/app.py --- a/lib/galaxy/app.py +++ b/lib/galaxy/app.py @@ -7,7 +7,7 @@ import galaxy.security from galaxy.managers.collections import DatasetCollectionManager import galaxy.quota -from galaxy.tags.tag_handler import GalaxyTagHandler +from galaxy.managers.tags import GalaxyTagManager from galaxy.visualization.genomes import Genomes from galaxy.visualization.data_providers.registry import DataProviderRegistry from galaxy.visualization.registry import VisualizationsRegistry @@ -58,7 +58,7 @@ # Security helper self._configure_security() # Tag handler - self.tag_handler = GalaxyTagHandler() + self.tag_handler = GalaxyTagManager( self ) # Dataset Collection Plugins self.dataset_collections_service = DatasetCollectionManager(self) diff -r d50ee9520583c225e48c577ab977f18fd6cb7d6a -r dcc40b6cdb65043fa0800c2852b60059b81bab91 lib/galaxy/managers/collections.py --- a/lib/galaxy/managers/collections.py +++ b/lib/galaxy/managers/collections.py @@ -36,7 +36,7 @@ self.security = app.security self.hda_manager = hdas.HDAManager() self.history_manager = histories.HistoryManager() - self.tag_manager = tags.TagsManager( app ) + self.tag_manager = tags.TagManager( app ) self.ldda_manager = lddas.LDDAManager( ) def create( @@ -163,7 +163,7 @@ dataset_collection_instance.add_item_annotation( trans.sa_session, trans.get_user(), dataset_collection_instance, new_data[ 'annotation' ] ) changed[ 'annotation' ] = new_data[ 'annotation' ] if 'tags' in new_data.keys() and trans.get_user(): - self.tag_manager.set_tags_from_list( trans, dataset_collection_instance, new_data[ 'tags' ], user=trans.user ) + self.tag_manager.set_tags_from_list( trans.get_user(), dataset_collection_instance, new_data[ 'tags' ] ) if changed.keys(): trans.sa_session.flush() diff -r d50ee9520583c225e48c577ab977f18fd6cb7d6a -r dcc40b6cdb65043fa0800c2852b60059b81bab91 lib/galaxy/managers/tags.py --- a/lib/galaxy/managers/tags.py +++ b/lib/galaxy/managers/tags.py @@ -1,20 +1,317 @@ +import re +import logging +from sqlalchemy.sql import select +from sqlalchemy.sql.expression import func -class TagsManager( object ): - """ Manages CRUD operations related to tagging objects. +log = logging.getLogger( __name__ ) + + +#Item-specific information needed to perform tagging. +class ItemTagAssocInfo( object ): + def __init__( self, item_class, tag_assoc_class, item_id_col ): + self.item_class = item_class + self.tag_assoc_class = tag_assoc_class + self.item_id_col = item_id_col + + +class TagManager( object ): + """ + Manages CRUD operations related to tagging objects. """ def __init__( self, app ): self.app = app - self.tag_handler = app.tag_handler + # Minimum tag length. + self.min_tag_len = 2 + # Maximum tag length. + self.max_tag_len = 255 + # Tag separator. + self.tag_separators = ',;' + # Hierarchy separator. + self.hierarchy_separator = '.' + # Key-value separator. + self.key_value_separators = "=:" + # Initialize with known classes - add to this in subclasses. + self.item_tag_assoc_info = {} - def set_tags_from_list( self, trans, item, new_tags_list, user=None ): + def set_tags_from_list( self, user, item, new_tags_list ): #precondition: item is already security checked against user #precondition: incoming tags is a list of sanitized/formatted strings - user = user or trans.user - self.tag_handler.delete_item_tags( trans, user, item ) + self.delete_item_tags( user, item ) new_tags_str = ','.join( new_tags_list ) - self.tag_handler.apply_item_tags( trans, user, item, unicode( new_tags_str.encode( 'utf-8' ), 'utf-8' ) ) - trans.sa_session.flush() + self.apply_item_tags( user, item, unicode( new_tags_str.encode( 'utf-8' ), 'utf-8' ) ) + self.app.model.context.flush() return item.tags + + def get_tag_assoc_class( self, item_class ): + """Returns tag association class for item class.""" + return self.item_tag_assoc_info[item_class.__name__].tag_assoc_class + + def get_id_col_in_item_tag_assoc_table( self, item_class ): + """Returns item id column in class' item-tag association table.""" + return self.item_tag_assoc_info[item_class.__name__].item_id_col + + def get_community_tags( self, item=None, limit=None ): + """Returns community tags for an item.""" + # Get item-tag association class. + item_class = item.__class__ + item_tag_assoc_class = self.get_tag_assoc_class( item_class ) + if not item_tag_assoc_class: + return [] + # Build select statement. + cols_to_select = [ item_tag_assoc_class.table.c.tag_id, func.count( '*' ) ] + from_obj = item_tag_assoc_class.table.join( item_class.table ).join( self.app.model.Tag.table ) + where_clause = ( self.get_id_col_in_item_tag_assoc_table( item_class ) == item.id ) + order_by = [ func.count( "*" ).desc() ] + group_by = item_tag_assoc_class.table.c.tag_id + # Do query and get result set. + query = select( columns=cols_to_select, + from_obj=from_obj, + whereclause=where_clause, + group_by=group_by, + order_by=order_by, + limit=limit ) + result_set = self.app.model.context.execute( query ) + # Return community tags. + community_tags = [] + for row in result_set: + tag_id = row[0] + community_tags.append( self.get_tag_by_id( tag_id ) ) + return community_tags + + def get_tool_tags( self ): + result_set = self.app.model.context.execute( select( columns=[ self.app.model.ToolTagAssociation.table.c.tag_id ], + from_obj=self.app.model.ToolTagAssociation.table ).distinct() ) + + tags = [] + for row in result_set: + tag_id = row[0] + tags.append( self.get_tag_by_id( tag_id ) ) + return tags + + def remove_item_tag( self, user, item, tag_name ): + """Remove a tag from an item.""" + # Get item tag association. + item_tag_assoc = self._get_item_tag_assoc( user, item, tag_name ) + # Remove association. + if item_tag_assoc: + # Delete association. + self.app.model.context.delete( item_tag_assoc ) + item.tags.remove( item_tag_assoc ) + return True + return False + + def delete_item_tags( self, user, item ): + """Delete tags from an item.""" + # Delete item-tag associations. + for tag in item.tags: + self.app.model.context.delete( tag ) + # Delete tags from item. + del item.tags[:] + + def item_has_tag( self, user, item, tag ): + """Returns true if item is has a given tag.""" + # Get tag name. + if isinstance( tag, basestring ): + tag_name = tag + elif isinstance( tag, self.app.model.Tag ): + tag_name = tag.name + # Check for an item-tag association to see if item has a given tag. + item_tag_assoc = self._get_item_tag_assoc( user, item, tag_name ) + if item_tag_assoc: + return True + return False + + def apply_item_tag( self, user, item, name, value=None ): + # Use lowercase name for searching/creating tag. + lc_name = name.lower() + # Get or create item-tag association. + item_tag_assoc = self._get_item_tag_assoc( user, item, lc_name ) + if not item_tag_assoc: + # Create item-tag association. + # Create tag; if None, skip the tag (and log error). + tag = self._get_or_create_tag( lc_name ) + if not tag: + log.warn( "Failed to create tag with name %s" % lc_name ) + return + # Create tag association based on item class. + item_tag_assoc_class = self.get_tag_assoc_class( item.__class__ ) + item_tag_assoc = item_tag_assoc_class() + # Add tag to association. + item.tags.append( item_tag_assoc ) + item_tag_assoc.tag = tag + item_tag_assoc.user = user + # Apply attributes to item-tag association. Strip whitespace from user name and tag. + lc_value = None + if value: + lc_value = value.lower() + item_tag_assoc.user_tname = name + item_tag_assoc.user_value = value + item_tag_assoc.value = lc_value + return item_tag_assoc + + def apply_item_tags( self, user, item, tags_str ): + """Apply tags to an item.""" + # Parse tags. + parsed_tags = self.parse_tags( tags_str ) + # Apply each tag. + for name, value in parsed_tags.items(): + self.apply_item_tag( user, item, name, value ) + + def get_tags_str( self, tags ): + """Build a string from an item's tags.""" + # Return empty string if there are no tags. + if not tags: + return "" + # Create string of tags. + tags_str_list = list() + for tag in tags: + tag_str = tag.user_tname + if tag.value is not None: + tag_str += ":" + tag.user_value + tags_str_list.append( tag_str ) + return ", ".join( tags_str_list ) + + def get_tag_by_id( self, tag_id ): + """Get a Tag object from a tag id.""" + return self.app.model.context.query( self.app.model.Tag ).filter_by( id=tag_id ).first() + + def get_tag_by_name( self, tag_name ): + """Get a Tag object from a tag name (string).""" + if tag_name: + return self.app.model.context.query( self.app.model.Tag ).filter_by( name=tag_name.lower() ).first() + return None + + def _create_tag( self, tag_str ): + """Create a Tag object from a tag string.""" + tag_hierarchy = tag_str.split( self.hierarchy_separator ) + tag_prefix = "" + parent_tag = None + for sub_tag in tag_hierarchy: + # Get or create subtag. + tag_name = tag_prefix + self._scrub_tag_name( sub_tag ) + tag = self.app.model.context.query( self.app.model.Tag ).filter_by( name=tag_name).first() + if not tag: + tag = self.app.model.Tag( type=0, name=tag_name ) + # Set tag parent. + tag.parent = parent_tag + # Update parent and tag prefix. + parent_tag = tag + tag_prefix = tag.name + self.hierarchy_separator + return tag + + def _get_or_create_tag( self, tag_str ): + """Get or create a Tag object from a tag string.""" + # Scrub tag; if tag is None after being scrubbed, return None. + scrubbed_tag_str = self._scrub_tag_name( tag_str ) + if not scrubbed_tag_str: + return None + # Get item tag. + tag = self.get_tag_by_name( scrubbed_tag_str ) + # Create tag if necessary. + if tag is None: + tag = self._create_tag( scrubbed_tag_str ) + return tag + + def _get_item_tag_assoc( self, user, item, tag_name ): + """ + Return ItemTagAssociation object for a user, item, and tag string; returns None if there is + no such association. + """ + scrubbed_tag_name = self._scrub_tag_name( tag_name ) + for item_tag_assoc in item.tags: + if ( item_tag_assoc.user == user ) and ( item_tag_assoc.user_tname == scrubbed_tag_name ): + return item_tag_assoc + return None + + def parse_tags( self, tag_str ): + """ + Returns a list of raw (tag-name, value) pairs derived from a string; method scrubs tag names and values as well. + Return value is a dictionary where tag-names are keys. + """ + # Gracefully handle None. + if not tag_str: + return dict() + # Split tags based on separators. + reg_exp = re.compile( '[' + self.tag_separators + ']' ) + raw_tags = reg_exp.split( tag_str ) + # Extract name-value pairs. + name_value_pairs = dict() + for raw_tag in raw_tags: + nv_pair = self._get_name_value_pair( raw_tag ) + scrubbed_name = self._scrub_tag_name( nv_pair[0] ) + scrubbed_value = self._scrub_tag_value( nv_pair[1] ) + name_value_pairs[scrubbed_name] = scrubbed_value + return name_value_pairs + + def _scrub_tag_value( self, value ): + """Scrub a tag value.""" + # Gracefully handle None: + if not value: + return None + # Remove whitespace from value. + reg_exp = re.compile( '\s' ) + scrubbed_value = re.sub( reg_exp, "", value ) + return scrubbed_value + + def _scrub_tag_name( self, name ): + """Scrub a tag name.""" + # Gracefully handle None: + if not name: + return None + # Remove whitespace from name. + reg_exp = re.compile( '\s' ) + scrubbed_name = re.sub( reg_exp, "", name ) + # Ignore starting ':' char. + if scrubbed_name.startswith( self.hierarchy_separator ): + scrubbed_name = scrubbed_name[1:] + # If name is too short or too long, return None. + if len( scrubbed_name ) < self.min_tag_len or len( scrubbed_name ) > self.max_tag_len: + return None + return scrubbed_name + + def _scrub_tag_name_list( self, tag_name_list ): + """Scrub a tag name list.""" + scrubbed_tag_list = list() + for tag in tag_name_list: + scrubbed_tag_list.append( self._scrub_tag_name( tag ) ) + return scrubbed_tag_list + + def _get_name_value_pair( self, tag_str ): + """Get name, value pair from a tag string.""" + # Use regular expression to parse name, value. + reg_exp = re.compile( "[" + self.key_value_separators + "]" ) + name_value_pair = reg_exp.split( tag_str ) + # Add empty slot if tag does not have value. + if len( name_value_pair ) < 2: + name_value_pair.append( None ) + return name_value_pair + +class GalaxyTagManager( TagManager ): + def __init__( self, app ): + from galaxy import model + TagManager.__init__( self, app ) + self.item_tag_assoc_info["History"] = ItemTagAssocInfo( model.History, + model.HistoryTagAssociation, + model.HistoryTagAssociation.table.c.history_id ) + self.item_tag_assoc_info["HistoryDatasetAssociation"] = \ + ItemTagAssocInfo( model.HistoryDatasetAssociation, + model.HistoryDatasetAssociationTagAssociation, + model.HistoryDatasetAssociationTagAssociation.table.c.history_dataset_association_id ) + self.item_tag_assoc_info["Page"] = ItemTagAssocInfo( model.Page, + model.PageTagAssociation, + model.PageTagAssociation.table.c.page_id ) + self.item_tag_assoc_info["StoredWorkflow"] = ItemTagAssocInfo( model.StoredWorkflow, + model.StoredWorkflowTagAssociation, + model.StoredWorkflowTagAssociation.table.c.stored_workflow_id ) + self.item_tag_assoc_info["Visualization"] = ItemTagAssocInfo( model.Visualization, + model.VisualizationTagAssociation, + model.VisualizationTagAssociation.table.c.visualization_id ) + + +class CommunityTagManager( TagManager): + def __init__( self ): + from galaxy.webapps.tool_shed import model # ?huh? + TagManager.__init__( self ) diff -r d50ee9520583c225e48c577ab977f18fd6cb7d6a -r dcc40b6cdb65043fa0800c2852b60059b81bab91 lib/galaxy/tags/tag_handler.py --- a/lib/galaxy/tags/tag_handler.py +++ b/lib/galaxy/tags/tag_handler.py @@ -1,301 +0,0 @@ -import re -import logging -from sqlalchemy.sql.expression import func -from sqlalchemy.sql.expression import and_ -from sqlalchemy.sql import select - -log = logging.getLogger( __name__ ) - -# Item-specific information needed to perform tagging. -class ItemTagAssocInfo( object ): - def __init__( self, item_class, tag_assoc_class, item_id_col ): - self.item_class = item_class - self.tag_assoc_class = tag_assoc_class - self.item_id_col = item_id_col - -class TagHandler( object ): - def __init__( self ): - # Minimum tag length. - self.min_tag_len = 2 - # Maximum tag length. - self.max_tag_len = 255 - # Tag separator. - self.tag_separators = ',;' - # Hierarchy separator. - self.hierarchy_separator = '.' - # Key-value separator. - self.key_value_separators = "=:" - # Initialize with known classes - add to this in subclasses. - self.item_tag_assoc_info = {} - - def get_tag_assoc_class( self, item_class ): - """Returns tag association class for item class.""" - return self.item_tag_assoc_info[item_class.__name__].tag_assoc_class - - def get_id_col_in_item_tag_assoc_table( self, item_class ): - """Returns item id column in class' item-tag association table.""" - return self.item_tag_assoc_info[item_class.__name__].item_id_col - - def get_community_tags( self, trans, item=None, limit=None ): - """Returns community tags for an item.""" - # Get item-tag association class. - item_class = item.__class__ - item_tag_assoc_class = self.get_tag_assoc_class( item_class ) - if not item_tag_assoc_class: - return [] - # Build select statement. - cols_to_select = [ item_tag_assoc_class.table.c.tag_id, func.count( '*' ) ] - from_obj = item_tag_assoc_class.table.join( item_class.table ).join( trans.app.model.Tag.table ) - where_clause = ( self.get_id_col_in_item_tag_assoc_table( item_class ) == item.id ) - order_by = [ func.count( "*" ).desc() ] - group_by = item_tag_assoc_class.table.c.tag_id - # Do query and get result set. - query = select( columns=cols_to_select, - from_obj=from_obj, - whereclause=where_clause, - group_by=group_by, - order_by=order_by, - limit=limit ) - result_set = trans.sa_session.execute( query ) - # Return community tags. - community_tags = [] - for row in result_set: - tag_id = row[0] - community_tags.append( self.get_tag_by_id( trans, tag_id ) ) - return community_tags - - def get_tool_tags( self, trans ): - result_set = trans.sa_session.execute( select( columns=[ trans.app.model.ToolTagAssociation.table.c.tag_id ], - from_obj=trans.app.model.ToolTagAssociation.table ).distinct() ) - - tags = [] - for row in result_set: - tag_id = row[0] - tags.append( self.get_tag_by_id( trans, tag_id ) ) - return tags - - def remove_item_tag( self, trans, user, item, tag_name ): - """Remove a tag from an item.""" - # Get item tag association. - item_tag_assoc = self._get_item_tag_assoc( user, item, tag_name ) - # Remove association. - if item_tag_assoc: - # Delete association. - trans.sa_session.delete( item_tag_assoc ) - item.tags.remove( item_tag_assoc ) - return True - return False - - def delete_item_tags( self, trans, user, item ): - """Delete tags from an item.""" - # Delete item-tag associations. - for tag in item.tags: - trans.sa_session.delete( tag ) - # Delete tags from item. - del item.tags[:] - - def item_has_tag( self, trans, user, item, tag ): - """Returns true if item is has a given tag.""" - # Get tag name. - if isinstance( tag, basestring ): - tag_name = tag - elif isinstance( tag, trans.app.model.Tag ): - tag_name = tag.name - # Check for an item-tag association to see if item has a given tag. - item_tag_assoc = self._get_item_tag_assoc( user, item, tag_name ) - if item_tag_assoc: - return True - return False - - def apply_item_tag( self, trans, user, item, name, value=None ): - # Use lowercase name for searching/creating tag. - lc_name = name.lower() - # Get or create item-tag association. - item_tag_assoc = self._get_item_tag_assoc( user, item, lc_name ) - if not item_tag_assoc: - # Create item-tag association. - # Create tag; if None, skip the tag (and log error). - tag = self._get_or_create_tag( trans, lc_name ) - if not tag: - log.warn( "Failed to create tag with name %s" % lc_name ) - return - # Create tag association based on item class. - item_tag_assoc_class = self.get_tag_assoc_class( item.__class__ ) - item_tag_assoc = item_tag_assoc_class() - # Add tag to association. - item.tags.append( item_tag_assoc ) - item_tag_assoc.tag = tag - item_tag_assoc.user = user - # Apply attributes to item-tag association. Strip whitespace from user name and tag. - lc_value = None - if value: - lc_value = value.lower() - item_tag_assoc.user_tname = name - item_tag_assoc.user_value = value - item_tag_assoc.value = lc_value - return item_tag_assoc - - def apply_item_tags( self, trans, user, item, tags_str ): - """Apply tags to an item.""" - # Parse tags. - parsed_tags = self.parse_tags( tags_str ) - # Apply each tag. - for name, value in parsed_tags.items(): - self.apply_item_tag( trans, user, item, name, value ) - - def get_tags_str( self, tags ): - """Build a string from an item's tags.""" - # Return empty string if there are no tags. - if not tags: - return "" - # Create string of tags. - tags_str_list = list() - for tag in tags: - tag_str = tag.user_tname - if tag.value is not None: - tag_str += ":" + tag.user_value - tags_str_list.append( tag_str ) - return ", ".join( tags_str_list ) - - def get_tag_by_id( self, trans, tag_id ): - """Get a Tag object from a tag id.""" - return trans.sa_session.query( trans.app.model.Tag ).filter_by( id=tag_id ).first() - - def get_tag_by_name( self, trans, tag_name ): - """Get a Tag object from a tag name (string).""" - if tag_name: - return trans.sa_session.query( trans.app.model.Tag ).filter_by( name=tag_name.lower() ).first() - return None - - def _create_tag( self, trans, tag_str ): - """Create a Tag object from a tag string.""" - tag_hierarchy = tag_str.split( self.hierarchy_separator ) - tag_prefix = "" - parent_tag = None - for sub_tag in tag_hierarchy: - # Get or create subtag. - tag_name = tag_prefix + self._scrub_tag_name( sub_tag ) - tag = trans.sa_session.query( trans.app.model.Tag ).filter_by( name=tag_name).first() - if not tag: - tag = trans.app.model.Tag( type=0, name=tag_name ) - # Set tag parent. - tag.parent = parent_tag - # Update parent and tag prefix. - parent_tag = tag - tag_prefix = tag.name + self.hierarchy_separator - return tag - - def _get_or_create_tag( self, trans, tag_str ): - """Get or create a Tag object from a tag string.""" - # Scrub tag; if tag is None after being scrubbed, return None. - scrubbed_tag_str = self._scrub_tag_name( tag_str ) - if not scrubbed_tag_str: - return None - # Get item tag. - tag = self.get_tag_by_name( trans, scrubbed_tag_str ) - # Create tag if necessary. - if tag is None: - tag = self._create_tag( trans, scrubbed_tag_str ) - return tag - - def _get_item_tag_assoc( self, user, item, tag_name ): - """ - Return ItemTagAssociation object for a user, item, and tag string; returns None if there is - no such association. - """ - scrubbed_tag_name = self._scrub_tag_name( tag_name ) - for item_tag_assoc in item.tags: - if ( item_tag_assoc.user == user ) and ( item_tag_assoc.user_tname == scrubbed_tag_name ): - return item_tag_assoc - return None - - def parse_tags( self, tag_str ): - """ - Returns a list of raw (tag-name, value) pairs derived from a string; method scrubs tag names and values as well. - Return value is a dictionary where tag-names are keys. - """ - # Gracefully handle None. - if not tag_str: - return dict() - # Split tags based on separators. - reg_exp = re.compile( '[' + self.tag_separators + ']' ) - raw_tags = reg_exp.split( tag_str ) - # Extract name-value pairs. - name_value_pairs = dict() - for raw_tag in raw_tags: - nv_pair = self._get_name_value_pair( raw_tag ) - scrubbed_name = self._scrub_tag_name( nv_pair[0] ) - scrubbed_value = self._scrub_tag_value( nv_pair[1] ) - name_value_pairs[scrubbed_name] = scrubbed_value - return name_value_pairs - - def _scrub_tag_value( self, value ): - """Scrub a tag value.""" - # Gracefully handle None: - if not value: - return None - # Remove whitespace from value. - reg_exp = re.compile( '\s' ) - scrubbed_value = re.sub( reg_exp, "", value ) - return scrubbed_value - - def _scrub_tag_name( self, name ): - """Scrub a tag name.""" - # Gracefully handle None: - if not name: - return None - # Remove whitespace from name. - reg_exp = re.compile( '\s' ) - scrubbed_name = re.sub( reg_exp, "", name ) - # Ignore starting ':' char. - if scrubbed_name.startswith( self.hierarchy_separator ): - scrubbed_name = scrubbed_name[1:] - # If name is too short or too long, return None. - if len( scrubbed_name ) < self.min_tag_len or len( scrubbed_name ) > self.max_tag_len: - return None - return scrubbed_name - - def _scrub_tag_name_list( self, tag_name_list ): - """Scrub a tag name list.""" - scrubbed_tag_list = list() - for tag in tag_name_list: - scrubbed_tag_list.append( self._scrub_tag_name( tag ) ) - return scrubbed_tag_list - - def _get_name_value_pair( self, tag_str ): - """Get name, value pair from a tag string.""" - # Use regular expression to parse name, value. - reg_exp = re.compile( "[" + self.key_value_separators + "]" ) - name_value_pair = reg_exp.split( tag_str ) - # Add empty slot if tag does not have value. - if len( name_value_pair ) < 2: - name_value_pair.append( None ) - return name_value_pair - - -class GalaxyTagHandler( TagHandler ): - def __init__( self ): - from galaxy import model - TagHandler.__init__( self ) - self.item_tag_assoc_info["History"] = ItemTagAssocInfo( model.History, - model.HistoryTagAssociation, - model.HistoryTagAssociation.table.c.history_id ) - self.item_tag_assoc_info["HistoryDatasetAssociation"] = \ - ItemTagAssocInfo( model.HistoryDatasetAssociation, - model.HistoryDatasetAssociationTagAssociation, - model.HistoryDatasetAssociationTagAssociation.table.c.history_dataset_association_id ) - self.item_tag_assoc_info["Page"] = ItemTagAssocInfo( model.Page, - model.PageTagAssociation, - model.PageTagAssociation.table.c.page_id ) - self.item_tag_assoc_info["StoredWorkflow"] = ItemTagAssocInfo( model.StoredWorkflow, - model.StoredWorkflowTagAssociation, - model.StoredWorkflowTagAssociation.table.c.stored_workflow_id ) - self.item_tag_assoc_info["Visualization"] = ItemTagAssocInfo( model.Visualization, - model.VisualizationTagAssociation, - model.VisualizationTagAssociation.table.c.visualization_id ) - - -class CommunityTagHandler( TagHandler ): - def __init__( self ): - from galaxy.webapps.tool_shed import model - TagHandler.__init__( self ) diff -r d50ee9520583c225e48c577ab977f18fd6cb7d6a -r dcc40b6cdb65043fa0800c2852b60059b81bab91 lib/galaxy/web/base/controller.py --- a/lib/galaxy/web/base/controller.py +++ b/lib/galaxy/web/base/controller.py @@ -2523,8 +2523,8 @@ def set_tags_from_list( self, trans, item, new_tags_list, user=None ): # Method deprecated - try to use TagsHandler instead. - tags_manager = tags.TagsManager( trans.app ) - return tags_manager.set_tags_from_list( trans, item, new_tags_list, user=user ) + tags_manager = tags.GalaxyTagManager( trans.app ) + return tags_manager.set_tags_from_list( user, item, new_tags_list ) def get_user_tags_used( self, trans, user=None ): """ https://bitbucket.org/galaxy/galaxy-central/commits/6bb0ddd5a4cc/ Changeset: 6bb0ddd5a4cc User: dannon Date: 2015-01-06 21:14:30+00:00 Summary: Update toolshed tag handler, but I don't think it's ever used. Affected #: 2 files diff -r dcc40b6cdb65043fa0800c2852b60059b81bab91 -r 6bb0ddd5a4cc1cba6e42fb838fabcfe818fc8ddb lib/galaxy/managers/tags.py --- a/lib/galaxy/managers/tags.py +++ b/lib/galaxy/managers/tags.py @@ -312,6 +312,6 @@ class CommunityTagManager( TagManager): - def __init__( self ): + def __init__( self, app ): from galaxy.webapps.tool_shed import model # ?huh? - TagManager.__init__( self ) + TagManager.__init__( self, app ) diff -r dcc40b6cdb65043fa0800c2852b60059b81bab91 -r 6bb0ddd5a4cc1cba6e42fb838fabcfe818fc8ddb lib/galaxy/webapps/tool_shed/app.py --- a/lib/galaxy/webapps/tool_shed/app.py +++ b/lib/galaxy/webapps/tool_shed/app.py @@ -8,7 +8,7 @@ from galaxy.openid.providers import OpenIDProviders from galaxy.util.dbkeys import GenomeBuilds from galaxy.web import security -from galaxy.tags.tag_handler import CommunityTagHandler +from galaxy.managers.tags import CommunityTagManager from tool_shed.grids.repository_grid_filter_manager import RepositoryGridFilterManager import tool_shed.repository_registry import tool_shed.repository_types.registry @@ -47,7 +47,7 @@ # Initialize the Tool SHed security helper. self.security = security.SecurityHelper( id_secret=self.config.id_secret ) # initialize the Tool Shed tag handler. - self.tag_handler = CommunityTagHandler() + self.tag_handler = CommunityTagManager( self ) # Initialize the Tool Shed tool data tables. Never pass a configuration file here # because the Tool Shed should always have an empty dictionary! self.tool_data_tables = galaxy.tools.data.ToolDataTableManager( self.config.tool_data_path ) https://bitbucket.org/galaxy/galaxy-central/commits/cb061e5ef947/ Changeset: cb061e5ef947 User: dannon Date: 2015-01-06 23:27:54+00:00 Summary: Minor typo in comment. Affected #: 1 file diff -r 6bb0ddd5a4cc1cba6e42fb838fabcfe818fc8ddb -r cb061e5ef9475f61c30c90a0e9e3c9ad614cc728 lib/galaxy/webapps/tool_shed/app.py --- a/lib/galaxy/webapps/tool_shed/app.py +++ b/lib/galaxy/webapps/tool_shed/app.py @@ -44,7 +44,7 @@ self.model = mapping.init( self.config.file_path, db_url, self.config.database_engine_options ) - # Initialize the Tool SHed security helper. + # Initialize the Tool Shed security helper. self.security = security.SecurityHelper( id_secret=self.config.id_secret ) # initialize the Tool Shed tag handler. self.tag_handler = CommunityTagManager( self ) https://bitbucket.org/galaxy/galaxy-central/commits/504fd0cce279/ Changeset: 504fd0cce279 User: dannon Date: 2015-01-07 18:08:14+00:00 Summary: Add Tagging PJA. Affected #: 1 file diff -r cb061e5ef9475f61c30c90a0e9e3c9ad614cc728 -r 504fd0cce279c54003fb9c38ad9107ae9fea6ce6 lib/galaxy/jobs/actions/post.py --- a/lib/galaxy/jobs/actions/post.py +++ b/lib/galaxy/jobs/actions/post.py @@ -1,5 +1,6 @@ """ -Actions to be run at job completion. Currently only used in workflows. +Actions to be run at job completion (or output hda creation, as in the case of +immediate_actions listed below. Currently only used in workflows. """ import datetime @@ -420,6 +421,43 @@ return "Delete parent datasets of this step created in this workflow that aren't flagged as outputs." +class TagDatasetAction(DefaultJobAction): + name = "TagDatasetAction" + verbose_name = "Add tag to dataset" + + @classmethod + def execute(cls, app, sa_session, action, job, replacement_dict): + if action.action_arguments: + tags = ','.join([t.strip() for t in action.action_arguments.get('tags', '').split(',')]) + if tags: + for dataset_assoc in job.output_datasets: + if action.output_name == '' or dataset_assoc.name == action.output_name: + app.tag_handler.apply_item_tags( job.user, dataset_assoc.dataset, + unicode(tags.encode('utf-8'), 'utf-8')) + sa_session.flush() + + @classmethod + def get_config_form(cls, trans): + form = """ + if (pja.action_arguments && pja.action_arguments.tags){ + p_str += "<label for='pja__"+pja.output_name+"__TagDatasetAction__tags'>Tags:</label>\ + <input type='text' name='pja__"+pja.output_name+"__TagDatasetAction__tags' value=\\"" + pja.action_arguments.tags.replace(/"/g, """) + "\\"/>"; + } + else{ + p_str += "<label for='pja__"+pja.output_name+"__TagDatasetAction__tags'>Tags:</label>\ + <input type='text' name='pja__"+pja.output_name+"__TagDatasetAction__tags' value=''/>"; + } + """ + return get_form_template(cls.name, cls.verbose_name, form, "This action will set tags for the dataset.") + + @classmethod + def get_short_str(cls, pja): + if pja.action_arguments and pja.action_arguments.get('tags', ''): + return "Add tag(s) '%s' to '%s'." % (pja.action_arguments['tags'], pja.output_name) + else: + return "Tag addition action used without a tag specified. No tag will be added." + + class ActionBox(object): actions = { "RenameDatasetAction": RenameDatasetAction, @@ -428,11 +466,13 @@ "ColumnSetAction": ColumnSetAction, "EmailAction": EmailAction, "DeleteIntermediatesAction": DeleteIntermediatesAction, + "TagDatasetAction": TagDatasetAction, } public_actions = ['RenameDatasetAction', 'ChangeDatatypeAction', 'ColumnSetAction', 'EmailAction', - 'DeleteIntermediatesAction'] - immediate_actions = ['ChangeDatatypeAction', 'RenameDatasetAction'] + 'DeleteIntermediatesAction', 'TagDatasetAction'] + immediate_actions = ['ChangeDatatypeAction', 'RenameDatasetAction', + 'TagDatasetAction'] @classmethod def get_short_str(cls, action): Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.
participants (1)
-
commits-noreply@bitbucket.org