8874824f022550b95b1acf475b9ad70473c7c979
[zzz-floof.git] / floof / lib / search.py
1 from floof.model import Art, ArtUser, ArtUserType, Tag, TagText, User
2
3 def parse(search_string):
4 """Parses a search query, and returns a query object on Art.
5
6 Queries can contain:
7 - Regular tags: foo
8 - User relations: by:kalu, of:eevee, for:ootachi
9
10 Later:
11 - Negative versions of anything above: -by:eevee, -dongs
12 """
13
14 # XXX doesn't do negative querying yet.
15 # XXX could use some sane limits.
16
17 # We'll be building this as we go.
18 q = Art.query
19
20 terms = search_string.split()
21 for tag in terms:
22 if ':' in tag:
23 # This is a special tag; at the moment, by/for/of to indicate
24 # related users
25 prefix, tag = tag.split(':', 1)
26
27 # XXX what to do if this fails? abort? return empty query?
28 target_user = User.get_by(name=tag)
29
30 if prefix == 'by':
31 rel = ArtUserType.BY
32 elif prefix == 'for':
33 rel = ArtUserType.FOR
34 elif prefix == 'of':
35 rel = ArtUserType.OF
36 else:
37 # Bogus tag. Not sure what to do here, so for the moment,
38 # ignore it
39 continue
40
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)
45
46 else:
47 # Regular ol' tag
48 q = q.join(Tag, TagText, aliased=True) \
49 .filter(TagText.text == tag)
50
51 return q