def manage_pasteObjects(self, cb_copy_data=None, REQUEST=None): """ override normal paste action to see if we're looking at the paste data being stored in cache """ if cb_copy_data is not None: cp = cb_copy_data elif REQUEST is not None and '__cp' in REQUEST: cp = REQUEST['__cp'] else: cp = None if cp is None: raise CopyError(eNoData) try: op, mdatas = _cb_decode(cp) except Exception: raise CopyError(eInvalid) try: if mdatas[0][0].startswith('cache:'): cache_key = mdatas[0][0].replace('cache:', '') new_mdatas = cache.get(cache_key) cdata = _cb_encode((op, new_mdatas)) return self._old_manage_pasteObjects(cdata) except IndexError: pass return self._old_manage_pasteObjects(cb_copy_data, REQUEST)
def objects_to_async(self, request_key='__cp'): """ get info of files to perform async operation """ newid = self.request.get(request_key) if not newid: raise CopyError(eNoItemsSpecified) try: _op, mdatas = _cb_decode(newid) except: raise CopyError(eInvalid) oblist = [] app = self.context.getPhysicalRoot() for mdata in mdatas: m = loadMoniker(mdata) try: ob = m.bind(app) except ConflictError: raise except: raise CopyError(eNotFound) oblist.append(ob) return oblist
def manage_renameObject(self, id, new_id, REQUEST=None): """Rename a particular sub-object, the *old* way. FIXME: hack that could be removed once Zope 2.4.x goes back to a useful semantics...""" 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 not ob.cb_isMoveable(): raise CopyError(eNotSupported % id) self._verifyObjectPaste(ob) try: ob._notifyOfCopyTo(self, op=1) except: raise CopyError( MessageDialog(title='Rename Error', message=sys.exc_info()[1], action='manage_main')) self._delObject(id) 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. self._setObject(new_id, ob, set_owner=False) if REQUEST is not None: return self.manage_main(self, REQUEST, update_menu=True) return None
def _getSourceObjects(self, cb_copy_data, REQUEST): """get the source objects to link""" cp = None if cb_copy_data is not None: cp = cb_copy_data else: if REQUEST and REQUEST.has_key('__cp'): cp = REQUEST['__cp'] if cp is None: raise CopyError(eNoData) try: cp = _cb_decode(cp) except Exception: raise CopyError(eInvalid) oblist = [] app = self.getPhysicalRoot() for mdata in cp[1]: m = Moniker.loadMoniker(mdata) try: ob = m.bind(app) except Exception: raise CopyError(eNotFound) self._verifyObjectLink() oblist.append(ob) return oblist
def async_move(context, success_event, fail_event, **kwargs): """ Async job """ newid = kwargs.get('newid', '') email = kwargs.get('email', '') anno = IAnnotations(context) job_id = anno.get('async_move_job') if not newid: wrapper = IContextWrapper(context)( error=u'Invalid newid' ) notify(fail_event(wrapper)) raise CopyError(eNoItemsSpecified) try: _op, mdatas = _cb_decode(newid) except: raise CopyError(eInvalid) oblist = [] app = context.getPhysicalRoot() for mdata in mdatas: m = loadMoniker(mdata) try: ob = m.bind(app) except ConflictError: raise except: raise CopyError(eNotFound) oblist.append(ob) wrapper = IContextWrapper(context)( folder_move_from=oblist and aq_parent( aq_inner(oblist[0])).absolute_url(), folder_move_to=context.absolute_url(), folder_move_objects=', '.join([obj.getId() for obj in oblist]), asyncmove_email=email ) try: manage_pasteObjects_no_events(context, cb_copy_data=newid) except Exception, err: logger.exception(err) wrapper.error = err.message wrapper.job_id = job_id notify(fail_event(wrapper)) raise CopyError(MessageDialog( title='Error', message=err.message, action='manage_main', ))
def manage_copyObjects(self, ids=None, uids=None, REQUEST=None, RESPONSE=None): """ Put a reference to the objects named in ids in the clip board """ #LOG("Manage Copy",0, "ids:%s uids:%s" % (str(ids), str(uids))) if ids is not None: # Use default methode return OriginalCopyContainer.manage_copyObjects( self, ids, REQUEST, RESPONSE) if uids is None and REQUEST is not None: return eNoItemsSpecified elif uids is None: raise ValueError('uids must be specified') if isinstance(uids, (str, int)): ids = [uids] oblist = [] for uid in uids: ob = self.getPortalObject().portal_catalog.getObject(uid) if not ob.cb_isCopyable(): raise CopyError(eNotSupported % uid) m = Moniker.Moniker(ob) oblist.append(m.dump()) cp = (0, oblist) cp = _cb_encode(cp) if REQUEST is not None: resp = REQUEST['RESPONSE'] resp.setCookie('__cp', cp, path='%s' % cookie_path(REQUEST)) REQUEST['__cp'] = cp return self.manage_main(self, REQUEST) return cp
def manage_pasteObjects(self, cp): """ merge another conversation """ try: op, mdatas = _cb_decode(cp) except Exception: raise CopyError("Invalid content") if op == 0: raise ValueError('Not allowed to copy content into conversation') if op != 1: raise ValueError("Invalid operation of content") obj = self.unrestrictedTraverse(mdatas[0]) if IConversation.providedBy(obj): if obj.getParentNode() != self.getParentNode(): raise ValueError("Invalid parent of content") forum = obj.getForum() obj_id = obj.getId() o_list = obj.objectValues() oblist = [Moniker(o1).dump() for o1 in o_list] cp = (1, oblist) cp = _cb_encode(cp) CopyContainer.manage_pasteObjects(self, cp) forum.manage_delObjects([obj_id]) elif IComment.providedBy(obj): return CopyContainer.manage_pasteObjects(self, cp) else: raise ValueError('Invalid type of content')
def manage_pasteObjects(self, cb_copy_data=None, is_indexable=None, reindex_kw=None, immediate_reindex=False, 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. If is_indexable is False, we will avoid indexing the pasted objects and subobjects immediate_reindex (bool) Immediately (=during current transaction) reindex created document, so it is possible to find it in catalog before transaction ends. Note: this does not apply to subobjects which may be created during pasting. Only the topmost object will be immediately reindexed. Any subobject will be reindexed later, using activities. If a ImmediateReindexContextManager instance is given, a context (in python sense) must have been entered with it, and indexation will occur when that context is exited, allowing further changes before first indexation (ex: workflow state change, property change). """ cp = None if cb_copy_data is not None: cp = cb_copy_data elif REQUEST is not None and REQUEST.has_key('__cp'): cp = REQUEST['__cp'] if cp is None: raise CopyError(eNoData) op, result = self.__duplicate( cp, duplicate=False, is_indexable=is_indexable, reindex_kw=reindex_kw, immediate_reindex=immediate_reindex, ) if REQUEST is None: return result if op == 0: cb_dataValid = 1 else: cb_dataValid = 0 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=cb_dataValid)
def _get_cb_copy_data(self, cb_copy_data=None, REQUEST=None): cp = None if cb_copy_data is not None: cp = cb_copy_data else: if REQUEST and '__cp' in REQUEST: cp = REQUEST['__cp'] if cp is None: raise CopyError(eNoData) try: cp = _cb_decode(cp) except: standard.writeError(self, '[CopySupport._get_cb_copy_data]: eInvalid') raise CopyError(eInvalid) return cp
def finish(self): oblist = [] for ob in self.oblist: if not ob.cb_isCopyable(): raise CopyError(eNotSupported % escape(id)) m = Moniker(ob) oblist.append(m.dump()) cp = (0, oblist) cp = _cb_encode(cp) resp = self.request.response resp.setCookie('__cp', cp, path='%s' % cookie_path(self.request)) self.request['__cp'] = cp
def unrestricted_rename(self, id, new_id): """Rename a particular sub-object Copied from OFS.CopySupport Less strict version of manage_renameObject: * no write look check * no verify object check from PortalFolder so it's allowed to rename even unallowed portal types inside a folder """ 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('Not supported {}'.format(escape(id))) #!#self._verifyObjectPaste(ob) #!#CopyContainer._verifyObjectPaste(self, ob) try: ob._notifyOfCopyTo(self, op=1) except: raise(CopyError, MessageDialog( title='Rename Error', message=sys.exc_info()[1], action ='manage_main')) self._delObject(id) 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. self._setObject(new_id, ob, set_owner=0) ob = self._getOb(new_id) ob._postCopy(self, op=1) #!#if REQUEST is not None: #!# return self.manage_main(self, REQUEST, update_menu=1) return None
def _unrestricted_rename(container, id, new_id): """Rename a particular sub-object Copied from OFS.CopySupport Less strict version of manage_renameObject: * no write lock check * no verify object check from PortalFolder so it's allowed to rename even unallowed portal types inside a folder """ try: container._checkId(new_id) except: raise CopyError( MessageDialog(title='Invalid Id', message=sys.exc_info()[1], action='manage_main')) ob = container._getOb(id) if not ob.cb_isMoveable(): raise CopyError('Not Supported {}'.format(escape(id))) try: ob._notifyOfCopyTo(container, op=1) except: raise CopyError( MessageDialog(title='Rename Error', message=sys.exc_info()[1], action='manage_main')) container._delObject(id) 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. container._setObject(new_id, ob, set_owner=0) ob = container._getOb(new_id) ob._postCopy(container, op=1) return None
def _verifyObjectPaste(self, object, validate_src=1): """ check to see if this object is allowed to be pasted into this path """ pathres = getattr(object, 'relationshipManagerPathRestriction', None) if (pathres and '/'.join(self.getPhysicalPath()).find(pathres) == -1): raise CopyError( MessageDialog( title='Not Supported', message='The object <EM>%s</EM> can not be pasted into' ' the path <EM>%s</EM>' % (object.id, '/'.join(self.getPhysicalPath())), action='manage_main', ))
def finish(self): oblist = [] for ob in self.oblist: if ob.wl_isLocked(): raise ResourceLockedError('Object "%s" is locked via WebDAV' % ob.getId()) if not ob.cb_isMoveable(): raise CopyError(eNotSupported % escape(id)) m = Moniker(ob) oblist.append(m.dump()) cp = (1, oblist) cp = _cb_encode(cp) resp = self.request.response resp.setCookie('__cp', cp, path='%s' % cookie_path(self.request)) self.request['__cp'] = cp
def _verifyObjectLink(self): """ When linking check that the user has "Copy or Move" permission on the relation. Can't use _verifyObjectPaste because there is an empty all_meta_types on ToManyRelations which causes it to falsely fail. """ if not getSecurityManager().checkPermission('Copy or Move', self): message = ('You do not possess the "Copy or Move" permission in ' 'the context of the container into which you are ' 'pasting, thus you are not able to perform ' 'this operation.') raise CopyError( MessageDialog( title='Insufficient Privileges', message=message, action='manage_main', ))
def get_paste_data(req): try: op, mdatas = _cb_decode(req['__cp']) except: raise CopyError(eInvalid) try: if mdatas[0][0].startswith('cache:'): cache_key = mdatas[0][0].replace('cache:', '') mdatas = cache.get(cache_key) except IndexError: pass paths = [] for mdata in mdatas: paths.append('/'.join(mdata)) catalog = api.portal.get_tool('portal_catalog') count = len(catalog(path={'query': paths, 'depth': -1})) return {'paths': paths, 'op': op, 'mdatas': mdatas, 'count': count}
def _verifyObjectPaste(self, object, validate_src=1): # Verify whether the current user is allowed to paste the # passed object into self. This is determined by checking # to see if the user could create a new object of the same # meta_type of the object passed in and checking that the # user actually is allowed to access the passed in object # in its existing context. # # Passing a false value for the validate_src argument will skip # checking the passed in object in its existing context. This is # mainly useful for situations where the passed in object has no # existing context, such as checking an object during an import # (the object will not yet have been connected to the acquisition # heirarchy). # # We also make sure that we are not pasting a checked-out document if IBaseDocument.providedBy(object) and object.is_checked_out(): raise CopyError('Checked out documents cannot be copied.') if not hasattr(object, 'meta_type'): raise CopyError(MessageDialog( title = 'Not Supported', message = ('The object <em>%s</em> does not support this' \ ' operation' % escape(absattr(object.id))), action = 'manage_main')) if not hasattr(self, 'all_meta_types'): raise CopyError( MessageDialog(title='Not Supported', message='Cannot paste into this object.', action='manage_main')) mt_permission = None meta_types = absattr(self.all_meta_types) for d in meta_types: if d['name'] == object.meta_type: mt_permission = d.get('permission') break if mt_permission is not None: sm = getSecurityManager() if sm.checkPermission(mt_permission, self): if validate_src: # Ensure the user is allowed to access the object on the # clipboard. try: parent = aq_parent(aq_inner(object)) except ConflictError: raise except Exception: parent = None if not sm.validate(None, parent, None, object): raise Unauthorized(absattr(object.id)) # --- Patch --- # Disable checking for `Delete objects` permission # if validate_src == 2: # moving # if not sm.checkPermission(delete_objects, parent): # raise Unauthorized('Delete not allowed.') # --- End Patch --- else: raise CopyError( MessageDialog( title='Insufficient Privileges', message=( 'You do not possess the %s permission in the ' 'context of the container into which you are ' 'pasting, thus you are not able to perform ' 'this operation.' % mt_permission), action='manage_main')) else: raise CopyError( MessageDialog( title='Not Supported', message=( 'The object <em>%s</em> does not support this ' 'operation.' % escape(absattr(object.id))), action='manage_main'))
def _verifyObjectPaste(self, *args, **kw): raise CopyError('Bad Boy!')
def __duplicate(self, cp, duplicate, is_indexable, reindex_kw, immediate_reindex): try: cp = _cb_decode(cp) except: raise CopyError(eInvalid) oblist = [] op = cp[0] app = self.getPhysicalRoot() for mdata in cp[1]: m = Moniker.loadMoniker(mdata) try: ob = m.bind(app) except: raise CopyError(eNotFound) self._verifyObjectPaste(ob, validate_src=op + 1) oblist.append(ob) result = [] def doMove(self, ob): aq_parent(aq_inner(ob))._delObject(ob.getId()) return aq_base(ob) is_doable_id, notify_error, do_sanity_check, do, set_owner, is_clone = ( ( # 0: Copy 'cb_isCopyable', 'Copy Error', lambda self, ob: True, lambda self, ob: ob._getCopy(self), 1, # Take ownership. True, ), ( # 1: Move 'cb_isMoveable', 'Move Error', sanity_check, doMove, 0, # Retain original ownership. False, ), )[op] for ob in oblist: if not getattr(ob, is_doable_id)(): raise CopyError(eNotSupported % escape(ob.getId())) try: ob._notifyOfCopyTo(self, op=op) except: raise CopyError(MessageDialog( title=notify_error, message=sys.exc_info()[1], action='manage_main', )) if not do_sanity_check(self, ob): raise CopyError('This object cannot be pasted into itself') if not set_owner: # try to make ownership explicit so that it gets carried # along to the new location if needed. ob.manage_changeOwnershipType(explicit=1) new_ob = do(self, ob) orig_id = ob.getId() new_id = self._get_id(orig_id) result.append({'id': orig_id, 'new_id': new_id}) new_ob._setId(new_id) if reindex_kw is not None: new_ob.setDefaultReindexParameterDict(reindex_kw) if is_indexable is not None and not is_indexable: new_ob._setNonIndexable() self._setObject(new_id, new_ob, set_owner=set_owner) new_ob = self._getOb(new_id) new_ob._postCopy(self, op=op) if is_clone: if duplicate: new_ob._postDuplicate() else: new_ob.manage_afterClone(new_ob) new_ob.wl_clearLocks() if not set_owner: # try to make ownership implicit if possible new_ob.manage_changeOwnershipType(explicit=0) method = new_ob.immediateReindexObject if reindex_kw is not None: method = partial(method, **reindex_kw) if isinstance(immediate_reindex, ImmediateReindexContextManager): immediate_reindex.append(method) elif immediate_reindex: # Immediately reindexing document that we just pasted is safe, as no # other transaction can by definition see it, so there cannot be a race # condition leading to stale catalog content. method() return op, result
def manage_pasteObjects_Version(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. """ # due to the ticket #14598: the need to also handle a cb_copy_data # structure that contains the desired new id on a copy/paste operation. # this feature will be used when creating a new version for an object. # if there is no new id also incapsulated in the cb_copy_data then # the copy/paste will work as default. # also the cut/paste remains the same. if cb_copy_data is not None: cp = cb_copy_data elif REQUEST is not None and '__cp' in REQUEST: cp = REQUEST['__cp'] else: cp = None if cp is None: raise CopyError(eNoData) try: op, mdatas, newids = _cb_decode(cp) except Exception: try: op, mdatas = _cb_decode(cp) newids = [] except Exception: raise CopyError(eInvalid) else: if len(mdatas) != len(newids): raise CopyError(eInvalid) oblist = [] app = self.getPhysicalRoot() for mdata in mdatas: m = loadMoniker(mdata) try: ob = m.bind(app) except ConflictError: raise except Exception: raise CopyError(eNotFound) self._verifyObjectPaste(ob, validate_src=op + 1) oblist.append(ob) if len(newids) == 0: newids = [''] * len(oblist) result = [] if op == 0: # Copy operation for ob, new_id in zip(oblist, newids): 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 Exception: raise CopyError( MessageDialog(title="Copy Error", message=sys.exc_info()[1], action='manage_main')) if new_id == '': new_id = self._get_id(orig_id) result.append({'id': orig_id, 'new_id': new_id}) orig_ob = ob ob = ob._getCopy(self) ob._setId(new_id) notify(ObjectCopiedEvent(ob, orig_ob)) self._setObject(new_id, ob) ob = self._getOb(new_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 Exception: 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): new_id = orig_id else: new_id = self._get_id(orig_id) result.append({'id': orig_id, 'new_id': new_id}) notify( ObjectWillBeMovedEvent(ob, orig_container, orig_id, self, new_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(new_id) 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, orig_container, orig_id, self, new_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 manage_pasteObjects_no_events(self, cb_copy_data=None, REQUEST=None): """Paste previously copied objects into the current object. If calling manage_pasteObjects from python code, pass the result of a previous call to manage_cutObjects or manage_copyObjects as the first argument. Also sends IObjectCopiedEvent and IObjectClonedEvent or IObjectWillBeMovedEvent and IObjectMovedEvent. """ anno = IAnnotations(self) job_id = anno.get('async_move_job') if not REQUEST: # Create a request to work with REQUEST = create_request() if cb_copy_data is not None: cp = cb_copy_data elif REQUEST is not None and REQUEST.has_key('__cp'): cp = REQUEST['__cp'] else: cp = None if cp is None: raise CopyError(eNoData) try: op, mdatas = _cb_decode(cp) except: raise CopyError(eInvalid) oblist = [] app = self.getPhysicalRoot() cat = getToolByName(self, 'portal_catalog') for mdata in mdatas: m = loadMoniker(mdata) try: ob = m.bind(app) except ConflictError: raise except: raise CopyError(eNotFound) # self._verifyObjectPaste(ob, validate_src=op+1) oblist.append(ob) result = [] steps = oblist and int(100/len(oblist)) or 0 notify(AsyncMoveSaveProgress( self, operation='initialize', job_id=job_id, oblist_id=[ (o.getId(), o.Title()) for o in oblist ])) if op == 0: # Copy operation for i, ob in enumerate(oblist): orig_id = ob.getId() if not ob.cb_isCopyable(): raise CopyError(eNotSupported % escape(orig_id)) oid = self._get_id(orig_id) result.append({'id': orig_id, 'new_id': oid}) notify(AsyncMoveSaveProgress( self, operation='sub_progress', job_id=job_id, obj_id=ob.getId(), progress=.25 )) ob = ob._getCopy(self) ob._setId(oid) notify(AsyncMoveSaveProgress( self, operation='sub_progress', job_id=job_id, obj_id=ob.getId(), progress=.50 )) self._setObject(oid, ob) ob = self._getOb(oid) ob.wl_clearLocks() notify(AsyncMoveSaveProgress( self, operation='sub_progress', job_id=job_id, obj_id=ob.getId(), progress=.75 )) ob._postCopy(self, op=0) compatibilityCall('manage_afterClone', ob, ob) notify(AsyncMoveSaveProgress( self, operation='sub_progress', job_id=job_id, obj_id=ob.getId(), progress=1 )) notify(AsyncMoveSaveProgress( self, operation='progress', job_id=job_id, progress=steps*(i+1)/100 )) if op == 1: # Move operation for i, ob in enumerate(oblist): orig_id = ob.getId() if not sanity_check(self, ob): raise CopyError( "This object cannot be pasted into itself") orig_container = aq_parent(aq_inner(ob)) if aq_base(orig_container) is aq_base(self): oid = orig_id else: oid = self._get_id(orig_id) result.append({'id': orig_id, 'new_id': oid}) unindex_object(ob, recursive=1) # try to make ownership explicit so that it gets carried # along to the new location if needed. ob.manage_changeOwnershipType(explicit=1) notify(AsyncMoveSaveProgress( self, operation='sub_progress', job_id=job_id, obj_id=ob.getId(), progress=.25 )) try: obj_path = '/'.join( orig_container.getPhysicalPath()) + '/' + orig_id orig_container._delObject(orig_id, suppress_events=True) uncatalog_path = obj_path try: uncatalog_objs = cat(path=obj_path) for obj_brain in uncatalog_objs: uncatalog_path = obj_brain.getPath() cat.uncatalog_object(uncatalog_path) except AttributeError: logger.warn("%s could not be found", uncatalog_path) except TypeError: orig_container._delObject(orig_id) logger.warn( "%s._delObject without suppress_events is discouraged.", orig_container.__class__.__name__) notify(AsyncMoveSaveProgress( self, operation='sub_progress', job_id=job_id, obj_id=ob.getId(), progress=.50 )) ob = aq_base(ob) ob._setId(oid) try: self._setObject(oid, ob, set_owner=0, suppress_events=True) except TypeError: self._setObject(oid, ob, set_owner=0) logger.warn( "%s._setObject without suppress_events is discouraged.", self.__class__.__name__) ob = self._getOb(oid) ob._postCopy(self, op=1) # try to make ownership implicit if possible ob.manage_changeOwnershipType(explicit=0) notify(AsyncMoveSaveProgress( self, operation='sub_progress', job_id=job_id, obj_id=ob.getId(), progress=.75 )) reindex_object(ob, recursive=1) notify(AsyncMoveSaveProgress( self, operation='sub_progress', job_id=job_id, obj_id=ob.getId(), progress=1 )) notify(AsyncMoveSaveProgress( self, operation='progress', job_id=job_id, progress=steps*(i+1)/100 )) notify(AsyncMoveSaveProgress( self, operation='progress', job_id=job_id, progress=1 )) del anno['async_move_job'] return result
def unrestricted_move(self, ob): """Move an object from one container to another bypassing certain checks.""" orig_id = ob.getId() if not ob.cb_isMoveable(): raise CopyError('Not supported {}'.format(escape(orig_id))) try: ob._notifyOfCopyTo(self, op=1) except ConflictError: raise except: raise CopyError( MessageDialog(title="Move Error", message=sys.exc_info()[1], action='manage_main')) if not sanity_check(self, ob): raise CopyError("This object cannot be pasted into itself") orig_container = aq_parent(aq_inner(ob)) if aq_base(orig_container) is aq_base(self): id = orig_id else: id = self._get_id(orig_id) notify(ObjectWillBeMovedEvent(ob, orig_container, orig_id, self, id)) # try to make ownership explicit so that it gets carried # along to the new location if needed. ob.manage_changeOwnershipType(explicit=1) try: orig_container._delObject(orig_id, suppress_events=True) except TypeError: # BBB: removed in Zope 2.11 orig_container._delObject(orig_id) warnings.warn( "%s._delObject without suppress_events is deprecated " "and will be removed in Zope 2.11." % orig_container.__class__.__name__, DeprecationWarning) ob = aq_base(ob) ob._setId(id) try: self._setObject(id, ob, set_owner=0, suppress_events=True) except TypeError: # BBB: removed in Zope 2.11 self._setObject(id, ob, set_owner=0) warnings.warn( "%s._setObject without suppress_events is deprecated " "and will be removed in Zope 2.11." % self.__class__.__name__, DeprecationWarning) ob = self._getOb(id) notify(ObjectMovedEvent(ob, orig_container, orig_id, self, id)) notifyContainerModified(orig_container) if aq_base(orig_container) is not aq_base(self): notifyContainerModified(self) ob._postCopy(self, op=1) # try to make ownership implicit if possible ob.manage_changeOwnershipType(explicit=0)
def __duplicate(self, cp, duplicate, is_indexable, reindex_kw, immediate_reindex): try: cp = _cb_decode(cp) except: raise CopyError(eInvalid) oblist = [] op = cp[0] app = self.getPhysicalRoot() for mdata in cp[1]: m = Moniker.loadMoniker(mdata) try: ob = m.bind(app) except: raise CopyError(eNotFound) self._verifyObjectPaste(ob, validate_src=op + 1) oblist.append(ob) result = [] def doMove(self, ob): aq_parent(aq_inner(ob))._delObject(ob.getId()) return aq_base(ob) is_doable_id, notify_error, do_sanity_check, do, set_owner, is_clone = ( ( # 0: Copy 'cb_isCopyable', 'Copy Error', lambda self, ob: True, lambda self, ob: ob._getCopy(self), 1, # Take ownership. True, ), ( # 1: Move 'cb_isMoveable', 'Move Error', sanity_check, doMove, 0, # Retain original ownership. False, ), )[op] for ob in oblist: if not getattr(ob, is_doable_id)(): raise CopyError(eNotSupported % escape(ob.getId())) try: ob._notifyOfCopyTo(self, op=op) except: raise CopyError( MessageDialog( title=notify_error, message=sys.exc_info()[1], action='manage_main', )) if not do_sanity_check(self, ob): raise CopyError('This object cannot be pasted into itself') if not set_owner: # try to make ownership explicit so that it gets carried # along to the new location if needed. ob.manage_changeOwnershipType(explicit=1) new_ob = do(self, ob) orig_id = ob.getId() new_id = self._get_id(orig_id) result.append({'id': orig_id, 'new_id': new_id}) new_ob._setId(new_id) if reindex_kw is not None: new_ob.setDefaultReindexParameterDict(reindex_kw) if is_indexable is not None and not is_indexable: new_ob._setNonIndexable() if is_clone: # Clear uids before spawning indexation activities, so the activity does # not do an uid check (as the uid is still the old one, and a new one # will be allocated by _postDuplicate, which must run after object gets # a parent). # Note: do not use __recurse as it only iterates over immediate content, # and then stop instead of calling itself into them. It relies on called # methods to call it back, and we do not want that for _setUid . # Basically this block of code is for ERP5ish objects only. todo_list = [new_ob] while todo_list: document = todo_list.pop() todo_list.extend(document.objectValues()) opaqueValues = getattr(document, 'opaqueValues', None) if opaqueValues is not None: todo_list.extend(opaqueValues()) _setUid = getattr(document, '_setUid', None) if _setUid is not None: _setUid(None) self._setObject(new_id, new_ob, set_owner=set_owner) new_ob = self._getOb(new_id) new_ob._postCopy(self, op=op) if is_clone: if duplicate: new_ob._postDuplicate() else: new_ob.manage_afterClone(new_ob) new_ob.wl_clearLocks() if not set_owner: # try to make ownership implicit if possible new_ob.manage_changeOwnershipType(explicit=0) method = new_ob.immediateReindexObject if reindex_kw is not None: method = partial(method, **reindex_kw) if isinstance(immediate_reindex, ImmediateReindexContextManager): immediate_reindex.append(method) elif immediate_reindex: # Immediately reindexing document that we just pasted is safe, as no # other transaction can by definition see it, so there cannot be a race # condition leading to stale catalog content. method() return op, result
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