invenio-vocabularies 4.0.0__py2.py3-none-any.whl → 4.2.0__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.

Files changed (76) hide show
  1. invenio_vocabularies/__init__.py +1 -1
  2. invenio_vocabularies/administration/__init__.py +10 -0
  3. invenio_vocabularies/administration/views/__init__.py +10 -0
  4. invenio_vocabularies/administration/views/vocabularies.py +45 -0
  5. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/CustomAwardForm.js +8 -20
  6. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/FundingField.js +2 -2
  7. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/FundingModal.js +5 -7
  8. invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/NoAwardResults.js +3 -3
  9. invenio_vocabularies/cli.py +5 -3
  10. invenio_vocabularies/config.py +35 -4
  11. invenio_vocabularies/contrib/affiliations/api.py +1 -2
  12. invenio_vocabularies/contrib/affiliations/config.py +2 -2
  13. invenio_vocabularies/contrib/affiliations/datastreams.py +92 -0
  14. invenio_vocabularies/contrib/affiliations/jsonschemas/affiliations/affiliation-v1.0.0.json +38 -1
  15. invenio_vocabularies/contrib/affiliations/mappings/os-v1/affiliations/affiliation-v1.0.0.json +21 -0
  16. invenio_vocabularies/contrib/affiliations/mappings/os-v2/affiliations/affiliation-v1.0.0.json +21 -0
  17. invenio_vocabularies/contrib/affiliations/mappings/v7/affiliations/affiliation-v1.0.0.json +21 -0
  18. invenio_vocabularies/contrib/affiliations/schema.py +17 -3
  19. invenio_vocabularies/contrib/affiliations/services.py +1 -2
  20. invenio_vocabularies/contrib/awards/awards.py +2 -1
  21. invenio_vocabularies/contrib/awards/datastreams.py +1 -0
  22. invenio_vocabularies/contrib/awards/jsonschemas/awards/award-v1.0.0.json +3 -0
  23. invenio_vocabularies/contrib/awards/mappings/os-v1/awards/award-v1.0.0.json +3 -0
  24. invenio_vocabularies/contrib/awards/mappings/os-v2/awards/award-v1.0.0.json +3 -0
  25. invenio_vocabularies/contrib/awards/mappings/v7/awards/award-v1.0.0.json +3 -0
  26. invenio_vocabularies/contrib/awards/services.py +1 -2
  27. invenio_vocabularies/contrib/common/ror/datastreams.py +140 -6
  28. invenio_vocabularies/contrib/funders/datastreams.py +36 -93
  29. invenio_vocabularies/contrib/funders/funders.py +2 -1
  30. invenio_vocabularies/contrib/funders/jsonschemas/funders/funder-v1.0.0.json +3 -0
  31. invenio_vocabularies/contrib/funders/mappings/os-v1/funders/funder-v1.0.0.json +3 -0
  32. invenio_vocabularies/contrib/funders/mappings/os-v2/funders/funder-v1.0.0.json +3 -0
  33. invenio_vocabularies/contrib/funders/mappings/v7/funders/funder-v1.0.0.json +3 -0
  34. invenio_vocabularies/contrib/funders/serializer.py +2 -1
  35. invenio_vocabularies/contrib/names/jsonschemas/names/name-v1.0.0.json +3 -0
  36. invenio_vocabularies/contrib/names/mappings/os-v1/names/name-v1.0.0.json +3 -0
  37. invenio_vocabularies/contrib/names/mappings/os-v2/names/name-v1.0.0.json +3 -0
  38. invenio_vocabularies/contrib/names/mappings/v7/names/name-v1.0.0.json +3 -0
  39. invenio_vocabularies/contrib/subjects/jsonschemas/subjects/subject-v1.0.0.json +3 -0
  40. invenio_vocabularies/contrib/subjects/mappings/os-v1/subjects/subject-v1.0.0.json +3 -0
  41. invenio_vocabularies/contrib/subjects/mappings/os-v2/subjects/subject-v1.0.0.json +3 -0
  42. invenio_vocabularies/contrib/subjects/mappings/v7/subjects/subject-v1.0.0.json +3 -0
  43. invenio_vocabularies/datastreams/factories.py +1 -2
  44. invenio_vocabularies/datastreams/readers.py +103 -0
  45. invenio_vocabularies/datastreams/tasks.py +25 -0
  46. invenio_vocabularies/datastreams/writers.py +21 -2
  47. invenio_vocabularies/ext.py +22 -7
  48. invenio_vocabularies/factories.py +16 -0
  49. invenio_vocabularies/proxies.py +2 -2
  50. invenio_vocabularies/records/jsonschemas/vocabularies/definitions-v1.0.0.json +7 -0
  51. invenio_vocabularies/records/jsonschemas/vocabularies/vocabulary-v1.0.0.json +1 -4
  52. invenio_vocabularies/records/models.py +2 -4
  53. invenio_vocabularies/records/pidprovider.py +1 -2
  54. invenio_vocabularies/resources/__init__.py +9 -1
  55. invenio_vocabularies/resources/config.py +105 -0
  56. invenio_vocabularies/resources/resource.py +31 -41
  57. invenio_vocabularies/resources/schema.py +2 -1
  58. invenio_vocabularies/services/__init__.py +5 -2
  59. invenio_vocabularies/services/config.py +179 -0
  60. invenio_vocabularies/services/custom_fields/subject.py +2 -1
  61. invenio_vocabularies/services/custom_fields/vocabulary.py +1 -1
  62. invenio_vocabularies/services/permissions.py +3 -1
  63. invenio_vocabularies/services/results.py +110 -0
  64. invenio_vocabularies/services/schema.py +11 -2
  65. invenio_vocabularies/services/service.py +41 -86
  66. invenio_vocabularies/services/tasks.py +1 -31
  67. invenio_vocabularies/templates/semantic-ui/invenio_vocabularies/vocabularies-list.html +12 -0
  68. invenio_vocabularies/templates/semantic-ui/invenio_vocabularies/vocabulary-details.html +71 -0
  69. invenio_vocabularies/views.py +7 -0
  70. {invenio_vocabularies-4.0.0.dist-info → invenio_vocabularies-4.2.0.dist-info}/METADATA +33 -1
  71. {invenio_vocabularies-4.0.0.dist-info → invenio_vocabularies-4.2.0.dist-info}/RECORD +76 -66
  72. {invenio_vocabularies-4.0.0.dist-info → invenio_vocabularies-4.2.0.dist-info}/entry_points.txt +4 -0
  73. {invenio_vocabularies-4.0.0.dist-info → invenio_vocabularies-4.2.0.dist-info}/AUTHORS.rst +0 -0
  74. {invenio_vocabularies-4.0.0.dist-info → invenio_vocabularies-4.2.0.dist-info}/LICENSE +0 -0
  75. {invenio_vocabularies-4.0.0.dist-info → invenio_vocabularies-4.2.0.dist-info}/WHEEL +0 -0
  76. {invenio_vocabularies-4.0.0.dist-info → invenio_vocabularies-4.2.0.dist-info}/top_level.txt +0 -0
@@ -7,6 +7,7 @@
7
7
  # details.
8
8
 
9
9
  """Awards datastreams, transformers, writers and readers."""
10
+
10
11
  import io
11
12
 
12
13
  import requests
@@ -7,6 +7,9 @@
7
7
  "$schema": {
8
8
  "$ref": "local://definitions-v1.0.0.json#/$schema"
9
9
  },
10
+ "tags": {
11
+ "$ref": "local://vocabularies/definitions-v1.0.0.json#/tags"
12
+ },
10
13
  "identifiers": {
11
14
  "description": "Alternate identifiers for the award.",
12
15
  "type": "array",
@@ -49,6 +49,9 @@
49
49
  "type": "object",
50
50
  "dynamic": "true"
51
51
  },
52
+ "tags": {
53
+ "type": "keyword"
54
+ },
52
55
  "number": {
53
56
  "type": "keyword"
54
57
  },
@@ -49,6 +49,9 @@
49
49
  "type": "object",
50
50
  "dynamic": "true"
51
51
  },
52
+ "tags": {
53
+ "type": "keyword"
54
+ },
52
55
  "number": {
53
56
  "type": "keyword"
54
57
  },
@@ -49,6 +49,9 @@
49
49
  "type": "object",
50
50
  "dynamic": "true"
51
51
  },
52
+ "tags": {
53
+ "type": "keyword"
54
+ },
52
55
  "number": {
53
56
  "type": "keyword"
54
57
  },
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
- # Copyright (C) 2022 CERN.
3
+ # Copyright (C) 2022-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
@@ -8,7 +8,6 @@
8
8
 
9
9
  """Vocabulary awards."""
10
10
 
11
-
12
11
  from .awards import record_type
13
12
 
14
13
  AwardsServiceConfig = record_type.service_config_cls
@@ -1,6 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright (C) 2024 CERN.
4
+ # Copyright (C) 2024 California Institute of Technology.
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
@@ -9,16 +10,24 @@
9
10
  """ROR-related Datastreams Readers/Writers/Transformers module."""
10
11
 
11
12
  import io
13
+ from datetime import datetime
12
14
 
13
15
  import requests
16
+ from idutils import normalize_ror
14
17
 
15
- from invenio_vocabularies.datastreams.errors import ReaderError
18
+ from invenio_vocabularies.datastreams.errors import ReaderError, TransformerError
16
19
  from invenio_vocabularies.datastreams.readers import BaseReader
20
+ from invenio_vocabularies.datastreams.transformers import BaseTransformer
17
21
 
18
22
 
19
23
  class RORHTTPReader(BaseReader):
20
24
  """ROR HTTP Reader returning an in-memory binary stream of the latest ROR data dump ZIP file."""
21
25
 
26
+ def __init__(self, origin=None, mode="r", since=None, *args, **kwargs):
27
+ """Constructor."""
28
+ self._since = since
29
+ super().__init__(origin, mode, *args, **kwargs)
30
+
22
31
  def _iter(self, fp, *args, **kwargs):
23
32
  raise NotImplementedError(
24
33
  "RORHTTPReader downloads one file and therefore does not iterate through items"
@@ -31,15 +40,41 @@ class RORHTTPReader(BaseReader):
31
40
  "RORHTTPReader does not support being chained after another reader"
32
41
  )
33
42
 
43
+ # Follow the DOI to get the link of the linkset
44
+ dataset_doi_link = "https://doi.org/10.5281/zenodo.6347574"
45
+ landing_page = requests.get(dataset_doi_link, allow_redirects=True)
46
+ landing_page.raise_for_status()
47
+
34
48
  # Call the signposting `linkset+json` endpoint for the Concept DOI (i.e. latest version) of the ROR data dump.
35
49
  # See: https://github.com/inveniosoftware/rfcs/blob/master/rfcs/rdm-0071-signposting.md#provide-an-applicationlinksetjson-endpoint
36
- headers = {"Accept": "application/linkset+json"}
37
- api_url = "https://zenodo.org/api/records/6347574"
38
- api_resp = requests.get(api_url, headers=headers)
39
- api_resp.raise_for_status()
50
+ if "linkset" not in landing_page.links:
51
+ raise ReaderError("Linkset not found in the ROR dataset record.")
52
+ linkset_response = requests.get(
53
+ landing_page.links["linkset"]["url"],
54
+ headers={"Accept": "application/linkset+json"},
55
+ )
56
+ linkset_response.raise_for_status()
57
+
58
+ if self._since:
59
+ for link in linkset_response.json()["linkset"]:
60
+ if "type" in link and link["type"] == "application/ld+json":
61
+ json_ld_reponse = requests.get(
62
+ link["anchor"], headers={"Accept": link["type"]}
63
+ )
64
+ json_ld_reponse.raise_for_status()
65
+
66
+ # TODO Update to use dateCreated once the field is added to InvenioRDM. (https://github.com/inveniosoftware/invenio-rdm-records/issues/1777)
67
+ last_dump_date = json_ld_reponse.json()["datePublished"]
68
+ if datetime.fromisoformat(last_dump_date) < datetime.fromisoformat(
69
+ self._since
70
+ ):
71
+ return
72
+ break
73
+ else:
74
+ raise ReaderError("Couldn't find json-ld in publisher's linkset.")
40
75
 
41
76
  # Extract the Landing page Link Set Object located as the first (index 0) item.
42
- landing_page_linkset = api_resp.json()["linkset"][0]
77
+ landing_page_linkset = linkset_response.json()["linkset"][0]
43
78
 
44
79
  # Extract the URL of the only ZIP file linked to the record.
45
80
  landing_page_zip_items = [
@@ -64,3 +99,102 @@ class RORHTTPReader(BaseReader):
64
99
  VOCABULARIES_DATASTREAM_READERS = {
65
100
  "ror-http": RORHTTPReader,
66
101
  }
102
+
103
+
104
+ class RORTransformer(BaseTransformer):
105
+ """Transforms a JSON ROR record into a funders record."""
106
+
107
+ def __init__(
108
+ self, *args, vocab_schemes=None, funder_fundref_doi_prefix=None, **kwargs
109
+ ):
110
+ """Initializes the transformer."""
111
+ self.vocab_schemes = vocab_schemes
112
+ self.funder_fundref_doi_prefix = funder_fundref_doi_prefix
113
+ super().__init__(*args, **kwargs)
114
+
115
+ def apply(self, stream_entry, **kwargs):
116
+ """Applies the transformation to the stream entry."""
117
+ record = stream_entry.entry
118
+ ror = {}
119
+ ror["title"] = {}
120
+
121
+ ror["id"] = normalize_ror(record.get("id"))
122
+ if not ror["id"]:
123
+ raise TransformerError(_("Id not found in ROR entry."))
124
+
125
+ # Using set so aliases are unique
126
+ aliases = set()
127
+ acronym = None
128
+ for name in record.get("names"):
129
+ lang = name.get("lang", "en")
130
+ if lang == None:
131
+ lang = "en"
132
+ if "ror_display" in name["types"]:
133
+ ror["name"] = name["value"]
134
+ if "label" in name["types"]:
135
+ ror["title"][lang] = name["value"]
136
+ if "alias" in name["types"]:
137
+ aliases.add(name["value"])
138
+ if "acronym" in name["types"]:
139
+ # The first acronyn goes in acronym field to maintain
140
+ # compatability with existing data structure
141
+ if not acronym:
142
+ acronym = name["value"]
143
+ else:
144
+ aliases.add(name["value"])
145
+ if acronym:
146
+ ror["acronym"] = acronym
147
+ if aliases:
148
+ ror["aliases"] = list(aliases)
149
+
150
+ # ror_display is required and should be in every entry
151
+ if not ror["name"]:
152
+ raise TransformerError(
153
+ _("Name with type ror_display not found in ROR entry.")
154
+ )
155
+
156
+ # This only gets the first location, to maintain compatability
157
+ # with existing data structure
158
+ location = record.get("locations", [{}])[0].get("geonames_details", {})
159
+ ror["country"] = location.get("country_code")
160
+ ror["country_name"] = location.get("country_name")
161
+ ror["location_name"] = location.get("name")
162
+
163
+ ror["types"] = record.get("types")
164
+
165
+ status = record.get("status")
166
+ ror["status"] = status
167
+
168
+ # The ROR is always listed in identifiers, expected by serialization
169
+ ror["identifiers"] = [{"identifier": ror["id"], "scheme": "ror"}]
170
+ if self.vocab_schemes:
171
+ valid_schemes = set(self.vocab_schemes.keys())
172
+ else:
173
+ valid_schemes = set()
174
+ fund_ref = "fundref"
175
+ if self.funder_fundref_doi_prefix:
176
+ valid_schemes.add(fund_ref)
177
+ for identifier in record.get("external_ids"):
178
+ scheme = identifier["type"]
179
+ if scheme in valid_schemes:
180
+ value = identifier.get("preferred") or identifier.get("all")[0]
181
+ if scheme == fund_ref:
182
+ if self.funder_fundref_doi_prefix:
183
+ value = f"{self.funder_fundref_doi_prefix}/{value}"
184
+ scheme = "doi"
185
+ ror["identifiers"].append(
186
+ {
187
+ "identifier": value,
188
+ "scheme": scheme,
189
+ }
190
+ )
191
+
192
+ stream_entry.entry = ror
193
+ return stream_entry
194
+
195
+
196
+ VOCABULARIES_DATASTREAM_TRANSFORMERS = {
197
+ "ror": RORTransformer,
198
+ }
199
+
200
+ VOCABULARIES_DATASTREAM_WRITERS = {}
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
- # Copyright (C) 2022 CERN.
3
+ # Copyright (C) 2022-2024 CERN.
4
4
  # Copyright (C) 2024 California Institute of Technology.
5
5
  #
6
6
  # Invenio-Vocabularies is free software; you can redistribute it and/or
@@ -9,14 +9,11 @@
9
9
 
10
10
  """Funders datastreams, transformers, writers and readers."""
11
11
 
12
- from idutils import normalize_ror
13
- from invenio_access.permissions import system_identity
12
+ from flask import current_app
14
13
  from invenio_i18n import lazy_gettext as _
15
14
 
16
- from ...datastreams.errors import TransformerError
17
- from ...datastreams.transformers import BaseTransformer
18
15
  from ...datastreams.writers import ServiceWriter
19
- from .config import funder_fundref_doi_prefix, funder_schemes
16
+ from ..common.ror.datastreams import RORTransformer
20
17
 
21
18
 
22
19
  class FundersServiceWriter(ServiceWriter):
@@ -32,98 +29,40 @@ class FundersServiceWriter(ServiceWriter):
32
29
  return entry["id"]
33
30
 
34
31
 
35
- class RORTransformer(BaseTransformer):
36
- """Transforms a JSON ROR record into a funders record."""
37
-
38
- def apply(self, stream_entry, **kwargs):
39
- """Applies the transformation to the stream entry."""
40
- record = stream_entry.entry
41
- funder = {}
42
- funder["title"] = {}
43
-
44
- funder["id"] = normalize_ror(record.get("id"))
45
- if not funder["id"]:
46
- raise TransformerError(_("Id not found in ROR entry."))
47
-
48
- aliases = []
49
- acronym = None
50
- for name in record.get("names"):
51
- # Some name entries have a `lang` key with a `None` value.
52
- # Therefore, providing a default value to `name.get("lang")` is not enough,
53
- # and we need instead to check if the result of `get` is None.
54
- lang = name.get("lang")
55
- if lang is None:
56
- lang = "en"
57
-
58
- if "ror_display" in name["types"]:
59
- funder["name"] = name["value"]
60
- if "label" in name["types"]:
61
- funder["title"][lang] = name["value"]
62
- if "alias" in name["types"]:
63
- aliases.append(name["value"])
64
- if "acronym" in name["types"]:
65
- # The first acronyn goes in acronym field to maintain
66
- # compatability with existing data structure
67
- if not acronym:
68
- acronym = name["value"]
69
- else:
70
- aliases.append(name["value"])
71
- if acronym:
72
- funder["acronym"] = acronym
73
- if aliases:
74
- funder["aliases"] = aliases
75
-
76
- # ror_display is required and should be in every entry
77
- if not funder["name"]:
78
- raise TransformerError(
79
- _("Name with type ror_display not found in ROR entry.")
32
+ class FundersRORTransformer(RORTransformer):
33
+ """Funders ROR Transformer."""
34
+
35
+ def __init__(
36
+ self, *args, vocab_schemes=None, funder_fundref_doi_prefix=None, **kwargs
37
+ ):
38
+ """Constructor."""
39
+ if vocab_schemes is None:
40
+ vocab_schemes = current_app.config.get("VOCABULARIES_FUNDER_SCHEMES")
41
+ if funder_fundref_doi_prefix is None:
42
+ funder_fundref_doi_prefix = current_app.config.get(
43
+ "VOCABULARIES_FUNDER_DOI_PREFIX"
80
44
  )
45
+ super().__init__(
46
+ *args,
47
+ vocab_schemes=vocab_schemes,
48
+ funder_fundref_doi_prefix=funder_fundref_doi_prefix,
49
+ **kwargs
50
+ )
81
51
 
82
- # This only gets the first location, to maintain compatability
83
- # with existing data structure
84
- location = record.get("locations", [{}])[0].get("geonames_details", {})
85
- funder["country"] = location.get("country_code")
86
- funder["country_name"] = location.get("country_name")
87
- funder["location_name"] = location.get("name")
88
-
89
- funder["types"] = record.get("types")
90
-
91
- status = record.get("status")
92
- funder["status"] = status
93
-
94
- # The ROR is always listed in identifiers, expected by serialization
95
- funder["identifiers"] = [{"identifier": funder["id"], "scheme": "ror"}]
96
- valid_schemes = set(funder_schemes.keys())
97
- fund_ref = "fundref"
98
- valid_schemes.add(fund_ref)
99
- for identifier in record.get("external_ids"):
100
- scheme = identifier["type"]
101
- if scheme in valid_schemes:
102
- value = identifier.get("preferred") or identifier.get("all")[0]
103
- if scheme == fund_ref:
104
- value = f"{funder_fundref_doi_prefix}/{value}"
105
- scheme = "doi"
106
- funder["identifiers"].append(
107
- {
108
- "identifier": value,
109
- "scheme": scheme,
110
- }
111
- )
112
-
113
- stream_entry.entry = funder
114
- return stream_entry
115
52
 
53
+ VOCABULARIES_DATASTREAM_READERS = {}
54
+ """Funders datastreams writers."""
116
55
 
117
- VOCABULARIES_DATASTREAM_TRANSFORMERS = {
118
- "ror-funder": RORTransformer,
56
+ VOCABULARIES_DATASTREAM_WRITERS = {
57
+ "funders-service": FundersServiceWriter,
119
58
  }
120
- """ROR Data Streams transformers."""
59
+ """Funders datastreams writers."""
121
60
 
122
61
 
123
- VOCABULARIES_DATASTREAM_WRITERS = {
124
- "funders-service": FundersServiceWriter,
62
+ VOCABULARIES_DATASTREAM_TRANSFORMERS = {
63
+ "ror-funders": FundersRORTransformer,
125
64
  }
126
- """Funders Data Streams transformers."""
65
+ """Funders datastreams transformers."""
127
66
 
128
67
 
129
68
  DATASTREAM_CONFIG = {
@@ -137,13 +76,17 @@ DATASTREAM_CONFIG = {
137
76
  {"type": "json"},
138
77
  ],
139
78
  "transformers": [
140
- {"type": "ror-funder"},
79
+ {
80
+ "type": "ror-funders",
81
+ },
141
82
  ],
142
83
  "writers": [
143
84
  {
144
- "type": "funders-service",
85
+ "type": "async",
145
86
  "args": {
146
- "identity": system_identity,
87
+ "writer": {
88
+ "type": "funders-service",
89
+ }
147
90
  },
148
91
  }
149
92
  ],
@@ -1,12 +1,13 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
- # Copyright (C) 2022 CERN.
3
+ # Copyright (C) 2022-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
7
7
  # details.
8
8
 
9
9
  """Vocabulary funders."""
10
+
10
11
  from flask_resources import (
11
12
  BaseListSchema,
12
13
  JSONSerializer,
@@ -7,6 +7,9 @@
7
7
  "$schema": {
8
8
  "$ref": "local://definitions-v1.0.0.json#/$schema"
9
9
  },
10
+ "tags": {
11
+ "$ref": "local://vocabularies/definitions-v1.0.0.json#/tags"
12
+ },
10
13
  "country": {
11
14
  "type": "string",
12
15
  "description": "Represents a funder's origin country as a country code."
@@ -81,6 +81,9 @@
81
81
  "title": {
82
82
  "type": "object",
83
83
  "dynamic": "true"
84
+ },
85
+ "tags": {
86
+ "type": "keyword"
84
87
  }
85
88
  }
86
89
  }
@@ -81,6 +81,9 @@
81
81
  "title": {
82
82
  "type": "object",
83
83
  "dynamic": "true"
84
+ },
85
+ "tags": {
86
+ "type": "keyword"
84
87
  }
85
88
  }
86
89
  }
@@ -81,6 +81,9 @@
81
81
  "title": {
82
82
  "type": "object",
83
83
  "dynamic": "true"
84
+ },
85
+ "tags": {
86
+ "type": "keyword"
84
87
  }
85
88
  }
86
89
  }
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
- # Copyright (C) 2022 CERN.
3
+ # Copyright (C) 2022-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
@@ -29,4 +29,5 @@ class FunderL10NItemSchema(Schema):
29
29
  props = fields.Dict(dump_only=True)
30
30
  name = fields.String(dump_only=True)
31
31
  country = fields.String(dump_only=True)
32
+ country_name = fields.String(dump_only=True)
32
33
  identifiers = fields.List(fields.Nested(IdentifierSchema), dump_only=True)
@@ -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"
@@ -24,6 +24,9 @@
24
24
  "id": {
25
25
  "type": "keyword"
26
26
  },
27
+ "tags": {
28
+ "type": "keyword"
29
+ },
27
30
  "name_sort": {
28
31
  "type": "keyword"
29
32
  },
@@ -24,6 +24,9 @@
24
24
  "id": {
25
25
  "type": "keyword"
26
26
  },
27
+ "tags": {
28
+ "type": "keyword"
29
+ },
27
30
  "name_sort": {
28
31
  "type": "keyword"
29
32
  },
@@ -24,6 +24,9 @@
24
24
  "id": {
25
25
  "type": "keyword"
26
26
  },
27
+ "tags": {
28
+ "type": "keyword"
29
+ },
27
30
  "name_sort": {
28
31
  "type": "keyword"
29
32
  },
@@ -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"
@@ -55,6 +55,9 @@
55
55
  "type": "keyword"
56
56
  }
57
57
  }
58
+ },
59
+ "tags": {
60
+ "type": "keyword"
58
61
  }
59
62
  }
60
63
  }
@@ -55,6 +55,9 @@
55
55
  "type": "keyword"
56
56
  }
57
57
  }
58
+ },
59
+ "tags": {
60
+ "type": "keyword"
58
61
  }
59
62
  }
60
63
  }
@@ -55,6 +55,9 @@
55
55
  "type": "keyword"
56
56
  }
57
57
  }
58
+ },
59
+ "tags": {
60
+ "type": "keyword"
58
61
  }
59
62
  }
60
63
  }
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
- # Copyright (C) 2021-2022 CERN.
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_)