oarepo-runtime 1.10.2__py3-none-any.whl → 2.0.0.dev3__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.
Files changed (171) hide show
  1. oarepo_runtime/__init__.py +24 -0
  2. oarepo_runtime/api.py +111 -0
  3. oarepo_runtime/cli/__init__.py +10 -21
  4. oarepo_runtime/cli/search.py +34 -0
  5. oarepo_runtime/config.py +86 -13
  6. oarepo_runtime/ext.py +64 -82
  7. oarepo_runtime/proxies.py +21 -5
  8. oarepo_runtime/records/__init__.py +11 -50
  9. oarepo_runtime/records/drafts.py +24 -18
  10. oarepo_runtime/records/mapping.py +84 -0
  11. oarepo_runtime/records/pid_providers.py +43 -7
  12. oarepo_runtime/records/systemfields/__init__.py +15 -33
  13. oarepo_runtime/records/systemfields/mapping.py +41 -24
  14. oarepo_runtime/records/systemfields/publication_status.py +59 -0
  15. oarepo_runtime/services/__init__.py +12 -0
  16. oarepo_runtime/services/config/__init__.py +15 -21
  17. oarepo_runtime/services/config/link_conditions.py +69 -75
  18. oarepo_runtime/services/config/permissions.py +62 -0
  19. oarepo_runtime/services/records/__init__.py +14 -1
  20. oarepo_runtime/services/records/links.py +21 -11
  21. oarepo_runtime/services/records/mapping.py +42 -0
  22. oarepo_runtime/services/results.py +98 -109
  23. oarepo_runtime/services/schema/__init__.py +12 -44
  24. oarepo_runtime/services/schema/i18n.py +47 -22
  25. oarepo_runtime/services/schema/i18n_ui.py +61 -24
  26. {oarepo_runtime-1.10.2.dist-info → oarepo_runtime-2.0.0.dev3.dist-info}/METADATA +9 -21
  27. oarepo_runtime-2.0.0.dev3.dist-info/RECORD +30 -0
  28. {oarepo_runtime-1.10.2.dist-info → oarepo_runtime-2.0.0.dev3.dist-info}/WHEEL +1 -2
  29. oarepo_runtime-2.0.0.dev3.dist-info/entry_points.txt +5 -0
  30. oarepo_runtime/cli/assets.py +0 -145
  31. oarepo_runtime/cli/base.py +0 -25
  32. oarepo_runtime/cli/cf.py +0 -15
  33. oarepo_runtime/cli/check.py +0 -167
  34. oarepo_runtime/cli/configuration.py +0 -51
  35. oarepo_runtime/cli/fixtures.py +0 -167
  36. oarepo_runtime/cli/index.py +0 -272
  37. oarepo_runtime/cli/permissions/__init__.py +0 -6
  38. oarepo_runtime/cli/permissions/base.py +0 -26
  39. oarepo_runtime/cli/permissions/evaluate.py +0 -63
  40. oarepo_runtime/cli/permissions/list.py +0 -239
  41. oarepo_runtime/cli/permissions/search.py +0 -121
  42. oarepo_runtime/cli/validate.py +0 -150
  43. oarepo_runtime/datastreams/__init__.py +0 -38
  44. oarepo_runtime/datastreams/asynchronous.py +0 -247
  45. oarepo_runtime/datastreams/catalogue.py +0 -150
  46. oarepo_runtime/datastreams/datastreams.py +0 -152
  47. oarepo_runtime/datastreams/errors.py +0 -54
  48. oarepo_runtime/datastreams/ext.py +0 -41
  49. oarepo_runtime/datastreams/fixtures.py +0 -265
  50. oarepo_runtime/datastreams/json.py +0 -4
  51. oarepo_runtime/datastreams/readers/__init__.py +0 -39
  52. oarepo_runtime/datastreams/readers/attachments.py +0 -51
  53. oarepo_runtime/datastreams/readers/excel.py +0 -123
  54. oarepo_runtime/datastreams/readers/json.py +0 -27
  55. oarepo_runtime/datastreams/readers/service.py +0 -54
  56. oarepo_runtime/datastreams/readers/yaml.py +0 -14
  57. oarepo_runtime/datastreams/semi_asynchronous.py +0 -91
  58. oarepo_runtime/datastreams/synchronous.py +0 -70
  59. oarepo_runtime/datastreams/transformers.py +0 -18
  60. oarepo_runtime/datastreams/types.py +0 -323
  61. oarepo_runtime/datastreams/utils.py +0 -131
  62. oarepo_runtime/datastreams/writers/__init__.py +0 -21
  63. oarepo_runtime/datastreams/writers/attachments_file.py +0 -92
  64. oarepo_runtime/datastreams/writers/attachments_service.py +0 -118
  65. oarepo_runtime/datastreams/writers/publish.py +0 -70
  66. oarepo_runtime/datastreams/writers/service.py +0 -175
  67. oarepo_runtime/datastreams/writers/utils.py +0 -30
  68. oarepo_runtime/datastreams/writers/validation_errors.py +0 -20
  69. oarepo_runtime/datastreams/writers/yaml.py +0 -56
  70. oarepo_runtime/ext_config.py +0 -67
  71. oarepo_runtime/i18n/__init__.py +0 -3
  72. oarepo_runtime/info/__init__.py +0 -0
  73. oarepo_runtime/info/check.py +0 -95
  74. oarepo_runtime/info/permissions/__init__.py +0 -0
  75. oarepo_runtime/info/permissions/debug.py +0 -191
  76. oarepo_runtime/info/views.py +0 -586
  77. oarepo_runtime/profile.py +0 -60
  78. oarepo_runtime/records/dumpers/__init__.py +0 -8
  79. oarepo_runtime/records/dumpers/edtf_interval.py +0 -38
  80. oarepo_runtime/records/dumpers/multilingual_dumper.py +0 -34
  81. oarepo_runtime/records/entity_resolvers/__init__.py +0 -13
  82. oarepo_runtime/records/entity_resolvers/proxies.py +0 -57
  83. oarepo_runtime/records/mappings/__init__.py +0 -0
  84. oarepo_runtime/records/mappings/rdm_parent_mapping.json +0 -483
  85. oarepo_runtime/records/owners/__init__.py +0 -3
  86. oarepo_runtime/records/owners/registry.py +0 -22
  87. oarepo_runtime/records/relations/__init__.py +0 -22
  88. oarepo_runtime/records/relations/base.py +0 -296
  89. oarepo_runtime/records/relations/internal.py +0 -46
  90. oarepo_runtime/records/relations/lookup.py +0 -28
  91. oarepo_runtime/records/relations/pid_relation.py +0 -102
  92. oarepo_runtime/records/systemfields/featured_file.py +0 -45
  93. oarepo_runtime/records/systemfields/has_draftcheck.py +0 -47
  94. oarepo_runtime/records/systemfields/icu.py +0 -371
  95. oarepo_runtime/records/systemfields/owner.py +0 -115
  96. oarepo_runtime/records/systemfields/record_status.py +0 -35
  97. oarepo_runtime/records/systemfields/selectors.py +0 -98
  98. oarepo_runtime/records/systemfields/synthetic.py +0 -130
  99. oarepo_runtime/resources/__init__.py +0 -4
  100. oarepo_runtime/resources/config.py +0 -12
  101. oarepo_runtime/resources/file_resource.py +0 -15
  102. oarepo_runtime/resources/json_serializer.py +0 -27
  103. oarepo_runtime/resources/localized_ui_json_serializer.py +0 -54
  104. oarepo_runtime/resources/resource.py +0 -53
  105. oarepo_runtime/resources/responses.py +0 -20
  106. oarepo_runtime/services/components.py +0 -429
  107. oarepo_runtime/services/config/draft_link.py +0 -23
  108. oarepo_runtime/services/config/permissions_presets.py +0 -174
  109. oarepo_runtime/services/config/service.py +0 -117
  110. oarepo_runtime/services/custom_fields/__init__.py +0 -80
  111. oarepo_runtime/services/custom_fields/mappings.py +0 -188
  112. oarepo_runtime/services/entity/__init__.py +0 -0
  113. oarepo_runtime/services/entity/config.py +0 -14
  114. oarepo_runtime/services/entity/schema.py +0 -9
  115. oarepo_runtime/services/entity/service.py +0 -48
  116. oarepo_runtime/services/expansions/__init__.py +0 -0
  117. oarepo_runtime/services/expansions/expandable_fields.py +0 -21
  118. oarepo_runtime/services/expansions/service.py +0 -4
  119. oarepo_runtime/services/facets/__init__.py +0 -33
  120. oarepo_runtime/services/facets/base.py +0 -12
  121. oarepo_runtime/services/facets/date.py +0 -72
  122. oarepo_runtime/services/facets/enum.py +0 -11
  123. oarepo_runtime/services/facets/facet_groups_names.py +0 -17
  124. oarepo_runtime/services/facets/max_facet.py +0 -13
  125. oarepo_runtime/services/facets/multilingual_facet.py +0 -33
  126. oarepo_runtime/services/facets/nested_facet.py +0 -32
  127. oarepo_runtime/services/facets/params.py +0 -192
  128. oarepo_runtime/services/facets/year_histogram.py +0 -200
  129. oarepo_runtime/services/files/__init__.py +0 -8
  130. oarepo_runtime/services/files/components.py +0 -62
  131. oarepo_runtime/services/files/service.py +0 -16
  132. oarepo_runtime/services/generators.py +0 -10
  133. oarepo_runtime/services/permissions/__init__.py +0 -3
  134. oarepo_runtime/services/permissions/generators.py +0 -103
  135. oarepo_runtime/services/relations/__init__.py +0 -0
  136. oarepo_runtime/services/relations/components.py +0 -15
  137. oarepo_runtime/services/relations/errors.py +0 -18
  138. oarepo_runtime/services/relations/mapping.py +0 -38
  139. oarepo_runtime/services/schema/cf.py +0 -13
  140. oarepo_runtime/services/schema/i18n_validation.py +0 -7
  141. oarepo_runtime/services/schema/marshmallow.py +0 -44
  142. oarepo_runtime/services/schema/marshmallow_to_json_schema.py +0 -72
  143. oarepo_runtime/services/schema/oneofschema.py +0 -192
  144. oarepo_runtime/services/schema/polymorphic.py +0 -21
  145. oarepo_runtime/services/schema/rdm.py +0 -75
  146. oarepo_runtime/services/schema/rdm_ui.py +0 -156
  147. oarepo_runtime/services/schema/ui.py +0 -251
  148. oarepo_runtime/services/schema/validation.py +0 -70
  149. oarepo_runtime/services/search.py +0 -282
  150. oarepo_runtime/services/service.py +0 -61
  151. oarepo_runtime/tasks.py +0 -6
  152. oarepo_runtime/translations/cs/LC_MESSAGES/messages.mo +0 -0
  153. oarepo_runtime/translations/cs/LC_MESSAGES/messages.po +0 -85
  154. oarepo_runtime/translations/default_translations.py +0 -6
  155. oarepo_runtime/translations/en/LC_MESSAGES/messages.mo +0 -0
  156. oarepo_runtime/translations/en/LC_MESSAGES/messages.po +0 -89
  157. oarepo_runtime/translations/messages.pot +0 -91
  158. oarepo_runtime/uow.py +0 -146
  159. oarepo_runtime/utils/__init__.py +0 -0
  160. oarepo_runtime/utils/functools.py +0 -37
  161. oarepo_runtime/utils/identity_utils.py +0 -35
  162. oarepo_runtime/utils/index.py +0 -11
  163. oarepo_runtime/utils/path.py +0 -97
  164. oarepo_runtime-1.10.2.dist-info/RECORD +0 -163
  165. oarepo_runtime-1.10.2.dist-info/entry_points.txt +0 -16
  166. oarepo_runtime-1.10.2.dist-info/top_level.txt +0 -2
  167. tests/marshmallow_to_json/__init__.py +0 -0
  168. tests/marshmallow_to_json/test_datacite_ui_schema.py +0 -1410
  169. tests/marshmallow_to_json/test_simple_schema.py +0 -52
  170. tests/pkg_data/__init__.py +0 -0
  171. {oarepo_runtime-1.10.2.dist-info → oarepo_runtime-2.0.0.dev3.dist-info}/licenses/LICENSE +0 -0
@@ -1,429 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import inspect
4
- from collections import defaultdict
5
- from dataclasses import dataclass, field
6
- from typing import Any, Type
7
-
8
- from flask import current_app
9
- from invenio_accounts.models import User
10
- from invenio_base.utils import obj_or_import_string
11
- from invenio_drafts_resources.services.records.config import (
12
- RecordServiceConfig as DraftsRecordServiceConfig,
13
- )
14
- from invenio_rdm_records.services.config import RDMRecordServiceConfig
15
- from invenio_records import Record
16
- from invenio_records_resources.services import FileServiceConfig
17
- from invenio_records_resources.services.records.config import (
18
- RecordServiceConfig as RecordsRecordServiceConfig,
19
- )
20
-
21
- from oarepo_runtime.proxies import current_oarepo
22
- from oarepo_runtime.services.custom_fields import (
23
- CustomFields,
24
- CustomFieldsMixin,
25
- InlinedCustomFields,
26
- )
27
- from oarepo_runtime.services.generators import RecordOwners
28
-
29
- try:
30
- from invenio_drafts_resources.services.records.uow import ParentRecordCommitOp
31
- except ImportError:
32
- from invenio_records_resources.services.uow import (
33
- RecordCommitOp as ParentRecordCommitOp,
34
- )
35
-
36
- from invenio_records_resources.services.records.components import ServiceComponent
37
-
38
-
39
- class OwnersComponent(ServiceComponent):
40
- def create(self, identity, *, record, **kwargs):
41
- """Create handler."""
42
- self.add_owner(identity, record)
43
-
44
- def add_owner(self, identity, record, commit=False):
45
- if not hasattr(identity, "id") or not isinstance(identity.id, int):
46
- return
47
-
48
- owners = getattr(record.parent, "owners", None)
49
- if owners is not None:
50
- user = User.query.filter_by(id=identity.id).first()
51
- record.parent.owners.add(user)
52
- if commit:
53
- self.uow.register(ParentRecordCommitOp(record.parent))
54
-
55
- def update(self, identity, *, record, **kwargs):
56
- """Update handler."""
57
- self.add_owner(identity, record, commit=True)
58
-
59
- def update_draft(self, identity, *, record, **kwargs):
60
- """Update handler."""
61
- self.add_owner(identity, record, commit=True)
62
-
63
- def search_drafts(self, identity, search, params, **kwargs):
64
- new_term = RecordOwners().query_filter(identity)
65
- if new_term:
66
- return search.filter(new_term)
67
- return search
68
-
69
-
70
- from datetime import datetime
71
-
72
-
73
- class DateIssuedComponent(ServiceComponent):
74
- def publish(self, identity, data=None, record=None, errors=None, **kwargs):
75
- """Create a new record."""
76
- if "dateIssued" not in record["metadata"]:
77
- record["metadata"]["dateIssued"] = datetime.today().strftime("%Y-%m-%d")
78
-
79
-
80
- class CFRegistry:
81
- def __init__(self):
82
- self.custom_field_names = defaultdict(list)
83
-
84
- def lookup(self, record_type: Type[Record]):
85
- if record_type not in self.custom_field_names:
86
- for fld in inspect.getmembers(
87
- record_type, lambda x: isinstance(x, CustomFieldsMixin)
88
- ):
89
- self.custom_field_names[record_type].append(fld[1])
90
- return self.custom_field_names[record_type]
91
-
92
-
93
- cf_registry = CFRegistry()
94
-
95
-
96
- class CustomFieldsComponent(ServiceComponent):
97
- def create(self, identity, data=None, record=None, **kwargs):
98
- """Create a new record."""
99
- self._set_cf_to_record(record, data)
100
-
101
- def update(self, identity, data=None, record=None, **kwargs):
102
- """Update a record."""
103
- self._set_cf_to_record(record, data)
104
-
105
- def _set_cf_to_record(self, record, data):
106
- for cf in cf_registry.lookup(type(record)):
107
- if isinstance(cf, CustomFields):
108
- setattr(record, cf.attr_name, data.get(cf.key, {}))
109
- elif isinstance(cf, InlinedCustomFields):
110
- config = current_app.config.get(cf.config_key, {})
111
- for c in config:
112
- record[c.name] = data.get(c.name)
113
-
114
-
115
- def process_service_configs(service_config, *additional_components):
116
- processed_components = []
117
- target_classes = {
118
- RDMRecordServiceConfig,
119
- DraftsRecordServiceConfig,
120
- RecordsRecordServiceConfig,
121
- FileServiceConfig,
122
- }
123
-
124
- for end_index, cls in enumerate(type(service_config).mro()):
125
- if cls in target_classes:
126
- break
127
-
128
- # We need this because if the "build" function is present in service_config,
129
- # there are two service_config instances in the MRO (Method Resolution Order) output.
130
- start_index = 2 if hasattr(service_config, "build") else 1
131
-
132
- service_configs = type(service_config).mro()[start_index : end_index + 1]
133
- for config in service_configs:
134
- if hasattr(config, "build"):
135
- config = config.build(current_app)
136
-
137
- if hasattr(config, "components"):
138
- component_property = config.components
139
- if isinstance(component_property, list):
140
- processed_components.extend(component_property)
141
- elif isinstance(component_property, tuple):
142
- processed_components.extend(list(component_property))
143
- else:
144
- raise ValueError(f"{config} component's definition is not supported")
145
-
146
- processed_components.extend(additional_components)
147
-
148
- for excluded_component in current_oarepo.rdm_excluded_components:
149
- if excluded_component in processed_components:
150
- processed_components.remove(excluded_component)
151
-
152
- processed_components = _sort_components(processed_components)
153
- return processed_components
154
-
155
-
156
- @dataclass
157
- class ComponentPlacement:
158
- """Component placement in the list of components.
159
-
160
- This is a helper class used in the component ordering algorithm.
161
- """
162
-
163
- component: Type[ServiceComponent]
164
- """Component to be ordered."""
165
-
166
- depends_on: list[ComponentPlacement] = field(default_factory=list)
167
- """List of components this one depends on.
168
-
169
- The components must be classes of ServiceComponent.
170
- """
171
-
172
- affects: list[ComponentPlacement] = field(default_factory=list)
173
- """List of components that depend on this one."""
174
-
175
- star_depends: bool = False
176
- """True if this component depends on all other components."""
177
-
178
- star_affects: bool = False
179
- """True if this component affects all other components."""
180
-
181
- def __hash__(self) -> int:
182
- return id(self.component)
183
-
184
- def __eq__(self, other: Any) -> bool:
185
- return self.component is other.component
186
-
187
- def __repr__(self) -> str:
188
- depends_on = [d.component.__name__ for d in self.depends_on]
189
- affects = [a.component.__name__ for a in self.affects]
190
- if self.star_affects:
191
- affects.append("*")
192
- if self.star_depends:
193
- depends_on.append("*")
194
- r = [f"<{self.component.__name__}"]
195
- if depends_on:
196
- r.append(f" depends_on: {depends_on}")
197
- if affects:
198
- r.append(f" affects: {affects}")
199
- r.append(">")
200
- return "".join(r)
201
-
202
- def __str__(self) -> str:
203
- return repr(self)
204
-
205
-
206
- def _sort_components(components) -> list[Type[ServiceComponent]]:
207
- """Sort components based on their dependencies while trying to
208
- keep the initial order as far as possible.
209
-
210
- Sorting algorithm:
211
-
212
- 1. Select all "affects" components that has "*" in their "affects" list.
213
- 2. Merge these components preserving other other "affects" and "depends_on" settings
214
- and output these
215
-
216
- 3. put "depends_on: *" components aside for the moment
217
- 4. Sort the remaining components by their dependencies
218
-
219
- 5. process depends_on: * in a similar way as in 2.
220
- """
221
-
222
- placements: list[ComponentPlacement] = _prepare_component_placement(components)
223
-
224
- # placements that must be first as they affect all other components
225
- affects_placements = [p for p in placements if p.star_affects]
226
-
227
- # placements that must be last as they depend on all other components
228
- depends_on_placements = [p for p in placements if p.star_depends]
229
-
230
- # if a component affects another that affects all components,
231
- # add it to affects_placements
232
- #
233
- # A[affects *] B[affects A] C => adds B to affects_placements
234
- modified = True
235
- while modified:
236
- modified = False
237
- for p in placements:
238
- if (
239
- any(q in affects_placements for q in p.affects)
240
- and p not in affects_placements
241
- ):
242
- affects_placements.append(p)
243
- modified = True
244
-
245
- # if a component depends on another that depends on all components,
246
- # add it to depends_on_placements
247
- # A[depends_on *] B[depends_on A] C => adds B to depends_on_placements
248
- modified = True
249
- while modified:
250
- modified = False
251
- for p in placements:
252
- if (
253
- any(q in depends_on_placements for q in p.depends_on)
254
- and p not in depends_on_placements
255
- ):
256
- depends_on_placements.append(p)
257
- modified = True
258
-
259
- # those that do not affect or depend on all components
260
- middle_placements = [
261
- p
262
- for p in placements
263
- if p not in depends_on_placements and p not in affects_placements
264
- ]
265
-
266
- # sort placements inside each group by their respective depends on and affects
267
- # relationships, ignoring the star relationships
268
- ret = []
269
- ret.extend(_sort_placements(affects_placements))
270
- ret.extend(_sort_placements(middle_placements))
271
- ret.extend(_sort_placements(depends_on_placements))
272
- return ret
273
-
274
-
275
- def _sort_placements(placements):
276
- """Sort placements based on their dependencies.
277
-
278
- The algorithm tries to keep the initial order as far as possible,
279
- while still respecting the dependencies.
280
-
281
- At first, for each component that affects another component, the algorithm
282
- moves the affecting component before the affected one one step at a time.
283
-
284
- When no more such moves are possible, the algorithm moves to the next step
285
- and does similar thing for components that depend on another component.
286
-
287
- The algorithm is repeated until all components are sorted. If they can not
288
- be after a set number of iterations, the algorithm raises an exception.
289
- """
290
-
291
- _filter_depends_on_and_affects(placements)
292
-
293
- for _ in range(10):
294
- for __ in range(10):
295
- # move components that affect other components before them
296
- modified = _move_affecting_components(placements)
297
-
298
- # move components that depend on other components after them
299
- if _move_depends_on_components(placements):
300
- modified = True
301
-
302
- # if the order was not modified, we are done
303
- if not modified:
304
- return (p.component for p in placements)
305
- else:
306
- # could not sort the components by simple move. This means that we are
307
- # in a situation where A C B[affects A depends on C] - we will try to
308
- # swap A with C and try again.
309
- _swap_out_of_order_components(placements)
310
-
311
- raise ValueError(f"Can not order components: {placements}")
312
-
313
-
314
- def _swap_out_of_order_components(placements):
315
- for idx, placement in enumerate(placements):
316
-
317
- # we are looking for a situation: A C placement[affects A depends on C]
318
- # so if there are not depends on and affects, try the next one
319
- if not placement.depends_on or not placement.affects:
320
- continue
321
-
322
- depends_on = [(p, placements.index(p)) for p in placement.depends_on]
323
- affects = [(p, placements.index(p)) for p in placement.affects]
324
-
325
- # if there are no indices to swap, continue
326
- if not depends_on or not affects:
327
- continue
328
-
329
- # keep the indices in order
330
- depends_on.sort(key=lambda x: x[1])
331
- affects.sort(key=lambda x: x[1])
332
-
333
- depends_on_indices = [d[1] for d in depends_on]
334
- affects_indices = [a[1] for a in affects]
335
-
336
- swapped_depends_on = [d[0] for d in depends_on]
337
- swapped_affects = [a[0] for a in affects]
338
-
339
- # if the index of the component the current placement depends on
340
- # is lower that any of the components that depend on the current placement,
341
- # we are ok as the placement can be moved to the space between them,
342
- # so just continue
343
- if max(depends_on_indices) < min(affects_indices):
344
- continue
345
-
346
- # add all to an array and sort them. This way depends on will be after
347
- # affects, keeping the positions inside the group
348
- indices = sorted([*affects_indices, *depends_on_indices])
349
-
350
- for idx, dep in zip(
351
- indices,
352
- [*swapped_depends_on, *swapped_affects],
353
- ):
354
- placements[idx] = dep
355
-
356
-
357
- def _filter_depends_on_and_affects(placements):
358
- """Filter out dependencies on components that are not in the placements list."""
359
- for placement in placements:
360
- placement.depends_on = [p for p in placement.depends_on if p in placements]
361
- placement.affects = [p for p in placement.affects if p in placements]
362
-
363
-
364
- def _move_affecting_components(placements):
365
- modified = False
366
-
367
- for idx, placement in list(enumerate(placements)):
368
- if not placement.affects:
369
- continue
370
- min_index = min(placements.index(a) for a in placement.affects)
371
- if min_index < idx:
372
- placements.remove(placement)
373
- placements.insert(min_index, placement)
374
- modified = True
375
- return modified
376
-
377
-
378
- def _move_depends_on_components(placements):
379
- modified = False
380
- for idx, placement in reversed(list(enumerate(placements))):
381
- if not placement.depends_on:
382
- continue
383
- max_index = max(placements.index(a) for a in placement.depends_on)
384
- if max_index > idx:
385
- placements.remove(placement)
386
- placements.insert(max_index, placement)
387
- modified = True
388
- return modified
389
-
390
-
391
- def _matching_placements(placements, dep_class_or_factory):
392
- for pl in placements:
393
- pl_component = pl.component
394
- if not inspect.isclass(pl_component):
395
- pl_component = type(pl_component(service=object()))
396
- if issubclass(pl_component, dep_class_or_factory):
397
- yield pl
398
-
399
-
400
- def _prepare_component_placement(components) -> list[ComponentPlacement]:
401
- """Convert components to ComponentPlacement instances and resolve dependencies."""
402
- placements = []
403
- for idx, c in enumerate(components):
404
- placement = ComponentPlacement(component=c)
405
- placements.append(placement)
406
-
407
- # direct dependencies
408
- for idx, placement in enumerate(placements):
409
- placements_without_this = placements[:idx] + placements[idx + 1 :]
410
- placement.star_depends = "*" in getattr(placement.component, "depends_on", [])
411
- placement.star_affects = "*" in getattr(placement.component, "affects", [])
412
-
413
- for dep in getattr(placement.component, "depends_on", []):
414
- if dep == "*":
415
- continue
416
- dep = obj_or_import_string(dep)
417
- for pl in _matching_placements(placements_without_this, dep):
418
- if pl not in placement.depends_on:
419
- placement.depends_on.append(pl)
420
-
421
- for dep in getattr(placement.component, "affects", []):
422
- if dep == "*":
423
- continue
424
- dep = obj_or_import_string(dep)
425
- for pl in _matching_placements(placements_without_this, dep):
426
- if pl not in placement.affects:
427
- placement.affects.append(pl)
428
-
429
- return placements
@@ -1,23 +0,0 @@
1
- from invenio_records_resources.services import RecordLink
2
-
3
- from oarepo_runtime.records.drafts import get_draft
4
-
5
-
6
- class DraftLink(RecordLink):
7
- """Draft link."""
8
-
9
- def __init__(self, *args, **kwargs):
10
- """Initialize draft link."""
11
- super().__init__(*args, **kwargs)
12
-
13
- @staticmethod
14
- def vars(record, vars):
15
- """Variables for the URI template."""
16
- # Some records don't have record.pid.pid_value yet (e.g. drafts)
17
- RecordLink.vars(record, vars)
18
- draft_record = get_draft(record)
19
-
20
- if draft_record:
21
- pid_value = getattr(draft_record.pid, "pid_value", None)
22
- if pid_value:
23
- vars.update({"id": pid_value})
@@ -1,174 +0,0 @@
1
- from invenio_records_permissions import RecordPermissionPolicy
2
- from invenio_records_permissions.generators import (
3
- AnyUser,
4
- AuthenticatedUser,
5
- SystemProcess,
6
- )
7
-
8
-
9
- class OaiHarvesterPermissionPolicy(RecordPermissionPolicy):
10
- """record policy for oai harvester (by default same as read only)"""
11
-
12
- can_search = [SystemProcess(), AnyUser()]
13
- can_read = [SystemProcess(), AnyUser()]
14
- can_create = [SystemProcess()]
15
- can_update = [SystemProcess()]
16
- can_delete = [SystemProcess()]
17
- can_manage = [SystemProcess()]
18
-
19
- can_create_files = [SystemProcess()]
20
- can_set_content_files = [SystemProcess()]
21
- can_get_content_files = [AnyUser(), SystemProcess()]
22
- can_commit_files = [SystemProcess()]
23
- can_read_files = [AnyUser(), SystemProcess()]
24
- can_update_files = [SystemProcess()]
25
- can_delete_files = [SystemProcess()]
26
- can_manage_files = [SystemProcess()]
27
-
28
- can_edit = [SystemProcess()]
29
- can_new_version = [SystemProcess()]
30
- can_search_drafts = [SystemProcess()]
31
- can_read_draft = [SystemProcess()]
32
- can_update_draft = [SystemProcess()]
33
- can_delete_draft = [SystemProcess()]
34
- can_publish = [SystemProcess()]
35
- can_search_versions = [SystemProcess()]
36
- can_draft_create_files = [SystemProcess()]
37
- can_draft_set_content_files = [SystemProcess()]
38
- can_draft_get_content_files = [SystemProcess()]
39
- can_draft_commit_files = [SystemProcess()]
40
- can_draft_read_files = [SystemProcess()]
41
- can_draft_update_files = [SystemProcess()]
42
- can_draft_delete_files = [SystemProcess()]
43
-
44
-
45
- class ReadOnlyPermissionPolicy(RecordPermissionPolicy):
46
- """record policy for read only repository"""
47
-
48
- can_search = [SystemProcess(), AnyUser()]
49
- can_read = [SystemProcess(), AnyUser()]
50
- can_create = [SystemProcess()]
51
- can_update = [SystemProcess()]
52
- can_delete = [SystemProcess()]
53
- can_manage = [SystemProcess()]
54
-
55
- can_create_files = [SystemProcess()]
56
- can_set_content_files = [SystemProcess()]
57
- can_get_content_files = [AnyUser(), SystemProcess()]
58
- can_commit_files = [SystemProcess()]
59
- can_read_files = [AnyUser(), SystemProcess()]
60
- can_update_files = [SystemProcess()]
61
- can_delete_files = [SystemProcess()]
62
- can_list_files = [SystemProcess()]
63
- can_manage_files = [SystemProcess()]
64
-
65
- can_edit = [SystemProcess()]
66
- can_new_version = [SystemProcess()]
67
- can_search_drafts = [SystemProcess()]
68
- can_read_draft = [SystemProcess()]
69
- can_update_draft = [SystemProcess()]
70
- can_delete_draft = [SystemProcess()]
71
- can_publish = [SystemProcess()]
72
- can_search_versions = [SystemProcess()]
73
- can_draft_create_files = [SystemProcess()]
74
- can_draft_set_content_files = [SystemProcess()]
75
- can_draft_get_content_files = [SystemProcess()]
76
- can_draft_commit_files = [SystemProcess()]
77
- can_draft_read_files = [SystemProcess()]
78
- can_draft_update_files = [SystemProcess()]
79
- can_draft_delete_files = [SystemProcess()]
80
-
81
- can_add_community = [SystemProcess()]
82
- can_remove_community = [SystemProcess()]
83
-
84
- can_read_deleted = [SystemProcess()]
85
- can_manage_record_access = [SystemProcess()]
86
- can_lift_embargo = [SystemProcess()]
87
-
88
-
89
- class EveryonePermissionPolicy(RecordPermissionPolicy):
90
- """record policy for read only repository"""
91
-
92
- can_search = [SystemProcess(), AnyUser()]
93
- can_read = [SystemProcess(), AnyUser()]
94
- can_create = [SystemProcess(), AnyUser()]
95
- can_update = [SystemProcess(), AnyUser()]
96
- can_delete = [SystemProcess(), AnyUser()]
97
- can_manage = [SystemProcess(), AnyUser()]
98
-
99
- can_create_files = [SystemProcess(), AnyUser()]
100
- can_set_content_files = [SystemProcess(), AnyUser()]
101
- can_get_content_files = [SystemProcess(), AnyUser()]
102
- can_commit_files = [SystemProcess(), AnyUser()]
103
- can_read_files = [SystemProcess(), AnyUser()]
104
- can_update_files = [SystemProcess(), AnyUser()]
105
- can_delete_files = [SystemProcess(), AnyUser()]
106
- can_list_files = [SystemProcess(), AnyUser()]
107
- can_manage_files = [SystemProcess(), AnyUser()]
108
-
109
- can_edit = [SystemProcess(), AnyUser()]
110
- can_new_version = [SystemProcess(), AnyUser()]
111
- can_search_drafts = [SystemProcess(), AnyUser()]
112
- can_read_draft = [SystemProcess(), AnyUser()]
113
- can_search_versions = [SystemProcess(), AnyUser()]
114
- can_update_draft = [SystemProcess(), AnyUser()]
115
- can_delete_draft = [SystemProcess(), AnyUser()]
116
- can_publish = [SystemProcess(), AnyUser()]
117
- can_draft_create_files = [SystemProcess(), AnyUser()]
118
- can_draft_set_content_files = [SystemProcess(), AnyUser()]
119
- can_draft_get_content_files = [SystemProcess(), AnyUser()]
120
- can_draft_commit_files = [SystemProcess(), AnyUser()]
121
- can_draft_read_files = [SystemProcess(), AnyUser()]
122
- can_draft_update_files = [SystemProcess(), AnyUser()]
123
- can_draft_delete_files = [SystemProcess(), AnyUser()]
124
-
125
- can_add_community = [SystemProcess(), AnyUser()]
126
- can_remove_community = [SystemProcess(), AnyUser()]
127
-
128
- can_read_deleted = [SystemProcess(), AnyUser()]
129
- can_manage_record_access = [SystemProcess(), AnyUser()]
130
- can_lift_embargo = [SystemProcess(), AnyUser()]
131
-
132
-
133
- class AuthenticatedPermissionPolicy(RecordPermissionPolicy):
134
- """record policy for read only repository"""
135
-
136
- can_search = [SystemProcess(), AuthenticatedUser()]
137
- can_read = [SystemProcess(), AnyUser()]
138
- can_read_deleted = [SystemProcess(), AnyUser()]
139
- can_create = [SystemProcess(), AuthenticatedUser()]
140
- can_update = [SystemProcess(), AuthenticatedUser()]
141
- can_delete = [SystemProcess(), AuthenticatedUser()]
142
- can_manage = [SystemProcess(), AuthenticatedUser()]
143
-
144
- can_create_files = [SystemProcess(), AuthenticatedUser()]
145
- can_set_content_files = [SystemProcess(), AuthenticatedUser()]
146
- can_get_content_files = [SystemProcess(), AnyUser()]
147
- can_commit_files = [SystemProcess(), AuthenticatedUser()]
148
- can_read_files = [SystemProcess(), AnyUser()]
149
- can_update_files = [SystemProcess(), AuthenticatedUser()]
150
- can_list_files = [SystemProcess(), AuthenticatedUser()]
151
- can_manage_files = [SystemProcess(), AuthenticatedUser()]
152
- can_delete_files = [SystemProcess(), AuthenticatedUser()]
153
-
154
- can_edit = [SystemProcess(), AuthenticatedUser()]
155
- can_new_version = [SystemProcess(), AuthenticatedUser()]
156
- can_search_drafts = [SystemProcess(), AuthenticatedUser()]
157
- can_read_draft = [SystemProcess(), AnyUser()]
158
- can_update_draft = [SystemProcess(), AuthenticatedUser()]
159
- can_delete_draft = [SystemProcess(), AuthenticatedUser()]
160
- can_publish = [SystemProcess(), AuthenticatedUser()]
161
- can_search_versions = [SystemProcess(), AuthenticatedUser()]
162
- can_draft_create_files = [SystemProcess(), AuthenticatedUser()]
163
- can_draft_set_content_files = [SystemProcess(), AuthenticatedUser()]
164
- can_draft_get_content_files = [SystemProcess(), AuthenticatedUser()]
165
- can_draft_commit_files = [SystemProcess(), AuthenticatedUser()]
166
- can_draft_read_files = [SystemProcess(), AuthenticatedUser()]
167
- can_draft_update_files = [SystemProcess(), AuthenticatedUser()]
168
- can_draft_delete_files = [SystemProcess(), AuthenticatedUser()]
169
-
170
- can_add_community = [SystemProcess(), AuthenticatedUser()]
171
- can_remove_community = [SystemProcess(), AuthenticatedUser()]
172
-
173
- can_manage_record_access = [SystemProcess(), AuthenticatedUser()]
174
- can_lift_embargo = [SystemProcess(), AuthenticatedUser()]