fbe323fb18b85c858e1b608b0a97a77c39878e3e
[Plinn.git] / catalog.py
1 # -*- coding: utf-8 -*-
2 from App.class_init import InitializeClass
3 from AccessControl import ClassSecurityInfo
4 from Products.CMFCore.interfaces import IIndexableObject
5 from Products.CMFCore.CatalogTool import CatalogTool as BaseCatalogTool
6 from Products.CMFCore.CatalogTool import IndexableObjectWrapper
7 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
8 from Products.CMFCore.permissions import ModifyPortalContent
9 from zope.component import queryMultiAdapter
10 from Products.ZCatalog.Catalog import Catalog
11 import transaction
12 from solr import *
13
14 class SolrTransactionHook :
15 ''' commit solr couplé sur le commit de la ZODB '''
16 def __init__(self, connection) :
17 self.connection = connection
18
19 def __call__(self, status) :
20 if status :
21 self.connection.commit()
22 self.connection.close()
23 else :
24 self.connection.close()
25
26 class CatalogTool(BaseCatalogTool) :
27 meta_type = 'Legivoc Catalog'
28 security = ClassSecurityInfo()
29 manage_options = (BaseCatalogTool.manage_options[:5] +
30 ({'label' : 'Solr', 'action' : 'manage_solr'},) +
31 BaseCatalogTool.manage_options[5:])
32 manage_solr = PageTemplateFile('www/manage_solr', globals())
33
34
35 def __init__(self, idxs=[]) :
36 super(CatalogTool, self).__init__()
37 self._catalog = DelegatedCatalog()
38 self.solr_url = 'http://localhost:8983/solr'
39 self.delegatedIndexes = ('Title', 'Description', 'SearchableText')
40
41 security.declarePrivate('solrAdd')
42 def solrAdd(self, object, idxs=[], uid=None) :
43 if IIndexableObject.providedBy(object):
44 w = object
45 else:
46 w = queryMultiAdapter( (object, self), IIndexableObject )
47 if w is None:
48 # BBB
49 w = IndexableObjectWrapper(object, self)
50
51 uid = uid if uid else self.__url(object)
52 idxs = idxs if idxs !=[] else self.delegatedIndexes
53 data = {'id' : uid}
54 for name in idxs :
55 attr = getattr(w, name, '')
56 data[name] = attr() if callable(attr) else attr
57 c = SolrConnection(self.solr_url)
58 c.add(**data)
59 txn = transaction.get()
60 txn.addAfterCommitHook(SolrTransactionHook(c))
61
62
63 # PortalCatalog api overloads
64 security.declareProtected(ModifyPortalContent, 'indexObject')
65 def indexObject(self, object) :
66 """ Add to catalog and send to Solr """
67 super(CatalogTool, self).indexObject(object)
68 self.solrAdd(object)
69
70 security.declarePrivate('reindexObject')
71 def reindexObject(self, object, idxs=[], update_metadata=1, uid=None):
72 super(CatalogTool, self).reindexObject(object,
73 idxs=idxs,
74 update_metadata=update_metadata,
75 uid=uid)
76 if idxs != []:
77 # Filter out invalid indexes.
78 valid_indexes = self._catalog.indexes.keys()
79 idxs = [i for i in idxs if i in valid_indexes and i in self.delegatedIndexes]
80 else :
81 idxs = self.delegatedIndexes
82
83 if idxs :
84 self.solrAdd(object, idxs=idxs, uid=uid)
85
86 security.declarePrivate('unindexObject')
87 def unindexObject(self, object):
88 """Remove from catalog.
89 """
90 super(CatalogTool, self).unindexObject(object)
91 c = SolrConnection(self.solr_url)
92 url = self.__url(object)
93 c.delete(id=url)
94 txn = transaction.get()
95 txn.addAfterCommitHook(SolrTransactionHook(c))
96
97 InitializeClass(CatalogTool)
98
99
100 class DelegatedCatalog(Catalog) :
101 '''C'est ici qu'on délègue effectivement à Solr '''
102 def search(self, query, sort_index=None, reverse=0, limit=None, merge=1):
103 return Catalog.search(self, query,
104 sort_index=sort_index,
105 reverse=reverse, limit=limit, merge=merge)