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

Last change on this file since 3142 was 3142, checked in by vmaksymiv, 13 years ago

pep8 fixes

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