Skip to content
Snippets Groups Projects
Commit 957db0f9 authored by vlorentz's avatar vlorentz
Browse files

Fix support of sword-v2-atom-codemeta-v2-in-json documents with missing @xmlns

parent 6718f356
No related branches found
No related tags found
1 merge request!517Fix support of sword-v2-atom-codemeta-v2-in-json documents with missing @xmlns
Pipeline #11085 failed
......@@ -170,6 +170,19 @@ class SwordCodemetaMapping(BaseExtrinsicMapping):
return compact(metadata, forgefed=False)
def iter_keys(d):
"""Recursively iterates on dictionary keys"""
if isinstance(d, dict):
yield from d
for value in d:
yield from iter_keys(value)
elif isinstance(d, list):
for value in d:
yield from iter_keys(value)
else:
pass
class JsonSwordCodemetaMapping(SwordCodemetaMapping):
"""
Variant of :class:`SwordCodemetaMapping` that reads the legacy
......@@ -193,9 +206,21 @@ class JsonSwordCodemetaMapping(SwordCodemetaMapping):
logger.error("Failed to parse JSON document: %s", content)
return None
else:
if json_doc.get("@xmlns") != ATOM_URI:
# Technically, non-default XMLNS were allowed, but it does not seem like
# anyone used them, so they do not need to be implemented here.
if "@xmlns" not in json_doc:
# Technically invalid, but old versions of the deposit dropped
# XMLNS information
json_doc["@xmlns"] = ATOM_URI
if "@xmlns:codemeta" not in json_doc and any(
key.startswith("codemeta:") for key in iter_keys(json_doc)
):
# ditto
json_doc["@xmlns:codemeta"] = CODEMETA_CONTEXT_URL
if json_doc["@xmlns"] not in (ATOM_URI, [ATOM_URI]):
# Technically, non-default XMLNS were allowed, but no one used them,
# and we don't write this format anymore, so they do not need to be
# implemented here.
raise NotImplementedError(f"Unexpected XMLNS set: {json_doc}")
# Root tag was stripped by swh-deposit
......
......@@ -541,6 +541,20 @@ def test_json_sword():
}
def test_json_sword_no_xmlns():
content = """{"title": "Example Software", "codemeta:url": "http://example.org/", "codemeta:author": [{"codemeta:name": "Author 1"}], "codemeta:version": "1.0"}""" # noqa
result = MAPPINGS["JsonSwordCodemetaMapping"]().translate(content)
assert result == {
"@context": "https://doi.org/10.5063/schema/codemeta-2.0",
"author": [
{"name": "Author 1"},
],
"name": "Example Software",
"url": "http://example.org/",
"version": "1.0",
}
def test_json_sword_codemeta_parsing_error(caplog):
caplog.set_level(logging.ERROR)
assert MAPPINGS["JsonSwordCodemetaMapping"]().translate(b"{123}") is None
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment