def testRenameEvents(self): self.assertRaises(KeyError, self.reflecto.manage_renameObjects, ('monty',), ('python',)) self.assertEqual(len(getEvents()), 0) self.assertRaises(KeyError, self.reflecto.manage_renameObjects, ('foo', 'monty'), ('bar', 'python')) self.assertEqual(len(getEvents()), 1) events = getEvents(IObjectWillBeMovedEvent) self.assertEqual(len(events), 1) self.assertEqual(events[0].oldName, 'foo') self.assertEqual(events[0].newName, 'bar') self.assertEqual(self.reflecto.manage_renameObjects(('foo',), ('bar',)), ['foo']) events = getEvents() self.assertEqual(len(events), 4) self.assertTrue(IObjectWillBeMovedEvent.providedBy(events[1])) self.assertTrue(IObjectMovedEvent.providedBy(events[2])) self.assertEqual(events[2].oldName, 'foo') self.assertEqual(events[2].newName, 'bar') self.assertTrue(IContainerModifiedEvent.providedBy(events[3])) self.assertTrue(events[3].object is self.reflecto)
def test_events(self): from OFS.interfaces import IObjectWillBeAddedEvent from zope.app.container.interfaces import IContainerModifiedEvent from zope.app.container.interfaces import IObjectAddedEvent from zope.component import adapter from zope.component import provideHandler from zope.lifecycleevent.interfaces import IObjectCreatedEvent events = [] @adapter(IObjectCreatedEvent) def _handleObjectCreated(event): events.append(event) provideHandler(_handleObjectCreated) @adapter(IObjectWillBeAddedEvent) def _handleObjectWillBeAdded(event): events.append(event) provideHandler(_handleObjectWillBeAdded) @adapter(IObjectAddedEvent) def _handleObjectAdded(event): events.append(event) provideHandler(_handleObjectAdded) @adapter(IContainerModifiedEvent) def _handleContainerModified(event): events.append(event) provideHandler(_handleContainerModified) self.ti.constructInstance(self.f, 'foo') self.assertEquals(len(events), 4) evt = events[0] self.failUnless(IObjectCreatedEvent.providedBy(evt)) self.assertEquals(evt.object, self.f.foo) evt = events[1] self.failUnless(IObjectWillBeAddedEvent.providedBy(evt)) self.assertEquals(evt.object, self.f.foo) self.assertEquals(evt.oldParent, None) self.assertEquals(evt.oldName, None) self.assertEquals(evt.newParent, self.f) self.assertEquals(evt.newName, 'foo') evt = events[2] self.failUnless(IObjectAddedEvent.providedBy(evt)) self.assertEquals(evt.object, self.f.foo) self.assertEquals(evt.oldParent, None) self.assertEquals(evt.oldName, None) self.assertEquals(evt.newParent, self.f) self.assertEquals(evt.newName, 'foo') evt = events[3] self.failUnless(IContainerModifiedEvent.providedBy(evt)) self.assertEquals(evt.object, self.f)
def create_version_on_save(context, event): """Creates a new version on a versionable object when the object is saved. A new version is created if the type is automatic versionable and has changed or if the user has entered a change note. """ # according to Products.CMFEditions' update_version_on_edit script # only version the modified object, not its container on modification if IContainerModifiedEvent.providedBy(event): return #aliases should not be versioned at all if hasattr(context.aq_base, '_alias_portal_type'): return # XXX dirty hack for stagingbehavior, which triggers a event with # a aq_based context when deleting the working copy try: pr = context.portal_repository except AttributeError: return if not pr.isVersionable(context): # cancel, the object is not versionable return create_version = False if getattr(context, 'REQUEST', None): changeNote = get_change_note(context.REQUEST, None) else: changeNote = None if changeNote: # user has entered a change note. create a new version even if nothing # has changed. create_version = True elif pr.supportsPolicy(context, 'at_edit_autoversion'): # automatic versioning is enabled for this portal type if not base_hasattr(context, 'version_id'): # we do not have a initial version create_version = True else: try: create_version = not pr.isUpToDate(context, context.version_id) except ArchivistUnregisteredError: # The object is not actually registered, but a version is # set, perhaps it was imported, or versioning info was # inappropriately destroyed create_version = True # create new version if needed if create_version: pr.save(obj=context, comment=changeNote)
def testCutEvents(self): cp = self.reflecto.manage_cutObjects(('foo',)) self.reflecto['subdir'].manage_pasteObjects(cp) events = getEvents() self.assertEqual(len(events), 4) self.assertTrue(IObjectWillBeMovedEvent.providedBy(events[0])) self.assertEqual(events[0].oldName, 'foo') self.assertEqual(events[0].oldParent, self.reflecto) self.assertEqual(events[0].newName, 'foo') self.assertEqual(events[0].newParent, self.reflecto['subdir']) self.assertTrue(IObjectMovedEvent.providedBy(events[1])) self.assertEqual(events[1].object.getId(), 'foo') self.assertTrue(IContainerModifiedEvent.providedBy(events[2])) self.assertEqual(events[2].object, self.reflecto) self.assertTrue(IContainerModifiedEvent.providedBy(events[3])) self.assertEqual(events[3].object, self.reflecto['subdir'])
def renameAfterCreation(obj, event): """Rename object after first edit. """ # Do no rename when the object is first added if not IContainerModifiedEvent.providedBy(event): utils = getToolByName(obj, 'plone_utils') # Rename only if the current id is autogenerated if utils.isIDAutoGenerated(obj.id): parent = aq_inner(obj).getParentNode() if parent is not None: chooser = INameChooser(parent) newid = chooser.chooseName('', obj) parent.manage_renameObject(obj.id, newid)
def validateContext(object, event): """ create the Zipfile after some final checks """ parent = getUtility(IECUtility).FindECParent(object) file_id = parent.id + ".zip" pw = event.object.portal_workflow if parent.portal_type == "Course": if pw.getInfoFor(parent, "review_state") == "Published": if not event.object.isTemporary(): if event.object.id != file_id: if not IContainerModifiedEvent.providedBy(event): ZipFileCreator(parent, event).createZipFile()
def testCopyEvents(self): cp = self.reflecto.manage_copyObjects(('foo',)) self.reflecto.manage_pasteObjects(cp) events = getEvents() self.assertEqual(len(events), 3) self.assertTrue(IObjectCopiedEvent.providedBy(events[0])) self.assertEqual(events[0].original.getId(), 'foo') self.assertEqual(events[0].object.getId(), 'copy_of_foo') self.assertTrue(IObjectClonedEvent.providedBy(events[1])) self.assertEqual(events[1].object.getId(), 'copy_of_foo') self.assertTrue(IContainerModifiedEvent.providedBy(events[2])) self.assertTrue(events[2].object is self.reflecto)
def save_featurelets(obj, event=None, request=None): """ IObjectModified event subscriber that installs the appropriate featurelets. """ if IContainerModifiedEvent.providedBy(event): # we only care about direct edits return if not request: request = obj.REQUEST if event and request.get('__initialize_project__', None): # bail if project isn't actuated yet and we are used via an # IObjectModifiedEvent event return if request.get('set_flets') is None: # don't do anything unless we're actually coming from the # project edit screen return # XXX there must be a better way... :-| if request.get('flet_recurse_flag') is not None: return request.set('flet_recurse_flag', True) supporter = IFeatureletSupporter(obj) flets = dict(getAdapters((supporter,), IFeaturelet)) desired = request.form.get('featurelets') if desired is None: desired = tuple() desired = set(desired) installed = set([name for name, flet in flets.items() if flet.installed]) needed = desired.difference(installed) for flet_id in needed: supporter.installFeaturelet(flets[flet_id]) removed = installed.difference(desired) for flet_id in removed: supporter.removeFeaturelet(flets[flet_id])
def testDeleteEvents(self): self.assertRaises(KeyError, self.reflecto.manage_delObjects, ('monty',)) self.assertEqual(len(getEvents()), 0) self.assertRaises(KeyError, self.reflecto.manage_delObjects, ('foo', 'monty',)) self.assertEqual(len(getEvents()), 1) events = getEvents(IObjectWillBeRemovedEvent) self.assertEqual(len(events), 1) self.assertEqual(events[0].oldName, 'foo') self.assertEqual(self.reflecto.manage_delObjects(('foo',)), None) events = getEvents() self.assertEqual(len(events), 4) self.assertTrue(IObjectWillBeRemovedEvent.providedBy(events[1])) self.assertTrue(IObjectRemovedEvent.providedBy(events[2])) self.assertEqual(events[2].oldName, 'foo') self.assertTrue(IContainerModifiedEvent.providedBy(events[3])) self.assertTrue(events[3].object is self.reflecto)
def changeMailingList(ml, event): """An event listener which registers and unregisters lists with the ListLookup utility on list changes. Some framework setup: >>> from zope.app.testing.placelesssetup import setUp, tearDown >>> import Products.Five >>> from Products.Five import zcml >>> setUp() >>> zcml.load_config('meta.zcml', package=Products.Five) >>> zcml.load_config('permissions.zcml', package=Products.Five) >>> zcml.load_config("configure.zcml", package=Products.Five.site) >>> from Products.listen.utilities import tests >>> zcml.load_config('configure.zcml', package=tests) Now let's make a fake mailing list in our site >>> from zope.app.component.hooks import setSite >>> app = self.folder >>> tests.enable_local_site(app) >>> setSite(app) >>> ml = tests.install_fake_ml(app, suppress_events=True) >>> setSite(ml) Then we setup our listener >>> from zope.app.event.interfaces import IObjectModifiedEvent >>> from zope.app.container.interfaces import IObjectMovedEvent >>> from OFS.interfaces import IObjectWillBeRemovedEvent >>> from Products.listen.utilities.list_lookup import changeMailingList >>> from zope.component import handle >>> from Products.listen.interfaces import IMailingList >>> handle([IMailingList, IObjectWillBeRemovedEvent], changeMailingList) >>> handle([IMailingList, IObjectMovedEvent], changeMailingList) >>> handle([IMailingList, IObjectModifiedEvent], changeMailingList) Create and register our utility. Have to do some faking of the component registry stuff to get our mock environment to work: >>> from Products.listen.interfaces import IListLookup >>> from Products.listen.utilities.list_lookup import ListLookup >>> from Products.listen.lib.common import get_utility_for_context >>> sm = app.getSiteManager() >>> sm.registerUtility(ListLookup('list_lookup'), IListLookup) >>> tests.register_fake_component_adapter() >>> ll = get_utility_for_context(IListLookup, context=app) >>> print ll.getListForAddress(ml.mailto) None Send our added event: >>> from zope.event import notify >>> from zope.app.container.contained import ObjectAddedEvent >>> notify(ObjectAddedEvent(ml, app, 'ml')) >>> ll.getListForAddress(ml.mailto) == ml True Change the list and send an event: >>> ml.mailto = '*****@*****.**' >>> from zope.app.event.objectevent import ObjectModifiedEvent >>> notify(ObjectModifiedEvent(ml)) >>> ll.getListForAddress(ml.mailto) == ml True Send a removal event, which should do nothing, as we rely on before removal: >>> from zope.app.container.contained import ObjectRemovedEvent >>> notify(ObjectRemovedEvent(ml, app, 'ml')) >>> ll.getListForAddress(ml.mailto) == ml True Send a before removal event: >>> from OFS.event import ObjectWillBeRemovedEvent >>> notify(ObjectWillBeRemovedEvent(ml)) >>> ll.getListForAddress(ml.mailto) is None True >>> tearDown() """ # Use the new parent object as the context, unless it is unavailable, then # use the list itself parent = None if hasattr(event, 'newParent'): parent = event.newParent if parent is None: parent = ml try: ll = getUtility(IListLookup) except ComponentLookupError: # site won't be set if you delete the Plone site from the ZMI orig_site = getSite() setSite(ml) ll = getUtility(IListLookup, context=ml) setSite(orig_site) if IObjectWillBeAddedEvent.providedBy(event): # Registration is taken care of after add pass elif IObjectWillBeRemovedEvent.providedBy(event): ll.unregisterList(ml) elif IObjectWillBeMovedEvent.providedBy(event): ll.unregisterList(ml) elif IObjectRemovedEvent.providedBy(event): # Unregistration is taken care of before removal pass elif IObjectModifiedEvent.providedBy(event): if not IContainerModifiedEvent.providedBy(event): ll.updateList(ml) elif IObjectAddedEvent.providedBy(event) or IObjectCreatedEvent.providedBy( event): ll.registerList(ml) elif IObjectMovedEvent.providedBy(event): ll.registerList(ml)
def changeMailingList(ml, event): """An event listener which registers and unregisters lists with the ListLookup utility on list changes. Some framework setup: >>> from zope.app.testing.placelesssetup import setUp, tearDown >>> import Products.Five >>> from Products.Five import zcml >>> setUp() >>> zcml.load_config('meta.zcml', package=Products.Five) >>> zcml.load_config('permissions.zcml', package=Products.Five) >>> zcml.load_config("configure.zcml", package=Products.Five.site) >>> from Products.listen.utilities import tests >>> zcml.load_config('configure.zcml', package=tests) Now let's make a fake mailing list in our site >>> from zope.app.component.hooks import setSite >>> app = self.folder >>> tests.enable_local_site(app) >>> setSite(app) >>> ml = tests.install_fake_ml(app, suppress_events=True) >>> setSite(ml) Then we setup our listener >>> from zope.app.event.interfaces import IObjectModifiedEvent >>> from zope.app.container.interfaces import IObjectMovedEvent >>> from OFS.interfaces import IObjectWillBeRemovedEvent >>> from Products.listen.utilities.list_lookup import changeMailingList >>> from zope.component import handle >>> from Products.listen.interfaces import IMailingList >>> handle([IMailingList, IObjectWillBeRemovedEvent], changeMailingList) >>> handle([IMailingList, IObjectMovedEvent], changeMailingList) >>> handle([IMailingList, IObjectModifiedEvent], changeMailingList) Create and register our utility. Have to do some faking of the component registry stuff to get our mock environment to work: >>> from Products.listen.interfaces import IListLookup >>> from Products.listen.utilities.list_lookup import ListLookup >>> from Products.listen.lib.common import get_utility_for_context >>> sm = app.getSiteManager() >>> sm.registerUtility(ListLookup('list_lookup'), IListLookup) >>> tests.register_fake_component_adapter() >>> ll = get_utility_for_context(IListLookup, context=app) >>> print ll.getListForAddress(ml.mailto) None Send our added event: >>> from zope.event import notify >>> from zope.app.container.contained import ObjectAddedEvent >>> notify(ObjectAddedEvent(ml, app, 'ml')) >>> ll.getListForAddress(ml.mailto) == ml True Change the list and send an event: >>> ml.mailto = '*****@*****.**' >>> from zope.app.event.objectevent import ObjectModifiedEvent >>> notify(ObjectModifiedEvent(ml)) >>> ll.getListForAddress(ml.mailto) == ml True Send a removal event, which should do nothing, as we rely on before removal: >>> from zope.app.container.contained import ObjectRemovedEvent >>> notify(ObjectRemovedEvent(ml, app, 'ml')) >>> ll.getListForAddress(ml.mailto) == ml True Send a before removal event: >>> from OFS.event import ObjectWillBeRemovedEvent >>> notify(ObjectWillBeRemovedEvent(ml)) >>> ll.getListForAddress(ml.mailto) is None True >>> tearDown() """ # Use the new parent object as the context, unless it is unavailable, then # use the list itself parent = None if hasattr(event, 'newParent'): parent = event.newParent if parent is None: parent = ml try: ll = getUtility(IListLookup) except ComponentLookupError: # site won't be set if you delete the Plone site from the ZMI orig_site = getSite() setSite(ml) ll = getUtility(IListLookup, context=ml) setSite(orig_site) if IObjectWillBeAddedEvent.providedBy(event): # Registration is taken care of after add pass elif IObjectWillBeRemovedEvent.providedBy(event): ll.unregisterList(ml) elif IObjectWillBeMovedEvent.providedBy(event): ll.unregisterList(ml) elif IObjectRemovedEvent.providedBy(event): # Unregistration is taken care of before removal pass elif IObjectModifiedEvent.providedBy(event): if not IContainerModifiedEvent.providedBy(event): ll.updateList(ml) elif IObjectAddedEvent.providedBy(event) or IObjectCreatedEvent.providedBy(event): ll.registerList(ml) elif IObjectMovedEvent.providedBy(event): ll.registerList(ml)