Exemple #1
0
def containing_subdossier(obj):
    """Returns the title of the subdossier the object is contained in,
    unless it's contained directly in the root of a dossier, in which
    case an empty string is returned.
    """
    if obj.portal_type not in TYPES_WITH_CONTAINING_SUBDOSSIER_INDEX:
        return ''

    context = aq_inner(obj)

    parent = context
    parent_dossier = None
    parent_dossier_found = False
    while not parent_dossier_found:
        parent = aq_parent(parent)
        if ISiteRoot.providedBy(parent):
            # Shouldn't happen, just to be safe
            break
        if IDossierMarker.providedBy(parent):
            parent_dossier_found = True
            parent_dossier = parent

    if IDossierMarker.providedBy(aq_parent(parent_dossier)):
        # parent dossier is a subdossier
        return parent_dossier.Title()
    return ''
Exemple #2
0
def containing_subdossier(obj):
    """Returns the title of the subdossier the object is contained in,
    unless it's contained directly in the root of a dossier, in which
    case an empty string is returned.
    """
    context = aq_inner(obj)
    # Only compute for types that actually can be contained in a dossier
    if not context.portal_type in ['opengever.document.document',
                                   'opengever.task.task',
                                   'ftw.mail.mail']:
        return ''

    parent = context
    parent_dossier = None
    parent_dossier_found = False
    while not parent_dossier_found:
        parent = aq_parent(parent)
        if ISiteRoot.providedBy(parent):
            # Shouldn't happen, just to be safe
            break
        if IDossierMarker.providedBy(parent):
            parent_dossier_found = True
            parent_dossier = parent

    if IDossierMarker.providedBy(aq_parent(parent_dossier)):
        # parent dossier is a subdossier
        return parent_dossier.Title()
    return ''
Exemple #3
0
def containing_subdossier(obj):
    """Returns the title of the subdossier the object is contained in,
    unless it's contained directly in the root of a dossier, in which
    case an empty string is returned.
    """
    context = aq_inner(obj)
    # Only compute for types that actually can be contained in a dossier
    if context.portal_type not in [
            'opengever.document.document', 'opengever.task.task',
            'ftw.mail.mail'
    ]:
        return ''

    parent = context
    parent_dossier = None
    parent_dossier_found = False
    while not parent_dossier_found:
        parent = aq_parent(parent)
        if ISiteRoot.providedBy(parent):
            # Shouldn't happen, just to be safe
            break
        if IDossierMarker.providedBy(parent):
            parent_dossier_found = True
            parent_dossier = parent

    if IDossierMarker.providedBy(aq_parent(parent_dossier)):
        # parent dossier is a subdossier
        return parent_dossier.Title()
    return ''
Exemple #4
0
def containing_subdossier(obj):
    """Returns the title of the subdossier the object is contained in,
    unless it's contained directly in the root of a dossier, in which
    case an empty string is returned.
    """
    if obj.portal_type not in TYPES_WITH_CONTAINING_SUBDOSSIER_INDEX:
        return ''

    context = aq_inner(obj)

    parent = context
    parent_dossier = None
    parent_dossier_found = False
    while not parent_dossier_found:
        parent = aq_parent(parent)
        if ISiteRoot.providedBy(parent):
            # Shouldn't happen, just to be safe
            break
        if IDossierMarker.providedBy(parent):
            parent_dossier_found = True
            parent_dossier = parent

    if IDossierMarker.providedBy(aq_parent(parent_dossier)):
        # parent dossier is a subdossier
        return parent_dossier.Title()
    return ''
def object_moved_or_added(context, event):
    if isinstance(event, ObjectAddedEvent):
        # Don't consider moving or removing an object a "touch". Mass-moves
        # would immediately fill up the touched log, and removals should not
        # be tracked anyway.
        if should_track_touches(context):
            notify(ObjectTouchedEvent(context))

        # If an object has been copy & pasted, we need to reindex some fields.
        # The IObjectCopiedEvent is too early to do that though, because at
        # that point the object doesn't have a full AQ chain yet. We therefore
        # just mark it during IObjectCopiedEvent, and do the reindexing here.
        if getattr(context, '_v_object_has_been_copied', False):
            context.reindexObject(idxs=reindex_after_copy)

    if IObjectRemovedEvent.providedBy(event):
        return

    # Update object security after moving or copying.
    # Specifically, this is needed for the case where an object is moved out
    # of a location where a Placeful Workflow Policy applies to a location
    # where it doesn't.
    #
    #  Plone then no longer provides the placeful workflow for that object,
    # but doesn't automatically update the object's security.
    #
    # We use ftw.upgrade's update_security_for() here to correctly
    # recalculate security, but do the reindexing ourselves because otherwise
    # Plone will do it recursively (unnecessarily so).
    changed = update_security_for(context, reindex_security=False)
    if changed:
        reindex_object_security_without_children(context)

    # There are several indices that need updating when a dossier is moved.
    # first make sure obj was actually moved and not created
    if not event.oldParent or not event.newParent:
        return

    # When an object is moved, its containing_dossier needs reindexing.
    to_reindex = ['containing_dossier']
    # containing_subdossier is really only used for documents,
    # while is_subdossier is only meaningful for dossiers.
    if IDossierMarker.providedBy(context):
        was_subdossier = IDossierMarker.providedBy(event.oldParent)
        is_subdossier = IDossierMarker.providedBy(event.newParent)
        if was_subdossier != is_subdossier:
            to_reindex.append('is_subdossier')

    if context.portal_type in TYPES_WITH_CONTAINING_SUBDOSSIER_INDEX:
        to_reindex.append('containing_subdossier')

    context.reindexObject(idxs=to_reindex)

    # synchronize with model if necessary
    if ITask.providedBy(context):
        sync_task(context, event)
    def test_one_of_the_parents_of_content_needs_to_be_a_dossier(self):
        self.login(self.regular_user)
        self.assertTrue(IDossierMarker.providedBy(aq_parent(self.document)))
        self.assertTrue(can_access_archival_file_form(self.regular_user, self.document))

        self.assertFalse(IDossierMarker.providedBy(aq_parent(self.taskdocument)))
        self.assertTrue(can_access_archival_file_form(self.regular_user, self.taskdocument))

        self.login(self.administrator)
        self.assertFalse(can_access_archival_file_form(self.administrator, self.inbox_document))
Exemple #7
0
def object_moved_or_added(context, event):
    if isinstance(event, ObjectAddedEvent):
        # Don't consider moving or removing an object a "touch". Mass-moves
        # would immediately fill up the touched log, and removals should not
        # be tracked anyway.
        if should_track_touches(context):
            notify(ObjectTouchedEvent(context))

    if IObjectRemovedEvent.providedBy(event):
        return

    # Update object security after moving or copying.
    # Specifically, this is needed for the case where an object is moved out
    # of a location where a Placeful Workflow Policy applies to a location
    # where it doesn't.
    #
    #  Plone then no longer provides the placeful workflow for that object,
    # but doesn't automatically update the object's security.
    #
    # We use ftw.upgrade's update_security_for() here to correctly
    # recalculate security, but do the reindexing ourselves because otherwise
    # Plone will do it recursively (unnecessarily so).
    changed = update_security_for(context, reindex_security=False)
    if changed:
        reindex_object_security_without_children(context)

    # There are several indices that need updating when a dossier is moved.
    # first make sure obj was actually moved and not created
    if not event.oldParent or not event.newParent:
        return

    # When an object is moved, its containing_dossier needs reindexing.
    to_reindex = ['containing_dossier']
    # containing_subdossier is really only used for documents,
    # while is_subdossier is only meaningful for dossiers.
    if IDossierMarker.providedBy(context):
        was_subdossier = IDossierMarker.providedBy(event.oldParent)
        is_subdossier = IDossierMarker.providedBy(event.newParent)
        if was_subdossier != is_subdossier:
            to_reindex.append('is_subdossier')

    if context.portal_type in TYPES_WITH_CONTAINING_SUBDOSSIER_INDEX:
        to_reindex.append('containing_subdossier')

    context.reindexObject(idxs=to_reindex)

    # synchronize with model if necessary
    if ITask.providedBy(context):
        sync_task(context, event)
Exemple #8
0
    def __call__(self):
        searchable = []
        # append some other attributes to the searchableText index
        # reference_number
        refNumb = getAdapter(self.context, IReferenceNumber)
        searchable.append(refNumb.get_number())

        # sequence_number
        seqNumb = getUtility(ISequenceNumber)
        searchable.append(str(seqNumb.get_number(self.context)))
        # responsible
        info = getUtility(IContactInformation)
        dossier = IDossier(self.context)
        searchable.append(info.describe(dossier.responsible).encode(
                'utf-8'))

        # filling_no
        dossier = IDossierMarker(self.context)
        if getattr(dossier, 'filing_no', None):
            searchable.append(str(getattr(dossier, 'filing_no',
                                          None)).encode('utf-8'))

        # comments
        comments = getattr(IDossier(self.context), 'comments', None)
        if comments:
            searchable.append(comments.encode('utf-8'))

        return ' '.join(searchable)
Exemple #9
0
    def move_repository_reference_mappings(self, obj):
        intids = getUtility(IIntIds)
        annotations = IAnnotations(obj)

        if annotations and annotations.get(CHILD_REF_KEY):
            repository_mapping = PersistentDict(
                {CHILD_REF_KEY: {},
                 PREFIX_REF_KEY: {}})
            dossier_mapping = PersistentDict(
                {CHILD_REF_KEY: {},
                 PREFIX_REF_KEY: {}})

            for number, intid in annotations.get(CHILD_REF_KEY).items():
                try:
                    child = intids.getObject(intid)
                except KeyError:
                    # the object with this intid does not longer exist.
                    continue

                if IDossierMarker.providedBy(child):
                    dossier_mapping[CHILD_REF_KEY][number] = intid
                    dossier_mapping[PREFIX_REF_KEY][intid] = number
                else:
                    repository_mapping[CHILD_REF_KEY][number] = intid
                    repository_mapping[PREFIX_REF_KEY][intid] = number

            # save mapping
            annotations[REPOSITORY_FOLDER_KEY] = repository_mapping
            annotations[DOSSIER_KEY] = dossier_mapping

            # drop old mapings
            annotations.pop(CHILD_REF_KEY)
            annotations.pop(PREFIX_REF_KEY)
    def _construct_object(self, container, item):
        portal_type = item['_type']
        fti = self._get_fti(portal_type)
        title_args = self._get_title_args(fti, item)

        with NoDossierReferenceNumbersIssued():
            # Create the object without automatically issuing a
            # reference number - we might want to set it explicitly
            obj = createContentInContainer(
                container, portal_type, **title_args)

            if IDossierMarker.providedBy(obj):
                prefix_adapter = IReferenceNumberPrefix(container)
                if not prefix_adapter.get_number(obj):
                    # Set the local reference number part for the
                    # dossier if provided in item, otherwise have
                    # the adapter issue the next one
                    local_refnum = item.get('reference_number')
                    if local_refnum is not None:
                        prefix_adapter.set_number(obj, local_refnum)
                    else:
                        prefix_adapter.set_number(obj)

        self._set_guid(obj, item)
        return obj
    def is_locked(self, recursive=True):
        """Determine whether a dossier currently is resolve locked.

        By default also considers a subdossier locked if any of its parent
        dossiers have a lock on them.

        If recursive=False is given, only the current dossier is checked for
        a lock (cheaper, this is used to display the state in the byline).

        If a lock exists (somewhere) but is older than RESOLVE_LOCK_LIFETIME,
        it is considered expired and treated as if it wouldn't exist.
        """
        item = self.context

        while IDossierMarker.providedBy(item):

            lockinfo = self.get_lockinfo(item)
            if lockinfo is not None and not self.is_expired(lockinfo):
                self.log("%s is resolve locked via lock on %r" % (self.context, item))
                return True

            if not recursive:
                return False

            item = aq_parent(item)

        return False
Exemple #12
0
    def raise_invalid(self):
        if IDossierMarker.providedBy(self.context):
            mail_address = IEmailAddress(
                self.request).get_email_for_object(self.context)
        else:
            parent = aq_parent(aq_inner(self.context))
            mail_address = IEmailAddress(
                self.request).get_email_for_object(parent)

        # Remove widget value in order to disable that the widget renders
        # radio-buttons (nochange/remove/replace) once a file has been
        # uploaded.
        # This is a special case since we are an additional validator
        # for the file field that may block an otherwise valid file upload.
        # The widget does not expect this to happen though.
        if getattr(self.view.parentForm, '_nullify_file_on_error', False):
            self.widget.value = None

        raise Invalid(_(
            u'error_mail_upload',
            default=(u"It's not possible to add E-mails here, please "
            "send it to ${mailaddress} or drag it to the dossier "
            "(Dragn'n'Drop)."),
            mapping={'mailaddress': mail_address}
            ))
Exemple #13
0
def get_containing_dossier(obj):
    while not IPloneSiteRoot.providedBy(obj):
        if IDossierMarker.providedBy(obj) or IInbox.providedBy(obj):
            return obj
        obj = aq_parent(aq_inner(obj))

    return None
Exemple #14
0
    def render(self):
        self.request.response.setHeader('Content-type', 'application/json')
        payloads = self.get_base_payloads()

        dossier_notifications = {}

        for payload in payloads:
            document = payload['document']
            parent_dossier = document.get_parent_dossier()

            if (parent_dossier and IDossierMarker.providedBy(parent_dossier)):
                if parent_dossier.is_open():
                    payload['bcc'] = (IEmailAddress(
                        self.request).get_email_for_object(parent_dossier))

                parent_dossier_uuid = api.content.get_uuid(parent_dossier)

                if parent_dossier_uuid not in dossier_notifications:
                    dossier_notifications[parent_dossier_uuid] = []

                dossier_notifications[parent_dossier_uuid].append(document)

            payload['title'] = document.title_or_id()
            payload['content-type'] = document.get_file().contentType
            payload['download'] = document.get_download_view_name()
            payload['filename'] = document.get_filename()
            del payload['document']
            notify(FileAttachedToEmailEvent(document))

        for uuid, documents in dossier_notifications.iteritems():
            dossier = api.content.get(UID=uuid)
            notify(DossierAttachedToEmailEvent(dossier, documents))

        return json.dumps(payloads)
Exemple #15
0
 def _add_descendants(self):
     objs = self.obj.objectValues()
     for obj in objs:
         if IDossierMarker.providedBy(obj):
             self.dossiers.append(Dossier(obj, self.path))
         elif IBaseDocument.providedBy(obj) and obj.get_file():
             self.documents.append(Document(obj, self.path))
Exemple #16
0
def isSubdossierIndexer(obj):
    # TODO: should be replaced with the is_subdossier method
    # from og.dossier.base.py
    parent = aq_parent(aq_inner(obj))
    if IDossierMarker.providedBy(parent):
        return True
    return False
    def is_allowed(self):
        """Perform the necessary checks to determine whether pasting is
        allowed / possible on the current context.
        """
        # Check whether pasting is allowed at all for the container type
        if self.context.portal_type in self.disabled_types:
            return False

        # XXX implement me in a more object oriented manner, i.e. by
        # implementing `is_pasting_allowed` for all our content types.
        if IDossierMarker.providedBy(self.context):
            if not self.context.is_open():
                return False

        objs = Clipboard(self.request).get_objs()
        if not objs:
            # Clipboard empty
            return False

        # Check whether there's an object in the clipboard whose type
        # is not allowed to be added to the container
        for obj in objs:
            if obj.portal_type not in self.allowed_content_types:
                return False

        return self.validate_private_folder_pasting(objs)
Exemple #18
0
def get_redirect_url(context):
        """return the url where the editing_document view was called from
        It should be a document listing."""

        referer = context.REQUEST.environ.get('HTTP_REFERER')
        portal_url = '/'.join(context.portal_url().split('/')[:-1])
        if referer:
            obj_path = referer[len(portal_url):]
            try:
                obj = context.restrictedTraverse(obj_path)
            except KeyError:
                return  '%s#overview' % context.absolute_url()

            # redirect to right tabbedview-tab
            if ITask.providedBy(obj):
                return '%s#relateddocuments' % (obj.absolute_url())
            elif IPloneSiteRoot.providedBy(obj):
                return '%s#mydocuments' % (obj.absolute_url())
            elif IDossierMarker.providedBy(obj):
                return '%s#documents' % (obj.absolute_url())
            else:
                return obj.absolute_url()

        else:
            return  '%s#overview' % context.absolute_url()
Exemple #19
0
    def replace_interactive_user(self, principal):
        """Replaces interactive users in the principal.
        """

        if principal == 'responsible':
            # find the dossier
            dossier = self.context
            while not IDossierMarker.providedBy(dossier):
                if IPloneSiteRoot.providedBy(dossier):
                    raise ValueError('Could not find dossier')
                dossier = aq_parent(aq_inner(dossier))
            # get the responsible of the dossier
            wrapped_dossier = IDossier(dossier)
            return wrapped_dossier.responsible

        elif principal == 'current_user':
            # get the current user
            mtool = getToolByName(self.context, 'portal_membership')
            member = mtool.getAuthenticatedMember()
            if not member:
                raise Unauthorized()
            return member.getId()

        else:
            return principal
Exemple #20
0
    def get_parent_dossier(self):
        parent = aq_parent(aq_inner(self))

        if IDossierMarker.providedBy(parent):
            return parent

        return None
    def is_allowed(self):
        """Perform the necessary checks to determine whether pasting is
        allowed / possible on the current context.
        """
        # Check whether the user has Copy or Move on the context
        if not api.user.has_permission('Copy or Move', obj=self.context):
            return False

        # Check whether pasting is allowed at all for the container type
        if self.context.portal_type in self.disabled_types:
            return False

        # XXX implement me in a more object oriented manner, i.e. by
        # implementing `is_pasting_allowed` for all our content types.
        if IDossierMarker.providedBy(self.context):
            if not self.context.is_open():
                return False

        objs = Clipboard(self.request).get_objs()
        if not objs:
            # Clipboard empty
            return False

        # Check whether there's an object in the clipboard whose type
        # is not allowed to be added to the container
        for obj in objs:
            if obj.portal_type not in self.allowed_content_types:
                return False

        return self.validate_private_folder_pasting(objs)
    def is_locked(self, recursive=True):
        """Determine whether a dossier currently is resolve locked.

        By default also considers a subdossier locked if any of its parent
        dossiers have a lock on them.

        If recursive=False is given, only the current dossier is checked for
        a lock (cheaper, this is used to display the state in the byline).

        If a lock exists (somewhere) but is older than RESOLVE_LOCK_LIFETIME,
        it is considered expired and treated as if it wouldn't exist.
        """
        item = self.context

        while IDossierMarker.providedBy(item):

            lockinfo = self.get_lockinfo(item)
            if lockinfo is not None and not self.is_expired(lockinfo):
                self.log("%s is resolve locked via lock on %r" %
                         (self.context, item))
                return True

            if not recursive:
                return False

            item = aq_parent(item)

        return False
def check_dossier_nesting(portal, options):
    """Find all Dossiers that are nested 3 levels or more (sub-sub-dossiers).
    """
    catalog = getToolByName(portal, 'portal_catalog')
    dossiers = catalog(object_provides=IDossierMarker.__identifier__)

    for brain in dossiers:
        obj = brain.getObject()
        subdossiers = [c for c in obj.getChildNodes()
                       if IDossierMarker.providedBy(c)]

        for subdossier in subdossiers:
            if subdossier.get_subdossiers() != []:
                badly_nested_dossiers = [c for c in subdossier.getChildNodes()
                                         if IDossierMarker.providedBy(c)]
                print badly_nested_dossiers
    def _construct_object(self, container, item):
        portal_type = item['_type']
        fti = self._get_fti(portal_type)
        title_args = self._get_title_args(fti, item)

        with NoDossierReferenceNumbersIssued():
            # Create the object without automatically issuing a
            # reference number - we might want to set it explicitly
            obj = createContentInContainer(container, portal_type,
                                           **title_args)

            if IDossierMarker.providedBy(obj):
                prefix_adapter = IReferenceNumberPrefix(container)
                if not prefix_adapter.get_number(obj):
                    # Set the local reference number part for the
                    # dossier if provided in item, otherwise have
                    # the adapter issue the next one
                    local_refnum = item.get('reference_number')
                    if local_refnum is not None:
                        prefix_adapter.set_number(obj, local_refnum)
                    else:
                        prefix_adapter.set_number(obj)

        self._set_guid(obj, item)
        return obj
Exemple #25
0
    def replace_interactive_user(self, principal):
        """Replaces interactive users in the principal.
        """

        if principal == 'responsible':
            # find the dossier
            dossier = self.context
            while not IDossierMarker.providedBy(dossier):
                if IPloneSiteRoot.providedBy(dossier):
                    raise ValueError('Could not find dossier')
                dossier = aq_parent(aq_inner(dossier))
            # get the responsible of the dossier
            wrapped_dossier = IDossier(dossier)
            return wrapped_dossier.responsible

        elif principal == 'current_user':
            # get the current user
            mtool = getToolByName(self.context, 'portal_membership')
            member = mtool.getAuthenticatedMember()
            if not member:
                raise Unauthorized()
            return member.getId()

        else:
            return principal
Exemple #26
0
 def _add_descendants(self):
     objs = self.obj.objectValues()
     for obj in objs:
         if IDossierMarker.providedBy(obj):
             self.dossiers[obj.UID()] = Dossier(obj)
         elif IDocumentSchema.providedBy(obj):
             self.documents[obj.UID()] = Document(obj)
Exemple #27
0
def get_redirect_url(context):
    """return the url where the editing_document view was called from
        It should be a document listing."""

    referer = context.REQUEST.environ.get('HTTP_REFERER')
    portal_url = '/'.join(context.portal_url().split('/')[:-1])
    if referer:
        obj_path = referer[len(portal_url):]
        try:
            obj = context.restrictedTraverse(obj_path)
        except KeyError:
            return '%s#overview' % context.absolute_url()

        # redirect to right tabbedview-tab
        if ITask.providedBy(obj):
            return '%s#relateddocuments' % (obj.absolute_url())
        elif IPloneSiteRoot.providedBy(obj):
            return '%s#mydocuments' % (obj.absolute_url())
        elif IDossierMarker.providedBy(obj):
            return '%s#documents' % (obj.absolute_url())
        else:
            return obj.absolute_url()

    else:
        return '%s#overview' % context.absolute_url()
Exemple #28
0
    def allowedContentTypes(self, *args, **kwargs):
        types = super(
            DossierContainer, self).allowedContentTypes(*args, **kwargs)
        # calculate depth
        depth = 0
        obj = self
        while IDossierMarker.providedBy(obj):
            depth += 1
            obj = aq_parent(aq_inner(obj))
            if IPloneSiteRoot.providedBy(obj):
                break

        # the adapter decides
        def filter_type(fti):
            # first we try the more specific one ...
            decider = queryMultiAdapter((self.REQUEST, self, fti),
                                    IConstrainTypeDecider,
                                    name=fti.portal_type)
            if not decider:
                # .. then we try the more general one
                decider = queryMultiAdapter((self.REQUEST, self, fti),
                                        IConstrainTypeDecider)
            if decider:
                return decider.addable(depth)
            # if we don't have an adapter, we just allow it
            return True
        # filter
        return filter(filter_type, types)
Exemple #29
0
def isSubdossierIndexer(obj):
    # TODO: should be replaced with the is_subdossier method
    # from og.dossier.base.py
    parent = aq_parent(aq_inner(obj))
    if IDossierMarker.providedBy(parent):
        return True
    return False
Exemple #30
0
    def allowedContentTypes(self, *args, **kwargs):
        types = super(DossierContainer,
                      self).allowedContentTypes(*args, **kwargs)
        # calculate depth
        depth = 0
        obj = self
        while IDossierMarker.providedBy(obj):
            depth += 1
            obj = aq_parent(aq_inner(obj))
            if IPloneSiteRoot.providedBy(obj):
                break

        # the adapter decides
        def filter_type(fti):
            # first we try the more specific one ...
            decider = queryMultiAdapter((self.REQUEST, self, fti),
                                        IConstrainTypeDecider,
                                        name=fti.portal_type)
            if not decider:
                # .. then we try the more general one
                decider = queryMultiAdapter((self.REQUEST, self, fti),
                                            IConstrainTypeDecider)
            if decider:
                return decider.addable(depth)
            # if we don't have an adapter, we just allow it
            return True

        # filter
        return filter(filter_type, types)
    def test_one_of_the_parents_of_content_needs_to_be_a_dossier(self):
        self.login(self.regular_user)
        self.assertTrue(IDossierMarker.providedBy(aq_parent(self.document)))
        self.assertTrue(
            can_access_archival_file_form(self.regular_user, self.document))

        self.assertFalse(
            IDossierMarker.providedBy(aq_parent(self.taskdocument)))
        self.assertTrue(
            can_access_archival_file_form(self.regular_user,
                                          self.taskdocument))

        self.login(self.administrator)
        self.assertFalse(
            can_access_archival_file_form(self.administrator,
                                          self.inbox_document))
Exemple #32
0
 def test_create_dossier_from_template(self):
     self.login(self.regular_user)
     command = CreateDossierFromTemplateCommand(self.dossier,
                                                self.dossiertemplate)
     dossier = command.execute()
     self.assertEqual(self.dossiertemplate.title, dossier.title)
     self.assertTrue(IDossierMarker.providedBy(dossier))
Exemple #33
0
    def render(self):
        self.request.response.setHeader('Content-type', 'application/json')
        payloads = self.get_base_payloads()

        dossier_notifications = {}

        for payload in payloads:
            document = payload['document']
            parent_dossier = document.get_parent_dossier()

            if parent_dossier and IDossierMarker.providedBy(parent_dossier) and parent_dossier.is_open():
                payload['bcc'] = IEmailAddress(self.request).get_email_for_object(parent_dossier)

                parent_dossier_uuid = api.content.get_uuid(parent_dossier)

                if parent_dossier_uuid not in dossier_notifications:
                    dossier_notifications[parent_dossier_uuid] = []

                dossier_notifications[parent_dossier_uuid].append(document)

            payload['title'] = document.title_or_id()
            payload['content-type'] = document.get_file().contentType
            payload['download'] = document.get_download_view_name()
            payload['filename'] = document.get_filename()
            del payload['document']
            notify(FileAttachedToEmailEvent(document))

        for uuid, documents in dossier_notifications.iteritems():
            dossier = api.content.get(UID=uuid)
            notify(DossierAttachedToEmailEvent(dossier, documents))

        return json.dumps(payloads)
Exemple #34
0
 def _add_descendants(self):
     objs = self.obj.objectValues()
     for obj in objs:
         if IDossierMarker.providedBy(obj):
             self.dossiers.append(Dossier(obj, self.path))
         elif IDocumentSchema.providedBy(obj):
             self.documents.append(Document(obj, self.path))
Exemple #35
0
 def _add_descendants(self):
     objs = self.obj.objectValues()
     for obj in objs:
         if IDossierMarker.providedBy(obj):
             self.dossiers[obj.UID()] = Dossier(obj)
         elif IDocumentSchema.providedBy(obj):
             self.documents[obj.UID()] = Document(obj)
Exemple #36
0
    def raise_invalid(self):
        if IDossierMarker.providedBy(self.context):
            mail_address = IEmailAddress(
                self.request).get_email_for_object(self.context)
        else:
            parent = aq_parent(aq_inner(self.context))
            mail_address = IEmailAddress(
                self.request).get_email_for_object(parent)

        # Remove widget value in order to disable that the widget renders
        # radio-buttons (nochange/remove/replace) once a file has been
        # uploaded.
        # This is a special case since we are an additional validator
        # for the file field that may block an otherwise valid file upload.
        # The widget does not expect this to happen though.
        if getattr(self.view.parentForm, '_nullify_file_on_error', False):
            self.widget.value = None

        raise Invalid(_(
            u'error_mail_upload',
            default=(u"It's not possible to add E-mails here, please "
            "send it to ${mailaddress} or drag it to the dossier "
            "(Dragn'n'Drop)."),
            mapping={'mailaddress': mail_address}
            ))
Exemple #37
0
    def get_parent_dossier(self):
        parent = aq_parent(aq_inner(self))

        if IDossierMarker.providedBy(parent):
            return parent

        return None
Exemple #38
0
 def label(self):
     if IDossierMarker.providedBy(self.context):
         return _(u'Add Subdossier')
     else:
         portal_type = self.portal_type
         fti = getUtility(IDexterityFTI, name=portal_type)
         type_name = fti.Title()
         return pd_mf(u"Add ${name}", mapping={'name': type_name})
Exemple #39
0
 def get_contained_folders(folder):
     children = folder.getChildNodes()
     return [
         child
         for child in children
         if IDossierMarker.providedBy(child)
         if api.user.has_permission('View', obj=child)
         ]
Exemple #40
0
 def assert_valid_container_state(self):
     container = self.context
     if not self.within_template_folder(container) and \
             IDossierMarker.providedBy(container) and not container.is_open():
         msg = _(u'Can only move objects from open dossiers!')
         IStatusMessage(self.request).addStatusMessage(msg, type='error')
         self.request.RESPONSE.redirect('%s#documents' %
                                        container.absolute_url())
Exemple #41
0
 def assert_valid_container_state(self):
     container = self.context
     if IDossierMarker.providedBy(container) and not container.is_open():
         msg = _(u'Can only move objects from open dossiers!')
         IStatusMessage(self.request).addStatusMessage(
             msg, type='error')
         self.request.RESPONSE.redirect(
             '%s#documents' % container.absolute_url())
Exemple #42
0
def default_title(context):
    # At this point, only proposals (not submitted proposals) should acquire
    # an actual default. This is indicated by the parent being a dossier.
    if not IDossierMarker.providedBy(context):
        return u''

    # Use Title() accessor to make this defaultFactor robust in regard to
    # objects with ITranslatedTitle behavior or titles stored in SQL
    return context.Title().decode('utf-8')
Exemple #43
0
def top_dossier_title(obj):
    """return the tilte of the top containing dossier."""
    dossier_title = ''
    while not IPloneSiteRoot.providedBy(obj):
        if IDossierMarker.providedBy(
            obj) or obj.portal_type == 'opengever.inbox.inbox':
            dossier_title = obj.Title()
        obj = aq_parent(aq_inner(obj))
    return dossier_title
Exemple #44
0
    def handle_submit(self, action):
        data, errors = self.extractData()
        if len(errors) == 0:

            source = data['request_paths'].split(';;')
            destination = data['destination_folder']
            failed_objects = []
            failed_resource_locked_objects = []
            copied_items = 0

            for path in source:

                # Get source object
                src_object = self.context.unrestrictedTraverse(
                    path.encode('utf-8'))

                # Get parent object
                source_container = aq_parent(aq_inner(
                    self.context.unrestrictedTraverse(
                        path.encode('utf-8'))))

                src_name = src_object.title
                src_id = src_object.id

                # If parent isn't a dossier and obj is a document
                # it's connected to a task and shouldn't be moved
                if not IDossierMarker.providedBy(source_container) and \
                    IDocumentSchema.providedBy(src_object):
                    msg = _(u'Document ${name} is connected to a Task.\
                    Please move the Task.', mapping=dict(name=src_name))
                    IStatusMessage(self.request).addStatusMessage(
                        msg, type='error')
                    continue

                try:
                    # Try to cut and paste object
                    clipboard = source_container.manage_cutObjects(src_id)
                    destination.manage_pasteObjects(clipboard)
                    copied_items += 1

                except ResourceLockedError:
                    # The object is locket over webdav
                    failed_resource_locked_objects.append(src_name)
                    continue

                except (ValueError, CopyError):
                    # Catch exception and add title to a list of failed objects
                    failed_objects.append(src_name)
                    continue

            self.create_statusmessages(
                copied_items,
                failed_objects,
                failed_resource_locked_objects, )

            self.request.RESPONSE.redirect(destination.absolute_url())
Exemple #45
0
    def find_dossier(self):
        obj = self.context

        while not IPloneSiteRoot.providedBy(obj):
            if IDossierMarker.providedBy(obj):
                return obj
            else:
                obj = aq_parent(aq_inner(obj))

        return None
Exemple #46
0
 def available(self):
     if not self.enabled():
         return False
     if IDossierMarker.providedBy(self.context):
         return True
     if not IRepositoryFolder.providedBy(self.context):
         return False
     if self.context.is_leaf_node():
         return True
     return False
Exemple #47
0
    def find_dossier(self):
        obj = self.context

        while not IPloneSiteRoot.providedBy(obj):
            if IDossierMarker.providedBy(obj):
                return obj
            else:
                obj = aq_parent(aq_inner(obj))

        return None
Exemple #48
0
 def _get_dossier_depth(self):
     # calculate depth
     depth = 0
     obj = self
     while IDossierMarker.providedBy(obj):
         depth += 1
         obj = aq_parent(aq_inner(obj))
         if IPloneSiteRoot.providedBy(obj):
             break
     return depth
Exemple #49
0
 def available(self):
     if not self.enabled():
         return False
     if IDossierMarker.providedBy(self.context):
         return True
     if not IRepositoryFolder.providedBy(self.context):
         return False
     if self.context.is_leaf_node():
         return True
     return False
Exemple #50
0
 def _get_dossier_depth(self):
     # calculate depth
     depth = 0
     obj = self
     while IDossierMarker.providedBy(obj):
         depth += 1
         obj = aq_parent(aq_inner(obj))
         if IPloneSiteRoot.providedBy(obj):
             break
     return depth
Exemple #51
0
    def containing_subdossier_title(self):
        """"Returns the title of the subdossier which the document is placed in.
        Returns None when the object is placed directly inside a main dossier.
        """
        dossier = self.get_parent_dossier()

        # Return None if the dossier is a main dossier
        if not IDossierMarker.providedBy(aq_parent(dossier)):
            return None

        return dossier.title
Exemple #52
0
def find_parent_dossier(content):
    """Returns the first parent dossier relative to the current context.
    """

    if IPloneSiteRoot.providedBy(content):
        raise ValueError('Site root passed as argument.')

    while content and not IDossierMarker.providedBy(content):
        content = aq_parent(aq_inner(content))
        if IPloneSiteRoot.providedBy(content):
            raise ValueError('Site root reached while searching '
                             'parent dossier.')
    return content
Exemple #53
0
def get_main_dossier(obj):
    """Helper method which returns the main dossier (or inbox) of the given
    object.
    If the given object is not storred inside a dossier it returns None."""

    dossier = None
    while not IPloneSiteRoot.providedBy(obj):
        if IDossierMarker.providedBy(obj) or IInbox.providedBy(obj):
            dossier = obj

        obj = aq_parent(aq_inner(obj))

    return dossier
    def find_parent_dossier(self):
        """Returns the first parent dossier relative to the current context.
        """

        obj = self.context
        while not IDossierMarker.providedBy(obj):
            obj = aq_parent(aq_inner(obj))

            if IPloneSiteRoot.providedBy(obj):
                return ValueError('Site root reached while searching '
                                  'parent dossier.')

        return obj
Exemple #55
0
def reindex_containing_dossier(dossier, event):
    """Reindex the containging_dossier index for all the contained obects,
    when the title has changed."""
    if not IDossierMarker.providedBy(aq_parent(aq_inner(dossier))):
        for descr in event.descriptions:
            for attr in descr.attributes:
                if attr == "IOpenGeverBase.title":
                    for brain in dossier.portal_catalog(path="/".join(dossier.getPhysicalPath())):

                        brain.getObject().reindexObject(idxs=["containing_dossier"])

                        if brain.portal_type in ["opengever.task.task", "opengever.inbox.forwarding"]:
                            sync_task(brain.getObject(), event)
Exemple #56
0
def find_parent_dossier(content):
    """Returns the first parent dossier relative to the current context.
    """

    if IPloneSiteRoot.providedBy(content):
        raise ValueError('Site root passed as argument.')

    while content and not IDossierMarker.providedBy(content):
        content = aq_parent(aq_inner(content))
        if IPloneSiteRoot.providedBy(content):
            raise ValueError('Site root reached while searching '
                             'parent dossier.')
    return content
Exemple #57
0
def get_main_dossier(obj):
    """Helper method which returns the main dossier (or inbox) of the given
    object.
    If the given object is not storred inside a dossier it returns None."""

    dossier = None
    while not IPloneSiteRoot.providedBy(obj):
        if IDossierMarker.providedBy(obj) or IInbox.providedBy(obj):
            dossier = obj

        obj = aq_parent(aq_inner(obj))

    return dossier