root/pyndexter/trunk/pyndexter/hyperestraier.py @ 331

Revision 331, 3.6 KB (checked in by athomas, 4 years ago)
  • Added a MetaSource, which proxies for multiple sources.
  • A few bug fixes in FileSource that came out of the woodwork when adding MetaSource.
  • Fixed bug in FileSource default include/exclude predicate function.
Line 
1import os
2import hype
3from pyndexter import *
4
5class HyperestraierIndexer(Indexer):
6    capabilities = CAP_READONLY | CAP_CONTENT | CAP_ATTRIBUTES | CAP_ORDERING |\
7                   CAP_HITCOUNT | CAP_LIST | CAP_RELEVANCE
8
9    def __init__(self, path, source=None, mode=READWRITE, hype_mode=None):
10        Indexer.__init__(self, source, mode, os.path.join(path, 'state.db'))
11        self.path = path
12        if not os.path.exists(self.path):
13            if mode != READWRITE:
14                raise IndexerError("Index directory has not been initialised")
15            os.makedirs(self.path)
16        self.hype_path = os.path.join(self.path, 'hyperestraier.db')
17        if hype_mode is None:
18            hype_mode = 0
19            if mode == READONLY:
20                hype_mode |= hype.ESTDBREADER
21            elif mode == READWRITE:
22                hype_mode |= hype.ESTDBWRITER|hype.ESTDBCREAT
23        self.db = hype.Database(self.hype_path, hype_mode)
24
25    def fetch(self, uri):
26        if self.source:
27            return self.source.fetch(uri)
28        doc = self.db.get_doc_by_uri(uri)
29        if doc is None:
30            raise DocumentNotFound(uri)
31        attributes = self._translate_attributes(doc)
32        return Document(content=doc.text, source=self.source, **attributes)
33
34    def index(self, document):
35        self._assert_rw()
36        if isinstance(document, basestring):
37            document = self.fetch(document)
38        hdoc = hype.Document()
39        for k, v in document.attributes.iteritems():
40            hdoc['@' + k] = v
41        hdoc.add_text(document.content)
42        self.db.put_doc(hdoc)
43
44    def discard(self, document):
45        self._assert_rw()
46        if isinstance(document, Document):
47            document = document.uri
48        doc = self.db.get_doc_by_uri(document)
49        if not doc:
50            raise DocumentNotFound(document)
51        self.db.remove(doc)
52
53    def search(self, phrase, order_by=None, order_ascending=True,
54               order_type=str, intersection=True):
55        phrase = (intersection and ' ' or '|').join(phrase.split())
56        order = None
57        if order_by is not None:
58            if order_type is int:
59                order_type = 'NUM'
60            else:
61                order_type = 'STR'
62            print order_ascending
63            order = u'@%s %s%s' % (order_by, order_type,
64                                   order_ascending and 'A' or 'D')
65        return self.hype_search(phrase, order=order)
66
67    def hype_search(self, phrase, simple=True, order=None):
68        """ Full Hyperestraier search phrase. """
69        search = self.db.search(phrase, simple=simple)
70        if order is not None:
71            search = search.order(order)
72        return HyperestraierSearch(self, phrase, search)
73
74    def optimize(self):
75        self._assert_rw()
76        self.db.optimize()
77
78    def sync(self):
79        if self.mode == READWRITE:
80            self.db.sync()
81            self._sync_source_state()
82
83    def close(self):
84        if self.mode == READWRITE:
85            self.sync()
86        self.db = None
87
88    # Internal methods
89    def _translate_attributes(self, hdoc):
90        attributes = {}
91        for k in hdoc.attributes:
92            if k[0] == '@':
93                attributes[k[1:]] = hdoc.get(k)
94            else:
95                attributes[k] = hdoc.get(k)
96        return attributes
97
98
99class HyperestraierSearch(Search):
100    def __iter__(self):
101        for doc in self.context:
102            # How do we get the score?
103            yield Hit(document=self.indexer.fetch,
104                      **self.indexer._translate_attributes(doc))
105
106    def __len__(self):
107        return len(self.context)
108
109    def __getitem__(self, index):
110        return self.context[index]['@uri']
Note: See TracBrowser for help on using the browser.