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, {}
示例#2
0
def transitionMovedContent(context, action):
    """Transition objects when they have been moved."""
    if IObjectAddedEvent.providedBy(action):
        return
    if IObjectRemovedEvent.providedBy(action):
        return

    wf = getattr(context, "portal_workflow", None)

    if getattr(action.oldParent, "getProjectRoomState", None) is not None:
        if getattr(action.newParent, "getProjectRoomState", None) is None:
            # If an object is moved out of a project room, take ownership.
            becomeOwner(context)
            restoreOwnerPermissions(context)

            # If it uses the intranett_workflow, also hide it.
            if "intranett_workflow" in wf.getChainFor(context):
                wf.doActionFor(context, "hide")
                return
        else:
            # If an object is renamed inside a project room or moved between
            # project rooms, reapply removeOwnerPermissions.
            if wf.getInfoFor(context, "review_state") == "published":
                action.action = "autopublish"  # Abuse existing event
                removeOwnerPermissions(context, action)
                return

    # In all other cases the automatic transitions do the right thing.
    try:
        wf.doActionFor(context, "auto")
    except WorkflowException:
        pass  # This workflow is not ProjectRoom aware.
示例#3
0
def cktemplate_moved(obj, event):
    """Managed the annotation for the Service template.

    Linked to creation, move, rename, delete and copy.
    """
    # TODO move it to ckeditortemplates
    if IObjectRemovedEvent.providedBy(event):
        return
    path = '/'.join(obj.getPhysicalPath()[:-1])
    # skip rename or inplace copy
    if event.oldParent == event.newParent or \
            (event.oldParent and path == '/'.join(event.oldParent.getPhysicalPath())):
        return
    if '/templates/oem' not in path:
        return  # oem has been renamed
    index = path.index('/templates/oem') + 14
    subpath = path[index + 1:]
    parts = subpath and subpath.split('/') or []
    value = u''
    if parts:
        pcat = obj.portal_catalog
        brains = pcat.unrestrictedSearchResults(path='{}/{}'.format(path[:index], parts[0]), sort_on='path', )
        titles = {br.getPath(): br.Title for br in brains}
        values = []
        current_path = path[:index]
        for part in parts:
            current_path += '/{}'.format(part)
            values.append(titles[current_path].decode('utf8'))
        value = u' - '.join(values)
    annot = IAnnotations(obj)
    annot['dmsmail.cke_tpl_tit'] = value
示例#4
0
def projectspace_moved(obj, event):
    """ When a projectspace is renamed, we correct collections """
    if IObjectRemovedEvent.providedBy(event):
        return
    portal = api.portal.get()
    path = '/'.join(obj.getPhysicalPath())
    # correct path criteria in collections
    for brain in portal.portal_catalog(path=path,
                                       portal_type='DashboardCollection'):
        ob = brain.getObject()
        query = ob.query
        for elt in query:
            if elt['i'] == 'path':
                elt['v'] = path
        ob.query = query
    # correct default collection
    for brain in portal.portal_catalog(
            path=path, object_provides=ICollectionCategories.__identifier__):
        ob = brain.getObject()
        criterion = getCollectionLinkCriterion(ob)
        criterias = ICriteria(ob)
        old_uid = criterias.get(criterion.__name__).get('default')
        old_path = uuidToPhysicalPath(old_uid)
        old_id = os.path.basename(old_path)
        if old_path.endswith('/{}/{}'.format(ob.id, old_id)):
            default_col = ob[old_id].UID()
            _updateDefaultCollectionFor(ob, default_col)
            logger.info('Replaced default col {} by {} on {}'.format(
                old_uid, default_col, ob.absolute_url()))
        else:
            raise ValueError("Cannot update default col on {}".format(
                ob.absolute_url()))
示例#5
0
def transitionMovedContent(context, action):
    """Transition objects when they have been moved."""
    if IObjectAddedEvent.providedBy(action):
        return
    if IObjectRemovedEvent.providedBy(action):
        return

    wf = getattr(context, 'portal_workflow', None)

    if getattr(action.oldParent, 'getProjectRoomState', None) is not None:
        if getattr(action.newParent, 'getProjectRoomState', None) is None:
            # If an object is moved out of a project room, take ownership.
            becomeOwner(context)
            restoreOwnerPermissions(context)

            # If it uses the intranett_workflow, also hide it.
            if 'intranett_workflow' in wf.getChainFor(context):
                wf.doActionFor(context, "hide")
                return
        else:
            # If an object is renamed inside a project room or moved between
            # project rooms, reapply removeOwnerPermissions.
            if wf.getInfoFor(context, 'review_state') == 'published':
                action.action = 'autopublish'  # Abuse existing event
                removeOwnerPermissions(context, action)
                return

    # In all other cases the automatic transitions do the right thing.
    try:
        wf.doActionFor(context, "auto")
    except WorkflowException:
        pass  # This workflow is not ProjectRoom aware.
示例#6
0
def moveIntIdSubscriber(ob, event):
    """A subscriber to ObjectMovedEvent

    Updates the stored path for the object in all the unique
    id utilities.
    """
    if IObjectRemovedEvent.providedBy(event) or \
           IObjectAddedEvent.providedBy(event):
        return
    utilities = tuple(getAllUtilitiesRegisteredFor(IIntIds))
    if utilities:
        key = None
        try:
            key = IKeyReference(ob, None)
        except NotYet:  # @@ temporary fix
            pass

        # Update objects that adapt to key reference
        if key is not None:
            for utility in utilities:
                try:
                    uid = utility.getId(ob)
                    utility.refs[uid] = key
                    utility.ids[key] = uid
                except KeyError:
                    pass
 def set_what(self, value):
     if IObjectAddedEvent.providedBy(value):
         self.data["what"] = "added"
         self.event = value
     elif IObjectRemovedEvent.providedBy(value):
         self.data["what"] = "removed"
         self.event = value
示例#8
0
def pstsubaction_moved(obj, event):
    """  """
    if IObjectAddedEvent.providedBy(
            event):  # Already managed in above subscriber
        return
    if event.newParent == event.oldParent and event.newName != event.oldName:  # it's not a move but a rename
        return
    # When deleting an action with a subaction, we pass here but the event context is the action !!!!
    if IObjectRemovedEvent.providedBy(event) and obj != event.object:
        return
    # Move of delete
    # we manage the flag on the old pstaction to indicate a subaction presence
    if not event.oldParent.listFolderContents(
        {'object_provides': IPSTSubAction.__identifier__}):
        set_to_annotation('imio.project.pst.has_subactions',
                          False,
                          obj=event.oldParent)
    # move into the moved subaction any existing task found in its new parent action
    if event.newParent:
        if getattr(obj, '_link_portal_type', '') == 'subaction_link':
            raise Invalid(
                "You cannot move a subaction link. Create a new one !")
        tasks = event.newParent.listFolderContents({'portal_type': 'task'})
        for task in tasks:
            api.content.move(task, obj)
        # we set a flag on the pstaction to indicate a subaction presence
        set_to_annotation('imio.project.pst.has_subactions',
                          True,
                          obj=event.newParent)
示例#9
0
def content_added(content, event):
    if (event.object != content or IObjectRemovedEvent.providedBy(event)
            or event.newParent == event.oldParent):
        return
    if IOrderableContainer.providedBy(event.newParent):
        manager = IOrderManager(event.newParent)
        manager.add(content)
示例#10
0
文件: intid.py 项目: CGTIC/Plone_SP
def moveIntIdSubscriber(ob, event):
    """A subscriber to ObjectMovedEvent

    Updates the stored path for the object in all the unique
    id utilities.
    """
    if IObjectRemovedEvent.providedBy(event) or \
           IObjectAddedEvent.providedBy(event):
        return
    utilities = tuple(getAllUtilitiesRegisteredFor(IIntIds))
    if utilities:
        key = None
        try:
            key = IKeyReference(ob, None)
        except NotYet: # @@ temporary fix
            pass

        # Update objects that adapt to key reference
        if key is not None:
            for utility in utilities:
                try:
                    uid = utility.getId(ob)
                    utility.refs[uid] = key
                    utility.ids[key] = uid
                except KeyError:
                    pass
示例#11
0
def mark_contact(contact, event):
    """ Set a marker interface on contact content. """
    if IObjectRemovedEvent.providedBy(event):
        # at site removal
        if event.object.portal_type == 'Plone Site':
            return
        invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.OMSenderVocabulary')
        return
    if '/plonegroup-organization' in contact.absolute_url_path():
        if not IPloneGroupContact.providedBy(contact):
            alsoProvides(contact, IPloneGroupContact)
        if INotPloneGroupContact.providedBy(contact):
            noLongerProvides(contact, INotPloneGroupContact)
        # don't check for IPersonnelContact because we can only add organization in this folder
    elif '/personnel-folder/' in contact.absolute_url_path():
        if not IPersonnelContact.providedBy(contact):
            alsoProvides(contact, IPersonnelContact)
        if INotPloneGroupContact.providedBy(contact):
            noLongerProvides(contact, INotPloneGroupContact)
        # don't check for IPloneGroupContact because we can't add organization in this folder
        invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.OMSenderVocabulary')
    else:
        if not INotPloneGroupContact.providedBy(contact):
            alsoProvides(contact, INotPloneGroupContact)
        if IPloneGroupContact.providedBy(contact):
            noLongerProvides(contact, IPloneGroupContact)
        if IPersonnelContact.providedBy(contact):
            noLongerProvides(contact, IPersonnelContact)
        invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.OMSenderVocabulary')

    contact.reindexObject(idxs='object_provides')
示例#12
0
def content_added(content, event):
    if (event.object != content or
        IObjectRemovedEvent.providedBy(event) or
        event.newParent == event.oldParent):
        return
    if IOrderableContainer.providedBy(event.newParent):
        manager = IOrderManager(event.newParent)
        manager.add(content)
def threadmoved(conv, event):
    """
    send email notification when a thread was moved
    """
    if IObjectRemovedEvent.providedBy(event) or IObjectAddedEvent.providedBy(event):
        return
    n = queryUtility(INotifier)
    n.thread_moved(conv)
示例#14
0
def index_moved_content(content, event):
    """We index all added content (due to a move).
    """
    if getattr(content, "__initialization__", False):
        return

    if not IObjectAddedEvent.providedBy(event) and not IObjectRemovedEvent.providedBy(event):
        ICataloging(content).index()
示例#15
0
def unrelateOnDeletion(event):
    """Remove all relationships when an object is deleted."""
    if not IObjectRemovedEvent.providedBy(event):
        return
    linkset = IRelationshipLinks(event.object, None)
    if linkset is not None:
        # event.object may be a ContainedProxy
        unrelateAll(getProxiedObject(event.object))
示例#16
0
def index_moved_content(content, event):
    """We index all added content (due to a move).
    """
    if getattr(content, '__initialization__', False):
        return

    if (not IObjectAddedEvent.providedBy(event)
            and not IObjectRemovedEvent.providedBy(event)):
        ICataloging(content).index()
示例#17
0
def forwardevent(obj, event):
    """ Trigger an ObjectMovedOrRenamedEvent only
    if it's not an ObjectAddedEvent or an ObjectRemovedEvent"""
    if IObjectAddedEvent.providedBy(event) \
        or IObjectRemovedEvent.providedBy(event) \
            or IObjectMovedOrRenamedEvent.providedBy(event):
        return
    notify(
        ObjectMovedOrRenamedEvent(event.object, event.oldParent, event.oldName,
                                  event.newParent, event.newName))
def related_change_on_moved(obj, event):
    """ Set local roles on related objects after moving """
    if IObjectAddedEvent.providedBy(event) or IObjectRemovedEvent.providedBy(event):  # not move
        return
    if event.oldParent and event.newParent and event.oldParent == event.newParent:  # rename
        return
    (fti_config, fti) = fti_configuration(obj)
    if 'static_config' not in fti_config:
        return
    related_role_addition(obj, get_state(obj), fti_config)
def threadmoved(conv, event):
    """
    Send email notification when a thread was moved
    """
    if IObjectRemovedEvent.providedBy(event) or IObjectAddedEvent.providedBy(event):
        return
    n = queryUtility(INotifier)
    n.thread_moved(conv)
    s = queryUtility(ISubscriptions)
    s.move_subscribers(event)
示例#20
0
def moved_event(event):
    # only execute moved event if it's not a added or removed event since
    # those are handled elsewhere and they base off of this event class
    if (IObjectAddedEvent.providedBy(event) or
            IObjectRemovedEvent.providedBy(event)):
        return

    obj = event.object
    if not (IContentish.providedBy(obj) or IComment.providedBy(obj)):
        return
    execute_event(event)
示例#21
0
def forwardevent(obj, event):
    """ Trigger an ObjectMovedOrRenamedEvent only
    if it's not an ObjectAddedEvent or an ObjectRemovedEvent"""
    if IObjectAddedEvent.providedBy(event) \
        or IObjectRemovedEvent.providedBy(event) \
        or IObjectMovedOrRenamedEvent.providedBy(event):
        return
    notify(ObjectMovedOrRenamedEvent(event.object,
                                event.oldParent,
                                event.oldName,
                                event.newParent,
                                event.newName))
示例#22
0
def unrelateCalendarOnDeletion(event):
    """When you delete an object, relationships of it's calendar should be removed

        >>> from schooltool.relationship.tests import setUp, tearDown
        >>> from schooltool.testing.setup import setUpCalendaring

        >>> setUp()
        >>> setUpCalendaring()

        >>> import zope.event
        >>> old_subscribers = zope.event.subscribers[:]
        >>> from schooltool.app.overlay import unrelateCalendarOnDeletion
        >>> zope.event.subscribers.append(unrelateCalendarOnDeletion)


    We will need some object that implements IHaveCalendar for that:

        >>> from zope.container.btree import BTreeContainer
        >>> container = BTreeContainer()
        >>> from schooltool.person.person import Person
        >>> container = BTreeContainer()
        >>> container['jonas'] = jonas = Person(username="******")
        >>> container['petras'] = petras =  Person(username="******")

    Let's add calendar of Petras to the list of overlaid calendars:

        >>> jonas.overlaid_calendars.add(ISchoolToolCalendar(petras))
        <...CalendarOverlayInfo object at ...>
        >>> list(jonas.overlaid_calendars)
        [<schooltool.app.overlay.CalendarOverlayInfo object at ...>]

    If we delete Petras - Jonas should have no calendars in his overlay list:

        >>> del container['petras']
        >>> list(jonas.overlaid_calendars)
        []

    Restore old subscribers:

        >>> zope.event.subscribers[:] = old_subscribers
        >>> tearDown()

    """
    if not IObjectRemovedEvent.providedBy(event):
        return
    # event.object may be a ContainedProxy
    obj = getProxiedObject(event.object)
    if not IHaveCalendar.providedBy(obj):
        return
    calendar = ISchoolToolCalendar(obj)
    linkset = IRelationshipLinks(calendar, None)
    if linkset is not None:
        unrelateAll(calendar)
示例#23
0
def unrelateCalendarOnDeletion(event):
    """When you delete an object, relationships of it's calendar should be removed

        >>> from schooltool.relationship.tests import setUp, tearDown
        >>> from schooltool.testing.setup import setUpCalendaring

        >>> setUp()
        >>> setUpCalendaring()

        >>> import zope.event
        >>> old_subscribers = zope.event.subscribers[:]
        >>> from schooltool.app.overlay import unrelateCalendarOnDeletion
        >>> zope.event.subscribers.append(unrelateCalendarOnDeletion)


    We will need some object that implements IHaveCalendar for that:

        >>> from zope.container.btree import BTreeContainer
        >>> container = BTreeContainer()
        >>> from schooltool.person.person import Person
        >>> container = BTreeContainer()
        >>> container['jonas'] = jonas = Person(username="******")
        >>> container['petras'] = petras =  Person(username="******")

    Let's add calendar of Petras to the list of overlaid calendars:

        >>> jonas.overlaid_calendars.add(ISchoolToolCalendar(petras))
        <...CalendarOverlayInfo object at ...>
        >>> list(jonas.overlaid_calendars)
        [<schooltool.app.overlay.CalendarOverlayInfo object at ...>]

    If we delete Petras - Jonas should have no calendars in his overlay list:

        >>> del container['petras']
        >>> list(jonas.overlaid_calendars)
        []

    Restore old subscribers:

        >>> zope.event.subscribers[:] = old_subscribers
        >>> tearDown()

    """
    if not IObjectRemovedEvent.providedBy(event):
        return
    # event.object may be a ContainedProxy
    obj = getProxiedObject(event.object)
    if not IHaveCalendar.providedBy(obj):
        return
    calendar = ISchoolToolCalendar(obj)
    linkset = IRelationshipLinks(calendar, None)
    if linkset is not None:
        unrelateAll(calendar)
示例#24
0
def _update_workspace_groupings(obj, event):
    """ If the relevant object is inside a workspace, the workspace grouping
        parameters (for the sidebar) need to be updated.
    """
    parent = parent_workspace(obj)
    if parent is None or not IGroupingStoragable.providedBy(parent):
        return

    storage = getAdapter(parent, IGroupingStorage)
    if IObjectRemovedEvent.providedBy(event) or IObjectWillBeRemovedEvent.providedBy(event):
        storage.remove_from_groupings(obj)
    else:
        storage.update_groupings(obj)
def related_change_on_moved(obj, event):
    """ Set local roles on related objects after moving """
    if IObjectAddedEvent.providedBy(event) or IObjectRemovedEvent.providedBy(event):  # not move
        return
    if event.oldParent and event.newParent and event.oldParent == event.newParent:  # rename
        return
    (fti_config, fti) = fti_configuration(obj)
    if not fti_config:
        return
    for (name, f) in get_localrole_fields(fti):
        if name not in fti_config:
            continue
        related_role_addition(obj, get_state(obj), fti_config[name], name)
示例#26
0
def createdEvent(obj, event):
    """ It can be a
        IObjectRemovedEvent - don't do anything
        IObjectMovedEvent
        IObjectAddedEvent
        IObjectCopiedEvent
    """
    if IObjectRemovedEvent.providedBy(event):
        return

    portal = getSite()
    language_tool = getToolByName(portal, 'portal_languages')

    # On ObjectCopiedEvent and ObjectMovedEvent aq_parent(event.object) is
    # always equal to event.newParent.
    parent = aq_parent(event.object)

    if (language_tool.startNeutral() and ITranslatable.providedBy(obj)):

        # We leave this untouched by now.
        # We don't set languages
        set_recursive_language(obj, LANGUAGE_INDEPENDENT)

    elif (IPloneSiteRoot.providedBy(parent) and
          ITranslatable.providedBy(obj) and
          ILanguage(obj).get_language() == LANGUAGE_INDEPENDENT):

        # It's a root folder and we set the default language
        # ( not independent allowed )
        language = language_tool.getPreferredLanguage()
        set_recursive_language(obj, language)

    elif ITranslatable.providedBy(parent):
        # Normal use case
        # We set the tg, linking
        language = ILanguage(parent).get_language()
        set_recursive_language(obj, language)
        sdm = obj.session_data_manager
        session = sdm.getSessionData()

        if 'tg' in session.keys() and \
           not portal.portal_factory.isTemporary(obj):
            IMutableTG(obj).set(session['tg'])
            old_obj = ITranslationManager(obj).get_translation(session['old_lang'])

            # Copy ILanguage Independent field on on-the-fly translation
            cloner = ITranslationCloner(old_obj)
            cloner(obj)

            reindex_object(obj)
            del session['tg']
示例#27
0
def createdEvent(obj, event):
    """ It can be a
        IObjectRemovedEvent - don't do anything
        IObjectMovedEvent
        IObjectAddedEvent
        IObjectCopiedEvent
    """
    if IObjectRemovedEvent.providedBy(event):
        return

    portal = getSite()
    language_tool = getToolByName(portal, 'portal_languages')

    # On ObjectCopiedEvent and ObjectMovedEvent aq_parent(event.object) is
    # always equal to event.newParent.
    parent = aq_parent(event.object)

    if (language_tool.startNeutral() and ITranslatable.providedBy(obj)):

        # We leave this untouched by now.
        # We don't set languages
        set_recursive_language(obj, LANGUAGE_INDEPENDENT)

    elif (IPloneSiteRoot.providedBy(parent) and ITranslatable.providedBy(obj)
          and ILanguage(obj).get_language() == LANGUAGE_INDEPENDENT):

        # It's a root folder and we set the default language
        # ( not independent allowed )
        language = language_tool.getPreferredLanguage()
        set_recursive_language(obj, language)

    elif ITranslatable.providedBy(parent):
        # Normal use case
        # We set the tg, linking
        language = ILanguage(parent).get_language()
        set_recursive_language(obj, language)
        sdm = obj.session_data_manager
        session = sdm.getSessionData()

        if 'tg' in session.keys() and \
           not portal.portal_factory.isTemporary(obj):
            IMutableTG(obj).set(session['tg'])
            old_obj = ITranslationManager(obj).get_translation(
                session['old_lang'])

            # Copy ILanguage Independent field on on-the-fly translation
            cloner = ITranslationCloner(old_obj)
            cloner(obj)

            reindex_object(obj)
            del session['tg']
def createdEvent(obj, event):
    """ Subscriber to set language on the child folder

    It can be a
    - IObjectRemovedEvent - don't do anything
    - IObjectMovedEvent
    - IObjectAddedEvent
    - IObjectCopiedEvent
    """
    if IObjectRemovedEvent.providedBy(event):
        return

    request = getattr(event.object, 'REQUEST', getRequest())
    if not IPloneAppMultilingualInstalled.providedBy(request):
        return

    # On ObjectCopiedEvent and ObjectMovedEvent aq_parent(event.object) is
    # always equal to event.newParent.
    parent = aq_parent(event.object)

    # special parent handling
    if not ITranslatable.providedBy(parent):
        set_recursive_language(obj, LANGUAGE_INDEPENDENT)
        return

    # Normal use case
    # We set the tg, linking
    language = ILanguage(parent).get_language()
    set_recursive_language(obj, language)

    request = getattr(event.object, 'REQUEST', getRequest())
    try:
        ti = request.translation_info
    except AttributeError:
        return

    # AT check
    portal = getSite()
    portal_factory = getToolByName(portal, 'portal_factory', None)
    if (
        not IDexterityContent.providedBy(obj)
        and portal_factory is not None
        and not portal_factory.isTemporary(obj)
    ):
        return

    IMutableTG(obj).set(ti['tg'])
    modified(obj)
    tm = ITranslationManager(obj)
    old_obj = tm.get_translation(ti['source_language'])
    ILanguageIndependentFieldsManager(old_obj).copy_fields(obj)
示例#29
0
def handle_workspace_move_or_rename(context, event):
    if IObjectRemovedEvent.providedBy(event):
        return  # not a move with new/old, but a removal -- handled elsewhere
    if IObjectAddedEvent.providedBy(event):
        return  # not an add, but a move of existing
    site = getSite()
    pasgroups = ISiteMembers(site).groups
    roster = WorkspaceRoster(context)
    for workgroup in roster.groups.values():
        groupname, title = workgroup.pas_group()
        if groupname not in pasgroups:
            pasgroups.add(groupname, title=title)
        else:
            pasgroups.get(groupname).title = _u(title)
示例#30
0
def handle_workspace_move_or_rename(context, event):
    if IObjectRemovedEvent.providedBy(event):
        return  # not a move with new/old, but a removal -- handled elsewhere
    if IObjectAddedEvent.providedBy(event):
        return  # not an add, but a move of existing
    site = getSite()
    pasgroups = ISiteMembers(site).groups
    roster = WorkspaceRoster(context)
    for workgroup in roster.groups.values():
        groupname, title = workgroup.pas_group()
        if groupname not in pasgroups:
            pasgroups.add(groupname, title=title)
        else:
            pasgroups.get(groupname).title = _u(title)
示例#31
0
def related_change_on_moved(obj, event):
    """ Set local roles on related objects after moving """
    if IObjectAddedEvent.providedBy(event) or IObjectRemovedEvent.providedBy(
            event):  # not move
        return
    if event.oldParent and event.newParent and event.oldParent == event.newParent:  # rename
        return
    (fti_config, fti) = fti_configuration(obj)
    if not fti_config:
        return
    for (name, f) in get_localrole_fields(fti):
        if name not in fti_config:
            continue
        related_role_addition(obj, get_state(obj), fti_config[name], name)
示例#32
0
def _update_workspace_groupings(obj, event):
    """ If the relevant object is inside a workspace, the workspace grouping
        parameters (for the sidebar) need to be updated.
    """
    parent = parent_workspace(obj)
    if parent is None or not IGroupingStoragable.providedBy(parent):
        return

    storage = getAdapter(parent, IGroupingStorage)
    if IObjectRemovedEvent.providedBy(event) or \
            IObjectWillBeRemovedEvent.providedBy(event):
        storage.remove_from_groupings(obj)
    else:
        storage.update_groupings(obj)
def createdEvent(obj, event):
    """ Subscriber to set language on the child folder

    It can be a
    - IObjectRemovedEvent - don't do anything
    - IObjectMovedEvent
    - IObjectAddedEvent
    - IObjectCopiedEvent
    """
    if IObjectRemovedEvent.providedBy(event):
        return

    request = getattr(event.object, 'REQUEST', getRequest())
    if not IPloneAppMultilingualInstalled.providedBy(request):
        return

    # On ObjectCopiedEvent and ObjectMovedEvent aq_parent(event.object) is
    # always equal to event.newParent.
    parent = aq_parent(event.object)

    # special parent handling
    if not ITranslatable.providedBy(parent):
        set_recursive_language(obj, LANGUAGE_INDEPENDENT)
        return

    # Normal use case
    # We set the tg, linking
    language = ILanguage(parent).get_language()
    set_recursive_language(obj, language)

    request = getattr(event.object, 'REQUEST', getRequest())
    try:
        ti = request.translation_info
    except AttributeError:
        return

    # AT check
    portal = getSite()
    portal_factory = getToolByName(portal, 'portal_factory', None)
    if (not IDexterityContent.providedBy(obj) and portal_factory is not None
            and not portal_factory.isTemporary(obj)):
        return

    IMutableTG(obj).set(ti['tg'])
    modified(obj)
    tm = ITranslationManager(obj)
    old_obj = tm.get_translation(ti['source_language'])
    ILanguageIndependentFieldsManager(old_obj).copy_fields(obj)
示例#34
0
def mark_contact(contact, event):
    """ Set a marker interface on contact content. """
    if IObjectRemovedEvent.providedBy(event):
        return
    if '/personnel-folder/' in contact.absolute_url_path() or '/plonegroup-organization' in contact.absolute_url_path():
        if not IPloneGroupContact.providedBy(contact):
            alsoProvides(contact, IPloneGroupContact)
        if INotPloneGroupContact.providedBy(contact):
            noLongerProvides(contact, INotPloneGroupContact)
    else:
        if not INotPloneGroupContact.providedBy(contact):
            alsoProvides(contact, INotPloneGroupContact)
        if IPloneGroupContact.providedBy(contact):
            noLongerProvides(contact, IPloneGroupContact)

    contact.reindexObject(idxs='object_provides')
示例#35
0
def organization_modified(obj, event):
    """
        Update the sortable_title index
    """
    # at site removal
    if IObjectRemovedEvent.providedBy(event):
        return
    # zope.container.contained.ContainerModifiedEvent: descriptions is () when it's called after children creation
    if hasattr(event, 'descriptions') and not event.descriptions:
        return
    # zope.lifecycleevent.ObjectAddedEvent: oldParent is None when creation
    if hasattr(event, 'oldParent') and not event.oldParent:
        return
    pc = api.portal.get_tool('portal_catalog')
    for brain in pc(portal_type='organization', path='/'.join(obj.getPhysicalPath()), sort_on='path')[1:]:
        brain.getObject().reindexObject(idxs=['sortable_title'])
示例#36
0
def purgeOnMovedOrRemoved(object, event):
    request = getRequest()
    confirmed_delete = ('delete_confirmation' in request.URL
                        and request.REQUEST_METHOD == 'POST'
                        and 'form.submitted' in request.form)
    if IObjectRemovedEvent.providedBy(event) and not confirmed_delete:
        # ignore extra delete events
        return
    # Don't purge when added
    if IObjectAddedEvent.providedBy(event):
        return
    if isPurged(object) and 'portal_factory' not in request.URL:
        notify(Purge(object))
    parent = object.getParentNode()
    if parent:
        notify(Purge(parent))
def mark_organization(contact, event):
    """ Set a marker interface on contact content. """
    if IObjectRemovedEvent.providedBy(event):
        return
    if '/%s' % PLONEGROUP_ORG in contact.absolute_url_path():
        if not IPloneGroupContact.providedBy(contact):
            alsoProvides(contact, IPloneGroupContact)
        if INotPloneGroupContact.providedBy(contact):
            noLongerProvides(contact, INotPloneGroupContact)
    else:
        if not INotPloneGroupContact.providedBy(contact):
            alsoProvides(contact, INotPloneGroupContact)
        if IPloneGroupContact.providedBy(contact):
            noLongerProvides(contact, IPloneGroupContact)

    contact.reindexObject(idxs='object_provides')
def mark_organization(contact, event):
    """ Set a marker interface on contact content. """
    if IObjectRemovedEvent.providedBy(event):
        return
    if '/%s' % PLONEGROUP_ORG in contact.absolute_url_path():
        if not IPloneGroupContact.providedBy(contact):
            alsoProvides(contact, IPloneGroupContact)
        if INotPloneGroupContact.providedBy(contact):
            noLongerProvides(contact, INotPloneGroupContact)
    else:
        if not INotPloneGroupContact.providedBy(contact):
            alsoProvides(contact, INotPloneGroupContact)
        if IPloneGroupContact.providedBy(contact):
            noLongerProvides(contact, IPloneGroupContact)

    contact.reindexObject(idxs='object_provides')
示例#39
0
def organization_modified(obj, event):
    """
        Update the sortable_title index
    """
    # at site removal
    if IObjectRemovedEvent.providedBy(event):
        return
    # zope.container.contained.ContainerModifiedEvent: descriptions is () when it's called after children creation
    if hasattr(event, 'descriptions') and not event.descriptions:
        return
    # zope.lifecycleevent.ObjectAddedEvent: oldParent is None when creation
    if hasattr(event, 'oldParent') and not event.oldParent:
        return
    pc = api.portal.get_tool('portal_catalog')
    for brain in pc.unrestrictedSearchResults(portal_type='organization', path='/'.join(obj.getPhysicalPath()),
                                              sort_on='path')[1:]:
        brain._unrestrictedGetObject().reindexObject(idxs=['sortable_title'])
def createdEvent(obj, event):
    """ It can be a
        IObjectRemovedEvent - don't do anything
        IObjectMovedEvent
        IObjectAddedEvent
        IObjectCopiedEvent
    """
    if IObjectRemovedEvent.providedBy(event):
        return

    # On ObjectCopiedEvent and ObjectMovedEvent aq_parent(event.object) is
    # always equal to event.newParent.
    parent = aq_parent(event.object)

    if ITranslatable.providedBy(parent):
        # Normal use case
        # We set the tg, linking
        language = ILanguage(parent).get_language()
        set_recursive_language(obj, language)
        sdm = obj.session_data_manager
        session = sdm.getSessionData()
        portal = getSite()
        portal_factory = getToolByName(portal, 'portal_factory', None)

        request = getattr(event.object, 'REQUEST', getRequest())
        has_pam_old_lang_in_form = (
            request and
            'form.widgets.pam_old_lang' not in request.form
        )
        if (not has_pam_old_lang_in_form
                and 'tg' in session.keys()
                and 'old_lang' in session.keys()
                and (portal_factory is None
                     or not portal_factory.isTemporary(obj))):
            IMutableTG(obj).set(session['tg'])
            modified(obj)
            del session['tg']
            old_obj = ITranslationManager(obj)\
                .get_translation(session['old_lang'])
            ILanguageIndependentFieldsManager(old_obj).copy_fields(obj)
            del session['old_lang']
    else:
        set_recursive_language(obj, LANGUAGE_INDEPENDENT)
示例#41
0
    def testDeletion(self):
        from zope.event import subscribers
        tree = BTreeContainer()
        item = Contained()
        tree['42'] = item
        events = []
        def subscriber(event):
            events.append(event)
            # events should happen after the deletion, not before)
            self.assertEqual(len(tree), 0)
            self.assertEqual(list(tree), [])
        subscribers.append(subscriber)

        del tree['42']
        self.assertEqual(item.__name__, None)
        self.assertEqual(item.__parent__, None)

        self.assertEqual(len(events), 2)
        self.assertTrue(IObjectRemovedEvent.providedBy(events[0]))
        self.assertTrue(IContainerModifiedEvent.providedBy(events[1]))
示例#42
0
    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)
示例#43
0
def object_moved(context, event):
    # Since IObjectAddedEvent subclasses IObjectMovedEvent this event
    # handler is also called for IObjectAddedEvent but we should not
    # do anything in this case.
    if IObjectAddedEvent.providedBy(event):
        return

    # Ignore object removals
    if IObjectRemovedEvent.providedBy(event):
        return

    # Skip automatically renamed objects during copy & paste process.
    if ICopyPasteRequestLayer.providedBy(getRequest()):
        return

    title = _(u'label_object_moved',
              default=u'Object moved: ${title}',
              mapping={'title': context.title_or_id()}
              )

    journal_entry_factory(
        context.aq_inner.aq_parent, OBJECT_MOVED_EVENT, title)
    return
示例#44
0
def createdEvent(obj, event):
    """ It can be a
        IObjectRemovedEvent - don't do anything
        IObjectMovedEvent
        IObjectAddedEvent
        IObjectCopiedEvent
    """
    if IObjectRemovedEvent.providedBy(event):
        return

    portal = getSite()

    # On ObjectCopiedEvent and ObjectMovedEvent aq_parent(event.object) is
    # always equal to event.newParent.
    parent = aq_parent(event.object)

    if ITranslatable.providedBy(parent):
        # Normal use case
        # We set the tg, linking
        language = ILanguage(parent).get_language()
        set_recursive_language(obj, language)
        sdm = obj.session_data_manager
        session = sdm.getSessionData()
        portal = getSite()

        if 'tg' in session.keys() and \
           'old_lang' in session.keys() and \
           not portal.portal_factory.isTemporary(obj):
            IMutableTG(obj).set(session['tg'])
            modified(obj)
            del session['tg']
            old_obj = ITranslationManager(obj)\
                .get_translation(session['old_lang'])
            ILanguageIndependentFieldsManager(old_obj).copy_fields(obj)
            del session['old_lang']
    else:
        set_recursive_language(obj, LANGUAGE_INDEPENDENT)
示例#45
0
    def get_what_info(self, event):
        #Archetypes
        if IObjectEditedEvent.providedBy(event):
            return self.get_object_modified_info(event)
        elif IObjectInitializedEvent.providedBy(event):
            return self.get_object_modified_info(event)
        #plone
        elif IConfigurationChangedEvent.providedBy(event):
            return self.get_configuration_changed_info(event)
#        #plone.app.form (formlib)
#        elif IEditSavedEvent.providedBy(event):
#            return 'editsaved'
#        #plone.app.iterate
#        elif ICheckinEvent.providedBy(event):
#            return 'checkedin'
#        elif ICheckoutEvent.providedBy(event):
#            return 'checkedout'
#        elif IWorkingCopyDeletedEvent.providedBy(event):
#            return 'workingcopydeleted'
#        #plone.app.registry
        elif IRecordModifiedEvent.providedBy(event):
            return self.get_record_modified_info(event)
        # DCWorkflow
        elif ITransitionEvent.providedBy(event):
            return self.get_transition_info(event)
        # CMFCore
        elif IActionSucceededEvent.providedBy(event):
            return self.get_action_succeed_info(event)
        # zope
        elif IObjectCopiedEvent.providedBy(event):
            return self.get_object_copied_info(event)
        elif IObjectMovedEvent.providedBy(event):
            return self.get_object_moved_info(event)
        elif IObjectAddedEvent.providedBy(event):
            return self.get_object_moved_info(event)
        elif IObjectRemovedEvent.providedBy(event):
            return self.get_object_moved_info(event)
示例#46
0
def reindex(obj, event):
    """Re-index mirrored folder content for all mirrors and master

    Mirror folder content objects are indexed once for each mirror and the
    master with different, mirror-specific UUID for each. When ever a mirrored
    folder content object is modified in some mirror or master, it must be
    re-indexed for all the other mirrors and master as well.

    """
    if IObjectRemovedEvent.providedBy(event):
        return

    info = mirror_info(obj)
    if info == NOT_MIRRORED:
        return

    # We try to access newly indexed objects via the parent in order to avoid
    # computing partial paths and starting traversal from master or mirrors.
    # However, the parent being a mirror is an exception in that mirrors' uuid
    # doesn't follow the pattern for uuids of mirrored objects.
    parent = aq_parent(obj)
    master_id = IUUID(info.master)
    if IMirror.providedBy(parent) or IUUID(parent) == master_id:
        parent_ids = [master_id] + info.mirror_ids
    else:
        parent_master_id = bare_uuid(parent)
        if not parent_master_id:
            return
        parent_ids = [parent_master_id] + [
            f'{parent_master_id}@{mirror_id}' for mirror_id in info.mirror_ids
        ]

    cat = api.portal.get_tool('portal_catalog')
    for parent_id in parent_ids:
        brains = cat.unrestrictedSearchResults(UID=parent_id)
        for brain in brains:
            brain.getObject()[obj.id].indexObject()
def reindex_language_independent(ob, event):
    """Re-index language independent object for other languages

    Language independent objects are indexed once for each language with
    different, language code post-fixed, UUID for each. When ever a language
    independent object is modified in some language, it must be re-indexed
    for all the other languages as well.

    """
    if not is_language_independent(ob):
        return

    if IObjectRemovedEvent.providedBy(event):
        return

    pc = getToolByName(ob, 'portal_catalog')
    parent = aq_parent(ob)

    # Re-index objects just below the language independent folder
    if ILanguageIndependentFolder.providedBy(parent):
        brains = pc.unrestrictedSearchResults(portal_type='LIF')
        for brain in brains:
            lif = brain._unrestrictedGetObject()
            if lif != parent:
                lif[ob.id].indexObject()
    # Re-index objects deeper inside language independent folder
    else:
        language_tool = getToolByName(ob, 'portal_languages')
        language_codes = language_tool.supported_langs
        parent_uuid = IUUID(parent).split('-')[0] + '-'
        for code in language_codes:
            results = pc.unrestrictedSearchResults(UID=parent_uuid + code)
            # When we have results, parent has been indexed and we can reindex:
            for brain in results:
                tmp = ob.unrestrictedTraverse(brain.getPath() + '/' + ob.id)
                tmp.reindexObject()
示例#48
0
    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)
示例#49
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
示例#50
0
def log_moved(context, event):
    is_remove = IObjectRemovedEvent.providedBy(event)
    is_add = IObjectAddedEvent.providedBy(event)
    if is_add or is_remove:
        return
    ModificationLogger().moved(context)
示例#51
0
    def __call__(self):
        event = self.event
        service_to_ping = self.element.service_to_ping
        obj = self.event.object
        container = obj.getParentNode()
        noasync_msg = 'No instance for async operations was defined.'

        def pingCRSDS(service_to_ping, obj_url, create):
            """ Ping the CR/SDS service
            """
            if async_service is None:
                logger.warn("Can't pingCRSDS, plone.app.async not installed!")
                return

            options = {}
            options['service_to_ping'] = service_to_ping
            options['obj_url'] = self.sanitize_url(obj_url)
            options['create'] = create
            queue = async_service.getQueues()['']
            try:
                async_service.queueJobInQueue(queue, ('rdf', ), ping_CRSDS,
                                              self.context, options)
            except ComponentLookupError:
                logger.info(noasync_msg)

        def pingCRSDS_backrel(service_to_ping, obj, create):
            """ Ping backward relations
            """
            back_relations = obj.getBRefs('relatesTo')
            for rel in back_relations:
                if rel is not None:
                    obj_url = "%s/@@rdf" % rel.absolute_url()
                    pingCRSDS(service_to_ping, obj_url, create)

        def pingCRSDS_children(service_to_ping, obj, create):
            """ Ping all sub-objects
            """
            if obj.portal_type == "Discussion Item":
                # 22047 skip object if it's of type Discussion Item
                return
            for child in obj.objectIds():
                child_obj = obj.get(child)
                if not child_obj:
                    logger.info("Couldn't retrieve child id %s for %s", child,
                                obj.absolute_url())
                    continue
                obj_url = "%s/@@rdf" % child_obj.absolute_url()
                pingCRSDS(service_to_ping, obj_url, create)
                pingCRSDS_children(service_to_ping, child_obj, create)

        # When no request the task is called from a async task, see #19830
        request = getattr(obj, 'REQUEST', None)

        # Detect special object used to force acquisition, see #18904
        if isinstance(request, str):
            request = None

        create = IObjectAddedEvent.providedBy(event)

        if service_to_ping == "":
            return

        if hasVersionsInstalled and IVersionEnhanced.providedBy(obj) \
                and request:
            obj_versions = IGetVersions(obj).versions()
        else:
            obj_versions = [obj]

        async_service = queryUtility(IAsyncService)

        # If object has translations
        if hasLinguaPloneInstalled and ITranslatable.providedBy(obj):
            if obj.isCanonical():
                # Ping all translations
                for trans in obj.getTranslations().items():
                    if trans[0] != 'en':
                        trans_obj = trans[1][0]
                        obj_url = trans_obj.absolute_url()
                        pingCRSDS(service_to_ping, obj_url, create)
            else:
                # Ping only canonical
                can_obj = obj.getCanonical()
                obj_url = can_obj.absolute_url()
                pingCRSDS(service_to_ping, obj_url, create)

        # If object was deleted
        if IObjectRemovedEvent.providedBy(event):
            # Ping backward relations
            pingCRSDS_backrel(service_to_ping, obj, create)

            # Ping all sub-objects
            pingCRSDS_children(service_to_ping, obj, create)

        # If object was moved/renamed first ping with the old object's URL
        if IObjectMovedOrRenamedEvent.providedBy(event):
            obj_url = "%s/%s/@@rdf" % (event.oldParent.absolute_url(),
                                       event.oldName)
            pingCRSDS(service_to_ping, obj_url, False)

            # then ping with the container of the old object
            obj_url = "%s/@@rdf" % event.oldParent.absolute_url()
            pingCRSDS(service_to_ping, obj_url, False)

            # Ping backward relations
            pingCRSDS_backrel(service_to_ping, obj, create)

            # Ping all sub-objects
            pingCRSDS_children(service_to_ping, obj, create)

        # Ping each version
        for obj in obj_versions:
            obj_url = "%s/@@rdf" % obj.absolute_url()
            pingCRSDS(service_to_ping, obj_url, create)

        # If no Aquisition there is no container, see #18904
        if container:
            obj_url = "%s/@@rdf" % container.absolute_url()
            pingCRSDS(service_to_ping, obj_url, False)

        return True
示例#52
0
 def is_uninstalling_plone(self):
     return IObjectRemovedEvent.providedBy(self.event) \
         and IPloneSiteRoot.providedBy(self.event.object)
示例#53
0
    def __call__(self):
        event = self.event
        service_to_ping = self.element.service_to_ping
        obj = self.event.object
        container = obj.getParentNode()
        noasync_msg = 'No instance for async operations was defined.'

        def pingCRSDS(service_to_ping, obj_url, create):
            """ Ping the CR/SDS service
            """
            options = {}
            options['service_to_ping'] = service_to_ping
            options['obj_url'] = self.sanitize_url(obj_url)
            options['create'] = create

            # Use RabbitMQ if available
            if self.rabbit_config:
                options['create'] = 'create' if options.get(
                    'create', False) else 'update'
                return ping_RabbitMQ(options)

            # Use zc.async if available
            if async_service is None:
                logger.warn("Can't pingCRSDS, plone.app.async not installed!")
                return

            queue = async_service.getQueues()['']
            try:
                async_service.queueJobInQueue(
                    queue, ('rdf',),
                    ping_CRSDS, self.context, options
                )
            except ComponentLookupError:
                logger.info(noasync_msg)

        def pingCRSDS_backrel(service_to_ping, obj, create):
            """ Ping backward relations
            """
            if hasattr(obj, 'getBRefs'):
                back_relations = obj.getBRefs('relatesTo')
            else:
                back_relations = [o.to_object
                    for o in getattr(obj, 'relatedItems')
                ]

            for rel in back_relations:
                if rel is not None:
                    obj_url = "%s/@@rdf" % rel.absolute_url()
                    pingCRSDS(service_to_ping, obj_url, create)

        def pingCRSDS_children(service_to_ping, obj, create):
            """ Ping all sub-objects
            """
            if obj.portal_type == "Discussion Item":
                # 22047 skip object if it's of type Discussion Item
                return
            for child in obj.objectIds():
                child_obj = obj.get(child)
                if not child_obj:
                    logger.info(
                        "Couldn't retrieve child id %s for %s",
                        child, obj.absolute_url())
                    continue
                obj_url = "%s/@@rdf" % child_obj.absolute_url()
                pingCRSDS(service_to_ping, obj_url, create)
                pingCRSDS_children(service_to_ping, child_obj, create)

        # When no request the task is called from a async task, see #19830
        request = getattr(obj, 'REQUEST', None)

        # Detect special object used to force acquisition, see #18904
        if isinstance(request, str):
            request = None

        create = IObjectAddedEvent.providedBy(event)

        if service_to_ping == "":
            return

        if hasVersionsInstalled and IVersionEnhanced.providedBy(obj) \
                and request:
            obj_versions = IGetVersions(obj).versions()
        else:
            obj_versions = [obj]

        async_service = queryUtility(IAsyncService)

        # If object has translations
        if hasLinguaPloneInstalled and ITranslatable.providedBy(obj):
            if obj.isCanonical():
                # Ping all translations
                for trans in obj.getTranslations().items():
                    if trans[0] != 'en':
                        trans_obj = trans[1][0]
                        obj_url = trans_obj.absolute_url()
                        pingCRSDS(service_to_ping, obj_url, create)
            else:
                # Ping only canonical
                can_obj = obj.getCanonical()
                obj_url = can_obj.absolute_url()
                pingCRSDS(service_to_ping, obj_url, create)

        # If object was deleted
        if IObjectRemovedEvent.providedBy(event):
            # Ping backward relations
            pingCRSDS_backrel(service_to_ping, obj, create)

            # Ping all sub-objects
            pingCRSDS_children(service_to_ping, obj, create)

        # If object was moved/renamed first ping with the old object's URL
        if IObjectMovedOrRenamedEvent.providedBy(event):
            obj_url = "%s/%s/@@rdf" % (event.oldParent.absolute_url(),
                                       event.oldName)
            pingCRSDS(service_to_ping, obj_url, False)

            # then ping with the container of the old object
            obj_url = "%s/@@rdf" % event.oldParent.absolute_url()
            pingCRSDS(service_to_ping, obj_url, False)

            # Ping backward relations
            pingCRSDS_backrel(service_to_ping, obj, create)

            # Ping all sub-objects
            pingCRSDS_children(service_to_ping, obj, create)

        # Ping each version
        for obj in obj_versions:
            obj_url = "%s/@@rdf" % obj.absolute_url()
            pingCRSDS(service_to_ping, obj_url, create)

        # If no Aquisition there is no container, see #18904
        if container:
            obj_url = "%s/@@rdf" % container.absolute_url()
            pingCRSDS(service_to_ping, obj_url, False)

        return True
示例#54
0
def fixOwnership(ob, event):
    if not IObjectRemovedEvent.providedBy(event):
        ob.fixOwnership()
示例#55
0
def index_task(obj, event):
    """Index the given task in opengever.globalindex.
    """
    # Skip this handler when trying to remove a Plone site. Otherwise the
    # component registry is already gone and we'll run into trouble.
    if IObjectRemovedEvent.providedBy(event) \
            and IPloneSiteRoot.providedBy(event.object):
        return None

    parent = aq_parent(aq_inner(obj))

    client_id = get_client_id()
    intids = getUtility(IIntIds)
    try:
        int_id = intids.getId(obj)
    except KeyError:
        try:
            # In some case (remote task updating etc)
            # only the base_object provides an intid.
            int_id = intids.getId(aq_base(obj))
        except KeyError:
            # The intid event handler didn' create a intid for this object
            # yet. The event will be fired again after creating the id.
            return

    session = Session()
    try:
        task = session.query(Task).filter(Task.client_id == client_id).filter(
            Task.int_id == int_id).one()
    except NoResultFound:
        task = Task(int_id, client_id)
        session.add(task)

    # title
    maximum_title_length = Task.title.property.columns[0].type.length
    title = obj.title
    if not isinstance(title, unicode):
        title = title.decode('utf-8')
    title = title[:maximum_title_length]
    task.title = title

    # Generate and store the breadcrumb tooltip
    breadcrumb_titles = []
    breadcrumbs_view = getMultiAdapter((obj, obj.REQUEST),
                                       name='breadcrumbs_view')
    for elem in breadcrumbs_view.breadcrumbs():
        if isinstance(elem.get('Title'), unicode):
            breadcrumb_titles.append(elem.get('Title'))
        else:
            breadcrumb_titles.append(elem.get('Title').decode('utf-8'))

    # we prevent to raise database-error, if we have a too long string
    # Shorten the breadcrumb_title to: mandant1 > repo1 > ...
    join_value = ' > '
    end_value = '...'

    maximum_length = Task.breadcrumb_title.property.columns[0].type.length
    maximum_length -= len(end_value)

    breadcrumb_title = breadcrumb_titles
    actual_length = 0

    for i, breadcrumb in enumerate(breadcrumb_titles):
        add_length = len(breadcrumb) + len(join_value) + len(end_value)
        if (actual_length + add_length) > maximum_length:
            breadcrumb_title = breadcrumb_titles[:i]
            breadcrumb_title.append(end_value)
            break

        actual_length += len(breadcrumb) + len(join_value)

    task.breadcrumb_title = join_value.join(breadcrumb_title)

    url_tool = obj.unrestrictedTraverse('@@plone_tools').url()
    task.physical_path = '/'.join(url_tool.getRelativeContentPath(obj))
    wftool = getToolByName(obj, 'portal_workflow')
    task.review_state = wftool.getInfoFor(obj, 'review_state')
    task.icon = obj.getIcon()
    task.responsible = obj.responsible
    task.issuer = obj.issuer

    # we need to have python datetime objects for make it work with sqlite etc.
    task.deadline = obj.deadline
    task.completed = obj.date_of_completion
    task.modified = obj.modified().asdatetime().replace(tzinfo=None)

    task.task_type = obj.task_type
    task.is_subtask = parent.portal_type == 'opengever.task.task'

    task.sequence_number = getUtility(ISequenceNumber).get_number(obj)
    task.reference_number = IReferenceNumber(obj).get_number()

    #get the containing_dossier value directly with the indexer
    catalog = getToolByName(obj, 'portal_catalog')
    task.containing_dossier = getMultiAdapter(
        (obj, catalog), IIndexer, name='containing_dossier')()

    # the dossier_sequence_number index is required for generating lists
    # of tasks as PDFs (LaTeX) as defined by the customer.
    task.dossier_sequence_number = get_dossier_sequence_number(obj)

    task.assigned_client = obj.responsible_client

    # index the predecessor
    if obj.predecessor:
        pred_client_id, pred_init_id = obj.predecessor.split(':', 1)
        try:
            predecessor = session.query(Task).filter_by(
                client_id=pred_client_id, int_id=pred_init_id).one()
        except NoResultFound:
            # For some reason the referenced predecessor doesn't exist
            predecessor = None

    else:
        predecessor = None

    task.predecessor = predecessor

    # index the principal which have View permission. This is according to the
    # allowedRolesAndUsers index but it does not car of global roles.
    allowed_roles = rolesForPermissionOn(View, obj)
    principals = []
    for principal, roles in _mergedLocalRoles(obj).items():
        for role in roles:
            if role in allowed_roles:
                principals.append(principal.decode('utf-8'))
                break

    task.principals = principals