oarepo-runtime 1.5.41__py3-none-any.whl → 1.5.43__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -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