commonmeta-py 0.17.2__py3-none-any.whl → 0.18__py3-none-any.whl

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.
@@ -108,6 +108,9 @@ def get_one_author(author, **kwargs):
108
108
  else:
109
109
  given_name = None
110
110
  family_name = None
111
+
112
+ # support various keys for affiliations
113
+ affiliations = author.get("affiliation", None) or author.get("affiliations", None)
111
114
 
112
115
  # return author in commonmeta format, using name vs. given/family name
113
116
  # depending on type
@@ -119,7 +122,7 @@ def get_one_author(author, **kwargs):
119
122
  "name": name if _type == "Organization" else None,
120
123
  "givenName": given_name if _type == "Person" else None,
121
124
  "familyName": family_name if _type == "Person" else None,
122
- "affiliation": presence(get_affiliations(wrap(author.get("affiliation", None)))
125
+ "affiliations": presence(get_affiliations(wrap(affiliations))
123
126
  ),
124
127
  }
125
128
  )
@@ -131,8 +131,12 @@ def insert_crossref_contributors(metadata, xml):
131
131
  ]
132
132
  for num, contributor in enumerate(con):
133
133
  contributor_role = (
134
- "author" if contributor.get("contributorRoles") == ["Author"] else "editor"
134
+ "author" if "Author" in contributor.get("contributorRoles") else None
135
135
  )
136
+ if contributor_role is None:
137
+ contributor_role = (
138
+ "editor" if "Editor" in contributor.get("contributorRoles") else None
139
+ )
136
140
  sequence = "first" if num == 0 else "additional"
137
141
  if (
138
142
  contributor.get("type", None) == "Organization"
@@ -153,7 +157,7 @@ def insert_crossref_contributors(metadata, xml):
153
157
  {"contributor_role": contributor_role, "sequence": sequence},
154
158
  )
155
159
  person_name = insert_crossref_person(contributor, person_name)
156
- elif contributor.get("affiliation", None) is not None:
160
+ elif contributor.get("affiliations", None) is not None:
157
161
  anonymous = etree.SubElement(
158
162
  contributors,
159
163
  "anonymous",
@@ -176,18 +180,17 @@ def insert_crossref_person(contributor, xml):
176
180
  if contributor.get("familyName", None) is not None:
177
181
  etree.SubElement(xml, "surname").text = contributor.get("familyName")
178
182
 
179
- if contributor.get("affiliation", None) is not None:
183
+ if contributor.get("affiliations", None) is not None:
180
184
  affiliations = etree.SubElement(xml, "affiliations")
181
185
  institution = etree.SubElement(affiliations, "institution")
182
- if py_.get(contributor, "affiliation.0.name") is not None:
186
+ if py_.get(contributor, "affiliations.0.name") is not None:
183
187
  etree.SubElement(institution, "institution_name").text = py_.get(
184
- contributor, "affiliation.0.name"
188
+ contributor, "affiliations.0.name"
185
189
  )
186
- if py_.get(contributor, "affiliation.0.id") is not None:
190
+ if py_.get(contributor, "affiliations.0.id") is not None:
187
191
  etree.SubElement(
188
192
  institution, "institution_id", {"type": "ror"}
189
- ).text = py_.get(contributor, "affiliation.0.id")
190
-
193
+ ).text = py_.get(contributor, "affiliations.0.id")
191
194
  orcid = normalize_orcid(contributor.get("id", None))
192
195
  if orcid is not None:
193
196
  etree.SubElement(xml, "ORCID").text = orcid
@@ -196,13 +199,13 @@ def insert_crossref_person(contributor, xml):
196
199
 
197
200
  def insert_crossref_anonymous(contributor, xml):
198
201
  """Insert crossref anonymous"""
199
- if contributor.get("affiliation", None) is None:
202
+ if contributor.get("affiliations", None) is None:
200
203
  return xml
201
204
  affiliations = etree.SubElement(xml, "affiliations")
202
205
  institution = etree.SubElement(affiliations, "institution")
203
- if py_.get(contributor, "affiliation.0.name") is not None:
206
+ if py_.get(contributor, "affiliations.0.name") is not None:
204
207
  etree.SubElement(institution, "institution_name").text = py_.get(
205
- contributor, "affiliation.0.name"
208
+ contributor, "affiliations.0.name"
206
209
  )
207
210
  return xml
208
211
 
@@ -225,6 +228,8 @@ def insert_citation_list(metadata, xml):
225
228
 
226
229
  citation_list = etree.SubElement(xml, "citation_list")
227
230
  for ref in metadata.references:
231
+ if ref.get("id", None) is None:
232
+ continue
228
233
  citation = etree.SubElement(
229
234
  citation_list, "citation", {"key": ref.get("key", None)}
230
235
  )
@@ -242,10 +247,10 @@ def insert_citation_list(metadata, xml):
242
247
  etree.SubElement(citation, "cYear").text = ref.get("publicationYear")
243
248
  if ref.get("title", None) is not None:
244
249
  etree.SubElement(citation, "article_title").text = ref.get("title")
245
- if ref.get("doi", None) is not None:
246
- etree.SubElement(citation, "doi").text = doi_from_url(ref.get("doi"))
247
- if ref.get("url", None) is not None:
248
- etree.SubElement(citation, "unstructured_citation").text = ref.get("url")
250
+ if ref.get("id", None) is not None:
251
+ etree.SubElement(citation, "doi").text = doi_from_url(ref.get("id"))
252
+ if ref.get("unstructured", None) is not None:
253
+ etree.SubElement(citation, "unstructured_citation").text = ref.get("unstructured")
249
254
  return xml
250
255
 
251
256
 
@@ -95,7 +95,7 @@ def read_crossref(data: Optional[dict], **kwargs) -> Commonmeta:
95
95
  identifiers.append(
96
96
  compact(
97
97
  {
98
- "identifier": normalize_doi(_id),
98
+ "identifier": _id,
99
99
  "identifierType": "DOI",
100
100
  }
101
101
  )
@@ -144,11 +144,11 @@ def read_crossref(data: Optional[dict], **kwargs) -> Commonmeta:
144
144
  "type": _type,
145
145
  # recommended and optional properties
146
146
  "additionalType": None,
147
- "archiveLocations": archive_locations,
147
+ "archiveLocations": presence(archive_locations),
148
148
  "container": presence(container),
149
149
  "contributors": presence(contributors),
150
150
  "date": presence(date),
151
- "descriptions": descriptions,
151
+ "descriptions": presence(descriptions),
152
152
  "files": presence(files),
153
153
  "fundingReferences": presence(funding_references),
154
154
  "geoLocations": None,
@@ -392,15 +392,12 @@ def crossref_reference(reference: Optional[dict]) -> Optional[dict]:
392
392
  doi = parse_attributes(reference.get("doi", None))
393
393
  unstructured = reference.get("unstructured_citation", None)
394
394
  if isinstance(unstructured, dict):
395
- url = unstructured.get("u", None)
396
395
  text = unstructured.get("font", None) or unstructured.get("#text", None)
397
396
  else:
398
- url = reference.get("url", None)
399
397
  text = reference.get("unstructured_citation", None)
400
398
  metadata = {
401
399
  "key": reference.get("key", None),
402
- "doi": normalize_doi(doi) if doi else None,
403
- "url": normalize_url(url) if url else None,
400
+ "id": normalize_doi(doi) if doi else None,
404
401
  "contributor": reference.get("author", None),
405
402
  "title": reference.get("article_title", None),
406
403
  "publisher": reference.get("publisher", None),
@@ -411,7 +408,7 @@ def crossref_reference(reference: Optional[dict]) -> Optional[dict]:
411
408
  "lastPage": reference.get("last_page", None),
412
409
  "containerTitle": reference.get("journal_title", None),
413
410
  "edition": None,
414
- "unstructured": sanitize(text) if text and doi is None else None,
411
+ "unstructured": sanitize(text) if text else None,
415
412
  }
416
413
  return compact(metadata)
417
414
 
@@ -70,7 +70,7 @@ def read_csl(data: dict, **kwargs) -> Commonmeta:
70
70
  descriptions = [
71
71
  {
72
72
  "description": sanitize(str(meta.get("abstract"))),
73
- "descriptionType": "Abstract",
73
+ "type": "Abstract",
74
74
  }
75
75
  ]
76
76
  else:
@@ -113,28 +113,26 @@ def read_datacite(data: dict, **kwargs) -> Commonmeta:
113
113
  # required properties
114
114
  "id": _id,
115
115
  "type": _type,
116
- "doi": doi_from_url(_id),
117
- "url": normalize_url(meta.get("url", None)),
118
- "contributors": presence(contributors),
119
- "titles": titles,
120
- "publisher": publisher,
121
- "date": compact(date),
122
116
  # recommended and optional properties
123
117
  "additionalType": additional_type,
124
- "subjects": presence(subjects),
125
- "language": meta.get("language", None),
118
+ "container": presence(container),
119
+ "contributors": presence(contributors),
120
+ "date": compact(date),
121
+ "descriptions": presence(descriptions),
122
+ "files": presence(files),
123
+ "fundingReferences": presence(meta.get("fundingReferences", None)),
124
+ "geoLocations": presence(geo_locations),
126
125
  "identifiers": presence(identifiers),
127
- "version": meta.get("version", None),
126
+ "language": meta.get("language", None),
128
127
  "license": presence(license_),
129
- "descriptions": descriptions,
130
- "geoLocations": presence(geo_locations),
131
- "fundingReferences": presence(meta.get("fundingReferences", None)),
128
+ "provider": "DataCite",
129
+ "publisher": publisher,
132
130
  "references": presence(references),
133
131
  "relations": presence(relations),
134
- # other properties
135
- "files": presence(files),
136
- "container": presence(container),
137
- "provider": "DataCite",
132
+ "subjects": presence(subjects),
133
+ "titles": presence(titles),
134
+ "url": normalize_url(meta.get("url", None)),
135
+ "version": meta.get("version", None),
138
136
  } | read_options
139
137
 
140
138
 
@@ -93,7 +93,7 @@ def read_datacite_xml(data: dict, **kwargs) -> Commonmeta:
93
93
  {
94
94
  "subject": subject.get("#text", None),
95
95
  "subjectScheme": subject.get("subjectScheme", None),
96
- "lang": subject.get("xml:lang", None),
96
+ "language": subject.get("xml:lang", None),
97
97
  }
98
98
  )
99
99
  return None
@@ -127,9 +127,9 @@ def get_references(references: list) -> list:
127
127
  identifier = reference.get("relatedIdentifier", None)
128
128
  identifier_type = reference.get("relatedIdentifierType", None)
129
129
  if identifier and identifier_type == "DOI":
130
- reference["doi"] = normalize_doi(identifier)
130
+ reference["id"] = normalize_doi(identifier)
131
131
  elif identifier and identifier_type == "URL":
132
- reference["url"] = normalize_url(identifier)
132
+ reference["id"] = normalize_url(identifier)
133
133
  reference = py_.omit(
134
134
  reference,
135
135
  [
@@ -102,7 +102,7 @@ def read_json_feed_item(data: Optional[dict], **kwargs) -> Commonmeta:
102
102
  description = meta.get("summary", None)
103
103
  if description is not None:
104
104
  descriptions = [
105
- {"description": sanitize(description), "descriptionType": "Abstract"}
105
+ {"description": sanitize(description), "type": "Abstract"}
106
106
  ]
107
107
  else:
108
108
  descriptions = None
@@ -165,13 +165,12 @@ def get_references(references: list) -> list:
165
165
  return None
166
166
  try:
167
167
  if reference.get("doi", None) and validate_doi(reference.get("doi")):
168
- doi = normalize_doi(reference.get("doi"))
168
+ id_ = normalize_doi(reference.get("doi"))
169
169
  return compact(
170
170
  {
171
- "doi": doi,
171
+ "id": id_,
172
172
  "title": reference.get("title", None),
173
173
  "publicationYear": reference.get("publicationYear", None),
174
- "url": reference.get("url", None),
175
174
  }
176
175
  )
177
176
 
@@ -185,7 +184,7 @@ def get_references(references: list) -> list:
185
184
  if response.status_code in [404]:
186
185
  return None
187
186
  return {
188
- "url": reference.get("url"),
187
+ "id": reference.get("url"),
189
188
  }
190
189
  except Exception as error:
191
190
  print(error)
@@ -12,8 +12,7 @@
12
12
  "properties": {
13
13
  "organization": { "$ref": "#/definitions/organization" }
14
14
  }
15
- },
16
- "uniqueItems": true
15
+ }
17
16
  },
18
17
  "contributorRole": {
19
18
  "description": "The type of contribution made by a contributor",
@@ -63,13 +62,21 @@
63
62
  ],
64
63
  "type": "string"
65
64
  },
65
+ "geoLocationBox": {
66
+ "type": "object",
67
+ "properties": {
68
+ "westBoundLongitude": { "$ref": "#/definitions/longitude" },
69
+ "eastBoundLongitude": { "$ref": "#/definitions/longitude" },
70
+ "southBoundLatitude": { "$ref": "#/definitions/latitude" },
71
+ "northBoundLatitude": { "$ref": "#/definitions/latitude" }
72
+ }
73
+ },
66
74
  "geoLocationPoint": {
67
75
  "type": "object",
68
76
  "properties": {
69
77
  "pointLongitude": { "$ref": "#/definitions/longitude" },
70
78
  "pointLatitude": { "$ref": "#/definitions/latitude" }
71
- },
72
- "required": ["pointLongitude", "pointLatitude"]
79
+ }
73
80
  },
74
81
  "id": {
75
82
  "description": "The unique identifier for the resource.",
@@ -137,9 +144,11 @@
137
144
  "Dissertation",
138
145
  "Document",
139
146
  "Entry",
147
+ "Event",
140
148
  "Grant",
141
149
  "Image",
142
150
  "Instrument",
151
+ "InteractiveResource",
143
152
  "JournalArticle",
144
153
  "JournalIssue",
145
154
  "JournalVolume",
@@ -182,8 +191,7 @@
182
191
  "Internet Archive",
183
192
  "DWT"
184
193
  ]
185
- },
186
- "uniqueItems": true
194
+ }
187
195
  },
188
196
  "container": {
189
197
  "description": "The container of the resource.",
@@ -247,14 +255,11 @@
247
255
  "items": {
248
256
  "$ref": "#/definitions/contributorRole"
249
257
  },
250
- "type": "array",
251
- "minItems": 1,
252
- "uniqueItems": true
258
+ "type": "array"
253
259
  }
254
260
  }
255
261
  },
256
- "minItems": 1,
257
- "uniqueItems": true
262
+ "minItems": 1
258
263
  },
259
264
  "date": {
260
265
  "description": "The dates for the resource.",
@@ -333,8 +338,7 @@
333
338
  },
334
339
  "required": ["url"]
335
340
  },
336
- "minItems": 1,
337
- "uniqueItems": true
341
+ "minItems": 1
338
342
  },
339
343
  "fundingReferences": {
340
344
  "description": "The funding references for the resource.",
@@ -368,21 +372,7 @@
368
372
  "properties": {
369
373
  "geoLocationPlace": { "type": "string" },
370
374
  "geoLocationPoint": { "$ref": "#/definitions/geoLocationPoint" },
371
- "geoLocationBox": {
372
- "type": "object",
373
- "properties": {
374
- "westBoundLongitude": { "$ref": "#/definitions/longitude" },
375
- "eastBoundLongitude": { "$ref": "#/definitions/longitude" },
376
- "southBoundLatitude": { "$ref": "#/definitions/latitude" },
377
- "northBoundLatitude": { "$ref": "#/definitions/latitude" }
378
- },
379
- "required": [
380
- "westBoundLongitude",
381
- "eastBoundLongitude",
382
- "southBoundLatitude",
383
- "northBoundLatitude"
384
- ]
385
- },
375
+ "geoLocationBox": { "$ref": "#/definitions/geoLocationBox" },
386
376
  "geoLocationPolygons": {
387
377
  "type": "array",
388
378
  "items": {
@@ -493,8 +483,7 @@
493
483
  },
494
484
  "required": ["id", "type"]
495
485
  },
496
- "minItems": 1,
497
- "uniqueItems": true
486
+ "minItems": 1
498
487
  },
499
488
  "references": {
500
489
  "type": "array",
@@ -517,8 +506,7 @@
517
506
  "unstructured": { "type": "string" }
518
507
  },
519
508
  "required": ["key"]
520
- },
521
- "uniqueItems": true
509
+ }
522
510
  },
523
511
  "subjects": {
524
512
  "type": "array",
@@ -532,8 +520,7 @@
532
520
  }
533
521
  },
534
522
  "required": ["subject"]
535
- },
536
- "uniqueItems": true
523
+ }
537
524
  },
538
525
  "titles": {
539
526
  "description": "The titles of the resource.",
@@ -556,8 +543,7 @@
556
543
  }
557
544
  },
558
545
  "required": ["title"]
559
- },
560
- "uniqueItems": true
546
+ }
561
547
  },
562
548
  "url": {
563
549
  "description": "The URL of the resource.",
@@ -0,0 +1,573 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://commonmeta.org/commonmeta_v0.14.json",
4
+ "title": "Commonmeta v0.14",
5
+ "description": "JSON representation of the Commonmeta schema.",
6
+ "commonmeta": {
7
+ "anyOf": [
8
+ { "$ref": "#/definitions/commonmeta"
9
+ },
10
+ {
11
+ "type": "array",
12
+ "description": "An array of commonmeta objects.",
13
+ "items": { "$ref": "#/definitions/commonmeta" }
14
+ }
15
+ ]
16
+ },
17
+ "definitions": {
18
+ "affiliations": {
19
+ "type": "array",
20
+ "items": {
21
+ "type": "object",
22
+ "properties": {
23
+ "organization": { "$ref": "#/definitions/organization" }
24
+ }
25
+ }
26
+ },
27
+ "commonmeta": {
28
+ "description": "A commonmeta object.",
29
+ "type": "object",
30
+ "additionalProperties": false,
31
+ "properties": {
32
+ "id": { "$ref": "#/definitions/id" },
33
+ "type": { "$ref": "#/definitions/type" },
34
+ "additionalType": {
35
+ "description": "The additional type of the resource.",
36
+ "type": "string"
37
+ },
38
+ "archiveLocations": {
39
+ "description": "The location where content is archived.",
40
+ "type": "array",
41
+ "items": {
42
+ "type": "string",
43
+ "enum": [
44
+ "CLOCKSS",
45
+ "LOCKSS",
46
+ "Portico",
47
+ "KB",
48
+ "Internet Archive",
49
+ "DWT"
50
+ ]
51
+ }
52
+ },
53
+ "container": {
54
+ "description": "The container of the resource.",
55
+ "type": "object",
56
+ "properties": {
57
+ "identifier": {
58
+ "description": "The identifier for the container.",
59
+ "type": "string"
60
+ },
61
+ "identifierType": {
62
+ "description": "The identifierType for the container.",
63
+ "type": "string"
64
+ },
65
+ "type": {
66
+ "description": "The type of the container.",
67
+ "type": "string",
68
+ "enum": [
69
+ "Book",
70
+ "BookSeries",
71
+ "Journal",
72
+ "Proceedings",
73
+ "ProceedingsSeries",
74
+ "Repository",
75
+ "DataRepository",
76
+ "Periodical",
77
+ "Series"
78
+ ]
79
+ },
80
+ "title": {
81
+ "description": "The title of the container.",
82
+ "type": "string"
83
+ },
84
+ "firstPage": {
85
+ "description": "The first page of the resource.",
86
+ "type": "string"
87
+ },
88
+ "lastPage": {
89
+ "description": "The last page of the resource.",
90
+ "type": "string"
91
+ },
92
+ "volume": {
93
+ "description": "The volume of the resource.",
94
+ "type": "string"
95
+ },
96
+ "issue": {
97
+ "description": "The issue of the resource.",
98
+ "type": "string"
99
+ }
100
+ }
101
+ },
102
+ "contributors": {
103
+ "description": "The contributors to the resource.",
104
+ "type": "array",
105
+ "items": {
106
+ "type": "object",
107
+ "properties": {
108
+ "organization": { "$ref": "#/definitions/organization" },
109
+ "person": { "$ref": "#/definitions/person" },
110
+ "contributorRoles": {
111
+ "description": "List of roles assumed by the contributor when working on the resource.",
112
+ "items": {
113
+ "$ref": "#/definitions/contributorRole"
114
+ },
115
+ "type": "array"
116
+ }
117
+ }
118
+ },
119
+ "minItems": 1
120
+ },
121
+ "date": {
122
+ "description": "The dates for the resource.",
123
+ "$comment": "The date fields are not required. Dates should be formatted as ISO 8601 dates.",
124
+ "type": "object",
125
+ "properties": {
126
+ "created": {
127
+ "description": "The date the resource was created.",
128
+ "type": "string"
129
+ },
130
+ "submitted": {
131
+ "description": "The date the resource was submitted.",
132
+ "type": "string"
133
+ },
134
+ "accepted": {
135
+ "description": "The date the resource was accepted.",
136
+ "type": "string"
137
+ },
138
+ "published": {
139
+ "description": "The date the resource was published.",
140
+ "type": "string"
141
+ },
142
+ "updated": {
143
+ "description": "The date the resource was updated.",
144
+ "type": "string"
145
+ },
146
+ "accessed": {
147
+ "description": "The date the resource was accessed.",
148
+ "type": "string"
149
+ },
150
+ "available": {
151
+ "description": "The date the resource was made available.",
152
+ "type": "string"
153
+ },
154
+ "withdrawn": {
155
+ "description": "The date the resource was withdrawn.",
156
+ "type": "string"
157
+ }
158
+ }
159
+ },
160
+ "descriptions": {
161
+ "description": "The descriptions of the resource.",
162
+ "type": "array",
163
+ "items": {
164
+ "type": "object",
165
+ "properties": {
166
+ "description": {
167
+ "description": "The description of the resource.",
168
+ "type": "string"
169
+ },
170
+ "type": {
171
+ "description": "The type of the description.",
172
+ "type": "string",
173
+ "enum": ["Abstract", "Summary", "Methods", "TechnicalInfo", "Other"]
174
+ },
175
+ "language": {
176
+ "description": "The language of the title. Use one of the language codes from the IETF BCP 47 standard.",
177
+ "type": "string"
178
+ }
179
+ },
180
+ "required": ["description"]
181
+ }
182
+ },
183
+ "files": {
184
+ "description": "The downloadable files for the resource.",
185
+ "type": "array",
186
+ "items": {
187
+ "type": "object",
188
+ "properties": {
189
+ "bucket": { "type": "string" },
190
+ "key": { "type": "string" },
191
+ "checksum": { "type": "string" },
192
+ "url": { "type": "string", "format": "uri" },
193
+ "size": { "type": "integer" },
194
+ "mimeType": { "type": "string" }
195
+ },
196
+ "required": ["url"]
197
+ },
198
+ "minItems": 1
199
+ },
200
+ "fundingReferences": {
201
+ "description": "The funding references for the resource.",
202
+ "type": "array",
203
+ "items": {
204
+ "type": "object",
205
+ "properties": {
206
+ "funderIdentifier": { "type": "string" },
207
+ "funderIdentifierType": {
208
+ "type": "string",
209
+ "enum": [
210
+ "Crossref Funder ID",
211
+ "ROR",
212
+ "GRID",
213
+ "ISNI",
214
+ "Ringgold",
215
+ "Other"
216
+ ]
217
+ },
218
+ "funderName": { "type": "string" },
219
+ "awardNumber": { "type": "string" },
220
+ "awardUri": { "type": "string", "format": "uri" }
221
+ },
222
+ "required": ["funderName"]
223
+ }
224
+ },
225
+ "geoLocations": {
226
+ "type": "array",
227
+ "items": {
228
+ "type": "object",
229
+ "properties": {
230
+ "geoLocationPlace": { "type": "string" },
231
+ "geoLocationPoint": { "$ref": "#/definitions/geoLocationPoint" },
232
+ "geoLocationBox": { "$ref": "#/definitions/geoLocationBox" },
233
+ "geoLocationPolygons": {
234
+ "type": "array",
235
+ "items": {
236
+ "type": "object",
237
+ "properties": {
238
+ "polygonPoints": {
239
+ "type": "array",
240
+ "items": { "$ref": "#/definitions/geoLocationPoint" },
241
+ "minItems": 4
242
+ },
243
+ "inPolygonPoint": { "$ref": "#/definitions/geoLocationPoint" }
244
+ },
245
+ "required": ["polygonPoints"]
246
+ },
247
+ "uniqueItems": true
248
+ }
249
+ }
250
+ },
251
+ "uniqueItems": true
252
+ },
253
+ "identifiers": {
254
+ "description": "Identifiers for the resource, including the id.",
255
+ "type": "array",
256
+ "items": {
257
+ "type": "object",
258
+ "properties": {
259
+ "identifier": { "type": "string" },
260
+ "identifierType": {
261
+ "type": "string",
262
+ "enum": [
263
+ "ARK",
264
+ "arXiv",
265
+ "Bibcode",
266
+ "DOI",
267
+ "Handle",
268
+ "ISBN",
269
+ "ISSN",
270
+ "PMID",
271
+ "PMCID",
272
+ "PURL",
273
+ "URL",
274
+ "URN",
275
+ "UUID",
276
+ "Other"
277
+ ]
278
+ }
279
+ },
280
+ "required": ["identifier", "identifierType"]
281
+ }
282
+ },
283
+ "language": {
284
+ "description": "The language of the resource. Use one of the language codes from the IETF BCP 47 standard.",
285
+ "type": "string"
286
+ },
287
+ "license": {
288
+ "description": "The license for the resource. Use one of the SPDX license identifiers.",
289
+ "type": "object",
290
+ "properties": {
291
+ "id": { "type": "string" },
292
+ "url": { "type": "string", "format": "uri" }
293
+ }
294
+ },
295
+ "provider": {
296
+ "description": "The provider of the resource. This can be a DOI registration agency or a repository.",
297
+ "type": "string",
298
+ "enum": ["Crossref", "DataCite", "GitHub", "JaLC", "KISTI", "mEDRA", "OP"]
299
+ },
300
+ "publisher": {
301
+ "description": "The publisher of the resource.",
302
+ "type": "object",
303
+ "properties": {
304
+ "organization": { "$ref": "#/definitions/organization" }
305
+ }
306
+ },
307
+ "relations": {
308
+ "description": "Other resolvable persistent unique IDs related to the resource.",
309
+ "type": "array",
310
+ "items": {
311
+ "type": "object",
312
+ "properties": {
313
+ "id": {
314
+ "type": "string",
315
+ "format": "uri"
316
+ },
317
+ "type": {
318
+ "type": "string",
319
+ "enum": [
320
+ "IsNewVersionOf",
321
+ "IsPreviousVersionOf",
322
+ "IsVersionOf",
323
+ "HasVersion",
324
+ "IsPartOf",
325
+ "HasPart",
326
+ "IsVariantFormOf",
327
+ "IsOriginalFormOf",
328
+ "IsIdenticalTo",
329
+ "IsTranslationOf",
330
+ "HasTranslation",
331
+ "IsReviewedBy",
332
+ "Reviews",
333
+ "HasReview",
334
+ "IsPreprintOf",
335
+ "HasPreprint",
336
+ "IsSupplementTo",
337
+ "IsSupplementedBy"
338
+ ]
339
+ }
340
+ },
341
+ "required": ["id", "type"]
342
+ },
343
+ "minItems": 1
344
+ },
345
+ "references": {
346
+ "type": "array",
347
+ "items": {
348
+ "type": "object",
349
+ "properties": {
350
+ "id": { "$ref": "#/definitions/id" },
351
+ "type": { "$ref": "#/definitions/type" },
352
+ "key": { "type": "string" },
353
+ "contributor": { "type": "string" },
354
+ "title": { "type": "string" },
355
+ "publisher": { "type": "string" },
356
+ "publicationYear": { "type": "string" },
357
+ "volume": { "type": "string" },
358
+ "issue": { "type": "string" },
359
+ "firstPage": { "type": "string" },
360
+ "lastPage": { "type": "string" },
361
+ "containerTitle": { "type": "string" },
362
+ "edition": { "type": "string" },
363
+ "unstructured": { "type": "string" }
364
+ },
365
+ "required": ["key"]
366
+ }
367
+ },
368
+ "subjects": {
369
+ "type": "array",
370
+ "items": {
371
+ "type": "object",
372
+ "properties": {
373
+ "subject": { "type": "string" },
374
+ "language": {
375
+ "description": "The language of the subject. Use one of the language codes from the IETF BCP 47 standard.",
376
+ "type": "string"
377
+ }
378
+ },
379
+ "required": ["subject"]
380
+ }
381
+ },
382
+ "titles": {
383
+ "description": "The titles of the resource.",
384
+ "type": "array",
385
+ "items": {
386
+ "type": "object",
387
+ "properties": {
388
+ "title": {
389
+ "description": "The title of the resource.",
390
+ "type": "string"
391
+ },
392
+ "type": {
393
+ "description": "The type of the title.",
394
+ "type": "string",
395
+ "enum": ["AlternativeTitle", "Subtitle", "TranslatedTitle"]
396
+ },
397
+ "language": {
398
+ "description": "The language of the title. Use one of the language codes from the IETF BCP 47 standard.",
399
+ "type": "string"
400
+ }
401
+ },
402
+ "required": ["title"]
403
+ }
404
+ },
405
+ "url": {
406
+ "description": "The URL of the resource.",
407
+ "type": "string",
408
+ "format": "uri"
409
+ },
410
+ "version": {
411
+ "description": "The version of the resource.",
412
+ "type": "string"
413
+ }
414
+ },
415
+ "required": ["id", "type"]
416
+ },
417
+ "contributorRole": {
418
+ "description": "The type of contribution made by a contributor",
419
+ "enum": [
420
+ "Author",
421
+ "Editor",
422
+ "Chair",
423
+ "Reviewer",
424
+ "ReviewAssistant",
425
+ "StatsReviewer",
426
+ "ReviewerExternal",
427
+ "Reader",
428
+ "Translator",
429
+ "ContactPerson",
430
+ "DataCollector",
431
+ "DataManager",
432
+ "Distributor",
433
+ "HostingInstitution",
434
+ "Producer",
435
+ "ProjectLeader",
436
+ "ProjectManager",
437
+ "ProjectMember",
438
+ "RegistrationAgency",
439
+ "RegistrationAuthority",
440
+ "RelatedPerson",
441
+ "ResearchGroup",
442
+ "RightsHolder",
443
+ "Researcher",
444
+ "Sponsor",
445
+ "WorkPackageLeader",
446
+ "Conceptualization",
447
+ "DataCuration",
448
+ "FormalAnalysis",
449
+ "FundingAcquisition",
450
+ "Investigation",
451
+ "Methodology",
452
+ "ProjectAdministration",
453
+ "Resources",
454
+ "Software",
455
+ "Supervision",
456
+ "Validation",
457
+ "Visualization",
458
+ "WritingOriginalDraft",
459
+ "WritingReviewEditing",
460
+ "Maintainer",
461
+ "Other"
462
+ ],
463
+ "type": "string"
464
+ },
465
+ "geoLocationBox": {
466
+ "type": "object",
467
+ "properties": {
468
+ "westBoundLongitude": { "$ref": "#/definitions/longitude" },
469
+ "eastBoundLongitude": { "$ref": "#/definitions/longitude" },
470
+ "southBoundLatitude": { "$ref": "#/definitions/latitude" },
471
+ "northBoundLatitude": { "$ref": "#/definitions/latitude" }
472
+ }
473
+ },
474
+ "geoLocationPoint": {
475
+ "type": "object",
476
+ "properties": {
477
+ "pointLongitude": { "$ref": "#/definitions/longitude" },
478
+ "pointLatitude": { "$ref": "#/definitions/latitude" }
479
+ }
480
+ },
481
+ "id": {
482
+ "description": "The unique identifier for the resource.",
483
+ "type": "string",
484
+ "format": "uri"
485
+ },
486
+ "latitude": {
487
+ "type": "number",
488
+ "minimum": -90,
489
+ "maximum": 90
490
+ },
491
+ "longitude": {
492
+ "type": "number",
493
+ "minimum": -180,
494
+ "maximum": 180
495
+ },
496
+ "organization": {
497
+ "type": "object",
498
+ "properties": {
499
+ "id": {
500
+ "description": "The unique identifier for the organization.",
501
+ "type": "string",
502
+ "format": "uri"
503
+ },
504
+ "type": { "type": "string", "const": "Organization" },
505
+ "name": {
506
+ "description": "The name of the organization.",
507
+ "type": "string"
508
+ }
509
+ },
510
+ "required": ["name", "type"]
511
+ },
512
+ "person": {
513
+ "type": "object",
514
+ "properties": {
515
+ "id": { "type": "string", "format": "uri" },
516
+ "type": { "type": "string", "const": "Person" },
517
+ "givenName": {
518
+ "description": "The given name of the person.",
519
+ "type": "string"
520
+ },
521
+ "familyName": {
522
+ "description": "The family name of the person.",
523
+ "type": "string"
524
+ },
525
+ "affiliation": { "$ref": "#/definitions/affiliations" }
526
+ },
527
+ "required": ["familyName", "type"]
528
+ },
529
+ "type": {
530
+ "type": "string",
531
+ "enum": [
532
+ "Article",
533
+ "Audiovisual",
534
+ "BookChapter",
535
+ "BookPart",
536
+ "BookSection",
537
+ "BookSeries",
538
+ "BookSet",
539
+ "Book",
540
+ "Collection",
541
+ "Component",
542
+ "Database",
543
+ "Dataset",
544
+ "Dissertation",
545
+ "Document",
546
+ "Entry",
547
+ "Event",
548
+ "Grant",
549
+ "Image",
550
+ "Instrument",
551
+ "InteractiveResource",
552
+ "JournalArticle",
553
+ "JournalIssue",
554
+ "JournalVolume",
555
+ "Journal",
556
+ "PeerReview",
557
+ "PhysicalObject",
558
+ "Presentation",
559
+ "ProceedingsArticle",
560
+ "ProceedingsSeries",
561
+ "Proceedings",
562
+ "ReportComponent",
563
+ "ReportSeries",
564
+ "Report",
565
+ "Software",
566
+ "Standard",
567
+ "StudyRegistration",
568
+ "WebPage",
569
+ "Other"
570
+ ]
571
+ }
572
+ }
573
+ }
@@ -7,7 +7,7 @@ from jsonschema import Draft202012Validator, ValidationError
7
7
  def json_schema_errors(instance, schema: str = "commonmeta"):
8
8
  """validate against JSON schema"""
9
9
  schema_map = {
10
- "commonmeta": "commonmeta_v0.13",
10
+ "commonmeta": "commonmeta_v0.14",
11
11
  "datacite": "datacite-v4.5",
12
12
  "crossref": "crossref-v0.2",
13
13
  "csl": "csl-data",
@@ -160,7 +160,7 @@ def to_datacite_creator(creator: dict) -> dict:
160
160
  "familyName": creator.get("familyName", None),
161
161
  "nameType": _type + "al" if _type else None,
162
162
  "nameIdentifiers": name_identifiers,
163
- "affiliation": creator.get("affiliation", None),
163
+ "affiliation": creator.get("affiliations", None),
164
164
  }
165
165
  )
166
166
 
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2022-2023 Front Matter
3
+ Copyright (c) 2022-2024 Front Matter
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: commonmeta-py
3
- Version: 0.17.2
3
+ Version: 0.18
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
@@ -1,10 +1,10 @@
1
1
  commonmeta/__init__.py,sha256=GEUiZwiQG_SxD0Fwl1CRMGOtq2Sfek1mSqMVJLgEhh8,1781
2
2
  commonmeta/api_utils.py,sha256=-ZHGVZZhJqnjnsLtp4-PoeHYbDqL0cQme7W70BEjo4U,2677
3
- commonmeta/author_utils.py,sha256=sABlti_yy-noT6RwCdRy4DklKaQDKpFvq0rivzcLgJQ,8217
3
+ commonmeta/author_utils.py,sha256=04iA1K2dMp-8xu0cH10tcWgWKIKW3aajYkxrYLzG2l4,8333
4
4
  commonmeta/base_utils.py,sha256=0t6fr9XGeeTBoMlKSAMI7p_EmKsA6wYRW0roEBXVcc8,3722
5
5
  commonmeta/cli.py,sha256=0IJF1SQ1sKPg7M0Gb8fpX2nBps-G0L13o01__M6c5Z0,6104
6
6
  commonmeta/constants.py,sha256=9MPQosZUqnScIbdzG2S8vpE7OXqsFDk6PVnw-1hdXxI,15598
7
- commonmeta/crossref_utils.py,sha256=XzbkITA5Yq1XSlCBr1x_T8q5QqBn0fZOIkgsjqmoOVY,21723
7
+ commonmeta/crossref_utils.py,sha256=hBodNdeHi1HilfTjazz9gDkN7FQiCZxA_qgzSBO4uA4,21972
8
8
  commonmeta/date_utils.py,sha256=amF3E0ZJlh8yY5eY3aVXQyAO1x2WuZHJXw-ajOEcdUQ,5808
9
9
  commonmeta/doi_utils.py,sha256=zzqoGZf0H3DYUUM9_zioNSnXOvcxzfLpPie7rpXD2es,7797
10
10
  commonmeta/metadata.py,sha256=wKVOL-M3nDBIat5NMjuxr_HvnSPvc1hZ83se7uumBgU,12259
@@ -13,19 +13,20 @@ commonmeta/readers/bibtex_reader.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
13
13
  commonmeta/readers/cff_reader.py,sha256=5HMFUvjE1zb-zfpQSNM8vtB0YunD0reom99hn8N0xKc,6144
14
14
  commonmeta/readers/codemeta_reader.py,sha256=efv2V1WPfdrKLQNxgSvoripdWqS2M6CwXWSGiRuzRtU,3658
15
15
  commonmeta/readers/commonmeta_reader.py,sha256=gNjdsJ-671-pXmBdzy1NybkQ29q9_qtorFoK2D-zStA,302
16
- commonmeta/readers/crossref_reader.py,sha256=bB-_pIkVm0ub9we9U-j1z-V6jqm9Y7KK1YVBKzK8VQU,12322
17
- commonmeta/readers/crossref_xml_reader.py,sha256=ytMAozgLBmvS6fDJ0xv5dTp8rXgBLjrRXwT7HfClA_c,18771
18
- commonmeta/readers/csl_reader.py,sha256=WndJ__wa-JKuHZCT6XVha3iuW2IsDYzp7xz5dgntRa8,3179
19
- commonmeta/readers/datacite_reader.py,sha256=pjixmWvFJhLU-KlWOuFr-Eg923VEbw9klm32gJDUUgg,12108
20
- commonmeta/readers/datacite_xml_reader.py,sha256=NGdmVAsiMUIARFaQv2RTVR8A1Y5V-SW4JmVi_PQe2ZI,13122
21
- commonmeta/readers/inveniordm_reader.py,sha256=aotm77ZlSGXQiw3J1K8S96DtjFPgdZJENEwWa2C2OBo,6297
22
- commonmeta/readers/json_feed_reader.py,sha256=Azu0NHVGsd7i-HfKN84Ew2lgkQ2xo8VIZXDHZ-MuyQw,13847
16
+ commonmeta/readers/crossref_reader.py,sha256=ySzzyhrWQ4Xd2uFpoZ7NP1KpHXSoqY_VYJdJ-WlPs6E,12327
17
+ commonmeta/readers/crossref_xml_reader.py,sha256=QF1A-r3OJbykBTH9YMSxusT3-KSKmmz7d6Ch8S0OM0I,18619
18
+ commonmeta/readers/csl_reader.py,sha256=bq0uGpUUbYcZ-4XaY1RBGYacLRpxeL2vvEFpLCqUFDg,3168
19
+ commonmeta/readers/datacite_reader.py,sha256=Mud4IKFjDUg3wHXoyLLo39yGe31HCOsCLxRZ-vdyJQE,12067
20
+ commonmeta/readers/datacite_xml_reader.py,sha256=I5tr0ekN-fa_8_t9Xq09w8Jhi-ODnOgA-ZBl5WguTMQ,13126
21
+ commonmeta/readers/inveniordm_reader.py,sha256=sAmJ9zTHPp1iCdcTQJh-VkNo0MKbubJA3Tx8XIKrdmY,6295
22
+ commonmeta/readers/json_feed_reader.py,sha256=ZEmMphAOAQDYhbHwpZVuS65SivyNylkSBNpscsL6F0c,13775
23
23
  commonmeta/readers/kbase_reader.py,sha256=NpIK-_fh5QFN4Q_ArqcrnH4tS5zR1gqbPew6VEjrUbs,6764
24
24
  commonmeta/readers/ris_reader.py,sha256=v6qOd-i2OcMTEFy5RGd3MlYthJcYSU6yzmZ5yHDzmII,3677
25
25
  commonmeta/readers/schema_org_reader.py,sha256=_iUwZDzOGkiU4oeYB1wFWt3r_Er_ibyCCfELa4_4HU4,16624
26
26
  commonmeta/resources/cff_v1.2.0.json,sha256=MpfjDYgX7fN9PLiG54ISZ2uu9WItNqfh-yaRuTf6Ptg,46691
27
27
  commonmeta/resources/commonmeta_v0.12.json,sha256=HUSNReXh2JN3Q6YWSt7CE69js8dh50OlpMYGTyU98oU,16762
28
- commonmeta/resources/commonmeta_v0.13.json,sha256=3o9tzgxUfM3DqMHc78z_cDe3gnK2HkypxhHsKCW_WzI,16236
28
+ commonmeta/resources/commonmeta_v0.13.json,sha256=2-WSZGijR13zVu97S_YHXr-cyeLW7hzHXYMlr6nIjdw,15787
29
+ commonmeta/resources/commonmeta_v0.14.json,sha256=nACmkTe4IrZkygd5AeJnAv9P4EWfzCwW9oL5AhubvnE,17657
29
30
  commonmeta/resources/crossref/AccessIndicators.xsd,sha256=en-G2FFt4ewIFRw5C6g4YA8Nc0M66fCM2CygiO_ZqqY,2825
30
31
  commonmeta/resources/crossref/JATS-journalpublishing1-3d2-mathml3-elements.xsd,sha256=l5jJMFm4xx09bavH2Gc3EqIdr-0PTf6M9YBTNpUaZhY,415409
31
32
  commonmeta/resources/crossref/JATS-journalpublishing1-3d2-mathml3.xsd,sha256=goO2ckm12fF2-kGFZC_FaTBdi4BK3YCRwb_ESur8dfY,2210
@@ -53,7 +54,7 @@ commonmeta/resources/styles/harvard-cite-them-right.csl,sha256=XmLVFDrfsgkECYaAb
53
54
  commonmeta/resources/styles/ieee.csl,sha256=DfuN__z8FZ5Rcdaj_Myc5y_FmB-fHwfRVTeS9-hOgmQ,15854
54
55
  commonmeta/resources/styles/modern-language-association.csl,sha256=HI2iU4krze1aHYc9VSQCUyw_2I6fEQYnA9xIWo-xNus,11594
55
56
  commonmeta/resources/styles/vancouver.csl,sha256=lun3_i2oTilgsANk4LjFao2UDPQlGj_hgFgKAWC_DF8,12878
56
- commonmeta/schema_utils.py,sha256=OnzVqIw-Jt1yd6i4QUtBtk0u1zyVDjxQH4oVFOWz4jc,915
57
+ commonmeta/schema_utils.py,sha256=Ep8suJgqtgDAvbjVkQxwzAY1MqwwqPwNRKDTMAxMQTg,915
57
58
  commonmeta/translators.py,sha256=RpGJtKNLjmz41VREZDY7KyyE2eXOi8j7m-da4jHmknI,1362
58
59
  commonmeta/utils.py,sha256=ZIJaE8zkUo0xvCmSr1BzQll0SFI64jEIBC8WUoTkZ3Y,38502
59
60
  commonmeta/writers/__init__.py,sha256=47-snms6xBHkoEXKYV1DBtH1npAtlVtvY29Z4Zr45qI,45
@@ -62,11 +63,11 @@ commonmeta/writers/citation_writer.py,sha256=RjaNh9EALxq6gfODLRWVJxGxPArGd6ZiHUl
62
63
  commonmeta/writers/commonmeta_writer.py,sha256=2qlttCfYpGhfVjrYkjzbIra7AywssRLT30FlxEWgXGw,1844
63
64
  commonmeta/writers/crossref_xml_writer.py,sha256=0Ds494RnXfdfjWw5CLX1kwV2zP7gqffdVqO-X74Uc6c,492
64
65
  commonmeta/writers/csl_writer.py,sha256=ep1U2oc8c0h9tXtVXu05o92ZR4_2pk0dEFa2iBiW7Jk,2807
65
- commonmeta/writers/datacite_writer.py,sha256=M9L5k_ARMVkjX3JM8QORG2Vgt6QEYqcEe6dqcSFWkX4,6190
66
+ commonmeta/writers/datacite_writer.py,sha256=dVlP2GOd6z5NhVfEJuAv1GyQzMPqjjurWSV1YkchfS4,6191
66
67
  commonmeta/writers/ris_writer.py,sha256=AcnCszS3WY9lF594NbFBtLylsA8ownnYp_XLQJ84Ios,2093
67
68
  commonmeta/writers/schema_org_writer.py,sha256=72cpjBpvaLkTph6I0xkjqI6ne4fKSihHKOsht4_CdmY,5698
68
- commonmeta_py-0.17.2.dist-info/LICENSE,sha256=lv-z2BuPoDWRiA17Q4K1QsG2F6EPGBD36iEVjOnmHt4,1074
69
- commonmeta_py-0.17.2.dist-info/METADATA,sha256=tFLRQYBDc1McuU23TrISqMBnKixlICcJWasE1lqIocs,8333
70
- commonmeta_py-0.17.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
71
- commonmeta_py-0.17.2.dist-info/entry_points.txt,sha256=vbcDw3_2lMTKdcAL2VUF4DRYRpKuzXVYLMCdgKVf88U,49
72
- commonmeta_py-0.17.2.dist-info/RECORD,,
69
+ commonmeta_py-0.18.dist-info/LICENSE,sha256=746hEF2wZCKkcckk5-_DcBLtHewfaEMS4iXTlA1PVwk,1074
70
+ commonmeta_py-0.18.dist-info/METADATA,sha256=iG-k7EOuiX9prNF1jAdYnFJp3JTXN5BFlTIpwA9kQzo,8331
71
+ commonmeta_py-0.18.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
72
+ commonmeta_py-0.18.dist-info/entry_points.txt,sha256=vbcDw3_2lMTKdcAL2VUF4DRYRpKuzXVYLMCdgKVf88U,49
73
+ commonmeta_py-0.18.dist-info/RECORD,,