oarepo-runtime 1.5.41__py3-none-any.whl → 1.5.43__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.
@@ -2,14 +2,7 @@ import click
2
2
  import tqdm
3
3
  from flask import current_app
4
4
  from flask.cli import with_appcontext
5
- from flask_login import login_user
6
- from flask_principal import (
7
- Identity,
8
- RoleNeed,
9
- UserNeed,
10
- identity_changed,
11
- identity_loaded,
12
- )
5
+ from flask_principal import Identity, RoleNeed, UserNeed
13
6
  from invenio_access.permissions import any_user, authenticated_user, system_identity
14
7
  from invenio_accounts.models import User
15
8
 
oarepo_runtime/ext.py CHANGED
@@ -39,9 +39,9 @@ class OARepoRuntime(object):
39
39
 
40
40
  for k in ext_config.OAREPO_PERMISSIONS_PRESETS:
41
41
  if k not in app.config["OAREPO_PERMISSIONS_PRESETS"]:
42
- app.config["OAREPO_PERMISSIONS_PRESETS"][
43
- k
44
- ] = ext_config.OAREPO_PERMISSIONS_PRESETS[k]
42
+ app.config["OAREPO_PERMISSIONS_PRESETS"][k] = (
43
+ ext_config.OAREPO_PERMISSIONS_PRESETS[k]
44
+ )
45
45
 
46
46
  for k in dir(ext_config):
47
47
  if k == "DEFAULT_DATASTREAMS_EXCLUDES":
@@ -146,6 +146,10 @@ class ICUSearchField(ICUField):
146
146
  "tokenizer": "standard",
147
147
  "filter": ["stemming_filter_en"],
148
148
  },
149
+ "ascii_folding_analyzer": {
150
+ "tokenizer": "standard",
151
+ "filter": ["ascii_folding_filter"],
152
+ },
149
153
  }
150
154
 
151
155
  default_stemming_filters = {
@@ -159,6 +163,7 @@ class ICUSearchField(ICUField):
159
163
  "name": "english",
160
164
  "language": "english",
161
165
  },
166
+ "ascii_folding_filter": {"type": "asciifolding", "preserve_original": True},
162
167
  }
163
168
 
164
169
  def __init__(self, source_field, key=None):
@@ -170,11 +175,24 @@ class ICUSearchField(ICUField):
170
175
  self.attr_name: {
171
176
  "type": "object",
172
177
  "properties": {
178
+ # normal stemming
173
179
  lang: setting.get(
174
180
  "search",
175
181
  {
176
182
  "type": "text",
177
- "analyzer": f"stemming_analyzer_{lang}",
183
+ "boost": 1,
184
+ "fields": {
185
+ "stemmed": {
186
+ "type": "text",
187
+ "analyzer": f"stemming_analyzer_{lang}",
188
+ "boost": 0.5,
189
+ },
190
+ "ascii_folded": {
191
+ "type": "text",
192
+ "analyzer": "ascii_folding_analyzer",
193
+ "boost": 0.3,
194
+ },
195
+ },
178
196
  },
179
197
  )
180
198
  for lang, setting in self.languages.items()
@@ -7,8 +7,6 @@
7
7
  # details.
8
8
 
9
9
  """Communities system field."""
10
- import functools
11
- import inspect
12
10
 
13
11
  from invenio_records.systemfields import SystemField
14
12
 
@@ -82,12 +80,7 @@ class OwnersField(MappingSystemFieldMixin, SystemField):
82
80
  return {
83
81
  self.attr_name: {
84
82
  "type": "object",
85
- "properties": {
86
- "user": {
87
- "type": "keyword",
88
- "ignore_above": 256
89
- }
90
- }
83
+ "properties": {"user": {"type": "keyword", "ignore_above": 256}},
91
84
  },
92
85
  }
93
86
 
@@ -1,12 +1,12 @@
1
- from typing import List
1
+ from typing import List, Any
2
2
 
3
3
 
4
4
  class Selector:
5
- def select(self, record):
5
+ def select(self, record) -> List[Any]:
6
6
  return []
7
7
 
8
8
 
9
- class PathSelector:
9
+ class PathSelector(Selector):
10
10
  def __init__(self, *paths):
11
11
  self.paths = [x.split(".") for x in paths]
12
12
 
@@ -2,6 +2,7 @@ import logging
2
2
 
3
3
  from invenio_records.systemfields import SystemField
4
4
 
5
+ from . import Selector
5
6
  from .mapping import MappingSystemFieldMixin
6
7
 
7
8
  log = logging.getLogger(__name__)
@@ -69,7 +70,7 @@ class SyntheticSystemField(MappingSystemFieldMixin, SystemField):
69
70
  ```
70
71
  """
71
72
 
72
- def __init__(self, selector=None, filter=None, map=None, key=None, **kwargs):
73
+ def __init__(self, selector: Selector=None, filter=None, map=None, key=None, **kwargs):
73
74
  self.selector = selector
74
75
  self.map = map
75
76
  self.filter = filter
@@ -4,7 +4,6 @@ from typing import List, Type
4
4
 
5
5
  from flask import current_app
6
6
  from flask_principal import RoleNeed
7
- from invenio_accounts.models import User
8
7
  from invenio_records_permissions import BasePermissionPolicy
9
8
  from invenio_records_permissions.generators import Generator
10
9
  from invenio_search.engine import dsl
@@ -19,7 +19,7 @@ from oarepo_runtime.records.systemfields.mapping import MappingSystemFieldMixin
19
19
  class Mapping(InvenioMapping):
20
20
  @classmethod
21
21
  def properties_for_fields(
22
- cls, given_fields_names, available_fields, field_name="custom_fields"
22
+ cls, given_fields_names, available_fields, field_name="custom_fields"
23
23
  ):
24
24
  """Prepare search mapping properties for each field."""
25
25
 
@@ -34,7 +34,7 @@ class Mapping(InvenioMapping):
34
34
 
35
35
  @classmethod
36
36
  def settings_for_fields(
37
- cls, given_fields_names, available_fields, field_name="custom_fields"
37
+ cls, given_fields_names, available_fields, field_name="custom_fields"
38
38
  ):
39
39
  """Prepare mapping settings for each field."""
40
40
 
@@ -87,9 +87,7 @@ def prepare_cf_index(record_class, config, path=[]):
87
87
  dynamic_templates = fld.dynamic_templates
88
88
 
89
89
  for pth in reversed(path):
90
- mapping = {
91
- pth: mapping
92
- }
90
+ mapping = {pth: mapping}
93
91
 
94
92
  # upload mapping
95
93
  try:
@@ -124,43 +122,24 @@ def prepare_parent_mapping(parent_class, config):
124
122
  "properties": {
125
123
  "created": {
126
124
  "type": "date",
127
- "format": "strict_date_time||strict_date_time_no_millis||basic_date_time||basic_date_time_no_millis||basic_date||strict_date||strict_date_hour_minute_second||strict_date_hour_minute_second_fraction"
128
- },
129
- "id": {
130
- "type": "keyword",
131
- "ignore_above": 1024
125
+ "format": "strict_date_time||strict_date_time_no_millis||basic_date_time||basic_date_time_no_millis||basic_date||strict_date||strict_date_hour_minute_second||strict_date_hour_minute_second_fraction",
132
126
  },
127
+ "id": {"type": "keyword", "ignore_above": 1024},
133
128
  "pid": {
134
129
  "properties": {
135
- "obj_type": {
136
- "type": "keyword",
137
- "ignore_above": 1024
138
- },
139
- "pid_type": {
140
- "type": "keyword",
141
- "ignore_above": 1024
142
- },
143
- "pk": {
144
- "type": "long"
145
- },
146
- "status": {
147
- "type": "keyword",
148
- "ignore_above": 1024
149
- }
130
+ "obj_type": {"type": "keyword", "ignore_above": 1024},
131
+ "pid_type": {"type": "keyword", "ignore_above": 1024},
132
+ "pk": {"type": "long"},
133
+ "status": {"type": "keyword", "ignore_above": 1024},
150
134
  }
151
135
  },
152
136
  "updated": {
153
137
  "type": "date",
154
- "format": "strict_date_time||strict_date_time_no_millis||basic_date_time||basic_date_time_no_millis||basic_date||strict_date||strict_date_hour_minute_second||strict_date_hour_minute_second_fraction"
155
- },
156
- "uuid": {
157
- "type": "keyword",
158
- "ignore_above": 1024
138
+ "format": "strict_date_time||strict_date_time_no_millis||basic_date_time||basic_date_time_no_millis||basic_date||strict_date||strict_date_hour_minute_second||strict_date_hour_minute_second_fraction",
159
139
  },
160
- "version_id": {
161
- "type": "long"
162
- }
163
- }
140
+ "uuid": {"type": "keyword", "ignore_above": 1024},
141
+ "version_id": {"type": "long"},
142
+ },
164
143
  }
165
144
  }
166
145
 
@@ -204,6 +183,6 @@ def update_index(record_index, settings, mapping, dynamic_templates=None):
204
183
 
205
184
  def get_mapping_fields(record_class) -> Iterable[MappingSystemFieldMixin]:
206
185
  for cfg_name, cfg_value in inspect.getmembers(
207
- record_class, lambda x: isinstance(x, MappingSystemFieldMixin)
186
+ record_class, lambda x: isinstance(x, MappingSystemFieldMixin)
208
187
  ):
209
188
  yield cfg_value
@@ -0,0 +1,32 @@
1
+ from .base import LabelledValuesTermsFacet
2
+ from .date import (
3
+ AutoDateHistogramFacet,
4
+ DateFacet,
5
+ DateIntervalFacet,
6
+ DateTimeFacet,
7
+ EDTFIntervalFacet,
8
+ TimeFacet,
9
+ )
10
+ from .enum import EnumTermsFacet
11
+ from .facet_groups_names import facet_groups_names
12
+ from .max_facet import MaxFacet
13
+ from .nested_facet import NestedLabeledFacet
14
+ from .params import FilteredFacetsParam, GroupedFacetsParam
15
+ from .year_histogram import YearAutoHistogramFacet
16
+
17
+ __all__ = [
18
+ "LabelledValuesTermsFacet",
19
+ "DateFacet",
20
+ "TimeFacet",
21
+ "DateTimeFacet",
22
+ "AutoDateHistogramFacet",
23
+ "EDTFIntervalFacet",
24
+ "DateIntervalFacet",
25
+ "EnumTermsFacet",
26
+ "facet_groups_names",
27
+ "MaxFacet",
28
+ "NestedLabeledFacet",
29
+ "GroupedFacetsParam",
30
+ "FilteredFacetsParam",
31
+ "YearAutoHistogramFacet",
32
+ ]
@@ -0,0 +1,200 @@
1
+ import re
2
+ from typing import Dict, List
3
+
4
+ from invenio_records_resources.services.records.facets.facets import LabelledFacetMixin
5
+ from invenio_search.engine import dsl
6
+
7
+
8
+ class YearAutoHistogramFacet(LabelledFacetMixin, dsl.Facet):
9
+ """Histogram facet.
10
+
11
+ .. code-block:: python
12
+
13
+ facets = {
14
+ 'year': IntegerHistogramFacet(
15
+ field='year',
16
+ label=_('Year'),
17
+ size=1000000
18
+ )
19
+ }
20
+
21
+ Usage in the oarepo model together with SyntheticSystemField::
22
+ record:
23
+ record:
24
+ imports:
25
+ - import: oarepo_runtime.records.systemfields.SyntheticSystemField
26
+ - import: oarepo_runtime.records.systemfields.PathSelector
27
+ fields:
28
+ year: |
29
+ SyntheticSystemField(
30
+ selector=PathSelector("metadata.date"),
31
+ key="year",
32
+ filter=lambda x: len(x) >= 4,
33
+ map=lambda x: x[:4]
34
+ )
35
+ properties:
36
+ year:
37
+ facets:
38
+ facet-class: oarepo_runtime.services.facets.year_histogram.YearAutoHistogramFacet
39
+ type: edtf
40
+ """
41
+
42
+ agg_type = "auto_date_histogram"
43
+
44
+ def __init__(self, **kwargs):
45
+ self._min_doc_count = kwargs.pop("min_doc_count", 0)
46
+ buckets = kwargs.pop("buckets", 20)
47
+ # TODO: the minimum interval should be year, but opensearch does not support it yet
48
+ super().__init__(
49
+ **kwargs, buckets=buckets, format="yyyy", minimum_interval="month"
50
+ )
51
+
52
+ def get_value_filter(self, filter_value):
53
+ if "/" in filter_value:
54
+ start, end = filter_value.split("/")
55
+ return dsl.query.Range(
56
+ _expand__to_dot=False,
57
+ **{
58
+ self._params["field"]: {
59
+ "gte": f"{start}-01-01",
60
+ "lte": f"{end}-12-31",
61
+ }
62
+ },
63
+ )
64
+ return dsl.query.Term(
65
+ _expand__to_dot=False,
66
+ **{
67
+ self._params["field"]: {
68
+ "gte": f"{filter_value}-01-01",
69
+ "lte": f"{filter_value}-12-31",
70
+ }
71
+ },
72
+ )
73
+
74
+ def add_filter(self, filter_values):
75
+ ret = super().add_filter(filter_values)
76
+ return ret
77
+
78
+ def get_labelled_values(self, data, filter_values):
79
+ """Get a labelled version of a bucket."""
80
+
81
+ # fix for opensearch bug
82
+ data = self.fix_yearly_interval(data)
83
+
84
+ interval = data["interval"]
85
+
86
+ interval_in_years = int(re.sub(r"\D", "", interval))
87
+
88
+ buckets = data["buckets"]
89
+
90
+ for bucket in buckets:
91
+ bucket["interval"] = interval_in_years
92
+
93
+ if self._min_doc_count > 0:
94
+ buckets = self._merge_small_buckets(buckets)
95
+
96
+ out_buckets = []
97
+ for i, bucket in enumerate(buckets):
98
+ value = int(bucket["key_as_string"].split("-")[0])
99
+
100
+ out_buckets.append(
101
+ {
102
+ **bucket,
103
+ "interval": f"{bucket['interval']}y",
104
+ "start": str(value),
105
+ }
106
+ )
107
+ if i > 0:
108
+ out_buckets[i - 1]["end"] = str(value - 1)
109
+
110
+ if out_buckets:
111
+ out_buckets[-1]["end"] = str(
112
+ int(out_buckets[-1]["start"]) + interval_in_years - 1
113
+ )
114
+
115
+ return {
116
+ "buckets": out_buckets,
117
+ "label": str(self._label),
118
+ "interval": interval,
119
+ }
120
+
121
+ def merge_buckets(self, buckets):
122
+ merged = {}
123
+
124
+ for bucket in buckets:
125
+ key = bucket["key_as_string"]
126
+ if key not in merged:
127
+ merged[key] = {
128
+ "key_as_string": key,
129
+ "key": bucket["key"],
130
+ "doc_count": 0,
131
+ }
132
+
133
+ merged[key]["doc_count"] += bucket["doc_count"]
134
+
135
+ result = list(merged.values())
136
+ return result
137
+
138
+ def fix_yearly_interval(self, data) -> Dict:
139
+ """
140
+ Currently opensearch has a bug that does not allow to set minimum_interval to year.
141
+ This function will fix the interval to be yearly if the minimum_interval is has lower value.
142
+ """
143
+ data = data.to_dict()
144
+
145
+ interval = data["interval"]
146
+
147
+ if interval.endswith("y"):
148
+ # no need to fix the interval, as it is in years
149
+ return data
150
+
151
+ # make sure it is in years
152
+ data["interval"] = "1y"
153
+
154
+ buckets = data["buckets"]
155
+ data["buckets"] = out_buckets = []
156
+
157
+ by_year = {}
158
+
159
+ # there might be several buckets returned with the same year - merge them
160
+ for bucket in buckets:
161
+ key = bucket["key_as_string"]
162
+ if key not in by_year:
163
+ by_year[key] = {
164
+ "key_as_string": key,
165
+ "key": bucket["key"],
166
+ "doc_count": 0,
167
+ }
168
+ out_buckets.append(by_year[key])
169
+
170
+ by_year[key]["doc_count"] += bucket["doc_count"]
171
+
172
+ return data
173
+
174
+ def _merge_small_buckets(self, buckets: List[Dict]):
175
+ """
176
+ Merges small buckets into the previous bucket. If the small bucket is the first one,
177
+ merge it with subsequent buckets until the first non-small bucket is found.
178
+ """
179
+ ret = []
180
+ initial_small_buckets = 0
181
+ initial_small_interval = 0
182
+ for bucket in buckets:
183
+ if bucket["doc_count"] < self._min_doc_count:
184
+ if ret:
185
+ ret[-1]["doc_count"] += bucket["doc_count"]
186
+ ret[-1]["interval"] += bucket["interval"]
187
+ else:
188
+ initial_small_buckets += bucket["doc_count"]
189
+ initial_small_interval += bucket["interval"]
190
+ else:
191
+ ret.append(bucket)
192
+
193
+ if ret and initial_small_buckets:
194
+ doc_count = ret[0]["doc_count"] + initial_small_buckets
195
+ interval = ret[0]["interval"] + initial_small_interval
196
+ ret[0] = buckets[0]
197
+ ret[0]["doc_count"] = doc_count
198
+ ret[0]["interval"] = interval
199
+
200
+ return ret
@@ -1,4 +1,3 @@
1
- import importlib
2
1
  from functools import lru_cache
3
2
 
4
3
  import langcodes
@@ -2,7 +2,6 @@ from functools import lru_cache
2
2
 
3
3
  from invenio_base.utils import obj_or_import_string
4
4
  from marshmallow import Schema, fields
5
- from marshmallow_utils.fields import SanitizedHTML
6
5
 
7
6
 
8
7
  @lru_cache
@@ -14,7 +14,6 @@ from invenio_records_resources.services.records.params import (
14
14
  from invenio_records_resources.services.records.queryparser import SuggestQueryParser
15
15
  from invenio_search.engine import dsl
16
16
 
17
-
18
17
  # TODO: integrate this to invenio_records_resources.services.records and remove SearchOptions class
19
18
  from oarepo_runtime.i18n import lazy_gettext as _
20
19
  from oarepo_runtime.records.systemfields.icu import ICUSuggestField
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: oarepo-runtime
3
- Version: 1.5.41
3
+ Version: 1.5.43
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=nB1LMJj6o2VZCREhdMetanyrGgoiH43RDvkIZRSD1w8,2371
2
+ oarepo_runtime/ext.py,sha256=zatf-tujtuP1Flo34p_5GJ38yKxzkAz0ENBjljapPlA,2373
3
3
  oarepo_runtime/ext_config.py,sha256=NiXqgag3QJABf06r5NiDYjd9AvoYoRY9UWiplo8Vcg4,2056
4
4
  oarepo_runtime/profile.py,sha256=QzrQoZncjoN74ZZnpkEKakNk08KCzBU7m6y42RN8AMY,1637
5
5
  oarepo_runtime/proxies.py,sha256=NN_WNj1xuKc-OveoZmzvTFlUonNjSmLIGsv_JUcHGls,285
@@ -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=kOstMsm2Ycoo9UIiy6f-L4KUmpRBlktf841TYaiDJYQ,5514
13
+ oarepo_runtime/cli/fixtures.py,sha256=l6zHpz1adjotrbFy_wcN2TOL8x20i-1jbQmaoEEo-UU,5419
14
14
  oarepo_runtime/cli/index.py,sha256=2dZvXtrph527YIgFTCQ8dIVsza-bZou9HBBzYRWAPTY,8243
15
15
  oarepo_runtime/cli/validate.py,sha256=HpSvHQCGHlrdgdpKix9cIlzlBoJEiT1vACZdMnOUGEY,2827
16
16
  oarepo_runtime/datastreams/__init__.py,sha256=_i52Ek9J8DMARST0ejZAZPzUKm55xrrlKlCSO7dl6y4,1008
@@ -58,12 +58,12 @@ oarepo_runtime/records/relations/pid_relation.py,sha256=zJjSf_ocFBViYsOuMMZLbQZp
58
58
  oarepo_runtime/records/systemfields/__init__.py,sha256=SPaMWM6t-azz6gZLUKvvXbOyE2_-LW6i_szQk8nhbAc,455
59
59
  oarepo_runtime/records/systemfields/featured_file.py,sha256=MbSaYR130_o5S9gEOblnChq-PVK4xGPGpSCrzwG3cwc,1720
60
60
  oarepo_runtime/records/systemfields/has_draftcheck.py,sha256=4JkMEefPLpqtPtlTgK3UT0KzTRgyw5_Qtkss2qcz5xk,1643
61
- oarepo_runtime/records/systemfields/icu.py,sha256=tAwplzy9y7C9Dm7HqcGZsDu2AKqVGXhCbKLsFlgVWg8,5921
61
+ oarepo_runtime/records/systemfields/icu.py,sha256=sSGAgi5WhsAY4cCBL7-7nMpvHAuctpW8Y8vRExHQUfk,6738
62
62
  oarepo_runtime/records/systemfields/mapping.py,sha256=tXOK_jkdY1pOUO7_VfChfDNB8UTi21GUXaidpugTnO8,1017
63
- oarepo_runtime/records/systemfields/owner.py,sha256=U7CD71Ve9midaH72pV4A4_I7AdywqZW0BSRHAK10_qA,3944
63
+ oarepo_runtime/records/systemfields/owner.py,sha256=dYRVBinniW7ECHuSnTAjeN6x1KhhJtNR9vxmD1KswMs,3805
64
64
  oarepo_runtime/records/systemfields/record_status.py,sha256=U3kem4-JkNsT17e0iAl3HIAZ2MvO5lY_0U757aZvTKE,935
65
- oarepo_runtime/records/systemfields/selectors.py,sha256=VlbV3FKP2h3PLU7H4-YsI4qrb0UO_SrhJ2dcsTBGoqI,900
66
- oarepo_runtime/records/systemfields/synthetic.py,sha256=GC7g6BZSQqVV7bFk3x6Y1E4dFgvX7VwHuIFXEDpmuSs,4238
65
+ oarepo_runtime/records/systemfields/selectors.py,sha256=8e8LaepwU5hrft8UDDJ1_FkxeZxBW0-JJKgUnqWHOx4,928
66
+ oarepo_runtime/records/systemfields/synthetic.py,sha256=6Le2lHMIPXY2JKW31ymPlYRZtIRriyxDp2xKPFbTK3o,4271
67
67
  oarepo_runtime/resources/__init__.py,sha256=v8BGrOTu_FjKzd0eozV7Q4GoGxyfybsL2cI-tbP5Pys,185
68
68
  oarepo_runtime/resources/file_resource.py,sha256=Ta3bFce7l0xwqkkOMOEu9mxbB8BbKj5HUHRHmidhnl8,414
69
69
  oarepo_runtime/resources/localized_ui_json_serializer.py,sha256=3V9cJaG_e1PMXKVX_wKfBp1LmbeForwHyBNYdyha4uQ,1878
@@ -71,16 +71,16 @@ oarepo_runtime/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
71
71
  oarepo_runtime/services/components.py,sha256=FkqyFe6-5HZKJDqglQ-Smm_AIsDZ-LyWcOr1u2yGu3k,1836
72
72
  oarepo_runtime/services/generators.py,sha256=V582uA813AIXnFhzqUwakmDgBOI1SQe3XZeJtUXNbwM,872
73
73
  oarepo_runtime/services/results.py,sha256=gPmQ7DzX4da5zuvqQE7u-AUn_Yvz-YHt8W8DaxPbQ-M,2706
74
- oarepo_runtime/services/search.py,sha256=eVOJ5xI9dKAVlWDM0E8mg1bYS3pGxsdpW8kTYNl5wRk,6228
74
+ oarepo_runtime/services/search.py,sha256=9xGTN5Yg6eTdptQ9qjO_umbacf9ooMuHYGXWYfla4-M,6227
75
75
  oarepo_runtime/services/config/__init__.py,sha256=SCqww5sV8qh3gmev6TE8EyJbD58juIEDCm_7MEHxtSg,440
76
76
  oarepo_runtime/services/config/permissions_presets.py,sha256=zApeA-2DYAlD--SzVz3vq_OFjq48Ko0pe08e4o2vxr4,6114
77
- oarepo_runtime/services/config/service.py,sha256=2aq5jobPH22T1QqlJDommvAxJwo9aQGiqK5q-k-l9CA,4668
77
+ oarepo_runtime/services/config/service.py,sha256=CJNBbFJmXEdEpLGrefQSGJVGRcJAtf-619Xdm1iK5_A,4627
78
78
  oarepo_runtime/services/custom_fields/__init__.py,sha256=xJ7XEyMJHPfIgX5JKpgpwh7SYc9Zee2dC5oC8cm99Qc,2282
79
- oarepo_runtime/services/custom_fields/mappings.py,sha256=d2uWqk-x4nfoxMx7Uw_PGWKba_Wlf_ukpRB5ruU-RPU,7397
79
+ oarepo_runtime/services/custom_fields/mappings.py,sha256=tg9CAdxGOkd_n6RB5Z2_wSwo_A0wqEey8RMcZ79AHo0,6906
80
80
  oarepo_runtime/services/expansions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
81
  oarepo_runtime/services/expansions/expandable_fields.py,sha256=7DWKFL6ml8J7zGI6wm9LO7Xd6R0LSylsuq4lyRumNHQ,745
82
82
  oarepo_runtime/services/expansions/service.py,sha256=HaEy76XOhDf__sQ91hi-8iH1hthM9q07pRhOmyZyVrs,144
83
- oarepo_runtime/services/facets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
83
+ oarepo_runtime/services/facets/__init__.py,sha256=Pq7xDiev2j3k8C55QyTXZWnUuRnRZUKWLi5ymZQgOOw,815
84
84
  oarepo_runtime/services/facets/base.py,sha256=-IEUUY0hZcAh_3SelceTjMSw_SaqMhgnLxzG62iq7tA,421
85
85
  oarepo_runtime/services/facets/date.py,sha256=Q0NP1YaCNHI6z11q927Wa41fBrzj4K08Ff-TPH2TLCg,2074
86
86
  oarepo_runtime/services/facets/enum.py,sha256=3LrShQIt9Vt5mkqUkc6FNxXCW5JEFdPwtGCTEmNB6i0,396
@@ -88,6 +88,7 @@ oarepo_runtime/services/facets/facet_groups_names.py,sha256=RR8eeUmD8d9t966Jqfhs
88
88
  oarepo_runtime/services/facets/max_facet.py,sha256=TZ4KMKKVJHzyU1KgNne4V7IMQPu1ALRpkz61Y0labrc,407
89
89
  oarepo_runtime/services/facets/nested_facet.py,sha256=y0xgjx37HsSj2xW7URxNemYTksD8hpPs7kOEfIBw22k,971
90
90
  oarepo_runtime/services/facets/params.py,sha256=NJLgqRYyamap6_ecpy6fgPpCl7JkcGPrY8xLl8jIZj8,3872
91
+ oarepo_runtime/services/facets/year_histogram.py,sha256=kdfwx1lgw4UmfjdaqqeElJCB8rAduMH2hy42aZjY37w,6257
91
92
  oarepo_runtime/services/files/__init__.py,sha256=K8MStrEQf_BUhvzhwPTF93Hkhwrd1dtv35LDo7iZeTM,268
92
93
  oarepo_runtime/services/files/components.py,sha256=x6Wd-vvkqTqB1phj2a6h42DNQksN8PuR2XKaOGoNHfw,2400
93
94
  oarepo_runtime/services/files/service.py,sha256=8DH0Pefr9kilM2JnOb-UYsnqerE8Z1Mu4p6DOJ4j_ZU,608
@@ -97,8 +98,8 @@ oarepo_runtime/services/relations/errors.py,sha256=VtlOKq9MEUeJ4IsiZhY7lWoshrusA
97
98
  oarepo_runtime/services/relations/mapping.py,sha256=D7IYk83SXVgTv-0ohSnHOCzvCwbFLXJsayO1eQfQn0U,1285
98
99
  oarepo_runtime/services/schema/__init__.py,sha256=5u8wTvon4W6ODJNRJhRNChmQHAZTXwo6LV2mYRYs-EM,1377
99
100
  oarepo_runtime/services/schema/cf.py,sha256=-m9seIH5VYUdxDsJlPVXS0-8f7xkpN7YfW1q9E1GacI,475
100
- oarepo_runtime/services/schema/i18n.py,sha256=-lah_Xmm4zv1FA8Q7BFTZJjTZcZVcVfeFNvyzunMpIw,1686
101
- oarepo_runtime/services/schema/i18n_ui.py,sha256=4abjHTrCl3SQDn0LKBwHGn2MFD9ivWSrzeKKwf94Z6U,2230
101
+ oarepo_runtime/services/schema/i18n.py,sha256=NACu0SqXWuuwKVpBZdz4K8tVfBaCEI9YpcCtC1l1YGI,1669
102
+ oarepo_runtime/services/schema/i18n_ui.py,sha256=MnEDW0gcZPvEODbJ6XzldxNCJ2suhfmdHQ4wkcAG6zA,2179
102
103
  oarepo_runtime/services/schema/i18n_validation.py,sha256=fyMTi2Rw-KiHv7c7HN61zGxRVa9sAjAEEkAL5wUyKNo,236
103
104
  oarepo_runtime/services/schema/marshmallow.py,sha256=LmcSxvbZ9jIhkNHCqqxt1SA2UNijoDmIzqli1MkoTrE,1153
104
105
  oarepo_runtime/services/schema/oneofschema.py,sha256=GnWH4Or_G5M0NgSmCoqMI6PBrJg5AC9RHrcB5QDKRq0,6661
@@ -116,9 +117,9 @@ oarepo_runtime/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
116
117
  oarepo_runtime/utils/functools.py,sha256=gKS9YZtlIYcDvdNA9cmYO00yjiXBYV1jg8VpcRUyQyg,1324
117
118
  oarepo_runtime/utils/path.py,sha256=V1NVyk3m12_YLbj7QHYvUpE1wScO78bYsX1LOLeXDkI,3108
118
119
  tests/pkg_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
119
- oarepo_runtime-1.5.41.dist-info/LICENSE,sha256=h2uWz0OaB3EN-J1ImdGJZzc7yvfQjvHVYdUhQ-H7ypY,1064
120
- oarepo_runtime-1.5.41.dist-info/METADATA,sha256=Kx5C6qgpAbZSJ0XztooVip_UQC9mTSJtPgrOciV_DsM,4680
121
- oarepo_runtime-1.5.41.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
122
- oarepo_runtime-1.5.41.dist-info/entry_points.txt,sha256=QrlXAKuPDVBinaSh_v3yO9_Nb9ZNmJCJ0VFcCW-z0Jg,327
123
- oarepo_runtime-1.5.41.dist-info/top_level.txt,sha256=bHhlkT1_RQC4IkfTQCqA3iN4KCB6cSFQlsXpQMSP-bE,21
124
- oarepo_runtime-1.5.41.dist-info/RECORD,,
120
+ oarepo_runtime-1.5.43.dist-info/LICENSE,sha256=h2uWz0OaB3EN-J1ImdGJZzc7yvfQjvHVYdUhQ-H7ypY,1064
121
+ oarepo_runtime-1.5.43.dist-info/METADATA,sha256=F2DEHBB8MB9qedtKvBbIplGSw9eVTehu59Ec8eucA-0,4680
122
+ oarepo_runtime-1.5.43.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
123
+ oarepo_runtime-1.5.43.dist-info/entry_points.txt,sha256=QrlXAKuPDVBinaSh_v3yO9_Nb9ZNmJCJ0VFcCW-z0Jg,327
124
+ oarepo_runtime-1.5.43.dist-info/top_level.txt,sha256=bHhlkT1_RQC4IkfTQCqA3iN4KCB6cSFQlsXpQMSP-bE,21
125
+ oarepo_runtime-1.5.43.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (70.2.0)
2
+ Generator: setuptools (70.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5