invenio-vocabularies 3.4.2__py2.py3-none-any.whl → 4.1.1__py2.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.
Potentially problematic release.
This version of invenio-vocabularies might be problematic. Click here for more details.
- invenio_vocabularies/__init__.py +1 -1
- invenio_vocabularies/administration/__init__.py +10 -0
- invenio_vocabularies/administration/views/__init__.py +10 -0
- invenio_vocabularies/administration/views/vocabularies.py +44 -0
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/CustomAwardForm.js +8 -20
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/FundingField.js +2 -2
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/FundingModal.js +5 -7
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/NoAwardResults.js +3 -3
- invenio_vocabularies/cli.py +10 -39
- invenio_vocabularies/config.py +33 -3
- invenio_vocabularies/contrib/affiliations/config.py +2 -2
- invenio_vocabularies/contrib/affiliations/datastreams.py +67 -0
- invenio_vocabularies/contrib/affiliations/jsonschemas/affiliations/affiliation-v1.0.0.json +38 -1
- invenio_vocabularies/contrib/affiliations/mappings/os-v1/affiliations/affiliation-v1.0.0.json +21 -0
- invenio_vocabularies/contrib/affiliations/mappings/os-v2/affiliations/affiliation-v1.0.0.json +21 -0
- invenio_vocabularies/contrib/affiliations/mappings/v7/affiliations/affiliation-v1.0.0.json +21 -0
- invenio_vocabularies/contrib/affiliations/schema.py +17 -3
- invenio_vocabularies/contrib/awards/datastreams.py +90 -3
- invenio_vocabularies/contrib/awards/jsonschemas/awards/award-v1.0.0.json +3 -0
- invenio_vocabularies/contrib/awards/mappings/os-v1/awards/award-v1.0.0.json +3 -0
- invenio_vocabularies/contrib/awards/mappings/os-v2/awards/award-v1.0.0.json +3 -0
- invenio_vocabularies/contrib/awards/mappings/v7/awards/award-v1.0.0.json +3 -0
- invenio_vocabularies/contrib/common/__init__.py +9 -0
- invenio_vocabularies/contrib/common/ror/__init__.py +9 -0
- invenio_vocabularies/contrib/common/ror/datastreams.py +166 -0
- invenio_vocabularies/contrib/funders/config.py +2 -0
- invenio_vocabularies/contrib/funders/datastreams.py +10 -59
- invenio_vocabularies/contrib/funders/jsonschemas/funders/funder-v1.0.0.json +36 -1
- invenio_vocabularies/contrib/funders/mappings/os-v1/funders/funder-v1.0.0.json +21 -0
- invenio_vocabularies/contrib/funders/mappings/os-v2/funders/funder-v1.0.0.json +21 -0
- invenio_vocabularies/contrib/funders/mappings/v7/funders/funder-v1.0.0.json +21 -0
- invenio_vocabularies/contrib/funders/schema.py +8 -0
- invenio_vocabularies/contrib/funders/serializer.py +2 -1
- invenio_vocabularies/contrib/names/jsonschemas/names/name-v1.0.0.json +3 -0
- invenio_vocabularies/contrib/names/mappings/os-v1/names/name-v1.0.0.json +3 -0
- invenio_vocabularies/contrib/names/mappings/os-v2/names/name-v1.0.0.json +3 -0
- invenio_vocabularies/contrib/names/mappings/v7/names/name-v1.0.0.json +3 -0
- invenio_vocabularies/contrib/subjects/jsonschemas/subjects/subject-v1.0.0.json +3 -0
- invenio_vocabularies/contrib/subjects/mappings/os-v1/subjects/subject-v1.0.0.json +3 -0
- invenio_vocabularies/contrib/subjects/mappings/os-v2/subjects/subject-v1.0.0.json +3 -0
- invenio_vocabularies/contrib/subjects/mappings/v7/subjects/subject-v1.0.0.json +3 -0
- invenio_vocabularies/datastreams/factories.py +1 -2
- invenio_vocabularies/datastreams/readers.py +96 -3
- invenio_vocabularies/datastreams/writers.py +2 -2
- invenio_vocabularies/ext.py +22 -7
- invenio_vocabularies/factories.py +93 -0
- invenio_vocabularies/proxies.py +2 -2
- invenio_vocabularies/records/jsonschemas/vocabularies/definitions-v1.0.0.json +7 -0
- invenio_vocabularies/records/jsonschemas/vocabularies/vocabulary-v1.0.0.json +1 -4
- invenio_vocabularies/resources/__init__.py +8 -1
- invenio_vocabularies/resources/config.py +105 -0
- invenio_vocabularies/resources/resource.py +31 -41
- invenio_vocabularies/services/__init__.py +5 -2
- invenio_vocabularies/services/config.py +179 -0
- invenio_vocabularies/services/permissions.py +3 -1
- invenio_vocabularies/services/results.py +110 -0
- invenio_vocabularies/services/schema.py +1 -1
- invenio_vocabularies/services/service.py +41 -86
- invenio_vocabularies/services/tasks.py +31 -1
- invenio_vocabularies/templates/semantic-ui/invenio_vocabularies/vocabularies-list.html +12 -0
- invenio_vocabularies/templates/semantic-ui/invenio_vocabularies/vocabulary-details.html +71 -0
- invenio_vocabularies/views.py +7 -0
- {invenio_vocabularies-3.4.2.dist-info → invenio_vocabularies-4.1.1.dist-info}/METADATA +32 -7
- {invenio_vocabularies-3.4.2.dist-info → invenio_vocabularies-4.1.1.dist-info}/RECORD +69 -56
- {invenio_vocabularies-3.4.2.dist-info → invenio_vocabularies-4.1.1.dist-info}/entry_points.txt +7 -0
- {invenio_vocabularies-3.4.2.dist-info → invenio_vocabularies-4.1.1.dist-info}/AUTHORS.rst +0 -0
- {invenio_vocabularies-3.4.2.dist-info → invenio_vocabularies-4.1.1.dist-info}/LICENSE +0 -0
- {invenio_vocabularies-3.4.2.dist-info → invenio_vocabularies-4.1.1.dist-info}/WHEEL +0 -0
- {invenio_vocabularies-3.4.2.dist-info → invenio_vocabularies-4.1.1.dist-info}/top_level.txt +0 -0
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
"$schema": {
|
|
9
9
|
"$ref": "local://definitions-v1.0.0.json#/$schema"
|
|
10
10
|
},
|
|
11
|
+
"tags": {
|
|
12
|
+
"$ref": "local://vocabularies/definitions-v1.0.0.json#/tags"
|
|
13
|
+
},
|
|
11
14
|
"scheme": {
|
|
12
15
|
"description": "Identifier of the name scheme.",
|
|
13
16
|
"$ref": "local://definitions-v1.0.0.json#/identifier"
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
"$schema": {
|
|
9
9
|
"$ref": "local://definitions-v1.0.0.json#/$schema"
|
|
10
10
|
},
|
|
11
|
+
"tags": {
|
|
12
|
+
"$ref": "local://vocabularies/definitions-v1.0.0.json#/tags"
|
|
13
|
+
},
|
|
11
14
|
"id": {
|
|
12
15
|
"description": "URI or classification code as identifier - globally unique among all subject schemes.",
|
|
13
16
|
"$ref": "local://definitions-v1.0.0.json#/identifier"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
#
|
|
3
|
-
# Copyright (C) 2021-
|
|
3
|
+
# Copyright (C) 2021-2024 CERN.
|
|
4
4
|
#
|
|
5
5
|
# Invenio-Vocabularies is free software; you can redistribute it and/or
|
|
6
6
|
# modify it under the terms of the MIT License; see LICENSE file for more
|
|
@@ -36,7 +36,6 @@ class Factory:
|
|
|
36
36
|
try:
|
|
37
37
|
type_ = config["type"]
|
|
38
38
|
args = config.get("args", {})
|
|
39
|
-
|
|
40
39
|
return cls.options()[type_](**args)
|
|
41
40
|
except KeyError:
|
|
42
41
|
raise FactoryError(name=cls.FACTORY_NAME, key=type_)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
#
|
|
3
3
|
# Copyright (C) 2021-2024 CERN.
|
|
4
|
+
# Copyright (C) 2024 University of Münster.
|
|
4
5
|
#
|
|
5
6
|
# Invenio-Vocabularies is free software; you can redistribute it and/or
|
|
6
7
|
# modify it under the terms of the MIT License; see LICENSE file for more
|
|
@@ -15,16 +16,21 @@ import re
|
|
|
15
16
|
import tarfile
|
|
16
17
|
import zipfile
|
|
17
18
|
from abc import ABC, abstractmethod
|
|
18
|
-
from collections import defaultdict
|
|
19
19
|
from json.decoder import JSONDecodeError
|
|
20
20
|
|
|
21
21
|
import requests
|
|
22
22
|
import yaml
|
|
23
|
+
from lxml import etree
|
|
23
24
|
from lxml.html import parse as html_parse
|
|
24
25
|
|
|
25
26
|
from .errors import ReaderError
|
|
26
27
|
from .xml import etree_to_dict
|
|
27
28
|
|
|
29
|
+
try:
|
|
30
|
+
import oaipmh_scythe
|
|
31
|
+
except ImportError:
|
|
32
|
+
oaipmh_scythe = None
|
|
33
|
+
|
|
28
34
|
|
|
29
35
|
class BaseReader(ABC):
|
|
30
36
|
"""Base reader."""
|
|
@@ -80,7 +86,12 @@ class TarReader(BaseReader):
|
|
|
80
86
|
def read(self, item=None, *args, **kwargs):
|
|
81
87
|
"""Opens a tar archive or uses the given file pointer."""
|
|
82
88
|
if item:
|
|
83
|
-
|
|
89
|
+
if isinstance(item, tarfile.TarFile):
|
|
90
|
+
yield from self._iter(fp=item, *args, **kwargs)
|
|
91
|
+
else:
|
|
92
|
+
# If the item is not already a TarFile (e.g. if it is a BytesIO), try to create a TarFile from the item.
|
|
93
|
+
with tarfile.open(mode=self._mode, fileobj=item) as archive:
|
|
94
|
+
yield from self._iter(fp=archive, *args, **kwargs)
|
|
84
95
|
else:
|
|
85
96
|
with tarfile.open(self._origin, self._mode) as archive:
|
|
86
97
|
yield from self._iter(fp=archive, *args, **kwargs)
|
|
@@ -136,7 +147,12 @@ class ZipReader(BaseReader):
|
|
|
136
147
|
"""Opens a Zip archive or uses the given file pointer."""
|
|
137
148
|
# https://docs.python.org/3/library/zipfile.html
|
|
138
149
|
if item:
|
|
139
|
-
|
|
150
|
+
if isinstance(item, zipfile.ZipFile):
|
|
151
|
+
yield from self._iter(fp=item, *args, **kwargs)
|
|
152
|
+
else:
|
|
153
|
+
# If the item is not already a ZipFile (e.g. if it is a BytesIO), try to create a ZipFile from the item.
|
|
154
|
+
with zipfile.ZipFile(item, **self._options) as archive:
|
|
155
|
+
yield from self._iter(fp=archive, *args, **kwargs)
|
|
140
156
|
else:
|
|
141
157
|
with zipfile.ZipFile(self._origin, **self._options) as archive:
|
|
142
158
|
yield from self._iter(fp=archive, *args, **kwargs)
|
|
@@ -217,3 +233,80 @@ class XMLReader(BaseReader):
|
|
|
217
233
|
raise ReaderError(f"Record not found in XML entry.")
|
|
218
234
|
|
|
219
235
|
yield record
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
class OAIPMHReader(BaseReader):
|
|
239
|
+
"""OAIPMH reader."""
|
|
240
|
+
|
|
241
|
+
def __init__(
|
|
242
|
+
self,
|
|
243
|
+
*args,
|
|
244
|
+
base_url=None,
|
|
245
|
+
metadata_prefix=None,
|
|
246
|
+
set=None,
|
|
247
|
+
from_date=None,
|
|
248
|
+
until_date=None,
|
|
249
|
+
verb=None,
|
|
250
|
+
**kwargs,
|
|
251
|
+
):
|
|
252
|
+
"""Constructor."""
|
|
253
|
+
self._base_url = base_url
|
|
254
|
+
self._metadata_prefix = metadata_prefix if not None else "oai_dc"
|
|
255
|
+
self._set = set
|
|
256
|
+
self._until = until_date
|
|
257
|
+
self._from = from_date
|
|
258
|
+
self._verb = verb if not None else "ListRecords"
|
|
259
|
+
super().__init__(*args, **kwargs)
|
|
260
|
+
|
|
261
|
+
def _iter(self, scythe, *args, **kwargs):
|
|
262
|
+
"""Read and parse an OAIPMH stream to dict."""
|
|
263
|
+
|
|
264
|
+
class OAIRecord(oaipmh_scythe.models.Record):
|
|
265
|
+
"""An XML unpacking implementation for more complicated formats."""
|
|
266
|
+
|
|
267
|
+
def get_metadata(self):
|
|
268
|
+
"""Extract and return the record's metadata as a dictionary."""
|
|
269
|
+
return xml_to_dict(
|
|
270
|
+
self.xml.find(f".//{self._oai_namespace}metadata").getchildren()[0],
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
scythe.class_mapping["ListRecords"] = OAIRecord
|
|
274
|
+
try:
|
|
275
|
+
records = scythe.list_records(
|
|
276
|
+
from_=self._from,
|
|
277
|
+
until=self._until,
|
|
278
|
+
metadata_prefix=self._metadata_prefix,
|
|
279
|
+
set_=self._set,
|
|
280
|
+
ignore_deleted=True,
|
|
281
|
+
)
|
|
282
|
+
for record in records:
|
|
283
|
+
yield {"record": record}
|
|
284
|
+
except oaipmh_scythe.NoRecordsMatch:
|
|
285
|
+
raise ReaderError(f"No records found in OAI-PMH request.")
|
|
286
|
+
|
|
287
|
+
def read(self, item=None, *args, **kwargs):
|
|
288
|
+
"""Reads from item or opens the file descriptor from origin."""
|
|
289
|
+
if item:
|
|
290
|
+
raise NotImplementedError(
|
|
291
|
+
"OAIPMHReader does not support being chained after another reader"
|
|
292
|
+
)
|
|
293
|
+
else:
|
|
294
|
+
with oaipmh_scythe.Scythe(self._base_url) as scythe:
|
|
295
|
+
yield from self._iter(scythe=scythe, *args, **kwargs)
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def xml_to_dict(tree: etree._Element):
|
|
299
|
+
"""Convert an XML tree to a dictionary.
|
|
300
|
+
|
|
301
|
+
This function takes an XML element tree and converts it into a dictionary.
|
|
302
|
+
|
|
303
|
+
Args:
|
|
304
|
+
tree: The root element of the XML tree to be converted.
|
|
305
|
+
|
|
306
|
+
Returns:
|
|
307
|
+
A dictionary with the key "record".
|
|
308
|
+
"""
|
|
309
|
+
dict_obj = dict()
|
|
310
|
+
dict_obj["record"] = etree.tostring(tree)
|
|
311
|
+
|
|
312
|
+
return dict_obj
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
#
|
|
3
|
-
# Copyright (C) 2021-
|
|
3
|
+
# Copyright (C) 2021-2024 CERN.
|
|
4
4
|
#
|
|
5
5
|
# Invenio-Vocabularies is free software; you can redistribute it and/or
|
|
6
6
|
# modify it under the terms of the MIT License; see LICENSE file for more
|
|
@@ -103,6 +103,6 @@ class YamlWriter(BaseWriter):
|
|
|
103
103
|
with open(self._filepath, "a") as file:
|
|
104
104
|
# made into array for safer append
|
|
105
105
|
# will always read array (good for reader)
|
|
106
|
-
yaml.safe_dump([stream_entry.entry], file)
|
|
106
|
+
yaml.safe_dump([stream_entry.entry], file, allow_unicode=True)
|
|
107
107
|
|
|
108
108
|
return stream_entry
|
invenio_vocabularies/ext.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
#
|
|
3
|
-
# Copyright (C) 2020-
|
|
3
|
+
# Copyright (C) 2020-2024 CERN.
|
|
4
4
|
# Copyright (C) 2023 Graz University of Technology.
|
|
5
5
|
#
|
|
6
6
|
# Invenio-Vocabularies is free software; you can redistribute it and/or
|
|
@@ -40,8 +40,14 @@ from .contrib.subjects import (
|
|
|
40
40
|
SubjectsService,
|
|
41
41
|
SubjectsServiceConfig,
|
|
42
42
|
)
|
|
43
|
-
from .resources
|
|
44
|
-
|
|
43
|
+
from .resources import (
|
|
44
|
+
VocabulariesAdminResource,
|
|
45
|
+
VocabulariesResource,
|
|
46
|
+
VocabulariesResourceConfig,
|
|
47
|
+
VocabularyTypeResourceConfig,
|
|
48
|
+
)
|
|
49
|
+
from .services.config import VocabularyTypesServiceConfig
|
|
50
|
+
from .services.service import VocabulariesService, VocabularyTypeService
|
|
45
51
|
|
|
46
52
|
|
|
47
53
|
class InvenioVocabularies(object):
|
|
@@ -76,6 +82,7 @@ class InvenioVocabularies(object):
|
|
|
76
82
|
funders = FundersServiceConfig
|
|
77
83
|
names = NamesServiceConfig
|
|
78
84
|
subjects = SubjectsServiceConfig
|
|
85
|
+
vocabulary_types = VocabularyTypesServiceConfig
|
|
79
86
|
|
|
80
87
|
return ServiceConfigs
|
|
81
88
|
|
|
@@ -93,9 +100,12 @@ class InvenioVocabularies(object):
|
|
|
93
100
|
self.funders_service = FundersService(config=service_configs.funders)
|
|
94
101
|
self.names_service = NamesService(config=service_configs.names)
|
|
95
102
|
self.subjects_service = SubjectsService(config=service_configs.subjects)
|
|
96
|
-
self.
|
|
103
|
+
self.vocabularies_service = VocabulariesService(
|
|
97
104
|
config=app.config["VOCABULARIES_SERVICE_CONFIG"],
|
|
98
105
|
)
|
|
106
|
+
self.vocabulary_types_service = VocabularyTypeService(
|
|
107
|
+
config=service_configs.vocabulary_types
|
|
108
|
+
)
|
|
99
109
|
|
|
100
110
|
def init_resource(self, app):
|
|
101
111
|
"""Initialize vocabulary resources."""
|
|
@@ -121,9 +131,13 @@ class InvenioVocabularies(object):
|
|
|
121
131
|
config=SubjectsResourceConfig,
|
|
122
132
|
)
|
|
123
133
|
self.resource = VocabulariesResource(
|
|
124
|
-
service=self.
|
|
134
|
+
service=self.vocabularies_service,
|
|
125
135
|
config=app.config["VOCABULARIES_RESOURCE_CONFIG"],
|
|
126
136
|
)
|
|
137
|
+
self.vocabulary_admin_resource = VocabulariesAdminResource(
|
|
138
|
+
service=self.vocabulary_types_service,
|
|
139
|
+
config=VocabularyTypeResourceConfig,
|
|
140
|
+
)
|
|
127
141
|
|
|
128
142
|
|
|
129
143
|
def finalize_app(app):
|
|
@@ -153,7 +167,8 @@ def init(app):
|
|
|
153
167
|
sregistry.register(ext.funders_service, service_id="funders")
|
|
154
168
|
sregistry.register(ext.names_service, service_id="names")
|
|
155
169
|
sregistry.register(ext.subjects_service, service_id="subjects")
|
|
156
|
-
sregistry.register(ext.
|
|
170
|
+
sregistry.register(ext.vocabularies_service, service_id="vocabularies")
|
|
171
|
+
sregistry.register(ext.vocabulary_types_service, service_id="vocabulary-types")
|
|
157
172
|
# Register indexers
|
|
158
173
|
iregistry = app.extensions["invenio-indexer"].registry
|
|
159
174
|
iregistry.register(ext.affiliations_service.indexer, indexer_id="affiliations")
|
|
@@ -161,4 +176,4 @@ def init(app):
|
|
|
161
176
|
iregistry.register(ext.funders_service.indexer, indexer_id="funders")
|
|
162
177
|
iregistry.register(ext.names_service.indexer, indexer_id="names")
|
|
163
178
|
iregistry.register(ext.subjects_service.indexer, indexer_id="subjects")
|
|
164
|
-
iregistry.register(ext.
|
|
179
|
+
iregistry.register(ext.vocabularies_service.indexer, indexer_id="vocabularies")
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2024 CERN.
|
|
4
|
+
# Copyright (C) 2024 KTH Royal Institute of Technology.
|
|
5
|
+
#
|
|
6
|
+
# Invenio-Vocabularies is free software; you can redistribute it and/or
|
|
7
|
+
# modify it under the terms of the MIT License; see LICENSE file for more
|
|
8
|
+
# details.
|
|
9
|
+
"""Generate Vocabulary Config."""
|
|
10
|
+
from copy import deepcopy
|
|
11
|
+
|
|
12
|
+
import yaml
|
|
13
|
+
from invenio_records_resources.proxies import current_service_registry
|
|
14
|
+
|
|
15
|
+
from .contrib.affiliations.datastreams import (
|
|
16
|
+
DATASTREAM_CONFIG as affiliations_ds_config,
|
|
17
|
+
)
|
|
18
|
+
from .contrib.awards.datastreams import DATASTREAM_CONFIG as awards_ds_config
|
|
19
|
+
from .contrib.funders.datastreams import DATASTREAM_CONFIG as funders_ds_config
|
|
20
|
+
from .contrib.names.datastreams import DATASTREAM_CONFIG as names_ds_config
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class VocabularyConfig:
|
|
24
|
+
"""Vocabulary Config Factory."""
|
|
25
|
+
|
|
26
|
+
config = None
|
|
27
|
+
vocabulary_name = None
|
|
28
|
+
|
|
29
|
+
def get_config(self, filepath=None, origin=None):
|
|
30
|
+
"""Get the configuration for the vocabulary."""
|
|
31
|
+
config = deepcopy(self.config)
|
|
32
|
+
if filepath:
|
|
33
|
+
with open(filepath, encoding="utf-8") as f:
|
|
34
|
+
config = yaml.safe_load(f).get(self.vocabulary_name)
|
|
35
|
+
if origin:
|
|
36
|
+
config["readers"][0].setdefault("args", {})
|
|
37
|
+
config["readers"][0]["args"]["origin"] = origin
|
|
38
|
+
return config
|
|
39
|
+
|
|
40
|
+
def get_service(self):
|
|
41
|
+
"""Get the service for the vocabulary."""
|
|
42
|
+
return current_service_registry.get(self.vocabulary_name)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class NamesVocabularyConfig(VocabularyConfig):
|
|
46
|
+
"""Names Vocabulary Config."""
|
|
47
|
+
|
|
48
|
+
config = names_ds_config
|
|
49
|
+
vocabulary_name = "names"
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class FundersVocabularyConfig(VocabularyConfig):
|
|
53
|
+
"""Funders Vocabulary Config."""
|
|
54
|
+
|
|
55
|
+
config = funders_ds_config
|
|
56
|
+
vocabulary_name = "funders"
|
|
57
|
+
|
|
58
|
+
def get_service(self):
|
|
59
|
+
"""Get the service for the vocabulary."""
|
|
60
|
+
raise NotImplementedError("Service not implemented for Funders")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class AwardsVocabularyConfig(VocabularyConfig):
|
|
64
|
+
"""Awards Vocabulary Config."""
|
|
65
|
+
|
|
66
|
+
config = awards_ds_config
|
|
67
|
+
vocabulary_name = "awards"
|
|
68
|
+
|
|
69
|
+
def get_service(self):
|
|
70
|
+
"""Get the service for the vocabulary."""
|
|
71
|
+
raise NotImplementedError("Service not implemented for Awards")
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class AffiliationsVocabularyConfig(VocabularyConfig):
|
|
75
|
+
"""Affiliations Vocabulary Config."""
|
|
76
|
+
|
|
77
|
+
config = affiliations_ds_config
|
|
78
|
+
vocabulary_name = "affiliations"
|
|
79
|
+
|
|
80
|
+
def get_service(self):
|
|
81
|
+
"""Get the service for the vocabulary."""
|
|
82
|
+
raise NotImplementedError("Service not implemented for Affiliations")
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def get_vocabulary_config(vocabulary):
|
|
86
|
+
"""Factory function to get the appropriate Vocabulary Config."""
|
|
87
|
+
vocab_config = {
|
|
88
|
+
"names": NamesVocabularyConfig,
|
|
89
|
+
"funders": FundersVocabularyConfig,
|
|
90
|
+
"awards": AwardsVocabularyConfig,
|
|
91
|
+
"affiliations": AffiliationsVocabularyConfig,
|
|
92
|
+
}
|
|
93
|
+
return vocab_config.get(vocabulary, VocabularyConfig)()
|
invenio_vocabularies/proxies.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
#
|
|
3
|
-
# Copyright (C) 2021 CERN.
|
|
3
|
+
# Copyright (C) 2021-2024 CERN.
|
|
4
4
|
# Copyright (C) 2021 Northwestern University.
|
|
5
5
|
#
|
|
6
6
|
# Invenio-Vocabularies is free software; you can redistribute it and/or
|
|
@@ -19,7 +19,7 @@ def _ext_proxy(attr):
|
|
|
19
19
|
)
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
current_service = _ext_proxy("
|
|
22
|
+
current_service = _ext_proxy("vocabularies_service")
|
|
23
23
|
"""Proxy to the instantiated vocabulary service."""
|
|
24
24
|
|
|
25
25
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
#
|
|
3
|
-
# Copyright (C) 2020-
|
|
3
|
+
# Copyright (C) 2020-2024 CERN.
|
|
4
4
|
#
|
|
5
5
|
# Invenio-Vocabularies is free software; you can redistribute it and/or
|
|
6
6
|
# modify it under the terms of the MIT License; see LICENSE file for more
|
|
@@ -9,7 +9,14 @@
|
|
|
9
9
|
"""Resources module."""
|
|
10
10
|
from invenio_vocabularies.resources.schema import L10NString, VocabularyL10Schema
|
|
11
11
|
|
|
12
|
+
from .config import VocabulariesResourceConfig, VocabularyTypeResourceConfig
|
|
13
|
+
from .resource import VocabulariesAdminResource, VocabulariesResource
|
|
14
|
+
|
|
12
15
|
__all__ = (
|
|
13
16
|
"VocabularyL10Schema",
|
|
14
17
|
"L10NString",
|
|
18
|
+
"VocabulariesResourceConfig",
|
|
19
|
+
"VocabularyTypeResourceConfig",
|
|
20
|
+
"VocabulariesAdminResource",
|
|
21
|
+
"VocabulariesResource",
|
|
15
22
|
)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2024 CERN.
|
|
4
|
+
# Copyright (C) 2024 University of Münster.
|
|
5
|
+
#
|
|
6
|
+
# Invenio-Vocabularies is free software; you can redistringibute it and/or modify it
|
|
7
|
+
# under the terms of the MIT License; see LICENSE file for more details.
|
|
8
|
+
|
|
9
|
+
"""Resources config."""
|
|
10
|
+
|
|
11
|
+
import marshmallow as ma
|
|
12
|
+
from flask_resources import (
|
|
13
|
+
BaseListSchema,
|
|
14
|
+
HTTPJSONException,
|
|
15
|
+
JSONSerializer,
|
|
16
|
+
MarshmallowSerializer,
|
|
17
|
+
ResourceConfig,
|
|
18
|
+
ResponseHandler,
|
|
19
|
+
create_error_handler,
|
|
20
|
+
)
|
|
21
|
+
from invenio_records_resources.resources import (
|
|
22
|
+
RecordResource,
|
|
23
|
+
RecordResourceConfig,
|
|
24
|
+
SearchRequestArgsSchema,
|
|
25
|
+
)
|
|
26
|
+
from invenio_records_resources.resources.errors import ErrorHandlersMixin
|
|
27
|
+
from invenio_records_resources.resources.records.args import SearchRequestArgsSchema
|
|
28
|
+
from invenio_records_resources.resources.records.headers import etag_headers
|
|
29
|
+
from invenio_records_resources.services.base.config import ConfiguratorMixin
|
|
30
|
+
|
|
31
|
+
from .serializer import VocabularyL10NItemSchema
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class VocabularySearchRequestArgsSchema(SearchRequestArgsSchema):
|
|
35
|
+
"""Vocabularies search request parameters."""
|
|
36
|
+
|
|
37
|
+
tags = ma.fields.Str()
|
|
38
|
+
active = ma.fields.Boolean()
|
|
39
|
+
status = ma.fields.Boolean()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class VocabulariesResourceConfig(RecordResourceConfig):
|
|
43
|
+
"""Vocabulary resource configuration."""
|
|
44
|
+
|
|
45
|
+
blueprint_name = "vocabularies"
|
|
46
|
+
url_prefix = "/vocabularies"
|
|
47
|
+
routes = {
|
|
48
|
+
"list": "/<type>",
|
|
49
|
+
"item": "/<type>/<pid_value>",
|
|
50
|
+
"tasks": "/tasks",
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
request_view_args = {
|
|
54
|
+
"pid_value": ma.fields.Str(),
|
|
55
|
+
"type": ma.fields.Str(required=True),
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
request_search_args = VocabularySearchRequestArgsSchema
|
|
59
|
+
|
|
60
|
+
response_handlers = {
|
|
61
|
+
"application/json": ResponseHandler(JSONSerializer(), headers=etag_headers),
|
|
62
|
+
"application/vnd.inveniordm.v1+json": ResponseHandler(
|
|
63
|
+
MarshmallowSerializer(
|
|
64
|
+
format_serializer_cls=JSONSerializer,
|
|
65
|
+
object_schema_cls=VocabularyL10NItemSchema,
|
|
66
|
+
list_schema_cls=BaseListSchema,
|
|
67
|
+
),
|
|
68
|
+
headers=etag_headers,
|
|
69
|
+
),
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class VocabularyTypeResourceConfig(ResourceConfig, ConfiguratorMixin):
|
|
74
|
+
"""Vocabulary list resource config."""
|
|
75
|
+
|
|
76
|
+
# /vocabulary/vocabulary_id
|
|
77
|
+
# Blueprint configuration
|
|
78
|
+
blueprint_name = "vocabulary_types"
|
|
79
|
+
url_prefix = "/vocabularies"
|
|
80
|
+
|
|
81
|
+
routes = {"list": "/"}
|
|
82
|
+
|
|
83
|
+
# Request parsing
|
|
84
|
+
request_read_args = {}
|
|
85
|
+
request_view_args = {
|
|
86
|
+
"pid_value": ma.fields.String,
|
|
87
|
+
"type": ma.fields.String,
|
|
88
|
+
}
|
|
89
|
+
request_search_args = VocabularySearchRequestArgsSchema
|
|
90
|
+
|
|
91
|
+
error_handlers = {
|
|
92
|
+
**ErrorHandlersMixin.error_handlers,
|
|
93
|
+
# TODO: Add custom error handlers here
|
|
94
|
+
}
|
|
95
|
+
response_handlers = {
|
|
96
|
+
"application/json": ResponseHandler(JSONSerializer(), headers=etag_headers),
|
|
97
|
+
"application/vnd.inveniordm.v1+json": ResponseHandler(
|
|
98
|
+
MarshmallowSerializer(
|
|
99
|
+
format_serializer_cls=JSONSerializer,
|
|
100
|
+
object_schema_cls=VocabularyL10NItemSchema,
|
|
101
|
+
list_schema_cls=BaseListSchema,
|
|
102
|
+
),
|
|
103
|
+
headers=etag_headers,
|
|
104
|
+
),
|
|
105
|
+
}
|