1 from floof
.model
import Art
, ArtUser
, ArtUserType
, Tag
, TagText
, User
3 def parse(search_string
):
4 """Parses a search query, and returns a query object on Art.
8 - User relations: by:kalu, of:eevee, for:ootachi
11 - Negative versions of anything above: -by:eevee, -dongs
14 # XXX doesn't do negative querying yet.
15 # XXX could use some sane limits.
17 # We'll be building this as we go.
20 terms
= search_string
.split()
23 # This is a special tag; at the moment, by/for/of to indicate
25 prefix
, tag
= tag
.split(':', 1)
27 # XXX what to do if this fails? abort? return empty query?
28 target_user
= User
.get_by(name
=tag
)
37 # Bogus tag. Not sure what to do here, so for the moment,
41 # Inner join to the ArtUser table
42 q
= q
.join(ArtUser
, aliased
=True) \
43 .filter(ArtUser
.user
== target_user
) \
44 .filter(ArtUser
.type == rel
)
48 q
= q
.join(Tag
, TagText
, aliased
=True) \
49 .filter(TagText
.text
== tag
)
53 def add_tags(art
, tag_string
, user
):
54 """Takes a string that looks like a tag query, and effectively modifies the
55 art's tags to match it.
58 # XXX what to do with invalid tags? just return them and let caller fix?
60 for tag_text
in tag_string
.split():
61 original_tag_text
= tag_text
62 tag_text
= tag_text
.lower()
64 # Adding or removing a tag?
65 if tag_text
[0] == '-':
67 tag_text
= tag_text
[1:]
69 # Allow "+foo" to mean "add foo"
70 if tag_text
[0] == '+':
71 tag_text
= tag_text
[1:]
74 # Check for special namespaces
77 prefix
, tag_text
= tag_text
.split(':', 1)
78 if prefix
not in ['by', 'for', 'of']:
79 # This is bogus. Skip it.
80 bad_tags
.append(original_tag_text
)
84 # XXX this needs supporting. silently ignore for now
87 # Must be 3-50 alphanumeric characters
88 if not re
.match('^[a-z0-9]{3,50}$', tag_text
):
89 bad_tags
.append(original_tag_text
)
94 target_user
= User
.get_by(name
=tag_text
)
96 # Special tag; at the moment, just a relationship
100 rel
= ArtUserType
.FOR
104 user_assoc_data
= dict(art
=art
, user
=target_user
, type=rel
)
106 find_or_create(ArtUser
, **user_assoc_data
)
109 # XXX this will die for nonassociations
110 user_assoc
= ArtUser
.get_by(art
=art
, **user_assoc_data
)
116 tag
= find_or_create(TagText
, text
=tag_text
)
117 find_or_create(Tag
, art
=art
, tagger
=user
, tagtext
=tag
)
120 tag
= TagText
.get_by(text
=tag_text
)
123 tag_assoc
= Tag
.get_by(art
=art
, tagger
=user
, tagtext
=tag
)
126 elixir
.session
.commit()