I have an indexer called 'calduedate_indexer', which indexes a DateIndex 'calDueDate' for any object that provides an interface ICalibratable. The index is added through setuphandlers and then defined as a metadata column in catalog.xml. Objects that provide ICalibratable can store content types called Calibrations. Calibrations have a calculated property 'next_calibration', which is stored in metadata. An accessor adapter with an interface ICalibrationAccessor is used to retrieve calibration information of a 'Calibratable' content type, such as a calculation for the date of an upcoming calibration.
In the indexer, a function on the accessor called getDueDate is called to get the next calibration by getting calibration records through a portal_catalog search (i.e. getFolderContents on the Calibratable type), returning None if there is no calibration due date.
This works when the calibration record is added/modified, but when a calibration record is deleted, the catalog search fails.
In adapters.py:
@indexer(ICalibratable)
def calduedate_indexer(obj):
duedate = ICalibrationAccessor(obj).getCalibrationDueDate()
return duedate
class ICalibrationAccessor(Interface):
def getCalibrationDueDate():
""" Get next calibration """
@adapter(ICalibratable)
@implementer(ICalibrationAccessor)
class CalibrationAccessor(object):
def __init__(self, context):
object.__setattr__(self, 'context', context)
def getCalibrationDueDate(self):
dates = []
brains = self.context.getFolderContents({'portal_type':'Calibration'})
for cal in brains:
if cal['next_calibration']:
dates.append(cal['next_calibration'])
if len(dates) > 0:
return sorted(dates)[0]
else:
return None
In configure.zcml:
<adapter name="calDueDate" factory=".adapters.calduedate_indexer/>
<adapter
for = "my.product.behaviors.interfaces.ICalibratable"
provides="my.product.adapters.ICalibrationAccessor"
factory="my.product.adapters.CalibrationAccessor"/>
Note: The indexer is called automatically when a Calibration is added or deleted, but it needs to be updated manually when modified, so I use an event subscriber on the calibration.
Is there a time when the portal_catalog can not be queried? If so, is there a work around?