oarepo-runtime 2.0.0.dev15__tar.gz → 2.0.0.dev18__tar.gz

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 (37) hide show
  1. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/PKG-INFO +1 -1
  2. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/__init__.py +1 -1
  3. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/ext.py +11 -0
  4. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/services/generators.py +53 -6
  5. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/.gitignore +0 -0
  6. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/LICENSE +0 -0
  7. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/README.md +0 -0
  8. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/api.py +0 -0
  9. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/cli/__init__.py +0 -0
  10. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/cli/search.py +0 -0
  11. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/config.py +0 -0
  12. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/proxies.py +0 -0
  13. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/py.typed +0 -0
  14. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/records/__init__.py +0 -0
  15. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/records/drafts.py +0 -0
  16. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/records/mapping.py +0 -0
  17. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/records/pid_providers.py +0 -0
  18. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/records/systemfields/__init__.py +0 -0
  19. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/records/systemfields/mapping.py +0 -0
  20. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/records/systemfields/publication_status.py +0 -0
  21. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/resources/__init__.py +0 -0
  22. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/resources/config.py +0 -0
  23. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/services/__init__.py +0 -0
  24. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/services/config/__init__.py +0 -0
  25. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/services/config/components.py +0 -0
  26. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/services/config/link_conditions.py +0 -0
  27. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/services/config/permissions.py +0 -0
  28. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/services/facets/__init__.py +0 -0
  29. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/services/facets/params.py +0 -0
  30. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/services/records/__init__.py +0 -0
  31. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/services/records/links.py +0 -0
  32. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/services/records/mapping.py +0 -0
  33. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/services/results.py +0 -0
  34. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/services/schema/__init__.py +0 -0
  35. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/services/schema/i18n.py +0 -0
  36. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/oarepo_runtime/services/schema/i18n_ui.py +0 -0
  37. {oarepo_runtime-2.0.0.dev15 → oarepo_runtime-2.0.0.dev18}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oarepo-runtime
3
- Version: 2.0.0.dev15
3
+ Version: 2.0.0.dev18
4
4
  Summary: A set of runtime extensions of Invenio repository
5
5
  Project-URL: Homepage, https://github.com/oarepo/oarepo-runtime
6
6
  License-Expression: MIT
@@ -19,6 +19,6 @@ from .api import Model
19
19
  from .ext import OARepoRuntime
20
20
  from .proxies import current_runtime
21
21
 
22
- __version__ = "2.0.0dev15"
22
+ __version__ = "2.0.0dev18"
23
23
 
24
24
  __all__ = ("Model", "OARepoRuntime", "__version__", "current_runtime")
@@ -29,6 +29,7 @@ if TYPE_CHECKING: # pragma: no cover
29
29
  from flask import Flask
30
30
  from invenio_drafts_resources.records.api import Draft
31
31
  from invenio_records_resources.services.base.service import Service
32
+ from invenio_records_resources.services.files.service import FileService
32
33
  from invenio_records_resources.services.records import RecordService
33
34
 
34
35
  from .api import Model
@@ -170,6 +171,16 @@ class OARepoRuntime:
170
171
  raise ValueError("Need to pass a record instance, got None")
171
172
  return self.get_record_service_for_record_class(type(record))
172
173
 
174
+ def get_file_service_for_record(self, record: Any) -> FileService | None:
175
+ """Return the file service for the given record (draft or published)."""
176
+ model = self.models_by_record_class.get(type(record))
177
+ if not model:
178
+ raise KeyError(f"No model found for record class '{type(record).__name__}'.")
179
+ is_draft = getattr(record, "is_draft", False)
180
+ if is_draft:
181
+ return model.draft_file_service
182
+ return model.file_service
183
+
173
184
  def get_record_service_for_record_class(self, record_cls: type[RecordBase]) -> RecordService:
174
185
  """Retrieve the service associated with a given record class."""
175
186
  for t in record_cls.mro():
@@ -10,20 +10,21 @@
10
10
 
11
11
  from __future__ import annotations
12
12
 
13
- from abc import abstractmethod
13
+ from abc import ABC, abstractmethod
14
+ from itertools import chain
14
15
  from typing import TYPE_CHECKING, Any, override
15
16
 
16
17
  from invenio_records_permissions.generators import (
17
18
  ConditionalGenerator as InvenioConditionalGenerator,
18
19
  )
19
20
  from invenio_records_permissions.generators import Generator as InvenioGenerator
21
+ from invenio_search.engine import dsl
20
22
 
21
23
  if TYPE_CHECKING:
22
24
  from collections.abc import Sequence
23
25
 
24
26
  from flask_principal import Need
25
27
  from invenio_records_resources.records.api import Record
26
- from invenio_search.engine import dsl
27
28
 
28
29
 
29
30
  class Generator(InvenioGenerator):
@@ -45,7 +46,7 @@ class Generator(InvenioGenerator):
45
46
  return super().query_filter(**kwargs) # type: ignore[no-any-return]
46
47
 
47
48
 
48
- class ConditionalGenerator(InvenioConditionalGenerator):
49
+ class ConditionalGenerator(InvenioConditionalGenerator, ABC):
49
50
  """Typed conditional generator.
50
51
 
51
52
  This class will be removed when invenio has proper type stubs.
@@ -58,7 +59,7 @@ class ConditionalGenerator(InvenioConditionalGenerator):
58
59
  @abstractmethod
59
60
  def _condition(self, **kwargs: Any) -> bool:
60
61
  """Condition to choose generators set."""
61
- raise NotImplementedError # pragma: nocover
62
+ raise NotImplementedError # pragma: no cover
62
63
 
63
64
  def _generators(self, record: Record, **kwargs: Any) -> Sequence[InvenioGenerator]:
64
65
  """Get the "then" or "else" generators."""
@@ -72,6 +73,52 @@ class ConditionalGenerator(InvenioConditionalGenerator):
72
73
  def excludes(self, **kwargs: Any) -> Sequence[Need]: # type: ignore[override]
73
74
  return super().excludes(**kwargs) # type: ignore[no-any-return]
74
75
 
76
+ @abstractmethod
77
+ def _query_instate(self, **context: Any) -> dsl.query.Query:
78
+ raise NotImplementedError # pragma: no cover
79
+
75
80
  @override
76
- def query_filter(self, **kwargs: Any) -> dsl.query.Query: # type: ignore[reportIncompatibleMethodOverride]
77
- return super().query_filter(**kwargs) # type: ignore[no-any-return]
81
+ def query_filter(self, **context: Any) -> dsl.query.Query: # type: ignore[reportIncompatibleMethodOverride]
82
+ """Apply then or else filter."""
83
+ then_query = super()._make_query(self.then_, **context)
84
+ else_query = super()._make_query(self.else_, **context)
85
+
86
+ q_instate = self._query_instate(**context)
87
+ q_outstate = ~q_instate
88
+
89
+ if then_query and else_query:
90
+ ret = (q_instate & then_query) | (q_outstate & else_query)
91
+ elif then_query:
92
+ ret = q_instate & then_query
93
+ elif else_query:
94
+ ret = q_outstate & else_query
95
+ else:
96
+ ret = dsl.Q("match_none")
97
+
98
+ return ret
99
+
100
+
101
+ class AggregateGenerator(Generator, ABC):
102
+ """Superclass for generators aggregating multiple generators."""
103
+
104
+ @abstractmethod
105
+ def _generators(self, **context: Any) -> Sequence[InvenioGenerator]:
106
+ """Return the generators."""
107
+ raise NotImplementedError # pragma: no cover
108
+
109
+ @override
110
+ def needs(self, **context: Any) -> Sequence[Need]:
111
+ """Get the needs from the policy."""
112
+ needs = [generator.needs(**context) for generator in self._generators(**context)]
113
+ return list(chain.from_iterable(needs))
114
+
115
+ @override
116
+ def excludes(self, **context: Any) -> Sequence[Need]:
117
+ """Get the excludes from the policy."""
118
+ excludes = [generator.excludes(**context) for generator in self._generators(**context)]
119
+ return list(chain.from_iterable(excludes))
120
+
121
+ @override
122
+ def query_filter(self, **context: Any) -> dsl.query.Query:
123
+ """Search filters."""
124
+ return ConditionalGenerator._make_query(self._generators(**context), **context) # noqa SLF001 # type: ignore[reportReturnType]