From 76cf55e054240c9ff742e9a4c76d265b761dce31 Mon Sep 17 00:00:00 2001 From: Peter Weber Date: Fri, 5 Feb 2021 12:12:00 +0100 Subject: [PATCH] public ui: better document type facet * The functionality of the document main, sub type facet for documents with multiple types was not clear. Now we display only the sub types accossiated with the main type in the facet. * closes #1697 Co-Authored-by: Peter Weber --- rero_ils/modules/documents/serializers.py | 9 ++++- rero_ils/modules/documents/utils.py | 44 ++++++++++++++++++++++ rero_ils/modules/documents/views.py | 2 +- rero_ils/modules/ext.py | 2 +- rero_ils/modules/imports/serializers.py | 2 + rero_ils/modules/items/serializers/json.py | 13 ++++++- rero_ils/modules/utils.py | 11 ++++++ 7 files changed, 79 insertions(+), 4 deletions(-) diff --git a/rero_ils/modules/documents/serializers.py b/rero_ils/modules/documents/serializers.py index c33bb5f678..8f847a32dc 100644 --- a/rero_ils/modules/documents/serializers.py +++ b/rero_ils/modules/documents/serializers.py @@ -21,7 +21,7 @@ from invenio_records_rest.serializers.response import record_responsify, \ search_responsify -from .utils import create_contributions +from .utils import create_contributions, filter_document_type_buckets from ..documents.api import Document from ..documents.utils import title_format_text_head from ..documents.views import create_title_alternate_graphic, \ @@ -133,6 +133,13 @@ def post_process_serialize_search(self, results, pid_fetcher): results['aggregations']['library'] = lib_agg del results['aggregations']['organisation'] + # Correct document type buckets + new_type_buckets = [] + type_buckets = results['aggregations']['document_type']['buckets'] + results['aggregations']['document_type']['buckets'] = \ + filter_document_type_buckets(type_buckets) + + return super( DocumentJSONSerializer, self).post_process_serialize_search( results, pid_fetcher) diff --git a/rero_ils/modules/documents/utils.py b/rero_ils/modules/documents/utils.py index b210001db8..0524102d5f 100644 --- a/rero_ils/modules/documents/utils.py +++ b/rero_ils/modules/documents/utils.py @@ -26,10 +26,54 @@ from elasticsearch_dsl.utils import AttrDict from flask import current_app from flask import request as flask_request +from invenio_jsonschemas.proxies import current_jsonschemas +from werkzeug.local import LocalProxy from .dojson.contrib.marc21tojson.model import remove_trailing_punctuation +from ..utils import get_schema_for_resource, memoized from ...utils import get_i18n_supported_languages +_records_state = LocalProxy(lambda: current_app.extensions['invenio-records']) + + +@memoized(timeout=3600) +def get_document_types_from_schema(schema='doc'): + """Create document type definition from schema.""" + path = current_jsonschemas.url_to_path(get_schema_for_resource(schema)) + schema = current_jsonschemas.get_schema(path=path) + schema = _records_state.replace_refs(schema) + schema_types = schema.get( + 'properties', {}).get('type', {}).get('items', {}).get('oneOf', []) + doc_types = {} + for schema_type in schema_types: + doc_types[schema_type['title']] = {} + sub_types = schema_type.get( + 'properties', {}).get('subtype', {}).get('enum', []) + for sub_type in sub_types: + doc_types[schema_type['title']][sub_type] = True + return doc_types + + +def filter_document_type_buckets(buckets): + """Removes unwanted sub types from buckets.""" + doc_types = get_document_types_from_schema() + new_type_buckets = buckets + if doc_types: + new_type_buckets = [] + for type_bucket in buckets: + new_type_bucket = type_bucket + main_type = type_bucket['key'] + new_subtype_buckets = [] + subtype_buckets = type_bucket['document_subtype']['buckets'] + for subtype_bucket in subtype_buckets: + if doc_types.get(main_type, {}).get(subtype_bucket['key']): + new_subtype_buckets.append(subtype_bucket) + new_type_bucket[ + 'document_subtype' + ]['buckets'] = new_subtype_buckets + new_type_buckets.append(new_type_bucket) + return new_type_buckets + def clean_text(data): """Delete all _text from data.""" diff --git a/rero_ils/modules/documents/views.py b/rero_ils/modules/documents/views.py index 847d101d20..02a30db6c6 100644 --- a/rero_ils/modules/documents/views.py +++ b/rero_ils/modules/documents/views.py @@ -575,7 +575,7 @@ def get_articles(record): for hit in search.scan(): articles.append({ 'title': title_format_text_head(hit.title), - 'pid':hit.pid + 'pid': hit.pid }) return articles diff --git a/rero_ils/modules/ext.py b/rero_ils/modules/ext.py index 6a140540ff..af61d5a177 100644 --- a/rero_ils/modules/ext.py +++ b/rero_ils/modules/ext.py @@ -182,7 +182,7 @@ def register_signals(self, app): after_record_insert.connect(create_subscription_patron_transaction) after_record_update.connect(create_subscription_patron_transaction) - + after_record_insert.connect(operation_log_record_create) after_record_update.connect(operation_log_record_update) diff --git a/rero_ils/modules/imports/serializers.py b/rero_ils/modules/imports/serializers.py index 234a2c8a56..0516fdad37 100644 --- a/rero_ils/modules/imports/serializers.py +++ b/rero_ils/modules/imports/serializers.py @@ -89,6 +89,8 @@ def serialize_search(self, pid_fetcher, search_result, links=None, ), aggregations=search_result.get('aggregations', dict()), ) + # TODO: If we have multiple types for a document we have to Correct + # the document type buckets here. return json.dumps(results, **self._format_args()) def post_process(self, metadata): diff --git a/rero_ils/modules/items/serializers/json.py b/rero_ils/modules/items/serializers/json.py index cc16be627b..d32dcf5f6f 100644 --- a/rero_ils/modules/items/serializers/json.py +++ b/rero_ils/modules/items/serializers/json.py @@ -19,7 +19,8 @@ """Item serializers.""" from rero_ils.modules.documents.api import search_document_by_pid -from rero_ils.modules.documents.utils import title_format_text_head +from rero_ils.modules.documents.utils import filter_document_type_buckets, \ + title_format_text_head from rero_ils.modules.item_types.api import ItemType from rero_ils.modules.items.api import Item from rero_ils.modules.items.models import ItemStatus @@ -110,4 +111,14 @@ def post_process_serialize_search(self, results, pid_fetcher): vendor = Vendor.get_record_by_pid(vendor_term.get('key')) vendor_term['name'] = vendor.get('name') + # Correct document type buckets + buckets = results['aggregations']['document_type']['buckets'] + results['aggregations']['document_type']['buckets'] = \ + filter_document_type_buckets(buckets) + return super().post_process_serialize_search(results, pid_fetcher) + + # Correct document type buckets + buckets = results['aggregations']['document_type']['buckets'] + results['aggregations']['document_type']['buckets'] = \ + filter_document_type_buckets(buckets) diff --git a/rero_ils/modules/utils.py b/rero_ils/modules/utils.py index d3b6ee6a27..4e5e10fa88 100644 --- a/rero_ils/modules/utils.py +++ b/rero_ils/modules/utils.py @@ -50,6 +50,17 @@ def wrapper(*args, **kwargs): return caching +def memoized(timeout=50): + """Memoize functions.""" + def memoize(f): + @wraps(f) + def wrapper(*args, **kwargs): + memoize_fun = current_cache.memoize(timeout=timeout) + return memoize_fun(f)(*args, **kwargs) + return wrapper + return memoize + + def strtotime(strtime): """String to datetime.""" splittime = strtime.split(':')