sobjects/parsers.py
changeset 7531 e891ca479586
parent 7481 23ae090fc6a4
child 7532 76914c7ba1b0
equal deleted inserted replaced
7527:ef1e9bc38137 7531:e891ca479586
    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: