commonmeta-py 0.27__tar.gz → 0.65__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {commonmeta_py-0.27 → commonmeta_py-0.65}/PKG-INFO +5 -6
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/__init__.py +4 -2
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/base_utils.py +1 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/cli.py +1 -2
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/constants.py +71 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/crossref_utils.py +16 -11
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/date_utils.py +16 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/doi_utils.py +32 -2
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/metadata.py +2 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/readers/crossref_reader.py +2 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/readers/csl_reader.py +2 -2
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/readers/inveniordm_reader.py +1 -3
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/readers/json_feed_reader.py +92 -75
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/readers/kbase_reader.py +1 -1
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/readers/schema_org_reader.py +10 -5
- commonmeta_py-0.65/commonmeta/resources/commonmeta_v0.15.json +575 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/schema_utils.py +1 -1
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/utils.py +164 -59
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/writers/csl_writer.py +8 -6
- commonmeta_py-0.65/commonmeta/writers/inveniordm_writer.py +358 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/pyproject.toml +12 -6
- commonmeta_py-0.27/commonmeta/writers/inveniordm_writer.py +0 -116
- {commonmeta_py-0.27 → commonmeta_py-0.65}/LICENSE +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/README.md +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/api_utils.py +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/author_utils.py +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/readers/__init__.py +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/readers/bibtex_reader.py +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/readers/cff_reader.py +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/readers/codemeta_reader.py +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/readers/commonmeta_reader.py +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/readers/crossref_xml_reader.py +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/readers/datacite_reader.py +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/readers/datacite_xml_reader.py +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/readers/ris_reader.py +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/cff_v1.2.0.json +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/commonmeta_v0.12.json +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/commonmeta_v0.13.json +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/commonmeta_v0.14.json +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/crossref/AccessIndicators.xsd +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/crossref/JATS-journalpublishing1-3d2-mathml3-elements.xsd +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/crossref/JATS-journalpublishing1-3d2-mathml3.xsd +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/crossref/JATS-journalpublishing1-elements.xsd +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/crossref/JATS-journalpublishing1-mathml3-elements.xsd +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/crossref/JATS-journalpublishing1-mathml3.xsd +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/crossref/JATS-journalpublishing1.xsd +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/crossref/clinicaltrials.xsd +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/crossref/common5.3.1.xsd +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/crossref/crossref5.3.1.xsd +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/crossref/crossref_query_output3.0.xsd +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/crossref/fundref.xsd +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/crossref/module-ali.xsd +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/crossref/relations.xsd +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/crossref-v0.2.json +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/csl-data.json +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/datacite-v4.5.json +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/datacite-v4.5pr.json +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/ietf-bcp-47.json +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/iso-8601.json +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/spdx/licenses.json +0 -0
- /commonmeta_py-0.27/commonmeta/resources/spdx-schema..json → /commonmeta_py-0.65/commonmeta/resources/spdx-schema.json +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/styles/apa.csl +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/styles/chicago-author-date.csl +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/styles/harvard-cite-them-right.csl +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/styles/ieee.csl +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/styles/modern-language-association.csl +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/resources/styles/vancouver.csl +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/translators.py +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/writers/__init__.py +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/writers/bibtex_writer.py +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/writers/citation_writer.py +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/writers/commonmeta_writer.py +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/writers/crossref_xml_writer.py +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/writers/datacite_writer.py +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/writers/ris_writer.py +0 -0
- {commonmeta_py-0.27 → commonmeta_py-0.65}/commonmeta/writers/schema_org_writer.py +0 -0
@@ -1,19 +1,20 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: commonmeta-py
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.65
|
4
4
|
Summary: Library for conversions to/from the Commonmeta scholarly metadata format
|
5
5
|
Home-page: https://python.commonmeta.org
|
6
6
|
License: MIT
|
7
7
|
Keywords: science,metadata,commonmeta,bibtex,csl,crossref,datacite
|
8
8
|
Author: Martin Fenner
|
9
9
|
Author-email: martin@front-matter.io
|
10
|
-
Requires-Python: >=3.9,<4.0
|
10
|
+
Requires-Python: >=3.9,<4.0
|
11
11
|
Classifier: License :: OSI Approved :: MIT License
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
13
13
|
Classifier: Programming Language :: Python :: 3.9
|
14
14
|
Classifier: Programming Language :: Python :: 3.10
|
15
15
|
Classifier: Programming Language :: Python :: 3.11
|
16
16
|
Classifier: Programming Language :: Python :: 3.12
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
17
18
|
Requires-Dist: PyYAML (>=6.0,<7.0)
|
18
19
|
Requires-Dist: anyio (>=4.2.0,<5.0.0)
|
19
20
|
Requires-Dist: asyncclick (>=8.1.7.1,<9.0.0.0)
|
@@ -27,23 +28,21 @@ Requires-Dist: click (>=8.1.7,<9.0.0)
|
|
27
28
|
Requires-Dist: datacite (>=1.1,<2.0)
|
28
29
|
Requires-Dist: dateparser (>=1.1.7,<2.0.0)
|
29
30
|
Requires-Dist: docutils (>=0.19,<0.20)
|
31
|
+
Requires-Dist: edtf (>=5.0.0,<6.0.0)
|
30
32
|
Requires-Dist: furl (>=2.1.3,<3.0.0)
|
31
33
|
Requires-Dist: httpx (>=0.27,<0.28)
|
32
34
|
Requires-Dist: jsonschema (>=4.21,<5.0)
|
33
|
-
Requires-Dist: jupyterlab (>=4.0.9,<5.0.0)
|
34
|
-
Requires-Dist: jupyterlab-quarto (>=0.2.8,<0.3.0)
|
35
35
|
Requires-Dist: lxml (>=4.8)
|
36
36
|
Requires-Dist: nameparser (>=1.1.2,<2.0.0)
|
37
37
|
Requires-Dist: nbstripout (>=0.6,<0.7)
|
38
38
|
Requires-Dist: nh3 (>=0.2.14,<0.3.0)
|
39
39
|
Requires-Dist: orjson (>=3.9.14,<4.0.0)
|
40
40
|
Requires-Dist: orjsonl (>=1.0.0,<2.0.0)
|
41
|
-
Requires-Dist: pikepdf (>=8.14
|
41
|
+
Requires-Dist: pikepdf (>=8.14,<10.0)
|
42
42
|
Requires-Dist: pycountry (>=23.12.11,<24.0.0)
|
43
43
|
Requires-Dist: pydash (>=7.0,<8.0)
|
44
44
|
Requires-Dist: pyjwt (>=2.8.0,<3.0.0)
|
45
45
|
Requires-Dist: python-dateutil (>=2.8.2,<3.0.0)
|
46
|
-
Requires-Dist: quartodoc (>=0.7.1,<0.8.0)
|
47
46
|
Requires-Dist: setuptools (>=70.0,<71.0)
|
48
47
|
Requires-Dist: simplejson (>=3.18,<4.0)
|
49
48
|
Requires-Dist: sphinx-autodoc-typehints (>=1.19,<2.0)
|
@@ -10,7 +10,7 @@ commonmeta-py is a Python library to convert scholarly metadata
|
|
10
10
|
"""
|
11
11
|
|
12
12
|
__title__ = "commonmeta-py"
|
13
|
-
__version__ = "0.
|
13
|
+
__version__ = "0.65"
|
14
14
|
__author__ = "Martin Fenner"
|
15
15
|
__license__ = "MIT"
|
16
16
|
|
@@ -54,7 +54,6 @@ from .utils import (
|
|
54
54
|
validate_orcid,
|
55
55
|
validate_url,
|
56
56
|
get_language,
|
57
|
-
encode_doi,
|
58
57
|
name_to_fos,
|
59
58
|
from_json_feed,
|
60
59
|
)
|
@@ -88,9 +87,12 @@ from .doi_utils import (
|
|
88
87
|
doi_from_url,
|
89
88
|
doi_as_url,
|
90
89
|
doi_resolver,
|
90
|
+
decode_doi,
|
91
|
+
encode_doi,
|
91
92
|
datacite_api_url,
|
92
93
|
get_doi_ra,
|
93
94
|
normalize_doi,
|
94
95
|
validate_doi,
|
95
96
|
validate_prefix,
|
97
|
+
is_rogue_scholar_doi,
|
96
98
|
)
|
@@ -5,8 +5,7 @@ import orjson as json
|
|
5
5
|
|
6
6
|
from commonmeta import Metadata, MetadataList # __version__
|
7
7
|
from commonmeta.api_utils import update_ghost_post_via_api
|
8
|
-
from commonmeta.doi_utils import validate_prefix
|
9
|
-
from commonmeta.utils import encode_doi, decode_doi
|
8
|
+
from commonmeta.doi_utils import validate_prefix, encode_doi, decode_doi
|
10
9
|
from commonmeta.readers.json_feed_reader import (
|
11
10
|
get_json_feed_item_uuid,
|
12
11
|
)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
"""Constants for commonmeta-py"""
|
2
|
+
|
2
3
|
from typing import Optional, TypedDict, List
|
3
4
|
|
4
5
|
|
@@ -407,11 +408,32 @@ SO_TO_CM_TRANSLATIONS = {
|
|
407
408
|
"DigitalDocument": "Document",
|
408
409
|
"Dissertation": "Dissertation",
|
409
410
|
"Instrument": "Instrument",
|
411
|
+
"MusicRecording": "Audiovisual",
|
412
|
+
"MusicAlbum": "Audiovisual",
|
410
413
|
"NewsArticle": "Article",
|
411
414
|
"Legislation": "LegalDocument",
|
415
|
+
"ProfilePage": "WebPage",
|
412
416
|
"Report": "Report",
|
413
417
|
"ScholarlyArticle": "JournalArticle",
|
414
418
|
"SoftwareSourceCode": "Software",
|
419
|
+
"Video": "Audiovisual",
|
420
|
+
"WebSite": "WebPage",
|
421
|
+
}
|
422
|
+
|
423
|
+
# OpenGraph to schema.org mapping
|
424
|
+
OG_TO_SO_TRANSLATIONS = {
|
425
|
+
"music.song": "MusicRecording",
|
426
|
+
"music.album": "MusicAlbum",
|
427
|
+
"music.playlist": "MusicPlaylist",
|
428
|
+
"music.radio_station": "RadioStation",
|
429
|
+
"video.movie": "Video",
|
430
|
+
"video.episode": "Video",
|
431
|
+
"video.tv_show": "Video",
|
432
|
+
"video.other": "Video",
|
433
|
+
"article": "Article",
|
434
|
+
"book": "Book",
|
435
|
+
"profile": "ProfilePage",
|
436
|
+
"website": "WebSite",
|
415
437
|
}
|
416
438
|
|
417
439
|
CM_TO_SO_TRANSLATIONS = {
|
@@ -585,3 +607,52 @@ COMMONMETA_CONTRIBUTOR_ROLES = [
|
|
585
607
|
"Maintainer",
|
586
608
|
"Other",
|
587
609
|
]
|
610
|
+
|
611
|
+
INVENIORDM_IDENTIFIER_TYPES = {
|
612
|
+
"Ark": "ark",
|
613
|
+
"ArXiv": "arxiv",
|
614
|
+
"Bibcode": "ads",
|
615
|
+
"CrossrefFunderID": "crossreffunderid",
|
616
|
+
"DOI": "doi",
|
617
|
+
"EAN13": "ean13",
|
618
|
+
"EISSN": "eissn",
|
619
|
+
"GRID": "grid",
|
620
|
+
"Handle": "handle",
|
621
|
+
"IGSN": "igsn",
|
622
|
+
"ISBN": "isbn",
|
623
|
+
"ISNI": "isni",
|
624
|
+
"ISSN": "issn",
|
625
|
+
"ISTC": "istc",
|
626
|
+
"LISSN": "lissn",
|
627
|
+
"LSID": "lsid",
|
628
|
+
"PMID": "pmid",
|
629
|
+
"PURL": "purl",
|
630
|
+
"UPC": "upc",
|
631
|
+
"URL": "url",
|
632
|
+
"URN": "urn",
|
633
|
+
"W3ID": "w3id",
|
634
|
+
"GUID": "guid",
|
635
|
+
"UUID": "uuid",
|
636
|
+
"Other": "other",
|
637
|
+
}
|
638
|
+
|
639
|
+
|
640
|
+
CROSSREF_FUNDER_ID_TO_ROR_TRANSLATIONS = {
|
641
|
+
"https://doi.org/10.13039/100000001": "https://ror.org/021nxhr62",
|
642
|
+
"https://doi.org/10.13039/501100000780": "https://ror.org/00k4n6c32",
|
643
|
+
"https://doi.org/10.13039/501100007601": "https://ror.org/00k4n6c32",
|
644
|
+
"https://doi.org/10.13039/501100001659": "https://ror.org/018mejw64",
|
645
|
+
"https://doi.org/10.13039/501100006390": "https://ror.org/019whta54",
|
646
|
+
"https://doi.org/10.13039/501100001711": "https://ror.org/00yjd3n13",
|
647
|
+
"https://doi.org/10.13039/501100003043": "https://ror.org/04wfr2810",
|
648
|
+
}
|
649
|
+
|
650
|
+
|
651
|
+
ROR_TO_CROSSREF_FUNDER_ID_TRANSLATIONS = {
|
652
|
+
"https://ror.org/021nxhr62": "https://doi.org/10.13039/100000001",
|
653
|
+
"https://ror.org/00k4n6c32": "https://doi.org/10.13039/501100000780",
|
654
|
+
"https://ror.org/018mejw64": "https://doi.org/10.13039/501100001659",
|
655
|
+
"https://ror.org/019whta54": "https://doi.org/10.13039/501100006390",
|
656
|
+
"https://ror.org/00yjd3n13": "https://doi.org/10.13039/501100001711",
|
657
|
+
"https://ror.org/04wfr2810": "https://doi.org/10.13039/501100003043",
|
658
|
+
}
|
@@ -8,7 +8,7 @@ import uuid
|
|
8
8
|
import pydash as py_
|
9
9
|
from furl import furl
|
10
10
|
|
11
|
-
from .constants import Commonmeta
|
11
|
+
from .constants import Commonmeta, ROR_TO_CROSSREF_FUNDER_ID_TRANSLATIONS
|
12
12
|
from .utils import wrap, compact, normalize_orcid, normalize_id, validate_url
|
13
13
|
from .doi_utils import doi_from_url, validate_doi
|
14
14
|
|
@@ -112,9 +112,11 @@ def insert_group_title(metadata, xml):
|
|
112
112
|
"""Insert group title"""
|
113
113
|
if metadata.subjects is None or len(metadata.subjects) == 0:
|
114
114
|
return xml
|
115
|
-
|
116
|
-
|
117
|
-
)
|
115
|
+
group_title = metadata.subjects[0].get("subject", None)
|
116
|
+
# strip optional FOS (Field of Science) prefix
|
117
|
+
if group_title.startswith("FOS: "):
|
118
|
+
group_title = group_title[5:]
|
119
|
+
etree.SubElement(xml, "group_title").text = group_title
|
118
120
|
return xml
|
119
121
|
|
120
122
|
|
@@ -360,11 +362,18 @@ def insert_funding_references(metadata, xml):
|
|
360
362
|
{"name": "funder_name"},
|
361
363
|
)
|
362
364
|
if funding_reference.get("funderIdentifier", None) is not None:
|
365
|
+
funder_identifier = funding_reference.get("funderIdentifier", None)
|
366
|
+
|
367
|
+
# translate ROR to Crossref funder ID until Crossref supports ROR
|
368
|
+
funder_identifier = ROR_TO_CROSSREF_FUNDER_ID_TRANSLATIONS.get(
|
369
|
+
funder_identifier, funder_identifier
|
370
|
+
)
|
371
|
+
|
363
372
|
etree.SubElement(
|
364
373
|
funder_name,
|
365
374
|
"assertion",
|
366
375
|
{"name": "funder_identifier"},
|
367
|
-
).text =
|
376
|
+
).text = funder_identifier
|
368
377
|
if funding_reference.get("awardNumber", None) is not None:
|
369
378
|
etree.SubElement(
|
370
379
|
assertion,
|
@@ -440,9 +449,7 @@ def insert_item_number(metadata, xml):
|
|
440
449
|
if metadata.identifiers is None:
|
441
450
|
return xml
|
442
451
|
for identifier in metadata.identifiers:
|
443
|
-
if identifier.get("
|
444
|
-
continue
|
445
|
-
if identifier.get("identifierType", None) is not None:
|
452
|
+
if identifier.get("identifierType", None) == "UUID":
|
446
453
|
# strip hyphen from UUIDs, as item_number can only be 32 characters long (UUIDv4 is 36 characters long)
|
447
454
|
if identifier.get("identifierType", None) == "UUID":
|
448
455
|
identifier["identifier"] = identifier.get("identifier", "").replace(
|
@@ -454,9 +461,7 @@ def insert_item_number(metadata, xml):
|
|
454
461
|
{"item_number_type": identifier.get("identifierType", "").lower()},
|
455
462
|
).text = identifier.get("identifier", None)
|
456
463
|
else:
|
457
|
-
|
458
|
-
"identifier", None
|
459
|
-
)
|
464
|
+
continue
|
460
465
|
return xml
|
461
466
|
|
462
467
|
|
@@ -3,6 +3,8 @@ import datetime
|
|
3
3
|
from datetime import datetime as dt
|
4
4
|
from typing import Optional, Union
|
5
5
|
import dateparser
|
6
|
+
from edtf import parse_edtf, DateAndTime, Date
|
7
|
+
from edtf.parser.edtf_exceptions import EDTFParseException
|
6
8
|
import pydash as py_
|
7
9
|
|
8
10
|
from .base_utils import compact
|
@@ -191,3 +193,17 @@ def normalize_date_dict(data: dict) -> dict:
|
|
191
193
|
"withdrawn": data.get("Withdrawn", None),
|
192
194
|
}
|
193
195
|
)
|
196
|
+
|
197
|
+
|
198
|
+
def validate_edtf(iso8601_time: Optional[str]) -> Optional[str]:
|
199
|
+
"""Validate EDTF string using edtf. Return None if invalid"""
|
200
|
+
if iso8601_time is None:
|
201
|
+
return None
|
202
|
+
try:
|
203
|
+
edtf = parse_edtf(iso8601_time)
|
204
|
+
except EDTFParseException as e:
|
205
|
+
print(e)
|
206
|
+
return None
|
207
|
+
if not isinstance(edtf, (DateAndTime, Date)):
|
208
|
+
return None
|
209
|
+
return edtf.isoformat()
|
@@ -4,6 +4,7 @@ import re
|
|
4
4
|
from typing import Optional
|
5
5
|
import httpx
|
6
6
|
from furl import furl
|
7
|
+
import base32_lib as base32
|
7
8
|
|
8
9
|
from .base_utils import compact
|
9
10
|
|
@@ -131,6 +132,34 @@ def get_doi_ra(doi) -> Optional[str]:
|
|
131
132
|
return response.json()[0].get("RA", None)
|
132
133
|
|
133
134
|
|
135
|
+
def encode_doi(prefix, number: Optional[int] = None, checksum: bool = True) -> str:
|
136
|
+
"""Generate a DOI using the DOI prefix and a random base32 suffix"""
|
137
|
+
if isinstance(number, int):
|
138
|
+
suffix = base32.encode(number, split_every=5, checksum=checksum)
|
139
|
+
else:
|
140
|
+
suffix = base32.generate(length=10, split_every=5, checksum=True)
|
141
|
+
print("s", suffix)
|
142
|
+
return f"https://doi.org/{prefix}/{suffix}"
|
143
|
+
|
144
|
+
|
145
|
+
def decode_doi(doi: str, checksum: bool = True) -> int:
|
146
|
+
"""Decode a DOI to a number"""
|
147
|
+
try:
|
148
|
+
doi = validate_doi(doi)
|
149
|
+
if doi is None:
|
150
|
+
return 0
|
151
|
+
suffix = doi.split("/", maxsplit=1)[1]
|
152
|
+
print(suffix, checksum)
|
153
|
+
if checksum:
|
154
|
+
number = base32.decode(suffix, checksum=True)
|
155
|
+
print("n", number)
|
156
|
+
number = base32.decode(suffix)
|
157
|
+
print("nn", number)
|
158
|
+
return number
|
159
|
+
except ValueError:
|
160
|
+
return 0
|
161
|
+
|
162
|
+
|
134
163
|
def get_crossref_member(member_id) -> Optional[dict]:
|
135
164
|
"""Return the Crossref member for a given member_id"""
|
136
165
|
response = httpx.get("https://api.crossref.org/members/" + member_id, timeout=10)
|
@@ -263,10 +292,11 @@ def is_rogue_scholar_doi(doi: str) -> bool:
|
|
263
292
|
"""Return True if DOI is from Rogue Scholar"""
|
264
293
|
prefix = validate_prefix(doi)
|
265
294
|
return prefix in [
|
266
|
-
"10.34732",
|
295
|
+
"10.34732", # not managed by Front Matter
|
267
296
|
"10.53731",
|
268
297
|
"10.54900",
|
269
|
-
"10.57689",
|
298
|
+
"10.57689", # not managed by Front Matter
|
299
|
+
"10.58079", # not managed by Front Matter
|
270
300
|
"10.59348",
|
271
301
|
"10.59349",
|
272
302
|
"10.59350",
|
@@ -101,6 +101,8 @@ class Metadata:
|
|
101
101
|
self.titles = meta.get("titles")
|
102
102
|
self.url = meta.get("url")
|
103
103
|
self.version = meta.get("version")
|
104
|
+
self.content = meta.get("content")
|
105
|
+
self.image = meta.get("image")
|
104
106
|
# other properties
|
105
107
|
self.date_created = meta.get("date_created")
|
106
108
|
self.date_registered = meta.get("date_registered")
|
@@ -339,6 +339,8 @@ def get_container(meta: dict, issn: str) -> dict:
|
|
339
339
|
)
|
340
340
|
isbn = isbn["value"] if isbn else None
|
341
341
|
container_title = parse_attributes(meta.get("container-title", None), first=True)
|
342
|
+
if not container_title and container_type in ["Periodical"]:
|
343
|
+
container_title = py_.get(meta, "institution.0.name")
|
342
344
|
volume = meta.get("volume", None)
|
343
345
|
issue = py_.get(meta, "journal-issue.issue")
|
344
346
|
if meta.get("page", None):
|
@@ -1,9 +1,9 @@
|
|
1
1
|
"""CSL-JSON reader for commonmeta-py"""
|
2
|
-
from ..utils import dict_to_spdx, from_csl, normalize_id, name_to_fos
|
2
|
+
from ..utils import dict_to_spdx, from_csl, normalize_id, name_to_fos
|
3
3
|
from ..base_utils import wrap, compact, sanitize, presence
|
4
4
|
from ..author_utils import get_authors
|
5
5
|
from ..date_utils import get_date_from_date_parts
|
6
|
-
from ..doi_utils import get_doi_ra, doi_from_url
|
6
|
+
from ..doi_utils import get_doi_ra, doi_from_url, encode_doi
|
7
7
|
from ..constants import (
|
8
8
|
CSL_TO_CM_TRANSLATIONS,
|
9
9
|
Commonmeta,
|
@@ -36,7 +36,6 @@ def get_inveniordm(pid: str, **kwargs) -> dict:
|
|
36
36
|
|
37
37
|
def read_inveniordm(data: dict, **kwargs) -> Commonmeta:
|
38
38
|
"""read_inveniordm"""
|
39
|
-
print(data)
|
40
39
|
meta = data
|
41
40
|
read_options = kwargs or {}
|
42
41
|
|
@@ -49,7 +48,6 @@ def read_inveniordm(data: dict, **kwargs) -> Commonmeta:
|
|
49
48
|
resource_type = py_.get(meta, "metadata.resource_type.type") or py_.get(
|
50
49
|
meta, "metadata.resource_type.id"
|
51
50
|
)
|
52
|
-
print(resource_type)
|
53
51
|
_type = INVENIORDM_TO_CM_TRANSLATIONS.get(resource_type, "Other")
|
54
52
|
|
55
53
|
contributors = py_.get(meta, "metadata.creators")
|
@@ -79,6 +77,7 @@ def read_inveniordm(data: dict, **kwargs) -> Commonmeta:
|
|
79
77
|
"title": "Zenodo",
|
80
78
|
}
|
81
79
|
)
|
80
|
+
publisher = {"name": "Zenodo"}
|
82
81
|
else:
|
83
82
|
container = py_.get(meta, "custom_fields.journal:journal")
|
84
83
|
if container:
|
@@ -96,7 +95,6 @@ def read_inveniordm(data: dict, **kwargs) -> Commonmeta:
|
|
96
95
|
)
|
97
96
|
if license_:
|
98
97
|
license_ = dict_to_spdx({"id": license_})
|
99
|
-
print(license_)
|
100
98
|
descriptions = format_descriptions(
|
101
99
|
[
|
102
100
|
py_.get(meta, "metadata.description"),
|