commonmeta-py 0.117__tar.gz → 0.119__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.117 → commonmeta_py-0.119}/PKG-INFO +2 -2
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/__init__.py +1 -1
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/doi_utils.py +0 -1
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/file_utils.py +0 -10
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/writers/crossref_xml_writer.py +43 -38
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/writers/inveniordm_writer.py +52 -39
- {commonmeta_py-0.117 → commonmeta_py-0.119}/pyproject.toml +2 -2
- {commonmeta_py-0.117 → commonmeta_py-0.119}/.gitignore +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/LICENSE +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/README.md +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/api_utils.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/author_utils.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/base_utils.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/cli.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/constants.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/date_utils.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/metadata.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/readers/__init__.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/readers/bibtex_reader.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/readers/cff_reader.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/readers/codemeta_reader.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/readers/commonmeta_reader.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/readers/crossref_reader.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/readers/crossref_xml_reader.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/readers/csl_reader.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/readers/datacite_reader.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/readers/datacite_xml_reader.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/readers/inveniordm_reader.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/readers/jsonfeed_reader.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/readers/kbase_reader.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/readers/openalex_reader.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/readers/ris_reader.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/readers/schema_org_reader.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/cff_v1.2.0.json +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/commonmeta_v0.12.json +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/commonmeta_v0.13.json +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/commonmeta_v0.14.json +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/commonmeta_v0.15.json +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/commonmeta_v0.16.json +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/AccessIndicators.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/JATS-journalpublishing1-3d2-mathml3-elements.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/JATS-journalpublishing1-3d2-mathml3.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/JATS-journalpublishing1-elements.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/JATS-journalpublishing1-mathml3-elements.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/JATS-journalpublishing1-mathml3.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/JATS-journalpublishing1.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/clinicaltrials.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/common5.4.0.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/crossref5.4.0.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/crossref_query_output3.0.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/doi_resources5.4.0.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/fundingdata5.4.0.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/fundref.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/languages5.4.0.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/mediatypes5.4.0.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/module-ali.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/relations.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/standard-modules/mathml3/mathml3-common.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/standard-modules/mathml3/mathml3-content.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/standard-modules/mathml3/mathml3-presentation.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/standard-modules/mathml3/mathml3-strict-content.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/standard-modules/mathml3/mathml3.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/standard-modules/mathml3/module-ali.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/standard-modules/module-ali.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/standard-modules/xlink.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/standard-modules/xml.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/xml.xsd +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref-v0.2.json +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/csl-data.json +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/datacite-v4.5.json +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/datacite-v4.5pr.json +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/spdx/licenses.json +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/spdx-schema.json +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/styles/apa.csl +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/styles/chicago-author-date.csl +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/styles/harvard-cite-them-right.csl +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/styles/ieee.csl +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/styles/modern-language-association.csl +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/styles/vancouver.csl +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/schema_utils.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/translators.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/utils.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/writers/__init__.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/writers/bibtex_writer.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/writers/citation_writer.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/writers/commonmeta_writer.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/writers/csl_writer.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/writers/datacite_writer.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/writers/ris_writer.py +0 -0
- {commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/writers/schema_org_writer.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: commonmeta-py
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.119
|
4
4
|
Summary: Library for conversions to/from the Commonmeta scholarly metadata format
|
5
5
|
Project-URL: Homepage, https://python.commonmeta.org
|
6
6
|
Project-URL: Repository, https://github.com/front-matter/commonmeta-py
|
@@ -36,7 +36,7 @@ Requires-Dist: pyyaml>=5.4
|
|
36
36
|
Requires-Dist: requests-toolbelt>=1.0.0
|
37
37
|
Requires-Dist: requests>=2.31.0
|
38
38
|
Requires-Dist: requests>=2.32.3
|
39
|
-
Requires-Dist: setuptools
|
39
|
+
Requires-Dist: setuptools<81,>=70.3.0
|
40
40
|
Requires-Dist: simplejson~=3.18
|
41
41
|
Requires-Dist: types-beautifulsoup4<5,>=4.11
|
42
42
|
Requires-Dist: types-dateparser~=1.1
|
@@ -342,7 +342,6 @@ def is_rogue_scholar_doi(doi: str, ra: str = "crossref") -> bool:
|
|
342
342
|
|
343
343
|
def generate_wordpress_doi(prefix: str, slug: str, guid: str) -> str:
|
344
344
|
"""Generate a DOI from a WordPress GUID and slug"""
|
345
|
-
import re
|
346
345
|
|
347
346
|
if not prefix or not guid:
|
348
347
|
return ""
|
@@ -44,16 +44,6 @@ def download_file(url: str) -> bytes:
|
|
44
44
|
resp = requests.get(url, stream=True)
|
45
45
|
resp.raise_for_status()
|
46
46
|
return resp.content
|
47
|
-
# # Progress bar
|
48
|
-
# total = int(resp.headers.get("content-length", 0))
|
49
|
-
|
50
|
-
# buf = io.BytesIO()
|
51
|
-
# with tqdm(total=total, unit="B", unit_scale=True, desc="downloading") as bar:
|
52
|
-
# for chunk in resp.iter_content(chunk_size=8192):
|
53
|
-
# if chunk:
|
54
|
-
# buf.write(chunk)
|
55
|
-
# bar.update(len(chunk))
|
56
|
-
# return buf.getvalue()
|
57
47
|
|
58
48
|
|
59
49
|
def write_file(filename: str, output: bytes) -> None:
|
@@ -1,6 +1,7 @@
|
|
1
1
|
"""Crossref XML writer for commonmeta-py"""
|
2
2
|
|
3
3
|
import io
|
4
|
+
import logging
|
4
5
|
from datetime import datetime
|
5
6
|
from time import time
|
6
7
|
from typing import Optional
|
@@ -18,6 +19,8 @@ from ..constants import Commonmeta
|
|
18
19
|
from ..doi_utils import doi_from_url, validate_doi
|
19
20
|
from ..utils import validate_url
|
20
21
|
|
22
|
+
logger = logging.getLogger(__name__)
|
23
|
+
|
21
24
|
POSTED_CONTENT_TYPES = [
|
22
25
|
"preprint",
|
23
26
|
"working_paper",
|
@@ -342,20 +345,25 @@ def write_crossref_xml(metadata: Commonmeta) -> Optional[str]:
|
|
342
345
|
|
343
346
|
data = convert_crossref_xml(metadata)
|
344
347
|
if data is None:
|
348
|
+
logger.error(f"Could not convert metadata to Crossref XML: {metadata.id}")
|
345
349
|
return None
|
350
|
+
|
351
|
+
# Use the marshmallow schema to dump the data
|
346
352
|
schema = CrossrefXMLSchema()
|
347
353
|
crossref_xml = schema.dump(data)
|
348
354
|
|
349
|
-
# Ensure
|
355
|
+
# Ensure consistent field ordering through the defined mapping
|
350
356
|
field_order = [MARSHMALLOW_MAP.get(k, k) for k in list(data.keys())]
|
351
357
|
crossref_xml = {k: crossref_xml[k] for k in field_order if k in crossref_xml}
|
358
|
+
|
352
359
|
# Convert to XML
|
353
360
|
return unparse_xml(crossref_xml, dialect="crossref")
|
354
361
|
|
355
362
|
|
356
|
-
def write_crossref_xml_list(metalist):
|
363
|
+
def write_crossref_xml_list(metalist) -> Optional[str]:
|
357
364
|
"""Write crossref_xml list"""
|
358
365
|
if metalist is None or not metalist.is_valid:
|
366
|
+
logger.error("Invalid metalist provided for Crossref XML generation")
|
359
367
|
return None
|
360
368
|
|
361
369
|
schema = CrossrefXMLSchema()
|
@@ -380,15 +388,17 @@ def push_crossref_xml_list(metalist, login_id: str, login_passwd: str) -> bytes:
|
|
380
388
|
"""Push crossref_xml list to Crossref API, returns the API response."""
|
381
389
|
|
382
390
|
input = write_crossref_xml_list(metalist)
|
391
|
+
if not input:
|
392
|
+
logger.error("Failed to generate XML for upload")
|
393
|
+
return "{}"
|
383
394
|
|
384
395
|
# Convert string to bytes if necessary
|
385
396
|
if isinstance(input, str):
|
386
397
|
input = input.encode("utf-8")
|
387
398
|
|
388
|
-
# The filename displayed in the Crossref admin interface
|
399
|
+
# The filename displayed in the Crossref admin interface
|
389
400
|
filename = f"{int(time())}"
|
390
401
|
|
391
|
-
# Create multipart form data
|
392
402
|
multipart_data = MultipartEncoder(
|
393
403
|
fields={
|
394
404
|
"fname": (filename, io.BytesIO(input), "application/xml"),
|
@@ -398,38 +408,32 @@ def push_crossref_xml_list(metalist, login_id: str, login_passwd: str) -> bytes:
|
|
398
408
|
}
|
399
409
|
)
|
400
410
|
|
401
|
-
# Set up the request
|
402
411
|
post_url = "https://doi.crossref.org/servlet/deposit"
|
403
412
|
headers = {"Content-Type": multipart_data.content_type}
|
413
|
+
resp = requests.post(post_url, data=multipart_data, headers=headers, timeout=10)
|
414
|
+
resp.raise_for_status()
|
415
|
+
|
416
|
+
# Parse the response
|
417
|
+
response = parse_xml(resp.content)
|
418
|
+
status = py_.get(response, "html.body.h2")
|
419
|
+
if status == "SUCCESS":
|
420
|
+
items = []
|
421
|
+
for item in metalist.items:
|
422
|
+
items.append(
|
423
|
+
{
|
424
|
+
"doi": item.id,
|
425
|
+
"updated": datetime.now().isoformat("T", "seconds"),
|
426
|
+
"status": "submitted",
|
427
|
+
}
|
428
|
+
)
|
404
429
|
|
405
|
-
|
406
|
-
|
407
|
-
resp = requests.post(post_url, data=multipart_data, headers=headers, timeout=10)
|
408
|
-
resp.raise_for_status()
|
409
|
-
|
410
|
-
# Parse the response
|
411
|
-
response = parse_xml(resp.content)
|
412
|
-
status = py_.get(response, "html.body.h2")
|
413
|
-
if status == "SUCCESS":
|
414
|
-
items = []
|
415
|
-
for item in metalist.items:
|
416
|
-
items.append(
|
417
|
-
{
|
418
|
-
"doi": item.id,
|
419
|
-
"updated": datetime.now().isoformat("T", "seconds"),
|
420
|
-
"status": "submitted",
|
421
|
-
}
|
422
|
-
)
|
423
|
-
|
424
|
-
# orjson has different options
|
425
|
-
return json.dumps(items, option=json.OPT_INDENT_2)
|
426
|
-
|
427
|
-
# if there is an error
|
428
|
-
message = py_.get(response, "html.body.p")
|
429
|
-
raise CrossrefError(f"Error uploading batch: {message}")
|
430
|
+
# Return JSON response
|
431
|
+
return json.dumps(items, option=json.OPT_INDENT_2)
|
430
432
|
|
431
|
-
|
432
|
-
|
433
|
+
# Handle error response
|
434
|
+
message = py_.get(response, "html.body.p")
|
435
|
+
logger.error(f"Crossref API error: {message}")
|
436
|
+
return "{}"
|
433
437
|
|
434
438
|
|
435
439
|
def get_attributes(obj, **kwargs) -> dict:
|
@@ -539,15 +543,16 @@ def get_institution(obj) -> Optional[dict]:
|
|
539
543
|
def get_titles(obj) -> Optional[dict]:
|
540
544
|
"""get titles"""
|
541
545
|
|
542
|
-
|
546
|
+
titles = {}
|
543
547
|
for t in wrap(py_.get(obj, "titles", [])):
|
544
548
|
if isinstance(t, str):
|
545
|
-
|
549
|
+
titles["title"] = t
|
546
550
|
elif isinstance(t, dict) and t.get("titleType", None) == "Subtitle":
|
547
|
-
|
548
|
-
elif isinstance(
|
549
|
-
|
550
|
-
|
551
|
+
titles["subtitle"] = t.get("title", None)
|
552
|
+
elif isinstance(t, dict):
|
553
|
+
titles["title"] = t.get("title", None)
|
554
|
+
|
555
|
+
return titles if titles else None
|
551
556
|
|
552
557
|
|
553
558
|
def get_contributors(obj) -> Optional[dict]:
|
@@ -1,8 +1,9 @@
|
|
1
1
|
"""InvenioRDM writer for commonmeta-py"""
|
2
2
|
|
3
|
+
import logging
|
3
4
|
import re
|
4
5
|
from time import time
|
5
|
-
from typing import Optional
|
6
|
+
from typing import Dict, Optional
|
6
7
|
from urllib.parse import urlparse
|
7
8
|
|
8
9
|
import orjson as json
|
@@ -15,6 +16,7 @@ from ..constants import (
|
|
15
16
|
COMMUNITY_TRANSLATIONS,
|
16
17
|
CROSSREF_FUNDER_ID_TO_ROR_TRANSLATIONS,
|
17
18
|
INVENIORDM_IDENTIFIER_TYPES,
|
19
|
+
Commonmeta,
|
18
20
|
)
|
19
21
|
from ..date_utils import get_iso8601_date
|
20
22
|
from ..doi_utils import doi_from_url, normalize_doi
|
@@ -28,6 +30,7 @@ from ..utils import (
|
|
28
30
|
validate_ror,
|
29
31
|
)
|
30
32
|
|
33
|
+
logger = logging.getLogger(__name__)
|
31
34
|
|
32
35
|
def write_inveniordm(metadata):
|
33
36
|
"""Write inveniordm"""
|
@@ -384,30 +387,35 @@ def write_inveniordm_list(metalist):
|
|
384
387
|
return [write_inveniordm(item) for item in metalist.items]
|
385
388
|
|
386
389
|
|
387
|
-
def push_inveniordm(
|
390
|
+
def push_inveniordm(
|
391
|
+
metadata: Commonmeta,
|
392
|
+
host: str,
|
393
|
+
token: str,
|
394
|
+
legacy_key: str
|
395
|
+
) -> Dict:
|
388
396
|
"""Push record to InvenioRDM"""
|
389
397
|
|
390
398
|
record = {}
|
391
|
-
|
399
|
+
output = write_inveniordm(metadata)
|
392
400
|
|
393
401
|
try:
|
394
402
|
# Remove IsPartOf relation with InvenioRDM community identifier after storing it
|
395
|
-
community_index = None
|
396
|
-
if hasattr(metadata, "relations") and metadata.relations:
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
403
|
+
# community_index = None
|
404
|
+
# if hasattr(metadata, "relations") and metadata.relations:
|
405
|
+
# for i, relation in enumerate(metadata.relations):
|
406
|
+
# if relation.get("type") == "IsPartOf" and relation.get(
|
407
|
+
# "id", ""
|
408
|
+
# ).startswith("https://rogue-scholar.org/api/communities/"):
|
409
|
+
# slug = relation.get("id").split("/")[5]
|
410
|
+
# community_id, _ = search_by_slug(slug, "blog", host, token)
|
411
|
+
# if community_id:
|
412
|
+
# record["community"] = slug
|
413
|
+
# record["community_id"] = community_id
|
414
|
+
# community_index = i
|
415
|
+
|
416
|
+
# # Remove the relation if we found and processed it
|
417
|
+
# if community_index is not None and hasattr(metadata, "relations"):
|
418
|
+
# metadata.relations.pop(community_index)
|
411
419
|
|
412
420
|
# Remove InvenioRDM rid after storing it
|
413
421
|
# rid_index = None
|
@@ -431,10 +439,10 @@ def push_inveniordm(metadata, host: str, token: str, legacy_key: str):
|
|
431
439
|
record = edit_published_record(record, host, token)
|
432
440
|
|
433
441
|
# Update draft record
|
434
|
-
record = update_draft_record(record, host, token,
|
442
|
+
record = update_draft_record(record, host, token, output)
|
435
443
|
else:
|
436
444
|
# Create draft record
|
437
|
-
record = create_draft_record(record, host, token,
|
445
|
+
record = create_draft_record(record, host, token, output)
|
438
446
|
|
439
447
|
# Publish draft record
|
440
448
|
record = publish_draft_record(record, host, token)
|
@@ -450,7 +458,8 @@ def push_inveniordm(metadata, host: str, token: str, legacy_key: str):
|
|
450
458
|
|
451
459
|
if hasattr(metadata, "subjects"):
|
452
460
|
for subject in metadata.subjects:
|
453
|
-
|
461
|
+
subject_name = subject.get("subject", "")
|
462
|
+
slug = string_to_slug(subject_name)
|
454
463
|
if slug in COMMUNITY_TRANSLATIONS:
|
455
464
|
slug = COMMUNITY_TRANSLATIONS[slug]
|
456
465
|
|
@@ -477,7 +486,11 @@ def push_inveniordm(metadata, host: str, token: str, legacy_key: str):
|
|
477
486
|
if host == "rogue-scholar.org" and legacy_key is not None:
|
478
487
|
record = update_legacy_record(record, legacy_key)
|
479
488
|
except Exception as e:
|
480
|
-
|
489
|
+
logger.error(f"Unexpected error in push_inveniordm: {str(e)}", exc_info=True, extra={
|
490
|
+
"host": host,
|
491
|
+
"record_id": record.get("id")
|
492
|
+
})
|
493
|
+
record["status"] = "error"
|
481
494
|
|
482
495
|
return record
|
483
496
|
|
@@ -504,15 +517,15 @@ def search_by_doi(doi, host, token) -> Optional[str]:
|
|
504
517
|
)
|
505
518
|
response.raise_for_status()
|
506
519
|
data = response.json()
|
507
|
-
if py_.get(data, "hits.total"
|
520
|
+
if py_.get(data, "hits.total", 0) > 0:
|
508
521
|
return py_.get(data, "hits.hits.0.id")
|
509
522
|
return None
|
510
523
|
except requests.exceptions.RequestException as e:
|
511
|
-
|
524
|
+
logger.error(f"Error searching for DOI {doi}: {str(e)}", exc_info=True)
|
512
525
|
return None
|
513
526
|
|
514
527
|
|
515
|
-
def create_draft_record(record, host, token,
|
528
|
+
def create_draft_record(record, host, token, output):
|
516
529
|
"""Create a new draft record in InvenioRDM"""
|
517
530
|
headers = {
|
518
531
|
"Authorization": f"Bearer {token}",
|
@@ -520,23 +533,23 @@ def create_draft_record(record, host, token, input):
|
|
520
533
|
}
|
521
534
|
try:
|
522
535
|
response = requests.post(
|
523
|
-
f"https://{host}/api/records", headers=headers, json=
|
536
|
+
f"https://{host}/api/records", headers=headers, json=output
|
524
537
|
)
|
525
538
|
if response.status_code == 429:
|
526
539
|
record["status"] = "failed_rate_limited"
|
527
540
|
return record
|
528
541
|
if response.status_code != 201:
|
529
|
-
|
542
|
+
logger.error(f"Failed to create draft record: {response.status_code} - {response.json()}")
|
530
543
|
record["status"] = "failed_create_draft"
|
531
544
|
return record
|
532
545
|
data = response.json()
|
533
|
-
record["id"]
|
546
|
+
record["id"] = data.get("id", None)
|
534
547
|
record["created"] = data.get("created", None)
|
535
548
|
record["updated"] = data.get("updated", None)
|
536
549
|
record["status"] = "draft"
|
537
550
|
return record
|
538
551
|
except requests.exceptions.RequestException as e:
|
539
|
-
|
552
|
+
logger.error(f"Error creating draft record: {str(e)}", exc_info=True)
|
540
553
|
record["status"] = "error_draft"
|
541
554
|
return record
|
542
555
|
|
@@ -557,7 +570,7 @@ def edit_published_record(record, host, token):
|
|
557
570
|
record["status"] = "edited"
|
558
571
|
return record
|
559
572
|
except requests.exceptions.RequestException as e:
|
560
|
-
|
573
|
+
logger.error(f"Error creating draft from published record: {str(e)}", exc_info=True)
|
561
574
|
record["status"] = "error_edit_published_record"
|
562
575
|
return record
|
563
576
|
|
@@ -581,7 +594,7 @@ def update_draft_record(record, host, token, inveniordm_data):
|
|
581
594
|
record["status"] = "updated"
|
582
595
|
return record
|
583
596
|
except requests.exceptions.RequestException as e:
|
584
|
-
|
597
|
+
logger.error(f"Error updating draft record: {str(e)}", exc_info=True)
|
585
598
|
record["status"] = "error_update_draft_record"
|
586
599
|
return record
|
587
600
|
|
@@ -604,8 +617,8 @@ def publish_draft_record(record, host, token):
|
|
604
617
|
record["status"] = "failed_rate_limited"
|
605
618
|
return record
|
606
619
|
if response.status_code != 202:
|
607
|
-
|
608
|
-
record["status"] = "
|
620
|
+
logger.error(f"Failed to publish draft record: {response.status_code} - {response.json()}")
|
621
|
+
record["status"] = "error_publish_draft_record"
|
609
622
|
return record
|
610
623
|
data = response.json()
|
611
624
|
record["uuid"] = py_.get(data, "metadata.identifiers.0.identifier")
|
@@ -614,7 +627,7 @@ def publish_draft_record(record, host, token):
|
|
614
627
|
record["status"] = "published"
|
615
628
|
return record
|
616
629
|
except requests.exceptions.RequestException as e:
|
617
|
-
|
630
|
+
logger.error(f"Error publishing draft record: {str(e)}", exc_info=True)
|
618
631
|
record["status"] = "error_publish_draft_record"
|
619
632
|
return record
|
620
633
|
|
@@ -634,7 +647,7 @@ def add_record_to_community(record, host, token, community_id):
|
|
634
647
|
response.raise_for_status()
|
635
648
|
return record
|
636
649
|
except requests.exceptions.RequestException as e:
|
637
|
-
|
650
|
+
logger.error(f"Error adding record to community: {str(e)}", exc_info=True)
|
638
651
|
return record
|
639
652
|
|
640
653
|
|
@@ -682,7 +695,7 @@ def update_legacy_record(record, legacy_key: str):
|
|
682
695
|
return record
|
683
696
|
|
684
697
|
except requests.exceptions.RequestException as e:
|
685
|
-
|
698
|
+
logger.error(f"Error updating legacy record: {str(e)}", exc_info=True)
|
686
699
|
record["status"] = "error_update_legacy_record"
|
687
700
|
return record
|
688
701
|
|
@@ -700,11 +713,11 @@ def search_by_slug(slug, type_value, host, token) -> Optional[str]:
|
|
700
713
|
)
|
701
714
|
response.raise_for_status()
|
702
715
|
data = response.json()
|
703
|
-
if py_.get(data, "hits.total"
|
716
|
+
if py_.get(data, "hits.total", 0) > 0:
|
704
717
|
return py_.get(data, "hits.hits.0.id")
|
705
718
|
return None
|
706
719
|
except requests.exceptions.RequestException as e:
|
707
|
-
|
720
|
+
logger.error(f"Error searching for community: {str(e)}", exc_info=True)
|
708
721
|
return None
|
709
722
|
|
710
723
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "commonmeta-py"
|
3
|
-
version = "0.
|
3
|
+
version = "0.119"
|
4
4
|
description = "Library for conversions to/from the Commonmeta scholarly metadata format"
|
5
5
|
authors = [{ name = "Martin Fenner", email = "martin@front-matter.io" }]
|
6
6
|
requires-python = ">=3.9,<4.0"
|
@@ -52,7 +52,7 @@ dependencies = [
|
|
52
52
|
"marshmallow-utils>=0.10.0",
|
53
53
|
"xmlschema>=4.0.1",
|
54
54
|
"requests-toolbelt>=1.0.0",
|
55
|
-
"setuptools>=70.3.0",
|
55
|
+
"setuptools>=70.3.0,<81",
|
56
56
|
]
|
57
57
|
|
58
58
|
[project.urls]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/AccessIndicators.xsd
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/clinicaltrials.xsd
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/doi_resources5.4.0.xsd
RENAMED
File without changes
|
{commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/fundingdata5.4.0.xsd
RENAMED
File without changes
|
File without changes
|
{commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/languages5.4.0.xsd
RENAMED
File without changes
|
{commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/mediatypes5.4.0.xsd
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/standard-modules/xlink.xsd
RENAMED
File without changes
|
{commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/crossref/standard-modules/xml.xsd
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/styles/chicago-author-date.csl
RENAMED
File without changes
|
{commonmeta_py-0.117 → commonmeta_py-0.119}/commonmeta/resources/styles/harvard-cite-them-right.csl
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|