oarepo-runtime 1.10.3__py3-none-any.whl → 2.0.0.dev4__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.
- oarepo_runtime/__init__.py +24 -0
- oarepo_runtime/api.py +210 -0
- oarepo_runtime/cli/__init__.py +10 -21
- oarepo_runtime/cli/search.py +34 -0
- oarepo_runtime/config.py +98 -13
- oarepo_runtime/ext.py +64 -82
- oarepo_runtime/proxies.py +21 -5
- oarepo_runtime/records/__init__.py +11 -50
- oarepo_runtime/records/drafts.py +24 -18
- oarepo_runtime/records/mapping.py +84 -0
- oarepo_runtime/records/pid_providers.py +43 -7
- oarepo_runtime/records/systemfields/__init__.py +15 -33
- oarepo_runtime/records/systemfields/mapping.py +41 -24
- oarepo_runtime/records/systemfields/publication_status.py +61 -0
- oarepo_runtime/services/__init__.py +12 -0
- oarepo_runtime/services/config/__init__.py +15 -21
- oarepo_runtime/services/config/link_conditions.py +69 -75
- oarepo_runtime/services/config/permissions.py +62 -0
- oarepo_runtime/services/facets/__init__.py +12 -33
- oarepo_runtime/services/facets/params.py +45 -110
- oarepo_runtime/services/records/__init__.py +14 -1
- oarepo_runtime/services/records/links.py +21 -11
- oarepo_runtime/services/records/mapping.py +42 -0
- oarepo_runtime/services/results.py +98 -109
- oarepo_runtime/services/schema/__init__.py +12 -44
- oarepo_runtime/services/schema/i18n.py +47 -22
- oarepo_runtime/services/schema/i18n_ui.py +61 -24
- {oarepo_runtime-1.10.3.dist-info → oarepo_runtime-2.0.0.dev4.dist-info}/METADATA +10 -21
- oarepo_runtime-2.0.0.dev4.dist-info/RECORD +32 -0
- {oarepo_runtime-1.10.3.dist-info → oarepo_runtime-2.0.0.dev4.dist-info}/WHEEL +1 -2
- oarepo_runtime-2.0.0.dev4.dist-info/entry_points.txt +5 -0
- oarepo_runtime/cli/assets.py +0 -145
- oarepo_runtime/cli/base.py +0 -25
- oarepo_runtime/cli/cf.py +0 -15
- oarepo_runtime/cli/check.py +0 -167
- oarepo_runtime/cli/configuration.py +0 -51
- oarepo_runtime/cli/fixtures.py +0 -167
- oarepo_runtime/cli/index.py +0 -272
- oarepo_runtime/cli/permissions/__init__.py +0 -6
- oarepo_runtime/cli/permissions/base.py +0 -26
- oarepo_runtime/cli/permissions/evaluate.py +0 -63
- oarepo_runtime/cli/permissions/list.py +0 -239
- oarepo_runtime/cli/permissions/search.py +0 -121
- oarepo_runtime/cli/validate.py +0 -150
- oarepo_runtime/datastreams/__init__.py +0 -38
- oarepo_runtime/datastreams/asynchronous.py +0 -247
- oarepo_runtime/datastreams/catalogue.py +0 -150
- oarepo_runtime/datastreams/datastreams.py +0 -152
- oarepo_runtime/datastreams/errors.py +0 -54
- oarepo_runtime/datastreams/ext.py +0 -41
- oarepo_runtime/datastreams/fixtures.py +0 -265
- oarepo_runtime/datastreams/json.py +0 -4
- oarepo_runtime/datastreams/readers/__init__.py +0 -39
- oarepo_runtime/datastreams/readers/attachments.py +0 -51
- oarepo_runtime/datastreams/readers/excel.py +0 -123
- oarepo_runtime/datastreams/readers/json.py +0 -27
- oarepo_runtime/datastreams/readers/service.py +0 -54
- oarepo_runtime/datastreams/readers/yaml.py +0 -14
- oarepo_runtime/datastreams/semi_asynchronous.py +0 -91
- oarepo_runtime/datastreams/synchronous.py +0 -70
- oarepo_runtime/datastreams/transformers.py +0 -18
- oarepo_runtime/datastreams/types.py +0 -323
- oarepo_runtime/datastreams/utils.py +0 -131
- oarepo_runtime/datastreams/writers/__init__.py +0 -21
- oarepo_runtime/datastreams/writers/attachments_file.py +0 -92
- oarepo_runtime/datastreams/writers/attachments_service.py +0 -118
- oarepo_runtime/datastreams/writers/publish.py +0 -70
- oarepo_runtime/datastreams/writers/service.py +0 -175
- oarepo_runtime/datastreams/writers/utils.py +0 -30
- oarepo_runtime/datastreams/writers/validation_errors.py +0 -20
- oarepo_runtime/datastreams/writers/yaml.py +0 -56
- oarepo_runtime/ext_config.py +0 -67
- oarepo_runtime/i18n/__init__.py +0 -3
- oarepo_runtime/info/__init__.py +0 -0
- oarepo_runtime/info/check.py +0 -95
- oarepo_runtime/info/permissions/__init__.py +0 -0
- oarepo_runtime/info/permissions/debug.py +0 -191
- oarepo_runtime/info/views.py +0 -586
- oarepo_runtime/profile.py +0 -60
- oarepo_runtime/records/dumpers/__init__.py +0 -8
- oarepo_runtime/records/dumpers/edtf_interval.py +0 -38
- oarepo_runtime/records/dumpers/multilingual_dumper.py +0 -34
- oarepo_runtime/records/entity_resolvers/__init__.py +0 -13
- oarepo_runtime/records/entity_resolvers/proxies.py +0 -57
- oarepo_runtime/records/mappings/__init__.py +0 -0
- oarepo_runtime/records/mappings/rdm_parent_mapping.json +0 -483
- oarepo_runtime/records/owners/__init__.py +0 -3
- oarepo_runtime/records/owners/registry.py +0 -22
- oarepo_runtime/records/relations/__init__.py +0 -22
- oarepo_runtime/records/relations/base.py +0 -296
- oarepo_runtime/records/relations/internal.py +0 -46
- oarepo_runtime/records/relations/lookup.py +0 -28
- oarepo_runtime/records/relations/pid_relation.py +0 -102
- oarepo_runtime/records/systemfields/featured_file.py +0 -45
- oarepo_runtime/records/systemfields/has_draftcheck.py +0 -47
- oarepo_runtime/records/systemfields/icu.py +0 -371
- oarepo_runtime/records/systemfields/owner.py +0 -115
- oarepo_runtime/records/systemfields/record_status.py +0 -35
- oarepo_runtime/records/systemfields/selectors.py +0 -98
- oarepo_runtime/records/systemfields/synthetic.py +0 -130
- oarepo_runtime/resources/__init__.py +0 -4
- oarepo_runtime/resources/config.py +0 -12
- oarepo_runtime/resources/file_resource.py +0 -15
- oarepo_runtime/resources/json_serializer.py +0 -27
- oarepo_runtime/resources/localized_ui_json_serializer.py +0 -54
- oarepo_runtime/resources/resource.py +0 -53
- oarepo_runtime/resources/responses.py +0 -20
- oarepo_runtime/services/components.py +0 -429
- oarepo_runtime/services/config/draft_link.py +0 -23
- oarepo_runtime/services/config/permissions_presets.py +0 -174
- oarepo_runtime/services/config/service.py +0 -117
- oarepo_runtime/services/custom_fields/__init__.py +0 -80
- oarepo_runtime/services/custom_fields/mappings.py +0 -188
- oarepo_runtime/services/entity/__init__.py +0 -0
- oarepo_runtime/services/entity/config.py +0 -14
- oarepo_runtime/services/entity/schema.py +0 -9
- oarepo_runtime/services/entity/service.py +0 -48
- oarepo_runtime/services/expansions/__init__.py +0 -0
- oarepo_runtime/services/expansions/expandable_fields.py +0 -21
- oarepo_runtime/services/expansions/service.py +0 -4
- oarepo_runtime/services/facets/base.py +0 -12
- oarepo_runtime/services/facets/date.py +0 -72
- oarepo_runtime/services/facets/enum.py +0 -11
- oarepo_runtime/services/facets/facet_groups_names.py +0 -17
- oarepo_runtime/services/facets/max_facet.py +0 -13
- oarepo_runtime/services/facets/multilingual_facet.py +0 -33
- oarepo_runtime/services/facets/nested_facet.py +0 -32
- oarepo_runtime/services/facets/year_histogram.py +0 -200
- oarepo_runtime/services/files/__init__.py +0 -8
- oarepo_runtime/services/files/components.py +0 -62
- oarepo_runtime/services/files/service.py +0 -16
- oarepo_runtime/services/generators.py +0 -10
- oarepo_runtime/services/permissions/__init__.py +0 -3
- oarepo_runtime/services/permissions/generators.py +0 -103
- oarepo_runtime/services/relations/__init__.py +0 -0
- oarepo_runtime/services/relations/components.py +0 -15
- oarepo_runtime/services/relations/errors.py +0 -18
- oarepo_runtime/services/relations/mapping.py +0 -38
- oarepo_runtime/services/schema/cf.py +0 -13
- oarepo_runtime/services/schema/i18n_validation.py +0 -7
- oarepo_runtime/services/schema/marshmallow.py +0 -44
- oarepo_runtime/services/schema/marshmallow_to_json_schema.py +0 -72
- oarepo_runtime/services/schema/oneofschema.py +0 -192
- oarepo_runtime/services/schema/polymorphic.py +0 -21
- oarepo_runtime/services/schema/rdm.py +0 -146
- oarepo_runtime/services/schema/rdm_ui.py +0 -156
- oarepo_runtime/services/schema/ui.py +0 -251
- oarepo_runtime/services/schema/validation.py +0 -70
- oarepo_runtime/services/search.py +0 -282
- oarepo_runtime/services/service.py +0 -61
- oarepo_runtime/tasks.py +0 -6
- oarepo_runtime/translations/cs/LC_MESSAGES/messages.mo +0 -0
- oarepo_runtime/translations/cs/LC_MESSAGES/messages.po +0 -95
- oarepo_runtime/translations/default_translations.py +0 -6
- oarepo_runtime/translations/en/LC_MESSAGES/messages.mo +0 -0
- oarepo_runtime/translations/en/LC_MESSAGES/messages.po +0 -97
- oarepo_runtime/translations/messages.pot +0 -100
- oarepo_runtime/uow.py +0 -146
- oarepo_runtime/utils/__init__.py +0 -0
- oarepo_runtime/utils/functools.py +0 -37
- oarepo_runtime/utils/identity_utils.py +0 -35
- oarepo_runtime/utils/index.py +0 -11
- oarepo_runtime/utils/path.py +0 -97
- oarepo_runtime-1.10.3.dist-info/RECORD +0 -163
- oarepo_runtime-1.10.3.dist-info/entry_points.txt +0 -16
- oarepo_runtime-1.10.3.dist-info/top_level.txt +0 -2
- tests/marshmallow_to_json/__init__.py +0 -0
- tests/marshmallow_to_json/test_datacite_ui_schema.py +0 -1410
- tests/marshmallow_to_json/test_simple_schema.py +0 -52
- tests/pkg_data/__init__.py +0 -0
- {oarepo_runtime-1.10.3.dist-info → oarepo_runtime-2.0.0.dev4.dist-info}/licenses/LICENSE +0 -0
@@ -1,192 +0,0 @@
|
|
1
|
-
import typing
|
2
|
-
|
3
|
-
from marshmallow import Schema, ValidationError
|
4
|
-
|
5
|
-
|
6
|
-
class OneOfSchema(Schema):
|
7
|
-
"""
|
8
|
-
This is a special kind of schema that actually multiplexes other schemas
|
9
|
-
based on object type. When serializing values, it uses get_obj_type() method
|
10
|
-
to get object type name. Then it uses `type_schemas` name-to-Schema mapping
|
11
|
-
to get schema for that particular object type, serializes object using that
|
12
|
-
schema and adds an extra "type" field with name of object type.
|
13
|
-
Deserialization is reverse.
|
14
|
-
|
15
|
-
Example:
|
16
|
-
|
17
|
-
class Foo(object):
|
18
|
-
def __init__(self, foo):
|
19
|
-
self.foo = foo
|
20
|
-
|
21
|
-
class Bar(object):
|
22
|
-
def __init__(self, bar):
|
23
|
-
self.bar = bar
|
24
|
-
|
25
|
-
class FooSchema(marshmallow.Schema):
|
26
|
-
foo = marshmallow.fields.String(required=True)
|
27
|
-
|
28
|
-
@marshmallow.post_load
|
29
|
-
def make_foo(self, data, **kwargs):
|
30
|
-
return Foo(**data)
|
31
|
-
|
32
|
-
class BarSchema(marshmallow.Schema):
|
33
|
-
bar = marshmallow.fields.Integer(required=True)
|
34
|
-
|
35
|
-
@marshmallow.post_load
|
36
|
-
def make_bar(self, data, **kwargs):
|
37
|
-
return Bar(**data)
|
38
|
-
|
39
|
-
class MyUberSchema(marshmallow.OneOfSchema):
|
40
|
-
type_schemas = {
|
41
|
-
'foo': FooSchema,
|
42
|
-
'bar': BarSchema,
|
43
|
-
}
|
44
|
-
|
45
|
-
def get_obj_type(self, obj):
|
46
|
-
if isinstance(obj, Foo):
|
47
|
-
return 'foo'
|
48
|
-
elif isinstance(obj, Bar):
|
49
|
-
return 'bar'
|
50
|
-
else:
|
51
|
-
raise Exception('Unknown object type: %s' % repr(obj))
|
52
|
-
|
53
|
-
MyUberSchema().dump([Foo(foo='hello'), Bar(bar=123)], many=True)
|
54
|
-
# => [{'type': 'foo', 'foo': 'hello'}, {'type': 'bar', 'bar': 123}]
|
55
|
-
|
56
|
-
You can control type field name added to serialized object representation by
|
57
|
-
setting `type_field` class property.
|
58
|
-
"""
|
59
|
-
|
60
|
-
type_field = "type"
|
61
|
-
type_field_remove = True
|
62
|
-
type_schemas: typing.Mapping[str, typing.Union[typing.Type[Schema], Schema]] = {}
|
63
|
-
|
64
|
-
def get_obj_type(self, obj):
|
65
|
-
"""Returns name of the schema during dump() calls, given the object
|
66
|
-
being dumped."""
|
67
|
-
return obj.__class__.__name__
|
68
|
-
|
69
|
-
def get_data_type(self, data):
|
70
|
-
"""Returns name of the schema during load() calls, given the data being
|
71
|
-
loaded. Defaults to looking up `type_field` in the data."""
|
72
|
-
data_type = data.get(self.type_field)
|
73
|
-
if self.type_field in data and self.type_field_remove:
|
74
|
-
data.pop(self.type_field)
|
75
|
-
return data_type
|
76
|
-
|
77
|
-
def dump(self, obj, *, many=None, **kwargs):
|
78
|
-
errors = {}
|
79
|
-
result_data = []
|
80
|
-
result_errors = {}
|
81
|
-
many = self.many if many is None else bool(many)
|
82
|
-
if not many:
|
83
|
-
result = result_data = self._dump(obj, **kwargs)
|
84
|
-
else:
|
85
|
-
for idx, o in enumerate(obj):
|
86
|
-
try:
|
87
|
-
result = self._dump(o, **kwargs)
|
88
|
-
result_data.append(result)
|
89
|
-
except ValidationError as error:
|
90
|
-
result_errors[idx] = error.normalized_messages()
|
91
|
-
result_data.append(error.valid_data)
|
92
|
-
|
93
|
-
result = result_data
|
94
|
-
errors = result_errors
|
95
|
-
|
96
|
-
if not errors:
|
97
|
-
return result
|
98
|
-
else:
|
99
|
-
exc = ValidationError(errors, data=obj, valid_data=result)
|
100
|
-
raise exc
|
101
|
-
|
102
|
-
def _dump(self, obj, *, update_fields=True, **kwargs):
|
103
|
-
obj_type = self.get_obj_type(obj)
|
104
|
-
if obj_type is None:
|
105
|
-
return (
|
106
|
-
None,
|
107
|
-
{"_schema": "Unknown object class: %s" % obj.__class__.__name__},
|
108
|
-
)
|
109
|
-
|
110
|
-
type_schema = self.type_schemas.get(obj_type)
|
111
|
-
if not type_schema:
|
112
|
-
return None, {"_schema": "Unsupported object type: %s" % obj_type}
|
113
|
-
|
114
|
-
schema = type_schema if isinstance(type_schema, Schema) else type_schema()
|
115
|
-
|
116
|
-
schema.context.update(getattr(self, "context", {}))
|
117
|
-
|
118
|
-
result = schema.dump(obj, many=False, **kwargs)
|
119
|
-
if result is not None:
|
120
|
-
result[self.type_field] = obj_type
|
121
|
-
return result
|
122
|
-
|
123
|
-
def load(self, data, *, many=None, partial=None, unknown=None, **kwargs):
|
124
|
-
errors = {}
|
125
|
-
result_data = []
|
126
|
-
result_errors = {}
|
127
|
-
many = self.many if many is None else bool(many)
|
128
|
-
if partial is None:
|
129
|
-
partial = self.partial
|
130
|
-
if not many:
|
131
|
-
try:
|
132
|
-
result_data = self._load(
|
133
|
-
data, partial=partial, unknown=unknown, **kwargs
|
134
|
-
)
|
135
|
-
except ValidationError as error:
|
136
|
-
result_errors = error.normalized_messages()
|
137
|
-
result_data = error.valid_data
|
138
|
-
else:
|
139
|
-
for idx, item in enumerate(data):
|
140
|
-
try:
|
141
|
-
result = self._load(item, partial=partial, **kwargs)
|
142
|
-
result_data.append(result)
|
143
|
-
except ValidationError as error:
|
144
|
-
result_errors[idx] = error.normalized_messages()
|
145
|
-
result_data.append(error.valid_data)
|
146
|
-
|
147
|
-
result = result_data
|
148
|
-
errors = result_errors
|
149
|
-
|
150
|
-
if not errors:
|
151
|
-
return result
|
152
|
-
else:
|
153
|
-
exc = ValidationError(errors, data=data, valid_data=result)
|
154
|
-
raise exc
|
155
|
-
|
156
|
-
def _load(self, data, *, partial=None, unknown=None, **kwargs):
|
157
|
-
if not isinstance(data, dict):
|
158
|
-
raise ValidationError({"_schema": "Invalid data type: %s" % data})
|
159
|
-
|
160
|
-
data = dict(data)
|
161
|
-
unknown = unknown or self.unknown
|
162
|
-
data_type = self.get_data_type(data)
|
163
|
-
|
164
|
-
if data_type is None:
|
165
|
-
raise ValidationError(
|
166
|
-
{self.type_field: ["Missing data for required field."]}
|
167
|
-
)
|
168
|
-
|
169
|
-
try:
|
170
|
-
type_schema = self.type_schemas.get(data_type)
|
171
|
-
except TypeError as error:
|
172
|
-
# data_type could be unhashable
|
173
|
-
raise ValidationError(
|
174
|
-
{self.type_field: ["Invalid value: %s" % data_type]}
|
175
|
-
) from error
|
176
|
-
if not type_schema:
|
177
|
-
raise ValidationError(
|
178
|
-
{self.type_field: ["Unsupported value: %s" % data_type]}
|
179
|
-
)
|
180
|
-
|
181
|
-
schema = type_schema if isinstance(type_schema, Schema) else type_schema()
|
182
|
-
|
183
|
-
schema.context.update(getattr(self, "context", {}))
|
184
|
-
|
185
|
-
return schema.load(data, many=False, partial=partial, unknown=unknown, **kwargs)
|
186
|
-
|
187
|
-
def validate(self, data, *, many=None, partial=None):
|
188
|
-
try:
|
189
|
-
self.load(data, many=many, partial=partial)
|
190
|
-
except ValidationError as ve:
|
191
|
-
return ve.messages
|
192
|
-
return {}
|
@@ -1,21 +0,0 @@
|
|
1
|
-
from functools import cached_property
|
2
|
-
|
3
|
-
import marshmallow as ma
|
4
|
-
|
5
|
-
# from marshmallow_oneofschema import OneOfSchema
|
6
|
-
from oarepo_runtime.services.schema.oneofschema import OneOfSchema
|
7
|
-
|
8
|
-
|
9
|
-
class PolymorphicSchema(OneOfSchema):
|
10
|
-
type_field_remove = False
|
11
|
-
|
12
|
-
def get_obj_type(self, obj):
|
13
|
-
return obj[self.type_field]
|
14
|
-
|
15
|
-
@cached_property
|
16
|
-
def type_schemas(self):
|
17
|
-
ret = {}
|
18
|
-
for key, fld in self.fields.items():
|
19
|
-
if isinstance(fld, ma.fields.Nested):
|
20
|
-
ret[fld.attribute or key] = type(fld.schema)
|
21
|
-
return ret
|
@@ -1,146 +0,0 @@
|
|
1
|
-
import re
|
2
|
-
from functools import partial
|
3
|
-
|
4
|
-
import marshmallow as ma
|
5
|
-
from invenio_access.permissions import system_identity
|
6
|
-
from invenio_i18n import gettext as _
|
7
|
-
from invenio_i18n.selectors import get_locale
|
8
|
-
from invenio_rdm_records.services.schemas.metadata import (
|
9
|
-
CreatorSchema,
|
10
|
-
record_identifiers_schemes,
|
11
|
-
)
|
12
|
-
from invenio_rdm_records.services.schemas.tombstone import DeletionStatusSchema
|
13
|
-
from invenio_rdm_records.services.schemas.versions import VersionsSchema
|
14
|
-
from invenio_records_resources.proxies import current_service_registry
|
15
|
-
from invenio_vocabularies.contrib.awards.schema import AwardRelationSchema
|
16
|
-
from invenio_vocabularies.contrib.funders.schema import FunderRelationSchema
|
17
|
-
from marshmallow import fields as ma_fields
|
18
|
-
from marshmallow import pre_load
|
19
|
-
from marshmallow_utils.fields import (
|
20
|
-
IdentifierSet,
|
21
|
-
)
|
22
|
-
from marshmallow_utils.fields.nestedattr import NestedAttribute
|
23
|
-
from marshmallow_utils.schemas.identifier import IdentifierSchema
|
24
|
-
|
25
|
-
from .i18n import MultilingualField
|
26
|
-
|
27
|
-
|
28
|
-
class RDMRecordMixin(ma.Schema):
|
29
|
-
versions = NestedAttribute(VersionsSchema, dump_only=True)
|
30
|
-
deletion_status = ma_fields.Nested(DeletionStatusSchema, dump_only=True)
|
31
|
-
|
32
|
-
|
33
|
-
class MultilingualAwardSchema(AwardRelationSchema):
|
34
|
-
class Meta:
|
35
|
-
unknown = ma.RAISE
|
36
|
-
|
37
|
-
@pre_load()
|
38
|
-
def convert_to_multilingual(self, data, many, **kwargs):
|
39
|
-
if "title" in data and type(data["title"]) is str:
|
40
|
-
lang = get_locale()
|
41
|
-
data["title"] = {lang: data["title"]}
|
42
|
-
return data
|
43
|
-
|
44
|
-
|
45
|
-
class FundingSchema(ma.Schema):
|
46
|
-
"""Funding schema."""
|
47
|
-
|
48
|
-
funder = ma_fields.Nested(FunderRelationSchema, required=True)
|
49
|
-
award = ma_fields.Nested(MultilingualAwardSchema)
|
50
|
-
|
51
|
-
|
52
|
-
class RecordIdentifierField(IdentifierSet):
|
53
|
-
def __init__(self, *args, **kwargs):
|
54
|
-
super().__init__(
|
55
|
-
ma.fields.Nested(
|
56
|
-
partial(IdentifierSchema, allowed_schemes=record_identifiers_schemes)
|
57
|
-
),
|
58
|
-
*args,
|
59
|
-
**kwargs,
|
60
|
-
)
|
61
|
-
|
62
|
-
|
63
|
-
class RelatedRecordIdentifierField(IdentifierSet):
|
64
|
-
def __init__(self, *args, **kwargs):
|
65
|
-
super().__init__(
|
66
|
-
ma.fields.Nested(
|
67
|
-
partial(IdentifierSchema, allowed_schemes=record_identifiers_schemes)
|
68
|
-
),
|
69
|
-
*args,
|
70
|
-
**kwargs,
|
71
|
-
)
|
72
|
-
|
73
|
-
|
74
|
-
class RDMSubjectSchema(ma.Schema):
|
75
|
-
"""Subject ui schema."""
|
76
|
-
|
77
|
-
class Meta:
|
78
|
-
unknown = ma.RAISE
|
79
|
-
|
80
|
-
_id = ma.fields.String(data_key="id")
|
81
|
-
|
82
|
-
subject = MultilingualField()
|
83
|
-
|
84
|
-
|
85
|
-
class RDMNTKCreatorsSchema(CreatorSchema):
|
86
|
-
"""NTK version of RDM creators schema.
|
87
|
-
|
88
|
-
This version makes sure that organizations are selected from the
|
89
|
-
list of organizations in the system. Record will not be valid if
|
90
|
-
organization is not in the system.
|
91
|
-
"""
|
92
|
-
|
93
|
-
@ma.validates_schema
|
94
|
-
def check_organization_or_affiliation(self, data, **kwargs):
|
95
|
-
"""Check if organization is in the system."""
|
96
|
-
person_or_org = data.get("person_or_org", {})
|
97
|
-
if person_or_org.get("type") == "personal":
|
98
|
-
affiliations = data.get("affiliations", [])
|
99
|
-
for affiliation in affiliations:
|
100
|
-
if not self.from_vocabulary(affiliation):
|
101
|
-
raise ma.ValidationError(
|
102
|
-
_(
|
103
|
-
"It is necessary to choose organization from the controlled vocabulary. "
|
104
|
-
"To add organization, please go to "
|
105
|
-
"https://nusl.techlib.cz/cs/migrace-nusl/navrh-novych-hesel/"
|
106
|
-
),
|
107
|
-
field_name="affiliations",
|
108
|
-
)
|
109
|
-
else:
|
110
|
-
# organization
|
111
|
-
name = person_or_org.get("name")
|
112
|
-
affiliations = current_service_registry.get("affiliations")
|
113
|
-
found = [
|
114
|
-
x["name"]
|
115
|
-
for x in affiliations.search(
|
116
|
-
system_identity,
|
117
|
-
q=f'name.suggest:"{escape_opensearch_query(name)}"',
|
118
|
-
size=100,
|
119
|
-
).hits
|
120
|
-
]
|
121
|
-
if name not in found:
|
122
|
-
raise ma.ValidationError(
|
123
|
-
_(
|
124
|
-
"It is necessary to choose organization from the controlled vocabulary. "
|
125
|
-
"To add organization, please go to "
|
126
|
-
"https://nusl.techlib.cz/cs/migrace-nusl/navrh-novych-hesel/"
|
127
|
-
),
|
128
|
-
field_name="person_or_org",
|
129
|
-
)
|
130
|
-
return data
|
131
|
-
|
132
|
-
def from_vocabulary(self, affiliation):
|
133
|
-
"""Check if affiliation is from the vocabulary."""
|
134
|
-
if "id" not in affiliation:
|
135
|
-
return False
|
136
|
-
return True
|
137
|
-
|
138
|
-
|
139
|
-
def escape_opensearch_query(value: str) -> str:
|
140
|
-
"""
|
141
|
-
Escapes special characters in a string for safe use in OpenSearch query syntax.
|
142
|
-
"""
|
143
|
-
# Escape each special character with a backslash
|
144
|
-
escaped = re.sub(r'([\\+\-=&|><!(){}\[\]^"~*?:/])', r"\\\1", value)
|
145
|
-
|
146
|
-
return escaped
|
@@ -1,156 +0,0 @@
|
|
1
|
-
import marshmallow as ma
|
2
|
-
from idutils import to_url
|
3
|
-
from oarepo_vocabularies.services.ui_schema import VocabularyI18nStrUIField
|
4
|
-
|
5
|
-
from oarepo_runtime.services.schema.marshmallow import DictOnlySchema
|
6
|
-
|
7
|
-
from .i18n_ui import MultilingualUIField
|
8
|
-
|
9
|
-
|
10
|
-
class RDMIdentifierWithSchemaUISchema(ma.Schema):
|
11
|
-
scheme = ma.fields.String(
|
12
|
-
required=True,
|
13
|
-
)
|
14
|
-
identifier = ma.fields.String(required=True)
|
15
|
-
|
16
|
-
@ma.post_dump
|
17
|
-
def add_url(self, value, **kwargs):
|
18
|
-
try:
|
19
|
-
# ignore errors here
|
20
|
-
if "identifier" in value and "scheme" in value:
|
21
|
-
url = to_url(
|
22
|
-
value["identifier"], value["scheme"].lower(), url_scheme="https"
|
23
|
-
)
|
24
|
-
if url:
|
25
|
-
value["url"] = url
|
26
|
-
except Exception:
|
27
|
-
pass
|
28
|
-
return value
|
29
|
-
|
30
|
-
|
31
|
-
class RDMAwardIdentifierUISchema(ma.Schema):
|
32
|
-
identifier = ma.fields.String()
|
33
|
-
|
34
|
-
|
35
|
-
class RDMAwardSubjectUISchema(ma.Schema):
|
36
|
-
_id = ma.fields.String(data_key="id")
|
37
|
-
|
38
|
-
subject = ma.fields.String()
|
39
|
-
|
40
|
-
|
41
|
-
class RDMAwardOrganizationUISchema(ma.Schema):
|
42
|
-
schema = ma.fields.String()
|
43
|
-
|
44
|
-
_id = ma.fields.String(data_key="id")
|
45
|
-
|
46
|
-
organization = ma.fields.String()
|
47
|
-
|
48
|
-
|
49
|
-
class RDMFunderVocabularyUISchema(DictOnlySchema):
|
50
|
-
class Meta:
|
51
|
-
unknown = ma.INCLUDE
|
52
|
-
|
53
|
-
_id = ma.fields.String(data_key="id", attribute="id")
|
54
|
-
|
55
|
-
_version = ma.fields.String(data_key="@v", attribute="@v")
|
56
|
-
|
57
|
-
name = ma.fields.String()
|
58
|
-
|
59
|
-
identifiers = ma.fields.List(ma.fields.Nested(RDMIdentifierWithSchemaUISchema()))
|
60
|
-
|
61
|
-
|
62
|
-
class RDMRoleVocabularyUISchema(DictOnlySchema):
|
63
|
-
class Meta:
|
64
|
-
unknown = ma.INCLUDE
|
65
|
-
|
66
|
-
_id = ma.fields.String(data_key="id", attribute="id")
|
67
|
-
|
68
|
-
_version = ma.fields.String(data_key="@v", attribute="@v")
|
69
|
-
|
70
|
-
title = VocabularyI18nStrUIField()
|
71
|
-
|
72
|
-
|
73
|
-
class RDMAwardVocabularyUISchema(DictOnlySchema):
|
74
|
-
class Meta:
|
75
|
-
unknown = ma.INCLUDE
|
76
|
-
|
77
|
-
_id = ma.fields.String(data_key="id", attribute="id")
|
78
|
-
|
79
|
-
_version = ma.fields.String(data_key="@v", attribute="@v")
|
80
|
-
|
81
|
-
title = VocabularyI18nStrUIField()
|
82
|
-
|
83
|
-
number = ma.fields.String()
|
84
|
-
|
85
|
-
identifier = ma.fields.List(ma.fields.Nested(RDMAwardIdentifierUISchema()))
|
86
|
-
|
87
|
-
acronym = ma.fields.String()
|
88
|
-
|
89
|
-
program = ma.fields.String()
|
90
|
-
|
91
|
-
subjects = ma.fields.List(ma.fields.Nested(RDMAwardSubjectUISchema()))
|
92
|
-
|
93
|
-
organizations = ma.fields.List(ma.fields.Nested(RDMAwardOrganizationUISchema()))
|
94
|
-
|
95
|
-
|
96
|
-
class RDMFundersUISchema(ma.Schema):
|
97
|
-
"""Funding ui schema."""
|
98
|
-
|
99
|
-
class Meta:
|
100
|
-
unknown = ma.RAISE
|
101
|
-
|
102
|
-
funder = ma.fields.Nested(lambda: RDMFunderVocabularyUISchema())
|
103
|
-
|
104
|
-
award = ma.fields.Nested(lambda: RDMAwardVocabularyUISchema())
|
105
|
-
|
106
|
-
|
107
|
-
class RDMPersonOrOrganizationUISchema(ma.Schema):
|
108
|
-
class Meta:
|
109
|
-
unknown = ma.INCLUDE
|
110
|
-
|
111
|
-
name = ma.fields.String()
|
112
|
-
|
113
|
-
type = ma.fields.String()
|
114
|
-
|
115
|
-
given_name = ma.fields.String()
|
116
|
-
|
117
|
-
family_name = ma.fields.String()
|
118
|
-
|
119
|
-
identifiers = ma.fields.List(ma.fields.Nested(RDMIdentifierWithSchemaUISchema()))
|
120
|
-
|
121
|
-
|
122
|
-
class RDMAffiliationVocabularyUISchema(DictOnlySchema):
|
123
|
-
class Meta:
|
124
|
-
unknown = ma.INCLUDE
|
125
|
-
|
126
|
-
_id = ma.fields.String(data_key="id", attribute="id")
|
127
|
-
|
128
|
-
_version = ma.fields.String(data_key="@v", attribute="@v")
|
129
|
-
|
130
|
-
name = ma.fields.String()
|
131
|
-
|
132
|
-
|
133
|
-
class RDMCreatorsUISchema(ma.Schema):
|
134
|
-
"""Funding ui schema."""
|
135
|
-
|
136
|
-
class Meta:
|
137
|
-
unknown = ma.RAISE
|
138
|
-
|
139
|
-
role = ma.fields.Nested(lambda: RDMRoleVocabularyUISchema())
|
140
|
-
|
141
|
-
affiliations = ma.fields.List(
|
142
|
-
ma.fields.Nested(lambda: RDMAffiliationVocabularyUISchema())
|
143
|
-
)
|
144
|
-
|
145
|
-
person_or_org = ma.fields.Nested(RDMPersonOrOrganizationUISchema())
|
146
|
-
|
147
|
-
|
148
|
-
class RDMSubjectUISchema(ma.Schema):
|
149
|
-
"""Subject ui schema."""
|
150
|
-
|
151
|
-
class Meta:
|
152
|
-
unknown = ma.RAISE
|
153
|
-
|
154
|
-
_id = ma.fields.String(data_key="id")
|
155
|
-
|
156
|
-
subject = MultilingualUIField()
|