Ejemplo n.º 1
0
def move_compromisso_para_agendadiaria(event, obj=None):
    """ Toda vez que um tipo compromisso for criado ou tiver sua
        data alterada
        ele sera movido para dentro de uma agenda diaria
    """
    if not obj:
        obj = event.object

    if not ICompromisso.providedBy(obj):  # nao eh um compromisso
        return

    start_date = getattr(obj, 'start_date', None)
    if not start_date:
        return

    formatted_date = start_date.strftime(AGENDADIARIAFMT)
    origin = aq_parent(obj)
    agenda = _get_agenda(origin)

    old_id = obj.getId()
    destination_id = formatted_date

    destination = _get_destination(agenda, obj, origin, destination_id)
    if not IAgendaDiaria.providedBy(destination):
        logger.warn('Objeto %s nao foi movido' % str(obj))
        # Reindexamos o SearchableText de origin
        origin.reindexObject(idxs=[
            'SearchableText',
        ])
        return None

    new_id = _generate_id(destination, old_id)

    # Prepare to move object
    notify(ObjectWillBeMovedEvent(obj, origin, old_id, destination, new_id))
    obj.manage_changeOwnershipType(explicit=1)

    # Remove object from origin
    origin._delObject(old_id, suppress_events=True)
    obj = aq_base(obj)

    # Set new_id -- which is unique on destination
    obj._setId(new_id)

    # Persist object in destination
    destination._setObject(new_id, obj, set_owner=0, suppress_events=True)
    obj = destination._getOb(new_id)
    notify(ObjectMovedEvent(obj, origin, old_id, destination, new_id))
    notifyContainerModified(origin)
    notifyContainerModified(destination)
    obj._postCopy(destination, op=1)
    # try to make ownership implicit if possible
    obj.manage_changeOwnershipType(explicit=0)
    # Reindexamos o SearchableText de destination
    destination.reindexObject(idxs=[
        'SearchableText',
    ])
    def test_integration_object_events(self):
        """ Trigger every event of a objec at least one times
        and check the journalentries.
        """

        dossier1 = create(Builder('dossier'))
        dossier2 = create(Builder('dossier'))

        document = create(
            Builder('document').within(dossier1).titled(u'Document'))
        document2 = create(
            Builder('document').within(dossier2).titled(u'Document'))

        notify(
            ObjectMovedEvent(
                document,
                dossier1,
                'oldName',
                dossier2,
                'newName',
            ))
        self.check_annotation(
            dossier1,
            action_type='Object moved',
            action_title='Object moved: %s' % document.title_or_id(),
        )

        # Test that a normal ObjectAddedEvent does not result in an object
        # moved journal entry.
        notify(ObjectAddedEvent(document2))
        entry1 = get_journal_entry(dossier2, entry=-1)
        entry2 = get_journal_entry(dossier2, entry=-2)
        self.assertTrue(entry1.get('action').get('type') != 'Object moved')
        self.assertTrue(entry2.get('action').get('type') != 'Object moved')

        notify(
            ObjectWillBeMovedEvent(
                document,
                dossier1,
                'oldName',
                dossier2,
                'newName',
            ))
        self.check_annotation(dossier1,
                              action_type='Object cut',
                              action_title='Object cut: %s' %
                              document.title_or_id())

        # Here we don't have a journal-entry
        length = get_journal_length(dossier1)
        notify(ObjectWillBeAddedEvent(
            document,
            dossier2,
            'newName',
        ))
        self.assertTrue(length == get_journal_length(dossier1))
Ejemplo n.º 3
0
    def manage_renameObject(self, id, new_id, REQUEST=None):
        """Rename a particular sub-object.
        """
        try:
            self._checkId(new_id)
        except Exception:
            raise CopyError('Invalid Id')

        ob = self._getOb(id)

        if ob.wl_isLocked():
            raise ResourceLockedError('Object "%s" is locked' % ob.getId())
        if not ob.cb_isMoveable():
            raise CopyError('Not Supported')
        self._verifyObjectPaste(ob)

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

        notify(ObjectWillBeMovedEvent(ob, self, id, self, new_id))

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

        # Note - because a rename always keeps the same context, we
        # can just leave the ownership info unchanged.
        try:
            self._setObject(new_id, ob, set_owner=0, suppress_events=True)
        except TypeError:
            self._setObject(new_id, ob, set_owner=0)
            warnings.warn(
                "%s._setObject without suppress_events is discouraged." %
                self.__class__.__name__, DeprecationWarning)
        ob = self._getOb(new_id)

        notify(ObjectMovedEvent(ob, self, id, self, new_id))
        notifyContainerModified(self)

        ob._postCopy(self, op=1)

        if REQUEST is not None:
            return self.manage_main(self, REQUEST)
Ejemplo n.º 4
0
    def manage_renameObjects(self, ids=[], new_ids=[]):
        """Rename reflected files or directories
        
        The objects specified in 'ids' get renamed to 'new_ids'. This emulates 
        the CopyContainer interface enough to support renaming in Plone only.
        When file renaming fails, errors are communicated through the return
        of the successful ids and the IStatusMessage utility
        
        """
        if len(ids) != len(new_ids):
            raise BadRequest('Please rename each listed object.')
        if not ids:
            raise ValueError('No items specified')

        # To avoid inconsistencies, first test file availability
        for old, new in zip(ids, new_ids):
            if not self.has_key(old):
                raise KeyError(old)
            if not self.acceptableFilename(new) or self.has_key(new):
                raise CopyError, 'Invalid Id'
            notify(ObjectWillBeMovedEvent(self[old], self, old, self, new))

        problem_ids = []
        path = self.getFilesystemPath()
        for id in ids:
            try:
                os.rename(os.path.join(path, old), os.path.join(path, new))
                notify(ObjectMovedEvent(self[new], self, old, self, new))
            except OSError:
                problem_ids.append(old)

        if problem_ids:
            sm = IStatusMessage(getattr(self, 'REQUEST', None), None)
            if sm is not None:
                sm.addStatusMessage(
                    'Failed to rename some files: %s' % problem_ids, 'stop')

        if set(ids) - set(problem_ids):
            indexview = self.unrestrictedTraverse('@@index')
            indexview.index()
            notifyContainerModified(self)

        return list(set(ids) - set(problem_ids))
Ejemplo n.º 5
0
    def __move(self, content, from_container, from_identifier, to_identifier):
        # Move a content into the container
        notify(
            ObjectWillBeMovedEvent(content, from_container, from_identifier,
                                   self.context, to_identifier))

        from_container._delObject(from_identifier, suppress_events=True)

        content = aq_base(content)
        content._setId(to_identifier)

        self.context._setObject(to_identifier,
                                content,
                                set_owner=0,
                                suppress_events=True)

        content = self.context._getOb(to_identifier)

        notify(
            ObjectMovedEvent(content, from_container, from_identifier,
                             self.context, to_identifier))
        return content
Ejemplo n.º 6
0
def move_obj(ob, destination):
    """
    This function has the same effect as:

        id = obj.getId()
        cp = origin.manage_cutObjects(id)
        destination.manage_pasteObjects(cp)

    but with slightly better performance and **without permission checks**. The
    code is mostly grabbed from OFS.CopySupport.CopyContainer_pasteObjects
    """
    id = ob.getId()

    # Notify the object will be copied to destination
    ob._notifyOfCopyTo(destination, op=1)

    # Notify that the object will be moved
    origin = aq_parent(aq_inner(ob))
    notify(ObjectWillBeMovedEvent(ob, origin, id, destination, id))

    # Effectively move the object from origin to destination
    origin._delObject(id, suppress_events=True)
    ob = aq_base(ob)
    destination._setObject(id, ob, set_owner=0, suppress_events=True)
    ob = destination._getOb(id)

    # Since we used "suppress_events=True", we need to manually notify that the
    # object has been moved and containers modified. This also makes the objects
    # to be re-catalogued
    notify(ObjectMovedEvent(ob, origin, id, destination, id))
    notifyContainerModified(origin)
    notifyContainerModified(destination)

    # Try to make ownership implicit if possible, so it acquires the permissions
    # from the container
    ob.manage_changeOwnershipType(explicit=0)
    return ob
Ejemplo n.º 7
0
    def MOVE(self, REQUEST, RESPONSE):
        """Move a resource to a new location. Though we may later try to
        make a move appear seamless across namespaces (e.g. from Zope
        to Apache), MOVE is currently only supported within the Zope
        namespace."""
        self.dav__init(REQUEST, RESPONSE)
        self.dav__validate(self, 'DELETE', REQUEST)
        if not hasattr(aq_base(self), 'cb_isMoveable') or \
           not self.cb_isMoveable():
            raise MethodNotAllowed('This object may not be moved.')

        dest = REQUEST.get_header('Destination', '')

        try:
            path = REQUEST.physicalPathFromURL(dest)
        except ValueError:
            raise BadRequest('No destination given')

        flag = REQUEST.get_header('Overwrite', 'F')
        flag = flag.upper()

        name = path.pop()
        parent_path = '/'.join(path)

        try:
            parent = self.restrictedTraverse(path)
        except ValueError:
            raise Conflict('Attempt to move to an unknown namespace.')
        except 'Not Found':
            raise Conflict('The resource %s must exist.' % parent_path)
        except Exception:
            raise

        if hasattr(parent, '__null_resource__'):
            raise Conflict('The resource %s must exist.' % parent_path)
        existing = hasattr(aq_base(parent), name)
        if existing and flag == 'F':
            raise PreconditionFailed('Resource %s exists.' % dest)
        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.  Since we're affecting the resource that we're
        # moving as well as the destination, we have to check both.
        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, 'MOVE', url=dest, refresh=1)
                    if not itrue:
                        raise PreconditionFailed
                else:
                    raise Locked('Destination is locked.')
        elif IWriteLock.providedBy(parent) and parent.wl_isLocked():
            # There's no existing object in the destination folder, so
            # we need to check the folders locks since we're changing its
            # member list
            if ifhdr:
                itrue = parent.dav__simpleifhandler(REQUEST, RESPONSE, 'MOVE',
                                                    col=1, url=dest, refresh=1)
                if not itrue:
                    raise PreconditionFailed('Condition failed.')
            else:
                raise Locked('Destination is locked.')
        if wl_isLocked(self):
            # Lastly, we check ourselves
            if ifhdr:
                itrue = self.dav__simpleifhandler(REQUEST, RESPONSE, 'MOVE',
                                                  refresh=1)
                if not itrue:
                    raise PreconditionFailed('Condition failed.')
            else:
                raise Locked('Source is locked and no condition was passed in')

        orig_container = aq_parent(aq_inner(self))
        orig_id = self.getId()

        self._notifyOfCopyTo(parent, op=1)

        notify(ObjectWillBeMovedEvent(self, orig_container, orig_id,
                                      parent, name))

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

        ob = self._getCopy(parent)
        ob._setId(name)

        orig_container._delObject(orig_id, suppress_events=True)

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

        parent._setObject(name, ob, set_owner=0, suppress_events=True)
        ob = parent._getOb(name)

        notify(ObjectMovedEvent(ob, orig_container, orig_id, parent, name))
        notifyContainerModified(orig_container)
        if aq_base(orig_container) is not aq_base(parent):
            notifyContainerModified(parent)

        ob._postCopy(parent, op=1)

        # try to make ownership implicit if possible
        ob.manage_changeOwnershipType(explicit=0)

        RESPONSE.setStatus(existing and 204 or 201)
        if not existing:
            RESPONSE.setHeader('Location', dest)
        RESPONSE.setBody('')
        return RESPONSE
Ejemplo n.º 8
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
Ejemplo n.º 9
0
    def test_integration_object_events(self):
        """ Trigger every event of a objec at least one times
        and check the journalentries.
        """
        portal = self.layer['portal']

        dossier1 = createContentInContainer(
            portal, 'opengever.dossier.businesscasedossier', 'd1')
        dossier2 = createContentInContainer(
            portal, 'opengever.dossier.businesscasedossier', 'd2')

        document = createContentInContainer(dossier1,
                                            'opengever.document.document',
                                            'doc1',
                                            title='Document')

        document2 = createContentInContainer(dossier2,
                                             'opengever.document.document',
                                             'doc2',
                                             title='Document2')

        notify(
            ObjectMovedEvent(
                document,
                dossier1,
                'oldName',
                dossier2,
                'newName',
            ))
        self.check_annotation(
            dossier1,
            action_type='Object moved',
            action_title='Object moved: %s' % document.title_or_id(),
        )

        # Test that a normal ObjectAddedEvent does not result in an object
        # moved journal entry.
        notify(ObjectAddedEvent(document2))
        entry1 = get_journal_entry(dossier2, entry=-1)
        entry2 = get_journal_entry(dossier2, entry=-2)
        self.assertTrue(entry1.get('action').get('type') != 'Object moved')
        self.assertTrue(entry2.get('action').get('type') != 'Object moved')

        notify(
            ObjectWillBeMovedEvent(
                document,
                dossier1,
                'oldName',
                dossier2,
                'newName',
            ))
        self.check_annotation(
            dossier1,
            action_type='Object cut',
            action_title='Object cut: %s' % document.title_or_id(),
        )

        # Here we don't have a journal-entry
        length = get_journal_length(dossier1)
        notify(ObjectWillBeAddedEvent(
            document,
            dossier2,
            'newName',
        ))
        self.assertTrue(length == get_journal_length(dossier1))
Ejemplo n.º 10
0
class MoveActionExecutor(object):
    """The executor for this action.
    """
    implements(IExecutable)
    adapts(Interface, IMoveAction, Interface)

    def __init__(self, context, element, event):
        self.context = context
        self.element = element
        self.event = event

    def __call__(self):
        portal_url = getToolByName(self.context, 'portal_url', None)
        if portal_url is None:
            return False

        obj = self.event.object
        parent = aq_parent(aq_inner(obj))

        path = self.element.target_folder
        if len(path) > 1 and path[0] == '/':
            path = path[1:]
        target = portal_url.getPortalObject().unrestrictedTraverse(
            str(path), None)

        if target is None:
            self.error(
                obj,
                _(u"Target folder ${target} does not exist.",
                  mapping={'target': path}))
            return False

        if target.absolute_url() == parent.absolute_url():
            # We're already here!
            return True

        try:
            obj._notifyOfCopyTo(target, op=1)
        except ConflictError:
            raise
        except Exception, e:
            self.error(obj, str(e))
            return False

        # Are we trying to move into the same container that we copied from?
        if not sanity_check(target, obj):
            return False

        old_id = obj.getId()
        new_id = self.generate_id(target, old_id)

        notify(ObjectWillBeMovedEvent(obj, parent, old_id, target, new_id))

        obj.manage_changeOwnershipType(explicit=1)

        try:
            parent._delObject(old_id, suppress_events=True)
        except TypeError:
            # BBB: removed in Zope 2.11
            parent._delObject(old_id)

        obj = aq_base(obj)
        obj._setId(new_id)

        try:
            target._setObject(new_id, obj, set_owner=0, suppress_events=True)
        except TypeError:
            # BBB: removed in Zope 2.11
            target._setObject(new_id, obj, set_owner=0)
        obj = target._getOb(new_id)

        notify(ObjectMovedEvent(obj, parent, old_id, target, new_id))
        notifyContainerModified(parent)
        if aq_base(parent) is not aq_base(target):
            notifyContainerModified(target)

        obj._postCopy(target, op=1)

        # try to make ownership implicit if possible
        obj.manage_changeOwnershipType(explicit=0)

        return True
Ejemplo n.º 11
0
def unrestricted_move(self, ob):
    """Move an object from one container to another bypassing certain
    checks."""
    orig_id = ob.getId()
    if not ob.cb_isMoveable():
        raise CopyError('Not supported {}'.format(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)

    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)
Ejemplo n.º 12
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
Ejemplo n.º 13
0
    def MOVE(self, REQUEST, RESPONSE):
        """Move a resource to a new location within the reflector"""
        self.dav__init(REQUEST, RESPONSE)
        self.dav__validate(self, 'DELETE', REQUEST)
        if not hasattr(aq_base(self), 'cb_isMoveable') or \
           not self.cb_isMoveable():
            raise MethodNotAllowed, 'This object may not be moved.'

        dest = REQUEST.get_header('Destination', '')

        try:
            path = REQUEST.physicalPathFromURL(dest)
        except ValueError:
            raise BadRequest, 'No destination given'

        flag = REQUEST.get_header('Overwrite', 'F')
        flag = flag.upper()

        name = path.pop()
        parent_path = '/'.join(path)

        try:
            parent = self.restrictedTraverse(path)
        except ValueError:
            raise Conflict, 'Attempt to move to an unknown namespace.'
        except 'Not Found':
            raise Conflict, 'The resource %s must exist.' % parent_path
        except:
            t, v, tb = sys.exc_info()
            raise t, v
        if hasattr(parent, '__null_resource__'):
            raise Conflict, 'The resource %s must exist.' % parent_path
        existing = hasattr(aq_base(parent), name)
        if existing and flag == 'F':
            raise PreconditionFailed, 'Resource %s exists.' % dest
        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.  Since we're affecting the resource that we're
        # moving as well as the destination, we have to check both.
        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,
                                                        'MOVE',
                                                        url=dest,
                                                        refresh=1)
                    if not itrue:
                        raise PreconditionFailed
                else:
                    raise Locked, 'Destination is locked.'
        elif IWriteLock.providedBy(parent) and parent.wl_isLocked():
            # There's no existing object in the destination folder, so
            # we need to check the folders locks since we're changing its
            # member list
            if ifhdr:
                itrue = parent.dav__simpleifhandler(REQUEST,
                                                    RESPONSE,
                                                    'MOVE',
                                                    col=1,
                                                    url=dest,
                                                    refresh=1)
                if not itrue:
                    raise PreconditionFailed, 'Condition failed.'
            else:
                raise Locked, 'Destination is locked.'
        if Lockable.wl_isLocked(self):
            # Lastly, we check ourselves
            if ifhdr:
                itrue = self.dav__simpleifhandler(REQUEST,
                                                  RESPONSE,
                                                  'MOVE',
                                                  refresh=1)
                if not itrue:
                    raise PreconditionFailed, 'Condition failed.'
            else:
                raise PreconditionFailed, 'Source is locked and no '\
                      'condition was passed in.'

        orig_container = aq_parent(aq_inner(self))
        orig_id = self.getId()

        self._notifyOfCopyTo(parent, op=1)

        #### This part is reflecto specific
        notify(
            ObjectWillBeMovedEvent(self, orig_container, orig_id, parent,
                                   name))
        self.unindexObject()
        if existing:
            object = parent[name]
            self.dav__validate(object, 'DELETE', REQUEST)
            parent.manage_delObjects([name])

        os.rename(self.getFilesystemPath(),
                  os.path.join(parent.getFilesystemPath(), name))
        ob = parent[name]
        ob.indexObject()
        ####

        notify(ObjectMovedEvent(ob, orig_container, orig_id, parent, name))
        notifyContainerModified(orig_container)
        if aq_base(orig_container) is not aq_base(parent):
            notifyContainerModified(parent)

        RESPONSE.setStatus(existing and 204 or 201)
        if not existing:
            RESPONSE.setHeader('Location', dest)
        RESPONSE.setBody('')
        return RESPONSE
Ejemplo n.º 14
0
    def manage_renameObject(self, id, new_id, REQUEST=None):
        """Rename a particular sub-object.
        """
        try:
            self._checkId(new_id)
        except:
            raise CopyError, MessageDialog(
                title='Invalid Id',
                message=sys.exc_info()[1],
                action ='manage_main')

        ob = self._getOb(id)

        if ob.wl_isLocked():
            raise ResourceLockedError, ('Object "%s" is locked via WebDAV'
                                        % ob.getId())
        if not ob.cb_isMoveable():
            raise CopyError, eNotSupported % escape(id)
        self._verifyObjectPaste(ob)

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

        notify(ObjectWillBeMovedEvent(ob, self, id, self, new_id))

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

        # Note - because a rename always keeps the same context, we
        # can just leave the ownership info unchanged.
        try:
            self._setObject(new_id, ob, set_owner=0, suppress_events=True)
        except TypeError:
            # BBB: removed in Zope 2.11
            self._setObject(new_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(new_id)

        notify(ObjectMovedEvent(ob, self, id, self, new_id))
        notifyContainerModified(self)

        ob._postCopy(self, op=1)

        if REQUEST is not None:
            return self.manage_main(self, REQUEST, update_menu=1)
        return None
Ejemplo n.º 15
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.
        """
        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)

                OFS.subscribers.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
Ejemplo n.º 16
0
    def manage_pasteObjects(self, cp):
        """Paste previously copied objects into the current object."""
        op, mdatas = _cb_decode(cp)
        COPY = op == 0  # Otherwise its a paste operation

        # Copy or paste always fails without write permission here
        sman = getSecurityManager()
        if not sman.checkPermission(AddFilesystemObject, self):
            raise CopyError, 'Insufficient Privileges'

        oblist = []
        app = self.getPhysicalRoot()

        # Loading and security checks
        for mdata in mdatas:
            m = loadMoniker(mdata)
            try:
                ob = m.bind(app)
            except ConflictError:
                raise
            except:
                raise CopyError, 'Item not found'
            if not IReflectoProxy.providedBy(ob) or IReflector.providedBy(ob):
                raise CopyError, 'Cannot paste into this object'
            parent = aq_parent(aq_inner(ob))
            if not sman.validate(None, parent, None, ob):
                raise Unauthorized(ob.getId())
            if not COPY:
                if not sman.checkPermission(DeleteObjects, parent):
                    raise Unauthorized('Delete not allowed')
                prefix = os.path.commonprefix(
                    (ob.getFilesystemPath(), self.getFilesystemPath()))
                if prefix == ob.getFilesystemPath():
                    raise CopyError, "This object cannot be pasted into itself"
            oblist.append(ob)

        result = []
        problem_ids = []
        path = self.getFilesystemPath()
        for ob in oblist:
            old = ob.getId()
            new = self._generate_copy_id(old)
            result.append(dict(id=old, new_id=new))
            oldpath = ob.getFilesystemPath()
            newpath = os.path.join(path, new)

            if COPY:
                try:
                    if IReflectoDirectory.providedBy(ob):
                        shutil.copytree(oldpath, newpath)
                    else:
                        shutil.copy2(oldpath, newpath)
                    notify(ObjectCopiedEvent(self[new], ob))
                    notify(ObjectClonedEvent(self[new]))
                except EnvironmentError:
                    problem_ids.append(result.pop())
            else:
                # paste/move
                oldparent = aq_parent(aq_inner(ob))
                notify(ObjectWillBeMovedEvent(ob, oldparent, old, self, new))

                if aq_base(self) is aq_base(oldparent):
                    # No need to move from self to self
                    result[-1]['new_id'] = old
                    # Original CopyContainer does emit events for this case
                    notify(ObjectMovedEvent(ob, self, old, self, old))
                    continue

                try:
                    shutil.move(oldpath, newpath)
                    indexview = oldparent.unrestrictedTraverse('@@index')
                    indexview.index()
                    notify(
                        ObjectMovedEvent(self[new], oldparent, old, self, new))
                    notifyContainerModified(oldparent)
                except EnvironmentError:
                    if os.path.exists(newpath):
                        # partial move
                        try:
                            if os.path.isdir(newpath):
                                shutil.rmtree(newpath)
                            else:
                                os.unlink(newpath)
                        except EnvironmentError:
                            pass  # Really weird access issues, time to bail
                    problem_ids.append(result.pop())

        if problem_ids:
            sm = IStatusMessage(getattr(self, 'REQUEST', None), None)
            if sm is not None:
                sm.addStatusMessage(
                    'Failed to copy or paste some files: %s' % problem_ids,
                    'stop')

        if result:
            indexview = self.unrestrictedTraverse('@@index')
            indexview.index()
            notifyContainerModified(self)

        return result