[PATCH 3 of 5 saem_ref] [seda] Add an "ark" attribute to SEDAArchiveUnit

Denis Laxalde denis.laxalde at logilab.fr
Wed Apr 11 16:30:07 CEST 2018


# HG changeset patch
# User Denis Laxalde <denis.laxalde at logilab.fr>
# Date 1523454610 -7200
#      Wed Apr 11 15:50:10 2018 +0200
# Node ID ffa768d7ef7f034ccf882c0e271924434fa504c2
# Parent  1ff8b995857342b54188eb816b234bb9b958ad85
# Available At http://hg.logilab.org/review/cubes/saem_ref
#              hg pull http://hg.logilab.org/review/cubes/saem_ref -r ffa768d7ef7f
# EXP-Topic ark-for-archiveunit
[seda] Add an "ark" attribute to SEDAArchiveUnit

We add an "ark" attribute and an "ark_naa" relation to SEDAArchiveUnit.

A couple of things has to be implemented in order things to keep
working:

* we need a IArkNAALocator adapter for this entity type; as for other
  entity types that can live under a parent entity (like Concept vs.
  ConceptScheme), we need to handle retrieval of the ARK NAA entity
  either directly or using the parent (first).

* we need to make sure that the "ark" attribute is not copied, thus the
  custom SEDAArchiveUnit entity class: this is completely identical to
  SEDAArchiveTransfer defined just above in entities/seda.py.

* we need a custom version of testutils.create_archive_unit() which
  would retrieve the "ark_naa" relation either directly or from the
  parent, if it is set.

Tests for ARK generation added in unittest_hooks.py.

CONSEJIRA-431

diff --git a/cubicweb_saem_ref/entities/__init__.py b/cubicweb_saem_ref/entities/__init__.py
--- a/cubicweb_saem_ref/entities/__init__.py
+++ b/cubicweb_saem_ref/entities/__init__.py
@@ -161,6 +161,23 @@ class ConceptArkNAALocator(ArkNAALocator
         return scheme.cw_adapt_to(self.__regid__).naa_what()
 
 
+class SEDAArchiveUnitArkNAALocator(ArkNAALocator):
+    """Return NAA for a SEDAArchiveUnit, either direct or through the
+    SEDAArchiveTransfer it belongs to.
+    """
+    __select__ = is_instance('SEDAArchiveUnit')
+
+    def naa_what(self):
+        # entity is usually not yet created, since ark has to be generated before entity creation
+        if 'seda_archive_unit' in getattr(self.entity, 'cw_edited', {}):
+            transfer = self._cw.entity_from_eid(self.entity.cw_edited['seda_archive_unit'])
+        elif self.entity.seda_archive_unit:
+            transfer = self.entity.seda_archive_unit[0]
+        else:
+            return direct_naa_what(self.entity)
+        return transfer.cw_adapt_to(self.__regid__).naa_what()
+
+
 class ExternalUri(AnyEntity):
     __regid__ = 'ExternalUri'
     fetch_attrs, cw_fetch_order = fetch_config(('uri',))
diff --git a/cubicweb_saem_ref/entities/seda.py b/cubicweb_saem_ref/entities/seda.py
--- a/cubicweb_saem_ref/entities/seda.py
+++ b/cubicweb_saem_ref/entities/seda.py
@@ -22,7 +22,10 @@ from cubicweb.predicates import is_insta
 from cubes.oaipmh import MetadataFormat
 from cubes.oaipmh.entities import OAISetSpec
 from cubicweb_seda.entities import SEDAArchiveTransferIClonableAdapter
-from cubicweb_seda.entities.custom import SEDAArchiveTransfer
+from cubicweb_seda.entities.custom import (
+    SEDAArchiveTransfer,
+    SEDAArchiveUnit,
+)
 from cubicweb_seda.entities.profile_generation import SEDA2ExportAdapter, SEDA1XSDExport
 from cubicweb_seda.views import export
 
@@ -104,6 +107,17 @@ class SEDAArchiveTransfer(SEDAArchiveTra
         return None
 
 
+class SEDAArchiveUnit(SEDAArchiveUnit):
+    SEDAArchiveUnit.fetch_attrs.append('ark')
+    cw_skip_copy_for = SEDAArchiveUnit.cw_skip_copy_for + [('ark', 'subject')]
+
+    def __getstate__(self):
+        # Exclude ark from copy to have so that it can be generated for the clone
+        odict = self.__dict__.copy()
+        odict['cw_attr_cache'].pop('ark', None)
+        return odict
+
+
 class TransferringAgentOAISetSpec(OAISetSpec):
     """OAI-PMH set specifier to match SEDAArchiveTransfer related to a transferring
     agent.
diff --git a/cubicweb_saem_ref/i18n/en.po b/cubicweb_saem_ref/i18n/en.po
--- a/cubicweb_saem_ref/i18n/en.po
+++ b/cubicweb_saem_ref/i18n/en.po
@@ -343,6 +343,10 @@ msgctxt "SEDAArchiveTransfer"
 msgid "ark"
 msgstr ""
 
+msgctxt "SEDAArchiveUnit"
+msgid "ark"
+msgstr ""
+
 msgid "ark_naa"
 msgstr "name assigning authority"
 
@@ -362,6 +366,10 @@ msgctxt "SEDAArchiveTransfer"
 msgid "ark_naa"
 msgstr ""
 
+msgctxt "SEDAArchiveUnit"
+msgid "ark_naa"
+msgstr ""
+
 msgctxt "SKOSSource"
 msgid "ark_naa"
 msgstr ""
diff --git a/cubicweb_saem_ref/i18n/fr.po b/cubicweb_saem_ref/i18n/fr.po
--- a/cubicweb_saem_ref/i18n/fr.po
+++ b/cubicweb_saem_ref/i18n/fr.po
@@ -360,6 +360,10 @@ msgctxt "SEDAArchiveTransfer"
 msgid "ark"
 msgstr ""
 
+msgctxt "SEDAArchiveUnit"
+msgid "ark"
+msgstr ""
+
 msgid "ark_naa"
 msgstr "autorité nommante ARK"
 
@@ -379,6 +383,10 @@ msgctxt "SEDAArchiveTransfer"
 msgid "ark_naa"
 msgstr ""
 
+msgctxt "SEDAArchiveUnit"
+msgid "ark_naa"
+msgstr ""
+
 msgctxt "SKOSSource"
 msgid "ark_naa"
 msgstr ""
diff --git a/cubicweb_saem_ref/migration/0.20.0_Any.py b/cubicweb_saem_ref/migration/0.20.0_Any.py
new file mode 100644
--- /dev/null
+++ b/cubicweb_saem_ref/migration/0.20.0_Any.py
@@ -0,0 +1,2 @@
+add_attribute('SEDAArchiveUnit', 'ark')
+add_relation_definition('SEDAArchiveUnit', 'ark_naa', 'ArkNameAssigningAuthority')
diff --git a/cubicweb_saem_ref/schema.py b/cubicweb_saem_ref/schema.py
--- a/cubicweb_saem_ref/schema.py
+++ b/cubicweb_saem_ref/schema.py
@@ -394,6 +394,7 @@ class ark(RelationDefinition):
         'Organization',
         'OrganizationUnit',
         'SEDAArchiveTransfer',
+        'SEDAArchiveUnit',
     )
     object = 'String'
     description = _('ARK Identifier - will be generated if not specified')
@@ -439,7 +440,7 @@ class mandatory_ark_naa(_ark_naa):
         'add': ('managers', 'users',),
         'delete': (),
     }
-    subject = ('AuthorityRecord', 'SEDAArchiveTransfer')
+    subject = ('AuthorityRecord', 'SEDAArchiveTransfer', 'SEDAArchiveUnit')
     cardinality = '1*'
     description = _("ARK identifier Name Assigning Authority (NAA)")
 
diff --git a/test/test_saem_ref.py b/test/test_saem_ref.py
--- a/test/test_saem_ref.py
+++ b/test/test_saem_ref.py
@@ -74,6 +74,8 @@ class ArkURLTC(testlib.CubicWebTC):
             'Organization': partial(testutils.authority_with_naa),
             'OrganizationUnit': partial(testutils.organization_unit, name=u'ou'),
             'SEDAArchiveTransfer': testutils.setup_profile,
+            'SEDAArchiveUnit': lambda cnx: testutils.create_archive_unit(
+                None, cnx=cnx, ark_naa=testutils.naa(cnx))[0],
         }
         baseurl = self.vreg.config['base-url']
         with self.admin_access.cnx() as cnx:
diff --git a/test/test_seda.py b/test/test_seda.py
--- a/test/test_seda.py
+++ b/test/test_seda.py
@@ -163,6 +163,9 @@ class CloneImportTC(CubicWebTC):
             rset = req.execute('Any X WHERE X seda_archive_unit P, P ark %(ark)s',
                                {'ark': ark})
             self.assertTrue(rset)
+            imported_unit = rset.one()
+            self.assertNotEqual(req.entity_from_eid(self.unit_eid).ark,
+                                imported_unit.ark)
 
 
 if __name__ == '__main__':
diff --git a/test/testutils.py b/test/testutils.py
--- a/test/testutils.py
+++ b/test/testutils.py
@@ -38,10 +38,20 @@ from cubicweb_saem_ref import ark
 # make some names them appear in this module namespace to ease test API
 assertValidationError = seda_testutils.assertValidationError
 assertUnauthorized = seda_testutils.assertUnauthorized
-create_archive_unit = seda_testutils.create_archive_unit
 create_data_object = seda_testutils.create_data_object
 
 
+def create_archive_unit(parent, *args, **kwargs):
+    """Create a SEDAArchiveTransfer with an "ark_naa" relation set."""
+    if 'ark_naa' not in kwargs:
+        cnx = kwargs.get('cnx', getattr(parent, '_cw', None))
+        assert cnx is not None
+        authority = authority_with_naa(cnx)
+        authority.cw_clear_all_caches()
+        kwargs['ark_naa'] = authority.ark_naa
+    return seda_testutils.create_archive_unit(parent, *args, **kwargs)
+
+
 def _authority(func):
     """Decorator binding an Organization with an NAA configured in
     kwargs['authority'].
diff --git a/test/unittest_hooks.py b/test/unittest_hooks.py
--- a/test/unittest_hooks.py
+++ b/test/unittest_hooks.py
@@ -293,6 +293,19 @@ class ARKGenerationHooksTC(CubicWebTC):
             self._check_ark(profile)
             self.assertEqual(profile.cwuri, 'http://example.org/profile/125')
 
+    def test_ark_generation_seda_archiveunit(self):
+        with self.admin_access.repo_cnx() as cnx:
+            naa = testutils.naa(cnx)
+            unit, _, _ = testutils.create_archive_unit(None, cnx=cnx, ark_naa=naa)
+            self._check_ark_and_cwuri(unit)
+
+    def test_ark_generation_seda_archiveunit_in_archivetransfer(self):
+        with self.admin_access.repo_cnx() as cnx:
+            profile = testutils.setup_profile(cnx)
+            unit, _, _ = testutils.create_archive_unit(profile, cnx)
+            self._check_ark_and_cwuri(unit)
+            self.assertTrue(unit.ark.startswith('0/'), unit.ark)
+
     def test_ark_generation_concept(self):
         with self.admin_access.repo_cnx() as cnx:
             scheme = cnx.create_entity('ConceptScheme', ark_naa=testutils.naa(cnx))


More information about the saem-devel mailing list