oarepo-runtime 1.5.42__py3-none-any.whl → 1.5.44__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.
- oarepo_runtime/cli/fixtures.py +1 -8
 - oarepo_runtime/datastreams/utils.py +11 -0
 - oarepo_runtime/ext.py +3 -3
 - oarepo_runtime/records/systemfields/icu.py +3 -8
 - oarepo_runtime/records/systemfields/owner.py +1 -8
 - oarepo_runtime/records/systemfields/selectors.py +3 -3
 - oarepo_runtime/records/systemfields/synthetic.py +2 -1
 - oarepo_runtime/services/config/service.py +0 -1
 - oarepo_runtime/services/custom_fields/mappings.py +14 -35
 - oarepo_runtime/services/facets/__init__.py +32 -0
 - oarepo_runtime/services/facets/year_histogram.py +200 -0
 - oarepo_runtime/services/schema/i18n.py +0 -1
 - oarepo_runtime/services/schema/i18n_ui.py +0 -1
 - oarepo_runtime/services/search.py +0 -1
 - {oarepo_runtime-1.5.42.dist-info → oarepo_runtime-1.5.44.dist-info}/METADATA +1 -1
 - {oarepo_runtime-1.5.42.dist-info → oarepo_runtime-1.5.44.dist-info}/RECORD +20 -19
 - {oarepo_runtime-1.5.42.dist-info → oarepo_runtime-1.5.44.dist-info}/WHEEL +1 -1
 - {oarepo_runtime-1.5.42.dist-info → oarepo_runtime-1.5.44.dist-info}/LICENSE +0 -0
 - {oarepo_runtime-1.5.42.dist-info → oarepo_runtime-1.5.44.dist-info}/entry_points.txt +0 -0
 - {oarepo_runtime-1.5.42.dist-info → oarepo_runtime-1.5.44.dist-info}/top_level.txt +0 -0
 
    
        oarepo_runtime/cli/fixtures.py
    CHANGED
    
    | 
         @@ -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  
     | 
| 
       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 
     | 
    
         | 
| 
         @@ -1,6 +1,8 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            from base64 import b64decode
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            import requests
         
     | 
| 
      
 4 
     | 
    
         
            +
            from deprecated import deprecated
         
     | 
| 
      
 5 
     | 
    
         
            +
            from flask import current_app
         
     | 
| 
       4 
6 
     | 
    
         
             
            from invenio_drafts_resources.services import RecordService as DraftRecordService
         
     | 
| 
       5 
7 
     | 
    
         
             
            from invenio_records_resources.proxies import current_service_registry
         
     | 
| 
       6 
8 
     | 
    
         
             
            from invenio_records_resources.services import FileService, RecordService
         
     | 
| 
         @@ -12,7 +14,16 @@ from requests.adapters import BaseAdapter 
     | 
|
| 
       12 
14 
     | 
    
         
             
            def get_record_service_for_record(record):
         
     | 
| 
       13 
15 
     | 
    
         
             
                if not record:
         
     | 
| 
       14 
16 
     | 
    
         
             
                    return None
         
     | 
| 
      
 17 
     | 
    
         
            +
                if "OAREPO_PRIMARY_RECORD_SERVICE" in current_app.config:
         
     | 
| 
      
 18 
     | 
    
         
            +
                    return current_app.config["OAREPO_PRIMARY_RECORD_SERVICE"][type(record)]
         
     | 
| 
      
 19 
     | 
    
         
            +
                else:
         
     | 
| 
      
 20 
     | 
    
         
            +
                    return get_record_service_for_record_deprecated(record)
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
       15 
22 
     | 
    
         | 
| 
      
 23 
     | 
    
         
            +
            @deprecated(
         
     | 
| 
      
 24 
     | 
    
         
            +
                version="1.5.43", reason="Please recompile model to remove this deprecation warning"
         
     | 
| 
      
 25 
     | 
    
         
            +
            )
         
     | 
| 
      
 26 
     | 
    
         
            +
            def get_record_service_for_record_deprecated(record):
         
     | 
| 
       16 
27 
     | 
    
         
             
                if getattr(record, "is_draft", False):
         
     | 
| 
       17 
28 
     | 
    
         
             
                    record_name = "draft_cls"
         
     | 
| 
       18 
29 
     | 
    
         
             
                    expect_draft_service = True
         
     | 
    
        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 
     | 
    
         
            -
                             
     | 
| 
      
 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":
         
     | 
| 
         @@ -148,9 +148,7 @@ class ICUSearchField(ICUField): 
     | 
|
| 
       148 
148 
     | 
    
         
             
                    },
         
     | 
| 
       149 
149 
     | 
    
         
             
                    "ascii_folding_analyzer": {
         
     | 
| 
       150 
150 
     | 
    
         
             
                        "tokenizer": "standard",
         
     | 
| 
       151 
     | 
    
         
            -
                        "filter": [
         
     | 
| 
       152 
     | 
    
         
            -
                            "ascii_folding_filter"
         
     | 
| 
       153 
     | 
    
         
            -
                        ]
         
     | 
| 
      
 151 
     | 
    
         
            +
                        "filter": ["ascii_folding_filter"],
         
     | 
| 
       154 
152 
     | 
    
         
             
                    },
         
     | 
| 
       155 
153 
     | 
    
         
             
                }
         
     | 
| 
       156 
154 
     | 
    
         | 
| 
         @@ -165,10 +163,7 @@ class ICUSearchField(ICUField): 
     | 
|
| 
       165 
163 
     | 
    
         
             
                        "name": "english",
         
     | 
| 
       166 
164 
     | 
    
         
             
                        "language": "english",
         
     | 
| 
       167 
165 
     | 
    
         
             
                    },
         
     | 
| 
       168 
     | 
    
         
            -
                    "ascii_folding_filter": {
         
     | 
| 
       169 
     | 
    
         
            -
                        "type": "asciifolding",
         
     | 
| 
       170 
     | 
    
         
            -
                        "preserve_original": True
         
     | 
| 
       171 
     | 
    
         
            -
                    }
         
     | 
| 
      
 166 
     | 
    
         
            +
                    "ascii_folding_filter": {"type": "asciifolding", "preserve_original": True},
         
     | 
| 
       172 
167 
     | 
    
         
             
                }
         
     | 
| 
       173 
168 
     | 
    
         | 
| 
       174 
169 
     | 
    
         
             
                def __init__(self, source_field, key=None):
         
     | 
| 
         @@ -197,7 +192,7 @@ class ICUSearchField(ICUField): 
     | 
|
| 
       197 
192 
     | 
    
         
             
                                                "analyzer": "ascii_folding_analyzer",
         
     | 
| 
       198 
193 
     | 
    
         
             
                                                "boost": 0.3,
         
     | 
| 
       199 
194 
     | 
    
         
             
                                            },
         
     | 
| 
       200 
     | 
    
         
            -
                                        }
         
     | 
| 
      
 195 
     | 
    
         
            +
                                        },
         
     | 
| 
       201 
196 
     | 
    
         
             
                                    },
         
     | 
| 
       202 
197 
     | 
    
         
             
                                )
         
     | 
| 
       203 
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 
     | 
    
         
            -
             
     | 
| 
      
 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 
     | 
    
         
            -
             
     | 
| 
      
 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 
     | 
    
         
            -
             
     | 
| 
       137 
     | 
    
         
            -
             
     | 
| 
       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 
     | 
    
         
            -
                            " 
     | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
       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 
     | 
    
         
            -
             
     | 
| 
      
 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
         
     | 
| 
         @@ -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,5 +1,5 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            oarepo_runtime/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         
     | 
| 
       2 
     | 
    
         
            -
            oarepo_runtime/ext.py,sha256= 
     | 
| 
      
 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= 
     | 
| 
      
 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
         
     | 
| 
         @@ -25,7 +25,7 @@ oarepo_runtime/datastreams/semi_asynchronous.py,sha256=TJWby2MDKXm5feRocoWB-8Ohs 
     | 
|
| 
       25 
25 
     | 
    
         
             
            oarepo_runtime/datastreams/synchronous.py,sha256=t5lfnMkLqy3jK5zMl-nIuA0HlMPiHGjwCqZ8XQP-3GM,2595
         
     | 
| 
       26 
26 
     | 
    
         
             
            oarepo_runtime/datastreams/transformers.py,sha256=q5KzHPl2kJg7HP1BtKJ7F_UMqg_7L1ZGDX0O7s8D6UI,521
         
     | 
| 
       27 
27 
     | 
    
         
             
            oarepo_runtime/datastreams/types.py,sha256=KZjblc3T_UFFW7LrMDmiR8lqVf86V484LAHj6yg05EI,9908
         
     | 
| 
       28 
     | 
    
         
            -
            oarepo_runtime/datastreams/utils.py,sha256= 
     | 
| 
      
 28 
     | 
    
         
            +
            oarepo_runtime/datastreams/utils.py,sha256=PAUVyL6AuD20PtESJcUEXsUeeSnxxKUB9LzxqwAgx9U,3939
         
     | 
| 
       29 
29 
     | 
    
         
             
            oarepo_runtime/datastreams/readers/__init__.py,sha256=P1n3llZQ3AFHnSPbeT1VaCJcEtRFz9AbHfjkZv5LG7s,1103
         
     | 
| 
       30 
30 
     | 
    
         
             
            oarepo_runtime/datastreams/readers/attachments.py,sha256=A7EC1TqyTHG-go5DIaRotlBSOm6o9hGqAKyVVAceCRU,1956
         
     | 
| 
       31 
31 
     | 
    
         
             
            oarepo_runtime/datastreams/readers/excel.py,sha256=CM8lr8mejN7NgoK5TJb1oXpjq0HxklQKMsuj3uqjTjA,3653
         
     | 
| 
         @@ -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= 
     | 
| 
      
 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= 
     | 
| 
      
 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= 
     | 
| 
       66 
     | 
    
         
            -
            oarepo_runtime/records/systemfields/synthetic.py,sha256= 
     | 
| 
      
 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= 
     | 
| 
      
 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= 
     | 
| 
      
 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= 
     | 
| 
      
 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= 
     | 
| 
      
 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 
     | 
| 
       101 
     | 
    
         
            -
            oarepo_runtime/services/schema/i18n_ui.py,sha256= 
     | 
| 
      
 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. 
     | 
| 
       120 
     | 
    
         
            -
            oarepo_runtime-1.5. 
     | 
| 
       121 
     | 
    
         
            -
            oarepo_runtime-1.5. 
     | 
| 
       122 
     | 
    
         
            -
            oarepo_runtime-1.5. 
     | 
| 
       123 
     | 
    
         
            -
            oarepo_runtime-1.5. 
     | 
| 
       124 
     | 
    
         
            -
            oarepo_runtime-1.5. 
     | 
| 
      
 120 
     | 
    
         
            +
            oarepo_runtime-1.5.44.dist-info/LICENSE,sha256=h2uWz0OaB3EN-J1ImdGJZzc7yvfQjvHVYdUhQ-H7ypY,1064
         
     | 
| 
      
 121 
     | 
    
         
            +
            oarepo_runtime-1.5.44.dist-info/METADATA,sha256=pDJg1hNUd-gXeg2V2bhwmr0aIofecKPJb_43bXQF4RQ,4680
         
     | 
| 
      
 122 
     | 
    
         
            +
            oarepo_runtime-1.5.44.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91
         
     | 
| 
      
 123 
     | 
    
         
            +
            oarepo_runtime-1.5.44.dist-info/entry_points.txt,sha256=QrlXAKuPDVBinaSh_v3yO9_Nb9ZNmJCJ0VFcCW-z0Jg,327
         
     | 
| 
      
 124 
     | 
    
         
            +
            oarepo_runtime-1.5.44.dist-info/top_level.txt,sha256=bHhlkT1_RQC4IkfTQCqA3iN4KCB6cSFQlsXpQMSP-bE,21
         
     | 
| 
      
 125 
     | 
    
         
            +
            oarepo_runtime-1.5.44.dist-info/RECORD,,
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     |