oarepo-runtime 1.5.6__py3-none-any.whl → 1.5.7__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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
|