X-Git-Url: http://git.veekun.com/zzz-floof.git/blobdiff_plain/b07336c562d537ea3407d6a1c9fcb280dae7f514..73fe4db9e53797b3dff9d5a369cb838daebeaee4:/floof/controllers/tag.py diff --git a/floof/controllers/tag.py b/floof/controllers/tag.py index e5ce85b..e57d0c5 100644 --- a/floof/controllers/tag.py +++ b/floof/controllers/tag.py @@ -1,16 +1,18 @@ import logging +import re -from pylons import request, response, session, tmpl_context as c, h +from pylons import request, response, session, tmpl_context as c, url from pylons.controllers.util import abort, redirect +import elixir +from floof.model import Art, ArtUser, ArtUserType, Tag, TagText, User from floof.lib.base import BaseController, render -from pylons import url +from floof.lib.dbhelpers import find_or_create +from floof.lib import helpers as h +from sqlalchemy import func log = logging.getLogger(__name__) -import elixir -from floof.model import Art, Tag - class TagController(BaseController): # TODO: login required @@ -23,7 +25,77 @@ class TagController(BaseController): # TODO: login required def create(self, art_id): c.art = h.get_object_or_404(Art, id=art_id) - c.art.add_tags(request.params.get("tags",""), c.user) + + tag_string = request.params.get('tags', '') + + # Add or remove tags + bad_tags = [] + for tag_text in tag_string.split(): + original_tag_text = tag_text + tag_text = tag_text.lower() + + # Adding or removing a tag? + if tag_text[0] == '-': + add = False + tag_text = tag_text[1:] + else: + # Allow "+foo" to mean "add foo" + if tag_text[0] == '+': + tag_text = tag_text[1:] + add = True + + # Check for special namespaces + prefix = None + if ':' in tag_text: + prefix, tag_text = tag_text.split(':', 1) + if prefix not in ['by', 'for', 'of']: + # This is bogus. Skip it. + bad_tags.append(original_tag_text) + continue + + if prefix == 'by': + # XXX this needs supporting. silently ignore for now + continue + + # Must be 3-50 alphanumeric characters + if not re.match('^[a-z0-9]{3,50}$', tag_text): + bad_tags.append(original_tag_text) + continue + + # Do work! + if prefix: + target_user = User.query.filter(func.lower(User.name) == tag_text) \ + .one() + + # Special tag; at the moment, just a relationship + if prefix == 'by': + rel = ArtUserType.BY + elif prefix == 'for': + rel = ArtUserType.FOR + elif prefix == 'of': + rel = ArtUserType.OF + + user_assoc_data = dict(art=c.art, user=target_user, type=rel) + if add: + find_or_create(ArtUser, **user_assoc_data) + + else: + # XXX this will die for nonassociations + user_assoc = ArtUser.get_by(art=c.art, **user_assoc_data) + user_assoc.delete() + + else: + # Regular tag + if add: + tag = find_or_create(TagText, text=tag_text) + find_or_create(Tag, art=c.art, tagger=c.user, tagtext=tag) + + else: + tag = TagText.get_by(text=tag_text) + if tag: + # XXX this will die + tag_assoc = Tag.get_by(art=c.art, tagger=c.user, tagtext=tag) + tag_assoc.delete() + elixir.session.commit() redirect(url('show_art', id=c.art.id)) -