[PATCH 2 of 2 eac V2] Add support for <functionRelation> in <cpfRelation>

gvandevelde guillaume.vandevelde at logilab.fr
Fri Aug 9 15:21:15 CEST 2019


On 8/9/19 2:32 PM, Denis Laxalde wrote:
> 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 c37835aca3abb4b6cb422bd9bc584123c8495b19
>> # Parent  506b5b445292e3f8c8206ecd4516b78da59e953a
>> # Available At http://hg.logilab.org/review/cubes/eac
>> #              hg pull http://hg.logilab.org/review/cubes/eac -r c37835aca3ab
>> Add support for <functionRelation> in <cpfRelation>
>>
>> Create a new entity EACFunctionRelation similar to EACRessourceRelation.
>>
>> diff -r 506b5b445292 -r c37835aca3ab 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,50 @@
>>           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"""
>> +        relationship = elem.attrib.get('functionRelationType')
>> +        if relationship is None:
>> +            self.import_log.record_warning(self._(
>> +                'found no functionRelationType attribute in element %s, defaulting '
>> +                'to performs') % etree.tostring(elem),
>> +                line=elem.sourceline)
>> +            relationship = 'performs'
> Why do you default to "performs" to set the r_type attribute, which is
> non-required? Can't it be left empty?

Right. I will change this part.

I took the other ternary relation as examples at this time,

which was a bad idea as I realize it now.

>> +        obj_uri = elem.attrib.get('{%(xlink)s}href' % self.namespaces)
>> +        if obj_uri is None:
>> +            self.import_log.record_warning(self._(
>> +                'found a functionRelation without any object (no xlink:href '
>> +                'attribute), skipping'), line=elem.sourceline)
>> +            return
> Here also, why choosing to ignore the entry when this attribute is
> missing? We could as well make "function_relation_function" non-required
> (cardinality = "?*").
Same explication here.
>> +        # Yield the ExternalUri object
> Can you explain why you choose to model this with an ExternalUri
> instead, e.g., as a simple "url = String()" attribute (as for EACSource)?

The url of this relation can represent another AuthorityRecord.

I thought an ExternalUri object would be better because it can be 
swapped with an

already existing AuthorityRecord if needed.

>> +        yield external_uri(obj_uri)
>> +        values = self.parse_tag_description(elem)
>> +        dates = self.parse_daterange(
>> +            self._elem_find(elem, 'eac:dateRange'))
>> +        if dates:
>> +            values.update(dates)
>> +        values.update({
>> +            'r_type': set([text_type(relationship)]),
>> +            'function_relation_function': set([text_type(obj_uri)]),
>> +            '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
>> +        }}
>> +        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 506b5b445292 -r c37835aca3ab 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
>> @@ -390,6 +390,42 @@
>>                 'xml_wrap': set(['<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
>>                },
>>               ),
>> +            ('EACFunctionRelation', _gen_extid(),
>> +             {'description': set([u'<p xmlns="urn:isbn:1-931666-33-4" xmlns:xsi="http:/'
>> +                                  '/www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http:'
>> +                                  '//www.w3.org/1999/xlink">The management of the University'
>> +                                  '\'s\n\t  communication with its alumni.\n\t  </p>']),
>> +              'r_type': [u'performs'],
>> +              'description_format': set([u'text/html']),
>> +              'function_relation_agent': set([u'FRAD033_EAC_00001']),
>> +              'function_relation_function': set([u'http://gael.gironde.fr/ead.html?'
>> +                                                 'id=FRAD033_IR_N']),
>> +              'relation_entry': set([u'Alumni communication\n\tmanagement, '
>> +                                     'University of\n\tGlasgow\n\t']),
>> +              'xml_wrap': set(['<mods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:isbn:1-931666-33-4" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.loc.gov/mods/v3 http:         //www.loc.gov/mods/v3/mods-3-3.xsd">\n\t    <titleInfo>\n\t      <title>Artisti trentini tra le due\n\t      guerre\n\t      </title>\n\t    </titleInfo>\n\t    <name>\n\t      <namePart type="given">Nicoletta\n\t      </namePart>\n\t      <namePart type="family">Boschiero\n\t      </namePart>\n\t      <role>\n\t\t<roleTerm type="text">autore\n\t\t</roleTerm>\n\t      </role>\n\t    </name>\n\t  </mods>\n\t']), # noqa
>> +              'attributes': set([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
> # noqa
>
>> +             },
>> +            ),
>> +            ('EACFunctionRelation', _gen_extid(),
>> +             {'function_relation_function': set([u'FRAD033_IR_N']),
>> +              'function_relation_agent': set([u'FRAD033_EAC_00001']),
>> +              'description': set([u'<p xmlns="urn:isbn:1-931666-33-4" '
>> +                                  'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '
>> +                                  'xmlns:xlink="http://www.w3.org/1999/xlink">'
>> +                                  'The second responsibility of the\n\t  '
>> +                                  'Department is to control the establishment\n\t  '
>> +                                  'and abolishment of schools.\n\t  </p>']),
>> +              'end_date': set([datetime.date(2001, 1, 1)]),
>> +              'r_type': set([u'controls']),
>> +              'description_format': set([u'text/html']),
>> +              'relation_entry': set([u'Establishment and abolishment\n\tof schools\n\t']),
>> +              'start_date': set([datetime.date(1922, 1, 1)])
>> +             },
>> +            ),
>> +            ('ExternalUri', 'FRAD033_IR_N',
>> +             {'uri': set([u'FRAD033_IR_N']),
>> +              'cwuri': set([u'FRAD033_IR_N'])},
>> +            ),
>>               ('ExternalUri', 'http://gael.gironde.fr/ead.html?id=FRAD033_IR_N',
>>                {'uri': set([u'http://gael.gironde.fr/ead.html?id=FRAD033_IR_N']),
>>                 'cwuri': set([u'http://gael.gironde.fr/ead.html?id=FRAD033_IR_N'])},
>> @@ -561,7 +597,7 @@
>>                                  cwuri=u'http://data.culture.fr/thesaurus/page/ark:/67717/T1-1074')
>>               cnx.commit()
>>               created, updated = testutils.eac_import(cnx, fpath)
>> -            self.assertEqual(len(created), 45)
>> +            self.assertEqual(len(created), 48)
>>               self.assertEqual(updated, set())
>>               rset = cnx.find('AuthorityRecord', isni=u'22330001300016')
>>               self.assertEqual(len(rset), 1)
>> @@ -669,6 +705,27 @@
>>                            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
>> +        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
> # noqa
>
>
>> +        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" xmlns="urn:isbn:1-931666-33-4" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.loc.gov/mods/v3 http:         //www.loc.gov/mods/v3/mods-3-3.xsd">\n\t    <titleInfo>\n\t      <title>Artisti trentini tra le due\n\t      guerre\n\t      </title>\n\t    </titleInfo>\n\t    <name>\n\t      <namePart type="given">Nicoletta\n\t      </namePart>\n\t      <namePart type="family">Boschiero\n\t      </namePart>\n\t      <role>\n\t\t<roleTerm type="text">autore\n\t\t</roleTerm>\n\t      </role>\n\t    </name>\n\t  </mods>\n\t') # noqa
>> +        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