invenio-vocabularies 1.2.0__py2.py3-none-any.whl → 6.3.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 +2 -2
- invenio_vocabularies/administration/__init__.py +10 -0
- invenio_vocabularies/administration/views/__init__.py +10 -0
- invenio_vocabularies/administration/views/vocabularies.py +45 -0
- invenio_vocabularies/alembic/4a9a4fd235f8_create_vocabulary_schemes.py +4 -4
- invenio_vocabularies/alembic/4f365fced43f_create_vocabularies_tables.py +2 -2
- invenio_vocabularies/alembic/55a700f897b6_add_names_and_afiliations_pid_column.py +96 -0
- invenio_vocabularies/alembic/676dd587542d_create_funders_vocabulary_table.py +1 -1
- invenio_vocabularies/alembic/e1146238edd3_create_awards_table.py +1 -1
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/.eslintrc.yml +11 -0
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/.prettierrc +1 -0
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/index.js +7 -0
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/package.json +25 -0
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/AwardResults.js +95 -0
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/CustomAwardForm.js +139 -0
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/FunderDropdown.js +87 -0
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/FundingField.js +223 -0
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/FundingField.test.js +1 -0
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/FundingFieldItem.js +152 -0
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/FundingModal.js +270 -0
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/NoAwardResults.js +37 -0
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/Funding/index.js +8 -0
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/forms/index.js +7 -0
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/contrib/index.js +7 -0
- invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies/src/index.js +7 -0
- invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/i18next-scanner.config.js +63 -0
- invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/i18next.js +36 -0
- invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/messages/index.js +1 -0
- invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/package.json +53 -0
- invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/scripts/compileCatalog.js +39 -0
- invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies/scripts/initCatalog.js +19 -0
- invenio_vocabularies/cli.py +31 -44
- invenio_vocabularies/config.py +74 -7
- invenio_vocabularies/contrib/affiliations/affiliations.py +22 -6
- invenio_vocabularies/contrib/affiliations/api.py +1 -2
- invenio_vocabularies/contrib/affiliations/config.py +10 -5
- invenio_vocabularies/contrib/affiliations/datastreams.py +186 -0
- invenio_vocabularies/contrib/affiliations/facets.py +36 -0
- invenio_vocabularies/contrib/affiliations/jsonschemas/affiliations/affiliation-v1.0.0.json +38 -7
- invenio_vocabularies/contrib/affiliations/mappings/os-v1/affiliations/affiliation-v1.0.0.json +22 -1
- invenio_vocabularies/contrib/affiliations/mappings/os-v1/affiliations/affiliation-v2.0.0.json +171 -0
- invenio_vocabularies/contrib/affiliations/mappings/os-v2/affiliations/affiliation-v1.0.0.json +22 -1
- invenio_vocabularies/contrib/affiliations/mappings/os-v2/affiliations/affiliation-v2.0.0.json +171 -0
- invenio_vocabularies/contrib/affiliations/mappings/v7/affiliations/affiliation-v1.0.0.json +22 -1
- invenio_vocabularies/contrib/affiliations/schema.py +23 -5
- invenio_vocabularies/contrib/affiliations/services.py +1 -2
- invenio_vocabularies/contrib/awards/awards.py +18 -6
- invenio_vocabularies/contrib/awards/config.py +1 -3
- invenio_vocabularies/contrib/awards/datastreams.py +246 -3
- invenio_vocabularies/contrib/awards/jsonschemas/awards/award-v1.0.0.json +41 -0
- invenio_vocabularies/contrib/awards/mappings/os-v1/awards/award-v1.0.0.json +53 -1
- invenio_vocabularies/contrib/awards/mappings/os-v2/awards/award-v1.0.0.json +53 -1
- invenio_vocabularies/contrib/awards/mappings/v7/awards/award-v1.0.0.json +53 -1
- invenio_vocabularies/contrib/awards/schema.py +27 -35
- invenio_vocabularies/contrib/awards/serializer.py +9 -1
- invenio_vocabularies/contrib/awards/services.py +1 -2
- invenio_vocabularies/contrib/common/__init__.py +9 -0
- invenio_vocabularies/contrib/common/openaire/__init__.py +9 -0
- invenio_vocabularies/contrib/common/openaire/datastreams.py +84 -0
- invenio_vocabularies/contrib/common/ror/__init__.py +9 -0
- invenio_vocabularies/contrib/common/ror/datastreams.py +220 -0
- invenio_vocabularies/contrib/funders/config.py +12 -5
- invenio_vocabularies/contrib/funders/datastreams.py +40 -62
- invenio_vocabularies/contrib/funders/facets.py +13 -5
- invenio_vocabularies/contrib/funders/funders.py +4 -2
- 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 +22 -1
- invenio_vocabularies/contrib/funders/mappings/os-v1/funders/funder-v2.0.0.json +156 -0
- invenio_vocabularies/contrib/funders/mappings/os-v2/funders/funder-v1.0.0.json +22 -1
- invenio_vocabularies/contrib/funders/mappings/os-v2/funders/funder-v2.0.0.json +156 -0
- invenio_vocabularies/contrib/funders/mappings/v7/funders/funder-v1.0.0.json +22 -1
- invenio_vocabularies/contrib/funders/schema.py +8 -0
- invenio_vocabularies/contrib/funders/serializer.py +2 -1
- invenio_vocabularies/contrib/names/config.py +5 -3
- invenio_vocabularies/contrib/names/datastreams.py +177 -38
- invenio_vocabularies/contrib/names/jsonschemas/names/name-v1.0.0.json +2 -6
- invenio_vocabularies/contrib/names/mappings/os-v1/names/name-v1.0.0.json +3 -0
- invenio_vocabularies/contrib/names/mappings/os-v1/names/name-v2.0.0.json +150 -0
- invenio_vocabularies/contrib/names/mappings/os-v2/names/name-v1.0.0.json +3 -0
- invenio_vocabularies/contrib/names/mappings/os-v2/names/name-v2.0.0.json +150 -0
- invenio_vocabularies/contrib/names/mappings/v7/names/name-v1.0.0.json +3 -0
- invenio_vocabularies/contrib/names/names.py +29 -13
- invenio_vocabularies/contrib/names/permissions.py +20 -0
- invenio_vocabularies/contrib/names/s3client.py +44 -0
- invenio_vocabularies/contrib/names/schema.py +31 -4
- invenio_vocabularies/contrib/subjects/config.py +9 -3
- invenio_vocabularies/contrib/subjects/datastreams.py +61 -0
- invenio_vocabularies/contrib/subjects/euroscivoc/__init__.py +9 -0
- invenio_vocabularies/contrib/subjects/euroscivoc/datastreams.py +171 -0
- invenio_vocabularies/contrib/subjects/jsonschemas/subjects/subject-v1.0.0.json +31 -0
- invenio_vocabularies/contrib/subjects/mappings/os-v1/subjects/subject-v1.0.0.json +35 -0
- invenio_vocabularies/contrib/subjects/mappings/os-v2/subjects/subject-v1.0.0.json +35 -0
- invenio_vocabularies/contrib/subjects/mappings/v7/subjects/subject-v1.0.0.json +35 -0
- invenio_vocabularies/contrib/subjects/mesh/__init__.py +9 -0
- invenio_vocabularies/contrib/subjects/mesh/datastreams.py +43 -0
- invenio_vocabularies/contrib/subjects/schema.py +47 -5
- invenio_vocabularies/contrib/subjects/subjects.py +10 -0
- invenio_vocabularies/datastreams/datastreams.py +61 -13
- invenio_vocabularies/datastreams/factories.py +1 -2
- invenio_vocabularies/datastreams/readers.py +138 -29
- invenio_vocabularies/datastreams/tasks.py +37 -0
- invenio_vocabularies/datastreams/transformers.py +17 -27
- invenio_vocabularies/datastreams/writers.py +116 -14
- invenio_vocabularies/datastreams/xml.py +34 -0
- invenio_vocabularies/ext.py +59 -5
- invenio_vocabularies/factories.py +137 -0
- invenio_vocabularies/jobs.py +133 -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/records/mappings/os-v1/vocabularies/vocabulary-v1.0.0.json +3 -3
- invenio_vocabularies/records/mappings/os-v2/vocabularies/vocabulary-v1.0.0.json +3 -3
- invenio_vocabularies/records/mappings/v7/vocabularies/vocabulary-v1.0.0.json +3 -3
- invenio_vocabularies/records/models.py +8 -10
- invenio_vocabularies/records/pidprovider.py +1 -2
- invenio_vocabularies/records/systemfields/relations.py +2 -2
- invenio_vocabularies/resources/__init__.py +9 -1
- invenio_vocabularies/resources/config.py +105 -0
- invenio_vocabularies/resources/resource.py +31 -41
- invenio_vocabularies/resources/schema.py +2 -1
- invenio_vocabularies/services/__init__.py +5 -2
- invenio_vocabularies/services/config.py +179 -0
- invenio_vocabularies/services/custom_fields/__init__.py +6 -2
- invenio_vocabularies/services/custom_fields/subject.py +82 -0
- invenio_vocabularies/services/custom_fields/vocabulary.py +19 -9
- invenio_vocabularies/services/facets.py +67 -37
- invenio_vocabularies/services/permissions.py +3 -1
- invenio_vocabularies/services/results.py +110 -0
- invenio_vocabularies/services/schema.py +39 -2
- invenio_vocabularies/services/service.py +46 -94
- invenio_vocabularies/services/tasks.py +1 -1
- invenio_vocabularies/templates/semantic-ui/invenio_vocabularies/subjects.html +23 -0
- 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/translations/af/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/af/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/ar/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/ar/LC_MESSAGES/messages.po +9 -8
- invenio_vocabularies/translations/bg/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/bg/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/ca/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/ca/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/cs/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/cs/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/da/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/da/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/de/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/de/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/de_AT/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/de_AT/LC_MESSAGES/messages.po +139 -0
- invenio_vocabularies/translations/de_DE/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/de_DE/LC_MESSAGES/messages.po +139 -0
- invenio_vocabularies/translations/el/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/el/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/en/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/en_AT/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/en_AT/LC_MESSAGES/messages.po +139 -0
- invenio_vocabularies/translations/en_HU/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/en_HU/LC_MESSAGES/messages.po +139 -0
- invenio_vocabularies/translations/es/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/es/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/es_CU/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/es_CU/LC_MESSAGES/messages.po +139 -0
- invenio_vocabularies/translations/es_MX/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/es_MX/LC_MESSAGES/messages.po +139 -0
- invenio_vocabularies/translations/et/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/et/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/et_EE/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/et_EE/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/fa/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/fa/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/fa_IR/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/fa_IR/LC_MESSAGES/messages.po +139 -0
- invenio_vocabularies/translations/fr/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/fr/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/fr_CI/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/fr_CI/LC_MESSAGES/messages.po +139 -0
- invenio_vocabularies/translations/fr_FR/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/fr_FR/LC_MESSAGES/messages.po +139 -0
- invenio_vocabularies/translations/gl/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/gl/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/hi_IN/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/hi_IN/LC_MESSAGES/messages.po +139 -0
- invenio_vocabularies/translations/hr/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/hr/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/hu/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/hu/LC_MESSAGES/messages.po +4 -4
- invenio_vocabularies/translations/hu_HU/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/hu_HU/LC_MESSAGES/messages.po +139 -0
- invenio_vocabularies/translations/it/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/it/LC_MESSAGES/messages.po +4 -3
- invenio_vocabularies/translations/ja/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/ja/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/ka/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/ka/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/lt/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/lt/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/messages.pot +95 -48
- invenio_vocabularies/translations/ne/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/ne/LC_MESSAGES/messages.po +139 -0
- invenio_vocabularies/translations/no/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/no/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/pl/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/pl/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/pt/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/pt/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/ro/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/ro/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/ru/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/ru/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/rw/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/rw/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/sk/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/sk/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/sv/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/sv/LC_MESSAGES/messages.po +4 -3
- invenio_vocabularies/translations/sv_SE/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/sv_SE/LC_MESSAGES/messages.po +139 -0
- invenio_vocabularies/translations/tr/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/tr/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/uk/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/uk/LC_MESSAGES/messages.po +17 -13
- invenio_vocabularies/translations/uk_UA/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/uk_UA/LC_MESSAGES/messages.po +139 -0
- invenio_vocabularies/translations/zh_CN/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/zh_CN/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/translations/zh_TW/LC_MESSAGES/messages.mo +0 -0
- invenio_vocabularies/translations/zh_TW/LC_MESSAGES/messages.po +1 -1
- invenio_vocabularies/views.py +12 -26
- invenio_vocabularies/webpack.py +51 -0
- invenio_vocabularies-6.3.1.dist-info/METADATA +346 -0
- invenio_vocabularies-6.3.1.dist-info/RECORD +306 -0
- {invenio_vocabularies-1.2.0.dist-info → invenio_vocabularies-6.3.1.dist-info}/WHEEL +1 -1
- {invenio_vocabularies-1.2.0.dist-info → invenio_vocabularies-6.3.1.dist-info}/entry_points.txt +20 -0
- invenio_vocabularies-1.2.0.dist-info/METADATA +0 -133
- invenio_vocabularies-1.2.0.dist-info/RECORD +0 -220
- {invenio_vocabularies-1.2.0.dist-info → invenio_vocabularies-6.3.1.dist-info}/AUTHORS.rst +0 -0
- {invenio_vocabularies-1.2.0.dist-info → invenio_vocabularies-6.3.1.dist-info}/LICENSE +0 -0
- {invenio_vocabularies-1.2.0.dist-info → invenio_vocabularies-6.3.1.dist-info}/top_level.txt +0 -0
|
@@ -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-RDM-Records is free software; you can redistribute it and/or modify
|
|
6
6
|
# it under the terms of the MIT License; see LICENSE file for more details.
|
|
@@ -12,6 +12,7 @@ from invenio_records_resources.services.custom_fields.base import BaseCF
|
|
|
12
12
|
from marshmallow import fields
|
|
13
13
|
|
|
14
14
|
from ...proxies import current_service
|
|
15
|
+
from ...records.api import Vocabulary
|
|
15
16
|
from ...resources.serializer import VocabularyL10NItemSchema
|
|
16
17
|
from ...services.schema import VocabularyRelationSchema
|
|
17
18
|
|
|
@@ -30,7 +31,15 @@ class VocabularyCF(BaseCF):
|
|
|
30
31
|
"""
|
|
31
32
|
|
|
32
33
|
def __init__(
|
|
33
|
-
self,
|
|
34
|
+
self,
|
|
35
|
+
name,
|
|
36
|
+
vocabulary_id,
|
|
37
|
+
multiple=False,
|
|
38
|
+
dump_options=True,
|
|
39
|
+
sort_by=None,
|
|
40
|
+
schema=VocabularyRelationSchema,
|
|
41
|
+
ui_schema=VocabularyL10NItemSchema,
|
|
42
|
+
**kwargs,
|
|
34
43
|
):
|
|
35
44
|
"""Constructor."""
|
|
36
45
|
super().__init__(name, **kwargs)
|
|
@@ -38,6 +47,10 @@ class VocabularyCF(BaseCF):
|
|
|
38
47
|
self.vocabulary_id = vocabulary_id
|
|
39
48
|
self.dump_options = dump_options
|
|
40
49
|
self.multiple = multiple
|
|
50
|
+
self.sort_by = sort_by
|
|
51
|
+
self.schema = schema
|
|
52
|
+
self.ui_schema = ui_schema
|
|
53
|
+
self.pid_field = Vocabulary.pid.with_type_ctx(self.vocabulary_id)
|
|
41
54
|
|
|
42
55
|
@property
|
|
43
56
|
def mapping(self):
|
|
@@ -47,7 +60,7 @@ class VocabularyCF(BaseCF):
|
|
|
47
60
|
"properties": {
|
|
48
61
|
"@v": {"type": "keyword"},
|
|
49
62
|
"id": {"type": "keyword"},
|
|
50
|
-
"title": {"type": "object", "dynamic":
|
|
63
|
+
"title": {"type": "object", "dynamic": "true"},
|
|
51
64
|
},
|
|
52
65
|
}
|
|
53
66
|
|
|
@@ -56,9 +69,7 @@ class VocabularyCF(BaseCF):
|
|
|
56
69
|
@property
|
|
57
70
|
def field(self):
|
|
58
71
|
"""Marshmallow schema for vocabulary custom fields."""
|
|
59
|
-
return fields.Nested(
|
|
60
|
-
VocabularyRelationSchema, many=self.multiple, **self._field_args
|
|
61
|
-
)
|
|
72
|
+
return fields.Nested(self.schema, many=self.multiple, **self._field_args)
|
|
62
73
|
|
|
63
74
|
@property
|
|
64
75
|
def ui_field(self):
|
|
@@ -67,9 +78,7 @@ class VocabularyCF(BaseCF):
|
|
|
67
78
|
This schema is used in the UIJSONSerializer and controls how the field will be
|
|
68
79
|
dumped in the UI. It takes responsibility of the localization of strings.
|
|
69
80
|
"""
|
|
70
|
-
return fields.Nested(
|
|
71
|
-
VocabularyL10NItemSchema, many=self.multiple, **self._field_args
|
|
72
|
-
)
|
|
81
|
+
return fields.Nested(self.ui_schema, many=self.multiple, **self._field_args)
|
|
73
82
|
|
|
74
83
|
def options(self, identity):
|
|
75
84
|
"""Return UI serialized vocabulary items."""
|
|
@@ -78,6 +87,7 @@ class VocabularyCF(BaseCF):
|
|
|
78
87
|
identity,
|
|
79
88
|
fields=self.field_keys,
|
|
80
89
|
type=self.vocabulary_id,
|
|
90
|
+
sort=self.sort_by,
|
|
81
91
|
)
|
|
82
92
|
options = []
|
|
83
93
|
for vocab in vocabs:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
#
|
|
3
|
-
# Copyright (C) 2021-
|
|
3
|
+
# Copyright (C) 2021-2023 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,6 +9,7 @@
|
|
|
9
9
|
"""Vocabulary facets."""
|
|
10
10
|
|
|
11
11
|
from flask_principal import AnonymousIdentity
|
|
12
|
+
from invenio_cache.decorators import cached_with_expiration
|
|
12
13
|
from invenio_i18n.ext import current_i18n
|
|
13
14
|
from invenio_records_resources.proxies import current_service_registry
|
|
14
15
|
from invenio_records_resources.services.errors import FacetNotFoundError
|
|
@@ -19,6 +20,31 @@ from sqlalchemy.exc import NoResultFound
|
|
|
19
20
|
from ..proxies import current_service
|
|
20
21
|
|
|
21
22
|
|
|
23
|
+
def get_service(service_id):
|
|
24
|
+
"""Get the service object by name.
|
|
25
|
+
|
|
26
|
+
It is required to access the registry lazily, to avoid "out of
|
|
27
|
+
application context" errors.
|
|
28
|
+
"""
|
|
29
|
+
return current_service_registry.get(service_id) if service_id else current_service
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def get_vocabs(service_id, type, fields, ids):
|
|
33
|
+
"""Fetch vocabulary values by ids, using the service."""
|
|
34
|
+
service = get_service(service_id)
|
|
35
|
+
vocabs = service.read_many(
|
|
36
|
+
AnonymousIdentity(), type=type, ids=list(ids), fields=list(fields)
|
|
37
|
+
)
|
|
38
|
+
return list(vocabs.hits) # the service returns a generator
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@cached_with_expiration
|
|
42
|
+
def get_cached_vocab(service_id, type, fields, id_):
|
|
43
|
+
"""Cache vocabulary values by type in-memory."""
|
|
44
|
+
vocabs = get_vocabs(service_id, type, fields, [id_])
|
|
45
|
+
return vocabs[0] if vocabs else None
|
|
46
|
+
|
|
47
|
+
|
|
22
48
|
def lazy_get_label(vocab_item):
|
|
23
49
|
"""Lazy evaluation of a localized vocabulary label."""
|
|
24
50
|
params = {"locale": current_i18n.locale, "default_locale": "en"}
|
|
@@ -29,56 +55,60 @@ def lazy_get_label(vocab_item):
|
|
|
29
55
|
class VocabularyLabels:
|
|
30
56
|
"""Fetching of vocabulary labels for facets."""
|
|
31
57
|
|
|
32
|
-
def __init__(
|
|
33
|
-
|
|
58
|
+
def __init__(
|
|
59
|
+
self, vocabulary, cache=True, cache_ttl=3600, service_id=None, id_field="id"
|
|
60
|
+
):
|
|
61
|
+
"""Initialize the labels.
|
|
62
|
+
|
|
63
|
+
:param vocabulary: the name of the vocabulary type.
|
|
64
|
+
:param cache: use simple process in-memory cache when True.
|
|
65
|
+
:param cache_ttl: cache expiration in seconds.
|
|
66
|
+
:param service_id: the id of the registered service to be used
|
|
67
|
+
when fetching values for the vocabulary.
|
|
68
|
+
:param id_field: the name of the `id` field.
|
|
69
|
+
"""
|
|
34
70
|
self.vocabulary = vocabulary
|
|
35
71
|
self.cache = cache
|
|
36
|
-
self.
|
|
37
|
-
self.
|
|
72
|
+
self.cache_ttl = cache_ttl
|
|
73
|
+
self.fields = ("id", "title") # not configurable
|
|
74
|
+
self.service_id = service_id
|
|
38
75
|
self.id_field = id_field
|
|
39
76
|
|
|
40
|
-
@property
|
|
41
|
-
def service(self):
|
|
42
|
-
"""Service property.
|
|
43
|
-
|
|
44
|
-
It is required to access the regitry lazily to avoid out of
|
|
45
|
-
application context errors.
|
|
46
|
-
"""
|
|
47
|
-
if not self.service_name:
|
|
48
|
-
return current_service
|
|
49
|
-
return current_service_registry.get(self.service_name)
|
|
50
|
-
|
|
51
77
|
def _vocab_to_label(self, vocab):
|
|
52
78
|
"""Returns the label string for a vocabulary entry."""
|
|
53
79
|
return lazy_get_label(vocab["title"])
|
|
54
80
|
|
|
55
81
|
def __call__(self, ids):
|
|
56
82
|
"""Return the mapping when evaluated."""
|
|
57
|
-
|
|
83
|
+
if not ids:
|
|
84
|
+
return {}
|
|
85
|
+
|
|
86
|
+
labels = {}
|
|
58
87
|
try:
|
|
59
|
-
if
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
88
|
+
if self.cache:
|
|
89
|
+
for id_ in ids:
|
|
90
|
+
vocab = get_cached_vocab(
|
|
91
|
+
self.service_id,
|
|
92
|
+
self.vocabulary,
|
|
93
|
+
self.fields,
|
|
94
|
+
id_,
|
|
95
|
+
cache_ttl=self.cache_ttl,
|
|
96
|
+
)
|
|
97
|
+
if not vocab:
|
|
98
|
+
continue
|
|
99
|
+
labels[vocab[self.id_field]] = self._vocab_to_label(vocab)
|
|
63
100
|
else:
|
|
64
|
-
|
|
65
|
-
|
|
101
|
+
vocab_list = get_vocabs(
|
|
102
|
+
self.service_id,
|
|
103
|
+
self.vocabulary,
|
|
104
|
+
self.fields,
|
|
105
|
+
ids,
|
|
66
106
|
)
|
|
107
|
+
for vocab in vocab_list:
|
|
108
|
+
id_ = vocab[self.id_field]
|
|
109
|
+
if id_ in ids:
|
|
110
|
+
labels[id_] = self._vocab_to_label(vocab)
|
|
67
111
|
except NoResultFound:
|
|
68
112
|
raise FacetNotFoundError(self.vocabulary)
|
|
69
113
|
|
|
70
|
-
labels = {}
|
|
71
|
-
vocab_list = list(vocabs.hits) # the service returns a generator
|
|
72
|
-
ids = set(ids)
|
|
73
|
-
seen = set()
|
|
74
|
-
for vocab in vocab_list:
|
|
75
|
-
# cannot loop over ids because vocab id is inside each item
|
|
76
|
-
if len(ids) == len(seen):
|
|
77
|
-
break
|
|
78
|
-
|
|
79
|
-
id_ = vocab[self.id_field]
|
|
80
|
-
if id_ in ids:
|
|
81
|
-
labels[id_] = self._vocab_to_label(vocab)
|
|
82
|
-
seen.add(id_)
|
|
83
|
-
|
|
84
114
|
return labels
|
|
@@ -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
|
|
@@ -21,3 +21,5 @@ class PermissionPolicy(RecordPermissionPolicy):
|
|
|
21
21
|
can_update = [SystemProcess()]
|
|
22
22
|
can_delete = [SystemProcess()]
|
|
23
23
|
can_manage = [SystemProcess()]
|
|
24
|
+
# this permission is needed for the /api/vocabularies/ endpoint
|
|
25
|
+
can_list_vocabularies = [SystemProcess(), AnyUser()]
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2024 CERN.
|
|
4
|
+
# Copyright (C) 2024 Uni Münster.
|
|
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
|
+
|
|
10
|
+
"""Vocabulary results."""
|
|
11
|
+
|
|
12
|
+
from flask import current_app
|
|
13
|
+
from invenio_records_resources.proxies import current_service_registry
|
|
14
|
+
from invenio_records_resources.services import RecordServiceConfig
|
|
15
|
+
from invenio_records_resources.services.records.results import RecordList
|
|
16
|
+
from invenio_search import current_search_client
|
|
17
|
+
|
|
18
|
+
from ..proxies import current_service
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class VocabularyTypeList(RecordList):
|
|
22
|
+
"""Ensures that vocabulary type metadata is returned in the proper format."""
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def total(self):
|
|
26
|
+
"""Get total number of hits."""
|
|
27
|
+
return self._results.total
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def custom_vocabulary_names(self):
|
|
31
|
+
"""Checks whether vocabulary is a custom vocabulary."""
|
|
32
|
+
return current_app.config.get("VOCABULARIES_CUSTOM_VOCABULARY_TYPES", [])
|
|
33
|
+
|
|
34
|
+
def to_dict(self):
|
|
35
|
+
"""Formats result to a dict of hits."""
|
|
36
|
+
config_vocab_types = current_app.config.get(
|
|
37
|
+
"INVENIO_VOCABULARY_TYPE_METADATA", {}
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
count_terms_agg = {}
|
|
41
|
+
generic_stats = self._generic_vocabulary_statistics()
|
|
42
|
+
custom_stats = self._custom_vocabulary_statistics()
|
|
43
|
+
|
|
44
|
+
for k in generic_stats.keys() | custom_stats.keys():
|
|
45
|
+
count_terms_agg[k] = generic_stats.get(k, 0) + custom_stats.get(k, 0)
|
|
46
|
+
|
|
47
|
+
hits = self._results.items
|
|
48
|
+
|
|
49
|
+
# Extend database data with configuration & aggregation data.
|
|
50
|
+
results = []
|
|
51
|
+
for db_vocab_type in hits:
|
|
52
|
+
result = {
|
|
53
|
+
"id": db_vocab_type.id,
|
|
54
|
+
"pid_type": db_vocab_type.pid_type,
|
|
55
|
+
"count": count_terms_agg.get(db_vocab_type.id, 0),
|
|
56
|
+
"is_custom_vocabulary": db_vocab_type.id
|
|
57
|
+
in self.custom_vocabulary_names,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if db_vocab_type.id in config_vocab_types:
|
|
61
|
+
for k, v in config_vocab_types[db_vocab_type.id].items():
|
|
62
|
+
result[k] = v
|
|
63
|
+
|
|
64
|
+
results.append(result)
|
|
65
|
+
|
|
66
|
+
for hit in results:
|
|
67
|
+
if self._links_item_tpl:
|
|
68
|
+
hit["links"] = self._links_item_tpl.expand(self._identity, hit)
|
|
69
|
+
|
|
70
|
+
res = {
|
|
71
|
+
"hits": {
|
|
72
|
+
"hits": results,
|
|
73
|
+
"total": self.total,
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if self._params:
|
|
78
|
+
if self._links_tpl:
|
|
79
|
+
res["links"] = self._links_tpl.expand(self._identity, self.pagination)
|
|
80
|
+
|
|
81
|
+
return res
|
|
82
|
+
|
|
83
|
+
def _custom_vocabulary_statistics(self):
|
|
84
|
+
# query database for count of terms in custom vocabularies
|
|
85
|
+
returndict = {}
|
|
86
|
+
for vocab_type in self.custom_vocabulary_names:
|
|
87
|
+
custom_service = current_service_registry.get(vocab_type)
|
|
88
|
+
record_cls = custom_service.config.record_cls
|
|
89
|
+
returndict[vocab_type] = record_cls.model_cls.query.count()
|
|
90
|
+
|
|
91
|
+
return returndict
|
|
92
|
+
|
|
93
|
+
def _generic_vocabulary_statistics(self):
|
|
94
|
+
# Opensearch query for generic vocabularies
|
|
95
|
+
config: RecordServiceConfig = (
|
|
96
|
+
current_service.config
|
|
97
|
+
) # TODO: Where to get the config from here? current_service is None
|
|
98
|
+
search_opts = config.search
|
|
99
|
+
|
|
100
|
+
search = search_opts.search_cls(
|
|
101
|
+
using=current_search_client,
|
|
102
|
+
index=config.record_cls.index.search_alias,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
search.aggs.bucket("vocabularies", {"terms": {"field": "type.id", "size": 100}})
|
|
106
|
+
|
|
107
|
+
search_result = search.execute()
|
|
108
|
+
buckets = search_result.aggs.to_dict()["vocabularies"]["buckets"]
|
|
109
|
+
|
|
110
|
+
return {bucket["key"]: bucket["doc_count"] for bucket in buckets}
|
|
@@ -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
|
|
@@ -14,6 +14,8 @@ from marshmallow import (
|
|
|
14
14
|
Schema,
|
|
15
15
|
ValidationError,
|
|
16
16
|
fields,
|
|
17
|
+
post_load,
|
|
18
|
+
pre_dump,
|
|
17
19
|
pre_load,
|
|
18
20
|
validate,
|
|
19
21
|
validates_schema,
|
|
@@ -33,6 +35,9 @@ class BaseVocabularyRelationSchema(Schema):
|
|
|
33
35
|
|
|
34
36
|
id = SanitizedUnicode(required=True)
|
|
35
37
|
|
|
38
|
+
# Nested field type for administration UI form generation
|
|
39
|
+
administration_schema_type = "vocabulary"
|
|
40
|
+
|
|
36
41
|
|
|
37
42
|
class VocabularyRelationSchema(BaseVocabularyRelationSchema):
|
|
38
43
|
"""Vocabulary relation schema."""
|
|
@@ -61,6 +66,9 @@ class ContribVocabularyRelationSchema(Schema):
|
|
|
61
66
|
ftf_name = None # free text field name
|
|
62
67
|
parent_field_name = None
|
|
63
68
|
|
|
69
|
+
# Nested field type for administration UI form generation
|
|
70
|
+
administration_schema_type = "vocabulary"
|
|
71
|
+
|
|
64
72
|
@validates_schema
|
|
65
73
|
def validate_relation_schema(self, data, **kwargs):
|
|
66
74
|
"""Validates that either id either the free text field are present."""
|
|
@@ -88,16 +96,45 @@ class BaseVocabularySchema(BaseRecordSchema):
|
|
|
88
96
|
title = i18n_strings
|
|
89
97
|
description = i18n_strings
|
|
90
98
|
icon = fields.Str(allow_none=False)
|
|
99
|
+
tags = fields.List(SanitizedUnicode())
|
|
100
|
+
|
|
101
|
+
# Nested field type for administration UI form generation
|
|
102
|
+
administration_schema_type = "vocabulary"
|
|
91
103
|
|
|
92
104
|
|
|
93
105
|
class VocabularySchema(BaseVocabularySchema):
|
|
94
106
|
"""Service schema for vocabulary records."""
|
|
95
107
|
|
|
96
108
|
props = fields.Dict(allow_none=False, keys=fields.Str(), values=fields.Str())
|
|
97
|
-
tags = fields.List(SanitizedUnicode())
|
|
98
109
|
type = fields.Str(attribute="type.id", required=True)
|
|
99
110
|
|
|
100
111
|
|
|
112
|
+
class ModePIDFieldVocabularyMixin:
|
|
113
|
+
"""Mixin for vocabularies using a model field for their PID."""
|
|
114
|
+
|
|
115
|
+
@validates_schema
|
|
116
|
+
def validate_id(self, data, **kwargs):
|
|
117
|
+
"""Validates ID."""
|
|
118
|
+
is_create = "record" not in self.context
|
|
119
|
+
if is_create and "id" not in data:
|
|
120
|
+
raise ValidationError(_("Missing PID."), "id")
|
|
121
|
+
if not is_create:
|
|
122
|
+
data.pop("id", None)
|
|
123
|
+
|
|
124
|
+
@post_load(pass_many=False)
|
|
125
|
+
def move_id(self, data, **kwargs):
|
|
126
|
+
"""Moves id to pid."""
|
|
127
|
+
if "id" in data:
|
|
128
|
+
data["pid"] = data.pop("id")
|
|
129
|
+
return data
|
|
130
|
+
|
|
131
|
+
@pre_dump(pass_many=False)
|
|
132
|
+
def extract_pid_value(self, data, **kwargs):
|
|
133
|
+
"""Extracts the PID value."""
|
|
134
|
+
data["id"] = data.pid.pid_value
|
|
135
|
+
return data
|
|
136
|
+
|
|
137
|
+
|
|
101
138
|
class DatastreamObject(Schema):
|
|
102
139
|
"""Datastream object (reader, transformer, writer)."""
|
|
103
140
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
#
|
|
3
|
-
# Copyright (C)
|
|
3
|
+
# Copyright (C) 2024 CERN.
|
|
4
4
|
# Copyright (C) 2021 Northwestern University.
|
|
5
|
+
# Copyright (C) 2024 University of Münster.
|
|
5
6
|
#
|
|
6
7
|
# Invenio-Vocabularies is free software; you can redistribute it and/or
|
|
7
8
|
# modify it under the terms of the MIT License; see LICENSE file for more
|
|
@@ -9,108 +10,59 @@
|
|
|
9
10
|
|
|
10
11
|
"""Vocabulary service."""
|
|
11
12
|
|
|
13
|
+
import sqlalchemy as sa
|
|
12
14
|
from invenio_cache import current_cache
|
|
13
|
-
from
|
|
14
|
-
from
|
|
15
|
-
from invenio_records_resources.services import (
|
|
16
|
-
Link,
|
|
17
|
-
LinksTemplate,
|
|
18
|
-
RecordService,
|
|
19
|
-
RecordServiceConfig,
|
|
20
|
-
SearchOptions,
|
|
21
|
-
pagination_links,
|
|
22
|
-
)
|
|
23
|
-
from invenio_records_resources.services.records.components import DataComponent
|
|
24
|
-
from invenio_records_resources.services.records.params import (
|
|
25
|
-
FilterParam,
|
|
26
|
-
SuggestQueryParser,
|
|
27
|
-
)
|
|
15
|
+
from invenio_records_resources.services import LinksTemplate, RecordService
|
|
16
|
+
from invenio_records_resources.services.base.utils import map_search_params
|
|
28
17
|
from invenio_records_resources.services.records.schema import ServiceSchemaWrapper
|
|
29
18
|
from invenio_records_resources.services.uow import unit_of_work
|
|
30
19
|
from invenio_search.engine import dsl
|
|
31
20
|
|
|
32
|
-
from ..records.api import Vocabulary
|
|
33
21
|
from ..records.models import VocabularyType
|
|
34
|
-
from .components import PIDComponent, VocabularyTypeComponent
|
|
35
|
-
from .permissions import PermissionPolicy
|
|
36
|
-
from .schema import TaskSchema, VocabularySchema
|
|
37
22
|
from .tasks import process_datastream
|
|
38
23
|
|
|
39
24
|
|
|
40
|
-
class
|
|
41
|
-
"""
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
]
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
title=_("Newest"),
|
|
73
|
-
fields=["-created"],
|
|
74
|
-
),
|
|
75
|
-
"oldest": dict(
|
|
76
|
-
title=_("Oldest"),
|
|
77
|
-
fields=["created"],
|
|
78
|
-
),
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
class VocabulariesServiceConfig(RecordServiceConfig):
|
|
83
|
-
"""Vocabulary service configuration."""
|
|
84
|
-
|
|
85
|
-
service_id = "vocabularies"
|
|
86
|
-
indexer_queue_name = "vocabularies"
|
|
87
|
-
permission_policy_cls = PermissionPolicy
|
|
88
|
-
record_cls = Vocabulary
|
|
89
|
-
schema = VocabularySchema
|
|
90
|
-
task_schema = TaskSchema
|
|
91
|
-
|
|
92
|
-
search = VocabularySearchOptions
|
|
93
|
-
|
|
94
|
-
components = [
|
|
95
|
-
# Order of components are important!
|
|
96
|
-
VocabularyTypeComponent,
|
|
97
|
-
DataComponent,
|
|
98
|
-
PIDComponent,
|
|
99
|
-
]
|
|
100
|
-
|
|
101
|
-
links_item = {
|
|
102
|
-
"self": Link(
|
|
103
|
-
"{+api}/vocabularies/{type}/{id}",
|
|
104
|
-
vars=lambda record, vars: vars.update(
|
|
105
|
-
{
|
|
106
|
-
"id": record.pid.pid_value,
|
|
107
|
-
"type": record.type.id,
|
|
108
|
-
}
|
|
109
|
-
),
|
|
110
|
-
),
|
|
111
|
-
}
|
|
25
|
+
class VocabularyTypeService(RecordService):
|
|
26
|
+
"""Vocabulary type service."""
|
|
27
|
+
|
|
28
|
+
def rebuild_index(self, identity, uow=None):
|
|
29
|
+
"""Raise error since services are not backed by search indices."""
|
|
30
|
+
raise NotImplementedError()
|
|
31
|
+
|
|
32
|
+
def search(self, identity, params=None):
|
|
33
|
+
"""Search for vocabulary types entries."""
|
|
34
|
+
self.require_permission(identity, "list_vocabularies")
|
|
35
|
+
|
|
36
|
+
search_params = map_search_params(self.config.search, params)
|
|
37
|
+
|
|
38
|
+
query_param = search_params["q"]
|
|
39
|
+
|
|
40
|
+
filters = []
|
|
41
|
+
if query_param:
|
|
42
|
+
filters.extend([VocabularyType.id.ilike(f"%{query_param}%")])
|
|
43
|
+
|
|
44
|
+
vocabulary_types = (
|
|
45
|
+
VocabularyType.query.filter(sa.or_(*filters))
|
|
46
|
+
.order_by(
|
|
47
|
+
search_params["sort_direction"](
|
|
48
|
+
sa.text(",".join(search_params["sort"]))
|
|
49
|
+
)
|
|
50
|
+
)
|
|
51
|
+
.paginate(
|
|
52
|
+
page=search_params["page"],
|
|
53
|
+
per_page=search_params["size"],
|
|
54
|
+
error_out=False,
|
|
55
|
+
)
|
|
56
|
+
)
|
|
112
57
|
|
|
113
|
-
|
|
58
|
+
return self.config.result_list_cls(
|
|
59
|
+
self,
|
|
60
|
+
identity,
|
|
61
|
+
vocabulary_types,
|
|
62
|
+
search_params,
|
|
63
|
+
links_tpl=LinksTemplate(self.config.links_search, context={"args": params}),
|
|
64
|
+
links_item_tpl=self.links_item_tpl,
|
|
65
|
+
)
|
|
114
66
|
|
|
115
67
|
|
|
116
68
|
class VocabulariesService(RecordService):
|
|
@@ -145,7 +97,7 @@ class VocabulariesService(RecordService):
|
|
|
145
97
|
params,
|
|
146
98
|
search_preference,
|
|
147
99
|
extra_filter=dsl.Q("term", type__id=vocabulary_type.id),
|
|
148
|
-
**kwargs
|
|
100
|
+
**kwargs,
|
|
149
101
|
).execute()
|
|
150
102
|
|
|
151
103
|
return self.result_list(
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{#
|
|
2
|
+
Copyright (C) 2024 CERN.
|
|
3
|
+
|
|
4
|
+
Invenio RDM Records is free software; you can redistribute it and/or modify
|
|
5
|
+
it under the terms of the MIT License; see LICENSE file for more details.
|
|
6
|
+
#}
|
|
7
|
+
|
|
8
|
+
{%- set subjects = field_value -%}
|
|
9
|
+
{% if subjects %}
|
|
10
|
+
<ul class="ui horizontal list no-bullets subjects">
|
|
11
|
+
{%- for subject in subjects %}
|
|
12
|
+
<li class="item">
|
|
13
|
+
{%- set q = 'metadata.subjects.subject:"' + subject.subject + '"' %}
|
|
14
|
+
<a href="{{ url_for('invenio_search_ui.search', q=q) }}"
|
|
15
|
+
class="subject"
|
|
16
|
+
title="{{ _('Search results for ') + subject.subject }}"
|
|
17
|
+
>
|
|
18
|
+
{{ subject.subject }}
|
|
19
|
+
</a>
|
|
20
|
+
</li>
|
|
21
|
+
{%- endfor %}
|
|
22
|
+
</ul>
|
|
23
|
+
{% endif %}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{#
|
|
2
|
+
Copyright (C) 2024 Uni Münster.
|
|
3
|
+
|
|
4
|
+
Invenio App RDM is free software; you can redistribute it and/or modify it
|
|
5
|
+
under the terms of the MIT License; see LICENSE file for more details.
|
|
6
|
+
#}
|
|
7
|
+
{% extends "invenio_administration/search.html" %}
|
|
8
|
+
|
|
9
|
+
{% block javascript %}
|
|
10
|
+
{{ super() }}
|
|
11
|
+
{{ webpack['invenio-vocabularies-search.js'] }}
|
|
12
|
+
{% endblock %}
|