oarepo-runtime 1.5.6__py3-none-any.whl → 1.5.7__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/cli/fixtures.py +6 -3
- oarepo_runtime/datastreams/fixtures.py +15 -6
- oarepo_runtime/ext.py +3 -5
- oarepo_runtime/info/__init__.py +0 -0
- oarepo_runtime/info/views.py +302 -0
- oarepo_runtime/records/systemfields/mapping.py +4 -0
- oarepo_runtime/records/systemfields/synthetic.py +79 -0
- oarepo_runtime/services/custom_fields/mappings.py +9 -3
- oarepo_runtime/services/results.py +5 -1
- oarepo_runtime/utils/functools.py +8 -0
- {oarepo_runtime-1.5.6.dist-info → oarepo_runtime-1.5.7.dist-info}/METADATA +1 -1
- {oarepo_runtime-1.5.6.dist-info → oarepo_runtime-1.5.7.dist-info}/RECORD +16 -12
- {oarepo_runtime-1.5.6.dist-info → oarepo_runtime-1.5.7.dist-info}/entry_points.txt +3 -0
- {oarepo_runtime-1.5.6.dist-info → oarepo_runtime-1.5.7.dist-info}/LICENSE +0 -0
- {oarepo_runtime-1.5.6.dist-info → oarepo_runtime-1.5.7.dist-info}/WHEEL +0 -0
- {oarepo_runtime-1.5.6.dist-info → oarepo_runtime-1.5.7.dist-info}/top_level.txt +0 -0
oarepo_runtime/cli/fixtures.py
CHANGED
@@ -48,6 +48,9 @@ def load(
|
|
48
48
|
else:
|
49
49
|
callback = fixtures_asynchronous_callback.s()
|
50
50
|
|
51
|
+
if fixture_dir:
|
52
|
+
system_fixtures = False
|
53
|
+
|
51
54
|
with current_app.wsgi_app.mounts["/api"].app_context():
|
52
55
|
load_fixtures(
|
53
56
|
fixture_dir,
|
@@ -56,9 +59,9 @@ def load(
|
|
56
59
|
system_fixtures=system_fixtures,
|
57
60
|
callback=callback,
|
58
61
|
batch_size=bulk_size,
|
59
|
-
datastreams_impl=
|
60
|
-
|
61
|
-
|
62
|
+
datastreams_impl=(
|
63
|
+
AsynchronousDataStream if on_background else SynchronousDataStream
|
64
|
+
),
|
62
65
|
)
|
63
66
|
if not on_background:
|
64
67
|
_show_stats(callback, "Load fixtures")
|
@@ -57,12 +57,20 @@ def load_fixtures(
|
|
57
57
|
)
|
58
58
|
|
59
59
|
if system_fixtures:
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
60
|
+
|
61
|
+
def get_priority(name):
|
62
|
+
match = re.match(r"(\d+)-", name)
|
63
|
+
if match:
|
64
|
+
return -int(match.group(1))
|
65
|
+
return 0
|
66
|
+
|
67
|
+
entry_points = list(
|
68
|
+
(get_priority(r.name), r.name, r)
|
69
|
+
for r in pkg_resources.iter_entry_points("oarepo.fixtures")
|
70
|
+
)
|
71
|
+
entry_points.sort(key=lambda x: x[:2])
|
72
|
+
for r in entry_points:
|
73
|
+
pkg = r[2].load()
|
66
74
|
pkg_fixture_dir = Path(pkg.__file__)
|
67
75
|
if pkg_fixture_dir.is_file():
|
68
76
|
pkg_fixture_dir = pkg_fixture_dir.parent
|
@@ -90,6 +98,7 @@ def _load_fixtures_from_catalogue(
|
|
90
98
|
continue
|
91
99
|
if any(x.match(catalogue_datastream.stream_name) for x in exclude):
|
92
100
|
continue
|
101
|
+
|
93
102
|
fixtures.add(catalogue_datastream.stream_name)
|
94
103
|
|
95
104
|
datastream = datastreams_impl(
|
oarepo_runtime/ext.py
CHANGED
@@ -28,9 +28,9 @@ class OARepoRuntime(object):
|
|
28
28
|
|
29
29
|
for k in ext_config.OAREPO_PERMISSIONS_PRESETS:
|
30
30
|
if k not in app.config["OAREPO_PERMISSIONS_PRESETS"]:
|
31
|
-
app.config["OAREPO_PERMISSIONS_PRESETS"][
|
32
|
-
k
|
33
|
-
|
31
|
+
app.config["OAREPO_PERMISSIONS_PRESETS"][k] = (
|
32
|
+
ext_config.OAREPO_PERMISSIONS_PRESETS[k]
|
33
|
+
)
|
34
34
|
|
35
35
|
for k in dir(ext_config):
|
36
36
|
if k == "DEFAULT_DATASTREAMS_EXCLUDES":
|
@@ -53,5 +53,3 @@ class OARepoRuntime(object):
|
|
53
53
|
for val_k, val_value in source.items():
|
54
54
|
if val_k not in target:
|
55
55
|
target[val_k] = val_value
|
56
|
-
|
57
|
-
|
File without changes
|
@@ -0,0 +1,302 @@
|
|
1
|
+
import json
|
2
|
+
import logging
|
3
|
+
import re
|
4
|
+
from functools import cached_property
|
5
|
+
from urllib.parse import urljoin
|
6
|
+
|
7
|
+
import importlib_metadata
|
8
|
+
import importlib_resources
|
9
|
+
import marshmallow as ma
|
10
|
+
from flask import current_app, request, url_for
|
11
|
+
from flask_resources import (
|
12
|
+
Resource,
|
13
|
+
ResourceConfig,
|
14
|
+
from_conf,
|
15
|
+
request_parser,
|
16
|
+
resource_requestctx,
|
17
|
+
response_handler,
|
18
|
+
route,
|
19
|
+
)
|
20
|
+
from flask_restful import abort
|
21
|
+
from invenio_base.utils import obj_or_import_string
|
22
|
+
from invenio_jsonschemas import current_jsonschemas
|
23
|
+
from invenio_records_resources.proxies import current_service_registry
|
24
|
+
|
25
|
+
logger = logging.getLogger("oarepo_runtime.info")
|
26
|
+
|
27
|
+
|
28
|
+
class InfoConfig(ResourceConfig):
|
29
|
+
blueprint_name = "oarepo_runtime_info"
|
30
|
+
url_prefix = "/.well-known/repository"
|
31
|
+
|
32
|
+
schema_view_args = {"schema": ma.fields.Str()}
|
33
|
+
model_view_args = {"model": ma.fields.Str()}
|
34
|
+
|
35
|
+
def __init__(self, app):
|
36
|
+
self.app = app
|
37
|
+
|
38
|
+
@cached_property
|
39
|
+
def components(self):
|
40
|
+
return tuple(
|
41
|
+
obj_or_import_string(x)
|
42
|
+
for x in self.app.config.get("INFO_ENDPOINT_COMPONENTS", [])
|
43
|
+
)
|
44
|
+
|
45
|
+
|
46
|
+
schema_view_args = request_parser(from_conf("schema_view_args"), location="view_args")
|
47
|
+
model_view_args = request_parser(from_conf("model_view_args"), location="view_args")
|
48
|
+
|
49
|
+
|
50
|
+
class InfoResource(Resource):
|
51
|
+
def create_url_rules(self):
|
52
|
+
return [
|
53
|
+
route("GET", "/", self.repository),
|
54
|
+
route("GET", "/models", self.models),
|
55
|
+
route("GET", "/schema/<path:schema>", self.schema),
|
56
|
+
route("GET", "/models/<model>", self.model),
|
57
|
+
]
|
58
|
+
|
59
|
+
@cached_property
|
60
|
+
def components(self):
|
61
|
+
return [x(self) for x in self.config.components]
|
62
|
+
|
63
|
+
@response_handler()
|
64
|
+
def repository(self):
|
65
|
+
"""Repository endpoint."""
|
66
|
+
ret = {
|
67
|
+
"name": current_app.config.get("THEME_SITENAME", ""),
|
68
|
+
"description": current_app.config.get("REPOSITORY_DESCRIPTION", ""),
|
69
|
+
"version": get_package_version("repo"),
|
70
|
+
"invenio_version": get_package_version("oarepo"),
|
71
|
+
"transfers": [
|
72
|
+
"local-file",
|
73
|
+
"url-fetch",
|
74
|
+
# TODO: where to get these? (permissions?)
|
75
|
+
# "direct-s3",
|
76
|
+
],
|
77
|
+
"links": {
|
78
|
+
"self": url_for(request.endpoint, _external=True),
|
79
|
+
"models": url_for("oarepo_runtime_info.models", _external=True),
|
80
|
+
},
|
81
|
+
}
|
82
|
+
self.call_components("repository", data=ret)
|
83
|
+
return ret, 200
|
84
|
+
|
85
|
+
@response_handler(many=True)
|
86
|
+
def models(self):
|
87
|
+
data = []
|
88
|
+
# iterate entrypoint oarepo.models
|
89
|
+
for model in importlib_metadata.entry_points().select(group="oarepo.models"):
|
90
|
+
package_name, file_name = model.value.split(":")
|
91
|
+
model_data = json.loads(
|
92
|
+
importlib_resources.files(package_name).joinpath(file_name).read_text()
|
93
|
+
)
|
94
|
+
model_data = model_data["model"]
|
95
|
+
if model_data["type"] != "model":
|
96
|
+
continue
|
97
|
+
|
98
|
+
service = self._get_service(model_data)
|
99
|
+
if not service:
|
100
|
+
continue
|
101
|
+
|
102
|
+
model_features = self._get_model_features(model_data)
|
103
|
+
|
104
|
+
links = {
|
105
|
+
"api": self._get_model_api_endpoint(model_data),
|
106
|
+
"html": self._get_model_html_endpoint(model_data),
|
107
|
+
"schema": self._get_model_schema_endpoint(model_data),
|
108
|
+
"model": self._get_model_model_endpoint(model.name),
|
109
|
+
# "openapi": url_for(self._get_model_openapi_endpoint(model_data), _external=True)
|
110
|
+
}
|
111
|
+
|
112
|
+
links["published"] = links["api"]
|
113
|
+
if "drafts" in model_features:
|
114
|
+
links["drafts"] = self._get_model_draft_endpoint(model_data)
|
115
|
+
|
116
|
+
data.append(
|
117
|
+
{
|
118
|
+
"name": model_data.get(
|
119
|
+
"model-name", model_data.get("module", {}).get("base", "")
|
120
|
+
).lower(),
|
121
|
+
"description": model_data.get("model-description", ""),
|
122
|
+
"version": model_data["json-schema-settings"]["version"],
|
123
|
+
"features": model_features,
|
124
|
+
"links": links,
|
125
|
+
# TODO: we also need to get previous schema versions here if we support
|
126
|
+
# multiple version of the same schema at the same time
|
127
|
+
"schemas": self._get_model_schemas(service),
|
128
|
+
}
|
129
|
+
)
|
130
|
+
self.call_components("repository", data=data)
|
131
|
+
return data, 200
|
132
|
+
|
133
|
+
@schema_view_args
|
134
|
+
@response_handler()
|
135
|
+
def schema(self):
|
136
|
+
schema = resource_requestctx.view_args["schema"]
|
137
|
+
return current_jsonschemas.get_schema(schema, resolved=True), 200
|
138
|
+
|
139
|
+
@model_view_args
|
140
|
+
@response_handler()
|
141
|
+
def model(self):
|
142
|
+
model = resource_requestctx.view_args["model"]
|
143
|
+
for _model in importlib_metadata.entry_points().select(
|
144
|
+
group="oarepo.models", name=model
|
145
|
+
):
|
146
|
+
package_name, file_name = _model.value.split(":")
|
147
|
+
model_data = json.loads(
|
148
|
+
importlib_resources.files(package_name).joinpath(file_name).read_text()
|
149
|
+
)
|
150
|
+
return self._remove_implementation_details_from_model(model_data), 200
|
151
|
+
abort(404)
|
152
|
+
|
153
|
+
IMPLEMENTATION_DETAILS = re.compile(
|
154
|
+
r"""
|
155
|
+
^(
|
156
|
+
class |
|
157
|
+
.*-class |
|
158
|
+
base-classes |
|
159
|
+
.*-base-classes |
|
160
|
+
module |
|
161
|
+
generate |
|
162
|
+
imports |
|
163
|
+
extra-code |
|
164
|
+
components |
|
165
|
+
.*-args
|
166
|
+
)$
|
167
|
+
""",
|
168
|
+
re.VERBOSE,
|
169
|
+
)
|
170
|
+
|
171
|
+
def _remove_implementation_details_from_model(self, model):
|
172
|
+
if isinstance(model, dict):
|
173
|
+
return self._remove_implementation_details_from_model_dict(model)
|
174
|
+
elif isinstance(model, list):
|
175
|
+
return self._remove_implementation_details_from_model_list(model)
|
176
|
+
else:
|
177
|
+
return model
|
178
|
+
|
179
|
+
def _remove_implementation_details_from_model_dict(self, model):
|
180
|
+
ret = {}
|
181
|
+
for k, v in model.items():
|
182
|
+
if not self.IMPLEMENTATION_DETAILS.match(k):
|
183
|
+
new_value = self._remove_implementation_details_from_model(v)
|
184
|
+
if new_value is not None and new_value != {} and new_value != []:
|
185
|
+
ret[k] = new_value
|
186
|
+
return ret
|
187
|
+
|
188
|
+
def _remove_implementation_details_from_model_list(self, model):
|
189
|
+
ret = []
|
190
|
+
for v in model:
|
191
|
+
new_value = self._remove_implementation_details_from_model(v)
|
192
|
+
if new_value is not None and new_value != {} and new_value != []:
|
193
|
+
ret.append(new_value)
|
194
|
+
return ret
|
195
|
+
|
196
|
+
def call_components(self, method_name, **kwargs):
|
197
|
+
for component in self.config.components:
|
198
|
+
if hasattr(component, method_name):
|
199
|
+
getattr(component, method_name)(**kwargs)
|
200
|
+
|
201
|
+
def _get_model_features(self, model):
|
202
|
+
features = []
|
203
|
+
if model.get("requests", {}):
|
204
|
+
features.append("requests")
|
205
|
+
if model.get("draft", {}):
|
206
|
+
features.append("drafts")
|
207
|
+
if model.get("files", {}):
|
208
|
+
features.append("files")
|
209
|
+
return features
|
210
|
+
|
211
|
+
def _get_model_api_endpoint(self, model):
|
212
|
+
try:
|
213
|
+
alias = model["api-blueprint"]["alias"]
|
214
|
+
return api_url_for(f"{alias}.search", _external=True)
|
215
|
+
except: # NOSONAR noqa
|
216
|
+
logger.exception("Failed to get model api endpoint")
|
217
|
+
return None
|
218
|
+
|
219
|
+
def _get_model_draft_endpoint(self, model):
|
220
|
+
try:
|
221
|
+
alias = model["api-blueprint"]["alias"]
|
222
|
+
return api_url_for(f"{alias}.search_user_records", _external=True)
|
223
|
+
except: # NOSONAR noqa
|
224
|
+
logger.exception("Failed to get model draft endpoint")
|
225
|
+
return None
|
226
|
+
|
227
|
+
def _get_model_html_endpoint(self, model):
|
228
|
+
try:
|
229
|
+
return urljoin(
|
230
|
+
self._get_model_api_endpoint(model),
|
231
|
+
model["resource-config"]["base-html-url"],
|
232
|
+
)
|
233
|
+
except: # NOSONAR noqa
|
234
|
+
logger.exception("Failed to get model html endpoint")
|
235
|
+
return None
|
236
|
+
|
237
|
+
def _get_model_schema_endpoint(self, model):
|
238
|
+
try:
|
239
|
+
return url_for(
|
240
|
+
"oarepo_runtime_info.schema",
|
241
|
+
schema=model["json-schema-settings"]["name"],
|
242
|
+
_external=True,
|
243
|
+
)
|
244
|
+
except: # NOSONAR noqa
|
245
|
+
logger.exception("Failed to get model schema endpoint")
|
246
|
+
return None
|
247
|
+
|
248
|
+
def _get_model_model_endpoint(self, model):
|
249
|
+
try:
|
250
|
+
return url_for("oarepo_runtime_info.model", model=model, _external=True)
|
251
|
+
except: # NOSONAR noqa
|
252
|
+
logger.exception("Failed to get model model endpoint")
|
253
|
+
return None
|
254
|
+
|
255
|
+
def _get_model_schemas(self, service):
|
256
|
+
try:
|
257
|
+
record_cls = service.config.record_cls
|
258
|
+
schema = getattr(record_cls, "schema", None)
|
259
|
+
if schema is not None:
|
260
|
+
return [schema.value]
|
261
|
+
except: # NOSONAR noqa
|
262
|
+
logger.exception("Failed to get model schemas")
|
263
|
+
return []
|
264
|
+
|
265
|
+
def _get_service(self, model_data):
|
266
|
+
service_id = model_data["service-config"]["service-id"]
|
267
|
+
try:
|
268
|
+
service = current_service_registry.get(service_id)
|
269
|
+
except KeyError:
|
270
|
+
return None
|
271
|
+
return service
|
272
|
+
|
273
|
+
|
274
|
+
def create_wellknown_blueprint(app):
|
275
|
+
"""Create blueprint."""
|
276
|
+
config_class = obj_or_import_string(
|
277
|
+
app.config.get("INFO_ENDPOINT_CONFIG", InfoConfig)
|
278
|
+
)
|
279
|
+
return InfoResource(config=config_class(app)).as_blueprint()
|
280
|
+
|
281
|
+
|
282
|
+
def get_package_version(package_name):
|
283
|
+
"""Get package version."""
|
284
|
+
from pkg_resources import get_distribution
|
285
|
+
|
286
|
+
try:
|
287
|
+
return re.sub(r"\+.*", "", get_distribution(package_name).version)
|
288
|
+
except Exception: # NOSONAR noqa
|
289
|
+
logger.exception(f"Failed to get package version for {package_name}")
|
290
|
+
return None
|
291
|
+
|
292
|
+
|
293
|
+
def api_url_for(endpoint, _external=True, **values):
|
294
|
+
"""API url_for."""
|
295
|
+
site_api_url = current_app.config["SITE_API_URL"]
|
296
|
+
site_url = current_app.config["SITE_UI_URL"]
|
297
|
+
base_url = url_for(endpoint, **values, _external=_external)
|
298
|
+
if base_url.startswith(site_api_url):
|
299
|
+
return base_url
|
300
|
+
if base_url.startswith(site_url):
|
301
|
+
return base_url.replace(site_url, site_api_url)
|
302
|
+
raise ValueError(f"URL {base_url} does not start with {site_url} or {site_api_url}")
|
@@ -0,0 +1,79 @@
|
|
1
|
+
from invenio_records.systemfields import SystemField
|
2
|
+
|
3
|
+
from .mapping import MappingSystemFieldMixin
|
4
|
+
|
5
|
+
|
6
|
+
class SyntheticSystemField(MappingSystemFieldMixin, SystemField):
|
7
|
+
"""
|
8
|
+
A class that provides a synthetic system field, that is a system field that
|
9
|
+
generates its content from what is already present inside the record.
|
10
|
+
|
11
|
+
The field is not stored in the record, but is generated on the fly when
|
12
|
+
the record is being indexed.
|
13
|
+
|
14
|
+
Usage:
|
15
|
+
|
16
|
+
1. Create a new class that inherits from SyntheticSystemField
|
17
|
+
2. Implement the _value method that returns the value of the field from a data (
|
18
|
+
either a dictionary or an instance of the record class)
|
19
|
+
3. Put the class onto the record. If you use oarepo-model-builder, add it to the model
|
20
|
+
like:
|
21
|
+
```yaml
|
22
|
+
record:
|
23
|
+
record:
|
24
|
+
extra-code: |-2
|
25
|
+
# extra custom fields for facets
|
26
|
+
faculty = {{common.theses.synthetic_fields.FacultySystemField}}()
|
27
|
+
department = {{common.theses.synthetic_fields.DepartmentSystemField}}()
|
28
|
+
defenseYear = {{common.theses.synthetic_fields.DefenseYearSystemField}}()
|
29
|
+
```
|
30
|
+
|
31
|
+
4. Add the extra fields to the mapping and facets. If using oarepo-model-builder, add it to the
|
32
|
+
model like the following piece of code and compile the model:
|
33
|
+
```yaml
|
34
|
+
record:
|
35
|
+
properties:
|
36
|
+
faculty:
|
37
|
+
type: vocabulary
|
38
|
+
vocabulary-type: institutions
|
39
|
+
facets:
|
40
|
+
facet-groups:
|
41
|
+
- default
|
42
|
+
label.cs: Fakulta
|
43
|
+
label.en: Faculty
|
44
|
+
|
45
|
+
|
46
|
+
department:
|
47
|
+
type: vocabulary
|
48
|
+
vocabulary-type: institutions
|
49
|
+
facets:
|
50
|
+
facet-groups:
|
51
|
+
- default
|
52
|
+
label.cs: Ústav
|
53
|
+
label.en: Department
|
54
|
+
|
55
|
+
defenseYear:
|
56
|
+
type: integer
|
57
|
+
facets:
|
58
|
+
facet-groups:
|
59
|
+
- default
|
60
|
+
label.cs: Rok obhajoby
|
61
|
+
label.en: Defense year
|
62
|
+
```
|
63
|
+
"""
|
64
|
+
|
65
|
+
def search_dump(self, data):
|
66
|
+
dt = self._value(data)
|
67
|
+
if dt:
|
68
|
+
data[self.key] = dt
|
69
|
+
|
70
|
+
def search_load(self, data):
|
71
|
+
data.pop(self.key)
|
72
|
+
|
73
|
+
def __get__(self, record, owner=None):
|
74
|
+
if record is None:
|
75
|
+
return self
|
76
|
+
return self._value(record)
|
77
|
+
|
78
|
+
def _value(self, data):
|
79
|
+
raise NotImplementedError("You must implement the _value method")
|
@@ -80,6 +80,7 @@ def prepare_cf_index(config: RecordServiceConfig):
|
|
80
80
|
# get mapping
|
81
81
|
mapping = fld.mapping
|
82
82
|
settings = fld.mapping_settings
|
83
|
+
dynamic_templates = fld.dynamic_templates
|
83
84
|
|
84
85
|
# upload mapping
|
85
86
|
try:
|
@@ -98,20 +99,25 @@ def prepare_cf_index(config: RecordServiceConfig):
|
|
98
99
|
),
|
99
100
|
using=current_search_client,
|
100
101
|
)
|
101
|
-
update_index(draft_index, settings, mapping)
|
102
|
+
update_index(draft_index, settings, mapping, dynamic_templates)
|
102
103
|
|
103
104
|
except search.RequestError as e:
|
104
105
|
click.secho("An error occurred while creating custom fields.", fg="red")
|
105
106
|
click.secho(e.info["error"]["reason"], fg="red")
|
106
107
|
|
107
108
|
|
108
|
-
def update_index(record_index, settings, mapping):
|
109
|
+
def update_index(record_index, settings, mapping, dynamic_templates=None):
|
109
110
|
if settings:
|
110
111
|
record_index.close()
|
111
112
|
record_index.put_settings(body=settings)
|
112
113
|
record_index.open()
|
114
|
+
body = {}
|
113
115
|
if mapping:
|
114
|
-
|
116
|
+
body["properties"] = mapping
|
117
|
+
if dynamic_templates:
|
118
|
+
body["dynamic_templates"] = dynamic_templates
|
119
|
+
if body:
|
120
|
+
record_index.put_mapping(body=body)
|
115
121
|
|
116
122
|
|
117
123
|
def get_mapping_fields(record_class) -> Iterable[MappingSystemFieldMixin]:
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import inspect
|
2
1
|
|
3
2
|
from invenio_records_resources.services.records.results import (
|
4
3
|
RecordItem as BaseRecordItem,
|
@@ -7,9 +6,12 @@ from invenio_records_resources.services.records.results import (
|
|
7
6
|
RecordList as BaseRecordList,
|
8
7
|
)
|
9
8
|
|
9
|
+
|
10
10
|
class RecordItem(BaseRecordItem):
|
11
11
|
"""Single record result."""
|
12
|
+
|
12
13
|
components = []
|
14
|
+
|
13
15
|
@property
|
14
16
|
def data(self):
|
15
17
|
if self._data:
|
@@ -19,8 +21,10 @@ class RecordItem(BaseRecordItem):
|
|
19
21
|
c.update_data(self._identity, self._record, _data)
|
20
22
|
return _data
|
21
23
|
|
24
|
+
|
22
25
|
class RecordList(BaseRecordList):
|
23
26
|
components = []
|
27
|
+
|
24
28
|
@property
|
25
29
|
def hits(self):
|
26
30
|
"""Iterator over the hits."""
|
@@ -0,0 +1,8 @@
|
|
1
|
+
def try_sequence(*funcs, ignored_exceptions=(), raised_exception=Exception):
|
2
|
+
raised_exceptions = []
|
3
|
+
for func in funcs:
|
4
|
+
try:
|
5
|
+
return func()
|
6
|
+
except ignored_exceptions as e:
|
7
|
+
raised_exceptions.append(e)
|
8
|
+
raise raised_exception(raised_exceptions) from raised_exceptions[-1]
|
@@ -1,5 +1,5 @@
|
|
1
1
|
oarepo_runtime/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
oarepo_runtime/ext.py,sha256=
|
2
|
+
oarepo_runtime/ext.py,sha256=XPEEg1fDDAC6uihCM3ASbKmkgdL050lg9qTdrqqbI4A,1959
|
3
3
|
oarepo_runtime/ext_config.py,sha256=c9q8zc78bjBosv1lbHGfenX2S6L-_9v0RZeQjbczvdI,1941
|
4
4
|
oarepo_runtime/profile.py,sha256=QzrQoZncjoN74ZZnpkEKakNk08KCzBU7m6y42RN8AMY,1637
|
5
5
|
oarepo_runtime/proxies.py,sha256=IuwZDwEqRcKxdqNdMrlSzOSiYjtWyJIgvg4zbFTWI8I,207
|
@@ -10,7 +10,7 @@ oarepo_runtime/cli/base.py,sha256=94RBTa8TOSPxEyEUmYLGXaWen-XktP2-MIbTtZSlCZo,54
|
|
10
10
|
oarepo_runtime/cli/cf.py,sha256=W0JEJK2JqKubQw8qtZJxohmADDRUBode4JZAqYLDGvc,339
|
11
11
|
oarepo_runtime/cli/check.py,sha256=AvC5VHAnwmtCd8R-Caj8v6nCAREKjObTdNtLJ24aJO8,4935
|
12
12
|
oarepo_runtime/cli/configuration.py,sha256=cLXoGDtjuA5uv9ZfYFcH0C4wcadj0qWC3P_E4Bf5-z0,1061
|
13
|
-
oarepo_runtime/cli/fixtures.py,sha256
|
13
|
+
oarepo_runtime/cli/fixtures.py,sha256=-OVPurbaIsyZ2MK7LL74q_bXHkI_YTScUcTanT2D1hY,2760
|
14
14
|
oarepo_runtime/cli/index.py,sha256=VB7g-HSCd-lR6rk0GLn9i-Rt9JlEnEiQrGnAQlklFME,5447
|
15
15
|
oarepo_runtime/cli/validate.py,sha256=HpSvHQCGHlrdgdpKix9cIlzlBoJEiT1vACZdMnOUGEY,2827
|
16
16
|
oarepo_runtime/datastreams/__init__.py,sha256=_i52Ek9J8DMARST0ejZAZPzUKm55xrrlKlCSO7dl6y4,1008
|
@@ -19,7 +19,7 @@ oarepo_runtime/datastreams/catalogue.py,sha256=D6leq-FPT3RP3SniEAXPm66v3q8ZdQnaU
|
|
19
19
|
oarepo_runtime/datastreams/datastreams.py,sha256=wnMk1UFv-cWXRO0jHwRNoJBO0cbZaHqrLnH7vgfnf78,4485
|
20
20
|
oarepo_runtime/datastreams/errors.py,sha256=WyZLU53EdFJTLv6K2ooM_M6ISjLS-U1dDw6B7guOLSc,1540
|
21
21
|
oarepo_runtime/datastreams/ext.py,sha256=ivugdVMCqwugK-5SeX14a-dMq6VaTt7DM2wFU357tR4,1406
|
22
|
-
oarepo_runtime/datastreams/fixtures.py,sha256=
|
22
|
+
oarepo_runtime/datastreams/fixtures.py,sha256=7uqA7YYtP4fs5Ktu5UYdbvZP4xm8cKiqykPvUyS6JDE,7770
|
23
23
|
oarepo_runtime/datastreams/json.py,sha256=OAiaH93eqpH5qNQSPKKc8K-hXKAn5lB0PUKwwZFqJSw,153
|
24
24
|
oarepo_runtime/datastreams/semi_asynchronous.py,sha256=TJWby2MDKXm5feRocoWB-8OhsShq5R9HoZ74O1rGBOk,2934
|
25
25
|
oarepo_runtime/datastreams/synchronous.py,sha256=t5lfnMkLqy3jK5zMl-nIuA0HlMPiHGjwCqZ8XQP-3GM,2595
|
@@ -40,6 +40,8 @@ oarepo_runtime/datastreams/writers/utils.py,sha256=Lk_ZLNeXTLuFEn04lw1-6bJ7duG6k
|
|
40
40
|
oarepo_runtime/datastreams/writers/validation_errors.py,sha256=wOCXdniR6so_4ExpdFYYgBRyENp7_6kVFZM2L-Hy3G8,661
|
41
41
|
oarepo_runtime/datastreams/writers/yaml.py,sha256=XchUJHQ58E2Mfgs8elImXbL38jFtI8Hfoye6yaR0gKI,1482
|
42
42
|
oarepo_runtime/i18n/__init__.py,sha256=G4PJ_kQlPDiBW6ntjQZ-O4qHQgkJWAXsNLUuOBcglNM,402
|
43
|
+
oarepo_runtime/info/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
44
|
+
oarepo_runtime/info/views.py,sha256=W1aa6c6ZYABcjSgH3DfjadHrFHqn2Myc1XarkEvWxU0,10399
|
43
45
|
oarepo_runtime/records/__init__.py,sha256=Bxm2XNtB9j6iOAKGSVsjXTKIZS-iXKPzakCqyNkEix8,432
|
44
46
|
oarepo_runtime/records/dumpers/__init__.py,sha256=OmzNhLdMNKibmCksnj9eTX9xPBG30dziiK3j3bAAp3k,233
|
45
47
|
oarepo_runtime/records/dumpers/edtf_interval.py,sha256=YCShZAoqBQYaxVilEVotS-jXZsxxoXO67yu2urhkaMA,1198
|
@@ -55,19 +57,20 @@ oarepo_runtime/records/systemfields/__init__.py,sha256=JpDSVry8TWvUNGlR7AXd_D9ND
|
|
55
57
|
oarepo_runtime/records/systemfields/featured_file.py,sha256=4_SXyGNMxAANeYOGrT4QLJmzVdF4FFeTP_n4T9KZ3M8,1725
|
56
58
|
oarepo_runtime/records/systemfields/has_draftcheck.py,sha256=3XLRsZJWRpT4BFF1HTg6C27ECVmIcZ4RrdGzYC8S7v0,1518
|
57
59
|
oarepo_runtime/records/systemfields/icu.py,sha256=-vGPbVkEUS53dIm50pEcRlk1T6h002s7fBY4Ic2X75c,5951
|
58
|
-
oarepo_runtime/records/systemfields/mapping.py,sha256=
|
60
|
+
oarepo_runtime/records/systemfields/mapping.py,sha256=GJeQUwH-J2Gxtd9cpzGUT0bxirObXkwCZ33_Q6WZTK0,787
|
59
61
|
oarepo_runtime/records/systemfields/record_status.py,sha256=iXasHCIc-veaOHyiSpxHL8CWNpleh_BDBybkv79iqb0,945
|
62
|
+
oarepo_runtime/records/systemfields/synthetic.py,sha256=kX_cSz5llbBXMjpK6MTjci1zah641eqV3ivXs5fZpcs,2448
|
60
63
|
oarepo_runtime/resources/__init__.py,sha256=v8BGrOTu_FjKzd0eozV7Q4GoGxyfybsL2cI-tbP5Pys,185
|
61
64
|
oarepo_runtime/resources/file_resource.py,sha256=Ta3bFce7l0xwqkkOMOEu9mxbB8BbKj5HUHRHmidhnl8,414
|
62
65
|
oarepo_runtime/resources/localized_ui_json_serializer.py,sha256=4Kle34k-_uu3Y9JJ2vAXcQ9DqYRxXgy-_iZhiFuukmE,1684
|
63
66
|
oarepo_runtime/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
64
|
-
oarepo_runtime/services/results.py,sha256=
|
67
|
+
oarepo_runtime/services/results.py,sha256=DsBPniwhNvOkYucS8Z0v3EC28LemY7JuZNVhl_17PhA,1500
|
65
68
|
oarepo_runtime/services/search.py,sha256=ywfwGH7oAM44WeOSjlIsY_qoCMZJ1TlTLd_NgE2ow3Y,5296
|
66
69
|
oarepo_runtime/services/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
67
70
|
oarepo_runtime/services/config/permissions_presets.py,sha256=zApeA-2DYAlD--SzVz3vq_OFjq48Ko0pe08e4o2vxr4,6114
|
68
71
|
oarepo_runtime/services/config/service.py,sha256=Uzo3rJGWljbkLcWd-E1BJOEglJHli8eUSIgFTJt9sXE,1566
|
69
72
|
oarepo_runtime/services/custom_fields/__init__.py,sha256=HVqgIIoPqg-pJHkP1KY_Phe-9fSD0RsnF02H5OS9wCM,2262
|
70
|
-
oarepo_runtime/services/custom_fields/mappings.py,sha256=
|
73
|
+
oarepo_runtime/services/custom_fields/mappings.py,sha256=1mb8nYeUlQxbBolsKURGKUIpIV1NDb-7Mcur32jjIjg,4433
|
71
74
|
oarepo_runtime/services/expansions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
72
75
|
oarepo_runtime/services/expansions/expandable_fields.py,sha256=7DWKFL6ml8J7zGI6wm9LO7Xd6R0LSylsuq4lyRumNHQ,745
|
73
76
|
oarepo_runtime/services/expansions/service.py,sha256=HaEy76XOhDf__sQ91hi-8iH1hthM9q07pRhOmyZyVrs,144
|
@@ -102,11 +105,12 @@ oarepo_runtime/translations/cs/LC_MESSAGES/messages.po,sha256=vGZQo5NlTtj_qsJuDw
|
|
102
105
|
oarepo_runtime/translations/en/LC_MESSAGES/messages.mo,sha256=FKAl1wlg2NhtQ1-9U2dkUwcotR959j5GuUKJygCYpwI,445
|
103
106
|
oarepo_runtime/translations/en/LC_MESSAGES/messages.po,sha256=rZ2PGvkcJbmuwrWeFX5edk0zJIzZnL83M9HSAceDP_U,1193
|
104
107
|
oarepo_runtime/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
108
|
+
oarepo_runtime/utils/functools.py,sha256=eueB-4MRv9wrOARs70ey21JvBb63gGeJV6m1fdGcnPQ,319
|
105
109
|
oarepo_runtime/utils/path.py,sha256=V1NVyk3m12_YLbj7QHYvUpE1wScO78bYsX1LOLeXDkI,3108
|
106
110
|
tests/pkg_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
107
|
-
oarepo_runtime-1.5.
|
108
|
-
oarepo_runtime-1.5.
|
109
|
-
oarepo_runtime-1.5.
|
110
|
-
oarepo_runtime-1.5.
|
111
|
-
oarepo_runtime-1.5.
|
112
|
-
oarepo_runtime-1.5.
|
111
|
+
oarepo_runtime-1.5.7.dist-info/LICENSE,sha256=h2uWz0OaB3EN-J1ImdGJZzc7yvfQjvHVYdUhQ-H7ypY,1064
|
112
|
+
oarepo_runtime-1.5.7.dist-info/METADATA,sha256=SHRsje7uchCfZ6fsSFhN26JCbGrwYexHiQI0DYNgVpg,4786
|
113
|
+
oarepo_runtime-1.5.7.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
114
|
+
oarepo_runtime-1.5.7.dist-info/entry_points.txt,sha256=QrlXAKuPDVBinaSh_v3yO9_Nb9ZNmJCJ0VFcCW-z0Jg,327
|
115
|
+
oarepo_runtime-1.5.7.dist-info/top_level.txt,sha256=bHhlkT1_RQC4IkfTQCqA3iN4KCB6cSFQlsXpQMSP-bE,21
|
116
|
+
oarepo_runtime-1.5.7.dist-info/RECORD,,
|
@@ -4,5 +4,8 @@ oarepo_runtime = oarepo_runtime.ext:OARepoRuntime
|
|
4
4
|
[invenio_base.apps]
|
5
5
|
oarepo_runtime = oarepo_runtime.ext:OARepoRuntime
|
6
6
|
|
7
|
+
[invenio_base.blueprints]
|
8
|
+
oarepo_runtime_info = oarepo_runtime.info.views:create_wellknown_blueprint
|
9
|
+
|
7
10
|
[invenio_celery.tasks]
|
8
11
|
oarepo_runtime_datastreams = oarepo_runtime.datastreams
|
File without changes
|
File without changes
|
File without changes
|