1# -*- coding: utf-8 -*-
2"""
3    sphinxcontrib.websupport.search.whooshsearch
4    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
6    Whoosh search adapter.
7
8    :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
9    :license: BSD, see LICENSE for details.
10"""
11
12from whoosh import index
13from whoosh.fields import Schema, ID, TEXT
14from whoosh.qparser import QueryParser
15from whoosh.analysis import StemmingAnalyzer
16
17from sphinx.util.osutil import ensuredir
18from sphinxcontrib.websupport.search import BaseSearch
19
20
21class WhooshSearch(BaseSearch):
22    """The whoosh search adapter for sphinx web support."""
23
24    # Define the Whoosh Schema for the search index.
25    schema = Schema(path=ID(stored=True, unique=True),
26                    title=TEXT(field_boost=2.0, stored=True),
27                    text=TEXT(analyzer=StemmingAnalyzer(), stored=True))
28
29    def __init__(self, db_path):
30        ensuredir(db_path)
31        if index.exists_in(db_path):
32            self.index = index.open_dir(db_path)
33        else:
34            self.index = index.create_in(db_path, schema=self.schema)
35        self.qparser = QueryParser('text', self.schema)
36
37    def init_indexing(self, changed=[]):
38        for changed_path in changed:
39            self.index.delete_by_term('path', changed_path)
40        self.index_writer = self.index.writer()
41
42    def finish_indexing(self):
43        self.index_writer.commit()
44
45    def add_document(self, pagename, filename, title, text):
46        self.index_writer.add_document(path=pagename,
47                                       title=title,
48                                       text=text)
49
50    def handle_query(self, q):
51        searcher = self.index.searcher()
52        whoosh_results = searcher.search(self.qparser.parse(q))
53        results = []
54        for result in whoosh_results:
55            context = self.extract_context(result['text'])
56            results.append((result['path'],
57                            result.get('title', ''),
58                            context))
59        return results
60