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)
Beispiel #2
0
    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 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)
Beispiel #7
0
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()
Beispiel #8
0
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 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)
Beispiel #10
0
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)