Beispiel #1
0
    def _delObject(self, id, dp=1, suppress_events=False):
        """Delete an object from this container.

        Also sends IObjectWillBeRemovedEvent and IObjectRemovedEvent.
        """
        ob = self._getOb(id)

        compatibilityCall('manage_beforeDelete', ob, ob, self)

        if not suppress_events:
            notify(ObjectWillBeRemovedEvent(ob, self, id))

        self._objects = tuple([i for i in self._objects
                               if i['id'] != id])
        self._delOb(id)

        # Indicate to the object that it has been deleted. This is
        # necessary for object DB mount points. Note that we have to
        # tolerate failure here because the object being deleted could
        # be a Broken object, and it is not possible to set attributes
        # on Broken objects.
        try:
            ob._v__object_deleted__ = 1
        except:
            pass

        if not suppress_events:
            notify(ObjectRemovedEvent(ob, self, id))
            notifyContainerModified(self)
Beispiel #2
0
    def manage_clone(self, ob, id, REQUEST=None):
        """Clone an object, creating a new object with the given id.
        """
        if not ob.cb_isCopyable():
            raise CopyError('Not Supported')
        try:
            self._checkId(id)
        except Exception:
            raise CopyError('Invalid Id')

        self._verifyObjectPaste(ob)

        try:
            ob._notifyOfCopyTo(self, op=0)
        except ConflictError:
            raise
        except Exception:
            raise CopyError('Clone Error')

        orig_ob = ob
        ob = ob._getCopy(self)
        ob._setId(id)
        notify(ObjectCopiedEvent(ob, orig_ob))

        self._setObject(id, ob)
        ob = self._getOb(id)

        ob._postCopy(self, op=0)

        compatibilityCall('manage_afterClone', ob, ob)

        notify(ObjectClonedEvent(ob))

        return ob
Beispiel #3
0
    def manage_clone(self, ob, id, REQUEST=None):
        """Clone an object, creating a new object with the given id.
        """
        if not ob.cb_isCopyable():
            raise CopyError('Not Supported')
        try:
            self._checkId(id)
        except Exception:
            raise CopyError('Invalid Id')

        self._verifyObjectPaste(ob)

        try:
            ob._notifyOfCopyTo(self, op=0)
        except ConflictError:
            raise
        except Exception:
            raise CopyError('Clone Error')

        orig_ob = ob
        ob = ob._getCopy(self)
        ob._setId(id)
        notify(ObjectCopiedEvent(ob, orig_ob))

        self._setObject(id, ob)
        ob = self._getOb(id)

        ob._postCopy(self, op=0)

        compatibilityCall('manage_afterClone', ob, ob)

        notify(ObjectClonedEvent(ob))

        return ob
    def _delObject(self, id, dp=1, suppress_events=False):
        """Delete an object from this container.

        Also sends IObjectWillBeRemovedEvent and IObjectRemovedEvent.
        """
        ob = self._getOb(id)

        compatibilityCall('manage_beforeDelete', ob, ob, self)

        if not suppress_events:
            notify(ObjectWillBeRemovedEvent(ob, self, id))

        self._objects = tuple([i for i in self._objects if i['id'] != id])
        self._delOb(id)

        # Indicate to the object that it has been deleted. This is
        # necessary for object DB mount points. Note that we have to
        # tolerate failure here because the object being deleted could
        # be a Broken object, and it is not possible to set attributes
        # on Broken objects.
        try:
            ob._v__object_deleted__ = 1
        except Exception:
            pass

        if not suppress_events:
            notify(ObjectRemovedEvent(ob, self, id))
            notifyContainerModified(self)
Beispiel #5
0
 def _setObject(self, id, object, roles=None, user=None, set_owner=1,
                suppress_events=False):
     """Set an object into this container.
     Also sends IObjectWillBeAddedEvent and IObjectAddedEvent.
     """
     ob = object
     if not suppress_events:
         # notify(ObjectAddedEvent(ob, self, id))
         notifyContainerModified(self)
     compatibilityCall('manage_afterAdd', ob, ob, self)
     return id
Beispiel #6
0
    def __copy(self, content, to_identifier):
        # Copy a content to to_identifier in the container
        copy = content._getCopy(self.context)
        copy._setId(to_identifier)
        notify(ObjectCopiedEvent(copy, content))

        self.context._setObject(to_identifier, copy)
        copy = self.context._getOb(to_identifier)

        compatibilityCall('manage_afterClone', copy, copy)
        notify(ObjectClonedEvent(copy))
        return copy
    def __copy(self, content, to_identifier):
        # Copy a content to to_identifier in the container
        copy = content._getCopy(self.context)
        copy._setId(to_identifier)
        notify(ObjectCopiedEvent(copy, content))

        self.context._setObject(to_identifier, copy)
        copy = self.context._getOb(to_identifier)

        compatibilityCall('manage_afterClone', copy, copy)
        notify(ObjectClonedEvent(copy))
        return copy
Beispiel #8
0
def _setObject(self,
               id,
               object,
               roles=None,
               user=None,
               set_owner=1,
               suppress_events=False):
    """Set an object into this container.

    Also sends IObjectAddedEvent.
    """
    ob = object  # better name, keep original function signature
    v = self._checkId(id)
    if v is not None:
        id = v
    t = getattr(ob, 'meta_type', None)

    # If an object by the given id already exists, remove it.
    for object_info in self._objects:
        if object_info['id'] == id:
            self._delObject(id)
            break

    if not suppress_events:
        notify(ObjectWillBeAddedEvent(ob, self, id))

    self._objects = self._objects + ({'id': id, 'meta_type': t}, )
    self._setOb(id, ob)
    ob = self._getOb(id)

    if set_owner:
        # TODO: eventify manage_fixupOwnershipAfterAdd
        # This will be called for a copy/clone, or a normal _setObject.
        ob.manage_fixupOwnershipAfterAdd()

    if set_owner:
        # Try to give user the local role "Owner", but only if
        # no local roles have been set on the object yet.
        if getattr(ob, '__ac_local_roles__', _marker) is None:
            user = getSecurityManager().getUser()
            if user is not None:
                userid = user.getId()
                if userid is not None:
                    ob.manage_setLocalRoles(userid, ['Owner'])

    if not suppress_events:
        notify(ObjectAddedEvent(ob, self, id))
        notifyContainerModified(self)

    compatibilityCall('manage_afterAdd', ob, ob, self)

    return id
Beispiel #9
0
    def _delObject(self, id, dp=1, suppress_events=False):
        ob = self._getOb(id)

        compatibilityCall('manage_beforeDelete', ob, ob, self)

        if not suppress_events:
            notify(ObjectWillBeRemovedEvent(ob, self, id))

        self._delOb(id)

        if not suppress_events:
            notify(ObjectRemovedEvent(ob, self, id))
            notifyContainerModified(self)
Beispiel #10
0
    def _delObject(self, id, dp=1, suppress_events=False):
        ob = self._getOb(id)

        compatibilityCall('manage_beforeDelete', ob, ob, self)

        if not suppress_events:
            notify(ObjectWillBeRemovedEvent(ob, self, id))

        self._delOb(id)

        if not suppress_events:
            notify(ObjectRemovedEvent(ob, self, id))
            notifyContainerModified(self)
Beispiel #11
0
    def deleter(self):
        to_delete = []
        container_ids = set(self.context.objectIds())

        try:
            protected = self.context._reserved_names
        except:
            protected = ()

        content = yield
        while content is not None:
            try:
                content.is_deletable()
            except ContentError as error:
                result = error
            else:
                content_id = content.getId()
                if (content_id in container_ids and
                    content_id not in protected and
                    aq_base(self.context) is aq_base(aq_parent(content))):
                    to_delete.append((content_id, content))
                    result = content
                else:
                    result = ContentError(
                        _(u"Cannot delete content."),
                        content)
            content = yield result

        # Event
        for identifier, content in to_delete:
            compatibilityCall('manage_beforeDelete', content, content, self.context)
            notify(ObjectWillBeRemovedEvent(content, self.context, identifier))

        # Delete
        for identifier, content in to_delete:
            self.context._objects = tuple(
                [i for i in self.context._objects if i['id'] != identifier])
            self.context._delOb(identifier)
            try:
                content._v__object_deleted__ = 1
            except:
                pass

        # Event
        for identifier, content in to_delete:
            notify(ObjectRemovedEvent(content, self.context, identifier))

        if to_delete:
            notifyContainerModified(self.context)
Beispiel #12
0
    def deleter(self):
        to_delete = []
        container_ids = set(self.context.objectIds())

        try:
            protected = self.context._reserved_names
        except:
            protected = ()

        content = yield
        while content is not None:
            try:
                content.is_deletable()
            except ContentError as error:
                result = error
            else:
                content_id = content.getId()
                if (content_id in container_ids and content_id not in protected
                        and
                        aq_base(self.context) is aq_base(aq_parent(content))):
                    to_delete.append((content_id, content))
                    result = content
                else:
                    result = ContentError(_("Cannot delete content."), content)
            content = yield result

        # Event
        for identifier, content in to_delete:
            compatibilityCall('manage_beforeDelete', content, content,
                              self.context)
            notify(ObjectWillBeRemovedEvent(content, self.context, identifier))

        # Delete
        for identifier, content in to_delete:
            self.context._objects = tuple(
                [i for i in self.context._objects if i['id'] != identifier])
            self.context._delOb(identifier)
            try:
                content._v__object_deleted__ = 1
            except:
                pass

        # Event
        for identifier, content in to_delete:
            notify(ObjectRemovedEvent(content, self.context, identifier))

        if to_delete:
            notifyContainerModified(self.context)
Beispiel #13
0
 def _setObject(self,
                id,
                object,
                roles=None,
                user=None,
                set_owner=1,
                suppress_events=False):
     """Set an object into this container.
     Also sends IObjectWillBeAddedEvent and IObjectAddedEvent.
     """
     ob = object
     if not suppress_events:
         # notify(ObjectAddedEvent(ob, self, id))
         notifyContainerModified(self)
     compatibilityCall('manage_afterAdd', ob, ob, self)
     return id
Beispiel #14
0
def _setObject(self, id, object, roles=None, user=None, set_owner=1,
               suppress_events=False):
    """Set an object into this container.

    Also sends IObjectAddedEvent.
    """
    ob = object # better name, keep original function signature
    v = self._checkId(id)
    if v is not None:
        id = v
    t = getattr(ob, 'meta_type', None)

    # If an object by the given id already exists, remove it.
    for object_info in self._objects:
        if object_info['id'] == id:
            self._delObject(id)
            break

    if not suppress_events:
        notify(ObjectWillBeAddedEvent(ob, self, id))

    self._objects = self._objects + ({'id': id, 'meta_type': t},)
    self._setOb(id, ob)
    ob = self._getOb(id)

    if set_owner:
        # TODO: eventify manage_fixupOwnershipAfterAdd
        # This will be called for a copy/clone, or a normal _setObject.
        ob.manage_fixupOwnershipAfterAdd()

    if set_owner:
        # Try to give user the local role "Owner", but only if
        # no local roles have been set on the object yet.
        if getattr(ob, '__ac_local_roles__', _marker) is None:
            user = getSecurityManager().getUser()
            if user is not None:
                userid = user.getId()
                if userid is not None:
                    ob.manage_setLocalRoles(userid, ['Owner'])

    if not suppress_events:
        notify(ObjectAddedEvent(ob, self, id))
        notifyContainerModified(self)

    compatibilityCall('manage_afterAdd', ob, ob, self)

    return id
Beispiel #15
0
    def manage_delObjects(self, ids=[], REQUEST=None):
        """Delete objects.
        """
        if isinstance(ids, str):
            ids = [ids]

        try:
            protected = self._reserved_names
        except:
            protected = ()

        deleted_objects = []
        for identifier in ids:
            if identifier in protected:
                continue
            ob = self._getOb(identifier, None)
            if ob is None:
                continue
            deleted_objects.append((identifier, ob))

        for identifier, ob in deleted_objects:
            compatibilityCall('manage_beforeDelete', ob, ob, self)
            notify(ObjectWillBeRemovedEvent(ob, self, identifier))

        for identifier, ob in deleted_objects:
            self._objects = tuple(
                [i for i in self._objects if i['id'] != identifier])
            self._delOb(identifier)
            try:
                ob._v__object_deleted__ = 1
            except:
                pass

        for identifier, ob in deleted_objects:
            notify(ObjectRemovedEvent(ob, self, identifier))

        if deleted_objects:
            notifyContainerModified(self)

        if REQUEST is not None:
            # For ZMI
            REQUEST.RESPONSE.redirect(
                absoluteURL(self, REQUEST) + '/manage_main')
Beispiel #16
0
    def manage_clone(self, ob, id, REQUEST=None):
        """Clone an object, creating a new object with the given id.
        """
        if not ob.cb_isCopyable():
            raise CopyError(eNotSupported % escape(ob.getId()))
        try:
            self._checkId(id)
        except:
            raise CopyError(MessageDialog(
                title='Invalid Id',
                message=sys.exc_info()[1],
                action ='manage_main'))

        self._verifyObjectPaste(ob)

        try:
            ob._notifyOfCopyTo(self, op=0)
        except ConflictError:
            raise
        except:
            raise CopyError(MessageDialog(
                title="Clone Error",
                message=sys.exc_info()[1],
                action='manage_main'))

        orig_ob = ob
        ob = ob._getCopy(self)
        ob._setId(id)
        notify(ObjectCopiedEvent(ob, orig_ob))

        self._setObject(id, ob)
        ob = self._getOb(id)

        ob._postCopy(self, op=0)

        compatibilityCall('manage_afterClone', ob, ob)

        notify(ObjectClonedEvent(ob))

        return ob
Beispiel #17
0
def manage_clone(self, ob, id, REQUEST=None):
    """Clone an object, creating a new object with the given id.
    """
    if not ob.cb_isCopyable():
        raise CopyError, eNotSupported % escape(ob.getId())
    try:
        self._checkId(id)
    except:
        raise CopyError, MessageDialog(
            title='Invalid Id',
            message=sys.exc_info()[1],
            action ='manage_main')

    self._verifyObjectPaste(ob)

    try:
        ob._notifyOfCopyTo(self, op=0)
    except ConflictError:
        raise
    except:
        raise CopyError, MessageDialog(
            title="Clone Error",
            message=sys.exc_info()[1],
            action='manage_main')

    orig_ob = ob
    ob = ob._getCopy(self)
    ob._setId(id)
    notify(ObjectCopiedEvent(ob, orig_ob))

    self._setObject(id, ob)
    ob = self._getOb(id)

    ob._postCopy(self, op=0)

    compatibilityCall('manage_afterClone', ob, ob)

    notify(ObjectClonedEvent(ob))

    return ob
def copyObject(ob, newParent, newName=None):
    """Move an object to a new container.
    """
    oldParent = aq_parent(ob)
    orig_id = ob.getId()
    if not ob.cb_isCopyable():
        raise CopyError(eNotSupported % escape(orig_id))

    try:
        ob._notifyOfCopyTo(newParent, op=0)
    except ConflictError:
        raise
    except:
        raise CopyError(MessageDialog(
            title="Copy Error",
            message=sys.exc_info()[1],
            action='manage_main'))

    if newName is None:
        id = newParent._get_id(orig_id)
    else:
        id = newName

    orig_ob = ob
    ob = ob._getCopy(oldParent)
    ob._setId(id)
    notify(ObjectCopiedEvent(ob, orig_ob))

    newParent._setObject(id, ob)
    ob = newParent._getOb(id)
    ob.wl_clearLocks()

    ob._postCopy(newParent, op=0)

    compatibilityCall('manage_afterClone', ob, ob)

    notify(ObjectClonedEvent(ob))

    return ob
Beispiel #19
0
    def _pasteObjects(self, cp, cb_maxsize=0):
        """Paste previously copied objects into the current object.

        ``cp`` is the list of objects for paste as encoded by ``_cb_encode``.
        If calling _pasteObjects from python code, pass the result of a
        previous call to manage_cutObjects or manage_copyObjects as the first
        argument.

        ``cb_maxsize`` is the maximum size of the JSON representation of the
        object list. Set it to a non-zero value to prevent DoS attacks with
        huge object lists or zlib bombs.

        This method sends IObjectCopiedEvent and IObjectClonedEvent
        or IObjectWillBeMovedEvent and IObjectMovedEvent.

        Returns tuple of (operator, list of {'id': orig_id, 'new_id': new_id}).
        Where `operator` is 0 for a copy operation and 1 for a move operation.
        """
        if cp is None:
            raise CopyError('No clipboard data found.')

        try:
            op, mdatas = _cb_decode(cp, cb_maxsize)
        except Exception as e:
            six.raise_from(CopyError('Clipboard Error'), e)

        oblist = []
        app = self.getPhysicalRoot()
        for mdata in mdatas:
            m = loadMoniker(mdata)
            try:
                ob = m.bind(app)
            except ConflictError:
                raise
            except Exception:
                raise CopyError('Item Not Found')
            self._verifyObjectPaste(ob, validate_src=op + 1)
            oblist.append(ob)

        result = []
        if op == 0:
            # Copy operation
            for ob in oblist:
                orig_id = ob.getId()
                if not ob.cb_isCopyable():
                    raise CopyError('Not Supported')

                try:
                    ob._notifyOfCopyTo(self, op=0)
                except ConflictError:
                    raise
                except Exception:
                    raise CopyError('Copy Error')

                id = self._get_id(orig_id)
                result.append({'id': orig_id, 'new_id': id})

                orig_ob = ob
                ob = ob._getCopy(self)
                ob._setId(id)
                notify(ObjectCopiedEvent(ob, orig_ob))

                self._setObject(id, ob)
                ob = self._getOb(id)
                ob.wl_clearLocks()

                ob._postCopy(self, op=0)

                compatibilityCall('manage_afterClone', ob, ob)

                notify(ObjectClonedEvent(ob))

        elif op == 1:
            # Move operation
            for ob in oblist:
                orig_id = ob.getId()
                if not ob.cb_isMoveable():
                    raise CopyError('Not Supported')

                try:
                    ob._notifyOfCopyTo(self, op=1)
                except ConflictError:
                    raise
                except Exception:
                    raise CopyError('Move Error')

                if not sanity_check(self, ob):
                    raise CopyError("This object cannot be pasted into itself")

                orig_container = aq_parent(aq_inner(ob))
                if aq_base(orig_container) is aq_base(self):
                    id = orig_id
                else:
                    id = self._get_id(orig_id)
                result.append({'id': orig_id, 'new_id': id})

                notify(
                    ObjectWillBeMovedEvent(ob, orig_container, orig_id, self,
                                           id))

                # try to make ownership explicit so that it gets carried
                # along to the new location if needed.
                ob.manage_changeOwnershipType(explicit=1)

                try:
                    orig_container._delObject(orig_id, suppress_events=True)
                except TypeError:
                    orig_container._delObject(orig_id)
                    warnings.warn(
                        "%s._delObject without suppress_events is discouraged."
                        % orig_container.__class__.__name__,
                        DeprecationWarning)
                ob = aq_base(ob)
                ob._setId(id)

                try:
                    self._setObject(id, ob, set_owner=0, suppress_events=True)
                except TypeError:
                    self._setObject(id, ob, set_owner=0)
                    warnings.warn(
                        "%s._setObject without suppress_events is discouraged."
                        % self.__class__.__name__, DeprecationWarning)
                ob = self._getOb(id)

                notify(ObjectMovedEvent(ob, orig_container, orig_id, self, id))
                notifyContainerModified(orig_container)
                if aq_base(orig_container) is not aq_base(self):
                    notifyContainerModified(self)

                ob._postCopy(self, op=1)
                # try to make ownership implicit if possible
                ob.manage_changeOwnershipType(explicit=0)

        return op, result
Beispiel #20
0
    def COPY(self, REQUEST, RESPONSE):
        """Create a duplicate of the source resource whose state
        and behavior match that of the source resource as closely
        as possible. Though we may later try to make a copy appear
        seamless across namespaces (e.g. from Zope to Apache), COPY
        is currently only supported within the Zope namespace."""
        self.dav__init(REQUEST, RESPONSE)
        if not hasattr(aq_base(self), 'cb_isCopyable') or \
           not self.cb_isCopyable():
            raise MethodNotAllowed, 'This object may not be copied.'

        depth=REQUEST.get_header('Depth', 'infinity')
        if not depth in ('0', 'infinity'):
            raise BadRequest, 'Invalid Depth header.'

        dest=REQUEST.get_header('Destination', '')
        while dest and dest[-1]=='/':
            dest=dest[:-1]
        if not dest:
            raise BadRequest, 'Invalid Destination header.'

        try: path = REQUEST.physicalPathFromURL(dest)
        except ValueError:
            raise BadRequest, 'Invalid Destination header'

        name = path.pop()

        oflag=REQUEST.get_header('Overwrite', 'F').upper()
        if not oflag in ('T', 'F'):
            raise BadRequest, 'Invalid Overwrite header.'

        try: parent=self.restrictedTraverse(path)
        except ValueError:
            raise Conflict, 'Attempt to copy to an unknown namespace.'
        except NotFound:
            raise Conflict, 'Object ancestors must already exist.'
        except:
            t, v, tb=sys.exc_info()
            raise t, v
        if hasattr(parent, '__null_resource__'):
            raise Conflict, 'Object ancestors must already exist.'
        existing=hasattr(aq_base(parent), name)
        if existing and oflag=='F':
            raise PreconditionFailed, 'Destination resource exists.'
        try:
            parent._checkId(name, allow_dup=1)
        except:
            raise Forbidden, sys.exc_info()[1]
        try:
            parent._verifyObjectPaste(self)
        except Unauthorized:
            raise
        except:
            raise Forbidden, sys.exc_info()[1]

        # Now check locks.  The If header on a copy only cares about the
        # lock on the destination, so we need to check out the destinations
        # lock status.
        ifhdr = REQUEST.get_header('If', '')
        if existing:
            # The destination itself exists, so we need to check its locks
            destob = aq_base(parent)._getOb(name)
            if IWriteLock.providedBy(destob) and destob.wl_isLocked():
                if ifhdr:
                    itrue = destob.dav__simpleifhandler(
                        REQUEST, RESPONSE, 'COPY', refresh=1)
                    if not itrue:
                        raise PreconditonFailed
                else:
                    raise Locked, 'Destination is locked.'
        elif IWriteLock.providedBy(parent) and parent.wl_isLocked():
            if ifhdr:
                parent.dav__simpleifhandler(REQUEST, RESPONSE, 'COPY',
                                            refresh=1)
            else:
                raise Locked, 'Destination is locked.'

        self._notifyOfCopyTo(parent, op=0)
        ob = self._getCopy(parent)
        ob._setId(name)

        if depth=='0' and isDavCollection(ob):
            for id in ob.objectIds():
                ob._delObject(id)

        notify(ObjectCopiedEvent(ob, self))

        if existing:
            object=getattr(parent, name)
            self.dav__validate(object, 'DELETE', REQUEST)
            parent._delObject(name)

        parent._setObject(name, ob)
        ob = parent._getOb(name)
        ob._postCopy(parent, op=0)

        compatibilityCall('manage_afterClone', ob, ob)

        notify(ObjectClonedEvent(ob))

        # We remove any locks from the copied object because webdav clients
        # don't track the lock status and the lock token for copied resources
        ob.wl_clearLocks()
        RESPONSE.setStatus(existing and 204 or 201)
        if not existing:
            RESPONSE.setHeader('Location', dest)
        RESPONSE.setBody('')
        return RESPONSE
Beispiel #21
0
def manage_pasteObjects_no_events(self, cb_copy_data=None, REQUEST=None):
    """Paste previously copied objects into the current object.
    If calling manage_pasteObjects from python code, pass the result of a
    previous call to manage_cutObjects or manage_copyObjects as the first
    argument.
    Also sends IObjectCopiedEvent and IObjectClonedEvent
    or IObjectWillBeMovedEvent and IObjectMovedEvent.
    """
    anno = IAnnotations(self)
    job_id = anno.get('async_move_job')

    if not REQUEST:
        # Create a request to work with
        REQUEST = create_request()

    if cb_copy_data is not None:
        cp = cb_copy_data
    elif REQUEST is not None and REQUEST.has_key('__cp'):
        cp = REQUEST['__cp']
    else:
        cp = None
    if cp is None:
        raise CopyError(eNoData)

    try:
        op, mdatas = _cb_decode(cp)
    except:
        raise CopyError(eInvalid)

    oblist = []
    app = self.getPhysicalRoot()
    cat = getToolByName(self, 'portal_catalog')

    for mdata in mdatas:
        m = loadMoniker(mdata)
        try:
            ob = m.bind(app)
        except ConflictError:
            raise
        except:
            raise CopyError(eNotFound)
        # self._verifyObjectPaste(ob, validate_src=op+1)
        oblist.append(ob)

    result = []

    steps = oblist and int(100/len(oblist)) or 0

    notify(AsyncMoveSaveProgress(
        self, operation='initialize', job_id=job_id, oblist_id=[
            (o.getId(), o.Title()) for o in oblist
            ]))

    if op == 0:
        # Copy operation
        for i, ob in enumerate(oblist):
            orig_id = ob.getId()
            if not ob.cb_isCopyable():
                raise CopyError(eNotSupported % escape(orig_id))

            oid = self._get_id(orig_id)
            result.append({'id': orig_id, 'new_id': oid})

            notify(AsyncMoveSaveProgress(
                self,
                operation='sub_progress',
                job_id=job_id,
                obj_id=ob.getId(), progress=.25
            ))

            ob = ob._getCopy(self)
            ob._setId(oid)

            notify(AsyncMoveSaveProgress(
                self,
                operation='sub_progress',
                job_id=job_id,
                obj_id=ob.getId(),
                progress=.50
            ))

            self._setObject(oid, ob)
            ob = self._getOb(oid)
            ob.wl_clearLocks()

            notify(AsyncMoveSaveProgress(
                self,
                operation='sub_progress',
                job_id=job_id,
                obj_id=ob.getId(),
                progress=.75
            ))

            ob._postCopy(self, op=0)

            compatibilityCall('manage_afterClone', ob, ob)

            notify(AsyncMoveSaveProgress(
                self,
                operation='sub_progress',
                job_id=job_id,
                obj_id=ob.getId(),
                progress=1
            ))

            notify(AsyncMoveSaveProgress(
                self,
                operation='progress',
                job_id=job_id,
                progress=steps*(i+1)/100
            ))

    if op == 1:
        # Move operation
        for i, ob in enumerate(oblist):
            orig_id = ob.getId()

            if not sanity_check(self, ob):
                raise CopyError(
                    "This object cannot be pasted into itself")

            orig_container = aq_parent(aq_inner(ob))
            if aq_base(orig_container) is aq_base(self):
                oid = orig_id
            else:
                oid = self._get_id(orig_id)
            result.append({'id': orig_id, 'new_id': oid})

            unindex_object(ob, recursive=1)
            # try to make ownership explicit so that it gets carried
            # along to the new location if needed.
            ob.manage_changeOwnershipType(explicit=1)

            notify(AsyncMoveSaveProgress(
                self,
                operation='sub_progress',
                job_id=job_id,
                obj_id=ob.getId(),
                progress=.25
            ))

            try:
                obj_path = '/'.join(
                    orig_container.getPhysicalPath()) + '/' + orig_id
                orig_container._delObject(orig_id, suppress_events=True)
                uncatalog_path = obj_path
                try:
                    uncatalog_objs = cat(path=obj_path)
                    for obj_brain in uncatalog_objs:
                        uncatalog_path = obj_brain.getPath()
                        cat.uncatalog_object(uncatalog_path)
                except AttributeError:
                    logger.warn("%s could not be found", uncatalog_path)
            except TypeError:
                orig_container._delObject(orig_id)
                logger.warn(
                    "%s._delObject without suppress_events is discouraged.",
                    orig_container.__class__.__name__)

            notify(AsyncMoveSaveProgress(
                self,
                operation='sub_progress',
                job_id=job_id,
                obj_id=ob.getId(),
                progress=.50
            ))

            ob = aq_base(ob)
            ob._setId(oid)

            try:
                self._setObject(oid, ob, set_owner=0, suppress_events=True)
            except TypeError:
                self._setObject(oid, ob, set_owner=0)
                logger.warn(
                    "%s._setObject without suppress_events is discouraged.",
                    self.__class__.__name__)
            ob = self._getOb(oid)

            ob._postCopy(self, op=1)
            # try to make ownership implicit if possible
            ob.manage_changeOwnershipType(explicit=0)

            notify(AsyncMoveSaveProgress(
                self,
                operation='sub_progress',
                job_id=job_id,
                obj_id=ob.getId(),
                progress=.75
            ))

            reindex_object(ob, recursive=1)

            notify(AsyncMoveSaveProgress(
                self,
                operation='sub_progress',
                job_id=job_id,
                obj_id=ob.getId(),
                progress=1
            ))

            notify(AsyncMoveSaveProgress(
                self,
                operation='progress',
                job_id=job_id,
                progress=steps*(i+1)/100
            ))

    notify(AsyncMoveSaveProgress(
        self, operation='progress', job_id=job_id,
        progress=1
    ))
    del anno['async_move_job']

    return result
Beispiel #22
0
    def manage_pasteObjects(self, cb_copy_data=None, REQUEST=None):
        """Paste previously copied objects into the current object.

        If calling manage_pasteObjects from python code, pass the result of a
        previous call to manage_cutObjects or manage_copyObjects as the first
        argument.

        Also sends IObjectCopiedEvent and IObjectClonedEvent
        or IObjectWillBeMovedEvent and IObjectMovedEvent.
        """
        cp = cb_copy_data
        if cp is None and REQUEST is not None and '__cp' in REQUEST:
            cp = REQUEST['__cp']
        if cp is None:
            raise CopyError('No clipboard data found.')

        try:
            op, mdatas = _cb_decode(cp)
        except Exception as e:
            six.raise_from(CopyError('Clipboard Error'), e)

        oblist = []
        app = self.getPhysicalRoot()
        for mdata in mdatas:
            m = loadMoniker(mdata)
            try:
                ob = m.bind(app)
            except ConflictError:
                raise
            except Exception:
                raise CopyError('Item Not Found')
            self._verifyObjectPaste(ob, validate_src=op + 1)
            oblist.append(ob)

        result = []
        if op == 0:
            # Copy operation
            for ob in oblist:
                orig_id = ob.getId()
                if not ob.cb_isCopyable():
                    raise CopyError('Not Supported')

                try:
                    ob._notifyOfCopyTo(self, op=0)
                except ConflictError:
                    raise
                except Exception:
                    raise CopyError('Copy Error')

                id = self._get_id(orig_id)
                result.append({'id': orig_id, 'new_id': id})

                orig_ob = ob
                ob = ob._getCopy(self)
                ob._setId(id)
                notify(ObjectCopiedEvent(ob, orig_ob))

                self._setObject(id, ob)
                ob = self._getOb(id)
                ob.wl_clearLocks()

                ob._postCopy(self, op=0)

                compatibilityCall('manage_afterClone', ob, ob)

                notify(ObjectClonedEvent(ob))

            if REQUEST is not None:
                return self.manage_main(self, REQUEST, cb_dataValid=1)

        elif op == 1:
            # Move operation
            for ob in oblist:
                orig_id = ob.getId()
                if not ob.cb_isMoveable():
                    raise CopyError('Not Supported')

                try:
                    ob._notifyOfCopyTo(self, op=1)
                except ConflictError:
                    raise
                except Exception:
                    raise CopyError('Move Error')

                if not sanity_check(self, ob):
                    raise CopyError("This object cannot be pasted into itself")

                orig_container = aq_parent(aq_inner(ob))
                if aq_base(orig_container) is aq_base(self):
                    id = orig_id
                else:
                    id = self._get_id(orig_id)
                result.append({'id': orig_id, 'new_id': id})

                notify(
                    ObjectWillBeMovedEvent(ob, orig_container, orig_id, self,
                                           id))

                # try to make ownership explicit so that it gets carried
                # along to the new location if needed.
                ob.manage_changeOwnershipType(explicit=1)

                try:
                    orig_container._delObject(orig_id, suppress_events=True)
                except TypeError:
                    orig_container._delObject(orig_id)
                    warnings.warn(
                        "%s._delObject without suppress_events is discouraged."
                        % orig_container.__class__.__name__,
                        DeprecationWarning)
                ob = aq_base(ob)
                ob._setId(id)

                try:
                    self._setObject(id, ob, set_owner=0, suppress_events=True)
                except TypeError:
                    self._setObject(id, ob, set_owner=0)
                    warnings.warn(
                        "%s._setObject without suppress_events is discouraged."
                        % self.__class__.__name__, DeprecationWarning)
                ob = self._getOb(id)

                notify(ObjectMovedEvent(ob, orig_container, orig_id, self, id))
                notifyContainerModified(orig_container)
                if aq_base(orig_container) is not aq_base(self):
                    notifyContainerModified(self)

                ob._postCopy(self, op=1)
                # try to make ownership implicit if possible
                ob.manage_changeOwnershipType(explicit=0)

            if REQUEST is not None:
                REQUEST['RESPONSE'].setCookie(
                    '__cp',
                    'deleted',
                    path='%s' % cookie_path(REQUEST),
                    expires='Wed, 31-Dec-97 23:59:59 GMT')
                REQUEST['__cp'] = None
                return self.manage_main(self, REQUEST, cb_dataValid=0)

        return result
    except Exception, e:
        raise e

    orig_obj = obj
    obj = obj._getCopy(target)
    obj._setId(new_id)

    notify(ObjectCopiedEvent(obj, orig_obj))

    target._setObject(new_id, obj)
    obj = target._getOb(new_id)
    obj.wl_clearLocks()

    obj._postCopy(target, op=0)

    subscribers.compatibilityCall('manage_afterClone', obj, obj)

    notify(ObjectClonedEvent(obj))

class EnableRevisionView(BrowserView):
    """ Clone revision view """
    implements(IEnableRevisionView)


    def __call__(self):
        """ Create a new revision folder based on an existing item """
        context_id = self.context.getId()
        parent = getMultiAdapter((self.context, self.request), name=u'plone_context_state').parent()
        try:
            uniqueid = parent.generateUniqueId('Folder')
            uniqueid = parent.invokeFactory('Folder', uniqueid)
Beispiel #24
0
    def COPY(self, REQUEST, RESPONSE):
        """Create a duplicate of the source resource whose state
        and behavior match that of the source resource as closely
        as possible. Though we may later try to make a copy appear
        seamless across namespaces (e.g. from Zope to Apache), COPY
        is currently only supported within the Zope namespace."""
        self.dav__init(REQUEST, RESPONSE)
        if not hasattr(aq_base(self), 'cb_isCopyable') or \
           not self.cb_isCopyable():
            raise MethodNotAllowed('This object may not be copied.')

        depth = REQUEST.get_header('Depth', 'infinity')
        if depth not in ('0', 'infinity'):
            raise BadRequest('Invalid Depth header.')

        dest = REQUEST.get_header('Destination', '')
        while dest and dest[-1] == '/':
            dest = dest[:-1]
        if not dest:
            raise BadRequest('Invalid Destination header.')

        try:
            path = REQUEST.physicalPathFromURL(dest)
        except ValueError:
            raise BadRequest('Invalid Destination header')

        name = path.pop()

        oflag = REQUEST.get_header('Overwrite', 'F').upper()
        if oflag not in ('T', 'F'):
            raise BadRequest('Invalid Overwrite header.')

        try:
            parent = self.restrictedTraverse(path)
        except ValueError:
            raise Conflict('Attempt to copy to an unknown namespace.')
        except NotFound:
            raise Conflict('Object ancestors must already exist.')
        except Exception:
            raise

        if hasattr(parent, '__null_resource__'):
            raise Conflict('Object ancestors must already exist.')
        existing = hasattr(aq_base(parent), name)
        if existing and oflag == 'F':
            raise PreconditionFailed('Destination resource exists.')
        try:
            parent._checkId(name, allow_dup=1)
        except Exception:
            raise Forbidden(sys.exc_info()[1])
        try:
            parent._verifyObjectPaste(self)
        except Unauthorized:
            raise
        except Exception:
            raise Forbidden(sys.exc_info()[1])

        # Now check locks.  The If header on a copy only cares about the
        # lock on the destination, so we need to check out the destinations
        # lock status.
        ifhdr = REQUEST.get_header('If', '')
        if existing:
            # The destination itself exists, so we need to check its locks
            destob = aq_base(parent)._getOb(name)
            if IWriteLock.providedBy(destob) and destob.wl_isLocked():
                if ifhdr:
                    itrue = destob.dav__simpleifhandler(
                        REQUEST, RESPONSE, 'COPY', refresh=1)
                    if not itrue:
                        raise PreconditionFailed()
                else:
                    raise Locked('Destination is locked.')
        elif IWriteLock.providedBy(parent) and parent.wl_isLocked():
            if ifhdr:
                parent.dav__simpleifhandler(REQUEST, RESPONSE, 'COPY',
                                            refresh=1)
            else:
                raise Locked('Destination is locked.')

        self._notifyOfCopyTo(parent, op=0)
        ob = self._getCopy(parent)
        ob._setId(name)

        if depth == '0' and isDavCollection(ob):
            for id in ob.objectIds():
                ob._delObject(id)

        notify(ObjectCopiedEvent(ob, self))

        if existing:
            object = getattr(parent, name)
            self.dav__validate(object, 'DELETE', REQUEST)
            parent._delObject(name)

        parent._setObject(name, ob)
        ob = parent._getOb(name)
        ob._postCopy(parent, op=0)

        compatibilityCall('manage_afterClone', ob, ob)

        notify(ObjectClonedEvent(ob))

        # We remove any locks from the copied object because webdav clients
        # don't track the lock status and the lock token for copied resources
        ob.wl_clearLocks()
        RESPONSE.setStatus(existing and 204 or 201)
        if not existing:
            RESPONSE.setHeader('Location', dest)
        RESPONSE.setBody('')
        return RESPONSE
Beispiel #25
0
def manage_pasteObjects(self, cb_copy_data=None, REQUEST=None):
    """Paste previously copied objects into the current object.

    If calling manage_pasteObjects from python code, pass the result of a
    previous call to manage_cutObjects or manage_copyObjects as the first
    argument.

    Also sends IObjectCopiedEvent or IObjectMovedEvent.
    """
    if cb_copy_data is not None:
        cp = cb_copy_data
    elif REQUEST is not None and REQUEST.has_key('__cp'):
        cp = REQUEST['__cp']
    else:
        cp = None
    if cp is None:
        raise CopyError, eNoData

    try:
        op, mdatas = _cb_decode(cp)
    except:
        raise CopyError, eInvalid

    oblist = []
    app = self.getPhysicalRoot()
    for mdata in mdatas:
        m = Moniker.loadMoniker(mdata)
        try:
            ob = m.bind(app)
        except ConflictError:
            raise
        except:
            raise CopyError, eNotFound
        self._verifyObjectPaste(ob, validate_src=op+1)
        oblist.append(ob)

    result = []
    if op == 0:
        # Copy operation
        for ob in oblist:
            orig_id = ob.getId()
            if not ob.cb_isCopyable():
                raise CopyError, eNotSupported % escape(orig_id)

            try:
                ob._notifyOfCopyTo(self, op=0)
            except ConflictError:
                raise
            except:
                raise CopyError, MessageDialog(
                    title="Copy Error",
                    message=sys.exc_info()[1],
                    action='manage_main')

            id = self._get_id(orig_id)
            result.append({'id': orig_id, 'new_id': id})

            orig_ob = ob
            ob = ob._getCopy(self)
            ob._setId(id)
            notify(ObjectCopiedEvent(ob, orig_ob))

            self._setObject(id, ob)
            ob = self._getOb(id)
            ob.wl_clearLocks()

            ob._postCopy(self, op=0)

            compatibilityCall('manage_afterClone', ob, ob)

            notify(ObjectClonedEvent(ob))

        if REQUEST is not None:
            return self.manage_main(self, REQUEST, update_menu=1,
                                    cb_dataValid=1)

    elif op == 1:
        # Move operation
        for ob in oblist:
            orig_id = ob.getId()
            if not ob.cb_isMoveable():
                raise CopyError, eNotSupported % escape(orig_id)

            try:
                ob._notifyOfCopyTo(self, op=1)
            except ConflictError:
                raise
            except:
                raise CopyError, MessageDialog(
                    title="Move Error",
                    message=sys.exc_info()[1],
                    action='manage_main')

            if not sanity_check(self, ob):
                raise CopyError, "This object cannot be pasted into itself"

            orig_container = aq_parent(aq_inner(ob))
            if aq_base(orig_container) is aq_base(self):
                id = orig_id
            else:
                id = self._get_id(orig_id)
            result.append({'id': orig_id, 'new_id': id})

            notify(ObjectWillBeMovedEvent(ob, orig_container, orig_id,
                                          self, id))

            # try to make ownership explicit so that it gets carried
            # along to the new location if needed.
            ob.manage_changeOwnershipType(explicit=1)

            try:
                orig_container._delObject(orig_id, suppress_events=True)
            except TypeError:
                # BBB: removed in Zope 2.11
                orig_container._delObject(orig_id)
                warnings.warn(
                    "%s._delObject without suppress_events is deprecated "
                    "and will be removed in Zope 2.11." %
                    orig_container.__class__.__name__, DeprecationWarning)
            ob = aq_base(ob)
            ob._setId(id)

            try:
                self._setObject(id, ob, set_owner=0, suppress_events=True)
            except TypeError:
                # BBB: removed in Zope 2.11
                self._setObject(id, ob, set_owner=0)
                warnings.warn(
                    "%s._setObject without suppress_events is deprecated "
                    "and will be removed in Zope 2.11." %
                    self.__class__.__name__, DeprecationWarning)
            ob = self._getOb(id)

            notify(ObjectMovedEvent(ob, orig_container, orig_id, self, id))
            notifyContainerModified(orig_container)
            if aq_base(orig_container) is not aq_base(self):
                notifyContainerModified(self)

            ob._postCopy(self, op=1)
            # try to make ownership implicit if possible
            ob.manage_changeOwnershipType(explicit=0)

        if REQUEST is not None:
            REQUEST['RESPONSE'].setCookie('__cp', 'deleted',
                                path='%s' % cookie_path(REQUEST),
                                expires='Wed, 31-Dec-97 23:59:59 GMT')
            REQUEST['__cp'] = None
            return self.manage_main(self, REQUEST, update_menu=1,
                                    cb_dataValid=0)

    return result
Beispiel #26
0
    def _pasteObjects(self, cp, cb_maxsize=0):
        """Paste previously copied objects into the current object.

        ``cp`` is the list of objects for paste as encoded by ``_cb_encode``.
        If calling _pasteObjects from python code, pass the result of a
        previous call to manage_cutObjects or manage_copyObjects as the first
        argument.

        ``cb_maxsize`` is the maximum size of the JSON representation of the
        object list. Set it to a non-zero value to prevent DoS attacks with
        huge object lists or zlib bombs.

        This method sends IObjectCopiedEvent and IObjectClonedEvent
        or IObjectWillBeMovedEvent and IObjectMovedEvent.

        Returns tuple of (operator, list of {'id': orig_id, 'new_id': new_id}).
        Where `operator` is 0 for a copy operation and 1 for a move operation.
        """
        if cp is None:
            raise CopyError('No clipboard data found.')

        try:
            op, mdatas = _cb_decode(cp, cb_maxsize)
        except Exception as e:
            six.raise_from(CopyError('Clipboard Error'), e)

        oblist = []
        app = self.getPhysicalRoot()
        for mdata in mdatas:
            m = loadMoniker(mdata)
            try:
                ob = m.bind(app)
            except ConflictError:
                raise
            except Exception:
                raise CopyError('Item Not Found')
            self._verifyObjectPaste(ob, validate_src=op + 1)
            oblist.append(ob)

        result = []
        if op == 0:
            # Copy operation
            for ob in oblist:
                orig_id = ob.getId()
                if not ob.cb_isCopyable():
                    raise CopyError('Not Supported')

                try:
                    ob._notifyOfCopyTo(self, op=0)
                except ConflictError:
                    raise
                except Exception:
                    raise CopyError('Copy Error')

                id = self._get_id(orig_id)
                result.append({'id': orig_id, 'new_id': id})

                orig_ob = ob
                ob = ob._getCopy(self)
                ob._setId(id)
                notify(ObjectCopiedEvent(ob, orig_ob))

                self._setObject(id, ob)
                ob = self._getOb(id)
                ob.wl_clearLocks()

                ob._postCopy(self, op=0)

                compatibilityCall('manage_afterClone', ob, ob)

                notify(ObjectClonedEvent(ob))

        elif op == 1:
            # Move operation
            for ob in oblist:
                orig_id = ob.getId()
                if not ob.cb_isMoveable():
                    raise CopyError('Not Supported')

                try:
                    ob._notifyOfCopyTo(self, op=1)
                except ConflictError:
                    raise
                except Exception:
                    raise CopyError('Move Error')

                if not sanity_check(self, ob):
                    raise CopyError("This object cannot be pasted into itself")

                orig_container = aq_parent(aq_inner(ob))
                if aq_base(orig_container) is aq_base(self):
                    id = orig_id
                else:
                    id = self._get_id(orig_id)
                result.append({'id': orig_id, 'new_id': id})

                notify(ObjectWillBeMovedEvent(ob, orig_container, orig_id,
                                              self, id))

                # try to make ownership explicit so that it gets carried
                # along to the new location if needed.
                ob.manage_changeOwnershipType(explicit=1)

                try:
                    orig_container._delObject(orig_id, suppress_events=True)
                except TypeError:
                    orig_container._delObject(orig_id)
                    warnings.warn(
                        "%s._delObject without suppress_events is discouraged."
                        % orig_container.__class__.__name__,
                        DeprecationWarning)
                ob = aq_base(ob)
                ob._setId(id)

                try:
                    self._setObject(id, ob, set_owner=0, suppress_events=True)
                except TypeError:
                    self._setObject(id, ob, set_owner=0)
                    warnings.warn(
                        "%s._setObject without suppress_events is discouraged."
                        % self.__class__.__name__, DeprecationWarning)
                ob = self._getOb(id)

                notify(ObjectMovedEvent(ob, orig_container, orig_id, self, id))
                notifyContainerModified(orig_container)
                if aq_base(orig_container) is not aq_base(self):
                    notifyContainerModified(self)

                ob._postCopy(self, op=1)
                # try to make ownership implicit if possible
                ob.manage_changeOwnershipType(explicit=0)

        return op, result