231 etype = entity.__regid__ |
231 etype = entity.__regid__ |
232 for (rtype, role, action), rules in self.source.mapping.get(etype, {}).iteritems(): |
232 for (rtype, role, action), rules in self.source.mapping.get(etype, {}).iteritems(): |
233 try: |
233 try: |
234 related_items = rels[role][rtype] |
234 related_items = rels[role][rtype] |
235 except KeyError: |
235 except KeyError: |
236 self.source.error('relation %s-%s not found in xml export of %s', |
236 self.import_log.record_error('relation %s-%s not found in xml export of %s' |
237 rtype, role, etype) |
237 % (rtype, role, etype)) |
238 continue |
238 continue |
239 try: |
239 try: |
240 linker = self.select_linker(action, rtype, role, entity) |
240 linker = self.select_linker(action, rtype, role, entity) |
241 except RegistryException: |
241 except RegistryException: |
242 self.source.error('no linker for action %s', action) |
242 self.import_log.record_error('no linker for action %s' % action) |
243 else: |
243 else: |
244 linker.link_items(related_items, rules) |
244 linker.link_items(related_items, rules) |
245 |
245 |
246 def before_entity_copy(self, entity, sourceparams): |
246 def before_entity_copy(self, entity, sourceparams): |
247 """IDataFeedParser callback""" |
247 """IDataFeedParser callback""" |
428 |
428 |
429 def _related_link(self, ttype, others, searchattrs): |
429 def _related_link(self, ttype, others, searchattrs): |
430 def issubset(x,y): |
430 def issubset(x,y): |
431 return all(z in y for z in x) |
431 return all(z in y for z in x) |
432 eids = [] # local eids |
432 eids = [] # local eids |
433 source = self.parser.source |
433 log = self.parser.import_log |
434 for item, rels in others: |
434 for item, rels in others: |
435 if item['cwtype'] != ttype: |
435 if item['cwtype'] != ttype: |
436 continue |
436 continue |
437 if not issubset(searchattrs, item): |
437 if not issubset(searchattrs, item): |
438 item, rels = self.parser.complete_item(item, rels) |
438 item, rels = self.parser.complete_item(item, rels) |
439 if not issubset(searchattrs, item): |
439 if not issubset(searchattrs, item): |
440 source.error('missing attribute, got %s expected keys %s', |
440 log.record_error('missing attribute, got %s expected keys %s' |
441 item, searchattrs) |
441 % (item, searchattrs)) |
442 continue |
442 continue |
443 # XXX str() needed with python < 2.6 |
443 # XXX str() needed with python < 2.6 |
444 kwargs = dict((str(attr), item[attr]) for attr in searchattrs) |
444 kwargs = dict((str(attr), item[attr]) for attr in searchattrs) |
445 targets = self._find_entities(item, kwargs) |
445 targets = self._find_entities(item, kwargs) |
446 if len(targets) == 1: |
446 if len(targets) == 1: |
447 entity = targets[0] |
447 entity = targets[0] |
448 elif not targets and self.create_when_not_found: |
448 elif not targets and self.create_when_not_found: |
449 entity = self._cw.create_entity(item['cwtype'], **kwargs) |
449 entity = self._cw.create_entity(item['cwtype'], **kwargs) |
450 else: |
450 else: |
451 if len(targets) > 1: |
451 if len(targets) > 1: |
452 source.error('ambiguous link: found %s entity %s with attributes %s', |
452 log.record_error('ambiguous link: found %s entity %s with attributes %s' |
453 len(targets), item['cwtype'], kwargs) |
453 % (len(targets), item['cwtype'], kwargs)) |
454 else: |
454 else: |
455 source.error('can not find %s entity with attributes %s', |
455 log.record_error('can not find %s entity with attributes %s' |
456 item['cwtype'], kwargs) |
456 % (item['cwtype'], kwargs)) |
457 continue |
457 continue |
458 eids.append(entity.eid) |
458 eids.append(entity.eid) |
459 self.parser.process_relations(entity, rels) |
459 self.parser.process_relations(entity, rels) |
460 if eids: |
460 if eids: |
461 self._set_relation(eids) |
461 self._set_relation(eids) |