source: products/quintagroup.catalogupdater/trunk/quintagroup/catalogupdater/utility.py @ 1865

Last change on this file since 1865 was 1865, checked in by mylan, 14 years ago

Fix dependency from plone.indexer

  • Property svn:eol-style set to native
File size: 5.3 KB
Line 
1import logging, types
2import transaction
3from zope.interface import implements
4from zope.component import getMultiAdapter
5from zope.component import queryMultiAdapter
6
7from Missing import MV
8from Acquisition import aq_inner
9from Acquisition import aq_parent
10
11from Products.CMFCore.utils import getToolByName
12from Products.ZCatalog.Catalog import safe_callable
13
14
15try:
16    from plone.indexer.interfaces import IIndexableObject
17except ImportError:
18    class IIndexableObject:pass
19    from plone.app.content.interfaces import IIndexableObjectWrapper \
20        as _old_IIndexableObjectWrapper
21    from plone.app.content.interfaces import IIndexableObjectWrapper
22
23    register_bbb_indexers = lambda:None
24
25    IS_NEW = False
26else:   
27    from Products.CMFPlone.CatalogTool import register_bbb_indexers
28    from Products.CMFPlone.CatalogTool import _old_IIndexableObjectWrapper
29
30    IS_NEW = True
31
32
33from quintagroup.catalogupdater.interfaces import ICatalogUpdater
34
35LOG = logging.getLogger('quintagroup.catalogupdater')
36
37
38class CatalogUpdaterUtility(object):
39
40    implements(ICatalogUpdater)
41
42    def validate(self, cat, cols):
43        # Validate catalog and column name
44        AVAIL_COLTYPES = list(types.StringTypes) + [types.ListType, types.TupleType]
45
46        _cat = getattr(cat, '_catalog', None)
47        if _cat is None:
48            raise AttributeError("%s - is not ZCatalog based catalog" % cat)
49
50        if not type(cols) in AVAIL_COLTYPES:
51            raise TypeError("'columns' parameter must be one of the following " \
52                "types: %s" % AVAIL_COLTYPES)
53        # Normalize columns
54        if type(cols) in types.StringTypes:
55            cols = [cols,]
56        # Check is every column present in the catalog
57        for col in cols:
58            if not _cat.schema.has_key(col):
59                raise AttributeError("'%s' - not presented column in %s catalog " % (col, cat))
60
61        return _cat, cols
62
63
64    def getWrappedObjectNew(self, obj, portal, catalog):
65        # Returned wrapped 'obj' object with IIndexable wrapper
66        w = obj
67        if not IIndexableObject.providedBy(obj):
68             # BBB: Compatibility wrapper lookup. Should be removed in Plone 4.
69             register_bbb_indexers()
70             wrapper = queryMultiAdapter((obj, portal), _old_IIndexableObjectWrapper)
71             if wrapper is not None:
72                 w = wrapper
73             else:
74                 # This is the CMF 2.2 compatible approach, which should be used going forward
75                 wrapper = queryMultiAdapter((obj, catalog), IIndexableObject)
76                 if wrapper is not None:
77                     w = wrapper
78        return w
79
80
81    def getWrappedObjectOld(self, obj, portal, catalog):
82        # Returned wrapped 'obj' object with IIndexable wrapper
83        wf = getattr(self, 'portal_workflow', None)
84        # A comment for all the frustrated developers which aren't able to pin
85        # point the code which adds the review_state to the catalog. :)
86        # The review_state var and some other workflow vars are added to the
87        # indexable object wrapper throught the code in the following lines
88        if wf is not None:
89            vars = wf.getCatalogVariablesFor(obj)
90        else:
91            vars = {}
92       
93        w = getMultiAdapter((obj, portal), _old_IIndexableObjectWrapper)
94        w.update(vars)
95
96        return w
97
98
99    def updateMetadata4All(self, catalog, columns):
100        """ Look into appropriate method of ICatalogUpdate interface
101        """
102
103        _catalog, columns = self.validate(catalog, columns)
104
105        portal = getToolByName(catalog, 'portal_url').getPortalObject()
106        root = aq_parent(portal)
107       
108        data = _catalog.data
109        schema = _catalog.schema
110        paths = _catalog.paths
111        getWrappedObject = IS_NEW and self.getWrappedObjectNew or self.getWrappedObjectOld
112        # For subtransaction support
113        threshold = getattr(catalog, 'threshold', 10000)
114        _v_total = 0
115        _v_transaction = None
116
117        # For each catalog record update metadata
118        for rid, md in data.items():
119            # get an object
120            obj_uid = paths[rid]
121            try:
122                obj = root.unrestrictedTraverse(obj_uid)
123                obj = getWrappedObject(obj, portal, catalog)
124            except:
125                LOG.error('updateMetadata4All could not resolve '
126                          'an object from the uid %r.' % obj_uid)
127                continue
128
129            mdlist = list(md)
130            for column in columns:
131                # calculate the column value
132                attr=getattr(obj, column, MV)
133                if(attr is not MV and safe_callable(attr)): attr=attr()
134                # Update metadata value
135                indx = schema[column]
136                mdlist[indx] = attr
137
138            # Update catalog record
139            data[rid] = tuple(mdlist)
140
141            # Steeled from ZCatalog
142            if threshold is not None:
143                # figure out whether or not to commit a subtransaction.
144                t = id(transaction.get())
145                if t != _v_transaction:
146                    _v_total = 0
147                _v_transaction = t
148                _v_total = _v_total + 1
149                if _v_total > threshold:
150                    transaction.savepoint(optimistic=True)
151                    catalog._p_jar.cacheGC()
152                    _v_total = 0
153                    LOG.info('commiting subtransaction')
154
Note: See TracBrowser for help on using the repository browser.