oarepo-runtime 1.5.5__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.
@@ -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=AsynchronousDataStream
60
- if on_background
61
- else SynchronousDataStream,
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
- for r in reversed(
61
- sorted(
62
- pkg_resources.iter_entry_points("oarepo.fixtures"), key=lambda r: r.name
63
- )
64
- ):
65
- pkg = r.load()
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
- ] = ext_config.OAREPO_PERMISSIONS_PRESETS[k]
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":
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}")
@@ -12,6 +12,10 @@ class MappingSystemFieldMixin:
12
12
  def mapping_settings(self):
13
13
  return {}
14
14
 
15
+ @property
16
+ def dynamic_templates(self):
17
+ return []
18
+
15
19
 
16
20
  class SystemFieldDumperExt(SearchDumperExt):
17
21
  def dump(self, record, data):
@@ -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
- record_index.put_mapping(body={"properties": mapping})
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,9 +1,30 @@
1
+
2
+ from invenio_records_resources.services.records.results import (
3
+ RecordItem as BaseRecordItem,
4
+ )
1
5
  from invenio_records_resources.services.records.results import (
2
6
  RecordList as BaseRecordList,
3
7
  )
4
8
 
5
9
 
10
+ class RecordItem(BaseRecordItem):
11
+ """Single record result."""
12
+
13
+ components = []
14
+
15
+ @property
16
+ def data(self):
17
+ if self._data:
18
+ return self._data
19
+ _data = super().data
20
+ for c in self.components:
21
+ c.update_data(self._identity, self._record, _data)
22
+ return _data
23
+
24
+
6
25
  class RecordList(BaseRecordList):
26
+ components = []
27
+
7
28
  @property
8
29
  def hits(self):
9
30
  """Iterator over the hits."""
@@ -27,5 +48,6 @@ class RecordList(BaseRecordList):
27
48
  projection["links"] = self._links_item_tpl.expand(
28
49
  self._identity, record
29
50
  )
30
-
51
+ for c in self.components:
52
+ c.update_data(self._identity, record, projection)
31
53
  yield projection
@@ -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,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: oarepo-runtime
3
- Version: 1.5.5
3
+ Version: 1.5.7
4
4
  Summary: A set of runtime extensions of Invenio repository
5
5
  Description-Content-Type: text/markdown
6
6
  License-File: LICENSE
@@ -1,5 +1,5 @@
1
1
  oarepo_runtime/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- oarepo_runtime/ext.py,sha256=6aYy1zbNDHBn4rNDo_v4xuUteyhbGAAoVtp6rtkxe20,1957
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=aSGquYoyTrCc9WTw9DzStPX3MBS26LHF1BXsqEHXFvc,2699
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=K3z4A-5Cwn-4tJWXWryBaPllrQDOA5XWTnlLyBOv_Y8,7525
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=jzKWn4jaVKZvysPZHtqWE_SWExh_4DBz7YSgflFyYoM,721
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=cgw8g08GK8E3M_MRgixjOQwdv6o3qXZKCj8bV9gq4vE,950
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=IY-uH1EWDomIes14TFDY223StIhY4k_hIfawWedlLug,4215
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.5.dist-info/LICENSE,sha256=h2uWz0OaB3EN-J1ImdGJZzc7yvfQjvHVYdUhQ-H7ypY,1064
108
- oarepo_runtime-1.5.5.dist-info/METADATA,sha256=wtO21olIlItYfhHu7CUZwujiFSbEsHqQq4Ud2fId9eM,4786
109
- oarepo_runtime-1.5.5.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
110
- oarepo_runtime-1.5.5.dist-info/entry_points.txt,sha256=i61xMZGzeBtomvtSb2NYbw-JB5u3fMgDrP_tdDNWvlA,225
111
- oarepo_runtime-1.5.5.dist-info/top_level.txt,sha256=bHhlkT1_RQC4IkfTQCqA3iN4KCB6cSFQlsXpQMSP-bE,21
112
- oarepo_runtime-1.5.5.dist-info/RECORD,,
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