def setData(self, data, metadata): """Inserts the field data on self.context """ for schemata in iterSchemata(self.context): repr = schemata(self.context) subdata = data.get(schemata.getName(), {}) for name, field in schema.getFieldsInOrder(schemata): if name not in subdata: continue value = subdata[name] value = self.unpack(name, field, value) if value == _marker: continue if name == 'description' and value == '' and isinstance( value, str): # Prevent ValueError: Description must be unicode. # Dexterity has a wrong default description which is str instead # of unicode. value = u'' setattr(repr, name, value) if HAS_RELATIONS: updateRelations(self.context, None)
def correctDocTypes(self): """ Replace references to global doc types with references to local doc types. """ request = self.REQUEST alsoProvides(request, IDisableCSRFProtection) dts = self.docTypes res = [] intids = getUtility(IIntIds) if dts: for dt in dts: t = dt.to_object new = None if t: tid = t.getId() try: new = self.config.dtypes[tid] except: pass if new: to_id = intids.getId(new) res.append(RelationValue(to_id)) self.docTypes = res updateRelations(self, None) self.setDocTypesUpdateCollection() self.reindexObject()
def test_initid_failure(self): """When an object has not yet been registered with the intid utility, getId fails with a KeyError. The event handlers need to handle this cleanly.""" # Our content is not yet registered with the intid utility # and has no __parent__ attribute try: event.updateRelations(self.content, None) except (KeyError, AttributeError): self.fail("updateRelations fails with unregistered object")
def reindex_relations(context): """Clear the relation catalog to fix issues with interfaces that don't exist anymore. This actually fixes the from_interfaces_flattened and to_interfaces_flattened indexes. """ rcatalog = getUtility(ICatalog) rcatalog.clear() catalog = api.portal.get_tool('portal_catalog') brains = catalog.searchResults(object_provides=IHasRelations.__identifier__) for brain in brains: obj = brain.getObject() updateRelations(obj, None)
def migrate_schema_fields(self): intids = component.getUtility(IIntIds) piece = [ i for i in api.content.find(portal_type='troupedu8.Piece') if i.Title == self.old.Title() ][0] relpiece = RelationValue(intids.getId(piece.getObject())) self.new.piece = relpiece updateRelations(self.new, None) for item in self.old.values(): api.content.move(source=item, target=self.new)
def reindex_relations(context): rcatalog = getUtility(ICatalog) # Clear the relation catalog to fix issues with interfaces that don't exist # anymore. rcatalog.clear() catalog = getToolByName(context, 'portal_catalog') brains = catalog.searchResults( object_provides=IHasRelations.__identifier__) for brain in brains: obj = brain.getObject() updateRelations(obj, None)
def uninvite_workspace(self, workspace, update=True): found = False ws_intid = workspace.intid for relation in self.invited_workspaces: if relation.to_id == ws_intid: self.invited_workspaces.remove(relation) found = True if found and update: updateRelations(self, None) return found
def add_workspace(self, workspace): was_invited = self.uninvite_workspace(workspace, update=False) if not was_invited: checkPermission = getSecurityManager().checkPermission if not checkPermission(AddPortalContent, self): raise Unauthorized self.clean_workspace_relations() self.workspace_relations.append(RelationValue(workspace.intid)) updateRelations(self, None)
def reindex_zc_relations(context): ''' Upgrade to version 1001 reindex zc.relations catalog ''' rcatalog = getUtility(ICatalog) # Clear the relation catalog to fix issues with interfaces that don't exist anymore. # This actually fixes the bug editing employees than reports a: # KeyError: <class 'plone.directives.form.schema.Schema'> rcatalog.clear() catalog = getToolByName(context, 'portal_catalog') brains = catalog.searchResults(object_provides=IHasRelations.__identifier__) for brain in brains: obj = brain.getObject() updateRelations(obj, None)
def to2(context): setup = getToolByName(context, 'portal_setup') setup.runAllImportStepsFromProfile('profile-wcc.books.upgrades:to2') portal_catalog = getToolByName(context, 'portal_catalog') intids = getUtility(IIntIds) for b in portal_catalog( portal_type=['wcc.books.book'], Language='all'): obj = b.getObject() for name, relation in _relations(obj): try: relation.to_id = intids.getId(relation.to_object) except KeyError: continue updateRelations(obj, None)
def to1005(context): setup = getToolByName(context, 'portal_setup') setup.runAllImportStepsFromProfile('profile-wcc.churches.upgrades:to1005') portal_catalog = getToolByName(context, 'portal_catalog') catalog = getUtility(ICatalog) intids = getUtility(IIntIds) for b in portal_catalog(portal_type=[ 'wcc.churches.churchmember', 'wcc.churches.churchfamily', 'wcc.churches.churchbody' ], Language='all'): obj = b.getObject() for name, relation in _relations(obj): try: relation.to_id = intids.getId(relation.to_object) except KeyError: continue updateRelations(obj, None)
def setData(self, data, metadata): """Inserts the field data on self.context """ for schemata in iterSchemata(self.context): repr = schemata(self.context) subdata = data.get(schemata.getName(), {}) for name, field in schema.getFieldsInOrder(schemata): if name not in subdata: continue value = subdata[name] value = self.unpack(name, field, value) if value == _marker: continue if name == 'description' and value == '' and isinstance(value, str): # Prevent ValueError: Description must be unicode. # Dexterity has a wrong default description which is str instead # of unicode. value = u'' setattr(repr, name, value) if HAS_RELATIONS: updateRelations(self.context, None)
def migrate(context): intids = component.getUtility(IIntIds) portal = api.portal.get() with open('acteurs.csv') as csv_file: csv_reader = csv.DictReader(csv_file, delimiter='|') for row in csv_reader: piece = row['piece'] acteur = row['acteur'] prenom = acteur.split(' ')[0] nom = ' '.join(acteur.split(' ')[1:]) dbpiece = [ i for i in api.content.find(portal_type='troupedu8.Piece') if i.Title == piece ] dbacteur = [ i for i in api.content.find(portal_type='troupedu8.Acteur') if i.Title == acteur ] if not dbpiece: raise Exception("%s n'existe pas" % piece) elif len(dbpiece) > 1: raise Exception("%s existe plusieurs fois" % piece) else: dbpiece = dbpiece[0].getObject() if not dbacteur: dbacteur = api.content.create( type='troupedu8.Acteur', title=acteur.decode('utf8'), firstname=prenom.decode('utf8'), lastname=nom.decode('utf8'), container=api.content.get('/acteurs')) api.content.transition(dbacteur, transition='publish') elif len(dbacteur) > 1: raise Exception("%s existe plusieurs fois" % acteur) else: dbacteur = dbacteur[0].getObject() if not dbpiece.acteurs: dbpiece.acteurs = [RelationValue(intids.getId(dbacteur))] else: if intids.getId(dbacteur) not in [ i.to_id for i in dbpiece.acteurs ]: dbpiece.acteurs.append( RelationValue(intids.getId(dbacteur))) updateRelations(dbpiece, None) updateRelations(dbacteur, None) dbpiece.reindexObject() brains = portal.portal_catalog( portal_type=['troupedu8.Acteur', 'troupedu8.Piece']) for brain in brains: collection = brain.getObject() updateRelations(collection, None) collection.reindexObject()
def restore_relations(context=None, all_relations=None): """Restore relations from a annotation on the portal. """ portal = api.portal.get() if all_relations is None: all_relations = IAnnotations(portal)[RELATIONS_KEY] logger.info('Loaded {0} relations to restore'.format(len(all_relations))) update_linkintegrity = set() modified_items = set() modified_relation_lists = defaultdict(list) # remove duplicates but keep original order unique_relations = [] seen = set() seen_add = seen.add for i in all_relations: hashable = tuple(i.items()) if hashable not in seen: unique_relations.append(i) seen_add(hashable) else: logger.info(u'Dropping duplicate: {}'.format(hashable)) if len(unique_relations) < len(all_relations): logger.info('Dropping {0} duplicates'.format( len(all_relations) - len(unique_relations))) all_relations = unique_relations intids = getUtility(IIntIds) for index, item in enumerate(all_relations, start=1): if not index % 500: logger.info(u'Restored {} of {} relations...'.format( index, len(all_relations))) source_obj = uuidToObject(item['from_uuid']) target_obj = uuidToObject(item['to_uuid']) if not source_obj: logger.info(u'{} is missing'.format(item['from_uuid'])) continue if not target_obj: logger.info(u'{} is missing'.format(item['to_uuid'])) continue if not IDexterityContent.providedBy(source_obj): logger.info(u'{} is no dexterity content'.format( source_obj.portal_type)) continue if not IDexterityContent.providedBy(target_obj): logger.info(u'{} is no dexterity content'.format( target_obj.portal_type)) continue from_attribute = item['from_attribute'] to_id = intids.getId(target_obj) if from_attribute == referencedRelationship: # Ignore linkintegrity for now. We'll rebuilt it at the end! update_linkintegrity.add(item['from_uuid']) continue if from_attribute == ITERATE_RELATION_NAME: # Iterate relations are not set as values of fields relation = StagingRelationValue(to_id) event._setRelation(source_obj, ITERATE_RELATION_NAME, relation) continue field_and_schema = get_field_and_schema_for_fieldname( from_attribute, source_obj.portal_type) if field_and_schema is None: # the from_attribute is no field # we could either create a fresh relation or log the case logger.info(u'No field. Setting relation: {}'.format(item)) event._setRelation(source_obj, from_attribute, RelationValue(to_id)) continue field, schema = field_and_schema relation = RelationValue(to_id) if isinstance(field, RelationList): logger.info( 'Add relation to relationslist {} from {} to {}'.format( from_attribute, source_obj.absolute_url(), target_obj.absolute_url())) if item['from_uuid'] in modified_relation_lists.get( from_attribute, []): # Do not purge relations existing_relations = getattr(source_obj, from_attribute, []) else: # First touch. Make sure we purge! existing_relations = [] existing_relations.append(relation) setattr(source_obj, from_attribute, existing_relations) modified_items.add(item['from_uuid']) modified_relation_lists[from_attribute].append(item['from_uuid']) continue elif isinstance(field, (Relation, RelationChoice)): logger.info('Add relation {} from {} to {}'.format( from_attribute, source_obj.absolute_url(), target_obj.absolute_url())) setattr(source_obj, from_attribute, relation) modified_items.add(item['from_uuid']) continue else: # we should never end up here! logger.info('Warning: Unexpected relation {} from {} to {}'.format( from_attribute, source_obj.absolute_url(), target_obj.absolute_url())) update_linkintegrity = set(update_linkintegrity) logger.info('Updating linkintegrity for {} items'.format( len(update_linkintegrity))) for uuid in sorted(update_linkintegrity): modifiedContent(uuidToObject(uuid), None) logger.info('Updating relations for {} items'.format(len(modified_items))) for uuid in sorted(modified_items): obj = uuidToObject(uuid) # updateRelations from z3c.relationfield does not properly update relations in behaviors # that are registered with a marker-interface. # update_behavior_relations (from plone.app.relationfield) does that but does not update # those in the main schema. Duh! updateRelations(obj, None) update_behavior_relations(obj, None) # purge annotation from portal if they exist if RELATIONS_KEY in IAnnotations(portal): del IAnnotations(portal)[RELATIONS_KEY] logger.info('Done!')
from z3c.relationfield.interfaces import IHasRelations from Products.CMFCore.utils import getToolByName logger = logging.getLogger() logger.setLevel(logging.DEBUG) handler = logging.StreamHandler(sys.stdout) formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") handler.setFormatter(formatter) logger.addHandler(handler) ''' Upgrade to version 1001 reindex zc.relations catalog ''' rcatalog = getUtility(ICatalog) # Clear the relation catalog to fix issues with interfaces that don't exist anymore. # This actually fixes the bug editing employees than reports a: # KeyError: <class 'plone.directives.form.schema.Schema'> transaction.begin() rcatalog.clear() site = app.get('Plone') catalog = getToolByName(site, 'portal_catalog') brains = catalog.searchResults(object_provides=IHasRelations.__identifier__) for brain in brains: logger.info(obj) obj = brain.getObject() updateRelations(obj, None) transaction.commit()
def invite_workspace(self, workspace): # prevent appending to the default-value: self.invited_workspaces = self.invited_workspaces self.invited_workspaces.append(RelationValue(workspace.intid)) updateRelations(self, None)