Skip to content

Commit 4213666

Browse files
committed
codemeta.json creation class (temp)
1 parent 3909e91 commit 4213666

1 file changed

Lines changed: 141 additions & 0 deletions

File tree

src/somesy/codemeta/create.py

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
"""codemeta.json creation module."""
2+
import json
3+
import logging
4+
from collections import OrderedDict
5+
from pathlib import Path
6+
from typing import List, Optional
7+
8+
from rich.pretty import pretty_repr
9+
10+
from somesy.core.models import Person, ProjectMetadata
11+
from somesy.core.writer import ProjectMetadataWriter
12+
13+
logger = logging.getLogger("somesy")
14+
15+
16+
class Codemeta(ProjectMetadataWriter):
17+
"""Codemeta.json parser and saver."""
18+
19+
def __init__(
20+
self,
21+
path: Path,
22+
):
23+
"""Codemeta.json parser.
24+
25+
See [somesy.core.writer.ProjectMetadataWriter.__init__][].
26+
"""
27+
mappings = {
28+
"repository": ["codeRepository"],
29+
"homepage": ["softwareHelp"],
30+
"keywords": ["keywords"],
31+
"authors": ["author"],
32+
"maintainers": ["maintainer"],
33+
"contributors": ["contributor"],
34+
}
35+
super().__init__(path, create_if_not_exists=True, direct_mappings=mappings)
36+
37+
@property
38+
def authors(self):
39+
"""Return the only author of the package.json file as list."""
40+
return self._get_property(self._get_key("publication_authors")) or []
41+
42+
@authors.setter
43+
def authors(self, authors: List[Person]) -> None:
44+
"""Set the authors of the project."""
45+
authors = [self._from_person(a) for a in authors]
46+
self._set_property(self._get_key("authors"), authors)
47+
48+
@property
49+
def contributors(self):
50+
"""Return the contributors of the package.json file."""
51+
return self._get_property(self._get_key("contributors"))
52+
53+
@contributors.setter
54+
def contributors(self, contributors: List[Person]) -> None:
55+
"""Set the contributors of the project."""
56+
contributors = [self._from_person(c) for c in contributors]
57+
self._set_property(self._get_key("contributors"), contributors)
58+
59+
def _load(self) -> None:
60+
"""Load package.json file."""
61+
with self.path.open() as f:
62+
self._data = json.load(f, object_pairs_hook=OrderedDict)
63+
64+
def _validate(self) -> None:
65+
"""Validate package.json content using pydantic class."""
66+
config = dict(self._get_property([]))
67+
68+
logger.debug(
69+
f"No validation for codemeta {Codemeta.__name__}: {pretty_repr(config)}"
70+
)
71+
72+
def _init_new_file(self) -> None:
73+
data = {
74+
"@context": [
75+
"https://doi.org/10.5063/schema/codemeta-2.0",
76+
"https://w3id.org/software-iodata",
77+
"https://raw.githubusercontent.com/jantman/repostatus.org/master/badges/latest/ontology.jsonld",
78+
"https://schema.org",
79+
"https://w3id.org/software-types",
80+
],
81+
"@type": "SoftwareSourceCode",
82+
"author": [],
83+
}
84+
# dump to file
85+
with self.path.open("w") as f:
86+
json.dump(data, f, indent=2)
87+
88+
def save(self, path: Optional[Path] = None) -> None:
89+
"""Save the package.json file."""
90+
path = path or self.path
91+
logger.debug(f"Saving package.json to {path}")
92+
93+
# copy the _data
94+
data = self._data.copy()
95+
96+
# set license
97+
if "license" in data:
98+
data["license"] = (f"https://spdx.org/licenses/{data['license']}",)
99+
100+
# if softwareHelp is set, set url to softwareHelp
101+
if "softwareHelp" in data:
102+
data["url"] = data["softwareHelp"]
103+
104+
with path.open("w") as f:
105+
# package.json indentation is 2 spaces
106+
json.dump(data, f, indent=2)
107+
108+
@staticmethod
109+
def _from_person(person: Person):
110+
"""Convert project metadata person object to package.json dict for person format."""
111+
person_dict = {
112+
"givenName": person.given_names,
113+
"familyName": person.family_names,
114+
"@type": "Person",
115+
}
116+
if person.email:
117+
person_dict["email"] = person.email
118+
if person.orcid:
119+
person_dict["@id"] = str(person.orcid)
120+
return person_dict
121+
122+
@staticmethod
123+
def _to_person(person) -> Person:
124+
"""Convert package.json dict or str for person format to project metadata person object."""
125+
person_obj = {
126+
"given-names": person["givenName"],
127+
"family-names": person["familyName"],
128+
}
129+
if "email" in person:
130+
person_obj["email"] = person["email"].strip()
131+
if "@id" in person:
132+
person_obj["orcid"] = person["@id"].strip()
133+
return Person(**person_obj)
134+
135+
def sync(self, metadata: ProjectMetadata) -> None:
136+
"""Sync package.json with project metadata.
137+
138+
Use existing sync function from ProjectMetadataWriter but update repository and contributors.
139+
"""
140+
super().sync(metadata)
141+
self.contributors = self._sync_person_list(self.contributors, metadata.people)

0 commit comments

Comments
 (0)