cubicweb/sobjects/cwxmlparser.py
changeset 11256 0d9105673ec9
parent 11057 0b59724cb3f2
equal deleted inserted replaced
11255:58be5fe4a232 11256:0d9105673ec9
     1 # copyright 2010-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     1 # copyright 2010-2015 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
     3 #
     3 #
     4 # This file is part of CubicWeb.
     4 # This file is part of CubicWeb.
     5 #
     5 #
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
    81 
    81 
    82 def extract_typed_attrs(eschema, stringdict, converters=DEFAULT_CONVERTERS):
    82 def extract_typed_attrs(eschema, stringdict, converters=DEFAULT_CONVERTERS):
    83     typeddict = {}
    83     typeddict = {}
    84     for rschema in eschema.subject_relations():
    84     for rschema in eschema.subject_relations():
    85         if rschema.final and rschema in stringdict:
    85         if rschema.final and rschema in stringdict:
    86             if rschema in ('eid', 'cwuri', 'cwtype', 'cwsource'):
    86             if rschema in ('eid', 'cwuri'):  # XXX really omit cwuri?
    87                 continue
    87                 continue
    88             attrtype = eschema.destination(rschema)
    88             attrtype = eschema.destination(rschema)
    89             value = stringdict[rschema]
    89             value = stringdict[rschema]
    90             if value is not None:
    90             if value is not None:
    91                 value = converters[attrtype](value)
    91                 value = converters[attrtype](value)
   195         if url.startswith('http'): # XXX similar loose test as in parse of sources.datafeed
   195         if url.startswith('http'): # XXX similar loose test as in parse of sources.datafeed
   196             url = self.complete_url(url)
   196             url = self.complete_url(url)
   197         super(CWEntityXMLParser, self).process(url, raise_on_error)
   197         super(CWEntityXMLParser, self).process(url, raise_on_error)
   198 
   198 
   199     def parse_etree(self, parent):
   199     def parse_etree(self, parent):
       
   200         """Overriden from :class:`DataFeedXMLParser` to use a builder component."""
   200         for node in list(parent):
   201         for node in list(parent):
   201             builder = self._cw.vreg['components'].select(
   202             builder = self._cw.vreg['components'].select(
   202                 'cw.entityxml.item-builder', self._cw, node=node,
   203                 'cw.entityxml.item-builder', self._cw, node=node,
   203                 parser=self)
   204                 parser=self)
   204             yield builder.build_item()
   205             yield builder.build_item()
   292             return self._parsed_urls[item['cwuri']]
   293             return self._parsed_urls[item['cwuri']]
   293         except KeyError:
   294         except KeyError:
   294             itemurl = self.complete_url(item['cwuri'], item['cwtype'], rels)
   295             itemurl = self.complete_url(item['cwuri'], item['cwtype'], rels)
   295             item_rels = list(self.parse(itemurl))
   296             item_rels = list(self.parse(itemurl))
   296             assert len(item_rels) == 1, 'url %s expected to bring back one '\
   297             assert len(item_rels) == 1, 'url %s expected to bring back one '\
   297                    'and only one entity, got %s' % (itemurl, len(item_rels))
   298                 'and only one entity, got %s' % (itemurl, len(item_rels))
   298             self._parsed_urls[item['cwuri']] = item_rels[0]
   299             self._parsed_urls[item['cwuri']] = item_rels[0]
   299             if rels:
   300             if rels:
   300                 # XXX (do it better) merge relations
   301                 # XXX (do it better) merge relations
   301                 new_rels = item_rels[0][1]
   302                 new_rels = item_rels[0][1]
   302                 new_rels.get('subject', {}).update(rels.get('subject', {}))
   303                 new_rels.get('subject', {}).update(rels.get('subject', {}))
   321         """
   322         """
   322         node = self.node
   323         node = self.node
   323         item = dict(node.attrib.items())
   324         item = dict(node.attrib.items())
   324         item['cwtype'] = text_type(node.tag)
   325         item['cwtype'] = text_type(node.tag)
   325         item.setdefault('cwsource', None)
   326         item.setdefault('cwsource', None)
   326         try:
   327         item['eid'] = int(item['eid'])
   327             item['eid'] = int(item['eid'])
       
   328         except KeyError:
       
   329             # cw < 3.11 compat mode XXX
       
   330             item['eid'] = int(node.find('eid').text)
       
   331             item['cwuri'] = node.find('cwuri').text
       
   332         rels = {}
   328         rels = {}
   333         for child in node:
   329         for child in node:
   334             role = child.get('role')
   330             role = child.get('role')
   335             if role:
   331             if role:
   336                 # relation
   332                 # relation
   416     requires a 'linkattr' option to control search of the linked entity.
   412     requires a 'linkattr' option to control search of the linked entity.
   417     """
   413     """
   418     __regid__ = 'cw.entityxml.action.link'
   414     __regid__ = 'cw.entityxml.action.link'
   419 
   415 
   420     def check_options(self, options, eid):
   416     def check_options(self, options, eid):
   421         if not 'linkattr' in options:
   417         if 'linkattr' not in options:
   422             msg = self._cw._("'%s' action requires 'linkattr' option") % self.action
   418             msg = self._cw._("'%s' action requires 'linkattr' option") % self.action
   423             raise ValidationError(eid, {rn('options', 'subject'): msg})
   419             raise ValidationError(eid, {rn('options', 'subject'): msg})
   424 
   420 
   425     create_when_not_found = False
   421     create_when_not_found = False
   426 
   422 
   475     """
   471     """
   476     __select__ = match_rtype('in_state')
   472     __select__ = match_rtype('in_state')
   477 
   473 
   478     def check_options(self, options, eid):
   474     def check_options(self, options, eid):
   479         super(CWEntityXMLActionLinkInState, self).check_options(options, eid)
   475         super(CWEntityXMLActionLinkInState, self).check_options(options, eid)
   480         if not 'name' in options['linkattr']:
   476         if 'name' not in options['linkattr']:
   481             msg = self._cw._("'%s' action for in_state relation should at least have 'linkattr=name' option") % self.action
   477             msg = self._cw._("'%s' action for in_state relation should at least "
       
   478                              "have 'linkattr=name' option") % self.action
   482             raise ValidationError(eid, {rn('options', 'subject'): msg})
   479             raise ValidationError(eid, {rn('options', 'subject'): msg})
   483 
   480 
   484     def _find_entities(self, item, kwargs):
   481     def _find_entities(self, item, kwargs):
   485         assert 'name' in item # XXX else, complete_item
   482         assert 'name' in item # XXX else, complete_item
   486         state_name = item['name']
   483         state_name = item['name']