Merged add_tags and lib.search into lib.tags.
authorEevee <git@veekun.com>
Sun, 6 Dec 2009 10:15:10 +0000 (02:15 -0800)
committerEevee <git@veekun.com>
Sun, 6 Dec 2009 10:15:10 +0000 (02:15 -0800)
floof/controllers/search.py
floof/controllers/tag.py
floof/lib/search.py [deleted file]
floof/lib/tags.py [new file with mode: 0644]
floof/templates/users/view.mako

index 720ca67..53343dd 100644 (file)
@@ -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__)
 
index 730bf72..5d13789 100644 (file)
@@ -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 (file)
index 8874824..0000000
+++ /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 (file)
index 0000000..104fe65
--- /dev/null
@@ -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()
index 9d34279..eb24b2d 100644 (file)
@@ -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:
 <h2>${gallery.string}</h2>
-${macros.thumbs(parse(gallery.search.string))}
+${macros.thumbs(parse(gallery.tags.string))}
 % endfor