From db4c5f0b56d22815ecc31754271797b2401c9458 Mon Sep 17 00:00:00 2001 From: Eevee Date: Sun, 6 Dec 2009 02:15:10 -0800 Subject: [PATCH] Merged add_tags and lib.search into lib.tags. --- floof/controllers/search.py | 2 +- floof/controllers/tag.py | 72 +---------------------- floof/lib/search.py | 51 ---------------- floof/lib/tags.py | 126 ++++++++++++++++++++++++++++++++++++++++ floof/templates/users/view.mako | 2 +- 5 files changed, 131 insertions(+), 122 deletions(-) delete mode 100644 floof/lib/search.py create mode 100644 floof/lib/tags.py diff --git a/floof/controllers/search.py b/floof/controllers/search.py index 720ca67..53343dd 100644 --- a/floof/controllers/search.py +++ b/floof/controllers/search.py @@ -5,7 +5,7 @@ from pylons.controllers.util import abort, redirect from pylons import url from floof.lib.base import BaseController, render -from floof.lib.search import parse +from floof.lib.tags import parse log = logging.getLogger(__name__) diff --git a/floof/controllers/tag.py b/floof/controllers/tag.py index 730bf72..5d13789 100644 --- a/floof/controllers/tag.py +++ b/floof/controllers/tag.py @@ -6,9 +6,10 @@ from pylons.controllers.util import abort, redirect import elixir from floof.model import Art, ArtUser, ArtUserType, Tag, TagText, User +from floof.lib import helpers as h from floof.lib.base import BaseController, render +from floof.lib.tags import add_tags from floof.lib.dbhelpers import find_or_create -from floof.lib import helpers as h log = logging.getLogger(__name__) @@ -26,74 +27,7 @@ class TagController(BaseController): c.art = h.get_object_or_404(Art, id=art_id) tag_string = request.params.get('tags', '') + add_tags(c.art, tag_string, c.user) # 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.get_by(name=tag_text) - - # 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)) diff --git a/floof/lib/search.py b/floof/lib/search.py deleted file mode 100644 index 8874824..0000000 --- a/floof/lib/search.py +++ /dev/null @@ -1,51 +0,0 @@ -from floof.model import Art, ArtUser, ArtUserType, Tag, TagText, User - -def parse(search_string): - """Parses a search query, and returns a query object on Art. - - Queries can contain: - - Regular tags: foo - - User relations: by:kalu, of:eevee, for:ootachi - - Later: - - Negative versions of anything above: -by:eevee, -dongs - """ - - # XXX doesn't do negative querying yet. - # XXX could use some sane limits. - - # We'll be building this as we go. - q = Art.query - - terms = search_string.split() - for tag in terms: - if ':' in tag: - # This is a special tag; at the moment, by/for/of to indicate - # related users - prefix, tag = tag.split(':', 1) - - # XXX what to do if this fails? abort? return empty query? - target_user = User.get_by(name=tag) - - if prefix == 'by': - rel = ArtUserType.BY - elif prefix == 'for': - rel = ArtUserType.FOR - elif prefix == 'of': - rel = ArtUserType.OF - else: - # Bogus tag. Not sure what to do here, so for the moment, - # ignore it - continue - - # Inner join to the ArtUser table - q = q.join(ArtUser, aliased=True) \ - .filter(ArtUser.user == target_user) \ - .filter(ArtUser.type == rel) - - else: - # Regular ol' tag - q = q.join(Tag, TagText, aliased=True) \ - .filter(TagText.text == tag) - - return q diff --git a/floof/lib/tags.py b/floof/lib/tags.py new file mode 100644 index 0000000..104fe65 --- /dev/null +++ b/floof/lib/tags.py @@ -0,0 +1,126 @@ +from floof.model import Art, ArtUser, ArtUserType, Tag, TagText, User + +def parse(search_string): + """Parses a search query, and returns a query object on Art. + + Queries can contain: + - Regular tags: foo + - User relations: by:kalu, of:eevee, for:ootachi + + Later: + - Negative versions of anything above: -by:eevee, -dongs + """ + + # XXX doesn't do negative querying yet. + # XXX could use some sane limits. + + # We'll be building this as we go. + q = Art.query + + terms = search_string.split() + for tag in terms: + if ':' in tag: + # This is a special tag; at the moment, by/for/of to indicate + # related users + prefix, tag = tag.split(':', 1) + + # XXX what to do if this fails? abort? return empty query? + target_user = User.get_by(name=tag) + + if prefix == 'by': + rel = ArtUserType.BY + elif prefix == 'for': + rel = ArtUserType.FOR + elif prefix == 'of': + rel = ArtUserType.OF + else: + # Bogus tag. Not sure what to do here, so for the moment, + # ignore it + continue + + # Inner join to the ArtUser table + q = q.join(ArtUser, aliased=True) \ + .filter(ArtUser.user == target_user) \ + .filter(ArtUser.type == rel) + + else: + # Regular ol' tag + q = q.join(Tag, TagText, aliased=True) \ + .filter(TagText.text == tag) + + return q + +def add_tags(art, tag_string, user): + """Takes a string that looks like a tag query, and effectively modifies the + art's tags to match it. + """ + + # XXX what to do with invalid tags? just return them and let caller fix? + 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.get_by(name=tag_text) + + # 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=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=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=art, tagger=user, tagtext=tag) + + else: + tag = TagText.get_by(text=tag_text) + if tag: + # XXX this will die + tag_assoc = Tag.get_by(art=art, tagger=user, tagtext=tag) + tag_assoc.delete() + + elixir.session.commit() diff --git a/floof/templates/users/view.mako b/floof/templates/users/view.mako index 9d34279..eb24b2d 100644 --- a/floof/templates/users/view.mako +++ b/floof/templates/users/view.mako @@ -24,5 +24,5 @@ ${h.form(url(controller='user_settings', action='rel_toggle', name=c.user.name.l <%! from floof.lib.search import parse %> % for gallery in c.this_user.primary_page.galleries:

${gallery.string}

-${macros.thumbs(parse(gallery.search.string))} +${macros.thumbs(parse(gallery.tags.string))} % endfor -- 2.7.4