details:
http://www.bx.psu.edu/hg/galaxy/rev/5b99d58c6f54
changeset: 3213:5b99d58c6f54
user: jeremy goecks <jeremy.goecks(a)emory.edu>
date: Thu Jan 07 13:41:44 2010 -0500
description:
Full model & controller (but not yet view/UI) support for community tags and workflows
tags. Specific enhancements include: (1) added columns to associate users with tags; (2)
added tables to support workflow tagging; (3) augmented data model to support community
tags; (4) refactored tag handler to use both individual and community tags; and (5) added
individual and community tag columns for grids. Also fixed a couple bugs in grid
framework.
diffstat:
lib/galaxy/model/__init__.py | 11 +-
lib/galaxy/model/mapping.py | 51 ++-
lib/galaxy/model/migrate/versions/0031_community_and_workflow_tags.py | 171 ++++++++++
lib/galaxy/tags/tag_handler.py | 19 +-
lib/galaxy/web/controllers/dataset.py | 2 +-
lib/galaxy/web/controllers/history.py | 4 +-
lib/galaxy/web/controllers/page.py | 4 +-
lib/galaxy/web/controllers/requests.py | 2 +-
lib/galaxy/web/controllers/requests_admin.py | 2 +-
lib/galaxy/web/controllers/tag.py | 105 ++---
lib/galaxy/web/framework/__init__.py | 7 +-
lib/galaxy/web/framework/helpers/grids.py | 62 ++-
templates/dataset/edit_attributes.mako | 4 +-
templates/grid_base.mako | 28 +-
templates/grid_base_async.mako | 10 +-
templates/history/view.mako | 8 +-
templates/page/display.mako | 4 +-
templates/page/history_annotation_table.mako | 4 +-
templates/root/history.mako | 4 +-
templates/tagging_common.mako | 56 +-
20 files changed, 388 insertions(+), 170 deletions(-)
diffs (1151 lines):
diff -r 3aa8c1020261 -r 5b99d58c6f54 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py Thu Jan 07 11:13:38 2010 -0500
+++ b/lib/galaxy/model/__init__.py Thu Jan 07 13:41:44 2010 -0500
@@ -1424,8 +1424,9 @@
return "Tag(id=%s, type=%i, parent_id=%s, name=%s)" % ( self.id,
self.type, self.parent_id, self.name )
class ItemTagAssociation ( object ):
- def __init__( self, id=None, item_id=None, tag_id=None, user_tname=None, value=None
):
+ def __init__( self, id=None, user=None, item_id=None, tag_id=None, user_tname=None,
value=None ):
self.id = id
+ self.user = user
self.item_id = item_id
self.tag_id = tag_id
self.user_tname = user_tname
@@ -1437,7 +1438,7 @@
class HistoryTagAssociation ( ItemTagAssociation ):
pass
-
+
class DatasetTagAssociation ( ItemTagAssociation ):
pass
@@ -1447,6 +1448,12 @@
class PageTagAssociation ( ItemTagAssociation ):
pass
+class WorkflowTagAssociation ( ItemTagAssociation ):
+ pass
+
+class StoredWorkflowTagAssociation ( ItemTagAssociation ):
+ pass
+
class UserPreference ( object ):
def __init__( self, name=None, value=None ):
self.name = name
diff -r 3aa8c1020261 -r 5b99d58c6f54 lib/galaxy/model/mapping.py
--- a/lib/galaxy/model/mapping.py Thu Jan 07 11:13:38 2010 -0500
+++ b/lib/galaxy/model/mapping.py Thu Jan 07 13:41:44 2010 -0500
@@ -710,6 +710,7 @@
Column( "id", Integer, primary_key=True ),
Column( "history_id", Integer, ForeignKey( "history.id" ),
index=True ),
Column( "tag_id", Integer, ForeignKey( "tag.id" ), index=True ),
+ Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ),
index=True ),
Column( "user_tname", TrimmedString(255), index=True),
Column( "value", TrimmedString(255), index=True),
Column( "user_value", TrimmedString(255), index=True) )
@@ -718,6 +719,7 @@
Column( "id", Integer, primary_key=True ),
Column( "dataset_id", Integer, ForeignKey( "dataset.id" ),
index=True ),
Column( "tag_id", Integer, ForeignKey( "tag.id" ), index=True ),
+ Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ),
index=True ),
Column( "user_tname", TrimmedString(255), index=True),
Column( "value", TrimmedString(255), index=True),
Column( "user_value", TrimmedString(255), index=True) )
@@ -726,14 +728,34 @@
Column( "id", Integer, primary_key=True ),
Column( "history_dataset_association_id", Integer, ForeignKey(
"history_dataset_association.id" ), index=True ),
Column( "tag_id", Integer, ForeignKey( "tag.id" ), index=True ),
+ Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ),
index=True ),
Column( "user_tname", TrimmedString(255), index=True),
Column( "value", TrimmedString(255), index=True),
Column( "user_value", TrimmedString(255), index=True) )
+
+WorkflowTagAssociation.table = Table( "workflow_tag_association", metadata,
+ Column( "id", Integer, primary_key=True ),
+ Column( "workflow_id", Integer, ForeignKey( "workflow.id" ),
index=True ),
+ Column( "tag_id", Integer, ForeignKey( "tag.id" ), index=True ),
+ Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ),
index=True ),
+ Column( "user_tname", Unicode(255), index=True),
+ Column( "value", Unicode(255), index=True),
+ Column( "user_value", Unicode(255), index=True) )
+
+StoredWorkflowTagAssociation.table = Table( "stored_workflow_tag_association",
metadata,
+ Column( "id", Integer, primary_key=True ),
+ Column( "stored_workflow_id", Integer, ForeignKey(
"stored_workflow.id" ), index=True ),
+ Column( "tag_id", Integer, ForeignKey( "tag.id" ), index=True ),
+ Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ),
index=True ),
+ Column( "user_tname", Unicode(255), index=True),
+ Column( "value", Unicode(255), index=True),
+ Column( "user_value", Unicode(255), index=True) )
PageTagAssociation.table = Table( "page_tag_association", metadata,
Column( "id", Integer, primary_key=True ),
Column( "page_id", Integer, ForeignKey( "page.id" ), index=True
),
Column( "tag_id", Integer, ForeignKey( "tag.id" ), index=True ),
+ Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ),
index=True ),
Column( "user_tname", TrimmedString(255), index=True),
Column( "value", TrimmedString(255), index=True),
Column( "user_value", TrimmedString(255), index=True) )
@@ -1127,7 +1149,9 @@
properties=dict( steps=relation( WorkflowStep, backref='workflow',
order_by=asc(WorkflowStep.table.c.order_index),
cascade="all, delete-orphan",
- lazy=False ) ) )
+ lazy=False ),
+ tags=relation(WorkflowTagAssociation,
order_by=WorkflowTagAssociation.table.c.id, backref="workflows")
+ ) )
assign_mapper( context, WorkflowStep, WorkflowStep.table )
@@ -1181,7 +1205,8 @@
primaryjoin=( StoredWorkflow.table.c.id ==
Workflow.table.c.stored_workflow_id ) ),
latest_workflow=relation( Workflow, post_update=True,
primaryjoin=(
StoredWorkflow.table.c.latest_workflow_id == Workflow.table.c.id ),
- lazy=False )
+ lazy=False ),
+ tags=relation(StoredWorkflowTagAssociation,
order_by=StoredWorkflowTagAssociation.table.c.id, backref="stored_workflows")
) )
assign_mapper( context, StoredWorkflowUserShareAssociation,
StoredWorkflowUserShareAssociation.table,
@@ -1225,24 +1250,28 @@
) )
assign_mapper( context, HistoryTagAssociation, HistoryTagAssociation.table,
- properties=dict( tag=relation(Tag, backref="tagged_histories") ),
- primary_key=[HistoryTagAssociation.table.c.history_id,
HistoryTagAssociation.table.c.tag_id]
+ properties=dict( tag=relation(Tag, backref="tagged_histories"),
user=relation( User ) )
)
assign_mapper( context, DatasetTagAssociation, DatasetTagAssociation.table,
- properties=dict( tag=relation(Tag, backref="tagged_datasets") ),
- primary_key=[DatasetTagAssociation.table.c.dataset_id,
DatasetTagAssociation.table.c.tag_id]
+ properties=dict( tag=relation(Tag, backref="tagged_datasets"),
user=relation( User ) )
)
assign_mapper( context, HistoryDatasetAssociationTagAssociation,
HistoryDatasetAssociationTagAssociation.table,
- properties=dict( tag=relation(Tag,
backref="tagged_history_dataset_associations") ),
-
primary_key=[HistoryDatasetAssociationTagAssociation.table.c.history_dataset_association_id,
HistoryDatasetAssociationTagAssociation.table.c.tag_id]
+ properties=dict( tag=relation(Tag,
backref="tagged_history_dataset_associations"), user=relation( User ) )
)
assign_mapper( context, PageTagAssociation, PageTagAssociation.table,
- properties=dict( tag=relation(Tag, backref="tagged_pages") ),
- primary_key=[PageTagAssociation.table.c.page_id,
PageTagAssociation.table.c.tag_id]
- )
+ properties=dict( tag=relation(Tag, backref="tagged_pages"), user=relation(
User ) )
+ )
+
+assign_mapper( context, WorkflowTagAssociation, WorkflowTagAssociation.table,
+ properties=dict( tag=relation(Tag, backref="tagged_workflows"),
user=relation( User ) )
+ )
+
+assign_mapper( context, StoredWorkflowTagAssociation,
StoredWorkflowTagAssociation.table,
+ properties=dict( tag=relation(Tag, backref="tagged_stored_workflows"),
user=relation( User ) )
+ )
assign_mapper( context, UserPreference, UserPreference.table,
properties = {}
diff -r 3aa8c1020261 -r 5b99d58c6f54
lib/galaxy/model/migrate/versions/0031_community_and_workflow_tags.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/model/migrate/versions/0031_community_and_workflow_tags.py Thu Jan 07
13:41:44 2010 -0500
@@ -0,0 +1,171 @@
+"""
+Migration script to (a) add and populate necessary columns for doing community tagging of
histories, datasets, and pages and \
+(b) add table for doing individual and community tagging of workflows.
+
+SQLite does not support 'ALTER TABLE ADD FOREIGN KEY', so this script will
generate error messages when run against \
+SQLite; however, script does execute successfully against SQLite.
+"""
+
+from sqlalchemy import *
+from sqlalchemy.orm import *
+from migrate import *
+from migrate.changeset import *
+
+import logging
+log = logging.getLogger( __name__ )
+
+metadata = MetaData( migrate_engine )
+db_session = scoped_session( sessionmaker( bind=migrate_engine, autoflush=False,
autocommit=True ) )
+
+StoredWorkflowTagAssociation_table = Table( "stored_workflow_tag_association",
metadata,
+ Column( "id", Integer, primary_key=True ),
+ Column( "stored_workflow_id", Integer, ForeignKey(
"stored_workflow.id" ), index=True ),
+ Column( "tag_id", Integer, ForeignKey( "tag.id" ), index=True ),
+ Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ),
index=True ),
+ Column( "user_tname", Unicode(255), index=True),
+ Column( "value", Unicode(255), index=True),
+ Column( "user_value", Unicode(255), index=True) )
+
+WorkflowTagAssociation_table = Table( "workflow_tag_association", metadata,
+ Column( "id", Integer, primary_key=True ),
+ Column( "workflow_id", Integer, ForeignKey( "workflow.id" ),
index=True ),
+ Column( "tag_id", Integer, ForeignKey( "tag.id" ), index=True ),
+ Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ),
index=True ),
+ Column( "user_tname", Unicode(255), index=True),
+ Column( "value", Unicode(255), index=True),
+ Column( "user_value", Unicode(255), index=True) )
+
+def upgrade():
+ print __doc__
+ metadata.reflect()
+
+ # Create user_id column in history_tag_association table.
+ HistoryTagAssociation_table = Table( "history_tag_association", metadata,
autoload=True )
+ c = Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ),
index=True )
+ try:
+ c.create( HistoryTagAssociation_table )
+ assert c is HistoryTagAssociation_table.c.user_id
+ except Exception, e:
+ # SQLite does not support 'ALTER TABLE ADD FOREIGN KEY', so catch
exception if it arises.
+ print str(e)
+ log.debug( "Adding user_id column to history_tag_association table failed:
%s" % str( e ) )
+
+ # Create user_id index for history_tag_association table.
+ try:
+ i = Index( "ix_history_tag_association_user_id",
HistoryTagAssociation_table.c.user_id )
+ i.create()
+ except:
+ # Mysql doesn't have a named index, but alter should work
+ HistoryTagAssociation_table.c.user_id.alter( unique=False )
+
+ # Populate column so that user_id is the id of the user who owns the history (and, up
to now, was the only person able to tag the history).
+ if c is HistoryTagAssociation_table.c.user_id:
+ db_session.execute(
+ "UPDATE history_tag_association SET user_id=( SELECT user_id FROM
history WHERE history_tag_association.history_id = history.id )"
+ )
+
+ # Create user_id column in history_dataset_association_tag_association table.
+ HistoryDatasetAssociationTagAssociation_table = Table(
"history_dataset_association_tag_association", metadata, autoload=True )
+ c = Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ),
index=True )
+ try:
+ c.create( HistoryDatasetAssociationTagAssociation_table )
+ assert c is HistoryDatasetAssociationTagAssociation_table.c.user_id
+ except Exception, e:
+ # SQLite does not support 'ALTER TABLE ADD FOREIGN KEY', so catch
exception if it arises.
+ print str(e)
+ log.debug( "Adding user_id column to
history_dataset_association_tag_association table failed: %s" % str( e ) )
+
+ # Create user_id index for history_dataset_association_tag_association table.
+ try:
+ i = Index( "ix_history_dataset_association_tag_association_user_id",
HistoryDatasetAssociationTagAssociation_table.c.user_id )
+ i.create()
+ except:
+ # Mysql doesn't have a named index, but alter should work
+ HistoryDatasetAssociationTagAssociation_table.c.user_id.alter( unique=False )
+
+ # Populate column so that user_id is the id of the user who owns the
history_dataset_association (and, up to now, was the only person able to tag the page).
+ if c is HistoryDatasetAssociationTagAssociation_table.c.user_id:
+ db_session.execute(
+ "UPDATE history_dataset_association_tag_association SET user_id=( SELECT
history.user_id FROM history, history_dataset_association WHERE
history_dataset_association.history_id = history.id AND history_dataset_association.id =
history_dataset_association_tag_association.history_dataset_association_id)"
+ )
+
+ # Create user_id column in page_tag_association table.
+ PageTagAssociation_table = Table( "page_tag_association", metadata,
autoload=True )
+ c = Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ),
index=True )
+ try:
+ c.create( PageTagAssociation_table )
+ assert c is PageTagAssociation_table.c.user_id
+ except Exception, e:
+ # SQLite does not support 'ALTER TABLE ADD FOREIGN KEY', so catch
exception if it arises.
+ print str(e)
+ log.debug( "Adding user_id column to history_tag_association table failed:
%s" % str( e ) )
+
+ # Create user_id index for page_tag_association table.
+ try:
+ i = Index( "ix_page_tag_association_user_id",
PageTagAssociation_table.c.user_id )
+ i.create()
+ except:
+ # Mysql doesn't have a named index, but alter should work
+ PageTagAssociation_table.c.user_id.alter( unique=False )
+
+ # Populate column so that user_id is the id of the user who owns the page (and, up to
now, was the only person able to tag the page).
+ if c is PageTagAssociation_table.c.user_id:
+ db_session.execute(
+ "UPDATE page_tag_association SET user_id=( SELECT user_id FROM page
WHERE page_tag_association.page_id = page.id )"
+ )
+
+ # Create stored_workflow_tag_association table.
+ try:
+ StoredWorkflowTagAssociation_table.create()
+ except Exception, e:
+ print str(e)
+ log.debug( "Creating stored_workflow_tag_association table failed: %s"
% str( e ) )
+
+ # Create workflow_tag_association table.
+ try:
+ WorkflowTagAssociation_table.create()
+ except Exception, e:
+ print str(e)
+ log.debug( "Creating workflow_tag_association table failed: %s" % str(
e ) )
+
+def downgrade():
+ metadata.reflect()
+
+ # Drop user_id column from history_tag_association table.
+ HistoryTagAssociation_table = Table( "history_tag_association", metadata,
autoload=True )
+ try:
+ HistoryTagAssociation_table.c.user_id.drop()
+ except Exception, e:
+ print str(e)
+ log.debug( "Dropping column user_id from history_tag_association table
failed: %s" % str( e ) )
+
+
+ # Drop user_id column from history_dataset_association_tag_association table.
+ HistoryDatasetAssociationTagAssociation_table = Table(
"history_dataset_association_tag_association", metadata, autoload=True )
+ try:
+ HistoryDatasetAssociationTagAssociation_table.c.user_id.drop()
+ except Exception, e:
+ print str(e)
+ log.debug( "Dropping column user_id from
history_dataset_association_tag_association table failed: %s" % str( e ) )
+
+ # Drop user_id column from page_tag_association table.
+ PageTagAssociation_table = Table( "page_tag_association", metadata,
autoload=True )
+ try:
+ PageTagAssociation_table.c.user_id.drop()
+ except Exception, e:
+ print str(e)
+ log.debug( "Dropping column user_id from page_tag_association table failed:
%s" % str( e ) )
+
+ # Drop stored_workflow_tag_association table.
+ try:
+ StoredWorkflowTagAssociation_table.drop()
+ except Exception, e:
+ print str(e)
+ log.debug( "Dropping stored_workflow_tag_association table failed: %s"
% str( e ) )
+
+ # Drop workflow_tag_association table.
+ try:
+ WorkflowTagAssociation_table.drop()
+ except Exception, e:
+ print str(e)
+ log.debug( "Dropping workflow_tag_association table failed: %s" % str(
e ) )
\ No newline at end of file
diff -r 3aa8c1020261 -r 5b99d58c6f54 lib/galaxy/tags/tag_handler.py
--- a/lib/galaxy/tags/tag_handler.py Thu Jan 07 11:13:38 2010 -0500
+++ b/lib/galaxy/tags/tag_handler.py Thu Jan 07 13:41:44 2010 -0500
@@ -73,10 +73,10 @@
return community_tags
- def remove_item_tag( self, trans, item, tag_name ):
+ 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(item, tag_name)
+ item_tag_assoc = self._get_item_tag_assoc(user, item, tag_name)
# Remove association.
if item_tag_assoc:
@@ -87,7 +87,7 @@
return False
- def delete_item_tags( self, trans, item ):
+ def delete_item_tags( self, trans, user, item ):
"""Delete tags from an item."""
# Delete item-tag associations.
for tag in item.tags:
@@ -96,7 +96,7 @@
# Delete tags from item.
del item.tags[:]
- def item_has_tag(self, item, tag):
+ def item_has_tag(self, user, item, tag):
"""Returns true if item is has a given tag."""
# Get tag name.
if isinstance(tag, basestring):
@@ -105,13 +105,13 @@
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(item, tag_name)
+ item_tag_assoc = self._get_item_tag_assoc(user, item, tag_name)
if item_tag_assoc:
return True
return False
- def apply_item_tags(self, db_session, item, tags_str):
+ def apply_item_tags(self, db_session, user, item, tags_str):
"""Apply tags to an item."""
# Parse tags.
parsed_tags = self.parse_tags(tags_str)
@@ -122,7 +122,7 @@
lc_name = name.lower()
# Get or create item-tag association.
- item_tag_assoc = self._get_item_tag_assoc(item, lc_name)
+ item_tag_assoc = self._get_item_tag_assoc(user, item, lc_name)
if not item_tag_assoc:
#
# Create item-tag association.
@@ -141,6 +141,7 @@
# 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
@@ -211,12 +212,12 @@
return tag
- def _get_item_tag_assoc(self, item, tag_name):
+ def _get_item_tag_assoc(self, user, item, tag_name):
"""Return ItemTagAssociation object for an item and a tag string;
returns None if there is
no such tag."""
scrubbed_tag_name = self._scrub_tag_name(tag_name)
for item_tag_assoc in item.tags:
- if item_tag_assoc.tag.name == scrubbed_tag_name:
+ if ( item_tag_assoc.user == user ) and ( item_tag_assoc.tag.name ==
scrubbed_tag_name ):
return item_tag_assoc
return None
diff -r 3aa8c1020261 -r 5b99d58c6f54 lib/galaxy/web/controllers/dataset.py
--- a/lib/galaxy/web/controllers/dataset.py Thu Jan 07 11:13:38 2010 -0500
+++ b/lib/galaxy/web/controllers/dataset.py Thu Jan 07 13:41:44 2010 -0500
@@ -87,7 +87,7 @@
link=( lambda item: iff( item.history.deleted, None, dict(
operation="switch", id=item.id ) ) ), filterable="advanced" ),
HistoryColumn( "History", key="history",
link=( lambda item: iff( item.history.deleted, None, dict(
operation="switch_history", id=item.id ) ) ) ),
- grids.TagsColumn( "Tags", "tags",
model.HistoryDatasetAssociation, model.HistoryDatasetAssociationTagAssociation,
filterable="advanced", grid_name="HistoryDatasetAssocationListGrid"
),
+ grids.IndividualTagsColumn( "Tags", "tags",
model.HistoryDatasetAssociation, model.HistoryDatasetAssociationTagAssociation,
filterable="advanced", grid_name="HistoryDatasetAssocationListGrid"
),
StatusColumn( "Status", key="deleted", attach_popup=False ),
grids.GridColumn( "Created", key="create_time",
format=time_ago ),
grids.GridColumn( "Last Updated", key="update_time",
format=time_ago ),
diff -r 3aa8c1020261 -r 5b99d58c6f54 lib/galaxy/web/controllers/history.py
--- a/lib/galaxy/web/controllers/history.py Thu Jan 07 11:13:38 2010 -0500
+++ b/lib/galaxy/web/controllers/history.py Thu Jan 07 13:41:44 2010 -0500
@@ -59,7 +59,7 @@
return accepted_filters
class SharingColumn( grids.GridColumn ):
- def filter( self, db_session, query, column_filter ):
+ def filter( self, db_session, user, query, column_filter ):
""" Modify query to filter histories by sharing status.
"""
if column_filter == "All":
pass
@@ -95,7 +95,7 @@
link=( lambda history: iff( history.deleted, None, dict(
operation="Switch", id=history.id ) ) ),
attach_popup=True, filterable="advanced" ),
DatasetsByStateColumn( "Datasets (by state)", ncells=4 ),
- grids.TagsColumn( "Tags", "tags", model.History,
model.HistoryTagAssociation, filterable="advanced",
grid_name="HistoryListGrid" ),
+ grids.IndividualTagsColumn( "Tags", "tags", model.History,
model.HistoryTagAssociation, filterable="advanced",
grid_name="HistoryListGrid" ),
StatusColumn( "Status", attach_popup=False ),
grids.GridColumn( "Created", key="create_time",
format=time_ago ),
grids.GridColumn( "Last Updated", key="update_time",
format=time_ago ),
diff -r 3aa8c1020261 -r 5b99d58c6f54 lib/galaxy/web/controllers/page.py
--- a/lib/galaxy/web/controllers/page.py Thu Jan 07 11:13:38 2010 -0500
+++ b/lib/galaxy/web/controllers/page.py Thu Jan 07 13:41:44 2010 -0500
@@ -84,7 +84,7 @@
return accepted_filters
class SharingColumn( grids.GridColumn ):
- def filter( self, db_session, query, column_filter ):
+ def filter( self, db_session, user, query, column_filter ):
""" Modify query to filter histories by sharing status.
"""
if column_filter == "All":
pass
@@ -121,7 +121,7 @@
num_rows_per_page = 10
columns = [
NameColumn( "Name", key="name", model_class=model.History,
filterable="advanced" ),
- grids.TagsColumn( "Tags", "tags", model.History,
model.HistoryTagAssociation, filterable="advanced"),
+ grids.IndividualTagsColumn( "Tags", "tags", model.History,
model.HistoryTagAssociation, filterable="advanced"),
grids.GridColumn( "Last Updated", key="update_time",
format=time_ago ),
# Columns that are valid for filtering but are not visible.
DeletedColumn( "Deleted", key="deleted", visible=False,
filterable="advanced" ),
diff -r 3aa8c1020261 -r 5b99d58c6f54 lib/galaxy/web/controllers/requests.py
--- a/lib/galaxy/web/controllers/requests.py Thu Jan 07 11:13:38 2010 -0500
+++ b/lib/galaxy/web/controllers/requests.py Thu Jan 07 13:41:44 2010 -0500
@@ -40,7 +40,7 @@
elif request.state() == request.states.COMPLETE:
return '<div class="count-box
state-color-ok">%s</div>' % request.state()
return request.state()
- def filter( self, db_session, query, column_filter ):
+ def filter( self, db_session, user, query, column_filter ):
""" Modify query to filter request by state.
"""
if column_filter == "All":
return query
diff -r 3aa8c1020261 -r 5b99d58c6f54 lib/galaxy/web/controllers/requests_admin.py
--- a/lib/galaxy/web/controllers/requests_admin.py Thu Jan 07 11:13:38 2010 -0500
+++ b/lib/galaxy/web/controllers/requests_admin.py Thu Jan 07 13:41:44 2010 -0500
@@ -45,7 +45,7 @@
elif request.state() == request.states.COMPLETE:
return '<div class="count-box
state-color-ok">%s</div>' % request.state()
return request.state()
- def filter( self, db_session, query, column_filter ):
+ def filter( self, db_session, user, query, column_filter ):
""" Modify query to filter request by state.
"""
if column_filter == "All":
return query
diff -r 3aa8c1020261 -r 5b99d58c6f54 lib/galaxy/web/controllers/tag.py
--- a/lib/galaxy/web/controllers/tag.py Thu Jan 07 11:13:38 2010 -0500
+++ b/lib/galaxy/web/controllers/tag.py Thu Jan 07 13:41:44 2010 -0500
@@ -19,63 +19,59 @@
@web.expose
@web.require_login( "Add tag to an item." )
- def add_tag_async( self, trans, id=None, item_class=None, new_tag=None, context=None
):
+ def add_tag_async( self, trans, item_id=None, item_class=None, new_tag=None,
context=None ):
""" Add tag to an item. """
-
- # Check that user owns item.
- item = self._get_item(trans, item_class, trans.security.decode_id( id ) )
- self._do_security_check( trans, item )
-
+
# Apply tag.
- self.tag_handler.apply_item_tags( trans.sa_session, item,
new_tag.encode('utf-8') )
+ item = self._get_item( trans, item_class, trans.security.decode_id( item_id ) )
+ user = trans.get_user()
+ self.tag_handler.apply_item_tags( trans.sa_session, user, item,
new_tag.encode('utf-8') )
trans.sa_session.flush()
# Log.
params = dict( item_id=item.id, item_class=item_class, tag=new_tag)
- trans.log_action( unicode( "tag"), context, params )
+ trans.log_action( user, unicode( "tag"), context, params )
@web.expose
@web.require_login( "Remove tag from an item." )
- def remove_tag_async( self, trans, id=None, item_class=None, tag_name=None,
context=None ):
+ def remove_tag_async( self, trans, item_id=None, item_class=None, tag_name=None,
context=None ):
""" Remove tag from an item. """
- # Check that user owns item.
- item = self._get_item(trans, item_class, trans.security.decode_id(id))
- self._do_security_check(trans, item)
-
# Remove tag.
- self.tag_handler.remove_item_tag( trans, item, tag_name.encode('utf-8')
)
+ item = self._get_item( trans, item_class, trans.security.decode_id( item_id) )
+ user = trans.get_user()
+ self.tag_handler.remove_item_tag( trans, user, item,
tag_name.encode('utf-8') )
trans.sa_session.flush()
# Log.
params = dict( item_id=item.id, item_class=item_class, tag=tag_name)
- trans.log_action( unicode( "untag"), context, params )
+ trans.log_action( user, unicode( "untag"), context, params )
# Retag an item. All previous tags are deleted and new tags are applied.
- @web.expose
+ #(a)web.expose
@web.require_login( "Apply a new set of tags to an item; previous tags are
deleted." )
- def retag_async( self, trans, id=None, item_class=None, new_tags=None ):
- """ Apply a new set of tags to an item; previous tags are deleted.
"""
- item = self._get_item(trans, item_class, trans.security.decode_id(id))
+ def retag_async( self, trans, item_id=None, item_class=None, new_tags=None ):
+ """ Apply a new set of tags to an item; previous tags are deleted.
"""
- self._do_security_check(trans, item)
-
+ # Apply tags.
+ item = self._get_item( trans, item_class, trans.security.decode_id( item_id ) )
+ user = trans.get_user()
tag_handler.delete_item_tags( trans, item )
- self.tag_handler.apply_item_tags( trans.sa_session, item,
new_tags.encode('utf-8') )
+ self.tag_handler.apply_item_tags( trans.sa_session, user, item,
new_tags.encode('utf-8') )
trans.sa_session.flush()
@web.expose
@web.require_login( "get autocomplete data for an item's tags" )
- def tag_autocomplete_data( self, trans, q=None, limit=None, timestamp=None, id=None,
item_class=None ):
+ def tag_autocomplete_data( self, trans, q=None, limit=None, timestamp=None,
item_id=None, item_class=None ):
""" Get autocomplete data for an item's tags.
"""
#
# Get item, do security check, and get autocomplete data.
#
item = None
- if id is not None:
- item = self._get_item(trans, item_class, trans.security.decode_id(id))
- self._do_security_check(trans, item)
+ if item_id is not None:
+ item = self._get_item( trans, item_class, trans.security.decode_id( item_id )
)
+ user = trans.get_user()
# Get item class. TODO: we should have a mapper that goes from class_name to
class object.
if item_class == 'History':
@@ -87,11 +83,11 @@
q = q.encode('utf-8')
if q.find(":") == -1:
- return self._get_tag_autocomplete_names(trans, q, limit, timestamp, item,
item_class)
+ return self._get_tag_autocomplete_names(trans, q, limit, timestamp, user,
item, item_class)
else:
- return self._get_tag_autocomplete_values(trans, q, limit, timestamp, item,
item_class)
+ return self._get_tag_autocomplete_values(trans, q, limit, timestamp, user,
item, item_class)
- def _get_tag_autocomplete_names( self, trans, q, limit, timestamp, item=None,
item_class=None ):
+ def _get_tag_autocomplete_names( self, trans, q, limit, timestamp, user=None,
item=None, item_class=None ):
"""Returns autocomplete data for tag names ordered from most
frequently used to
least frequently used."""
#
@@ -109,8 +105,10 @@
# 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(Tag.table)
- where_clause =
and_(self._get_column_for_filtering_item_by_user_id(item_class)==trans.get_user().id,
- Tag.table.c.name.like(q + "%"))
+ where_clause = and_(
+ Tag.table.c.name.like(q + "%"),
+ item_tag_assoc_class.table.c.user_id == user.id
+ )
order_by = [ func.count("*").desc() ]
group_by = item_tag_assoc_class.table.c.tag_id
@@ -125,7 +123,7 @@
tag = self.tag_handler.get_tag_by_id(trans.sa_session, row[0])
# Exclude tags that are already applied to the item.
- if ( item is not None ) and ( self.tag_handler.item_has_tag(item, tag) ):
+ if ( item is not None ) and ( self.tag_handler.item_has_tag(
trans.get_user(), item, tag ) ):
continue
# Add tag to autocomplete data. Use the most frequent name that user
# has employed for the tag.
@@ -135,7 +133,7 @@
return ac_data
- def _get_tag_autocomplete_values(self, trans, q, limit, timestamp, item=None,
item_class=None):
+ def _get_tag_autocomplete_values(self, trans, q, limit, timestamp, user=None,
item=None, item_class=None):
"""Returns autocomplete data for tag values ordered from most
frequently used to
least frequently used."""
@@ -158,9 +156,9 @@
# Build select statement.
cols_to_select = [ item_tag_assoc_class.table.c.value, func.count('*') ]
from_obj = item_tag_assoc_class.table.join(item_class.table).join(Tag.table)
- where_clause =
and_(self._get_column_for_filtering_item_by_user_id(item_class)==trans.get_user().id,
- Tag.table.c.id==tag.id,
- item_tag_assoc_class.table.c.value.like(tag_value +
"%"))
+ where_clause = and_( item_tag_assoc_class.table.c.user_id == user.id,
+ Tag.table.c.id==tag.id,
+ item_tag_assoc_class.table.c.value.like(tag_value +
"%") )
order_by = [ func.count("*").desc(),
item_tag_assoc_class.table.c.value ]
group_by = item_tag_assoc_class.table.c.value
@@ -182,8 +180,8 @@
# Build select stmt.
cols_to_select = [ item_tag_assoc_class.table.c.user_tname,
func.count('*') ]
- where_clause =
and_(self._get_column_for_filtering_item_by_user_id(item_class)==user.id ,
- item_tag_assoc_class.table.c.tag_id==tag.id)
+ where_clause = and_( item_tag_assoc_class.table.c.user_id == user.id,
+ item_tag_assoc_class.table.c.tag_id == tag.id )
group_by = item_tag_assoc_class.table.c.user_tname
order_by = [ func.count("*").desc() ]
@@ -198,35 +196,8 @@
return user_tag_names
- def _get_column_for_filtering_item_by_user_id(self, item_class):
- """ Returns the column to use when filtering by user id.
"""
- if item_class is HistoryDatasetAssociation:
- # Use the user_id associated with the HDA's history.
- return History.table.c.user_id
- else:
- # Generically, just use the user_id column of the tagged item's table.
- return item_class.table.c.user_id
-
- def _get_item(self, trans, item_class_name, id):
+ def _get_item( self, trans, item_class_name, id ):
""" Get an item based on type and id. """
item_class = self.tag_handler.item_tag_assoc_info[item_class_name].item_class
item = trans.sa_session.query(item_class).filter("id=" + str(id))[0]
- return item;
-
- def _do_security_check(self, trans, item):
- """ Do security check on an item. """
- if isinstance(item, History):
- history = item;
- # Check that the history exists, and is either owned by the current
- # user (if logged in) or the current history
- assert history is not None
- if history.user is None:
- assert history == trans.get_history()
- else:
- assert history.user == trans.user
- elif isinstance(item, HistoryDatasetAssociation):
- # TODO.
- pass
- elif isinstance(item, Page):
- # TODO.
- pass
+ return item
diff -r 3aa8c1020261 -r 5b99d58c6f54 lib/galaxy/web/framework/__init__.py
--- a/lib/galaxy/web/framework/__init__.py Thu Jan 07 11:13:38 2010 -0500
+++ b/lib/galaxy/web/framework/__init__.py Thu Jan 07 13:41:44 2010 -0500
@@ -171,14 +171,17 @@
to allow migration toward a more SQLAlchemy 0.4 style of use.
"""
return self.app.model.context.current
- def log_action( self, action, context, params):
+ def log_action( self, user=None, action=None, context=None, params=None):
"""
Application-level logging of user actions.
"""
if self.app.config.log_actions:
action = self.app.model.UserAction(action=action, context=context,
params=unicode( to_json_string( params ) ) )
try:
- action.user = self.user
+ if user:
+ action.user = user
+ else:
+ action.user = self.user
except:
action.user = None
try:
diff -r 3aa8c1020261 -r 5b99d58c6f54 lib/galaxy/web/framework/helpers/grids.py
--- a/lib/galaxy/web/framework/helpers/grids.py Thu Jan 07 11:13:38 2010 -0500
+++ b/lib/galaxy/web/framework/helpers/grids.py Thu Jan 07 13:41:44 2010 -0500
@@ -129,7 +129,7 @@
if column_filter == '':
continue
# Update query.
- query = column.filter( trans.sa_session, query, column_filter )
+ query = column.filter( trans.sa_session, trans.get_user(), query,
column_filter )
# Upate current filter dict.
cur_filter_dict[ column.key ] = column_filter
# Carry filter along to newly generated urls; make sure filter is a
string so
@@ -208,7 +208,7 @@
params = cur_filter_dict.copy()
params['sort'] = sort_key
params['async'] = ( 'async' in kwargs )
- trans.log_action( unicode( "grid.view"), context, params )
+ trans.log_action( trans.get_user(), unicode( "grid.view"), context,
params )
# Render grid.
def url( *args, **kwargs ):
@@ -308,7 +308,7 @@
if self.link and self.link( item ):
return self.link( item )
return None
- def filter( self, db_session, query, column_filter ):
+ def filter( self, db_session, user, query, column_filter ):
""" Modify query to reflect the column filter. """
if column_filter == "All":
pass
@@ -328,14 +328,14 @@
# Generic column that employs freetext and, hence, supports freetext, case-independent
filtering.
class TextColumn( GridColumn ):
- def filter( self, db_session, query, column_filter ):
+ def filter( self, db_session, user, query, column_filter ):
""" Modify query to filter using free text, case independence.
"""
if column_filter == "All":
pass
elif column_filter:
- query = query.filter( self.get_filter( column_filter ) )
+ query = query.filter( self.get_filter( user, column_filter ) )
return query
- def get_filter( self, column_filter ):
+ def get_filter( self, user, column_filter ):
""" Returns a SQLAlchemy criterion derived from column_filter.
"""
model_class_key_field = getattr( self.model_class, self.key )
@@ -347,30 +347,26 @@
clause_list.append( func.lower( model_class_key_field ).like(
"%" + filter.lower() + "%" ) )
return and_( *clause_list )
-# Generic column that supports tagging.
-class TagsColumn( TextColumn ):
+# Column that supports community tags.
+class CommunityTagsColumn( TextColumn ):
def __init__( self, col_name, key, model_class, model_tag_association_class,
filterable, grid_name=None ):
GridColumn.__init__(self, col_name, key=key, model_class=model_class,
filterable=filterable)
self.model_tag_association_class = model_tag_association_class
# Tags cannot be sorted.
self.sortable = False
# Column-specific attributes.
- self.tag_elt_id_gen = 0
self.grid_name = grid_name
def get_value( self, trans, grid, item ):
- self.tag_elt_id_gen += 1
- elt_id="tagging-elt" + str( self.tag_elt_id_gen )
- div_elt = "<div id=%s></div>" % elt_id
- return div_elt + trans.fill_template( "/tagging_common.mako",
trans=trans, tagged_item=item, elt_context=self.grid_name,
- elt_id = elt_id, in_form=True,
input_size="20", tag_click_fn="add_tag_to_grid_filter" )
- def filter( self, db_session, query, column_filter ):
+ return trans.fill_template( "/tagging_common.mako",
tag_type="community", trans=trans, user=trans.get_user(), tagged_item=item,
elt_context=self.grid_name,
+ in_form=True, input_size="20",
tag_click_fn="add_tag_to_grid_filter" )
+ def filter( self, db_session, user, query, column_filter ):
""" Modify query to filter model_class by tag. Multiple filters
are ANDed. """
if column_filter == "All":
pass
elif column_filter:
- query = query.filter( self.get_filter( column_filter ) )
+ query = query.filter( self.get_filter( user, column_filter ) )
return query
- def get_filter( self, column_filter ):
+ def get_filter( self, user, column_filter ):
# Parse filter to extract multiple tags.
tag_handler = TagHandler()
if isinstance( column_filter, list ):
@@ -380,19 +376,41 @@
clause_list = []
for name, value in raw_tags.items():
if name:
- # Search for tag names.
+ # Filter by all tags.
clause_list.append( self.model_class.tags.any( func.lower(
self.model_tag_association_class.user_tname ).like( "%" + name.lower() +
"%" ) ) )
if value:
- # Search for tag values.
+ # Filter by all values.
clause_list.append( self.model_class.tags.any( func.lower(
self.model_tag_association_class.user_value ).like( "%" + value.lower() +
"%" ) ) )
return and_( *clause_list )
+# Column that supports individual tags.
+class IndividualTagsColumn( CommunityTagsColumn ):
+ def get_value( self, trans, grid, item ):
+ return trans.fill_template( "/tagging_common.mako",
tag_type="individual", trans=trans, user=trans.get_user(), tagged_item=item,
elt_context=self.grid_name,
+ in_form=True, input_size="20",
tag_click_fn="add_tag_to_grid_filter" )
+ def get_filter( self, user, column_filter ):
+ # Parse filter to extract multiple tags.
+ tag_handler = TagHandler()
+ if isinstance( column_filter, list ):
+ # Collapse list of tags into a single string; this is redundant but
effective. TODO: fix this by iterating over tags.
+ column_filter = ",".join( column_filter )
+ raw_tags = tag_handler.parse_tags( column_filter.encode("utf-8") )
+ clause_list = []
+ for name, value in raw_tags.items():
+ if name:
+ # Filter by individual's tag names.
+ clause_list.append( self.model_class.tags.any( and_( func.lower(
self.model_tag_association_class.user_tname ).like( "%" + name.lower() +
"%" ), self.model_tag_association_class.user == user ) ) )
+ if value:
+ # Filter by individual's tag values.
+ clause_list.append( self.model_class.tags.any( and_( func.lower(
self.model_tag_association_class.user_value ).like( "%" + value.lower() +
"%" ), self.model_tag_association_class.user == user ) ) )
+ return and_( *clause_list )
+
# Column that performs multicolumn filtering.
class MulticolFilterColumn( TextColumn ):
def __init__( self, col_name, cols_to_filter, key, visible,
filterable="default" ):
GridColumn.__init__( self, col_name, key=key, visible=visible,
filterable=filterable)
self.cols_to_filter = cols_to_filter
- def filter( self, db_session, query, column_filter ):
+ def filter( self, db_session, user, query, column_filter ):
""" Modify query to filter model_class by tag. Multiple filters
are ANDed. """
if column_filter == "All":
return query
@@ -401,13 +419,13 @@
for filter in column_filter:
part_clause_list = []
for column in self.cols_to_filter:
- part_clause_list.append( column.get_filter( filter ) )
+ part_clause_list.append( column.get_filter( user, filter ) )
clause_list.append( or_( *part_clause_list ) )
complete_filter = and_( *clause_list )
else:
clause_list = []
for column in self.cols_to_filter:
- clause_list.append( column.get_filter( column_filter ) )
+ clause_list.append( column.get_filter( user, column_filter ) )
complete_filter = or_( *clause_list )
return query.filter( complete_filter )
diff -r 3aa8c1020261 -r 5b99d58c6f54 templates/dataset/edit_attributes.mako
--- a/templates/dataset/edit_attributes.mako Thu Jan 07 11:13:38 2010 -0500
+++ b/templates/dataset/edit_attributes.mako Thu Jan 07 13:41:44 2010 -0500
@@ -55,7 +55,7 @@
<div style="clear: both"></div>
</div>
%if trans.get_user() is not None:
- <%namespace file="../tagging_common.mako"
import="render_tagging_element" />
+ <%namespace file="../tagging_common.mako"
import="render_individual_tagging_element" />
<div class="form-row">
<label>
Tags:
@@ -66,7 +66,7 @@
border: none;
}
</style>
- ${render_tagging_element(data, "edit_attributes.mako",
use_toggle_link=False, in_form=True, input_size="30")}
+ ${render_individual_tagging_element(user=trans.get_user(),
tagged_item=data, elt_context="edit_attributes.mako", use_toggle_link=False,
in_form=True, input_size="30")}
</div>
<div style="clear: both"></div>
</div>
diff -r 3aa8c1020261 -r 5b99d58c6f54 templates/grid_base.mako
--- a/templates/grid_base.mako Thu Jan 07 11:13:38 2010 -0500
+++ b/templates/grid_base.mako Thu Jan 07 13:41:44 2010 -0500
@@ -776,6 +776,14 @@
## Render grid.
<%def name="render_grid_table()">
+ <%
+ # Set flag to indicate whether grid has operations that operate on multiple
items.
+ multiple_item_ops_exist = False
+ for operation in grid.operations:
+ if operation.allow_multiple:
+ multiple_item_ops_exist = True
+ %>
+
<form action="${url()}" method="post" onsubmit="return
false;">
<div class='loading-elt-overlay'></div>
<table id='grid-table' class="grid">
@@ -817,17 +825,17 @@
</tr>
</thead>
<tbody id="grid-table-body">
- ${render_grid_table_body_contents()}
+ ${render_grid_table_body_contents(multiple_item_ops_exist)}
</tbody>
<tfoot>
- ${render_grid_table_footer_contents()}
+ ${render_grid_table_footer_contents(multiple_item_ops_exist)}
</tfoot>
</table>
</form>
</%def>
## Render grid table body contents.
-<%def name="render_grid_table_body_contents()">
+<%def
name="render_grid_table_body_contents(multiple_item_ops_exist=False)">
<% num_rows_rendered = 0 %>
%if query.count() == 0:
## No results.
@@ -842,7 +850,7 @@
## Item selection column
<td style="width: 1.5em;">
- %if grid.operations:
+ %if multiple_item_ops_exist:
<input type="checkbox" name="id"
value=${trans.security.encode_id( item.id )} class="grid-row-select-checkbox"
/>
%endif
</td>
@@ -917,7 +925,7 @@
</%def>
## Render grid table footer contents.
-<%def name="render_grid_table_footer_contents()">
+<%def
name="render_grid_table_footer_contents(multiple_item_ops_exist=False)">
## Row for navigating among pages.
<%
# Mapping between item class and plural term for item.
@@ -956,14 +964,8 @@
</td>
</tr>
%endif
- ## Grid operations.
- <%
- num_allow_multiple_ops = 0
- for operation in grid.operations:
- if operation.allow_multiple:
- num_allow_multiple_ops += 1
- %>
- %if num_allow_multiple_ops:
+ ## Grid operations for multiple items.
+ %if multiple_item_ops_exist:
<tr>
<td></td>
<td colspan="100">
diff -r 3aa8c1020261 -r 5b99d58c6f54 templates/grid_base_async.mako
--- a/templates/grid_base_async.mako Thu Jan 07 11:13:38 2010 -0500
+++ b/templates/grid_base_async.mako Thu Jan 07 13:41:44 2010 -0500
@@ -1,6 +1,14 @@
<%namespace file="./grid_base.mako" import="*" />
-${render_grid_table_body_contents()}
+<%
+ # Set flag to indicate whether grid has operations that operate on multiple items.
+ multiple_item_ops_exist = False
+ for operation in grid.operations:
+ if operation.allow_multiple:
+ multiple_item_ops_exist = True
+%>
+
+${render_grid_table_body_contents(multiple_item_ops_exist=multiple_item_ops_exist)}
*****
${num_pages}
*****
diff -r 3aa8c1020261 -r 5b99d58c6f54 templates/history/view.mako
--- a/templates/history/view.mako Thu Jan 07 11:13:38 2010 -0500
+++ b/templates/history/view.mako Thu Jan 07 13:41:44 2010 -0500
@@ -1,7 +1,7 @@
<%inherit file="/base_panels.mako"/>
<%namespace file="/display_common.mako" import="get_history_link"
/>
<%namespace file="/root/history_common.mako"
import="render_dataset" />
-<%namespace file="../tagging_common.mako"
import="render_tagging_element, render_community_tagging_element" />
+<%namespace file="../tagging_common.mako"
import="render_individual_tagging_element, render_community_tagging_element"
/>
<%def name="javascripts()">
${parent.javascripts()}
@@ -404,11 +404,11 @@
none
%endif
</div>
- ## User tags.
+ ## Individual tags.
<p>
<div>
- ##Yours:
- ##${render_tagging_element( tagged_item=history,
elt_context='view.mako', use_toggle_link=False )}
+ Yours:
+ ${render_individual_tagging_element( user=trans.get_user(),
tagged_item=history, elt_context='view.mako', use_toggle_link=False )}
</div>
</div>
diff -r 3aa8c1020261 -r 5b99d58c6f54 templates/page/display.mako
--- a/templates/page/display.mako Thu Jan 07 11:13:38 2010 -0500
+++ b/templates/page/display.mako Thu Jan 07 13:41:44 2010 -0500
@@ -238,8 +238,8 @@
## User tags.
<p>
<div>
- ##Yours:
- ##${render_tagging_element( tagged_item=page,
elt_context='display.mako', use_toggle_link=False )}
+ Yours:
+ ${render_individual_tagging_element( tagged_item=page,
elt_context='display.mako', use_toggle_link=False )}
</div>
</div>
</div>
diff -r 3aa8c1020261 -r 5b99d58c6f54 templates/page/history_annotation_table.mako
--- a/templates/page/history_annotation_table.mako Thu Jan 07 11:13:38 2010 -0500
+++ b/templates/page/history_annotation_table.mako Thu Jan 07 13:41:44 2010 -0500
@@ -1,4 +1,4 @@
-<%namespace file="../tagging_common.mako"
import="render_tagging_element_html" />
+<%namespace file="../tagging_common.mako"
import="render_individual_tagging_element_html" />
<%namespace file="../root/history_common.mako"
import="render_dataset" />
<table>
@@ -15,7 +15,7 @@
</div>
%endif
%if trans.get_user() is not None:
- Tags: ${render_tagging_element_html( tags=history.tags, editable=False,
use_toggle_link=False )}
+ Tags: ${render_individual_tagging_element_html( tags=history.tags,
editable=False, use_toggle_link=False )}
%endif
</td>
</tr>
diff -r 3aa8c1020261 -r 5b99d58c6f54 templates/root/history.mako
--- a/templates/root/history.mako Thu Jan 07 11:13:38 2010 -0500
+++ b/templates/root/history.mako Thu Jan 07 13:41:44 2010 -0500
@@ -318,7 +318,7 @@
<p></p>
%endif
-<%namespace file="../tagging_common.mako"
import="render_tagging_element" />
+<%namespace file="../tagging_common.mako"
import="render_individual_tagging_element" />
<%namespace file="history_common.mako" import="render_dataset"
/>
%if trans.get_user() is not None:
@@ -327,7 +327,7 @@
margin-bottom: 0.5em;
}
</style>
- ${render_tagging_element( tagged_item=history, elt_context='history.mako',
get_toggle_link_text_fn='get_toggle_link_text' )}
+ ${render_individual_tagging_element( user=trans.get_user(), tagged_item=history,
elt_context='history.mako', get_toggle_link_text_fn='get_toggle_link_text'
)}
%endif
%if not datasets:
diff -r 3aa8c1020261 -r 5b99d58c6f54 templates/tagging_common.mako
--- a/templates/tagging_common.mako Thu Jan 07 11:13:38 2010 -0500
+++ b/templates/tagging_common.mako Thu Jan 07 13:41:44 2010 -0500
@@ -12,7 +12,11 @@
## Render a tagging element if there is a tagged_item.
%if tagged_item is not None:
- ${render_tagging_element(tagged_item=tagged_item, elt_context=elt_context,
in_form=in_form, input_size=input_size, tag_click_fn=tag_click_fn)}
+ %if tag_type == "individual":
+ ${render_individual_tagging_element(user=user, tagged_item=tagged_item,
elt_context=elt_context, in_form=in_form, input_size=input_size,
tag_click_fn=tag_click_fn)}
+ %elif tag_type == "community":
+ ${render_community_tagging_element(tagged_item=tagged_item,
elt_context=elt_context, tag_click_fn=tag_click_fn)}
+ %endif
%endif
## Render HTML for a list of tags.
@@ -78,7 +82,7 @@
</%def>
## Render community tagging element.
-<%def name="render_community_tagging_element(tagged_item=None,
use_toggle_link=False, tag_click_fn='default_tag_click_fn')">
+<%def name="render_community_tagging_element(tagged_item=None, elt_context=None,
use_toggle_link=False, tag_click_fn='default_tag_click_fn')">
## Build HTML.
<%
elt_id = int ( floor ( random()*maxint ) )
@@ -93,36 +97,26 @@
</%def>
-## Render the tags 'tags' as an autocomplete element.
-<%def name="render_tagging_element(tagged_item=None, elt_context=None,
use_toggle_link=True, in_form=False, input_size='15',
tag_click_fn='default_tag_click_fn',
get_toggle_link_text_fn='default_get_toggle_link_text_fn',
editable=True)">
+## Render individual tagging element.
+<%def name="render_individual_tagging_element(user=None, tagged_item=None,
elt_context=None, use_toggle_link=True, in_form=False, input_size='15',
tag_click_fn='default_tag_click_fn',
get_toggle_link_text_fn='default_get_toggle_link_text_fn',
editable=True)">
## Useful attributes.
- <%
- tagged_item_id = str( trans.security.encode_id (tagged_item.id) )
+ <%
+ # Useful ids.
+ tagged_item_id = str( trans.security.encode_id ( tagged_item.id ) )
elt_id = int ( floor ( random()*maxint ) )
+
+ # Get list of user's item tags. TODO: this could be moved to a database query
for speed purposes.
+ item_tags = [ tag for tag in tagged_item.tags if ( tag.user == user ) ]
%>
## Build HTML.
- ${self.render_tagging_element_html(elt_id, tagged_item.tags, editable,
use_toggle_link, input_size, in_form)}
+ ${self.render_tagging_element_html(elt_id, item_tags, editable, use_toggle_link,
input_size, in_form)}
## Build script that augments tags using progressive javascript.
<script type="text/javascript">
//
// Set up autocomplete tagger.
//
- <%
- ## Build string of tag name, values.
- tag_names_and_values = dict()
- for tag in tagged_item.tags:
- tag_name = tag.user_tname
- tag_value = ""
- if tag.value is not None:
- tag_value = tag.user_value
- ## Tag names and values may be string or unicode object.
- if isinstance( tag_name, str ):
- tag_names_and_values[unicode(tag_name, 'utf-8')] =
unicode(tag_value, 'utf-8')
- else: ## isInstance( tag_name, unicode ):
- tag_names_and_values[tag_name] = tag_value
- %>
//
// Default function get text to display on the toggle link.
@@ -167,6 +161,20 @@
// Default function to handle a tag click.
var default_tag_click_fn = function(tag_name, tag_value) { };
+ <%
+ ## Build dict of tag name, values.
+ tag_names_and_values = dict()
+ for tag in item_tags:
+ tag_name = tag.user_tname
+ tag_value = ""
+ if tag.value is not None:
+ tag_value = tag.user_value
+ ## Tag names and values may be string or unicode object.
+ if isinstance( tag_name, str ):
+ tag_names_and_values[unicode(tag_name, 'utf-8')] =
unicode(tag_value, 'utf-8')
+ else: ## isInstance( tag_name, unicode ):
+ tag_names_and_values[tag_name] = tag_value
+ %>
var options =
{
tags : ${h.to_json_string(tag_names_and_values)},
@@ -174,9 +182,9 @@
get_toggle_link_text_fn: ${get_toggle_link_text_fn},
tag_click_fn: ${tag_click_fn},
## Use forward slash in controller to suppress route memory.
- ajax_autocomplete_tag_url: "${h.url_for( controller='/tag',
action='tag_autocomplete_data', id=tagged_item_id,
item_class=tagged_item.__class__.__name__ )}",
- ajax_add_tag_url: "${h.url_for( controller='/tag',
action='add_tag_async', id=tagged_item_id,
item_class=tagged_item.__class__.__name__, context=elt_context )}",
- ajax_delete_tag_url: "${h.url_for( controller='/tag',
action='remove_tag_async', id=tagged_item_id,
item_class=tagged_item.__class__.__name__, context=elt_context )}",
+ ajax_autocomplete_tag_url: "${h.url_for( controller='/tag',
action='tag_autocomplete_data', item_id=tagged_item_id,
item_class=tagged_item.__class__.__name__ )}",
+ ajax_add_tag_url: "${h.url_for( controller='/tag',
action='add_tag_async', item_id=tagged_item_id,
item_class=tagged_item.__class__.__name__, context=elt_context )}",
+ ajax_delete_tag_url: "${h.url_for( controller='/tag',
action='remove_tag_async', item_id=tagged_item_id,
item_class=tagged_item.__class__.__name__, context=elt_context )}",
delete_tag_img:
"${h.url_for('/static/images/delete_tag_icon_gray.png')}",
delete_tag_img_rollover:
"${h.url_for('/static/images/delete_tag_icon_white.png')}",
use_toggle_link: ${iff( use_toggle_link, 'true', 'false' )},