[PATCH eac V4] Add support for <functionRelation> in <cpfRelation>

Denis Laxalde denis.laxalde at logilab.fr
Mon Aug 12 12:03:27 CEST 2019


Guillaume Vandevelde a écrit :
> # HG changeset patch
> # User Guillaume Vandevelde <gvandevelde at logilab.fr>
> # Date 1564500697 -7200
> #      Tue Jul 30 17:31:37 2019 +0200
> # Node ID 6207d39462a3a7b35e93e3cfb3ca97e9b280dfff
> # Parent  8abcfe4e3ba441a6d5d5e5666b413961b8c22246
> # Available At http://hg.logilab.org/review/cubes/eac
> #              hg pull http://hg.logilab.org/review/cubes/eac -r 6207d39462a3
> Add support for <functionRelation> in <cpfRelation>
> 
> Create a new entity EACFunctionRelation similar to EACRessourceRelation.
> 
> diff -r 8abcfe4e3ba4 -r 6207d39462a3 cubicweb_eac/dataimport.py
> --- a/cubicweb_eac/dataimport.py	Tue Jul 30 17:31:36 2019 +0200
> +++ b/cubicweb_eac/dataimport.py	Tue Jul 30 17:31:37 2019 +0200

> @@ -836,6 +837,43 @@
>          values.update(self.parse_tag_description(elem))
>          yield ExtEntity(etype, self._gen_extid(), values)
>  
> +    @add_xml_wrap_for('EACFunctionRelation')
> +    def build_function_relation(self, elem):
> +        """Build a relation between function entities
> +
> +        yield an ExternalUri object, and an EACFunctionRelation
> +        object that make the link between the ExternalUri and
> +        the AuthorityRecord object"""
> +        values = self.parse_tag_description(elem)
> +        relationship = elem.attrib.get('functionRelationType')
> +        obj_uri = elem.attrib.get('{%(xlink)s}href' % self.namespaces)
> +        # Yield the ExternalUri object
> +        if obj_uri:
> +            yield external_uri(obj_uri)
> +            values.update(
> +                {'function_relation_function': set([text_type(obj_uri)])})
> +        dates = self.parse_daterange(
> +            self._elem_find(elem, 'eac:dateRange'))
> +        if dates:
> +            values.update(dates)
> +        print('relationship', relationship)

left-over print()

> +        if relationship:
> +            values.update({'r_type': set([text_type(relationship)])})
> +        values.update({
> +            'function_relation_agent': set([text_type(self.record.extid)]),
> +        })
> +        values.update(self.values_from_xpaths(
> +            elem,
> +            (('place_entry', 'eac:placeEntry'),
> +             ('relation_entry', 'eac:relationEntry'))))
> +        attrib = {k: v for (k, v) in dict(elem.attrib).items() if k not in {
> +            'functionRelationType',
> +            '{%(xlink)s}href' % self.namespaces
> +        }}

I'd suggest to .pop() those attributes instead of .get() them.
This way, you wouldn't need this line.

> +        if attrib:
> +            values.update({'attributes': set([text_type(attrib)])})
> +        yield ExtEntity('EACFunctionRelation', self._gen_extid(), values)
> +
>      @add_xml_wrap_for('EACResourceRelation')
>      def build_resource_relation(self, elem):
>          """Build a `EACResourceRelation` external entity (along with
> diff -r 8abcfe4e3ba4 -r 6207d39462a3 cubicweb_eac/entities.py
> --- a/cubicweb_eac/entities.py	Tue Jul 30 17:31:36 2019 +0200
> +++ b/cubicweb_eac/entities.py	Tue Jul 30 17:31:37 2019 +0200
> @@ -134,6 +134,23 @@
>                   'to': resource_title})
>  
>  
> +class EACFunctionRelation(AnyEntity):
> +    __regid__ = 'EACFunctionRelation'
> +    fetch_attrs, cw_fetch_order = fetch_config(('r_type',
> +                                                'description',
> +                                                'relation_entry',
> +                                                'place_entry',
> +                                                'attributes',))
> +
> +    @property
> +    def record(self):
> +        return self.function_relation_agent[0]
> +
> +    @property
> +    def resource(self):
> +        return self.function_relation_function[0]

Those will lead to IndexError if there is no relation
(subject-cardinality is '?').

In fact, I don't see the point of this entity class.

> +
> +
>  class SameAsMixIn(object):
>      """Mix-in class for entity types supporting vocabulary_source and
>      equivalent_concept relations.

> diff -r 8abcfe4e3ba4 -r 6207d39462a3 cubicweb_eac/schema.py
> --- a/cubicweb_eac/schema.py	Tue Jul 30 17:31:36 2019 +0200
> +++ b/cubicweb_eac/schema.py	Tue Jul 30 17:31:37 2019 +0200
> @@ -371,6 +371,35 @@
>  
>  @xml_wrap
>  @dated_entity_type
> +class EACFunctionRelation(EntityType):
> +    """Represent a relation between an AuthorityRecord and a function"""
> +    r_type = String(internationalizable=True,
> +                    description=_('type of relation the function has '
> +                                  'with the Authority'))
> +    description = RichString(fulltextindexed=True)
> +    relation_entry = String(fulltextindexed=True)
> +    place_entry = String(fulltextindexed=True)
> +    attributes = String(fulltextindexed=True)
> +
> +
> +class function_relation_agent(RelationDefinition):
> +    subject = 'EACFunctionRelation'
> +    object = 'AuthorityRecord'
> +    cardinality = '?*'

This one should be required. We certainly do not want an
EACFunctionRelation entity not related to its AuthorityRecord.

> +    inlined = True
> +    composite = 'object'
> +    fulltext_container = 'object'
> +
> +
> +class function_relation_function(RelationDefinition):
> +    subject = 'EACFunctionRelation'
> +    object = 'ExternalUri'
> +    cardinality = '?*'
> +    inlined = True
> +
> +
> + at xml_wrap
> + at dated_entity_type
>  class EACResourceRelation(EntityType):
>      """Represent a relation between an AuthorityRecord and a remote resource in the
>      EAC-CPF model.

> diff -r 8abcfe4e3ba4 -r 6207d39462a3 test/test_dataimport.py
> --- a/test/test_dataimport.py	Tue Jul 30 17:31:36 2019 +0200
> +++ b/test/test_dataimport.py	Tue Jul 30 17:31:37 2019 +0200

> @@ -666,7 +747,40 @@
>          self.assertEqual(exturi.uri,
>                           u'http://gael.gironde.fr/ead.html?id=FRAD033_IR_N')
>          self.assertEqual(rrelation.xml_wrap.getvalue(),
> -                         '<he xmlns="urn:isbn:1-931666-33-4" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">joe</he>')  # noqa
> +                         u'<he xmlns="urn:isbn:1-931666-33-4" xmlns:xlink="http'
> +                         u'://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org'
> +                         u'/2001/XMLSchema-instance">joe</he>')
> +        rset = cnx.find('EACFunctionRelation', r_type=u'performs')
> +        func_relation = rset.one()
> +        self.assertEqual(func_relation.attributes,
> +                         u"{'{http://www.w3.org/1999/xlink}actuate': 'onLoad', '{http://www.w3.org/1999/xlink}arcrole': 'http://test_arcrole.lol.com', '{http://www.w3.org/1999/xlink}role': 'http://test_role.lmao.com'}") # noqa

Since you seem to insist on #noqa, perhaps you can scope it to only
catch line too long? (# noqa E501). Although here, this is certainly not
a good idea (a dict).

> +        self.assertEqual(func_relation.relation_entry,
> +                         u'Alumni communication\n\tmanagement, '
> +                         'University of\n\tGlasgow\n\t')
> +        self.assertEqual(func_relation.xml_wrap.getvalue(),
> +                         u'<mods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
> +                         u' xmlns="urn:isbn:1-931666-33-4" xmlns:xlink="http://www.w3'
> +                         u'.org/1999/xlink" xsi:schemaLocation="http://www.loc.gov'
> +                         u'/mods/v3 http:         //www.loc.gov/mods/v3/mods-3-3.xsd'
> +                         u'">\n\t    <titleInfo>\n\t      <title>Artisti trentini tra'
> +                         u' le due\n\t      guerre\n\t      </title>\n\t    </titleInfo>\n'
> +                         u'\t    <name>\n\t      <namePart type="given">Nicoletta\n\t'
> +                         u'      </namePart>\n\t      <namePart type="family">Boschiero\n'
> +                         u'\t      </namePart>\n\t      <role>\n\t\t<roleTerm type="text'
> +                         u'">autore\n\t\t</roleTerm>\n\t      </role>\n\t    </name>\n\t'
> +                         u'  </mods>\n\t')
> +        self.assertEqual(func_relation.function_relation_agent[0], record)
> +        self.assertEqual(func_relation.function_relation_function[0].uri,
> +                         u'http://gael.gironde.fr/ead.html?id=FRAD033_IR_N')
> +        rset = cnx.find('EACFunctionRelation', r_type=u'controls')
> +        func_relation = rset.one()
> +        self.assertEqual(func_relation.function_relation_agent[0], record)
> +        self.assertEqual(func_relation.function_relation_function[0].uri,
> +                         u'FRAD033_IR_N')
> +        self.assertEqual(func_relation.start_date,
> +                         datetime.date(1922, 1, 1))
> +        self.assertEqual(func_relation.end_date,
> +                         datetime.date(2001, 1, 1))
>  
>      def _check_equivalent_concept(self, cnx, record):
>          functions = dict((f.name, f) for f in record.reverse_function_agent)



More information about the saem-devel mailing list