Example #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)
Example #2
0
    def move(self, pos):
        """ AJAX method to change field position within its schema.
        The position is relative to the fieldset.
        """
        schema = IEditableSchema(self.schema)
        fieldname = self.field.__name__
        pos = int(pos)


        ordered_field_ids = [name for (name, field) in sortedFields(self.schema)]
        for fieldset in self.schema.getTaggedValue(FIELDSETS_KEY):
            # if we are in a fieldset, pos is the position relative to the fieldset
            if fieldname in fieldset.fields:
                old_field_of_position = fieldset.fields[pos]
                absolute_position = ordered_field_ids.index(old_field_of_position)
                break
        else:
            # in default fieldset, the relative position == the absolute position
            fieldset = None
            absolute_position = pos

        schema.moveField(fieldname, absolute_position)
        # if field is in a fieldset, also reorder fieldset tagged value
        ordered_field_ids = [name for (name, field) in sortedFields(self.schema)]
        if fieldset is not None:
            fieldset.fields = sorted(fieldset.fields,
                                     key=lambda x: ordered_field_ids.index(x))

        notifyContainerModified(self.schema)
        notify(SchemaModifiedEvent(self.aq_parent.aq_parent))
Example #3
0
    def move(self, pos, fieldset_index):
        """ AJAX method to change field position within its schema.
        The position is relative to the fieldset.
        """
        schema = IEditableSchema(self.schema)
        fieldname = self.field.__name__
        pos = int(pos)
        fieldset_index = int(fieldset_index)
        fieldset_index -= 1  # index 0 is default fieldset

        fieldsets = self.schema.queryTaggedValue(FIELDSETS_KEY, [])
        new_fieldset = fieldset_index >= 0 and fieldsets[
            fieldset_index] or None
        schema.changeFieldFieldset(fieldname, new_fieldset)

        ordered_field_ids = [info[0] for info in sortedFields(self.schema)]
        if new_fieldset:
            old_field_of_position = new_fieldset.fields[pos]
            new_absolute_position = ordered_field_ids.index(
                old_field_of_position)
        else:
            new_absolute_position = pos

        # if fieldset changed, update fieldsets
        schema.moveField(fieldname, new_absolute_position)

        notifyContainerModified(self.schema)
        notify(SchemaModifiedEvent(self.__parent__.__parent__))
Example #4
0
    def mover(self):
        any_moves = False

        def do_move(from_container, content):
            from_identifier = content.getId()
            to_identifier = self.__make_id('move', from_identifier)

            content = self.__move(
                content, from_container, from_identifier, to_identifier)

            content.manage_changeOwnershipType(explicit=0)

            notifyContainerModified(from_container)
            return content

        content = yield
        while content is not None:
            result = self.__verify_moveable(content)
            if result is None:
                from_container = aq_parent(aq_inner(content))
                if (aq_base(from_container) is not aq_base(self.context)):
                    result = do_move(from_container, content)
                    any_moves = True
                else:
                    result = ContainerError(
                        _(u"Content already in the target container."),
                        content)

            content = yield result

        if any_moves:
            notifyContainerModified(self.context)
Example #5
0
 def __setitem__(self, key, value):
     if not key:
         raise ValueError("empty names are not allowed")
     object, event = containedEvent(value, self, key)
     self._setitemf(key, value)
     if event:
         notify(event)
         notifyContainerModified(self)
Example #6
0
 def _delObject(self, id):
     object = self._getOb(id)
     notify(ObjectWillBeRemovedEvent(object, self, id))
     if hasattr(aq_base(object), 'manage_beforeDelete'):
         object.manage_beforeDelete(object, self)
     self._delOb(id)
     notify(ObjectRemovedEvent(object, self, id))
     notifyContainerModified(self)
Example #7
0
 def move(self, pos):
     """ AJAX method to change field position within its schema.
     """
     
     schema = IEditableSchema(self.schema)
     fieldname = self.field.__name__
     schema.moveField(fieldname, int(pos))
     notifyContainerModified(self.schema)
     notify(SchemaModifiedEvent(self.aq_parent.aq_parent))
    def change(self, fieldset_index):
        """ AJAX method to change the fieldset of a field
        """
        fieldset_index = int(fieldset_index)
        fieldsets = self.schema.getTaggedValue(FIELDSETS_KEY)
        field_name = self.field.__name__

        # get current fieldset
        fieldset_fields = []
        current_fieldset = None
        for fieldset in fieldsets:
            if field_name in fieldset.fields:
                current_fieldset = fieldset

            fieldset_fields.extend(fieldset.fields)

        # get future fieldset
        if len(sortedFields(self.schema)) != len(fieldset_fields):
            # we have a default fieldset
            fieldset_index -= 1

        if fieldset_index >= 0:
            # the field has not been moved into default
            next_fieldset = fieldsets[fieldset_index]
        else:
            next_fieldset = None

        # computing new Position, which is the last position of the new fieldset
        ordered_field_ids = [name for (name, field) in sortedFields(self.schema)]
        if next_fieldset is None:
            # if this is the default,
            new_position = ordered_field_ids.index(fieldset_fields[0])
        else:
            # first we get the first of the fieldsets after the new one
            new_position = None
            for fieldset in fieldsets[fieldsets.index(next_fieldset)+1:]:
                if len(fieldset.fields) > 0:
                    new_position = ordered_field_ids.index(fieldset.fields[0]) - 1
                    break
            else:
                new_position = len(ordered_field_ids) - 1

        schema = IEditableSchema(self.schema)
        schema.moveField(field_name, new_position)

        # move field
        if next_fieldset is not None:
            next_fieldset.fields.append(field_name)

        if current_fieldset is not None:
            current_fieldset.fields.remove(field_name)

        notifyContainerModified(self.schema)
        notify(SchemaModifiedEvent(self.aq_parent.aq_parent))
Example #9
0
    def moveObjectsByDelta(
        self,
        ids,
        delta,
        subset_ids=None,
        suppress_events=False
    ):
        """Move specified sub-objects by delta."""
        if isinstance(ids, basestring):
            ids = (ids,)
        min_position = 0
        objects = list(self._objects)
        if subset_ids is None:
            subset_ids = self.getIdsSubset(objects)
        else:
            subset_ids = list(subset_ids)
        # unify moving direction
        if delta > 0:
            ids = list(ids)
            ids.reverse()
            subset_ids.reverse()
        counter = 0

        for id in ids:
            old_position = subset_ids.index(id)
            new_position = max(old_position - abs(delta), min_position)
            if new_position == min_position:
                min_position += 1
            if not old_position == new_position:
                subset_ids.remove(id)
                subset_ids.insert(new_position, id)
                counter += 1

        if counter > 0:
            if delta > 0:
                subset_ids.reverse()
            obj_dict = {}
            for obj in objects:
                obj_dict[obj['id']] = obj
            pos = 0
            for i in range(len(objects)):
                if objects[i]['id'] in subset_ids:
                    try:
                        objects[i] = obj_dict[subset_ids[pos]]
                        pos += 1
                    except KeyError:
                        raise ValueError('The object with the id "%s" does '
                                         'not exist.' % subset_ids[pos])
            self._objects = tuple(objects)

        if not suppress_events:
            notifyContainerModified(self)

        return counter
Example #10
0
        def do_move(from_container, content):
            from_identifier = content.getId()
            to_identifier = self.__make_id('move', from_identifier)

            content = self.__move(
                content, from_container, from_identifier, to_identifier)

            content.manage_changeOwnershipType(explicit=0)

            notifyContainerModified(from_container)
            return content
Example #11
0
    def set_container_order(self, order):
        if not isinstance(order, ListType) and \
            not isinstance(order, TupleType):
            raise TypeError('order must be a tuple or a list.')

        for i in order:
            if i not in self:
                raise ValueError('order item not in container.')

        self._container_order = PersistentList(order)
        notifyContainerModified(self)
Example #12
0
 def _setObject(self, id, object, suppress_events=False):
     if not suppress_events:
         notify(ObjectWillBeAddedEvent(object, self, id))
     self._setOb(id, object)
     object = self._getOb(id)
     if hasattr(aq_base(object), 'manage_afterAdd'):
         object.manage_afterAdd(object, self)
     if not suppress_events:
         notify(ObjectAddedEvent(object, self, id))
         notifyContainerModified(self)
     return object
Example #13
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)
 def moveObjectsByDelta(self, ids, delta, subset_ids=None,  # noqa: C901 FIXME
                        suppress_events=False):
     """Move the specified ids (a sequence, or a single string id) by the
     given delta (a positive or negative number). By default, this moves the
     objects within the whole set of sub-items in the context container, but
     if subset_ids is specified, it gives a subset of ids to consider.
     Should return the number of objects that changed position.
     """
     # changes for reverse ordering are marked with "# reversed"
     delta = -delta  # reversed
     order = self._order()
     pos = self._pos()
     min_position = 0
     if isinstance(ids, basestring):
         ids = [ids]
     if subset_ids is None:
         # delegate to default implementation
         subset_ids = super(ReversedOrdering, self).idsInOrder()  # reversed
     elif not isinstance(subset_ids, list):
         subset_ids = list(subset_ids)
     subset_ids.reverse()  # reversed
     if delta > 0:  # unify moving direction
         ids = reversed(ids)
         subset_ids.reverse()
     counter = 0
     for id in ids:
         try:
             old_position = subset_ids.index(id)
         except ValueError:
             continue
         new_position = max(old_position - abs(delta), min_position)
         if new_position == min_position:
             min_position += 1
         if not old_position == new_position:
             subset_ids.remove(id)
             subset_ids.insert(new_position, id)
             counter += 1
     if counter > 0:
         if delta > 0:
             subset_ids.reverse()
         idx = 0
         for i in range(len(order)):
             if order[i] in subset_ids:
                 id = subset_ids[idx]
                 try:
                     order[i] = id
                     pos[id] = i
                     idx += 1
                 except KeyError:
                     raise ValueError('No object with id "{0}" exists.'.format(id))
     if not suppress_events:
         notifyContainerModified(self.context)
     return counter
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', ])
Example #16
0
    def __iter__(self):
        # Store positions in a mapping containing an id to position mapping for
        # each parent path {parent_path: {item_id: item_pos}}.
        positions_mapping = {}
        for item in self.previous:
            keys = item.keys()
            pathkey = self.pathkey(*keys)[0]
            poskey = self.poskey(*keys)[0]
            if not (pathkey and poskey):
                yield item
                continue

            item_id = item[pathkey].split('/')[-1]
            parent_path = '/'.join(item[pathkey].split('/')[:-1])
            if parent_path not in positions_mapping:
                positions_mapping[parent_path] = {}
            positions_mapping[parent_path][item_id] = item[poskey]

            yield item

        # Set positions on every parent
        for path, positions in positions_mapping.items():

            # Normalize positions
            ordered_keys = sorted(positions.keys(), key=lambda x: positions[x])
            normalized_positions = {}
            for pos, key in enumerate(ordered_keys):
                normalized_positions[key] = pos

            # TODO: After the new collective.transmogrifier release (>1.4), the
            # utils.py provides a traverse method.
            # from collective.transmogrifier.utils import traverse
            # parent = traverse(self.context, path)
            parent = self.context.unrestrictedTraverse(path.lstrip('/'))
            if not parent:
                continue

            parent_base = aq_base(parent)

            if hasattr(parent_base, 'getOrdering'):
                ordering = parent.getOrdering()
                # Only DefaultOrdering of p.folder is supported
                if (not hasattr(ordering, '_order')
                    and not hasattr(ordering, '_pos')):
                    continue
                order = ordering._order()
                pos = ordering._pos()
                order.sort(key=lambda x: normalized_positions.get(x,
                           pos.get(x, self.default_pos)))
                for i, id_ in enumerate(order):
                    pos[id_] = i

                notifyContainerModified(parent)
Example #17
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 # better name, keep original function signature
        v = self._checkId(id)
        if v is not None:
            id = v

        # If an object by the given id already exists, remove it.
        makeKeyFromId = IKeyIdSubobjectSupport(self).makeKeyFromId
        key = makeKeyFromId(id)

        query = select([self.item_class.key],
                self.item_class.key == key)
        cursor = self.saSession.execute(query)
        try:
            rows = cursor.fetchall()
            if len(rows):
                self._delObject(id)
        except:
            pass

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

        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()

            # 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)

        OFS.subscribers.compatibilityCall('manage_afterAdd', ob, ob, self)

        return id
Example #18
0
 def moveObjectsByDelta(
     self,
     ids,
     delta,
     subset_ids=None,
     suppress_events=False
 ):
     """ see interfaces.py """
     order = self._order()
     pos = self._pos()
     min_position = 0
     if isinstance(ids, basestring):
         ids = [ids]
     if subset_ids is None:
         subset_ids = self.idsInOrder()
     elif not isinstance(subset_ids, list):
         subset_ids = list(subset_ids)
     if delta > 0:                   # unify moving direction
         ids = reversed(ids)
         subset_ids.reverse()
     counter = 0
     for obj_id in ids:
         try:
             old_position = subset_ids.index(obj_id)
         except ValueError:
             continue
         new_position = max(old_position - abs(delta), min_position)
         if new_position == min_position:
             min_position += 1
         if not old_position == new_position:
             subset_ids.remove(obj_id)
             subset_ids.insert(new_position, obj_id)
             counter += 1
     if counter > 0:
         if delta > 0:
             subset_ids.reverse()
         idx = 0
         for i in range(len(order)):
             if order[i] not in subset_ids:
                 continue
             obj_id = subset_ids[idx]
             try:
                 order[i] = obj_id
                 pos[obj_id] = i
                 idx += 1
             except KeyError:
                 raise ValueError(
                     'No object with id "{0:s}" exists.'.format(obj_id)
                 )
     if not suppress_events:
         notifyContainerModified(self.context)
     return counter
Example #19
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)
    def add(self, new_fieldset):
        schema = self.context.schema
        fieldsets = schema.getTaggedValue(FIELDSETS_KEY)

        for fieldset in fieldsets:
            if fieldset.__name__ == new_fieldset.__name__:
                raise WidgetActionExecutionError('__name__',
                    Invalid(_(u'Please select a fieldset name that is not already used.')))

        fieldsets.append(new_fieldset)
        schema.setTaggedValue(FIELDSETS_KEY, fieldsets)
        notifyContainerModified(schema)
        notify(SchemaModifiedEvent(self.context))
        self.status = _(u"Fieldset added successfully.")
Example #21
0
    def change(self, fieldset_index):
        """ AJAX method to change the fieldset of a field
        """
        schema = self.context.field.interface
        field_name = self.context.field.__name__
        fieldset = get_fieldset_from_index(schema, fieldset_index)
        position = new_field_position(schema, fieldset_index)

        editable_schema = IEditableSchema(schema)
        editable_schema.changeFieldFieldset(field_name, fieldset)
        editable_schema.moveField(field_name, position)

        notifyContainerModified(schema)
        notify(SchemaModifiedEvent(self.__parent__.__parent__))
Example #22
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)
Example #23
0
    def updateOrder(self, order):
        """Impose a new order on the items in this container.

        Items in this container are, by default, returned in the order
        in which they were inserted.  To change the order, provide an
        argument to this method that is a sequence containing every key
        already in the container, but in a new order.

        """
        if set(order) != set(self._order):
            raise ValueError("Incompatible key set.")

        self._order = PersistentList()
        self._order.extend(order)
        notifyContainerModified(self)
Example #24
0
    def renamer(self):
        any_renames = False

        data = yield
        while data is not None:
            content, to_identifier, to_title = data
            result = None

            # Rename identifier
            from_identifier = content.getId()
            if to_identifier is not None and from_identifier != to_identifier:
                result = self.__verify_moveable(content)
                if result is None:
                    try:
                        ISilvaNameChooser(self.context).checkName(
                            to_identifier, content)
                    except ContentError as e:
                        result = ContainerError(reason=e.reason,
                                content=content)
                if result is None:
                    content = self.__move(
                        content, self.context, from_identifier, to_identifier)
                    any_renames = True

            # Update title
            if to_title is not None:
                if not isinstance(to_title, unicode):
                    to_title = to_title.decode('utf-8')
                editable = content.get_editable()
                if editable is None:
                    if result is None:
                        result = ContentError(
                            _(u"There is no editable version to set the title on."),
                            content)
                elif editable.get_title() != to_title:
                    try:
                        editable.set_title(to_title)
                    except ContentError as error:
                        result = error

            if result is None:
                result = content

            data = yield result

        if any_renames:
            notifyContainerModified(self.context)
Example #25
0
 def manage_delObjects(self, ids=[], REQUEST=None):
     """Delete reflected files or directories
     
     The objects specified in 'ids' get deleted. This emulates the
     ObjectManager interface enough to support deletion in Plone only.
     When file removal fails, errors are communicated through the return
     of the successful ids and the IStatusMessage utility
     
     """
     if type(ids) is StringType:
         ids = [ids]
     if not ids:
         raise ValueError('No items specified')
     
     # To avoid inconsistencies, first test file availability
     for id in ids:
         if not self.has_key(id):
             raise KeyError(id)
         notify(ObjectWillBeRemovedEvent(self[id], self, id))
         
     problem_ids = []
     path = self.getFilesystemPath()
     for id in ids:
         subpath = os.path.join(path, id)
         ob = self[id]
         try:
             if os.path.isdir(subpath):
                 shutil.rmtree(subpath)
             else:
                 os.unlink(subpath)
             notify(ObjectRemovedEvent(ob, self, id))
         except OSError:
             problem_ids.append(id)
                 
     if problem_ids:
         sm = IStatusMessage(getattr(self, 'REQUEST', None), None)
         if sm is not None:
             sm.addStatusMessage(
                 'Failed to remove some files: %s' % problem_ids, 'stop')
             
     if set(ids) - set(problem_ids):
         indexview = self.unrestrictedTraverse('@@index')
         indexview.index()
         notifyContainerModified(self)
     
     return problem_ids or None # None expected by webdav on success
Example #26
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 # 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()

            # 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
Example #27
0
 def moveObjectsByDelta(self, ids, delta, subset_ids=None,
         suppress_events=False):
     """ see interfaces.py """
     min_position = 0
     if isinstance(ids, basestring):
         ids = [ids]
     if subset_ids is None:
         subset_ids = self.idsInOrder(onlyOrderables=True)
     elif not isinstance(subset_ids, list):
         subset_ids = list(subset_ids)
     if delta > 0:                   # unify moving direction
         ids = reversed(ids)
         subset_ids.reverse()
     counter = 0
     for id in ids:
         try:
             old_position = subset_ids.index(id)
         except ValueError:
             continue
         new_position = max(old_position - abs(delta), min_position)
         if new_position == min_position:
             min_position += 1
         if not old_position == new_position:
             subset_ids.remove(id)
             subset_ids.insert(new_position, id)
             counter += 1
     if counter > 0:
         if delta > 0:
             subset_ids.reverse()
         idx = 0
         for i, value in enumerate(self.order):
             if value in subset_ids:
                 id = subset_ids[idx]
                 try:
                     self.order[i] = id
                     idx += 1
                 except KeyError:
                     raise ValueError('No object with id "%s" exists.' % id)
         if idx > 0:
             self.context._p_changed = True      # the order was changed
     if not suppress_events:
         notifyContainerModified(self.context)
     return counter
Example #28
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))
Example #29
0
    def replace_in_parent(self, old_object, new_object):
        parent = aq_parent(aq_inner(old_object))
        new_object = aq_base(new_object)

        parent._delOb(old_object.id)
        objects = [info for info in parent._objects
                   if info['id'] != new_object.id]
        objects = tuple(objects)
        objects += ({'id': new_object.id,
                     'meta_type': getattr(new_object, 'meta_type', None)},)
        parent._objects = objects
        parent._setOb(new_object.id, new_object)
        notifyContainerModified(parent)

        if hasattr(aq_base(parent), '_tree'):
            del parent._tree[new_object.id]
            parent._tree[new_object.id] = new_object

        return parent._getOb(new_object.id)
Example #30
0
    def _constructInstance(self, container, id, *args, **kw):
        """Build a bare instance of the appropriate type.

        Does not do any security checks.
        """
        constructor = self.restrictedTraverse( self.constructor_path )

        # make sure ownership is explicit before switching the context
        if not hasattr( aq_base(constructor), '_owner' ):
            constructor._owner = aq_get(constructor, '_owner')
        #   Rewrap to get into container's context.
        constructor = aq_base(constructor).__of__( container )

        id = str(id)
        obj = constructor(container, id, *args, **kw)
        if hasattr(obj, '_setPortalTypeName'):
            obj._setPortalTypeName(self.getId())
        notify(ObjectAddedEvent(obj, container, obj.getId()))
        notifyContainerModified(container)
        return obj
Example #31
0
    def updateOrder(self, order):
        """ See `IOrderedContainer`.

        >>> oc = OrderedContainer()
        >>> oc['foo'] = 'bar'
        >>> oc['baz'] = 'quux'
        >>> oc['zork'] = 'grue'
        >>> oc.keys()
        ['foo', 'baz', 'zork']
        >>> oc.updateOrder(['baz', 'foo', 'zork'])
        >>> oc.keys()
        ['baz', 'foo', 'zork']
        >>> oc.updateOrder(['baz', 'zork', 'foo'])
        >>> oc.keys()
        ['baz', 'zork', 'foo']
        >>> oc.updateOrder(['baz', 'zork', 'foo'])
        >>> oc.keys()
        ['baz', 'zork', 'foo']
        >>> oc.updateOrder(('zork', 'foo', 'baz'))
        >>> oc.keys()
        ['zork', 'foo', 'baz']
        >>> oc.updateOrder(['baz', 'zork'])
        Traceback (most recent call last):
        ...
        ValueError: Incompatible key set.
        >>> oc.updateOrder(['foo', 'bar', 'baz', 'quux'])
        Traceback (most recent call last):
        ...
        ValueError: Incompatible key set.
        >>> oc.updateOrder(1)
        Traceback (most recent call last):
        ...
        TypeError: order must be a tuple or a list.
        >>> oc.updateOrder('bar')
        Traceback (most recent call last):
        ...
        TypeError: order must be a tuple or a list.
        >>> oc.updateOrder(['baz', 'zork', 'quux'])
        Traceback (most recent call last):
        ...
        ValueError: Incompatible key set.
        >>> del oc['baz']
        >>> del oc['zork']
        >>> del oc['foo']
        >>> len(oc)
        0
        """

        if not isinstance(order, list) and \
            not isinstance(order, tuple):
            raise TypeError('order must be a tuple or a list.')

        if len(order) != len(self._order):
            raise ValueError("Incompatible key set.")

        was_dict = {}
        will_be_dict = {}
        new_order = PersistentList()

        for i in range(len(order)):
            was_dict[self._order[i]] = 1
            will_be_dict[order[i]] = 1
            new_order.append(order[i])

        if will_be_dict != was_dict:
            raise ValueError("Incompatible key set.")

        self._order = new_order
        notifyContainerModified(self)
Example #32
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:
            raise CopyError('Clipboard Error') from 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
Example #33
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
Example #34
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 isRenameable(ob):
        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:
        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, update_menu=1)
    return None
Example #35
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
Example #36
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:
            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:
            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 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
Example #37
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 = 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:
                    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,
                                        update_menu=1,
                                        cb_dataValid=0)

        return result
Example #38
0
    def updateOrder(self, order):
        """ See `IOrderedContainer`.

        >>> oc = OrderedContainer()
        >>> oc['foo'] = 'bar'
        >>> oc['baz'] = 'quux'
        >>> oc['zork'] = 'grue'
        >>> oc.keys()
        ['foo', 'baz', 'zork']
        >>> oc.updateOrder(['baz', 'foo', 'zork'])
        >>> oc.keys()
        ['baz', 'foo', 'zork']
        >>> oc.updateOrder(['baz', 'zork', 'foo'])
        >>> oc.keys()
        ['baz', 'zork', 'foo']
        >>> oc.updateOrder(['baz', 'zork', 'foo'])
        >>> oc.keys()
        ['baz', 'zork', 'foo']
        >>> oc.updateOrder(('zork', 'foo', 'baz'))
        >>> oc.keys()
        ['zork', 'foo', 'baz']
        >>> oc.updateOrder(['baz', 'zork'])
        Traceback (most recent call last):
        ...
        ValueError: Incompatible key set.
        >>> oc.updateOrder(['foo', 'bar', 'baz', 'quux'])
        Traceback (most recent call last):
        ...
        ValueError: Incompatible key set.
        >>> oc.updateOrder(1)
        Traceback (most recent call last):
        ...
        TypeError: order must be a tuple or a list.
        >>> oc.updateOrder('bar')
        Traceback (most recent call last):
        ...
        TypeError: order must be a tuple or a list.
        >>> oc.updateOrder(['baz', 'zork', 'quux'])
        Traceback (most recent call last):
        ...
        ValueError: Incompatible key set.
        >>> del oc['baz']
        >>> del oc['zork']
        >>> del oc['foo']
        >>> len(oc)
        0
        """

        if not isinstance(order, (list, tuple)):
            raise TypeError('order must be a tuple or a list.')

        if len(order) != len(self._order):
            raise ValueError("Incompatible key set.")

        order = [checkAndConvertName(x) for x in order]

        if frozenset(order) != frozenset(self._order):
            raise ValueError("Incompatible key set.")

        if order == self._order:
            return

        self._order[:] = order

        notifyContainerModified(self)