-def log_exception_wrapper(f):
- def _wrap(*a):
- try:
- f(*a)
- except Exception, e:
- log.error("Error in indexing thread: %s" % e)
- traceback.print_exc()
- raise e
- return _wrap
-
-
-class ReusableIndex(Index):
- """
- Works like index, but does not close/optimize Lucene index
- until program exit (uses atexit hook).
- This is usefull for importbooks command.
-
- if you cannot rely on atexit, use ReusableIndex.close_reusable() yourself.
- """
- index = None
-
- def open(self, analyzer=None, **kw):
- if ReusableIndex.index:
- self.index = ReusableIndex.index
- else:
- Index.open(self, analyzer, **kw)
- ReusableIndex.index = self.index
- atexit.register(ReusableIndex.close_reusable)
-
- # def index_book(self, *args, **kw):
- # job = ReusableIndex.pool.apply_async(log_exception_wrapper(Index.index_book), (self,) + args, kw)
- # ReusableIndex.pool_jobs.append(job)
-
- @staticmethod
- def close_reusable():
- if ReusableIndex.index:
- ReusableIndex.index.optimize()
- ReusableIndex.index.close()
- ReusableIndex.index = None
-
- index_changed.send_robust(None)
-
- def close(self):
- if ReusableIndex.index:
- ReusableIndex.index.commit()
-
-
-class JoinSearch(object):
- """
- This mixin could be used to handle block join queries.
- (currently unused)
- """
- def __init__(self, *args, **kw):
- super(JoinSearch, self).__init__(*args, **kw)
-
- def wrapjoins(self, query, fields=[]):
- """
- This functions modifies the query in a recursive way,
- so Term and Phrase Queries contained, which match
- provided fields are wrapped in a BlockJoinQuery,
- and so delegated to children documents.
- """
- if BooleanQuery.instance_(query):
- qs = BooleanQuery.cast_(query)
- for clause in qs:
- clause = BooleanClause.cast_(clause)
- clause.setQuery(self.wrapjoins(clause.getQuery(), fields))
- return qs
- else:
- termset = HashSet()
- query.extractTerms(termset)
- for t in termset:
- t = Term.cast_(t)
- if t.field() not in fields:
- return query
- return BlockJoinQuery(query, self.parent_filter,
- BlockJoinQuery.ScoreMode.Total)
-
- def bsearch(self, query, max_results=50):
- q = self.query(query)
- bjq = BlockJoinQuery(q, self.parent_filter, BlockJoinQuery.ScoreMode.Avg)
-
- tops = self.searcher.search(bjq, max_results)
- bks = []
- for found in tops.scoreDocs:
- doc = self.searcher.doc(found.doc)
- bks.append(catalogue.models.Book.objects.get(id=doc.get("book_id")))
- return (bks, tops.totalHits)
-
-