def test_replace(events):
    """If we try to replace an item without deleting it first, we'll get
    an error.
    """
    container = {}

    # We create a first item
    item = Item()
    setitem(container, container.__setitem__, u'c', item)

    # We try to override
    with pytest.raises(KeyError):
        setitem(container, container.__setitem__, u'c', [])

    # We have to delete to replace a key
    del container[u'c']
    setitem(container, container.__setitem__, u'c', [])

    assert len(events) == 4
    event = events.popleft()
    assert IObjectAddedEvent.providedBy(event)
    event = events.popleft()
    assert IObjectModifiedEvent.providedBy(event)
    event = events.popleft()
    assert IObjectAddedEvent.providedBy(event)
    event = events.popleft()
    assert IObjectModifiedEvent.providedBy(event)
Example #2
0
    def test_fires_modified_event_on_change_props_per_changed_property(self):
        fti = DexterityFTI(u"testtype")
        fti.title = "Old title"
        fti.allow_discussion = False
        fti.global_allow = True

        notify_mock = self.mocker.replace('zope.event.notify')
        self.expect(
            notify_mock(
                mocker.MATCH(
                    lambda x: IObjectModifiedEvent.providedBy(x)
                    and len(x.descriptions) == 1
                    and x.descriptions[0].attribute == 'title'
                    and x.descriptions[0].oldValue == "Old title"
                )
            )
        )

        self.expect(
            notify_mock(
                mocker.MATCH(
                    lambda x: IObjectModifiedEvent.providedBy(x)
                    and len(x.descriptions) == 1
                    and x.descriptions[0].attribute == 'global_allow'
                    and x.descriptions[0].oldValue is True
                )
            )
        )
        self.replay()

        fti.manage_changeProperties(
            title="New title",
            allow_discussion=False,
            global_allow=False
        )
Example #3
0
    def test_fires_modified_event_on_change_props_per_changed_property(self):
        fti = DexterityFTI('testtype')
        fti.title = 'Old title'
        fti.allow_discussion = False
        fti.global_allow = True

        notify_mock = self.mocker.replace('zope.event.notify')
        self.expect(
            notify_mock(
                mocker.MATCH(
                    lambda x: IObjectModifiedEvent.providedBy(x) and len(
                        x.descriptions) == 1 and x.descriptions[0].attribute ==
                    'title' and x.descriptions[0].oldValue == 'Old title')))

        self.expect(
            notify_mock(
                mocker.MATCH(
                    lambda x: IObjectModifiedEvent.providedBy(x) and len(
                        x.descriptions) == 1 and x.descriptions[0].attribute ==
                    'global_allow' and x.descriptions[0].oldValue is True)))
        self.replay()

        fti.manage_changeProperties(title='New title',
                                    allow_discussion=False,
                                    global_allow=False)
    def extract_what(self):
        #Archetypes
        if IObjectInitializedEvent.providedBy(self.event):
            return 'created', self.get_object_modified_info()
        elif IObjectEditedEvent.providedBy(self.event):
            return 'modified', self.get_object_modified_info()
#        #TODO: plone.app.iterate
#        elif ICheckinEvent.providedBy(self.event):
#            return 'checkedin'
#        elif ICheckoutEvent.providedBy(self.event):
#            return 'checkedout'
#        elif IWorkingCopyDeletedEvent.providedBy(self.event):
#            return 'workingcopydeleted'
        # DCWorkflow
        elif IAfterTransitionEvent.providedBy(self.event):
            return 'statechanged', self.get_transition_info()
        # CMFCore (useless)
#        elif IActionSucceededEvent.providedBy(self.event):
#            return None
#            return 'statechanged', self.get_action_succeed_info()
        # zope
#        elif IObjectAddedEvent.providedBy(self.event):
#            return 'added', self.get_object_moved_info()
        elif IObjectCopiedEvent.providedBy(self.event):
            return 'copied', self.get_object_copied_info()
        elif IObjectMovedEvent.providedBy(self.event):
            return 'moved', self.get_object_moved_info()
        elif IObjectRemovedEvent.providedBy(self.event):
            return 'removed', self.get_object_moved_info()
        elif IObjectModifiedEvent.providedBy(self.event):
            return 'modified', self.get_object_modified_info()
        return None, {}
Example #5
0
def set_sitting_parent_ids(ob, event):
    """We add the group ID/sesssion id if adding a sitting in contexts
    not bound to groups in traversal hierarchy
    """
    scheduling_context = ISchedulingContext(ob.__parent__, None)
    if ob.group_id is None:
        if scheduling_context is not None:
            ob.group_id = removeSecurityProxy(scheduling_context).group_id
    if ob.session_id is None or IObjectModifiedEvent.providedBy(event):
        if scheduling_context is not None:
            group = scheduling_context.get_group()
            if interfaces.IParliament.providedBy(group):
                container = removeSecurityProxy(group).sessions
            else:
                return
        else:
            try:
                container = ob.group.sessions
            except AttributeError:
                return
        try:
            session_id = container._query.filter(
                sql.and_(
                    domain.Session.start_date < ob.start_date,
                    domain.Session.end_date > ob.end_date
                )
            ).one().session_id
            ob.session_id = session_id
        except (orm.exc.NoResultFound, orm.exc.MultipleResultsFound):
            log.error("Could not determine session for sitting %s", ob)
def test_move_event(events):
    """If the item had a parent or name (as in a move or rename),
    we generate a move event, rather than an add event.
    """
    container = {}

    # We create a first item
    item = Item()
    setitem(container, container.__setitem__, u'c1', item)

    # Add operation are "moved" events.
    assert len(events) == 2
    event = events.popleft()
    assert IObjectAddedEvent.providedBy(event)
    event = events.popleft()
    assert IObjectModifiedEvent.providedBy(event)
    assert isinstance(event, ContainerModifiedEvent)

    # We created an item already contained.
    item = Item()
    item.__parent__, item.__name__ = container, 'c2'
    setitem(container, container.__setitem__, u'c2', item)
    assert not len(events)

    # We now rewrite 'c2' under another name
    # Thus, we created a move event : +1 modification +1 move.
    setitem(container, container.__setitem__, u'c3', item)
    assert len(container) == 3
    event = events.popleft()
    assert IObjectMovedEvent.providedBy(event)
Example #7
0
    def test_order_events(self):
        # Prepare the setup::
        from zope.container.contained import ContainerModifiedEvent

        # Prepare some objects::

        from zope.container.ordered import OrderedContainer
        oc = OrderedContainer()
        oc['foo'] = 'bar'
        oc['baz'] = 'quux'
        oc['zork'] = 'grue'
        self.assertEqual(oc.keys(), ['foo', 'baz', 'zork'])

        # Now change the order::

        clearEvents()
        oc.updateOrder(['baz', 'foo', 'zork'])
        self.assertEqual(oc.keys(), ['baz', 'foo', 'zork'])

        # Check what events have been sent::

        events = getEvents()
        self.assertEqual(1, len(events))
        self.assertIsInstance(events[0], ContainerModifiedEvent)

        # This is in fact a specialized modification event::

        from zope.lifecycleevent.interfaces import IObjectModifiedEvent
        self.assertTrue(IObjectModifiedEvent.providedBy(events[0]))
Example #8
0
    def test_order_events(self):
        # Prepare the setup::
        from zope.container.contained import ContainerModifiedEvent

        # Prepare some objects::

        from zope.container.ordered import OrderedContainer
        oc = OrderedContainer()
        oc['foo'] = 'bar'
        oc['baz'] = 'quux'
        oc['zork'] = 'grue'
        self.assertEqual(oc.keys(),
                         ['foo', 'baz', 'zork'])

        # Now change the order::

        clearEvents()
        oc.updateOrder(['baz', 'foo', 'zork'])
        self.assertEqual(oc.keys(),
                         ['baz', 'foo', 'zork'])

        # Check what events have been sent::

        events = getEvents()
        self.assertEqual(1, len(events))
        self.assertIsInstance(events[0], ContainerModifiedEvent)

        # This is in fact a specialized modification event::

        from zope.lifecycleevent.interfaces import IObjectModifiedEvent
        self.assertTrue(IObjectModifiedEvent.providedBy(events[0]))
Example #9
0
def set_sitting_parent_ids(ob, event):
    """We add the group ID/sesssion id if adding a sitting in contexts
    not bound to groups in traversal hierarchy
    """
    scheduling_context = ISchedulingContext(ob.__parent__, None)
    if ob.group_id is None:
        if scheduling_context is not None:
            ob.group_id = removeSecurityProxy(scheduling_context).group_id
    if ob.session_id is None or IObjectModifiedEvent.providedBy(event):
        if scheduling_context is not None:
            group = scheduling_context.get_group()
            if interfaces.IChamber.providedBy(group):
                container = removeSecurityProxy(group).sessions
            else:
                return
        else:
            try:
                container = ob.group.sessions
            except AttributeError:
                return
        try:
            session_id = container._query.filter(
                sql.and_(
                    domain.Session.start_date < ob.start_date,
                    domain.Session.end_date > ob.end_date)).one().session_id
            ob.session_id = session_id
        except (orm.exc.NoResultFound, orm.exc.MultipleResultsFound):
            log.error("Could not determine session for sitting %s", ob)
Example #10
0
 def test_event_descriptions(self):
     self.request.form = {'description': 'test'}
     view = ContentView(self.todo1, self.request)
     view.can_edit = True
     view.update()
     self.assertTrue(IObjectModifiedEvent.providedBy(self.event))
     self.assertTrue(IAttributes.providedBy(self.event.descriptions[0]))
     self.assertEqual(self.event.descriptions[0].interface,
                      IBasic)
     self.assertEqual(self.event.descriptions[0].attributes,
                      ('description',))
Example #11
0
    def test_event_onsetProperty(self):
        request = TestRequest(
            set_properties = """<Dt:exampletextprop xmlns:Dt="DAVtest:">Example Text Prop</Dt:exampletextprop>""")
        resource = Resource("Text Prop", 10)

        propp = z3c.dav.proppatch.PROPPATCH(resource, request)
        propp.PROPPATCH()

        self.assertEqual(resource.text, "Example Text Prop") # property modified
        self.assertEqual(len(self.events), 1)
        self.assert_(IObjectModifiedEvent.providedBy(self.events[0]))
        self.assertEqual(self.events[0].object, resource)
    def __call__(self, content, event):
        """Called by the event system."""
        if IDexterityTranslatable.providedBy(content):
            self.canonical = ITranslationManager(content).query_canonical()

            if event.descriptions \
               and len(event.descriptions) > 1 \
               and event.descriptions[1] == self.canonical:
                return

            if IObjectModifiedEvent.providedBy(event):
                self.handle_modified(content)
def test_interface_providing(events):
    """If the object implements `ILocation`, but not `IContained`, set it's
    `__parent__` and `__name__` attributes *and* declare that it
    implements `IContained`.
    """
    container = {}

    item = Location()
    assert not IContained.providedBy(item)

    setitem(container, container.__setitem__, u'l', item)
    assert container[u'l'] is item
    assert item.__parent__ is container
    assert item.__name__ == u'l'
    assert IContained.providedBy(item)

    # We get added and modification events:
    assert len(events) == 2
    event = events.popleft()
    assert IObjectAddedEvent.providedBy(event)
    event = events.popleft()
    assert IObjectModifiedEvent.providedBy(event)

    # If the object doesn't even implement `ILocation`, put a
    # `ContainedProxy` around it:
    item = []
    setitem(container, container.__setitem__, u'i', item)
    assert container[u'i'] == []
    assert not container[u'i'] is item

    item = container[u'i']
    assert item.__parent__ is container
    assert item.__name__ == u'i'

    assert IContained.providedBy(item)
    event = events.popleft()
    assert IObjectAddedEvent.providedBy(event)
    event = events.popleft()
    assert IObjectModifiedEvent.providedBy(event)
Example #14
0
 def test_multiple_event_descriptions(self):
     self.request.form = {
         'title': 'Todo 2000',
         'description': 'test',
         'due': '2015-10-24',
     }
     view = ContentView(self.todo1, self.request)
     view.can_edit = True
     view.update()
     self.assertTrue(IObjectModifiedEvent.providedBy(self.event))
     self.assertTrue(IAttributes.providedBy(self.event.descriptions[0]))
     self.assertTrue(IAttributes.providedBy(self.event.descriptions[1]))
     descs = dict([(d.interface, d.attributes)
                   for d in self.event.descriptions])
     self.assertEqual(descs[IBasic], ('description', 'title'))
     self.assertEqual(descs[ITodo], ('due', ))
    def __call__(self, content, event):
        """Called by the event system."""
        sdm = content.session_data_manager
        session = sdm.getSessionData()
        if "tg" in session.keys():
            # In case it's a on the fly translation avoid
            return

        if IDexterityTranslatable.providedBy(content):
            self.canonical = ITranslationManager(content).query_canonical()

            if event.descriptions and len(event.descriptions) > 1 and event.descriptions[1] == self.canonical:
                return

            if IObjectModifiedEvent.providedBy(event):
                self.handle_modified(content)
Example #16
0
    def test_fires_modified_event_on_update_property_if_changed(self):
        fti = DexterityFTI(u"testtype")

        fti.title = u"Old title"
        fti.global_allow = False

        notify_mock = self.mocker.replace('zope.event.notify')
        self.expect(notify_mock(mocker.MATCH(lambda x: IObjectModifiedEvent.providedBy(x) \
                                                        and len(x.descriptions) == 1 \
                                                        and x.descriptions[0].attribute == 'title' \
                                                        and x.descriptions[0].oldValue == "Old title")))

        self.replay()

        fti._updateProperty('title', "New title")  # fires event caught above
        fti._updateProperty('allow_discussion', False)  # does not fire
Example #17
0
    def test_event_multipleProperty(self):
        request = TestRequest(
            set_properties = """
<Dt:exampletextprop xmlns:Dt="DAVtest:">Text Prop</Dt:exampletextprop>
<Dt:exampleintprop xmlns:Dt="DAVtest:">14</Dt:exampleintprop>
""")
        resource = Resource("Text Prop", 10)

        propp = z3c.dav.proppatch.PROPPATCH(resource, request)
        propp.PROPPATCH()

        self.assertEqual(resource.text, "Text Prop")
        self.assertEqual(resource.intprop, 14)
        self.assertEqual(len(self.events), 1)
        self.assertEqual(IObjectModifiedEvent.providedBy(self.events[0]), True)
        self.assertEqual(self.events[0].object, resource)
Example #18
0
 def test_fires_modified_event_on_update_property_if_changed(self):
     fti = DexterityFTI(u"testtype")
     
     fti.title = u"Old title"
     fti.global_allow = False
     
     notify_mock = self.mocker.replace('zope.event.notify')
     self.expect(notify_mock(mocker.MATCH(lambda x: IObjectModifiedEvent.providedBy(x) \
                                                     and len(x.descriptions) == 1 \
                                                     and x.descriptions[0].attribute == 'title' \
                                                     and x.descriptions[0].oldValue == "Old title")))
     
     self.replay()
     
     fti._updateProperty('title', "New title") # fires event caught above
     fti._updateProperty('allow_discussion', False) # does not fire
Example #19
0
    def test_fires_modified_event_on_update_property_if_changed(self):
        fti = DexterityFTI(u"testtype")

        fti.title = u"Old title"
        fti.global_allow = False

        from zope.event import notify
        notify_mock = self.patch_global(notify)

        fti._updateProperty('title', "New title")  # fires event caught above
        fti._updateProperty('allow_discussion', False)  # does not fire

        event = notify_mock.call_args[0][0]
        self.assertTrue(IObjectModifiedEvent.providedBy(event))
        self.assertEqual(len(event.descriptions), 1)
        self.assertEqual(event.descriptions[0].attribute, 'title')
        self.assertEqual(event.descriptions[0].oldValue, 'Old title')
Example #20
0
    def test_fires_modified_event_on_update_property_if_changed(self):
        fti = DexterityFTI(u"testtype")

        fti.title = u"Old title"
        fti.global_allow = False

        from zope.event import notify
        notify_mock = self.patch_global(notify)

        fti._updateProperty('title', "New title")  # fires event caught above
        fti._updateProperty('allow_discussion', False)  # does not fire

        event = notify_mock.call_args[0][0]
        self.assertTrue(IObjectModifiedEvent.providedBy(event))
        self.assertEqual(len(event.descriptions), 1)
        self.assertEqual(event.descriptions[0].attribute, 'title')
        self.assertEqual(event.descriptions[0].oldValue, 'Old title')
Example #21
0
    def test_event_on_remove_property(self):
        request = TestRequest(
            remove_properties = """<Dt:exampledeadprop xmlns:Dt="example:">Example Text Prop</Dt:exampledeadprop>""")

        testprop = "{example:}exampledeadprop"

        resource = Resource("Text Prop", 10)
        deadprops = DEADProperties(resource)
        deadprops.setProperty(testprop, "Example Text Prop")

        propp = z3c.dav.proppatch.PROPPATCH(resource, request)
        propp.PROPPATCH()

        self.assertEqual(deadprops.hasProperty(testprop), False)

        self.assertEqual(len(self.events), 1)
        self.assertEqual(IObjectModifiedEvent.providedBy(self.events[0]), True)
        self.assertEqual(self.events[0].object, resource)
Example #22
0
def test_order_events(events):
    oc = OrderedBTreeContainer()

    oc['foo'] = 'bar'
    oc['baz'] = 'quux'
    oc['zork'] = 'grue'

    assert oc.keys() == ['foo', 'baz', 'zork']

    events.clear()
    oc.updateOrder(['baz', 'foo', 'zork'])
    assert oc.keys() == ['baz', 'foo', 'zork']

    assert [event.__class__.__name__ for event in events] == [
        'ContainerModifiedEvent',
    ]

    assert IObjectModifiedEvent.providedBy(events.pop())
    def __call__(self, content, event):
        """Called by the event system."""
        request = getattr(event.object, 'REQUEST', getRequest())
        translation_info = getattr(request, 'translation_info', {})

        if 'tg' in translation_info.keys():
            # In case it's a on the fly translation avoid
            return

        if IDexterityTranslatable.providedBy(content):
            self.canonical = ITranslationManager(content).query_canonical()

            if event.descriptions \
               and len(event.descriptions) > 1 \
               and event.descriptions[1] == self.canonical:
                return

            if IObjectModifiedEvent.providedBy(event):
                self.handle_modified(content)
    def __call__(self, content, event):
        """Called by the event system."""
        request = getattr(event.object, 'REQUEST', getRequest())
        translation_info = getattr(request, 'translation_info', {})

        if 'tg' in translation_info.keys():
            # In case it's a on the fly translation avoid
            return

        if IDexterityTranslatable.providedBy(content):
            self.canonical = ITranslationManager(content).query_canonical()

            if event.descriptions \
               and len(event.descriptions) > 1 \
               and event.descriptions[1] == self.canonical:
                return

            if IObjectModifiedEvent.providedBy(event):
                self.handle_modified(content)
    def __call__(self, content, event):
        """Called by the event system."""
        if aq_parent(content) is None:
            # The event is thrown on a non acquired object
            # so we can't get the session_data_manager
            sdm = getSite().session_data_manager
        else:
            sdm = getToolByName(content, 'session_data_manager')

        session = sdm.getSessionData()
        if 'tg' in session.keys():
            # In case it's a on the fly translation avoid 
            return

        if IDexterityTranslatable.providedBy(content):
            self.canonical = ITranslationManager(content).query_canonical()

            if event.descriptions \
               and len(event.descriptions) > 1 \
               and event.descriptions[1] == self.canonical:
                return

            if IObjectModifiedEvent.providedBy(event):
                self.handle_modified(content)
Example #26
0
    def getLogEntry(self):
        ''' Get's a log entry for your action
        '''
        event = self.event
        obj = event.object
        data = {'info': ''}

        # order of those checks is important since some interfaces
        # base off the others
        if IPloneFormGenField.providedBy(obj):
            # if ploneformgen field, use parent object for modified data
            data['field'] = obj.getId()
            obj = aq_parent(obj)

        # the order of those interface checks matters since some interfaces
        # inherit from others
        if IObjectRemovedEvent.providedBy(event):
            # need to keep track of removed events so it doesn't get called
            # more than once for each object
            action = 'removed'
        elif (
            IObjectInitializedEvent.providedBy(event) or
            IObjectCreatedEvent.providedBy(event) or
            IObjectAddedEvent.providedBy(event)
        ):
            action = 'added'
        elif IObjectMovedEvent.providedBy(event):
            # moves can also be renames. Check the parent object
            if event.oldParent == event.newParent:
                if 'Rename' not in self.rule.rule.title:
                    # cut out here, double action for this event
                    return {}
                data['info'] = 'previous id: %s' % event.oldName
                action = 'rename'
            else:
                if 'Moved' not in self.rule.rule.title:
                    # step out immediately since this could be a double action
                    return {}
                data['info'] = 'previous location: %s/%s' % (
                    '/'.join(event.oldParent.getPhysicalPath()),
                    event.oldName,
                )
                action = 'moved'
        elif IObjectModifiedEvent.providedBy(event):
            action = 'modified'
        elif IActionSucceededEvent.providedBy(event):
            data['info'] = 'workflow transition: %s; comments: %s' % (
                event.action,
                self.get_history_comment(),
            )
            action = 'workflow'
        elif IObjectClonedEvent.providedBy(event):
            action = 'copied'
        elif ICheckinEvent.providedBy(event):
            data['info'] = event.message
            action = 'checked in'
            self.request.environ['disable.auditlog'] = True
            data['working_copy'] = '/'.join(obj.getPhysicalPath())
            obj = event.baseline
        elif IBeforeCheckoutEvent.providedBy(event):
            action = 'checked out'
            self.request.environ['disable.auditlog'] = True
        elif ICancelCheckoutEvent.providedBy(event):
            action = 'cancel check out'
            self.request.environ['disable.auditlog'] = True
            data['working_copy'] = '/'.join(obj.getPhysicalPath())
            obj = event.baseline
        else:
            logger.warn('no action matched')
            return {}

        if IWorkingCopy.providedBy(obj):
            # if working copy, iterate, check if Track Working Copies is
            # enabled
            if not self.trackWorkingCopies:
                # if not enabled, we only care about checked messages
                if 'check' not in action:
                    return {}
            # if enabled in control panel, use original object and move
            # working copy path to working_copy
            data['working_copy'] = '/'.join(obj.getPhysicalPath())
            relationships = obj.getReferences(
                WorkingCopyRelation.relationship)
            # check relationships, if none, something is wrong, not logging
            # action
            if len(relationships) <= 0:
                return {}
            obj = relationships[0]

        data.update(self._getObjectInfo(obj))
        data['action'] = action
        return data
Example #27
0
 def __call__(self, content, event):
     """Called by the event system."""
     if IArchetypesTranslatable.providedBy(content):
         if IObjectModifiedEvent.providedBy(event):
             self.handle_modified(content)
Example #28
0
 def test_event_thrown_on_field_change(self):
     self.request.form = {'description': 'test'}
     view = ContentView(self.todo1, self.request)
     view.can_edit = True
     view.update()
     self.assertTrue(IObjectModifiedEvent.providedBy(self.event))
Example #29
0
    def getLogEntry(self):
        ''' Get's a log entry for your action
        '''
        event = self.event
        obj = event.object
        data = {'info': ''}

        # order of those checks is important since some interfaces
        # base off the others
        if IPloneFormGenField.providedBy(obj):
            # if ploneformgen field, use parent object for modified data
            data['field'] = obj.getId()
            obj = aq_parent(obj)

        # the order of those interface checks matters since some interfaces
        # inherit from others
        if IObjectRemovedEvent.providedBy(event):
            # need to keep track of removed events so it doesn't get called
            # more than once for each object
            action = 'removed'
        elif (IObjectInitializedEvent.providedBy(event)
              or IObjectCreatedEvent.providedBy(event)
              or IObjectAddedEvent.providedBy(event)):
            action = 'added'
        elif IObjectMovedEvent.providedBy(event):
            # moves can also be renames. Check the parent object
            if event.oldParent == event.newParent:
                if 'Rename' not in self.rule.rule.title:
                    # cut out here, double action for this event
                    return {}
                data['info'] = 'previous id: %s' % event.oldName
                action = 'rename'
            else:
                if 'Moved' not in self.rule.rule.title:
                    # step out immediately since this could be a double action
                    return {}
                data['info'] = 'previous location: %s/%s' % (
                    '/'.join(event.oldParent.getPhysicalPath()),
                    event.oldName,
                )
                action = 'moved'
        elif IObjectModifiedEvent.providedBy(event):
            action = 'modified'
        elif IActionSucceededEvent.providedBy(event):
            data['info'] = 'workflow transition: %s; comments: %s' % (
                event.action,
                self.get_history_comment(),
            )
            action = 'workflow'
        elif IObjectClonedEvent.providedBy(event):
            action = 'copied'
        elif ICheckinEvent.providedBy(event):
            data['info'] = event.message
            action = 'checked in'
            self.request.environ['disable.auditlog'] = True
            data['working_copy'] = '/'.join(obj.getPhysicalPath())
            obj = event.baseline
        elif IBeforeCheckoutEvent.providedBy(event):
            action = 'checked out'
            self.request.environ['disable.auditlog'] = True
        elif ICancelCheckoutEvent.providedBy(event):
            action = 'cancel check out'
            self.request.environ['disable.auditlog'] = True
            data['working_copy'] = '/'.join(obj.getPhysicalPath())
            obj = event.baseline
        else:
            logger.warn('no action matched')
            return {}

        if IWorkingCopy.providedBy(obj):
            # if working copy, iterate, check if Track Working Copies is
            # enabled
            if not self.trackWorkingCopies:
                # if not enabled, we only care about checked messages
                if 'check' not in action:
                    return {}
            # if enabled in control panel, use original object and move
            # working copy path to working_copy
            data['working_copy'] = '/'.join(obj.getPhysicalPath())
            relationships = obj.getReferences(WorkingCopyRelation.relationship)
            # check relationships, if none, something is wrong, not logging
            # action
            if len(relationships) <= 0:
                return {}
            obj = relationships[0]

        data.update(self._getObjectInfo(obj))
        data['action'] = action
        return data
Example #30
0
    def __call__(self):
        req = getRequest()
        if req.environ.get('disable.auditlog', False):
            return True

        event = self.event
        obj = event.object
        # order of those checks is important since some interfaces
        # base off the others
        rule = inspect.stack()[1][0].f_locals.get('self', None)
        registry = getUtility(IRegistry)
        trackWorkingCopies = registry['collective.auditlog.interfaces.IAuditLogSettings.trackworkingcopies']  # noqa

        if not self.canExecute(rule, req):
            return True  # cut out early, we can't do this event

        data = {
            'info': ''
        }

        if IPloneFormGenField.providedBy(obj):
            # if ploneformgen field, use parent object for modified data
            data['field'] = obj.getId()
            obj = aq_parent(obj)

        # the order of those interface checks matters since some interfaces
        # inherit from others
        if IObjectRemovedEvent.providedBy(event):
            # need to keep track of removed events so it doesn't get called
            # more than once for each object
            action = 'removed'
        elif (IObjectInitializedEvent.providedBy(event) or
                IObjectCreatedEvent.providedBy(event) or
                IObjectAddedEvent.providedBy(event)):
            action = 'added'
        elif IObjectMovedEvent.providedBy(event):
            # moves can also be renames. Check the parent object
            if event.oldParent == event.newParent:
                if rule is None or 'Rename' in rule.rule.title:
                    info = {'previous_id': event.oldName}
                    data['info'] = json.dumps(info)
                    action = 'rename'
                else:
                    # cut out here, double action for this event
                    return True
            else:
                if rule is None or 'Moved' in rule.rule.title:
                    parent_path = '/'.join(event.oldParent.getPhysicalPath())
                    previous_location = parent_path + '/' + event.oldName
                    info = {'previous_location': previous_location}
                    data['info'] = json.dumps(info)
                    action = 'moved'
                else:
                    # step out immediately since this could be a double action
                    return True
        elif IObjectModifiedEvent.providedBy(event):
            action = 'modified'
        elif IActionSucceededEvent.providedBy(event):
            info = {'transition': event.action,
                    'comments': self.get_history_comment()}
            data['info'] = json.dumps(info)
            action = 'workflow'
        elif IObjectClonedEvent.providedBy(event):
            action = 'copied'
        elif ICheckinEvent.providedBy(event):
            info = {'message': event.message}
            data['info'] = json.dumps(info)
            action = 'checked in'
            req.environ['disable.auditlog'] = True
            data['working_copy'] = '/'.join(obj.getPhysicalPath())
            obj = event.baseline
        elif IBeforeCheckoutEvent.providedBy(event):
            action = 'checked out'
            req.environ['disable.auditlog'] = True
        elif ICancelCheckoutEvent.providedBy(event):
            action = 'cancel check out'
            req.environ['disable.auditlog'] = True
            data['working_copy'] = '/'.join(obj.getPhysicalPath())
            obj = event.baseline
        elif IUserLoggedInEvent.providedBy(event):
            action = 'logged in'
            info = {'user': event.object.getUserName()}
            data['info'] = json.dumps(info)
        elif IUserLoggedOutEvent.providedBy(event):
            action = 'logged out'
        else:
            logger.warn('no action matched')
            return True

        if IWorkingCopy.providedBy(obj):
            # if working copy, iterate, check if Track Working Copies is
            # enabled
            if trackWorkingCopies:
                # if enabled in control panel, use original object and move
                # working copy path to working_copy
                data['working_copy'] = '/'.join(obj.getPhysicalPath())
                relationships = obj.getReferences(
                    WorkingCopyRelation.relationship)
                # check relationships, if none, something is wrong, not logging
                # action
                if len(relationships) > 0:
                    obj = relationships[0]
                else:
                    return True
            else:
                # if not enabled, we only care about checked messages
                if 'check' not in action:
                    return True

        data.update(getObjectInfo(obj))
        data['action'] = action

        addLogEntry(obj, data)
        return True
Example #31
0
 def __call__(self, content, event):
     """Called by the event system."""
     if IArchetypesTranslatable.providedBy(content):
         if IObjectModifiedEvent.providedBy(event):
             self.handle_modified(content)