Skip to content

Commit 2f33742

Browse files
committed
feat: support multiple ways of linking codemeta roles
1 parent 2c7a24c commit 2f33742

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

codemeticulous/codemeta/models.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,37 @@ def collapse_jsonld_context(cls, values):
200200
values.pop("@context", None)
201201
return values
202202

203+
@root_validator(pre=True)
204+
def fix_role_node_link(cls, values):
205+
"""roles aren't terribly well documented, but they appear to be done by linking
206+
a Role to a Person or Organization node with "@id" or "contributor"/"author". The
207+
Codemeta generator uses the key "schema:author" and "contributor", but it seems better
208+
to use the node @id that actually exists in a schema.org Role
209+
210+
see https://github.com/codemeta/codemeta/issues/240
211+
"""
212+
KEYS = ["author", "contributor", "schema:author", "schema:contributor"]
213+
214+
def transform_role(role_item):
215+
if isinstance(role_item, dict) and (
216+
role_item.get("type") == "Role" or role_item.get("@type") == "Role"
217+
):
218+
for key in KEYS:
219+
if key in role_item:
220+
role_item["@id"] = role_item.pop(key)
221+
break
222+
return role_item
223+
224+
for field in ["author", "contributor"]:
225+
if field in values:
226+
if isinstance(values[field], list):
227+
values[field] = [
228+
transform_role(role_item) for role_item in values[field]
229+
]
230+
else:
231+
values[field] = transform_role(values[field])
232+
return values
233+
203234
@root_validator(pre=True)
204235
def coalesce_embargo_end_date(cls, values):
205236
embargo_date = values.get("embargoDate")

0 commit comments

Comments
 (0)