+class Hint(object):
+ def __init__(self, search):
+ self.search = search
+ self.book_tags = {}
+ self.part_tags = []
+ self._books = []
+
+ def books(self, *books):
+ self._books = books
+
+ def tags(self, tags):
+ for t in tags:
+ if t.category in ['author', 'title', 'epoch', 'genre', 'kind']:
+ lst = self.book_tags.get(t.category, [])
+ lst.append(t)
+ self.book_tags[t.category] = lst
+ if t.category in ['theme']:
+ self.part_tags.append(t)
+
+ def tag_filter(self, tags, field='tags'):
+ q = BooleanQuery()
+
+ for tag in tags:
+ toks = self.search.get_tokens(tag.name, field=field)
+ tag_phrase = PhraseQuery()
+ for tok in toks:
+ tag_phrase.add(Term(field, tok))
+ q.add(BooleanClause(tag_phrase, BooleanClause.Occur.MUST))
+
+ return QueryWrapperFilter(q)
+
+ def book_filter(self):
+ tags = reduce(lambda a, b: a + b, self.book_tags.values(), [])
+ if tags:
+ return self.tag_filter(tags)
+ else:
+ return None
+
+ def part_filter(self):
+ fs = []
+ if self.part_tags:
+ fs.append(self.tag_filter(self.part_tags, field='themes'))
+
+ if self._books != []:
+ bf = BooleanFilter()
+ for b in self._books:
+ id_filter = NumericRangeFilter.newIntRange('book_id', b.id, b.id, True, True)
+ bf.add(FilterClause(id_filter, BooleanClause.Occur.SHOULD))
+ fs.append(bf)
+
+ return MultiSearch.chain_filters(fs)
+
+ def should_search_for_book(self):
+ return self._books == []
+
+ def just_search_in(self, all):
+ """Holds logic to figure out which indexes should be search, when we have some hinst already"""
+ some = []
+ for field in all:
+ if field == 'authors' and 'author' in self.book_tags:
+ continue
+ if field == 'title' and self._books != []:
+ continue
+ if (field == 'themes' or field == 'themes_pl') and self.part_tags:
+ continue
+ some.append(field)
+ return some
+
+