31 |
31 |
32 """ |
32 """ |
33 |
33 |
34 import os.path as osp |
34 import os.path as osp |
35 from datetime import datetime, timedelta |
35 from datetime import datetime, timedelta |
36 import urllib |
36 from urllib import urlencode |
|
37 from urlparse import parse_qs |
37 |
38 |
38 from logilab.common.date import todate, totime |
39 from logilab.common.date import todate, totime |
39 from logilab.common.textutils import splitstrip, text_to_dict |
40 from logilab.common.textutils import splitstrip, text_to_dict |
40 |
41 |
41 from yams.constraints import BASE_CONVERTERS |
42 from yams.constraints import BASE_CONVERTERS |
188 rules = [x for x in rules if not x[0] == ttype] |
189 rules = [x for x in rules if not x[0] == ttype] |
189 if not rules: |
190 if not rules: |
190 del self.source.mapping[etype][(rtype, role, action)] |
191 del self.source.mapping[etype][(rtype, role, action)] |
191 |
192 |
192 # import handling ########################################################## |
193 # import handling ########################################################## |
|
194 |
|
195 def process(self, url, raise_on_error=False, partialcommit=True): |
|
196 """IDataFeedParser main entry point""" |
|
197 super(CWEntityXMLParser, self).process(self.complete_url(url), |
|
198 raise_on_error, partialcommit) |
193 |
199 |
194 # XXX suppression support according to source configuration. If set, get all |
200 # XXX suppression support according to source configuration. If set, get all |
195 # cwuri of entities from this source, and compare with newly imported ones |
201 # cwuri of entities from this source, and compare with newly imported ones |
196 |
202 |
197 def process_item(self, item, rels): |
203 def process_item(self, item, rels): |
299 if eids: |
305 if eids: |
300 self._set_relation(entity, rtype, role, eids) |
306 self._set_relation(entity, rtype, role, eids) |
301 else: |
307 else: |
302 self._clear_relation(entity, rtype, role, (ttype,)) |
308 self._clear_relation(entity, rtype, role, (ttype,)) |
303 |
309 |
|
310 def complete_url(self, url, etype=None): |
|
311 """append to the url's query string information about relation that should |
|
312 be included in the resulting xml, according to source mapping. |
|
313 |
|
314 If etype is not specified, try to guess it using the last path part of |
|
315 the url. |
|
316 """ |
|
317 try: |
|
318 url, qs = url.split('?', 1) |
|
319 except ValueError: |
|
320 qs = '' |
|
321 if etype is None: |
|
322 try: |
|
323 etype = url.rsplit('/', 1)[1] |
|
324 except ValueError: |
|
325 return url |
|
326 try: |
|
327 etype = self._cw.vreg.case_insensitive_etypes[etype] |
|
328 except KeyError: |
|
329 return url |
|
330 params = parse_qs(qs) |
|
331 if not 'vid' in params: |
|
332 params['vid'] = ['xml'] |
|
333 relations = params.setdefault('relation', []) |
|
334 for rtype, role, _ in self.source.mapping.get(etype, ()): |
|
335 reldef = '%s-%s' % (rtype, role) |
|
336 if not reldef in relations: |
|
337 relations.append(reldef) |
|
338 return url + '?' + self._cw.build_url_params(**params) |
|
339 |
304 def _complete_item(self, item, add_relations=True): |
340 def _complete_item(self, item, add_relations=True): |
305 try: |
341 try: |
306 return self._parsed_urls[(item['cwuri'], add_relations)] |
342 return self._parsed_urls[(item['cwuri'], add_relations)] |
307 except KeyError: |
343 except KeyError: |
308 query = [('vid','xml')] |
344 itemurl = self.complete_url(item['cwuri'], item['cwtype']) |
309 if add_relations: |
|
310 for rtype, role, _ in self.source.mapping.get(item['cwtype'], ()): |
|
311 query.append(('relation','%s-%s' % (rtype, role))) |
|
312 itemurl = item['cwuri'] + '?' + urllib.urlencode(query) |
|
313 item_rels = list(self.parse(itemurl)) |
345 item_rels = list(self.parse(itemurl)) |
314 assert len(item_rels) == 1, 'url %s expected to bring back one '\ |
346 assert len(item_rels) == 1, 'url %s expected to bring back one '\ |
315 'and only one entity, got %s' % (itemurl, len(item_rels)) |
347 'and only one entity, got %s' % (itemurl, len(item_rels)) |
316 self._parsed_urls[(item['cwuri'], add_relations)] = item_rels[0] |
348 self._parsed_urls[(item['cwuri'], add_relations)] = item_rels[0] |
317 return item_rels[0] |
349 return item_rels[0] |
335 rql = 'SET %s, Y eid IN (%s), NOT Y %s X' % (rqlbase, eidstr, rtype) |
367 rql = 'SET %s, Y eid IN (%s), NOT Y %s X' % (rqlbase, eidstr, rtype) |
336 else: |
368 else: |
337 rql = 'SET %s, Y eid IN (%s), NOT X %s Y' % (rqlbase, eidstr, rtype) |
369 rql = 'SET %s, Y eid IN (%s), NOT X %s Y' % (rqlbase, eidstr, rtype) |
338 self._cw.execute(rql, {'x': entity.eid}) |
370 self._cw.execute(rql, {'x': entity.eid}) |
339 |
371 |
|
372 |
340 def registration_callback(vreg): |
373 def registration_callback(vreg): |
341 vreg.register_all(globals().values(), __name__) |
374 vreg.register_all(globals().values(), __name__) |
342 global HOST_MAPPING |
375 global HOST_MAPPING |
343 HOST_MAPPING = {} |
376 HOST_MAPPING = {} |
344 if vreg.config.apphome: |
377 if vreg.config.apphome: |