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'] |