home contents changes options help subscribe edit (external edit)

A Quick Event-based Cataloging How-to for Zope 2

I'm building a Zope 2 app where I need to index objects that are not catalog aware when they're added, modified or removed. To make things harder, this also needs to work via Zope and WebDAV.

OK, so here's the solution:

1. Create yourself a python module called subscribers.py and put it on your python path, containing the following:

from Acquisition import aq_base from zope.interface import Interface

class ICatalogAware?(Interface): pass

def catalog(object,event):
if aq_base(object) is object:
# ObjectModified? can get emitted during creation, # before the object has any acquisition context return
object.getPhysicalRoot().unrestrictedTraverse(
'/catalog'

).catalog_object(object)

def uncatalog(object,event):
object.getPhysicalRoot().unrestrictedTraverse(
'/catalog'

).uncatalog_object('/'.join(object.getPhysicalPath()))

2. Slap the ICatalogAware? marker interface on any classes you want to have indexed. Here's an example for the good old File object. Put the following in your site.zcml:

<class class="OFS.Image.File"> <implements interface="subscribers.ICatalogAware?"/> </class>

3. Finally, wire up the events so that files get indexed when they're created, modified or removed, again by adding the following to site.zcml:

<subscriber

handler="subscribers.catalog" for="ICatalogAware?

zope.app.container.contained.ObjectAddedEvent?"

/>

<subscriber

handler="subscribers.catalog" for="ICatalogAware?

zope.app.container.contained.ObjectModifiedEvent?"

/>

<subscriber

handler="subscribers.uncatalog" for="ICatalogAware?

zope.app.container.contained.ObjectRemovedEvent?"

/>

4. Okay, sadly you do need to get do some patching if you want changes to the file to result in recataloging :-/ Here's a diff:

--- Image.py.original 2006-09-26 16:32:20.759375000 +0100 +++ Image.py 2006-09-26 16:33:11.384375000 +0100 @@ -33,6 +33,8 @@

from ZPublisher.HTTPRequest? import FileUpload? from ZPublisher.Iterators import filestream_iterator from zExceptions import Redirect

+from zope.event import notify +from zope.app.container.contained import ObjectModifiedEvent?

from cgi import escape import transaction
@@ -437,6 +439,7 @@
self.ZCacheable?_invalidate() self.ZCacheable?_set(None) self.http__refreshEtag()
  • notify(ObjectModifiedEvent?(self))
def manage_edit(self, title, content_type, precondition='',
filedata=None, REQUEST=None):



subject:
  ( 24 subscribers )