oarepo-runtime 1.5.74__py3-none-any.whl → 1.5.76__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.
@@ -15,12 +15,16 @@ def get_record_service_for_record(record):
15
15
  if not record:
16
16
  return None
17
17
  if "OAREPO_PRIMARY_RECORD_SERVICE" in current_app.config:
18
- service_id = current_app.config["OAREPO_PRIMARY_RECORD_SERVICE"][type(record)]
19
- return current_service_registry.get(service_id)
18
+ return get_record_service_for_record_class(type(record))
20
19
  else:
21
20
  return get_record_service_for_record_deprecated(record)
22
21
 
23
22
 
23
+ def get_record_service_for_record_class(record_cls):
24
+ service_id = current_app.config["OAREPO_PRIMARY_RECORD_SERVICE"][record_cls]
25
+ return current_service_registry.get(service_id)
26
+
27
+
24
28
  @deprecated(
25
29
  version="1.5.43", reason="Please recompile model to remove this deprecation warning"
26
30
  )
@@ -44,7 +48,6 @@ def get_record_service_for_record_deprecated(record):
44
48
  if service_record == type(record):
45
49
  return svc
46
50
 
47
-
48
51
  def get_file_service_for_record_class(record_class):
49
52
  if not record_class:
50
53
  return None
@@ -56,6 +59,9 @@ def get_file_service_for_record_class(record_class):
56
59
  continue
57
60
  return svc
58
61
 
62
+ def get_file_service_for_file_record_class(file_record_class):
63
+ record_class = file_record_class.record_cls
64
+ return get_file_service_for_record_class(record_class)
59
65
 
60
66
  def get_file_service_for_record_service(
61
67
  record_service, check_draft_files=True, record=None
@@ -1,5 +1,6 @@
1
1
  from typing import Type
2
2
 
3
+ from deprecated import deprecated
3
4
  from invenio_records_resources.records import Record
4
5
 
5
6
 
@@ -11,20 +12,39 @@ def select_record_for_update(record_cls: Type[Record], persistent_identifier):
11
12
  return record_cls(obj.data, model=obj)
12
13
 
13
14
 
14
- def is_published_record(record, ctx):
15
- """Shortcut for links to determine if record is a published record."""
16
- return not getattr(record, "is_draft", False)
15
+ @deprecated("Moved to oarepo_runtime.services.config.link_conditions")
16
+ def is_published_record_function():
17
+ """Shortcut for links to determine if record is a published.
17
18
 
19
+ This function is deprecated. Use oarepo_runtime.services.config.is_published_record instead.
20
+ """
21
+ from oarepo_runtime.services.config.link_conditions import is_published_record
18
22
 
19
- def is_draft_record(record, ctx):
20
- """Shortcut for links to determine if record is a draft record."""
21
- return getattr(record, "is_draft", False)
23
+ return is_published_record()
22
24
 
23
25
 
24
- def has_draft(record, ctx):
25
- """Shortcut for links to determine if record is either a draft or a published one with a draft associated."""
26
- if getattr(record, "is_draft", False):
27
- return True
28
- if getattr(record, "has_draft", False):
29
- return True
30
- return False
26
+ @deprecated("Moved to oarepo_runtime.services.config.link_conditions")
27
+ def is_draft_record_function():
28
+ """Shortcut for links to determine if record is a draft record.
29
+
30
+ This function is deprecated. Use oarepo_runtime.services.config.is_draft_record instead.
31
+ """
32
+ from oarepo_runtime.services.config.link_conditions import is_draft_record
33
+
34
+ return is_draft_record()
35
+
36
+
37
+ @deprecated("Moved to oarepo_runtime.services.config.link_conditions")
38
+ def has_draft_function():
39
+ """Shortcut for links to determine if record is either a draft or a published one with a draft associated.
40
+
41
+ This function is deprecated. Use oarepo_runtime.services.config.has_draft instead.
42
+ """
43
+ from oarepo_runtime.services.config.link_conditions import has_draft
44
+
45
+ return has_draft()
46
+
47
+
48
+ is_published_record = is_published_record_function()
49
+ is_draft = is_draft_record_function()
50
+ has_draft = has_draft_function()
@@ -1,3 +1,11 @@
1
+ from .link_conditions import (
2
+ has_draft,
3
+ has_permission,
4
+ has_permission_file_service,
5
+ has_published_record,
6
+ is_draft_record,
7
+ is_published_record,
8
+ )
1
9
  from .permissions_presets import (
2
10
  AuthenticatedPermissionPolicy,
3
11
  EveryonePermissionPolicy,
@@ -12,4 +20,10 @@ __all__ = (
12
20
  "ReadOnlyPermissionPolicy",
13
21
  "EveryonePermissionPolicy",
14
22
  "AuthenticatedPermissionPolicy",
23
+ "is_published_record",
24
+ "is_draft_record",
25
+ "has_draft",
26
+ "has_permission",
27
+ "has_permission_file_service",
28
+ "has_published_record",
15
29
  )
@@ -0,0 +1,101 @@
1
+ from abc import abstractmethod
2
+
3
+ from invenio_pidstore.errors import PIDDoesNotExistError, PIDUnregistered
4
+ from invenio_records_resources.records.api import FileRecord
5
+ from invenio_records.api import RecordBase
6
+ from invenio_records_resources.records.api import Record
7
+ from logging import getLogger
8
+ from ...datastreams.utils import (
9
+ get_file_service_for_file_record_class,
10
+ get_file_service_for_record_class,
11
+ get_record_service_for_record,
12
+ )
13
+ log = getLogger(__name__)
14
+
15
+ class Condition:
16
+
17
+ @abstractmethod
18
+ def __call__(self, obj, ctx: dict):
19
+ raise NotImplementedError
20
+
21
+ def __and__(self, other):
22
+ return type(
23
+ "CompositeCondition",
24
+ (Condition,),
25
+ {"__call__": lambda _, obj, ctx: self(obj, ctx) and other(obj, ctx)},
26
+ )()
27
+
28
+ def __or__(self, other):
29
+ return type(
30
+ "CompositeCondition",
31
+ (Condition,),
32
+ {"__call__": lambda _, obj, ctx: self(obj, ctx) or other(obj, ctx)},
33
+ )()
34
+
35
+
36
+ class is_published_record(Condition):
37
+ """Shortcut for links to determine if record is a published record."""
38
+
39
+ def __call__(self, obj: Record, ctx: dict):
40
+ return not getattr(obj, "is_draft", False)
41
+
42
+
43
+ class is_draft_record(Condition):
44
+ """Shortcut for links to determine if record is a draft record."""
45
+
46
+ def __call__(self, obj: Record, ctx: dict):
47
+ return getattr(obj, "is_draft", False)
48
+
49
+
50
+ class has_draft(Condition):
51
+ """Shortcut for links to determine if record is either a draft or a published one with a draft associated."""
52
+
53
+ def __call__(self, obj: Record, ctx: dict):
54
+ if getattr(obj, "is_draft", False):
55
+ return True
56
+ if getattr(obj, "has_draft", False):
57
+ return True
58
+ return False
59
+
60
+
61
+ class has_permission(Condition):
62
+ def __init__(self, action_name):
63
+ self.action_name = action_name
64
+
65
+ def __call__(self, obj: RecordBase, ctx: dict):
66
+ if isinstance(obj, FileRecord):
67
+ obj = obj.record
68
+ service = get_record_service_for_record(obj)
69
+ try:
70
+ return service.check_permission(
71
+ action_name=self.action_name, record=obj, **ctx
72
+ )
73
+ except Exception as e:
74
+ log.exception(f"Unexpected exception {e}.")
75
+
76
+
77
+
78
+ class has_permission_file_service(has_permission):
79
+
80
+ def __call__(self, obj: RecordBase, ctx: dict):
81
+ if isinstance(obj, FileRecord):
82
+ service = get_file_service_for_file_record_class(type(obj))
83
+ else:
84
+ service = get_file_service_for_record_class(type(obj))
85
+ try:
86
+ return service.check_permission(
87
+ action_name=self.action_name, record=obj, **ctx
88
+ )
89
+ except Exception as e:
90
+ log.exception(f"Unexpected exception {e}.")
91
+
92
+
93
+ class has_published_record(Condition):
94
+
95
+ def __call__(self, obj: Record, ctx: dict):
96
+ service = get_record_service_for_record(obj)
97
+ try:
98
+ service.record_cls.pid.resolve(obj["id"])
99
+ except (PIDUnregistered, PIDDoesNotExistError):
100
+ return False
101
+ return True
@@ -56,6 +56,7 @@ class ReadOnlyPermissionPolicy(RecordPermissionPolicy):
56
56
  can_read_files = [AnyUser(), SystemProcess()]
57
57
  can_update_files = [SystemProcess()]
58
58
  can_delete_files = [SystemProcess()]
59
+ can_list_files = [SystemProcess()]
59
60
 
60
61
  can_edit = [SystemProcess()]
61
62
  can_new_version = [SystemProcess()]
@@ -92,6 +93,7 @@ class EveryonePermissionPolicy(RecordPermissionPolicy):
92
93
  can_read_files = [SystemProcess(), AnyUser()]
93
94
  can_update_files = [SystemProcess(), AnyUser()]
94
95
  can_delete_files = [SystemProcess(), AnyUser()]
96
+ can_list_files = [SystemProcess(), AnyUser()]
95
97
 
96
98
  can_edit = [SystemProcess(), AnyUser()]
97
99
  can_new_version = [SystemProcess(), AnyUser()]
@@ -128,6 +130,7 @@ class AuthenticatedPermissionPolicy(RecordPermissionPolicy):
128
130
  can_read_files = [SystemProcess(), AnyUser()]
129
131
  can_update_files = [SystemProcess(), AuthenticatedUser()]
130
132
  can_delete_files = [SystemProcess(), AuthenticatedUser()]
133
+ can_list_files = [SystemProcess(), AuthenticatedUser()]
131
134
 
132
135
  can_edit = [SystemProcess(), AuthenticatedUser()]
133
136
  can_new_version = [SystemProcess(), AuthenticatedUser()]
@@ -0,0 +1,3 @@
1
+ from .links import pagination_links_html
2
+
3
+ __all__ = ("pagination_links_html",)
@@ -0,0 +1,21 @@
1
+ from invenio_records_resources.services.base.links import Link
2
+
3
+ def pagination_links_html(tpl: str)->dict[str, Link]:
4
+ """Create pagination links (prev/selv/next) from the same template."""
5
+ return {
6
+ "prev_html": Link(
7
+ tpl,
8
+ when=lambda pagination, ctx: pagination.has_prev,
9
+ vars=lambda pagination, vars: vars["args"].update(
10
+ {"page": pagination.prev_page.page}
11
+ ),
12
+ ),
13
+ "self_html": Link(tpl),
14
+ "next_html": Link(
15
+ tpl,
16
+ when=lambda pagination, ctx: pagination.has_next,
17
+ vars=lambda pagination, vars: vars["args"].update(
18
+ {"page": pagination.next_page.page}
19
+ ),
20
+ ),
21
+ }
@@ -114,7 +114,12 @@ class RecordList(BaseRecordList):
114
114
  record=record,
115
115
  ),
116
116
  )
117
- if self._links_item_tpl:
117
+ if hasattr(self._service.config, "links_search_item"):
118
+ links_tpl = self._service.config.search_item_links_template(
119
+ self._service.config.links_search_item
120
+ )
121
+ projection["links"] = links_tpl.expand(self._identity, record)
122
+ elif self._links_item_tpl:
118
123
  projection["links"] = self._links_item_tpl.expand(
119
124
  self._identity, record
120
125
  )
@@ -122,7 +127,7 @@ class RecordList(BaseRecordList):
122
127
  for c in self.components:
123
128
  c.update_data(
124
129
  identity=self._identity,
125
- record=self._record,
130
+ record=record,
126
131
  projection=projection,
127
132
  expand=self._expand,
128
133
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: oarepo-runtime
3
- Version: 1.5.74
3
+ Version: 1.5.76
4
4
  Summary: A set of runtime extensions of Invenio repository
5
5
  Description-Content-Type: text/markdown
6
6
  License-File: LICENSE
@@ -26,7 +26,7 @@ oarepo_runtime/datastreams/semi_asynchronous.py,sha256=kNc6BBnV6oFoY9kHgf5l8fd1w
26
26
  oarepo_runtime/datastreams/synchronous.py,sha256=t5lfnMkLqy3jK5zMl-nIuA0HlMPiHGjwCqZ8XQP-3GM,2595
27
27
  oarepo_runtime/datastreams/transformers.py,sha256=q5KzHPl2kJg7HP1BtKJ7F_UMqg_7L1ZGDX0O7s8D6UI,521
28
28
  oarepo_runtime/datastreams/types.py,sha256=KZjblc3T_UFFW7LrMDmiR8lqVf86V484LAHj6yg05EI,9908
29
- oarepo_runtime/datastreams/utils.py,sha256=GYpVdwMks0GRdz8DBpErdiV_2aJ-3V1uAkOHyz67bZw,4001
29
+ oarepo_runtime/datastreams/utils.py,sha256=w24qRRw1ZawPFbgqtxhpYnxPnghSn0pp49JLLy8wTms,4280
30
30
  oarepo_runtime/datastreams/readers/__init__.py,sha256=P1n3llZQ3AFHnSPbeT1VaCJcEtRFz9AbHfjkZv5LG7s,1103
31
31
  oarepo_runtime/datastreams/readers/attachments.py,sha256=A7EC1TqyTHG-go5DIaRotlBSOm6o9hGqAKyVVAceCRU,1956
32
32
  oarepo_runtime/datastreams/readers/excel.py,sha256=CM8lr8mejN7NgoK5TJb1oXpjq0HxklQKMsuj3uqjTjA,3653
@@ -44,7 +44,7 @@ oarepo_runtime/i18n/__init__.py,sha256=h0knW_HwiyIt5TBHfdGqN7_BBYfpz1Fw6zhVy0C28
44
44
  oarepo_runtime/info/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
45
  oarepo_runtime/info/check.py,sha256=6O5Wjsdorx4eqiBiPU3z33XhCiwPTO_FGkzMDK7UH6I,3049
46
46
  oarepo_runtime/info/views.py,sha256=q9PG46aM-1ihaVxJGjfcD5HvJWanM28gMefao8FIQk4,12440
47
- oarepo_runtime/records/__init__.py,sha256=3vzRsAPxl4d5QOnGyls-vUg4E6PunmR4ACObtacMAIQ,1038
47
+ oarepo_runtime/records/__init__.py,sha256=JUf9_o09_6q4vuG43JzhSeTu7c-m_CVDSmgTQ7epYEo,1776
48
48
  oarepo_runtime/records/dumpers/__init__.py,sha256=OmzNhLdMNKibmCksnj9eTX9xPBG30dziiK3j3bAAp3k,233
49
49
  oarepo_runtime/records/dumpers/edtf_interval.py,sha256=YCShZAoqBQYaxVilEVotS-jXZsxxoXO67yu2urhkaMA,1198
50
50
  oarepo_runtime/records/dumpers/multilingual_dumper.py,sha256=PbNFCLsiH4XV3E1v8xga_fzlcEImHy8OXn_UKh_8VBU,1090
@@ -73,10 +73,11 @@ oarepo_runtime/resources/localized_ui_json_serializer.py,sha256=3V9cJaG_e1PMXKVX
73
73
  oarepo_runtime/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
74
  oarepo_runtime/services/components.py,sha256=k--zu1RinwoKzg5qHp4H-Ddp9AFyjMJ97fydQ0DvI-A,4238
75
75
  oarepo_runtime/services/generators.py,sha256=j87HitHA_w2awsz0C5IAAJ0qjg9JMtvdO3dvh6FQyfg,250
76
- oarepo_runtime/services/results.py,sha256=HVBEPAMFwwCJDqBhaP3t3ekH1CpNDtE6ovVNKgWxuw8,5409
76
+ oarepo_runtime/services/results.py,sha256=Ap2mUJHl3V4BSduTrBWPuco0inQVq0QsuCbVhez48uY,5705
77
77
  oarepo_runtime/services/search.py,sha256=9xGTN5Yg6eTdptQ9qjO_umbacf9ooMuHYGXWYfla4-M,6227
78
- oarepo_runtime/services/config/__init__.py,sha256=dtlD84pJ6xI77UF22IPrCOt7tHD3g5DAEDApUdjDVFE,406
79
- oarepo_runtime/services/config/permissions_presets.py,sha256=zApeA-2DYAlD--SzVz3vq_OFjq48Ko0pe08e4o2vxr4,6114
78
+ oarepo_runtime/services/config/__init__.py,sha256=EOpmlw0rjAUGmErTRcLOOBADeXKJKdsk62lAgFbRKQ8,731
79
+ oarepo_runtime/services/config/link_conditions.py,sha256=xCusAqc7zqh0EGu2f6CF84ImyYHvzEKIOmLQYpyewzE,3113
80
+ oarepo_runtime/services/config/permissions_presets.py,sha256=yUyzynM4xgM6ydSbwWBa35fL0y-2WHZKAn0zi9vTfC8,6263
80
81
  oarepo_runtime/services/config/service.py,sha256=s-dVbGkLICpsce6jgu7b5kzYFz9opWjSQFDBgbIhKio,4002
81
82
  oarepo_runtime/services/custom_fields/__init__.py,sha256=_gqMcA_I3rdEZcBtCuDjO4wdVCqFML5NzaccuPx5a3o,2565
82
83
  oarepo_runtime/services/custom_fields/mappings.py,sha256=tg9CAdxGOkd_n6RB5Z2_wSwo_A0wqEey8RMcZ79AHo0,6906
@@ -101,6 +102,8 @@ oarepo_runtime/services/files/components.py,sha256=x6Wd-vvkqTqB1phj2a6h42DNQksN8
101
102
  oarepo_runtime/services/files/service.py,sha256=8DH0Pefr9kilM2JnOb-UYsnqerE8Z1Mu4p6DOJ4j_ZU,608
102
103
  oarepo_runtime/services/permissions/__init__.py,sha256=Cgin2Zr1fpaYr-aZcUotdmv0hsrPTUJVQt8ouvU8tuU,95
103
104
  oarepo_runtime/services/permissions/generators.py,sha256=YEOBCCvU-RG0BSWMtg76sv8qLcMbXxNu3rRJPDLtvvQ,1371
105
+ oarepo_runtime/services/records/__init__.py,sha256=hIoa2fx1AkDr6c-MgY561U2oN9LFeUCtfbVnetpBUOg,78
106
+ oarepo_runtime/services/records/links.py,sha256=gVe-_hGkLtX7pd6sS6jTbRIhBby2FTn9PXyYPy3yxzs,737
104
107
  oarepo_runtime/services/relations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
105
108
  oarepo_runtime/services/relations/components.py,sha256=3g0VdnGUM-2yYt50fPi-OADReBGJb4h05vmYHfh-QFs,592
106
109
  oarepo_runtime/services/relations/errors.py,sha256=VtlOKq9MEUeJ4IsiZhY7lWoshrusA_RL4SOHe2titno,552
@@ -130,9 +133,9 @@ tests/marshmallow_to_json/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
130
133
  tests/marshmallow_to_json/test_datacite_ui_schema.py,sha256=82iLj8nW45lZOUewpWbLX3mpSkpa9lxo-vK-Qtv_1bU,48552
131
134
  tests/marshmallow_to_json/test_simple_schema.py,sha256=izZN9p0v6kovtSZ6AdxBYmK_c6ZOti2_z_wPT_zXIr0,1500
132
135
  tests/pkg_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
133
- oarepo_runtime-1.5.74.dist-info/LICENSE,sha256=h2uWz0OaB3EN-J1ImdGJZzc7yvfQjvHVYdUhQ-H7ypY,1064
134
- oarepo_runtime-1.5.74.dist-info/METADATA,sha256=GHmgrkCfquYWIKwTRibqKKAOZUAD6FIfgOstHCJLFi0,4720
135
- oarepo_runtime-1.5.74.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
136
- oarepo_runtime-1.5.74.dist-info/entry_points.txt,sha256=k7O5LZUOGsVeSpB7ulU0txBUNp1CVQG7Q7TJIVTPbzU,491
137
- oarepo_runtime-1.5.74.dist-info/top_level.txt,sha256=bHhlkT1_RQC4IkfTQCqA3iN4KCB6cSFQlsXpQMSP-bE,21
138
- oarepo_runtime-1.5.74.dist-info/RECORD,,
136
+ oarepo_runtime-1.5.76.dist-info/LICENSE,sha256=h2uWz0OaB3EN-J1ImdGJZzc7yvfQjvHVYdUhQ-H7ypY,1064
137
+ oarepo_runtime-1.5.76.dist-info/METADATA,sha256=fYKfxR5RxKYsSOHJ0NmubeZmnHSqJtWMDE88ysa2mQk,4720
138
+ oarepo_runtime-1.5.76.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
139
+ oarepo_runtime-1.5.76.dist-info/entry_points.txt,sha256=k7O5LZUOGsVeSpB7ulU0txBUNp1CVQG7Q7TJIVTPbzU,491
140
+ oarepo_runtime-1.5.76.dist-info/top_level.txt,sha256=bHhlkT1_RQC4IkfTQCqA3iN4KCB6cSFQlsXpQMSP-bE,21
141
+ oarepo_runtime-1.5.76.dist-info/RECORD,,