200 # cwuri of entities from this source, and compare with newly imported ones |
200 # cwuri of entities from this source, and compare with newly imported ones |
201 |
201 |
202 def process_item(self, item, rels): |
202 def process_item(self, item, rels): |
203 entity = self.extid2entity(str(item.pop('cwuri')), item.pop('cwtype'), |
203 entity = self.extid2entity(str(item.pop('cwuri')), item.pop('cwtype'), |
204 item=item) |
204 item=item) |
|
205 if entity is None: |
|
206 return None |
205 if not (self.created_during_pull(entity) or self.updated_during_pull(entity)): |
207 if not (self.created_during_pull(entity) or self.updated_during_pull(entity)): |
206 self.notify_updated(entity) |
208 self.notify_updated(entity) |
207 item.pop('eid') |
209 item.pop('eid') |
208 # XXX check modification date |
210 # XXX check modification date |
209 attrs = extract_typed_attrs(entity.e_schema, item) |
211 attrs = extract_typed_attrs(entity.e_schema, item) |
231 """implementation of 'copy' action |
233 """implementation of 'copy' action |
232 |
234 |
233 Takes no option. |
235 Takes no option. |
234 """ |
236 """ |
235 assert not any(x[1] for x in rules), "'copy' action takes no option" |
237 assert not any(x[1] for x in rules), "'copy' action takes no option" |
236 ttypes = set([x[0] for x in rules]) |
238 ttypes = frozenset([x[0] for x in rules]) |
237 others = [item for item in others if item['cwtype'] in ttypes] |
|
238 eids = [] # local eids |
239 eids = [] # local eids |
239 if not others: |
240 for item in others: |
|
241 if item['cwtype'] in ttypes: |
|
242 item, _rels = self._complete_item(item) |
|
243 other_entity = self.process_item(item, []) |
|
244 if other_entity is not None: |
|
245 eids.append(other_entity.eid) |
|
246 if eids: |
|
247 self._set_relation(entity, rtype, role, eids) |
|
248 else: |
240 self._clear_relation(entity, rtype, role, ttypes) |
249 self._clear_relation(entity, rtype, role, ttypes) |
241 return |
|
242 for item in others: |
|
243 item, _rels = self._complete_item(item) |
|
244 other_entity = self.process_item(item, []) |
|
245 eids.append(other_entity.eid) |
|
246 self._set_relation(entity, rtype, role, eids) |
|
247 |
250 |
248 def related_link(self, entity, rtype, role, others, rules): |
251 def related_link(self, entity, rtype, role, others, rules): |
249 """implementation of 'link' action |
252 """implementation of 'link' action |
250 |
253 |
251 requires an options to control search of the linked entity. |
254 requires an options to control search of the linked entity. |
295 ensure_str_keys(kwargs) # XXX necessary with python < 2.6 |
298 ensure_str_keys(kwargs) # XXX necessary with python < 2.6 |
296 eids.append(self._cw.create_entity(item['cwtype'], **kwargs).eid) |
299 eids.append(self._cw.create_entity(item['cwtype'], **kwargs).eid) |
297 else: |
300 else: |
298 self.source.error('can not find %s entity with attributes %s', |
301 self.source.error('can not find %s entity with attributes %s', |
299 item['cwtype'], kwargs) |
302 item['cwtype'], kwargs) |
300 if not eids: |
303 if eids: |
|
304 self._set_relation(entity, rtype, role, eids) |
|
305 else: |
301 self._clear_relation(entity, rtype, role, (ttype,)) |
306 self._clear_relation(entity, rtype, role, (ttype,)) |
302 else: |
|
303 self._set_relation(entity, rtype, role, eids) |
|
304 |
307 |
305 def _complete_item(self, item, add_relations=True): |
308 def _complete_item(self, item, add_relations=True): |
306 itemurl = item['cwuri'] + '?vid=xml' |
309 itemurl = item['cwuri'] + '?vid=xml' |
307 if add_relations: |
310 if add_relations: |
308 for rtype, role, _ in self.source.mapping.get(item['cwtype'], ()): |
311 for rtype, role, _ in self.source.mapping.get(item['cwtype'], ()): |
319 typerestr = ', Y is %s' % ','.join(ttypes) |
322 typerestr = ', Y is %s' % ','.join(ttypes) |
320 self._cw.execute('DELETE ' + rtype_role_rql(rtype, role) + typerestr, |
323 self._cw.execute('DELETE ' + rtype_role_rql(rtype, role) + typerestr, |
321 {'x': entity.eid}) |
324 {'x': entity.eid}) |
322 |
325 |
323 def _set_relation(self, entity, rtype, role, eids): |
326 def _set_relation(self, entity, rtype, role, eids): |
|
327 assert eids |
324 rqlbase = rtype_role_rql(rtype, role) |
328 rqlbase = rtype_role_rql(rtype, role) |
325 rql = 'DELETE %s' % rqlbase |
329 eidstr = ','.join(str(eid) for eid in eids) |
326 if eids: |
330 self._cw.execute('DELETE %s, NOT Y eid IN (%s)' % (rqlbase, eidstr), |
327 eidstr = ','.join(str(eid) for eid in eids) |
331 {'x': entity.eid}) |
328 rql += ', NOT Y eid IN (%s)' % eidstr |
332 if role == 'object': |
|
333 rql = 'SET %s, Y eid IN (%s), NOT Y %s X' % (rqlbase, eidstr, rtype) |
|
334 else: |
|
335 rql = 'SET %s, Y eid IN (%s), NOT X %s Y' % (rqlbase, eidstr, rtype) |
329 self._cw.execute(rql, {'x': entity.eid}) |
336 self._cw.execute(rql, {'x': entity.eid}) |
330 if eids: |
|
331 if role == 'object': |
|
332 rql = 'SET %s, Y eid IN (%s), NOT Y %s X' % (rqlbase, eidstr, rtype) |
|
333 else: |
|
334 rql = 'SET %s, Y eid IN (%s), NOT X %s Y' % (rqlbase, eidstr, rtype) |
|
335 self._cw.execute(rql, {'x': entity.eid}) |
|
336 |
337 |
337 def registration_callback(vreg): |
338 def registration_callback(vreg): |
338 vreg.register_all(globals().values(), __name__) |
339 vreg.register_all(globals().values(), __name__) |
339 global HOST_MAPPING |
340 global HOST_MAPPING |
340 HOST_MAPPING = {} |
341 HOST_MAPPING = {} |