def _get_position_in_parent(obj): # Use IOrderedContainer interface to extract the object's manual ordering position parent = obj.aq_inner.aq_parent ordered = IOrderedContainer(parent, None) if ordered is not None: return ordered.getObjectPosition(obj.getId()) return 0
def set_positions_in_parent(self): """ Set positions of container object given by `id` and `position` """ data = json.loads(self.request.BODY) num_data = len(data) for i, item in enumerate(data): path = item['path'] position = item['position'] print(i, num_data, path, position) obj = self.context.restrictedTraverse(path, None) if obj is None: continue try: ordered = IOrderedContainer(obj.aq_parent) except (AttributeError, TypeError) as e: print(e) continue try: ordered.moveObjectToPosition(obj.getId(), position) except ValueError as e: print(e) continue obj.reindexObject(idxs=['getObjPositionInParent']) self.request.response.setStatus(204)
def test_export_ordering(self): # First create some content. app = self.layer["app"] portal = self.layer["portal"] login(app, SITE_OWNER_NAME) folder1 = api.content.create( container=portal, type="Folder", id="folder1", title="Folder 1" ) doc1 = api.content.create( container=folder1, type="Document", id="doc1", title="Document 1" ) doc2 = api.content.create( container=folder1, type="Document", id="doc2", title="Document 2" ) doc3 = api.content.create( container=folder1, type="Document", id="doc3", title="Document 3" ) transaction.commit() # Export. browser = self.open_page("@@export_ordering") browser.getForm(action="@@export_ordering").submit(name="form.submitted") contents = browser.contents if not browser.contents: contents = DATA[-1] data = json.loads(contents) # Turn the list into a dict for easier searching and comparing. data_uuid2order = {} for item in data: data_uuid2order[item["uuid"]] = item["order"] data_uuids = sorted(data_uuid2order.keys()) # All content UIDs are in the export: content_uuids = sorted([item.UID() for item in (folder1, doc1, doc2, doc3)]) self.assertListEqual(data_uuids, content_uuids) # All documents have the correct order: self.assertEqual(data_uuid2order[doc1.UID()], 0) self.assertEqual(data_uuid2order[doc2.UID()], 1) self.assertEqual(data_uuid2order[doc3.UID()], 2) # Reorder the documents. ordered = IOrderedContainer(folder1) ordered.moveObjectsToTop(["doc3"]) transaction.commit() # Export and check. browser = self.open_page("@@export_ordering") browser.getForm(action="@@export_ordering").submit(name="form.submitted") contents = browser.contents if not browser.contents: contents = DATA[-1] data = json.loads(contents) data_uuid2order = {} for item in data: data_uuid2order[item["uuid"]] = item["order"] self.assertEqual(data_uuid2order[doc3.UID()], 0) self.assertEqual(data_uuid2order[doc1.UID()], 1) self.assertEqual(data_uuid2order[doc2.UID()], 2)
def revertOrder(obj, eve): """ Use IOrderedContainer interface to move an object to top of folder on creation. """ parent = obj.aq_inner.aq_parent ordered = IOrderedContainer(parent, None) if ordered is not None: ordered.moveObjectToPosition(obj.getId(), 0)
def set_position_in_parent(self): """ Set position of container object given by `id` and `position` """ data = json.loads(self.request.BODY) position = int(data["position"]) ordered = IOrderedContainer(self.context.aq_parent) ordered.moveObjectToPosition(self.context.getId(), position) self.request.response.setStatus(204)
def getObjPositionInParent(obj): """ Helper method for catalog based folder contents. """ parent = aq_parent(aq_inner(obj)) ordered = IOrderedContainer(parent, None) if ordered is not None: return ordered.getObjectPosition(obj.getId()) return 0
def _getPositionInParent(obj): parent = aq_parent(aq_inner(obj)) ordered = IOrderedContainer(parent, None) if ordered is not None: pos = ordered.getObjectPosition(obj.getId()) else: pos = 0 return pos
def keys(param): """ Goal: order by level of folder, parent folder, position in folder,""" (obj, path) = param level = len(path.split('/')) parent = aq_parent(aq_inner(obj)) ordered = IOrderedContainer(parent, None) if ordered is not None: return (level, path, ordered.getObjectPosition(obj.getId())) return (level, path, 0)
def get_position_in_parent(obj, path): uid = IUUID(obj, None) if not uid: return parent = obj.__parent__ ordered = IOrderedContainer(parent, None) if ordered is not None: order = ordered.getObjectPosition(obj.getId()) results.append({"uuid": uid, "order": order}) return
def getObjPositionInParent(obj): """ Helper method for catalog based folder contents. Overwritten here to avoid problem during unindexing. """ parent = aq_parent(aq_inner(obj)) ordered = IOrderedContainer(parent, None) if ordered is not None: try: return ordered.getObjectPosition(obj.getId()) except ValueError: return 0 return 0
def getObjPositionInParent(obj): """ Helper method for catalog based folder contents. >>> from Products.CMFPlone.CatalogTool import getObjPositionInParent >>> getObjPositionInParent(self.folder) 0 """ parent = aq_parent(aq_inner(obj)) ordered = IOrderedContainer(parent, None) if ordered is not None: return ordered.getObjectPosition(obj.getId()) return 0
def getOrdering(self): if IPloneSiteRoot.providedBy(self.context): return self.context try: ordering = self.context.aq_base.getOrdering() except AttributeError: if IOrderedContainer.providedBy(self.context): # Archetype return IOrderedContainer(self.context) return None if not IExplicitOrdering.providedBy(ordering): return None return ordering
def migrate(self, unittest=0): """Migrates the object """ beforeChange, afterChange = self.getMigrationMethods() # Unlock according to plone.locking: lockable = ILockable(self.old, None) if lockable and lockable.locked(): lockable.unlock() # Unlock according to webdav: if self.old.wl_isLocked(): self.old.wl_clearLocks() for method in beforeChange: __traceback_info__ = (self, method, self.old, self.orig_id) # may raise an exception, catch it later method() # preserve position on rename self.need_order = IOrderedContainer.providedBy(self.parent) if self.need_order: self._position = self.parent.getObjectPosition(self.orig_id) self.renameOld() self.createNew() for method in afterChange: __traceback_info__ = (self, method, self.old, self.orig_id) # may raise an exception, catch it later method() self.reorder() self.remove()
def __init__(self, context): self.context = context self.mship = getToolByName(self.context, 'portal_membership') self.sort = IOrderedContainer.providedBy(self.context) and self.mship.checkPermission(permissions.ModifyPortalContent, self.context) self.sort_url = '%s/article_moveitem?anchor=%%s&delta=%%s&item_id=%%s' % self.context.absolute_url() self.show_hide_url = '%s/@@article_showhideitem?anchor=%%s&action=%%s&uid=%%s&component=%%s' % self.context.absolute_url() self.delete = self.mship.checkPermission(permissions.DeleteObjects, self.context)
def migrate_children(self): """Copy childish objects from the old folder to the new one """ subobjs = self.subobjs for id, obj in subobjs.items(): # we have to use _setObject instead of _setOb because it adds the object # to folder._objects but also reindexes all objects. __traceback_info__ = __traceback_info__ = ('migrate_children', self.old, self.orig_id, 'Migrating subobject %s' % id) try: self.new._setObject(id, obj, set_owner=0) except BadRequest: # If we already have the object we need to remove it carefully # and retry. We can assume that such an object must be # autogenerated by a prior migration step and thus is less # correct than the original. Such objects may want to # consider setting the attribute '__replaceable__' to avoid # this. if id in self.new.objectIds(): self.new._delOb(id) if getattr(self.new, '_objects', None) is not None: self.new._objects = tuple([o for o in self.new._objects if o['id'] != id]) self.new._setObject(id, obj, set_owner=0) else: raise # reorder items # in CMF 1.5 Topic is orderable while ATCT's Topic is not orderable # order objects only when old *and* new are orderable we can't check # when creating the map because self.new == None. if self.orderAble and IOrderedContainer.providedBy(self.new): orderMap = self.orderMap for id, pos in orderMap.items(): self.new.moveObjectToPosition(id, pos)
def import_ordering(self, data): results = 0 total = len(data) for index, item in enumerate(data, start=1): obj = api.content.get(UID=item["uuid"]) if not obj: continue ordered = IOrderedContainer(obj.__parent__, None) if not ordered: continue ordered.moveObjectToPosition(obj.getId(), item["order"]) if not index % 1000: logger.info(u"Ordered {} ({}%) of {} items".format( index, round(index / total * 100, 2), total)) results += 1 return results
def migrate(self, unittest=0): """Migrates the object """ beforeChange, afterChange = self.getMigrationMethods() lockable = ILockable(self.old, None) if lockable and lockable.locked(): lockable.unlock() for method in beforeChange: __traceback_info__ = (self, method, self.old, self.orig_id) # may raise an exception, catch it later method() # preserve position on rename self.need_order = IOrderedContainer.providedBy(self.parent) if self.need_order: self._position = self.parent.getObjectPosition(self.orig_id) self.renameOld() self.createNew() for method in afterChange: __traceback_info__ = (self, method, self.old, self.orig_id) # may raise an exception, catch it later method() self.reorder() self.remove()
def __init__(self, context): self.pos = [] self.component = '' self.context = context self.mship = getToolByName(self.context, 'portal_membership') self.delete = self.mship.checkPermission(permissions.DeleteObjects, self.context) or False self.sort = (IOrderedContainer.providedBy(self.context) and self.mship.checkPermission(permissions.ModifyPortalContent, self.context)) or False
def __call__(self, config): parent = aq_parent(aq_inner(self.context)) klass = self.context.__class__ owner = self.context.getOwner() data = {'_classname': klass.__name__, '_class': klass.__module__ + '.' + klass.__name__, '_id': self.context.getId(), '_owner': owner and owner.getId(), '_path': '/'.join(self.context.getPhysicalPath()), '_type': self.context.portal_type} ordered_parent = IOrderedContainer(parent, None) if ordered_parent: data['_obj_position_in_parent'] = ordered_parent.getObjectPosition( self.context.getId()) return data
def _extractObjects(self): fragment = self._doc.createDocumentFragment() objects = self.context.objectValues() if not IOrderedContainer.providedBy(self.context): objects = list(objects) objects.sort(lambda x,y: cmp(x.getId(), y.getId())) for obj in objects: exporter = queryMultiAdapter((obj, self.environ), INode) if exporter: fragment.appendChild(exporter.node) return fragment
def _extractObjects(self): fragment = self._doc.createDocumentFragment() objects = self.context.objectValues() if not IOrderedContainer.providedBy(self.context): objects = list(objects) objects.sort(lambda x, y: cmp(x.getId(), y.getId())) for obj in objects: exporter = queryMultiAdapter((obj, self.environ), INode) if exporter: fragment.appendChild(exporter.node) return fragment
def __call__(self, config): parent = aq_parent(aq_inner(self.context)) klass = self.context.__class__ owner = self.context.getOwner() data = { '_classname': klass.__name__, '_class': klass.__module__ + '.' + klass.__name__, '_id': self.context.getId(), '_owner': owner and owner.getId(), '_path': '/'.join(self.context.getPhysicalPath()), '_type': self.context.portal_type } ordered_parent = IOrderedContainer(parent, None) if ordered_parent: data['_obj_position_in_parent'] = ordered_parent.getObjectPosition( self.context.getId()) return data
def orderable(self): """ """ if self.is_special_type(): return True iface = IOrderedContainer.providedBy(aq_inner(self.context)) attr = self.context.aq_explicit\ .get('sortAttribute', '') == 'getObjPositionInParent' if self.contentFilter.get('sort_on', '') != 'getObjPositionInParent': return False return iface and attr
def _extractObjects(self): fragment = self._doc.createDocumentFragment() objects = self.context.objectValues() if not IOrderedContainer.providedBy(self.context): objects = list(objects) objects.sort(lambda x, y: cmp(x.getId(), y.getId())) for obj in objects: # Check if the object can be exported if not can_export(obj): logger.info("Skipping {}".format(repr(obj))) continue exporter = queryMultiAdapter((obj, self.environ), INode) if exporter: node = exporter.node if node is not None: fragment.appendChild(exporter.node) return fragment
def beforeChange_storeSubojects(self): """store subobjects from old folder This methods gets all subojects from the old folder and removes them from the old. It also preservers the folder order in a dict. For performance reasons the objects are removed from the old folder before it is renamed. Elsewise the objects would be reindex more often. """ orderAble = IOrderedContainer.providedBy(self.old) orderMap = {} subobjs = {} # using objectIds() should be safe with BrokenObjects for id in self.old.objectIds(): obj = getattr(self.old.aq_inner.aq_explicit, id) # Broken object support. Maybe we are able to migrate them? if isinstance(obj, BrokenClass): LOG.warning('BrokenObject in %s' % self.old.absolute_url(1)) #continue if orderAble: try: orderMap[id] = self.old.getObjectPosition(id) except AttributeError: LOG.debug("Broken OrderSupport", exc_info=True) orderAble = 0 subobjs[id] = aq_base(obj) # delOb doesn't call manage_afterAdd which safes some time because it # doesn't unindex an object. The migrate children method uses # _setObject later. This methods indexes the object again and # so updates all catalogs. for id in self.old.objectIds(): # Loop again to remove objects, order is not preserved when # deleting objects self.old._delOb(id) # We need to take care to remove the relevant ids from _objects # otherwise objectValues breaks. if getattr(self.old, '_objects', None) is not None: self.old._objects = tuple([o for o in self.old._objects if o['id'] != id]) self.orderMap = orderMap self.subobjs = subobjs self.orderAble = orderAble
def beforeChange_storeSubojects(self): """store subobjects from old folder This methods gets all subojects from the old folder and removes them from the old. It also preservers the folder order in a dict. For performance reasons the objects are removed from the old folder before it is renamed. Elsewise the objects would be reindex more often. """ orderAble = IOrderedContainer.providedBy(self.old) orderMap = {} subobjs = {} # using objectIds() should be safe with BrokenObjects for id in self.old.objectIds(): obj = getattr(self.old.aq_inner.aq_explicit, id) # Broken object support. Maybe we are able to migrate them? if isinstance(obj, BrokenClass): LOG.warning('BrokenObject in %s' % self.old.absolute_url(1)) #continue if orderAble: try: orderMap[id] = self.old.getObjectPosition(id) or 0 except AttributeError: LOG.debug("Broken OrderSupport", exc_info=True) orderAble = 0 subobjs[id] = aq_base(obj) # delOb doesn't call manage_afterAdd which safes some time because it # doesn't unindex an object. The migrate children method uses # _setObject later. This methods indexes the object again and # so updates all catalogs. for id in self.old.objectIds(): # Loop again to remove objects, order is not preserved when # deleting objects self.old._delOb(id) # We need to take care to remove the relevant ids from _objects # otherwise objectValues breaks. if getattr(self.old, '_objects', None) is not None: self.old._objects = tuple( [o for o in self.old._objects if o['id'] != id]) self.orderMap = orderMap self.subobjs = subobjs self.orderAble = orderAble
def __call__(self): if not self.is_setup_with_subinboxes(): log.warn('ConvertMainInboxes upgradestep skipped,' 'because it is not an setup with multiptle subinboxes') return main_inbox = self.get_main_inbox() local_roles = main_inbox.get_local_roles() position = IOrderedContainer(self.portal).getObjectPosition( main_inbox.getId()) # create temp container and move inbox-content inside temp_container = createContentInContainer(self.portal, 'opengever.inbox.container', title=u'Temp. Eingangskorb') self.move_all_items(source_container=main_inbox, target=temp_container) self.safe_delete(main_inbox) # create real inbox container and move temp-content inside inbox_container = createContentInContainer(self.portal, 'opengever.inbox.container', id='eingangskorb', title=u'Eingangskorb') self.move_all_items(source_container=temp_container, target=inbox_container) self.safe_delete(temp_container) # readd the local roles for principal, roles in local_roles: roles_list = [item for item in roles] inbox_container.manage_setLocalRoles(principal, roles_list) inbox_container.reindexObjectSecurity() # set original position self.portal.moveObject(inbox_container.getId(), position)
def _copyPortalAttributes(self, peer): peer.portal_type = self.context.portal_type peer.content_uid = self.context.UID() peer.id = self.context.id peer.path = '/'.join(self.context.getPhysicalPath()) portal_url = getattr(self.context, 'portal_url', None) if portal_url: peer.relative_path = "/".join( portal_url.getRelativeContentPath(self.context)) wf_tool = getattr(self.context, 'portal_workflow', None) if wf_tool is None: return peer.status = wf_tool.getCatalogVariablesFor( self.context).get('review_state') container = self.context.getParentNode() if not IOrderedContainer.providedBy(container): return peer.folder_position = container.getObjectPosition( self.context.getId())
def migrate_children(self): """Copy childish objects from the old folder to the new one """ subobjs = self.subobjs for id, obj in subobjs.items(): # we have to use _setObject instead of _setOb because it adds the object # to folder._objects but also reindexes all objects. __traceback_info__ = __traceback_info__ = ( 'migrate_children', self.old, self.orig_id, 'Migrating subobject %s' % id) try: self.new._setObject(id, obj, set_owner=0) except BadRequest: # If we already have the object we need to remove it carefully # and retry. We can assume that such an object must be # autogenerated by a prior migration step and thus is less # correct than the original. Such objects may want to # consider setting the attribute '__replaceable__' to avoid # this. if id in self.new.objectIds(): self.new._delOb(id) if getattr(self.new, '_objects', None) is not None: self.new._objects = tuple( [o for o in self.new._objects if o['id'] != id]) self.new._setObject(id, obj, set_owner=0) else: raise # reorder items # in CMF 1.5 Topic is orderable while ATCT's Topic is not orderable # order objects only when old *and* new are orderable we can't check # when creating the map because self.new == None. if self.orderAble and IOrderedContainer.providedBy(self.new): orderMap = self.orderMap for id, pos in orderMap.items(): self.new.moveObjectToPosition(id, pos)
def __call__(self): log = self.mklog() real = timer() self.install_folderish_types() log("collective.folderishtypes installed.") catalog = api.portal.get_tool("portal_catalog") catalog.clearFindAndRebuild() log("Portal catalog has been rebuilt.") changed_base_classes = [ "plone.app.contenttypes.content.Document", "plone.app.contenttypes.content.NewsItem", "plone.app.contenttypes.content.Event", ] migrated = [] not_migrated = [] for brain in catalog(): obj = brain.getObject() old_class_name = dxmigration.get_old_class_name_string(obj) if old_class_name in changed_base_classes: prevented_delete = prevented_move = False obj_id = obj.getId() parent = aq_parent(aq_inner(obj)) if IPreventDelete.providedBy(obj): prevented_delete = True noLongerProvides(obj, IPreventDelete) if IPreventMoveOrRename.providedBy(obj): prevented_move = True noLongerProvides(obj, IPreventMoveOrRename) position_in_parent = None ordered = IOrderedContainer(parent, None) if ordered is not None: position_in_parent = ordered.getObjectPosition(obj_id) if dxmigration.migrate_base_class_to_new_class( obj, migrate_to_folderish=True): migrated.append(obj) if position_in_parent is not None: ordered.moveObject(obj_id, position_in_parent) if prevented_delete: alsoProvides(obj, IPreventDelete) if prevented_move: alsoProvides(obj, IPreventMoveOrRename) else: not_migrated.append(obj) if migrated: log("{0} objects have been migrated.".format(len(migrated))) if not_migrated: log( "{0} objects have NOT been migrated.".format( len(not_migrated)), level="warn", ) catalog.clearFindAndRebuild() log("Portal catalog has been rebuilt.") msg = "Processed folderish types migration in {0}.".format(real.next()) log(msg)
def test_implementsOrderInterface(self): self.assertTrue(IOrderedContainer.providedBy(self._ATCT)) self.assertTrue(verifyObject(IOrderedContainer, self._ATCT))
def test_isOrdered(self): self.failUnless(IOrderedContainer.providedBy(self._ATCT))
def test_isOrdered(self): self.assertTrue(IOrderedContainer.providedBy(self._ATCT))
def test_implementsOrderInterface(self): self.failUnless(OFSIOrderedContainer.providedBy(self._ATCT)) self.failUnless(IZopeOrderedContainer.isImplementedBy(self._ATCT)) self.failUnless(IOrderedContainer.isImplementedBy(self._ATCT)) self.failUnless(verifyObject(IZopeOrderedContainer, self._ATCT)) self.failUnless(verifyObject(IOrderedContainer, self._ATCT))
def get_position_in_parent(obj): parent = obj.aq_inner.aq_parent ordered = IOrderedContainer(parent, None) if ordered is not None: return ordered.getObjectPosition(obj.getId()) return 0
def test_implementsOrderInterface(self): self.failUnless(IOrderedContainer.providedBy(self._ATCT)) self.failUnless(verifyObject(IOrderedContainer, self._ATCT))
def test_ordered_container_interface(self): """Verify the OrderedContainer interface being used.""" self.assertTrue(IOrderedContainer.providedBy(self.folder))
def orderable(self): """ """ return IOrderedContainer.providedBy(aq_inner(self.context))