From aba7adbc8367523f0eb3d51252f3a018a0566e9c Mon Sep 17 00:00:00 2001 From: alejandromumo Date: Tue, 19 Nov 2024 11:08:30 +0100 Subject: [PATCH 1/9] record: added swh field --- site/zenodo_rdm/api.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/site/zenodo_rdm/api.py b/site/zenodo_rdm/api.py index e5e49e18..cc8cf794 100644 --- a/site/zenodo_rdm/api.py +++ b/site/zenodo_rdm/api.py @@ -11,6 +11,7 @@ from invenio_pidstore.providers.recordid import RecordIdProvider from invenio_rdm_records.records.api import RDMDraft, RDMParent, RDMRecord from invenio_records_resources.records.systemfields import PIDField +from invenio_swh.records.systemfields import SWHSysField class DraftRecordIdProvider(RecordIdProvider): @@ -50,6 +51,8 @@ class ZenodoRDMRecord(RDMRecord): ZenodoRDMParent, create=False, soft_delete=False, hard_delete=False ) + swh = SWHSysField("swh") + class ZenodoRDMDraft(RDMDraft): """Zenodo RDMDraft API class.""" From 0e3d8e8536a7243a4b4c2533c026d9d8011cfe3f Mon Sep 17 00:00:00 2001 From: alejandromumo Date: Wed, 20 Nov 2024 11:19:52 +0100 Subject: [PATCH 2/9] config: added service schema for zenodo records * added export formats in config * override bibtex serializer to include swhid --- invenio.cfg | 13 ++++++ site/zenodo_rdm/config.py | 6 +++ .../legacy/serializers/schemas/zenodojson.py | 2 + site/zenodo_rdm/schema.py | 26 ++++++++++++ site/zenodo_rdm/serializers/__init__.py | 11 +++++ site/zenodo_rdm/serializers/bibtex.py | 41 +++++++++++++++++++ 6 files changed, 99 insertions(+) create mode 100644 site/zenodo_rdm/schema.py create mode 100644 site/zenodo_rdm/serializers/__init__.py create mode 100644 site/zenodo_rdm/serializers/bibtex.py diff --git a/invenio.cfg b/invenio.cfg index 50929839..d646c930 100644 --- a/invenio.cfg +++ b/invenio.cfg @@ -1064,3 +1064,16 @@ COMMUNITIES_SHOW_BROWSE_MENU_ENTRY = True JOBS_ADMINISTRATION_ENABLED = True """Enable Jobs administration view.""" + +from invenio_app_rdm.config import APP_RDM_RECORD_EXPORTERS as default_exporters + +APP_RDM_RECORD_EXPORTERS = { + **default_exporters, + "bibtex": { + "name": _("BibTeX"), + "serializer": ("zenodo_rdm.serializers:ZenodoBibtexSerializer"), + "params": {}, + "content-type": "application/x-bibtex", + "filename": "{id}.bib", + } +} \ No newline at end of file diff --git a/site/zenodo_rdm/config.py b/site/zenodo_rdm/config.py index fad10757..cdf7272f 100644 --- a/site/zenodo_rdm/config.py +++ b/site/zenodo_rdm/config.py @@ -6,6 +6,7 @@ # under the terms of the MIT License; see LICENSE file for more details. """Custom code config.""" + from .params import ZenodoArgsSchema, ZenodoSearchOptions from .redirector import ( communities_detail_view_function, @@ -27,6 +28,7 @@ redirect_records_search_slash, search_view_function, ) +from .schema import ZenodoRecordSchema # I18N_TRANSLATIONS_PATHS = [os.path.abspath("./site/zenodo_rdm/translations")] @@ -370,3 +372,7 @@ def lock_edit_record_published_files(service, identity, record=None, draft=None) "//cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.js" "?config=TeX-AMS-MML_HTMLorMML" ) + + +RDM_RECORD_SCHEMA = ZenodoRecordSchema +"""Base record schema.""" diff --git a/site/zenodo_rdm/legacy/serializers/schemas/zenodojson.py b/site/zenodo_rdm/legacy/serializers/schemas/zenodojson.py index 64bf3dae..d53b23f7 100644 --- a/site/zenodo_rdm/legacy/serializers/schemas/zenodojson.py +++ b/site/zenodo_rdm/legacy/serializers/schemas/zenodojson.py @@ -177,6 +177,8 @@ class ZenodoSchema(common.LegacySchema): files = fields.Method("dump_files", dump_only=True) metadata = fields.Nested(MetadataSchema) + swh = fields.Dict(dump_only=True) + owners = fields.Method("dump_owners") def dump_owners(self, obj): diff --git a/site/zenodo_rdm/schema.py b/site/zenodo_rdm/schema.py new file mode 100644 index 00000000..54482624 --- /dev/null +++ b/site/zenodo_rdm/schema.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2024 CERN. +# +# Zenodo-RDM is free software; you can redistribute it and/or modify +# it under the terms of the MIT License; see LICENSE file for more details. +"""Zenodo-RDM service schema.""" + +from invenio_rdm_records.services.schemas import RDMRecordSchema +from marshmallow import Schema, fields + + +class SWHSchema(Schema): + """Software Heritage schema.""" + + swhid = fields.Str() + + +class ZenodoRecordSchema(RDMRecordSchema): + """Zenodo service schema. + + This schema subclasses the base schema and extends it with Zenodo-specific + fields. + """ + + swh = fields.Nested(SWHSchema, dump_only=True) diff --git a/site/zenodo_rdm/serializers/__init__.py b/site/zenodo_rdm/serializers/__init__.py new file mode 100644 index 00000000..b27760dc --- /dev/null +++ b/site/zenodo_rdm/serializers/__init__.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2024 CERN. +# +# ZenodoRDM is free software; you can redistribute it and/or modify +# it under the terms of the MIT License; see LICENSE file for more details. +"""Zenodo serializers.""" + +from .bibtex import ZenodoBibtexSerializer + +__all__ = ("ZenodoBibtexSerializer",) diff --git a/site/zenodo_rdm/serializers/bibtex.py b/site/zenodo_rdm/serializers/bibtex.py new file mode 100644 index 00000000..f8ef291d --- /dev/null +++ b/site/zenodo_rdm/serializers/bibtex.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2024 CERN. +# +# ZenodoRDM is free software; you can redistribute it and/or modify +# it under the terms of the MIT License; see LICENSE file for more details. +"""Zenodo bibtex serializer.""" + +from flask_resources import BaseListSchema, MarshmallowSerializer +from flask_resources.serializers import SimpleSerializer +from invenio_rdm_records.resources.serializers import BibtexSerializer +from invenio_rdm_records.resources.serializers.bibtex.schema import BibTexSchema +from marshmallow import fields, missing + + +class ZenodoBibtexSchema(BibTexSchema): + """Zenodo bibtex schema.""" + + swhid = fields.Method("get_swhid") + + def get_swhid(self, obj): + """Get swhid.""" + return obj.get("swh", {}).get("swhid") or missing + + +class ZenodoBibtexSerializer(MarshmallowSerializer): + """Zenodo bibtex serializer.""" + + def __init__(self, **options): + """Initialize serializer.""" + super().__init__( + format_serializer_cls=SimpleSerializer, + object_schema_cls=ZenodoBibtexSchema, + list_schema_cls=BaseListSchema, + encoder=self.bibtex_tostring, + ) + + @classmethod + def bibtex_tostring(cls, record): + """Stringify a BibTex record.""" + return record From df320209d148a0311cc1616a71c0e6a1a39d9417 Mon Sep 17 00:00:00 2001 From: alejandromumo Date: Thu, 21 Nov 2024 09:55:37 +0100 Subject: [PATCH 3/9] serializers: added codemeta with swhid --- invenio.cfg | 11 +++++-- site/zenodo_rdm/serializers/__init__.py | 6 +++- site/zenodo_rdm/serializers/codemeta.py | 42 +++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 site/zenodo_rdm/serializers/codemeta.py diff --git a/invenio.cfg b/invenio.cfg index d646c930..43c2bcac 100644 --- a/invenio.cfg +++ b/invenio.cfg @@ -1074,6 +1074,13 @@ APP_RDM_RECORD_EXPORTERS = { "serializer": ("zenodo_rdm.serializers:ZenodoBibtexSerializer"), "params": {}, "content-type": "application/x-bibtex", - "filename": "{id}.bib", - } + "filename": "{id}.bib" + }, + "codemeta": { + "name": _("Codemeta"), + "serializer": "zenodo_rdm.serializers:ZenodoCodemetaSerializer", + "params": {}, + "content-type": "application/ld+json", + "filename": "{id}.json", + }, } \ No newline at end of file diff --git a/site/zenodo_rdm/serializers/__init__.py b/site/zenodo_rdm/serializers/__init__.py index b27760dc..e9ac6eb3 100644 --- a/site/zenodo_rdm/serializers/__init__.py +++ b/site/zenodo_rdm/serializers/__init__.py @@ -7,5 +7,9 @@ """Zenodo serializers.""" from .bibtex import ZenodoBibtexSerializer +from .codemeta import ZenodoCodemetaSerializer -__all__ = ("ZenodoBibtexSerializer",) +__all__ = ( + "ZenodoBibtexSerializer", + "ZenodoCodemetaSerializer", +) diff --git a/site/zenodo_rdm/serializers/codemeta.py b/site/zenodo_rdm/serializers/codemeta.py new file mode 100644 index 00000000..582e0edf --- /dev/null +++ b/site/zenodo_rdm/serializers/codemeta.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2024 CERN. +# +# ZenodoRDM is free software; you can redistribute it and/or modify +# it under the terms of the MIT License; see LICENSE file for more details. +"""Zenodo bibtex serializer.""" + +from flask_resources import BaseListSchema, MarshmallowSerializer +from flask_resources.serializers import JSONSerializer +from invenio_rdm_records.contrib.codemeta.processors import CodemetaDumper +from invenio_rdm_records.resources.serializers.codemeta.schema import CodemetaSchema +from invenio_rdm_records.resources.serializers.schemaorg.schema import ( + _serialize_identifiers, +) +from marshmallow import fields, missing + + +class ZenodoCodemetaSchema(CodemetaSchema): + """Zenodo Codemeta schema.""" + + def get_sameAs(self, obj): + """Get sameAs field.""" + ret = super().get_sameAs(obj) or [] + swhid = obj.get("swh", {}).get("swhid") + if swhid: + ret.append({"@id": swhid}) + return ret or missing + + +class ZenodoCodemetaSerializer(MarshmallowSerializer): + """Zenodo Codemeta serializer.""" + + def __init__(self, **options): + """Initialize serializer.""" + super().__init__( + format_serializer_cls=JSONSerializer, + object_schema_cls=ZenodoCodemetaSchema, + list_schema_cls=BaseListSchema, + schema_kwargs={"dumpers": [CodemetaDumper()]}, # Order matters + **options + ) From a956ea04d3bac88dd40b9cdf548e30edaaf7aa21 Mon Sep 17 00:00:00 2001 From: alejandromumo Date: Thu, 21 Nov 2024 10:15:01 +0100 Subject: [PATCH 4/9] serializers: added zenodo datacite with swhid --- invenio.cfg | 9 +++++ site/zenodo_rdm/serializers/__init__.py | 2 ++ site/zenodo_rdm/serializers/codemeta.py | 7 ++-- site/zenodo_rdm/serializers/datacite.py | 47 +++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 site/zenodo_rdm/serializers/datacite.py diff --git a/invenio.cfg b/invenio.cfg index 43c2bcac..7cdb36f7 100644 --- a/invenio.cfg +++ b/invenio.cfg @@ -1083,4 +1083,13 @@ APP_RDM_RECORD_EXPORTERS = { "content-type": "application/ld+json", "filename": "{id}.json", }, + "datacite-json": { + "name": _("DataCite JSON"), + "serializer": ( + "zenodo_rdm.serializers:ZenodoDataciteJSONSerializer" + ), + "params": {"options": {"indent": 2, "sort_keys": True}}, + "content-type": "application/vnd.datacite.datacite+json", + "filename": "{id}.json", + }, } \ No newline at end of file diff --git a/site/zenodo_rdm/serializers/__init__.py b/site/zenodo_rdm/serializers/__init__.py index e9ac6eb3..a66d8ffb 100644 --- a/site/zenodo_rdm/serializers/__init__.py +++ b/site/zenodo_rdm/serializers/__init__.py @@ -8,8 +8,10 @@ from .bibtex import ZenodoBibtexSerializer from .codemeta import ZenodoCodemetaSerializer +from .datacite import ZenodoDataciteJSONSerializer __all__ = ( "ZenodoBibtexSerializer", "ZenodoCodemetaSerializer", + "ZenodoDataciteJSONSerializer", ) diff --git a/site/zenodo_rdm/serializers/codemeta.py b/site/zenodo_rdm/serializers/codemeta.py index 582e0edf..d39d105e 100644 --- a/site/zenodo_rdm/serializers/codemeta.py +++ b/site/zenodo_rdm/serializers/codemeta.py @@ -4,16 +4,13 @@ # # ZenodoRDM is free software; you can redistribute it and/or modify # it under the terms of the MIT License; see LICENSE file for more details. -"""Zenodo bibtex serializer.""" +"""Zenodo codemeta serializer.""" from flask_resources import BaseListSchema, MarshmallowSerializer from flask_resources.serializers import JSONSerializer from invenio_rdm_records.contrib.codemeta.processors import CodemetaDumper from invenio_rdm_records.resources.serializers.codemeta.schema import CodemetaSchema -from invenio_rdm_records.resources.serializers.schemaorg.schema import ( - _serialize_identifiers, -) -from marshmallow import fields, missing +from marshmallow import missing class ZenodoCodemetaSchema(CodemetaSchema): diff --git a/site/zenodo_rdm/serializers/datacite.py b/site/zenodo_rdm/serializers/datacite.py new file mode 100644 index 00000000..2f78e836 --- /dev/null +++ b/site/zenodo_rdm/serializers/datacite.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2024 CERN. +# +# ZenodoRDM is free software; you can redistribute it and/or modify +# it under the terms of the MIT License; see LICENSE file for more details. +"""Zenodo datacite serializer.""" + +from flask import current_app +from flask_resources import BaseListSchema, MarshmallowSerializer +from flask_resources.serializers import JSONSerializer +from invenio_rdm_records.contrib.journal.processors import JournalDataciteDumper +from invenio_rdm_records.resources.serializers.datacite.schema import DataCite43Schema +from marshmallow import missing + + +class ZenodoDataciteSchema(DataCite43Schema): + """Zenodo Datacite schema.""" + + def get_related_identifiers(self, obj): + """Get related identifiers.""" + ret = super().get_related_identifiers(obj) or [] + swhid = obj.get("swh", {}).get("swhid") + if swhid: + _url = f"{current_app.config['SWH_UI_BASE_URL']}/{swhid}" + ret.append( + { + "relation": "isIdenticalTo", + "relatedIdentifier": _url, + "relatedIdentifierType": "url", + } + ) + return ret or missing + + +class ZenodoDataciteJSONSerializer(MarshmallowSerializer): + """Zenodo Datacite serializer.""" + + def __init__(self, **options): + """Instantiate serializer.""" + super().__init__( + format_serializer_cls=JSONSerializer, + object_schema_cls=ZenodoDataciteSchema, + list_schema_cls=BaseListSchema, + schema_kwargs={"dumpers": [JournalDataciteDumper()]}, # Order matters + **options, + ) From 852dfa89423c02e4a16ae917494347670675181e Mon Sep 17 00:00:00 2001 From: alejandromumo Date: Thu, 21 Nov 2024 10:44:17 +0100 Subject: [PATCH 5/9] serializers: added CFF serializer with swhid --- invenio.cfg | 7 +++++ site/zenodo_rdm/serializers/__init__.py | 2 ++ site/zenodo_rdm/serializers/cff.py | 40 +++++++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 site/zenodo_rdm/serializers/cff.py diff --git a/invenio.cfg b/invenio.cfg index 7cdb36f7..a576fc04 100644 --- a/invenio.cfg +++ b/invenio.cfg @@ -1092,4 +1092,11 @@ APP_RDM_RECORD_EXPORTERS = { "content-type": "application/vnd.datacite.datacite+json", "filename": "{id}.json", }, + "cff": { + "name": _("Citation File Format"), + "serializer": "zenodo_rdm.serializers:ZenodoCFFSerializer", + "params": {}, + "content-type": "application/x-yaml", + "filename": "{id}.yaml", + }, } \ No newline at end of file diff --git a/site/zenodo_rdm/serializers/__init__.py b/site/zenodo_rdm/serializers/__init__.py index a66d8ffb..d1c1ac04 100644 --- a/site/zenodo_rdm/serializers/__init__.py +++ b/site/zenodo_rdm/serializers/__init__.py @@ -7,6 +7,7 @@ """Zenodo serializers.""" from .bibtex import ZenodoBibtexSerializer +from .cff import ZenodoCFFSerializer from .codemeta import ZenodoCodemetaSerializer from .datacite import ZenodoDataciteJSONSerializer @@ -14,4 +15,5 @@ "ZenodoBibtexSerializer", "ZenodoCodemetaSerializer", "ZenodoDataciteJSONSerializer", + "ZenodoCFFSerializer", ) diff --git a/site/zenodo_rdm/serializers/cff.py b/site/zenodo_rdm/serializers/cff.py new file mode 100644 index 00000000..010a6866 --- /dev/null +++ b/site/zenodo_rdm/serializers/cff.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2024 CERN. +# +# ZenodoRDM is free software; you can redistribute it and/or modify +# it under the terms of the MIT License; see LICENSE file for more details. +"""Zenodo CFF serializer.""" + +import yaml +from flask_resources import BaseListSchema, MarshmallowSerializer +from flask_resources.serializers import SimpleSerializer +from invenio_rdm_records.resources.serializers.cff.schema import CFFSchema +from marshmallow import missing + + +class ZenodoCFFSchema(CFFSchema): + """Zenodo Codemeta schema.""" + + def get_identifiers(self, obj): + """Get identifiers.""" + ret = super().get_identifiers(obj) or [] + swhid = obj.get("swh", {}).get("swhid") + if swhid: + ret.append({"value": swhid, "type": "swh"}) + return ret or missing + + +class ZenodoCFFSerializer(MarshmallowSerializer): + """Zenodo Codemeta serializer.""" + + def __init__(self, **options): + """Initialize serializer.""" + encoder = options.get("encoder", yaml.dump) + super().__init__( + format_serializer_cls=SimpleSerializer, + object_schema_cls=ZenodoCFFSchema, + list_schema_cls=BaseListSchema, + encoder=encoder, + **options, + ) From 0dbd653920dae193556c52194bff6f5642895c8a Mon Sep 17 00:00:00 2001 From: alejandromumo Date: Thu, 21 Nov 2024 15:31:10 +0100 Subject: [PATCH 6/9] codemeta: export swhid as `identifier` * Add `swhid` as an identifier in the codemeta serialization. * Identifier field is either a single value or a list of two values: DOI and Software Hash ID. --- site/zenodo_rdm/serializers/codemeta.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/site/zenodo_rdm/serializers/codemeta.py b/site/zenodo_rdm/serializers/codemeta.py index d39d105e..86040ab3 100644 --- a/site/zenodo_rdm/serializers/codemeta.py +++ b/site/zenodo_rdm/serializers/codemeta.py @@ -6,8 +6,10 @@ # it under the terms of the MIT License; see LICENSE file for more details. """Zenodo codemeta serializer.""" +from flask import current_app from flask_resources import BaseListSchema, MarshmallowSerializer from flask_resources.serializers import JSONSerializer +from idutils import normalize_doi, to_url from invenio_rdm_records.contrib.codemeta.processors import CodemetaDumper from invenio_rdm_records.resources.serializers.codemeta.schema import CodemetaSchema from marshmallow import missing @@ -16,12 +18,25 @@ class ZenodoCodemetaSchema(CodemetaSchema): """Zenodo Codemeta schema.""" - def get_sameAs(self, obj): - """Get sameAs field.""" - ret = super().get_sameAs(obj) or [] + id_ = missing + + def get_id(self, obj): + """Compute the "identifier". + + It uses the DOI expressed as a URL and the Software Hash ID as `swhid`. + If only one identifier is present, it returns it as a single entry. + """ + doi = obj.get("pids", {}).get("doi", {}).get("identifier") + ret = [] + if doi: + doi_url = to_url(normalize_doi(doi), "doi") + ret.append({"@type": "doi", "value": doi, "propertyID": doi_url}) swhid = obj.get("swh", {}).get("swhid") if swhid: - ret.append({"@id": swhid}) + swh_url = f"{current_app.config['SWH_UI_BASE_URL']}/{swhid}" + ret.append({"@type": "swhid", "value": swhid, "propertyID": swh_url}) + if len(ret) == 1: + return ret[0] return ret or missing @@ -35,5 +50,5 @@ def __init__(self, **options): object_schema_cls=ZenodoCodemetaSchema, list_schema_cls=BaseListSchema, schema_kwargs={"dumpers": [CodemetaDumper()]}, # Order matters - **options + **options, ) From c52954bd568b7378334a444f0b3c148abca30441 Mon Sep 17 00:00:00 2001 From: alejandromumo Date: Thu, 21 Nov 2024 15:50:10 +0100 Subject: [PATCH 7/9] serializers: added datacite XML with swhid --- invenio.cfg | 10 ++++++++++ site/zenodo_rdm/serializers/__init__.py | 3 ++- site/zenodo_rdm/serializers/datacite.py | 22 +++++++++++++++++++--- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/invenio.cfg b/invenio.cfg index a576fc04..f53c79d6 100644 --- a/invenio.cfg +++ b/invenio.cfg @@ -1091,6 +1091,15 @@ APP_RDM_RECORD_EXPORTERS = { "params": {"options": {"indent": 2, "sort_keys": True}}, "content-type": "application/vnd.datacite.datacite+json", "filename": "{id}.json", + }, + "datacite-xml": { + "name": _("DataCite XML"), + "serializer": ( + "zenodo_rdm.serializers:ZenodoDataciteXMLSerializer" + ), + "params": {}, + "content-type": "application/vnd.datacite.datacite+xml", + "filename": "{id}.xml", }, "cff": { "name": _("Citation File Format"), @@ -1099,4 +1108,5 @@ APP_RDM_RECORD_EXPORTERS = { "content-type": "application/x-yaml", "filename": "{id}.yaml", }, + } \ No newline at end of file diff --git a/site/zenodo_rdm/serializers/__init__.py b/site/zenodo_rdm/serializers/__init__.py index d1c1ac04..9e631dab 100644 --- a/site/zenodo_rdm/serializers/__init__.py +++ b/site/zenodo_rdm/serializers/__init__.py @@ -9,11 +9,12 @@ from .bibtex import ZenodoBibtexSerializer from .cff import ZenodoCFFSerializer from .codemeta import ZenodoCodemetaSerializer -from .datacite import ZenodoDataciteJSONSerializer +from .datacite import ZenodoDataciteJSONSerializer, ZenodoDataciteXMLSerializer __all__ = ( "ZenodoBibtexSerializer", "ZenodoCodemetaSerializer", "ZenodoDataciteJSONSerializer", + "ZenodoDataciteXMLSerializer", "ZenodoCFFSerializer", ) diff --git a/site/zenodo_rdm/serializers/datacite.py b/site/zenodo_rdm/serializers/datacite.py index 2f78e836..61d571e6 100644 --- a/site/zenodo_rdm/serializers/datacite.py +++ b/site/zenodo_rdm/serializers/datacite.py @@ -6,9 +6,10 @@ # it under the terms of the MIT License; see LICENSE file for more details. """Zenodo datacite serializer.""" +from datacite import schema43 from flask import current_app from flask_resources import BaseListSchema, MarshmallowSerializer -from flask_resources.serializers import JSONSerializer +from flask_resources.serializers import JSONSerializer, SimpleSerializer from invenio_rdm_records.contrib.journal.processors import JournalDataciteDumper from invenio_rdm_records.resources.serializers.datacite.schema import DataCite43Schema from marshmallow import missing @@ -25,9 +26,9 @@ def get_related_identifiers(self, obj): _url = f"{current_app.config['SWH_UI_BASE_URL']}/{swhid}" ret.append( { - "relation": "isIdenticalTo", "relatedIdentifier": _url, - "relatedIdentifierType": "url", + "relatedIdentifierType": "URL", + "relationType": "IsIdenticalTo", } ) return ret or missing @@ -45,3 +46,18 @@ def __init__(self, **options): schema_kwargs={"dumpers": [JournalDataciteDumper()]}, # Order matters **options, ) + + +class ZenodoDataciteXMLSerializer(MarshmallowSerializer): + """Zenodo Datacite XML serializer.""" + + def __init__(self, **options): + """Instantiate serializer.""" + encoder = options.get("encoder", schema43.tostring) + super().__init__( + format_serializer_cls=SimpleSerializer, + object_schema_cls=ZenodoDataciteSchema, + list_schema_cls=BaseListSchema, + schema_kwargs={"dumpers": [JournalDataciteDumper()]}, # Order matters + encoder=encoder, + ) From e92315f124e65542bb2ccd14ffcf875f9b001cb4 Mon Sep 17 00:00:00 2001 From: alejandromumo Date: Fri, 22 Nov 2024 09:30:17 +0100 Subject: [PATCH 8/9] codemeta: use identifiers field --- site/zenodo_rdm/serializers/codemeta.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/site/zenodo_rdm/serializers/codemeta.py b/site/zenodo_rdm/serializers/codemeta.py index 86040ab3..7c6f4085 100644 --- a/site/zenodo_rdm/serializers/codemeta.py +++ b/site/zenodo_rdm/serializers/codemeta.py @@ -12,15 +12,15 @@ from idutils import normalize_doi, to_url from invenio_rdm_records.contrib.codemeta.processors import CodemetaDumper from invenio_rdm_records.resources.serializers.codemeta.schema import CodemetaSchema -from marshmallow import missing +from marshmallow import fields, missing class ZenodoCodemetaSchema(CodemetaSchema): """Zenodo Codemeta schema.""" - id_ = missing + identifier = fields.Method("get_identifiers") - def get_id(self, obj): + def get_identifiers(self, obj): """Compute the "identifier". It uses the DOI expressed as a URL and the Software Hash ID as `swhid`. From e2908f59e03591179cef20f915a9f072464d5aa4 Mon Sep 17 00:00:00 2001 From: alejandromumo Date: Fri, 22 Nov 2024 10:50:34 +0100 Subject: [PATCH 9/9] installation: bump invenio-swh --- Pipfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pipfile b/Pipfile index 49dca939..48189638 100644 --- a/Pipfile +++ b/Pipfile @@ -17,7 +17,7 @@ sentry-sdk = ">=1.45,<2.0.0" zenodo_rdm = {editable="True", path="./site"} zenodo_legacy = {editable="True", path="./legacy"} # TODO: Remove once we fix PyPI package issues -invenio-swh = {git = "https://github.com/inveniosoftware/invenio-swh", ref = "v0.10.3"} +invenio-swh = {git = "https://github.com/inveniosoftware/invenio-swh", ref = "v0.11.0"} jsonschema = ">=4.17.0,<4.18.0" # due to compatibility issues with alpha ipython = "!=8.1.0" uwsgi = ">=2.0"