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 _replaceBaseline(self, baseline): # move the working copy object to the baseline, returns the new # baseline # First, copy children of baseline to the working copy for key in baseline.keys(): sub_ob = baseline[key] baseline._delObject(key, suppress_events=True) # use _get_id to handle naming in case of conflicts new_id = self.context._get_id(key) self.context._setObject(new_id, sub_ob, suppress_events=True) # delete the baseline from the folder to make room for the committed # working copy baseline_id = baseline.getId() baseline_container = aq_parent(aq_inner(baseline)) baseline_container._delOb(baseline_id) # delete the working copy from the its container wc_container = aq_parent(aq_inner(self.context)) # trick out the at machinery to not delete references self.context._v_cp_refs = 1 self.context._v_is_cp = 0 wc_id = self.context.getId() wc_container._delObject(wc_id) # move the working copy back to the baseline container working_copy = aq_base(self.context) working_copy.setId(baseline_id) baseline_container._setOb(baseline_id, working_copy) new_baseline = baseline_container._getOb(baseline_id) # reregister our references with the reference machinery after moving Referenceable.manage_afterAdd(new_baseline, new_baseline, baseline_container) notify( ObjectMovedEvent(new_baseline, wc_container, wc_id, baseline_container, baseline_id)) return new_baseline
def manage_afterAdd(self, item, container): original_location_path = getattr(self, '__five_location_path__', None) self.__five_location_path__ = self.getPhysicalPath() # if there still is an object in the original location, we're copied # we cannot rely on manage_afterClone, as this gets triggered only # *after* a manage_afterAdd. This logic might fail in the case where # something *is* somehow left in the original location that can # be traversed to. is_copied = original_location_path and (self.unrestrictedTraverse( original_location_path, None) is not None) if is_copied: notify(ObjectCopiedEvent(self)) if original_location_path is None or is_copied: notify(ObjectAddedEvent(self)) else: original_location = self.unrestrictedTraverse( original_location_path[:-1]) notify(ObjectMovedEvent(self, original_location, original_location_path[-1], container, self.id)) # call original method = getattr(self, '__five_original_manage_afterAdd', None) if method is not None: self.__five_original_manage_afterAdd(item, container)
def __init__(self, object, oldParent=None, oldName=None): if oldParent is None: oldParent = object.aq_inner.aq_parent if oldName is None: oldName = object.id ObjectMovedEvent.__init__(self, object, oldParent, oldName, None, None)
def __init__(self, object, newParent=None, newName=None): if newParent is None: newParent = object.aq_inner.aq_parent if newName is None: newName = object.id ObjectMovedEvent.__init__(self, object, None, None, newParent, newName)
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 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