def _delObject(self, id, dp=1, suppress_events=False): """Delete an object from this container. Also sends IObjectWillBeRemovedEvent and IObjectRemovedEvent. """ ob = self._getOb(id) OFS.subscribers.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)
def _delObject(self, id, dp=1, suppress_events=False): """Delete an object from this container. Also sends 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)
def cutAndPaste(self, sourcepath, id, targetpath): """ uses OFS to cur and paste an object sourecpath must refer to the folder which contains the object to move id must be a string containing the id of the object to move targetpath must be the folder to move to both paths must contain one single %s to place the language """ context = Acquisition.aq_inner(self.context) if '%s' not in sourcepath: return ["Wrong sourcepath"] if '%s' not in targetpath: return ["Wrong targetpath"] results = [] for lang in self.langs: results.append("Trying language: %s" % lang) spath = sourcepath % lang source = context.restrictedTraverse(spath, None) if source is None: results.append(" # Break, source is none") continue spathtest = "/".join(source.getPhysicalPath()) if spath != spathtest: results.append( " # Break, requested path not sourcepath (%s != %s)" % (spath, spathtest)) continue tpath = targetpath % lang target = context.restrictedTraverse(tpath, None) if target is None: results.append(" # Break, target is none") continue tpathtest = "/".join(target.getPhysicalPath()) if tpath != tpathtest: results.append( " # Break, requested path not targetpath (%s != %s)" % (tpath, tpathtest)) continue ob = getattr(source, id) ob = Acquisition.aq_base(ob) if ob is None: results.append(" # Break, ob is None!!") source._delObject(id, suppress_events=True) target._setObject(id, ob, set_owner=0, suppress_events=True) ob = target._getOb(id) notify(ObjectMovedEvent(ob, source, id, target, id)) notifyContainerModified(source) if Acquisition.aq_base(source) is not Acquisition.aq_base(target): notifyContainerModified(target) ob._postCopy(target, op=1) results.append("Copy&Paste successful for language %s" % lang) return results
def moveObjectsByDelta(self, ids, delta, subset_ids=None, suppress_events=False): """ Move specified sub-objects by delta. """ res = self.__five_original_moveObjectsByDelta(ids, delta, subset_ids) if not suppress_events: notifyContainerModified(self) return res
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)
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 _setObject(self, id, object): 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) notify(ObjectAddedEvent(object, self, id)) notifyContainerModified(self) return object
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 # Reorder Collage items if parent.portal_type == 'Collage' or parent.portal_type == 'CollageColumn' or parent.portal_type == 'CollageRow': for key in normalized_positions.keys(): parent.moveObjectToPosition(key, normalized_positions[key]) 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)
def cutAndPaste(self, sourcepath, id, targetpath): """ Uses OFS to cut and paste an object. Sourecpath must refer to the folder which contains the object to move. id must be a string containing the id of the object to move. targetpath must be the folder to move to. Both paths must contain one single %s to place the language """ context = Acquisition.aq_inner(self.context) if "%s" not in sourcepath: return ["Wrong sourcepath"] if "%s" not in targetpath: return ["Wrong targetpath"] results = [] for lang in self.langs: results.append("Trying language: %s" % lang) spath = sourcepath % lang source = context.restrictedTraverse(spath, None) if source is None: results.append(" # Break, source is none") continue spathtest = "/".join(source.getPhysicalPath()) if spath != spathtest: results.append(" # Break, requested path not sourcepath " "(%s != %s)" % (spath, spathtest)) continue tpath = targetpath % lang target = context.restrictedTraverse(tpath, None) if target is None: results.append(" # Break, target is none") continue tpathtest = "/".join(target.getPhysicalPath()) if tpath != tpathtest: results.append(" # Break, requested path not targetpath " "(%s != %s)" % (tpath, tpathtest)) continue ob = getattr(source, id, None) ob = Acquisition.aq_base(ob) if ob is None: results.append(" # Break, ob is None!!") continue source._delObject(id, suppress_events=True) target._setObject(id, ob, set_owner=0, suppress_events=True) ob = target._getOb(id) notify(ObjectMovedEvent(ob, source, id, target, id)) notifyContainerModified(source) if Acquisition.aq_base(source) is not Acquisition.aq_base(target): notifyContainerModified(target) ob._postCopy(target, op=1) results.append("Copy&Paste successful for language %s" % lang) return results
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)
def _setObject(self, id, object, roles=None, user=None, set_owner=1, suppress_events=False): """Set an object into this container. Also sends IObjectWillBeAddedEvent and IObjectAddedEvent. """ ob = object if not suppress_events: # notify(ObjectAddedEvent(ob, self, id)) notifyContainerModified(self) compatibilityCall('manage_afterAdd', ob, ob, self) return id
def moveObjectsByDelta(self, ids, delta, subset_ids=None, suppress_events=False): """ Move specified sub-objects by delta. """ if type(ids) is StringType: ids = (ids, ) min_position = 0 objects = list(self._objects) if subset_ids == None: subset_ids = [obj['id'] for obj in 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
def _setObject(self, id, object, roles=None, user=None, set_owner=1, suppress_events=False): """Set an object into this container. Also sends IObjectAddedEvent. """ ob = object # better name, keep original function signature v = self._checkId(id) if v is not None: id = v t = getattr(ob, 'meta_type', None) # If an object by the given id already exists, remove it. for object_info in self._objects: if object_info['id'] == id: self._delObject(id) break if not suppress_events: notify(ObjectWillBeAddedEvent(ob, self, id)) self._objects = self._objects + ({'id': id, 'meta_type': t}, ) self._setOb(id, ob) ob = self._getOb(id) if set_owner: # TODO: eventify manage_fixupOwnershipAfterAdd # This will be called for a copy/clone, or a normal _setObject. ob.manage_fixupOwnershipAfterAdd() if set_owner: # Try to give user the local role "Owner", but only if # no local roles have been set on the object yet. if getattr(ob, '__ac_local_roles__', _marker) is None: user = getSecurityManager().getUser() if user is not None: userid = user.getId() if userid is not None: ob.manage_setLocalRoles(userid, ['Owner']) if not suppress_events: notify(ObjectAddedEvent(ob, self, id)) notifyContainerModified(self) compatibilityCall('manage_afterAdd', ob, ob, self) return id
def moveObjectsByDelta(self, ids, delta, subset_ids=None, suppress_events=False): """Move specified sub-objects by delta.""" if type(ids) is StringType: ids = (ids,) min_position = 0 objects = list(self._objects) if subset_ids == None: subset_ids = self.getCMFObjectsSubsetIds(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: 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() 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
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 = list(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 list(positions_mapping.items()): # Normalize positions ordered_keys = sorted(list(positions.keys()), key=lambda x: positions[x]) normalized_positions = {} for pos, key in enumerate(ordered_keys): normalized_positions[key] = pos path = safe_unicode(path.lstrip('/')).encode('ascii') parent = traverse(self.context, path, None) 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)
def _delObject(self, id, dp=1, suppress_events=False): ob = self._getOb(id) OFS.subscribers.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 __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 path = safe_unicode(path.lstrip('/')).encode('ascii') parent = traverse(self.context, path, None) 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)
def __setitem__(self, name, object): """Add the given object to the folder under the given name. """ if not isinstance(name, int): raise TypeError("Name must be an integer rather than a %s" % name.__class__.__name__) if self.__contains__(name): raise DuplicationError("key %r is already in use." % name) object, event = contained.containedEvent(object, self, name) IOBTreeStorage.__setitem__(self, name, object) if event: notify(event) contained.notifyContainerModified(self)
def setitem(container, setitemmf, name, object): # Do basic name check: if isinstance(name, str): try: name = unicode(name) except UnicodeError: raise TypeError("name not unicode or ascii string") elif not isinstance(name, unicode): raise TypeError("name not unicode or ascii string") if not name: raise ValueError("empty names are not allowed") old = container.get(name) if old is object: return if old is not None: raise DuplicationError(name) oldparent = object.__parent__ oldname = object.__name__ # create and store draft dct = getUtility(IDraftContentType, IContentType(object).name) draft = dct.klass(removeAllProxies(object)) draft.__name__ = name draft.__parent__ = container if oldparent is not None: draft.shortname = oldname draft.location = getUtility(IIntIds).getId(oldparent) event.notify(ObjectCreatedEvent(draft)) # added draft to container setitemmf(name, draft) event.notify(ObjectAddedEvent(draft, container, name)) # notify content and container objects if oldparent is not None: event.notify( ObjectMovedEvent(object,oldparent,oldname,draft,object.__name__)) event.notify(ObjectModifiedEvent(object)) notifyContainerModified(container)
def _setObject(self, id, object, roles=None, user=None, set_owner=1, suppress_events=False): """Set an object into this container. Also sends IObjectAddedEvent. """ ob = object # better name, keep original function signature v = self._checkId(id) if v is not None: id = v t = getattr(ob, 'meta_type', None) # If an object by the given id already exists, remove it. for object_info in self._objects: if object_info['id'] == id: self._delObject(id) break if not suppress_events: notify(ObjectWillBeAddedEvent(ob, self, id)) self._objects = self._objects + ({'id': id, 'meta_type': t},) self._setOb(id, ob) ob = self._getOb(id) if set_owner: # TODO: eventify manage_fixupOwnershipAfterAdd # This will be called for a copy/clone, or a normal _setObject. ob.manage_fixupOwnershipAfterAdd() if set_owner: # Try to give user the local role "Owner", but only if # no local roles have been set on the object yet. if getattr(ob, '__ac_local_roles__', _marker) is None: user = getSecurityManager().getUser() if user is not None: userid = user.getId() if userid is not None: ob.manage_setLocalRoles(userid, ['Owner']) if not suppress_events: notify(ObjectAddedEvent(ob, self, id)) notifyContainerModified(self) compatibilityCall('manage_afterAdd', ob, ob, self) return id
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
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 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 "%s" exists.' % id) if not suppress_events: notifyContainerModified(self.context) return counter
def _setObject(self, id, object, roles=None, user=None, set_owner=1, suppress_events=False): 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. if self.has_key(id): self._delObject(id) 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
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))
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
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
def _constructInstance(self, container, id, *args, **kw): """Build a bare instance of the appropriate type. Does not do any security checks. """ # XXX: this method violates the rules for tools/utilities: # it depends on self.REQUEST id = str(id) if self.product: # oldstyle factory m = self._getFactoryMethod(container, check_security=0) if getattr(aq_base(m), 'isDocTemp', 0): kw['id'] = id newid = m(m.aq_parent, self.REQUEST, *args, **kw) else: newid = m(id, *args, **kw) # allow factory to munge ID newid = newid or id obj = container._getOb(newid) if hasattr(obj, '_setPortalTypeName'): obj._setPortalTypeName(self.getId()) notify(ObjectCreatedEvent(obj)) notify(ObjectAddedEvent(obj, container, newid)) notifyContainerModified(container) else: # newstyle factory factory = getUtility(IFactory, self.factory) obj = factory(id, *args, **kw) if hasattr(obj, '_setPortalTypeName'): obj._setPortalTypeName(self.getId()) notify(ObjectCreatedEvent(obj)) rval = container._setObject(id, obj) newid = isinstance(rval, basestring) and rval or id obj = container._getOb(newid) return obj
def updateOrder(self, order): if not isinstance(order, types.ListType) and \ not isinstance(order, types.TupleType): 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 = {} orderValues = self.order.values() for i in range(len(order)): was_dict[orderValues[i]] = 1 will_be_dict[order[i]] = 1 new_order[i] = order[i] if will_be_dict != was_dict: raise ValueError("Incompatible key set.") order = [] keys = list(new_order.keys()) keys.sort() for key in keys: if new_order[key] not in order: order.append(new_order[key]) self.order.clear() self.border.clear() for idx in range(len(order)): self.order[idx] = order[idx] self.border[order[idx]] = idx notifyContainerModified(self)
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, ListType) and \ not isinstance(order, TupleType): 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)
def COPY(self, REQUEST, RESPONSE): """Create a duplicate of the source resource. This is only allowed within the same reflecto directory.""" self.dav__init(REQUEST, RESPONSE) if not hasattr(aq_base(self), 'cb_isCopyable') or \ not self.cb_isCopyable(): raise MethodNotAllowed, 'This object may not be copied.' depth=REQUEST.get_header('Depth', 'infinity') if not depth in ('0', 'infinity'): raise BadRequest, 'Invalid Depth header.' dest=REQUEST.get_header('Destination', '') while dest and dest[-1]=='/': dest=dest[:-1] if not dest: raise BadRequest, 'Invalid Destination header.' try: path = REQUEST.physicalPathFromURL(dest) except ValueError: raise BadRequest, 'Invalid Destination header' name = path.pop() oflag=REQUEST.get_header('Overwrite', 'F').upper() if not oflag in ('T', 'F'): raise BadRequest, 'Invalid Overwrite header.' try: parent=self.restrictedTraverse(path) except ValueError: raise Conflict, 'Attempt to copy to an unknown namespace.' except NotFound: raise Conflict, 'Object ancestors must already exist.' except: t, v, tb=sys.exc_info() raise t, v if hasattr(parent, '__null_resource__'): raise Conflict, 'Object ancestors must already exist.' existing=hasattr(aq_base(parent), name) if existing and oflag=='F': raise PreconditionFailed, 'Destination resource exists.' try: parent._checkId(name, allow_dup=1) except: raise Forbidden, sys.exc_info()[1] try: parent._verifyObjectPaste(self) except Unauthorized: raise except: raise Forbidden, sys.exc_info()[1] # Now check locks. The If header on a copy only cares about the # lock on the destination, so we need to check out the destinations # lock status. ifhdr = REQUEST.get_header('If', '') if existing: # The destination itself exists, so we need to check its locks destob = aq_base(parent)._getOb(name) if IWriteLock.providedBy(destob) and destob.wl_isLocked(): if ifhdr: itrue = destob.dav__simpleifhandler( REQUEST, RESPONSE, 'COPY', refresh=1) if not itrue: raise PreconditionFailed else: raise Locked, 'Destination is locked.' elif IWriteLock.providedBy(parent) and parent.wl_isLocked(): if ifhdr: parent.dav__simpleifhandler(REQUEST, RESPONSE, 'COPY', refresh=1) else: raise Locked, 'Destination is locked.' self._notifyOfCopyTo(parent, op=0) #### This part is reflecto specific if existing: object=getattr(parent, name) self.dav__validate(object, 'DELETE', REQUEST) parent.manage_delObjects([name]) oldpath = self.getFilesystemPath() newpath = os.path.join(parent.getFilesystemPath(), name) if IReflectoDirectory.providedBy(self): if depth=='0': os.mkdir(newpath, 0775) else: shutil.copytree(oldpath, newpath) else: shutil.copy2(oldpath, newpath) ob = parent[name] ob.indexObject() notify(ObjectCopiedEvent(ob, self)) notify(ObjectClonedEvent(ob)) notifyContainerModified(parent) #### # We remove any locks from the copied object because webdav clients # don't track the lock status and the lock token for copied resources ob.wl_clearLocks() RESPONSE.setStatus(existing and 204 or 201) if not existing: RESPONSE.setHeader('Location', dest) RESPONSE.setBody('') return RESPONSE
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
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: 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) or WriteLockInterface.isImplementedBy(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) or WriteLockInterface.isImplementedBy(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) 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) 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) if existing: object=getattr(parent, name) self.dav__validate(object, 'DELETE', REQUEST) parent._delObject(name) try: parent._setObject(name, ob, set_owner=0, suppress_events=True) except TypeError: # BBB: removed in Zope 2.11 parent._setObject(name, ob, set_owner=0) warnings.warn( "%s._setObject without suppress_events is deprecated " "and will be removed in Zope 2.11." % parent.__class__.__name__, DeprecationWarning) 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
def manage_pasteObjects(self, cb_copy_data=None, REQUEST=None): """Paste previously copied objects into the current object. If calling manage_pasteObjects from python code, pass the result of a previous call to manage_cutObjects or manage_copyObjects as the first argument. Also sends IObjectCopiedEvent or IObjectMovedEvent. """ if cb_copy_data is not None: cp = cb_copy_data elif REQUEST is not None and REQUEST.has_key('__cp'): cp = REQUEST['__cp'] else: cp = None if cp is None: raise CopyError, eNoData try: op, mdatas = _cb_decode(cp) except: raise CopyError, eInvalid oblist = [] app = self.getPhysicalRoot() for mdata in mdatas: m = Moniker.loadMoniker(mdata) try: ob = m.bind(app) except ConflictError: raise except: raise CopyError, eNotFound self._verifyObjectPaste(ob, validate_src=op+1) oblist.append(ob) result = [] if op == 0: # Copy operation for ob in oblist: orig_id = ob.getId() if not ob.cb_isCopyable(): raise CopyError, eNotSupported % escape(orig_id) try: ob._notifyOfCopyTo(self, op=0) except ConflictError: raise except: raise CopyError, MessageDialog( title="Copy Error", message=sys.exc_info()[1], action='manage_main') id = self._get_id(orig_id) result.append({'id': orig_id, 'new_id': id}) orig_ob = ob ob = ob._getCopy(self) ob._setId(id) notify(ObjectCopiedEvent(ob, orig_ob)) self._setObject(id, ob) ob = self._getOb(id) ob.wl_clearLocks() ob._postCopy(self, op=0) compatibilityCall('manage_afterClone', ob, ob) notify(ObjectClonedEvent(ob)) if REQUEST is not None: return self.manage_main(self, REQUEST, update_menu=1, cb_dataValid=1) elif op == 1: # Move operation for ob in oblist: orig_id = ob.getId() if not ob.cb_isMoveable(): raise CopyError, eNotSupported % escape(orig_id) try: ob._notifyOfCopyTo(self, op=1) except ConflictError: raise except: raise CopyError, MessageDialog( title="Move Error", message=sys.exc_info()[1], action='manage_main') if not sanity_check(self, ob): raise CopyError, "This object cannot be pasted into itself" orig_container = aq_parent(aq_inner(ob)) if aq_base(orig_container) is aq_base(self): id = orig_id else: id = self._get_id(orig_id) result.append({'id': orig_id, 'new_id': id}) notify(ObjectWillBeMovedEvent(ob, orig_container, orig_id, self, id)) # try to make ownership explicit so that it gets carried # along to the new location if needed. ob.manage_changeOwnershipType(explicit=1) try: orig_container._delObject(orig_id, suppress_events=True) except TypeError: # BBB: removed in Zope 2.11 orig_container._delObject(orig_id) warnings.warn( "%s._delObject without suppress_events is deprecated " "and will be removed in Zope 2.11." % orig_container.__class__.__name__, DeprecationWarning) ob = aq_base(ob) ob._setId(id) try: self._setObject(id, ob, set_owner=0, suppress_events=True) except TypeError: # BBB: removed in Zope 2.11 self._setObject(id, ob, set_owner=0) warnings.warn( "%s._setObject without suppress_events is deprecated " "and will be removed in Zope 2.11." % self.__class__.__name__, DeprecationWarning) ob = self._getOb(id) notify(ObjectMovedEvent(ob, orig_container, orig_id, self, id)) notifyContainerModified(orig_container) if aq_base(orig_container) is not aq_base(self): notifyContainerModified(self) ob._postCopy(self, op=1) # try to make ownership implicit if possible ob.manage_changeOwnershipType(explicit=0) if REQUEST is not None: REQUEST['RESPONSE'].setCookie('__cp', 'deleted', path='%s' % cookie_path(REQUEST), expires='Wed, 31-Dec-97 23:59:59 GMT') REQUEST['__cp'] = None return self.manage_main(self, REQUEST, update_menu=1, cb_dataValid=0) return result
def cut_and_paste(ob, *args, **kw): """ Uses OFS to cut and paste an object. """ err = list() targetpath = kw['target_path'] if not targetpath: err.append('You must specify a target path') id = kw['id_to_move'] if not id: err.append(u'You must select an object to move') targetpath = targetpath.encode('utf-8') id = id.encode('utf-8') lang = kw['lang'] portal_path = kw['portal_path'] if not err: if targetpath.startswith('/'): if not targetpath.startswith(portal_path): targetpath = portal_path + targetpath target_base = ob.restrictedTraverse(targetpath, None) if target_base is None: err.append(u'No object was found at the given taget path %s' \ % targetpath) return err if ITranslatable.providedBy(target_base): target = target_base.getTranslation(lang) else: err.append(u'The target object is not translatable. Please '\ 'choose a different target that is translatable.') return err if target is None: err.append(u'No translation in language "%s" was found of '\ 'the target %s' % (lang, targetpath)) return err if not IBaseFolder.providedBy(target): err.append(u'The target object is not folderish - pasting is '\ 'not possible.') return err name = None if id in ob.objectIds(): name = id trans_object = getattr(ob, name) else: # look for translation via getTranslation target_object = kw.get('target_object', None) if target_object: trans_object = target_object.getTranslation(lang) if trans_object: if Acquisition.aq_parent(trans_object) == ob: name = trans_object.getId() if name is None: err.append(u'No translation of the requested object for language '\ '%s found in %s' % ( lang, '/'.join(ob.getPhysicalPath()))) return err if target == trans_object: err.append(u'The target cannot be identical to the object you '\ 'want to move') return err ob._delObject(name, suppress_events=True) target._setObject(id, trans_object, set_owner=0, suppress_events=True) trans_object = target._getOb(id) notify(ObjectMovedEvent(trans_object, ob, id, target, id)) notifyContainerModified(ob) if Acquisition.aq_base(ob) is not Acquisition.aq_base(target): notifyContainerModified(target) trans_object._postCopy(target, op=1) trans_object.reindexObject() return err
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
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
def update(self): if self.updated: return context = self.context request = self.request if 'form.buttons.apply' in request: self.environ['applyButton'] = True elif 'form.buttons.rename' in request: if not request.get("ids"): IStatusMessage(request).add( _("You didn't specify any ids to rename."), 'warning') else: interface.alsoProvides(self, IRenameContainerContents) elif "form.buttons.delete" in request: self.removeObjects() elif "form.buttons.copy" in request: self.copyObjects() elif "form.buttons.cut" in request: self.cutObjects() elif "form.buttons.paste" in request: self.pasteObjects() elif "form.buttons.pasteLink" in request: self.pasteObjectLinks() order = IOrder(context, None) if order is not None and IReordable.providedBy(order): self.orderButtons = len(order) > 1 changed = False selected = request.get('ids', []) if 'form.buttons.moveup' in request: changed = order.moveUp(selected) elif 'form.buttons.movetop' in request: changed = order.moveTop(selected) elif 'form.buttons.movedown' in request: changed = order.moveDown(selected) elif 'form.buttons.movebottom' in request: changed = order.moveBottom(selected) if changed: notifyContainerModified(context) IStatusMessage(request).add( _(u'Items order have been changed.')) else: self.orderButtons = False super(ContainerContents, self).update() self.setupButtons() self.updated = True
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