From a9c614d6ac95c7882851f3d2a3653bb2688d2a32 Mon Sep 17 00:00:00 2001 From: Peter Weber Date: Mon, 11 Nov 2019 15:17:04 +0100 Subject: [PATCH] data: add dump function for documents * Computes `_text` field for provisionActivity and series to documents, to display unstructured statement from the structured data. Co-Authored-by: Peter Weber --- rero_ils/modules/documents/api.py | 13 ++++ rero_ils/modules/documents/utils.py | 99 +++++++++++++++++++++++++++++ rero_ils/modules/documents/views.py | 58 ++--------------- tests/api/test_documents_rest.py | 5 +- tests/api/test_pid_rest.py | 3 +- 5 files changed, 121 insertions(+), 57 deletions(-) create mode 100644 rero_ils/modules/documents/utils.py diff --git a/rero_ils/modules/documents/api.py b/rero_ils/modules/documents/api.py index 96fb5000a2..7efe15d465 100644 --- a/rero_ils/modules/documents/api.py +++ b/rero_ils/modules/documents/api.py @@ -25,6 +25,7 @@ from invenio_search.api import RecordsSearch from .models import DocumentIdentifier +from .utils import publication_statement_text, series_format_text from ..api import IlsRecord from ..fetchers import id_fetcher from ..minters import id_minter @@ -128,3 +129,15 @@ def reasons_not_to_delete(self): if self.harvested: cannot_delete['others'] = dict(harvested=True) return cannot_delete + + def dumps(self, **kwargs): + """Return pure Python dictionary with record metadata.""" + dump = super(Document, self).dumps(**kwargs) + provision_activities = dump.get('provisionActivity') + for provision_activity in provision_activities: + provision_activity["_text"] = \ + publication_statement_text(provision_activity) + series = dump.get('series') + for series_element in series: + series_element["_text"] = series_format_text(series_element) + return dump diff --git a/rero_ils/modules/documents/utils.py b/rero_ils/modules/documents/utils.py new file mode 100644 index 0000000000..0ac21b5048 --- /dev/null +++ b/rero_ils/modules/documents/utils.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +# +# RERO ILS +# Copyright (C) 2019 RERO +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +"""Blueprint used for loading templates.""" + +from __future__ import absolute_import, print_function + +from .dojson.contrib.marc21tojson.model import remove_trailing_punctuation + + +def localized_data_name(data, language): + """Get localized name.""" + return data.get( + 'name_{language}'.format(language=language), + data.get('name', '') + ) + + +def clean_text(data): + """Delete all _text from data.""" + if isinstance(data, list): + new_val = [] + for val in data: + new_val.append(clean_text(val)) + data = new_val + elif isinstance(data, dict): + if '_text' in data: + del data['_text'] + new_data = {} + for key, val in data.items(): + new_data[key] = clean_text(val) + data = new_data + return data + + +def publication_statement_text(provision_activity): + """Create publication statement from place, agent and date values.""" + punctuation = { + 'bf:Place': ' ; ', + 'bf:Agent': ', ' + } + + statement_with_language = {'default': ''} + statement_type = None + + for statement in provision_activity['statement']: + labels = statement['label'] + + for label in labels: + language = label.get('language', 'default') + + if not statement_with_language.get(language): + statement_with_language[language] = '' + + if statement_with_language[language]: + if statement_type == statement['type']: + statement_with_language[language] += punctuation[ + statement_type + ] + else: + if statement['type'] == 'bf:Place': + statement_with_language[language] += ' ; ' + else: + statement_with_language[language] += ' : ' + + statement_with_language[language] += label['value'] + statement_type = statement['type'] + + # date field: remove ';' and append + for key, value in statement_with_language.items(): + value = remove_trailing_punctuation(value) + if provision_activity.get('date'): + value += ', ' + provision_activity.get('date') + statement_with_language[key] = value + return statement_with_language + + +def series_format_text(serie): + """Format series for template.""" + output = [] + if serie.get('name'): + output.append(serie.get('name')) + if serie.get('number'): + output.append(', ' + serie.get('number')) + return ''.join(str(x) for x in output) diff --git a/rero_ils/modules/documents/views.py b/rero_ils/modules/documents/views.py index 5e539c3683..cbfecdd215 100644 --- a/rero_ils/modules/documents/views.py +++ b/rero_ils/modules/documents/views.py @@ -35,8 +35,9 @@ from invenio_records_ui.signals import record_viewed from .api import Document -from .dojson.contrib.marc21tojson.model import remove_trailing_punctuation from .dojson.contrib.unimarctojson import unimarctojson +from .utils import localized_data_name, publication_statement_text, \ + series_format_text from ..holdings.api import Holding from ..items.api import Item, ItemStatus from ..libraries.api import Library @@ -249,14 +250,6 @@ def patron_request_rank(item): return False -def localized_data_name(data, language): - """Get localized name.""" - return data.get( - 'name_{language}'.format(language=language), - data.get('name', '') - ) - - @blueprint.app_template_filter() def authors_format(pid, language, viewcode): """Format authors for template.""" @@ -308,12 +301,7 @@ def series_format(series): """Format series for template.""" output = [] for serie in series: - line = [] - if serie.get('name'): - line.append(serie.get('name')) - if serie.get('number'): - line.append(', ' + serie.get('number')) - output.append(''.join(str(x) for x in line)) + output.append(series_format_text(serie)) return '; '.join(str(x) for x in output) @@ -440,42 +428,4 @@ def document_availability(document_pid): @blueprint.app_template_filter() def create_publication_statement(provision_activity): """Create publication statement from place, agent and date values.""" - punctuation = { - 'bf:Place': ' ; ', - 'bf:Agent': ', ' - } - - statement_with_language = {'default': ''} - statement_type = None - - for statement in provision_activity['statement']: - labels = statement['label'] - - for label in labels: - language = label.get('language', 'default') - - if not statement_with_language.get(language): - statement_with_language[language] = '' - - if statement_with_language[language]: - if statement_type == statement['type']: - statement_with_language[language] += punctuation[ - statement_type - ] - else: - if statement['type'] == 'bf:Place': - statement_with_language[language] += ' ; ' - else: - statement_with_language[language] += ' : ' - - statement_with_language[language] += label['value'] - statement_type = statement['type'] - - # date field: remove ';' and append - for key, value in statement_with_language.items(): - value = remove_trailing_punctuation(value) - if provision_activity.get('date'): - value += ', ' + provision_activity.get('date') - statement_with_language[key] = value - - return statement_with_language + return publication_statement_text(provision_activity) diff --git a/tests/api/test_documents_rest.py b/tests/api/test_documents_rest.py index e04e98eff0..7d6eef0a0c 100644 --- a/tests/api/test_documents_rest.py +++ b/tests/api/test_documents_rest.py @@ -24,6 +24,7 @@ from invenio_accounts.testutils import login_user_via_session from utils import VerifyRecordPermissionPatch, get_json, postdata +from rero_ils.modules.documents.utils import clean_text from rero_ils.modules.documents.views import can_request, \ item_library_pickup_locations, item_status_text, number_of_requests, \ patron_request_rank, requested_this_item @@ -121,12 +122,12 @@ def test_documents_post_put_delete(client, document_data, assert res.status_code == 201 # Check that the returned record matches the given data - assert data['metadata'] == document_data + assert clean_text(data['metadata']) == document_data res = client.get(item_url) assert res.status_code == 200 data = get_json(res) - assert document_data == data['metadata'] + assert clean_text(data['metadata']) == document_data # Update record/PUT data = document_data diff --git a/tests/api/test_pid_rest.py b/tests/api/test_pid_rest.py index 58d21c0dd8..7c316e4b9b 100644 --- a/tests/api/test_pid_rest.py +++ b/tests/api/test_pid_rest.py @@ -18,9 +18,10 @@ """API tests for PID and IlsRecords""" from invenio_accounts.testutils import login_user_via_session -from rero_ils.modules.locations.api import Location from utils import postdata +from rero_ils.modules.locations.api import Location + def test_ilsrecord_pid_after_validationerror( client, loc_online_martigny_data, librarian_martigny_no_email):