X-Git-Url: http://git.veekun.com/zzz-floof.git/blobdiff_plain/6fb3ad2a578aa2e0eced735187a02a79a8907668..e0b6c733c6bea7ff31b9361650fb8534b9433597:/floof/lib/search.py diff --git a/floof/lib/search.py b/floof/lib/search.py index 3acb248..8874824 100644 --- a/floof/lib/search.py +++ b/floof/lib/search.py @@ -1,33 +1,51 @@ -def parse(query): - words = query.split() - - tags = [] - for word in words: - components = word.split(':') - if len(components) == 1: - # tags are plain. - tags.append(word) - elif components[0] == "rating": - if components[1].isnumeric(): - score = int(components[1]) - else: - score = Rating.reverse_options.get(components[1]) +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 - if -1 <= score <= 3: - pass - # TODO: Find stuff that has this rating - # Rating.query.filter(Rating.s) + 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 - tagtexts = TagText.query.filter(TagText.text.in_(tags)) - tagtext_ids = map(lambda x:x.id, tagtexts) + # Inner join to the ArtUser table + q = q.join(ArtUser, aliased=True) \ + .filter(ArtUser.user == target_user) \ + .filter(ArtUser.type == rel) - # TODO: this is wrong. Please fix it so it returns art that has all the tags. - art_tag_pairs = elixir.session.query(Art,Tag).filter(Art.id == Tag.art_id).\ - filter(Tag.tagtext_id.in_(tagtext_ids)).all() + else: + # Regular ol' tag + q = q.join(Tag, TagText, aliased=True) \ + .filter(TagText.text == tag) - # just the art please. - c.artwork = map(lambda x: x[0], art_tag_pairs) - return render('/index.mako') + return q