[1755] | 1 | import logging, types |
---|
[1754] | 2 | from zope.interface import implements |
---|
| 3 | from zope.component import queryMultiAdapter |
---|
| 4 | from plone.indexer.interfaces import IIndexableObject |
---|
| 5 | |
---|
| 6 | from Missing import MV |
---|
| 7 | from Acquisition import aq_inner |
---|
| 8 | from Acquisition import aq_parent |
---|
| 9 | |
---|
| 10 | from Products.CMFCore.utils import getToolByName |
---|
| 11 | from Products.ZCatalog.Catalog import safe_callable |
---|
| 12 | from Products.CMFPlone.CatalogTool import register_bbb_indexers |
---|
| 13 | from Products.CMFPlone.CatalogTool import _old_IIndexableObjectWrapper |
---|
| 14 | |
---|
| 15 | from quintagroup.catalogupdater.interfaces import ICatalogUpdater |
---|
| 16 | |
---|
| 17 | LOG = logging.getLogger('quintagroup.catalogupdater') |
---|
| 18 | |
---|
| 19 | |
---|
| 20 | class CatalogUpdaterUtility(object): |
---|
| 21 | |
---|
| 22 | implements(ICatalogUpdater) |
---|
| 23 | |
---|
[1755] | 24 | def validate(self, cat, cols): |
---|
[1754] | 25 | # Validate catalog and column name |
---|
[1755] | 26 | AVAIL_COLTYPES = list(types.StringTypes) + [types.ListType, types.TupleType] |
---|
| 27 | |
---|
[1754] | 28 | _cat = getattr(cat, '_catalog', None) |
---|
| 29 | if _cat is None: |
---|
| 30 | raise AttributeError("%s - is not ZCatalog based catalog" % cat) |
---|
| 31 | |
---|
[1755] | 32 | if not type(cols) in AVAIL_COLTYPES: |
---|
| 33 | raise TypeError("'columns' parameter must be one of the following " \ |
---|
| 34 | "types: %s" % AVAIL_COLTYPES) |
---|
| 35 | # Normalize columns |
---|
| 36 | if type(cols) in types.StringTypes: |
---|
| 37 | cols = [cols,] |
---|
| 38 | # Check is every column present in the catalog |
---|
| 39 | for col in cols: |
---|
| 40 | if not _cat.schema.has_key(col): |
---|
| 41 | raise AttributeError("'%s' - not presented column in %s catalog " % (col, cat)) |
---|
[1754] | 42 | |
---|
[1755] | 43 | return _cat, cols |
---|
| 44 | |
---|
[1754] | 45 | def getWrapedObject(self, obj, portal, catalog): |
---|
| 46 | # Returned wrapped 'obj' object with IIndexable wrapper |
---|
| 47 | w = obj |
---|
| 48 | if not IIndexableObject.providedBy(obj): |
---|
| 49 | # BBB: Compatibility wrapper lookup. Should be removed in Plone 4. |
---|
| 50 | register_bbb_indexers() |
---|
| 51 | wrapper = queryMultiAdapter((obj, portal), _old_IIndexableObjectWrapper) |
---|
| 52 | if wrapper is not None: |
---|
| 53 | w = wrapper |
---|
| 54 | else: |
---|
| 55 | # This is the CMF 2.2 compatible approach, which should be used going forward |
---|
| 56 | wrapper = queryMultiAdapter((obj, catalog), IIndexableObject) |
---|
| 57 | if wrapper is not None: |
---|
| 58 | w = wrapper |
---|
| 59 | return w |
---|
| 60 | |
---|
| 61 | |
---|
[1755] | 62 | def updateMetadata4All(self, catalog, columns): |
---|
[1754] | 63 | """ Look into appropriate method of ICatalogUpdate interface |
---|
| 64 | """ |
---|
| 65 | |
---|
[1755] | 66 | _catalog, columns = self.validate(catalog, columns) |
---|
| 67 | |
---|
[1754] | 68 | portal = getToolByName(catalog, 'portal_url').getPortalObject() |
---|
| 69 | root = aq_parent(portal) |
---|
| 70 | |
---|
| 71 | data = _catalog.data |
---|
| 72 | schema = _catalog.schema |
---|
| 73 | paths = _catalog.paths |
---|
| 74 | |
---|
| 75 | # For each catalog record update metadata |
---|
| 76 | for rid, md in data.items(): |
---|
| 77 | # get an object |
---|
| 78 | obj_uid = paths[rid] |
---|
| 79 | try: |
---|
| 80 | obj = root.unrestrictedTraverse(obj_uid) |
---|
| 81 | obj = self.getWrapedObject(obj, portal, catalog) |
---|
| 82 | except: |
---|
[1755] | 83 | LOG.error('updateMetadata4All could not resolve ' |
---|
[1754] | 84 | 'an object from the uid %r.' % obj_uid) |
---|
| 85 | continue |
---|
| 86 | |
---|
| 87 | mdlist = list(md) |
---|
[1755] | 88 | for column in columns: |
---|
| 89 | # calculate the column value |
---|
| 90 | attr=getattr(obj, column, MV) |
---|
| 91 | if(attr is not MV and safe_callable(attr)): attr=attr() |
---|
| 92 | # Update metadata value |
---|
| 93 | indx = schema[column] |
---|
| 94 | mdlist[indx] = attr |
---|
[1754] | 95 | |
---|
[1755] | 96 | # Update catalog record |
---|
[1754] | 97 | data[rid] = tuple(mdlist) |
---|
| 98 | |
---|