From 66f5d99fab15ddca3ef4cd6b8358dc3a89c2b8fa Mon Sep 17 00:00:00 2001 From: Bertrand Zuchuat Date: Mon, 10 Jul 2023 12:06:44 +0200 Subject: [PATCH] entities: public view for local and remote * Changes english date format to en_GB (DD/MM/YYYY). * Fixes `reasons_not_to_delete` and `get_links_to_me` methods for `Entity` resource. * Adds `alternative_names` as alias for autocomplete search. Co-Authored-by: Bertrand Zuchuat Co-Authored-by: Renaud Michotte --- pyproject.toml | 2 +- rero_ils/config.py | 1 + rero_ils/filter.py | 21 +++ rero_ils/modules/documents/api.py | 24 +++ .../rero_ils/detailed_view_documents.html | 36 ++++- rero_ils/modules/documents/views.py | 59 ++++--- rero_ils/modules/entities/api.py | 120 +++++++++----- .../modules/entities/local_entities/api.py | 22 --- .../local_entities/local_entity-v0.0.1.json | 10 +- .../entities/remote_entities/__init__.py | 5 +- .../templates/rero_ils/_entity_by_source.html | 55 ------- .../templates/rero_ils/_entity_unified.html | 45 ------ .../rero_ils/detailed_view_entity.html | 82 ---------- .../modules/entities/remote_entities/views.py | 152 +----------------- .../rero_ils/_local_organisation.html | 28 ++++ .../templates/rero_ils/_local_person.html | 26 +++ .../templates/rero_ils/_local_place.html | 21 +++ .../templates/rero_ils/_local_temporal.html | 21 +++ .../templates/rero_ils/_local_topic.html | 22 +++ .../templates/rero_ils/_local_work.html | 21 +++ .../rero_ils/_remote_organisation.html} | 26 ++- .../templates/rero_ils/_remote_person.html | 44 +++++ .../templates/rero_ils/_remote_topic.html | 71 ++++++++ .../templates/rero_ils/_search_link.html | 24 +++ .../templates/rero_ils/entity_local.html | 64 ++++++++ .../templates/rero_ils/entity_remote.html | 64 ++++++++ .../templates/rero_ils/macros/entity.html | 28 +--- rero_ils/modules/entities/views.py | 148 +++++++++++++++++ rero_ils/modules/ext.py | 3 +- .../rero_ils/address_block/eng.tpl.txt | 2 +- .../rero_ils/address_block/fre.tpl.txt | 2 +- .../rero_ils/address_block/ger.tpl.txt | 2 +- .../rero_ils/address_block/ita.tpl.txt | 2 +- tests/ui/documents/test_documents_api.py | 3 +- tests/ui/documents/test_documents_filter.py | 102 ++++++++---- .../test_remote_entities_api.py | 4 + .../test_remote_entities_filter.py | 108 ------------- .../test_remote_entities_ui.py | 29 ++-- tests/ui/entities/test_entities_ui.py | 137 ++++++++++++++++ tests/ui/test_filters.py | 14 +- 40 files changed, 1014 insertions(+), 636 deletions(-) delete mode 100644 rero_ils/modules/entities/remote_entities/templates/rero_ils/_entity_by_source.html delete mode 100644 rero_ils/modules/entities/remote_entities/templates/rero_ils/_entity_unified.html delete mode 100644 rero_ils/modules/entities/remote_entities/templates/rero_ils/detailed_view_entity.html create mode 100644 rero_ils/modules/entities/templates/rero_ils/_local_organisation.html create mode 100644 rero_ils/modules/entities/templates/rero_ils/_local_person.html create mode 100644 rero_ils/modules/entities/templates/rero_ils/_local_place.html create mode 100644 rero_ils/modules/entities/templates/rero_ils/_local_temporal.html create mode 100644 rero_ils/modules/entities/templates/rero_ils/_local_topic.html create mode 100644 rero_ils/modules/entities/templates/rero_ils/_local_work.html rename rero_ils/modules/entities/{remote_entities/templates/rero_ils/_entity_by_source_data.html => templates/rero_ils/_remote_organisation.html} (62%) create mode 100644 rero_ils/modules/entities/templates/rero_ils/_remote_person.html create mode 100644 rero_ils/modules/entities/templates/rero_ils/_remote_topic.html create mode 100644 rero_ils/modules/entities/templates/rero_ils/_search_link.html create mode 100644 rero_ils/modules/entities/templates/rero_ils/entity_local.html create mode 100644 rero_ils/modules/entities/templates/rero_ils/entity_remote.html rename rero_ils/modules/entities/{remote_entities => }/templates/rero_ils/macros/entity.html (72%) create mode 100644 rero_ils/modules/entities/views.py delete mode 100644 tests/ui/entities/remote_entities/test_remote_entities_filter.py create mode 100644 tests/ui/entities/test_entities_ui.py diff --git a/pyproject.toml b/pyproject.toml index d27487cf6d..71209ca4db 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -186,7 +186,7 @@ rero-ils = "rero_ils.modules.ext:REROILSAPP" [tool.poetry.plugins."invenio_base.blueprints"] circ_policies = "rero_ils.modules.circ_policies.views:blueprint" collections = "rero_ils.modules.collections.views:blueprint" -remote_entities = "rero_ils.modules.entities.remote_entities.views:blueprint" +entities = "rero_ils.modules.entities.views:blueprint" documents = "rero_ils.modules.documents.views:blueprint" holdings = "rero_ils.modules.holdings.views:blueprint" ill_requests = "rero_ils.modules.ill_requests.views:blueprint" diff --git a/rero_ils/config.py b/rero_ils/config.py index f8dc528b39..c42181b836 100644 --- a/rero_ils/config.py +++ b/rero_ils/config.py @@ -3060,6 +3060,7 @@ def _(x): #: Entities RERO_ILS_AGENTS_SOURCES = ['idref', 'gnd', 'rero'] +RERO_ILS_AGENTS_SOURCES_EXCLUDE_LINK = ['rero'] RERO_ILS_AGENTS_LABEL_ORDER = { 'fallback': 'fr', 'fr': ['idref', 'rero', 'gnd'], diff --git a/rero_ils/filter.py b/rero_ils/filter.py index 6c461061f0..162b47fbe3 100644 --- a/rero_ils/filter.py +++ b/rero_ils/filter.py @@ -25,6 +25,7 @@ import dateparser from babel.dates import format_date, format_datetime, format_time from flask import current_app, render_template +from flask_babelex import gettext as _ from invenio_i18n.ext import current_i18n from jinja2 import TemplateNotFound from markupsafe import Markup @@ -102,6 +103,10 @@ def format_date_filter( if not locale: locale = current_i18n.locale.language + # Date formatting in GB English (DD/MM/YYYY) + if locale == 'en': + locale += '_GB' + if timezone: tzinfo = timezone else: @@ -184,3 +189,19 @@ def message_filter(key): :return: none or a json (check structure into the class Message). """ return Message.get(key) + + +def translate(data, prefix='', separator=', '): + """Translate data. + + :param data: the data to translate + :param prefix: A prefix as a character string + :param separator: A character string separator. + :return: The translated string + """ + if data: + if isinstance(data, list): + translated = [_(f'{prefix}{item}') for item in data] + return separator.join(translated) + elif isinstance(data, str): + return _(f'{prefix}{data}') diff --git a/rero_ils/modules/documents/api.py b/rero_ils/modules/documents/api.py index 170b8fcaa1..93d44859f5 100644 --- a/rero_ils/modules/documents/api.py +++ b/rero_ils/modules/documents/api.py @@ -73,6 +73,30 @@ class Meta: default_filter = None + def by_entity(self, entity, subjects=True, imported_subjects=True, + genre_forms=True): + """Build a search to get hits related to an entity. + + :param entity: the entity record to search. + :param subjects: search on `subject` field. + :param imported_subjects: search on `imported_subject` field. + :param genre_forms: search on `genre_forms` field. + :returns: An ElasticSearch query to get hits related the entity. + :rtype: `elasticsearch_dsl.Search` + """ + field = f'contribution.entity.pids.{entity.resource_type}' + filters = Q('term', **{field: entity.pid}) + if subjects: + field = f'subjects.entity.pids.{entity.resource_type}' + filters |= Q('term', **{field: entity.pid}) + if imported_subjects: + field = f'subjects_imported.pids.{entity.resource_type}' + filters |= Q('term', **{field: entity.pid}) + if genre_forms: + field = f'genreForm.entity.pids.{entity.resource_type}' + filters |= Q('term', **{field: entity.pid}) + return self.filter(filters) + class Document(IlsRecord): """Document class.""" diff --git a/rero_ils/modules/documents/templates/rero_ils/detailed_view_documents.html b/rero_ils/modules/documents/templates/rero_ils/detailed_view_documents.html index cb9119c715..b06131708a 100644 --- a/rero_ils/modules/documents/templates/rero_ils/detailed_view_documents.html +++ b/rero_ils/modules/documents/templates/rero_ils/detailed_view_documents.html @@ -2,6 +2,7 @@ RERO ILS Copyright (C) 2019-2023 RERO + Copyright (C) 2019-2023 UCLouvain 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 @@ -62,14 +63,24 @@ {% if 'genreForm' in record %}
    - {% for genreForm in record.genreForm %} - {% if 'entity' in genreForm %} + {% for genreForm in record.genreForm %} + {% if 'entity' in genreForm %} + {% set type, value, label = genreForm.entity | doc_entity_label(language=current_i18n.language) %} + {% if 'textual' == type %} + {% set query = 'genreForm.entity.authorized_access_point_' ~ current_i18n.language ~ ':"' ~ value ~ '"' %} + {% elif type in ['local', 'remote'] %} + {% set query = 'genreForm.entity.pids.' ~ type ~ ':' ~ value %} + {% endif %}
  • - - {{ genreForm.entity | doc_entity_label(language=current_i18n.language) }} + + {% if query %} + {{ label }} + {% else %} + {{ label }} + {% endif %}
  • - {% endif %} - {% endfor %} + {% endif %} + {% endfor %}
{% endif %} @@ -230,7 +241,18 @@

{% for subject in record.subjects %} {% if 'entity' in subject %} - {{ subject.entity | doc_entity_label(language=current_i18n.language) }} + {% set type, value, label = subject.entity | doc_entity_label(language=current_i18n.language) %} + {% if 'textual' == type %} + {% set query = 'subjects.entity.authorized_access_point_' ~ current_i18n.language ~ ':"' ~ value ~ '"' %} + {% elif type in ['local', 'remote'] %} + {% set query = 'subjects.entity.pids.' ~ type ~ ':' ~ value %} + {% endif %} + + {% if query %} + {{ label }} + {% else %} + {{ label }} + {% endif %} {% endif %} {% endfor %} diff --git a/rero_ils/modules/documents/views.py b/rero_ils/modules/documents/views.py index 6d3335b79c..2c3bf8c3c0 100644 --- a/rero_ils/modules/documents/views.py +++ b/rero_ils/modules/documents/views.py @@ -24,23 +24,17 @@ import click from elasticsearch_dsl.query import Q -from flask import Blueprint, abort, current_app, jsonify, render_template, \ - url_for +from flask import Blueprint, abort, current_app, jsonify, render_template from flask import request as flask_request +from flask import url_for from flask_babelex import gettext as _ from flask_login import current_user from invenio_records_ui.signals import record_viewed -from .api import Document, DocumentsSearch -from .extensions import EditionStatementExtension, \ - ProvisionActivitiesExtension, SeriesStatementExtension, TitleExtension -from .utils import display_alternate_graphic_first, get_remote_cover, \ - title_format_text, title_format_text_alternate_graphic, \ - title_variant_format_text from rero_ils.modules.collections.api import CollectionsSearch -from rero_ils.modules.entities.remote_entities.api import RemoteEntity -from rero_ils.modules.entities.models import EntityType +from rero_ils.modules.entities.api import Entity from rero_ils.modules.entities.helpers import get_entity_record_from_data +from rero_ils.modules.entities.models import EntityType from rero_ils.modules.holdings.models import HoldingNoteTypes from rero_ils.modules.items.models import ItemCirculationAction from rero_ils.modules.libraries.api import Library @@ -49,6 +43,13 @@ from rero_ils.modules.patrons.api import current_patrons from rero_ils.modules.utils import cached, extracted_data_from_ref +from .api import Document, DocumentsSearch +from .extensions import EditionStatementExtension, \ + ProvisionActivitiesExtension, SeriesStatementExtension, TitleExtension +from .utils import display_alternate_graphic_first, get_remote_cover, \ + title_format_text, title_format_text_alternate_graphic, \ + title_variant_format_text + def doc_item_view_method(pid, record, template=None, **kwargs): """Display default view. @@ -274,13 +275,19 @@ def contribution_format(contributions, language, viewcode, with_roles=False): f'{entity.pid}', 'simple': 0 } - url = url_for('rero_ils.search', **args) - label = f'{text}' else: default_key = 'authorized_access_point' - localized_key = f'{default_key}_{language}' - label = contrib['entity'].get(localized_key) or \ + localized_key = f'authorized_access_point_{language}' + text = contrib['entity'].get(localized_key) or \ contrib['entity'].get(default_key) + args = { + 'viewcode': viewcode, + 'recordType': 'documents', + 'q': f'contribution.entity.{localized_key}:"{text}"', + 'simple': 0 + } + url = url_for('rero_ils.search', **args) + label = f'{text}' if with_roles: if roles := [_(role) for role in contrib.get('role', [])]: @@ -288,7 +295,7 @@ def contribution_format(contributions, language, viewcode, with_roles=False): label += f' ({roles_str})' output.append(label) - return ' ; '.join(output) + return ' ; '.join(output) @blueprint.app_template_filter() @@ -301,20 +308,28 @@ def doc_entity_label(entity, language=None, part_separator=' - ') -> str: :returns: the best possible label to display. """ parts = [] - if 'pid' in entity: - entity = RemoteEntity.get_record_by_pid(entity['pid']) - parts.append(entity.get_authorized_access_point(language=language)) + if '$ref' in entity: + # Local or remote entity + if entity := Entity.get_record_by_ref(entity['$ref']): + entity_type = entity.resource_type + value = entity.pid + parts.append(entity.get_authorized_access_point(language=language)) else: + # Textual entity + entity_type = 'textual' default_key = 'authorized_access_point' localized_key = f'{default_key}_{language}' - parts.append(entity.get(localized_key) or entity.get(default_key)) + value = entity.get(localized_key) or entity.get(default_key) + parts.append(value) + # Subdivisions (only for textual entity) for subdivision in entity.get('subdivisions', []): if sub_entity := subdivision.get('entity'): - parts.append( - doc_entity_label(sub_entity, language, part_separator)) + _, _, label = doc_entity_label( + sub_entity, language, part_separator) + parts.append(label) - return part_separator.join(filter(None, parts)) + return entity_type, value, part_separator.join(filter(None, parts)) @blueprint.app_template_filter() diff --git a/rero_ils/modules/entities/api.py b/rero_ils/modules/entities/api.py index 906763202a..a8b6498a99 100644 --- a/rero_ils/modules/entities/api.py +++ b/rero_ils/modules/entities/api.py @@ -20,16 +20,42 @@ from abc import ABC, abstractmethod -from elasticsearch_dsl import Q, A +from elasticsearch_dsl import A from flask import current_app -from rero_ils.modules.api import IlsRecord +from rero_ils.modules.api import IlsRecord, IlsRecordsSearch from rero_ils.modules.documents.api import DocumentsSearch +from rero_ils.modules.entities.remote_entities.utils import \ + extract_data_from_mef_uri +from rero_ils.modules.utils import extracted_data_from_ref, sorted_pids + + +class EntitiesSearch(IlsRecordsSearch): + """Entities search class.""" + + class Meta: + """Meta class.""" + + index = 'entities' + doc_types = None + fields = ('*', ) + facets = {} + + default_filter = None class Entity(IlsRecord, ABC): """Entity class.""" + @classmethod + def get_record_by_ref(cls, ref): + """.""" + from .remote_entities.api import RemoteEntity + if entity := extracted_data_from_ref(ref, 'record'): + return entity + _, _type, _pid = extract_data_from_mef_uri(ref) + return RemoteEntity.get_entity(_type, _pid) + @abstractmethod def get_authorized_access_point(self, language): """Get localized authorized_access_point. @@ -39,6 +65,30 @@ def get_authorized_access_point(self, language): """ raise NotImplementedError + @abstractmethod + def get_links_to_me(self, get_pids=False): + """Get links to other resources. + + :param get_pids: related resource pids are included into response ; + otherwise the count of related resources are specified. + :returns: list of related resource to this entity. + :rtype: dict. + """ + document_query = DocumentsSearch().by_entity(self) + documents = sorted_pids(document_query) if get_pids \ + else document_query.count() + links = { + 'documents': documents + } + return {k: v for k, v in links.items() if v} + + def reasons_not_to_delete(self): + """Get reasons not to delete record.""" + cannot_delete = {} + if links := self.get_links_to_me(): + cannot_delete['links'] = links + return cannot_delete + @property @abstractmethod def resource_type(self): @@ -47,8 +97,8 @@ def resource_type(self): @property def organisation_pids(self): - """Get organisations pids.""" - search = self._search_documents() + """Get organisation pids related with this entity.""" + search = DocumentsSearch().by_entity(self)[:0] agg = A( 'terms', field='holdings.organisation.organisation_pid', @@ -64,39 +114,25 @@ def organisation_pids(self): for result in results.aggregations.organisation.buckets }) - def _search_documents( + def documents_pids( self, with_subjects=True, with_subjects_imported=True, with_genre_forms=True ): - """Get ES query to search documents containing this entity. + """Get documents pids related to this entity. - :param with_subjects: search also on `subjects` ? - :param with_subjects_imported: search also on `subject_imported` ? - :param with_genre_forms: search also on `genreForm` ? + :param with_subjects: is the document `subject` field must be analyzed. + :param with_subjects_imported: is the document `subject_imported` field + must be analyzed. + :param with_genre_forms: is the document `genre_forms` field must be + analyzed. + :returns: document pids related to this entity. + :rtype: list """ - contribution_key = f'contribution.entity.pids.{self.resource_type}' - filters = Q('term', **{contribution_key: self.pid}) - if with_subjects: - search_field = f'subjects.entity.pids.{self.resource_type}' - filters |= Q('term', **{search_field: self.pid}) - if with_subjects_imported: - search_field = f'subjects_imported.pids.{self.resource_type}' - filters |= Q('term', **{search_field: self.pid}) - if with_genre_forms: - search_field = f'genreForm.entity.pids.{self.resource_type}' - filters |= Q('term', **{search_field: self.pid}) - - return DocumentsSearch().filter(filters) - - def documents_pids( - self, with_subjects=True, with_subjects_imported=True, - with_genre_forms=True - ): - """Get documents pids.""" - search = self._search_documents( - with_subjects=with_subjects, - with_subjects_imported=with_subjects_imported, - with_genre_forms=with_genre_forms + search = DocumentsSearch().by_entity( + self, + subjects=with_subjects, + imported_subjects=with_subjects_imported, + genre_forms=with_genre_forms ).source('pid') return [hit.pid for hit in search.scan()] @@ -104,10 +140,20 @@ def documents_ids( self, with_subjects=True, with_subjects_imported=True, with_genre_forms=True ): - """Get documents ids.""" - search = self._search_documents( - with_subjects=with_subjects, - with_subjects_imported=with_subjects_imported, - with_genre_forms=with_genre_forms + """Get document ID's/UUID related to this entity. + + :param with_subjects: is the document `subject` field must be analyzed. + :param with_subjects_imported: is the document `subject_imported` field + must be analyzed. + :param with_genre_forms: is the document `genre_forms` field must be + analyzed. + :returns: document ID's/UUID related to this entity. + :rtype: list + """ + search = DocumentsSearch().by_entity( + self, + subjects=with_subjects, + imported_subjects=with_subjects_imported, + genre_forms=with_genre_forms ).source(False) return [hit.meta.id for hit in search.scan()] diff --git a/rero_ils/modules/entities/local_entities/api.py b/rero_ils/modules/entities/local_entities/api.py index 955b1a33f4..6d847d6e64 100644 --- a/rero_ils/modules/entities/local_entities/api.py +++ b/rero_ils/modules/entities/local_entities/api.py @@ -21,7 +21,6 @@ from functools import partial from rero_ils.modules.api import IlsRecordsSearch -from rero_ils.modules.utils import sorted_pids from rero_ils.modules.fetchers import id_fetcher from rero_ils.modules.minters import id_minter from rero_ils.modules.operation_logs.extensions import \ @@ -113,24 +112,3 @@ def resolve(self): # The links will be stored as a `$ref` and `replace_refs_dumper` # will be used. return self.dumps(replace_refs_dumper) - - def get_links_to_me(self, get_pids=False): - """Record links. - - :param get_pids: if True list of linked pids - if False count of linked records - """ - document_query = self._search_documents() - documents = sorted_pids(document_query) if get_pids \ - else document_query.count() - links = { - 'documents': documents - } - return {k: v for k, v in links.items() if v} - - def reasons_not_to_delete(self): - """Get reasons not to delete record.""" - cannot_delete = {} - if links := self.get_links_to_me(): - cannot_delete['links'] = links - return cannot_delete diff --git a/rero_ils/modules/entities/local_entities/mappings/v7/local_entities/local_entity-v0.0.1.json b/rero_ils/modules/entities/local_entities/mappings/v7/local_entities/local_entity-v0.0.1.json index 7c96955e5c..f28776ac0c 100644 --- a/rero_ils/modules/entities/local_entities/mappings/v7/local_entities/local_entity-v0.0.1.json +++ b/rero_ils/modules/entities/local_entities/mappings/v7/local_entities/local_entity-v0.0.1.json @@ -124,10 +124,16 @@ "type": "text" }, "alternative_names": { - "type": "text" + "type": "text", + "copy_to": [ + "autocomplete_name" + ] }, "fuller_form_of_name": { - "type": "text" + "type": "text", + "copy_to": [ + "autocomplete_name" + ] }, "gender": { "type": "keyword" diff --git a/rero_ils/modules/entities/remote_entities/__init__.py b/rero_ils/modules/entities/remote_entities/__init__.py index ff7065b145..aba233d747 100644 --- a/rero_ils/modules/entities/remote_entities/__init__.py +++ b/rero_ils/modules/entities/remote_entities/__init__.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- # # RERO ILS -# Copyright (C) 2019-2022 RERO +# Copyright (C) 2019-2023 RERO +# Copyright (C) 2019-2023 UCLouvain # # 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 @@ -15,4 +16,4 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -"""Mef Contributions Records.""" +"""Remote entities Records.""" diff --git a/rero_ils/modules/entities/remote_entities/templates/rero_ils/_entity_by_source.html b/rero_ils/modules/entities/remote_entities/templates/rero_ils/_entity_by_source.html deleted file mode 100644 index 3eb2fe35ce..0000000000 --- a/rero_ils/modules/entities/remote_entities/templates/rero_ils/_entity_by_source.html +++ /dev/null @@ -1,55 +0,0 @@ -{# -*- coding: utf-8 -*- - - RERO ILS - Copyright (C) 2019-2023 RERO - Copyright (C) 2019-2023 UCLouvain - - 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 . - -#} - - -{% for agency in ["rero", "gnd", "idref"] %} -{% if record[agency] %} -
-
-
-
- - - -
-
-

- {{ _(agency) }} -

-
-
-
-
-
-
-   -
-
-
- {% with data=record[agency], source_name='agency', source=agency %} - {% include('rero_ils/_entity_by_source_data.html') %} - {% endwith %} -
-
-
-
-
-{% endif %} -{% endfor %} diff --git a/rero_ils/modules/entities/remote_entities/templates/rero_ils/_entity_unified.html b/rero_ils/modules/entities/remote_entities/templates/rero_ils/_entity_unified.html deleted file mode 100644 index cf6305d56c..0000000000 --- a/rero_ils/modules/entities/remote_entities/templates/rero_ils/_entity_unified.html +++ /dev/null @@ -1,45 +0,0 @@ -{# -*- coding: utf-8 -*- - - RERO ILS - Copyright (C) 2019-2023 RERO - Copyright (C) 2019-2023 UCLouvain - - 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 . - -#} - -{% from 'rero_ils/macros/entity.html' import dl, dl_bool, dl_permalink %} -{% set record = record %} -{% set data = record | entity_merge_data_values %} - -
- {{ dl(_('Birth date'), data.date_of_birth) }} - {{ dl(_('Death date'), data.date_of_death) }} - {% if data.language %} - {{ dl(_('Language'), data.language|translat_unified('lang_')) }} - {% endif %} - {{ dl(_('Gender'), data.gender) }} - {{ dl(_('Biographical information'), data.biographical_information | biographicaUrl) }} - {{ dl(_('Qualifier'), data.qualifier) }} - {{ dl(_('Numeration'), data.numeration) }} - {{ dl(_('Date establishment'), data.date_of_establishment) }} - {{ dl(_('Death termination'), data.date_of_termination) }} - {{ dl_bool(_('Conference'), data.conference) }} - {% if data.country_associated %} - {{ dl(_('Associated country'), data.country_associated|translat_unified('country_')) }} - {% endif %} - {{ dl_permalink(_('ID'), data) }} - {{ dl(_('Authorized access point'), data.authorized_access_point) }} - {{ dl(_('Variant access point'), data.variant_access_point) }} - {{ dl(_('Parallel access point'), data.parallel_access_point) }} -
diff --git a/rero_ils/modules/entities/remote_entities/templates/rero_ils/detailed_view_entity.html b/rero_ils/modules/entities/remote_entities/templates/rero_ils/detailed_view_entity.html deleted file mode 100644 index 5541cbe30d..0000000000 --- a/rero_ils/modules/entities/remote_entities/templates/rero_ils/detailed_view_entity.html +++ /dev/null @@ -1,82 +0,0 @@ -{# -*- coding: utf-8 -*- - - RERO ILS - Copyright (C) 2019-2022 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 . - -#} - -{%- extends 'rero_ils/page.html' %} - -{%- block body %} -
-
- {% if record.type == "bf:Organisation" %} - - {% else %} - - {% endif %} -
-
-

{{ record | entity_label(current_i18n.language) }}

- MEF ID: {{ record.pid }} -
-
- - -{%- if record.documents %} -
-
-

{{ _('Documents') }}

-
- -
-{% endif %} - -{% endblock body %} diff --git a/rero_ils/modules/entities/remote_entities/views.py b/rero_ils/modules/entities/remote_entities/views.py index 61dddb9985..a2b5229d52 100644 --- a/rero_ils/modules/entities/remote_entities/views.py +++ b/rero_ils/modules/entities/remote_entities/views.py @@ -20,93 +20,18 @@ from __future__ import absolute_import, print_function -from flask import Blueprint, abort, current_app, render_template -from flask_babelex import gettext as translate -from invenio_records_ui.signals import record_viewed +from flask import Blueprint, abort from rero_ils.modules.decorators import check_logged_as_librarian -from rero_ils.modules.documents.api import DocumentsSearch -from rero_ils.modules.organisations.api import Organisation -from rero_ils.theme.views import url_active -from .api import RemoteEntity -from ..models import EntityType from .proxy import MEFProxyFactory -blueprint = Blueprint( - 'remote_entities', - __name__, - url_prefix='/', - template_folder='templates', - static_folder='static', -) - api_blueprint = Blueprint( 'api_remote_entities', __name__ ) -def remote_entity_proxy(viewcode, pid, entity_type): - """Proxy for entities. - - :param viewcode: viewcode of html request - :param pid: pid of contribution - :param entity_type: type of the entity - :returns: entity template - """ - entity = RemoteEntity.get_record_by_pid(pid) - if not entity or entity.get('type') != entity_type: - abort(404, 'Record not found') - return remote_entity_view_method( - pid=entity.persistent_identifier, - record=entity, - template='rero_ils/detailed_view_entity.html', - viewcode=viewcode - ) - - -def remote_entity_view_method(pid, record, template=None, **kwargs): - """Display default view. - - Sends record_viewed signal and renders template. - - :param pid: PID object. - :param record: the `Entity` record, - :param template: the template to use to render the entity - """ - record_viewed.send( - current_app._get_current_object(), pid=pid, record=record) - - # Get contribution persons documents - search = DocumentsSearch()\ - .filter('term', contribution__entity__pid=pid.pid_value) - - viewcode = kwargs['viewcode'] - if viewcode != current_app.config.get('RERO_ILS_SEARCH_GLOBAL_VIEW_CODE'): - org_pid = Organisation.get_record_by_viewcode(viewcode)['pid'] - search = search \ - .filter('term', holdings__organisation__organisation_pid=org_pid) - search = search \ - .params(preserve_order=True)\ - .sort({'sort_title': {'order': 'asc'}}) - - record['documents'] = list(search.scan()) - return render_template(template, record=record, viewcode=viewcode) - - -@blueprint.route('/persons/', methods=['GET']) -def persons_proxy(viewcode, pid): - """Proxy person for entity.""" - return remote_entity_proxy(viewcode, pid, EntityType.PERSON) - - -@blueprint.route('/corporate-bodies/', methods=['GET']) -def corporate_bodies_proxy(viewcode, pid): - """Proxy corporate bodies for entity.""" - return remote_entity_proxy(viewcode, pid, EntityType.ORGANISATION) - - @api_blueprint.route('/remote_entities/search/', defaults={'entity_type': 'agents'}) @api_blueprint.route('/remote_entities/search//') @@ -126,78 +51,3 @@ def remote_search_proxy(entity_type, term): return MEFProxyFactory.create_proxy(entity_type).search(term) except ValueError as err: abort(400, str(err)) - - -# TEMPLATE JINJA FILTERS ====================================================== -@blueprint.app_template_filter() -def entity_merge_data_values(data): - """Create merged data for values.""" - sources = current_app.config.get('RERO_ILS_AGENTS_SOURCES', []) - result = {} - for source in sources: - if data.get(source): - result[source] = { - 'pid': data[source]['pid'], - 'identifier': data[source]['identifier'] - } - for key, values in data.get(source, {}).items(): - if key == 'conference': - result['conference'] = data[source]['conference'] - else: - if key not in result: - result[key] = {} - if isinstance(values, str): - values = [values] - for value in values: - if value in result[key]: - result[key][value].append(source) - else: - result[key][value] = [source] - return result - - -@blueprint.app_template_filter() -def entity_label(data, language): - """Create contribution label.""" - order = current_app.config.get('RERO_ILS_AGENTS_LABEL_ORDER', []) - source_order = order.get(language, order.get(order['fallback'], [])) - for source in source_order: - if label := data.get(source, {}).get('authorized_access_point', None): - return label - return '-' - - -@blueprint.app_template_filter() -def translat_unified(data, prefix=''): - """Translate the keys of an dictionary. - - :param data: dictionary to translate - :param prefix: prefix to add to keys - :returns: dictionary with translated keys - """ - return { - translate(f'{prefix}{key}'): value - for key, value - in data.items() - } - - -@blueprint.app_template_filter() -@api_blueprint.app_template_filter() -def translat(data, prefix='', seperator=', '): - """Translate data.""" - if data: - if isinstance(data, list): - translated = [translate(f'{prefix}{item}') for item in data] - return seperator.join(translated) - elif isinstance(data, str): - return translate(f'{prefix}{data}') - - -@blueprint.app_template_filter('biographicaUrl') -def biographical_url(biographicals): - """Add link url on text if http detected.""" - return { - url_active(biographical, '_blank'): biographicals[biographical] - for biographical in biographicals - } diff --git a/rero_ils/modules/entities/templates/rero_ils/_local_organisation.html b/rero_ils/modules/entities/templates/rero_ils/_local_organisation.html new file mode 100644 index 0000000000..a88976f481 --- /dev/null +++ b/rero_ils/modules/entities/templates/rero_ils/_local_organisation.html @@ -0,0 +1,28 @@ +{# -*- coding: utf-8 -*- + + RERO ILS + Copyright (C) 2019-2023 RERO + Copyright (C) 2019-2023 UCLouvain + + 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 . + +#} +{{ dl(_('Name'), record.name) }} +{{ dl(_('Subordinate units'), record.subordinate_units) }} +{{ dl(_('Conference place'), record.conference_place) }} +{{ dl(_('Conference numbering'), record.conference_numbering) }} +{{ dl(_('Conference date'), record.conference_date) }} +{{ dl_bool(_('Conference'), record.conference) }} +{{ dl(_('Start date'), record.start_date) }} +{{ dl(_('End date'), record.end_date) }} +{{ dl(_('Alternative names'), record.alternative_names) }} diff --git a/rero_ils/modules/entities/templates/rero_ils/_local_person.html b/rero_ils/modules/entities/templates/rero_ils/_local_person.html new file mode 100644 index 0000000000..89a4ea4067 --- /dev/null +++ b/rero_ils/modules/entities/templates/rero_ils/_local_person.html @@ -0,0 +1,26 @@ +{# -*- coding: utf-8 -*- + + RERO ILS + Copyright (C) 2019-2023 RERO + Copyright (C) 2019-2023 UCLouvain + + 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 . + +#} +{{ dl(_('Name'), record.name) }} +{{ dl(_('Birth date'), record.date_of_birth) }} +{{ dl(_('Death date'), record.date_of_death) }} +{{ dl(_('Numeration'), record.numeration) }} +{{ dl(_('Qualifier'), record.qualifier) }} +{{ dl(_('Fuller form of name'), record.fuller_form_of_name) }} +{{ dl(_('Alternative names'), record.alternative_names) }} diff --git a/rero_ils/modules/entities/templates/rero_ils/_local_place.html b/rero_ils/modules/entities/templates/rero_ils/_local_place.html new file mode 100644 index 0000000000..8c281c2318 --- /dev/null +++ b/rero_ils/modules/entities/templates/rero_ils/_local_place.html @@ -0,0 +1,21 @@ +{# -*- coding: utf-8 -*- + + RERO ILS + Copyright (C) 2019-2023 RERO + Copyright (C) 2019-2023 UCLouvain + + 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 . + +#} +{{ dl(_('Name'), record.name) }} +{{ dl(_('Alternative names'), record.alternative_names) }} diff --git a/rero_ils/modules/entities/templates/rero_ils/_local_temporal.html b/rero_ils/modules/entities/templates/rero_ils/_local_temporal.html new file mode 100644 index 0000000000..8c281c2318 --- /dev/null +++ b/rero_ils/modules/entities/templates/rero_ils/_local_temporal.html @@ -0,0 +1,21 @@ +{# -*- coding: utf-8 -*- + + RERO ILS + Copyright (C) 2019-2023 RERO + Copyright (C) 2019-2023 UCLouvain + + 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 . + +#} +{{ dl(_('Name'), record.name) }} +{{ dl(_('Alternative names'), record.alternative_names) }} diff --git a/rero_ils/modules/entities/templates/rero_ils/_local_topic.html b/rero_ils/modules/entities/templates/rero_ils/_local_topic.html new file mode 100644 index 0000000000..327fe585b6 --- /dev/null +++ b/rero_ils/modules/entities/templates/rero_ils/_local_topic.html @@ -0,0 +1,22 @@ +{# -*- coding: utf-8 -*- + + RERO ILS + Copyright (C) 2019-2023 RERO + Copyright (C) 2019-2023 UCLouvain + + 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 . + +#} +{{ dl(_('Name'), record.name) }} +{{ dl_bool(_('Genre form'), record.genreForm) }} +{{ dl(_('Alternative names'), record.alternative_names) }} diff --git a/rero_ils/modules/entities/templates/rero_ils/_local_work.html b/rero_ils/modules/entities/templates/rero_ils/_local_work.html new file mode 100644 index 0000000000..5d534f4ef0 --- /dev/null +++ b/rero_ils/modules/entities/templates/rero_ils/_local_work.html @@ -0,0 +1,21 @@ +{# -*- coding: utf-8 -*- + + RERO ILS + Copyright (C) 2019-2023 RERO + Copyright (C) 2019-2023 UCLouvain + + 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 . + +#} +{{ dl(_('Title'), record.title) }} +{{ dl(_('Creator'), record.creator) }} diff --git a/rero_ils/modules/entities/remote_entities/templates/rero_ils/_entity_by_source_data.html b/rero_ils/modules/entities/templates/rero_ils/_remote_organisation.html similarity index 62% rename from rero_ils/modules/entities/remote_entities/templates/rero_ils/_entity_by_source_data.html rename to rero_ils/modules/entities/templates/rero_ils/_remote_organisation.html index 0086768e61..c25c78cde8 100644 --- a/rero_ils/modules/entities/remote_entities/templates/rero_ils/_entity_by_source_data.html +++ b/rero_ils/modules/entities/templates/rero_ils/_remote_organisation.html @@ -18,24 +18,20 @@ #} -{% from 'rero_ils/macros/entity.html' import dl, dl_bool, dl_permalink_by_source %} - -{{ dl(_('Birth date'), data.date_of_birth) }} -{{ dl(_('Death date'), data.date_of_death) }} -{% if data.language %} - {{ dl(_('Language'), data.language|translat('lang_')) }} -{% endif %} -{{ dl(_('Gender'), data.gender) }} -{{ dl(_('Biographical information'), data.biographical_information | join('\n') | urlActive('_blank') | nl2br | safe ) }} -{{ dl(_('Qualifier'), data.qualifier) }} -{{ dl(_('Numeration'), data.numeration) }} + {{ dl(_('Date establishment'), data.date_of_establishment) }} + {{ dl(_('Death termination'), data.date_of_termination) }} -{{ dl_bool(_('Conference'), data.conference) }} + +{% if data.language %} + {{ dl(_('Language'), data.language|translate('lang_')) }} +{% endif %} + {% if data.country_associated %} - {{ dl(_('Associated country'), data.country_associated|translat('country_')) }} + {{ dl(_('Associated country'), data.country_associated|translate('country_')) }} {% endif %} -{{ dl_permalink_by_source(_('ID'), data, source) }} + {{ dl(_('Authorized access point'), data.authorized_access_point) }} + {{ dl(_('Variant access point'), data.variant_access_point) }} -{{ dl(_('Parallel access point'), data.parallel_access_point) }} + diff --git a/rero_ils/modules/entities/templates/rero_ils/_remote_person.html b/rero_ils/modules/entities/templates/rero_ils/_remote_person.html new file mode 100644 index 0000000000..c2b6eebad1 --- /dev/null +++ b/rero_ils/modules/entities/templates/rero_ils/_remote_person.html @@ -0,0 +1,44 @@ +{# -*- coding: utf-8 -*- + + RERO ILS + Copyright (C) 2019-2023 RERO + Copyright (C) 2019-2023 UCLouvain + + 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 . + +#} + + +{% if data.date_of_birth %} + {{ dl(_('Birth date'), data.date_of_birth | format_date(date_format='short', time_format=None)) }} +{% endif %} + +{% if data.date_of_death %} + {{ dl(_('Death date'), data.date_of_death | format_date(date_format='short', time_format=None)) }} +{% endif %} + +{% if data.language %} + {{ dl(_('Language'), data.language|translate('lang_')) }} +{% endif %} + +{{ dl(_('Gender'), data.gender) }} + +{% if data.biographical_information %} +{{ dl(_('Biographical information'), data.biographical_information | join('\n') | urlActive('_blank') | nl2br | safe ) }} +{% endif %} + +{{ dl(_('Name'), data.name) }} + +{{ dl(_('Variant access point'), data.variant_access_point) }} + +{{ dl(_('Authorized access point'), data.authorized_access_point) }} diff --git a/rero_ils/modules/entities/templates/rero_ils/_remote_topic.html b/rero_ils/modules/entities/templates/rero_ils/_remote_topic.html new file mode 100644 index 0000000000..e11561c534 --- /dev/null +++ b/rero_ils/modules/entities/templates/rero_ils/_remote_topic.html @@ -0,0 +1,71 @@ +{# -*- coding: utf-8 -*- + + RERO ILS + Copyright (C) 2019-2023 RERO + Copyright (C) 2019-2023 UCLouvain + + 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 . + +#} + + +{% if data.bnf_type %} + {{ dl(_('Type'), data.bnf_type) }} +{% endif %} + +{% if data.variant_access_point %} + {{ dl(_('Variant access point(s)'), data.variant_access_point) }} +{% endif %} + +{% if data.broader %} +
{{ _('Broader') }}
+
+
    + {% for broader in data.broader %} +
  • {{ broader.authorized_access_point }}
  • + {% endfor %} +
+
+{% endif %} + +{% if data.related %} +
{{ _('Related') }}
+
+
    + {% for related in data.related %} +
  • {{ related.authorized_access_point }}
  • + {% endfor %} +
+
+{% endif %} + +{% if data.classification %} +
{{ _('Classification(s)') }}
+
+
    + {% for classification in data.classification %} +
  • + {% if classification.classificationPortion %} + {{ classification.classificationPortion }} + {% endif %} + {% if classification.name %} + {{ classification.name }} + {% endif %} + {% if classification.type %} + {{ _(classification.type) }} + {% endif %} +
  • + {% endfor %} +
+
+{% endif %} diff --git a/rero_ils/modules/entities/templates/rero_ils/_search_link.html b/rero_ils/modules/entities/templates/rero_ils/_search_link.html new file mode 100644 index 0000000000..67c06af6cc --- /dev/null +++ b/rero_ils/modules/entities/templates/rero_ils/_search_link.html @@ -0,0 +1,24 @@ +{# -*- coding: utf-8 -*- + + RERO ILS + Copyright (C) 2019-2023 RERO + Copyright (C) 2019-2023 UCLouvain + + 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 . + +#} + + + + {{ _('Search documents') }} + diff --git a/rero_ils/modules/entities/templates/rero_ils/entity_local.html b/rero_ils/modules/entities/templates/rero_ils/entity_local.html new file mode 100644 index 0000000000..e13b98bca5 --- /dev/null +++ b/rero_ils/modules/entities/templates/rero_ils/entity_local.html @@ -0,0 +1,64 @@ +{# -*- coding: utf-8 -*- + + RERO ILS + Copyright (C) 2019-2023 RERO + Copyright (C) 2019-2023 UCLouvain + + 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 . + +#} +{% from 'rero_ils/macros/entity.html' import dl, dl_bool, dl_permalink_by_source %} + +{% extends 'rero_ils/page.html' %} + +{% set pid = record.pid %} + +{%- block body %} +
+
+

+ + {{ record.authorized_access_point }} +

+ {{ _('LOCAL ID') }}: {{ pid }} +
+
+ {% include 'rero_ils/_search_link.html' %} +
+
+
+ {% if record['type'] == 'bf:Organisation' %} + {% include 'rero_ils/_local_organisation.html' %} + {% elif record['type'] == 'bf:Person' %} + {% include 'rero_ils/_local_person.html' %} + {% elif record['type'] == 'bf:Place' %} + {% include 'rero_ils/_local_place.html' %} + {% elif record['type'] == 'bf:Temporal' %} + {% include 'rero_ils/_local_temporal.html' %} + {% elif record['type'] == 'bf:Topic' %} + {% include 'rero_ils/_local_topic.html' %} + {% elif record['type'] == 'bf:Work' %} + {% include 'rero_ils/_local_work.html' %} + {% endif %} + + + {{ dl(_('Source catalog'), record.source_catalog) }} + {% if record.identifier %} +
{{ _('Identifier') }}
+
+ {{ _(record.identifier.type) }} - {{ record.identifier.value }} + {% if record.identifier.source %}({{ record.identifier.source }}){% endif %} +
+ {% endif %} +
+{%- endblock body %} diff --git a/rero_ils/modules/entities/templates/rero_ils/entity_remote.html b/rero_ils/modules/entities/templates/rero_ils/entity_remote.html new file mode 100644 index 0000000000..97f2efbe88 --- /dev/null +++ b/rero_ils/modules/entities/templates/rero_ils/entity_remote.html @@ -0,0 +1,64 @@ +{# -*- coding: utf-8 -*- + + RERO ILS + Copyright (C) 2019-2023 RERO + Copyright (C) 2019-2023 UCLouvain + + 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 . + +#} +{% from 'rero_ils/macros/entity.html' import dl, dl_bool, dl_permalink_by_source %} + +{% extends 'rero_ils/page.html' %} + +{% set source, data = record|extract_data_from_remote_entity %} +{% set pid = record.pid %} + +{%- block body %} +
+
+

+ + {{ record | entity_label(current_i18n.language) }} +

+ MEF ID: {{ pid }} +
+
+ {% include 'rero_ils/_search_link.html' %} +
+
+
+ {% if record['type'] == 'bf:Organisation' %} + {% include 'rero_ils/_remote_organisation.html' %} + {% elif record['type'] == 'bf:Person' %} + {% include 'rero_ils/_remote_person.html' %} + {% elif record['type'] == 'bf:Topic' %} + {% include 'rero_ils/_remote_topic.html' %} + {% endif %} + + {% set links = record|sources_link %} + {% if links != {} %} +
{{ _('Source(s)') }}
+
+
    + {% for source, link in links.items() %} +
  • + {{ source }} + {{ "; " if not loop.last else "" }} +
  • + {% endfor %} +
+
+ {% endif %} +
+{%- endblock body %} diff --git a/rero_ils/modules/entities/remote_entities/templates/rero_ils/macros/entity.html b/rero_ils/modules/entities/templates/rero_ils/macros/entity.html similarity index 72% rename from rero_ils/modules/entities/remote_entities/templates/rero_ils/macros/entity.html rename to rero_ils/modules/entities/templates/rero_ils/macros/entity.html index 9bd81f1392..8dd8572b9e 100644 --- a/rero_ils/modules/entities/remote_entities/templates/rero_ils/macros/entity.html +++ b/rero_ils/modules/entities/templates/rero_ils/macros/entity.html @@ -20,10 +20,10 @@ {% macro dl(name, value, prefix) %} {% if value %} -
+
{{ name }}:
-
+
{% if value is string %} {% if prefix %} {{ _(prefix.format(v=value)) }} @@ -56,33 +56,11 @@ {{ name }}:
- +
{% endif %} {% endmacro %} -{% macro dl_permalink(name, record) %} -
- {{ _(name) }}: -
-
-
    - {% for source in config.RERO_ILS_AGENTS_SOURCES %} - {% if record[source] %} -
  • - {% if source != 'rero' %} - {{ record[source].pid }} - {% else %} - {{ record[source].pid }} - {% endif %} - {{ source }} -
  • - {% endif %} - {% endfor %} -
-
-{% endmacro %} - {% macro dl_permalink_by_source(name, data, source) %} {% if data.pid %}
diff --git a/rero_ils/modules/entities/views.py b/rero_ils/modules/entities/views.py new file mode 100644 index 0000000000..b6e9f481f8 --- /dev/null +++ b/rero_ils/modules/entities/views.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- +# +# RERO ILS +# Copyright (C) 2019-2023 RERO +# Copyright (C) 2019-2023 UCLouvain +# +# 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 entities.""" +from flask import Blueprint, abort, current_app, render_template +from flask_babelex import gettext as _ +from invenio_i18n.ext import current_i18n + +from rero_ils.modules.entities.models import EntityType + +from .local_entities.api import LocalEntity +from .remote_entities.api import RemoteEntity + +blueprint = Blueprint( + 'entities', + __name__, + url_prefix='//entities', + template_folder='templates', + static_folder='static', +) + + +@blueprint.route('//') +def entity_detailed_view(viewcode, type, pid): + """Display entity view (local or remote). + + :param: viewcode: The current view code. + :param: type: Resource type. + :param: pid: Resource PID. + :returns: The html rendering of the resource. + """ + entity_class = LocalEntity if type == 'local' else RemoteEntity + if not (record := entity_class.get_record_by_pid(pid)): + abort(404, _('Entity not found.')) + + return render_template( + f'rero_ils/entity_{type}.html', + record=record, + viewcode=viewcode, + search_link=search_link(record) + ) + + +@blueprint.app_template_filter() +def entity_icon(type): + """Selects the right icon according to type. + + :param: type: Resource type. + :returns: string, The class of the selected icon. + """ + icons = { + EntityType.ORGANISATION: 'fa-building-o', + EntityType.PERSON: 'fa-user-o', + EntityType.PLACE: 'fa-map-marker', + EntityType.TEMPORAL: 'fa-calendar', + EntityType.TOPIC: 'fa-tag', + EntityType.WORK: 'fa-book' + } + return icons.get(type, 'fa-question-circle-o') + + +@blueprint.app_template_filter() +def extract_data_from_remote_entity(record): + """Data extraction based on language and resource type. + + Used only on remote entity. + + :param: record: the json record + :returns: source and the dictionary of the resource selected. + """ + locale = current_i18n.locale.language + agent_order = current_app.config.get('RERO_ILS_AGENTS_LABEL_ORDER') + if locale not in agent_order: + locale = agent_order.get('fallback', {}) + sources = agent_order.get(locale) + for source in sources: + if data := record.get(source): + return source, data + + +@blueprint.app_template_filter() +def entity_label(data, language): + """Create contribution label. + + :param data: The record metadata. + :param language: The current language. + :returns: The contribution label. + """ + order = current_app.config.get('RERO_ILS_AGENTS_LABEL_ORDER', []) + source_order = order.get(language, order.get(order['fallback'], [])) + for source in source_order: + if label := data.get(source, {}).get('authorized_access_point', None): + return label + return '-' + + +@blueprint.app_template_filter() +def sources_link(data): + """Extract sources link. + + :param data: The record metadata. + :returns A dict with the source and link. + """ + links = {} + sources_link = list(filter(lambda source: source not in + current_app.config.get( + 'RERO_ILS_AGENTS_SOURCES_EXCLUDE_LINK', []), + data.get('sources', []))) + + for source in sources_link: + if identifier := data.get(source, {}).get('identifier'): + links[source] = identifier + return links + + +def search_link(metadata): + """Generate Link for search entities. + + :param metadata: the record metadata. + :returns: the search link. + """ + queries = [] + for field in ['contribution', 'subjects', 'genreForm']: + if 'sources' in metadata: + # Remote entities + source, data = extract_data_from_remote_entity(metadata) + entity_id = data.get('pid') + else: + # Local entities + source = 'local' + entity_id = metadata.get('pid') + queries.append(f'{field}.entity.pids.{source}:{entity_id}') + return " OR ".join(queries) + "&simple=0" diff --git a/rero_ils/modules/ext.py b/rero_ils/modules/ext.py index 186083cb1c..cddd0d56db 100644 --- a/rero_ils/modules/ext.py +++ b/rero_ils/modules/ext.py @@ -42,7 +42,7 @@ from rero_ils.filter import address_block, empty_data, format_date_filter, \ get_record_by_ref, jsondumps, message_filter, node_assets, text_to_id, \ - to_pretty_json + to_pretty_json, translate from rero_ils.modules.acquisition.acq_accounts.listener import \ enrich_acq_account_data from rero_ils.modules.acquisition.acq_order_lines.listener import \ @@ -175,6 +175,7 @@ def __init__(self, app=None): app.add_template_filter(address_block) app.add_template_filter(message_filter, name='message') app.add_template_filter(issue_client_reference) + app.add_template_filter(translate) app.jinja_env.add_extension('jinja2.ext.do') app.jinja_env.globals['version'] = __version__ self.register_signals(app) diff --git a/rero_ils/theme/templates/rero_ils/address_block/eng.tpl.txt b/rero_ils/theme/templates/rero_ils/address_block/eng.tpl.txt index 16820da98c..c4c01298c5 100644 --- a/rero_ils/theme/templates/rero_ils/address_block/eng.tpl.txt +++ b/rero_ils/theme/templates/rero_ils/address_block/eng.tpl.txt @@ -1,7 +1,7 @@ {{ data.name }} {{ data.address.street }} {{ data.address.zip_code }} - {{ data.address.city }} -{{ data.address.country | translat('country_') }} +{{ data.address.country | translate('country_') }} {%- if data.email %} Email: {{ data.email }} {%- endif %} diff --git a/rero_ils/theme/templates/rero_ils/address_block/fre.tpl.txt b/rero_ils/theme/templates/rero_ils/address_block/fre.tpl.txt index 4bb3d15337..5583059424 100644 --- a/rero_ils/theme/templates/rero_ils/address_block/fre.tpl.txt +++ b/rero_ils/theme/templates/rero_ils/address_block/fre.tpl.txt @@ -1,7 +1,7 @@ {{ data.name }} {{ data.address.street }} {{ data.address.zip_code }} - {{ data.address.city }} -{{ data.address.country | translat('country_') }} +{{ data.address.country | translate('country_') }} {%- if data.email %} E-mail: {{ data.email }} {%- endif %} diff --git a/rero_ils/theme/templates/rero_ils/address_block/ger.tpl.txt b/rero_ils/theme/templates/rero_ils/address_block/ger.tpl.txt index 2dd13d4009..b1e49c29c2 100644 --- a/rero_ils/theme/templates/rero_ils/address_block/ger.tpl.txt +++ b/rero_ils/theme/templates/rero_ils/address_block/ger.tpl.txt @@ -1,7 +1,7 @@ {{ data.name }} {{ data.address.street }} {{ data.address.zip_code }} - {{ data.address.city }} -{{ data.address.country | translat('country_') }} +{{ data.address.country | translate('country_') }} {%- if data.email %} E-mail: {{ data.email }} {%- endif %} diff --git a/rero_ils/theme/templates/rero_ils/address_block/ita.tpl.txt b/rero_ils/theme/templates/rero_ils/address_block/ita.tpl.txt index 3454e4259d..60cca2d6b6 100644 --- a/rero_ils/theme/templates/rero_ils/address_block/ita.tpl.txt +++ b/rero_ils/theme/templates/rero_ils/address_block/ita.tpl.txt @@ -1,7 +1,7 @@ {{ data.name }} {{ data.address.street }} {{ data.address.zip_code }} - {{ data.address.city }} -{{ data.address.country | translat('country_') }} +{{ data.address.country | translate('country_') }} {%- if data.email %} E-mail: {{ data.email }} {%- endif %} diff --git a/tests/ui/documents/test_documents_api.py b/tests/ui/documents/test_documents_api.py index 18125b5b2b..0ee5a57f2a 100644 --- a/tests/ui/documents/test_documents_api.py +++ b/tests/ui/documents/test_documents_api.py @@ -182,8 +182,9 @@ def test_document_linked_subject( in subject['entity']['variant_access_point'] # reset fixtures - entity.delete() + doc.delete_from_index() doc.delete() + entity.delete() def test_document_add_cover_url(db, document): diff --git a/tests/ui/documents/test_documents_filter.py b/tests/ui/documents/test_documents_filter.py index 210e991964..e7dc724623 100644 --- a/tests/ui/documents/test_documents_filter.py +++ b/tests/ui/documents/test_documents_filter.py @@ -400,15 +400,26 @@ def test_contribution_format(db, entity_organisation): 'authorized_access_point_fr': 'author_fr' } }] - assert contribution_format(contributions, 'en', 'global') == 'author_def' - assert contribution_format(contributions, 'fr', 'global') == 'author_fr' - assert contribution_format(contributions, 'zh', 'global') == 'author_def' + # ---- Textual contribution + # With english language + link_part = '/global/search/documents?q=' \ + 'contribution.entity.authorized_access_point_en%3A' \ + '%22author_def%22' + assert link_part in contribution_format(contributions, 'en', 'global') + + # With french language + link_part = '/global/search/documents?q=' \ + 'contribution.entity.authorized_access_point_fr%3A' \ + '%22author_fr%22' + assert link_part in contribution_format(contributions, 'fr', 'global') + + # ---- Remote contribution contributions = [{ 'entity': {'pid': entity.pid} }] - link_part = f'/global/search/documents?q' \ - f'=contribution.entity.pids.{entity.resource_type}%3A' \ + link_part = f'/global/search/documents?q=' \ + f'contribution.entity.pids.{entity.resource_type}%3A' \ f'{entity.pid}' assert link_part in contribution_format(contributions, 'en', 'global') @@ -550,46 +561,71 @@ def test_main_title_text(): assert extract[0].get('_text') is not None -def test_doc_entity_label_filter(entity_person): +def test_doc_entity_label_filter(entity_person, local_entity_person): """Test entity label filter.""" + + # Remote entity + remote_pid = entity_person['idref']['pid'] data = { 'entity': { - 'authorized_access_point': 'subject topic', - 'type': EntityType.TOPIC + '$ref': f'https://mef.rero.ch/api/concepts/idref/{remote_pid}', + 'pid': remote_pid } } - assert doc_entity_label(data['entity'], None) == 'subject topic' - assert doc_entity_label(data['entity'], 'fr') == 'subject topic' + entity_type, value, label = doc_entity_label(data['entity'], 'fr') + assert 'remote' == entity_type + assert 'ent_pers' == value + assert 'Loy, Georg, 1885-19..' == label + # Local entity + pid = local_entity_person['pid'] data = { 'entity': { - 'authorized_access_point': 'topic_default', - 'authorized_access_point_fr': 'topic_fr', - 'type': EntityType.TOPIC + '$ref': f'https://bib.rero.ch/api/local_entities/{pid}' } } - assert doc_entity_label(data['entity'], 'fr') == 'topic_fr' - assert doc_entity_label(data['entity'], 'en') == 'topic_default' - assert doc_entity_label(data['entity'], None) == 'topic_default' + entity_type, value, label = doc_entity_label(data['entity'], 'fr') + assert 'local' == entity_type + assert 'locent_pers' == value + assert 'Loy, Georg (1881-1968)' == label + entity_type, value, label = doc_entity_label(data['entity'], 'en') + assert 'local' == entity_type + assert 'locent_pers' == value + assert 'Loy, Georg (1881-1968)' == label + + # Textual data = { 'entity': { - 'authorized_access_point': 'topic_default', - 'subdivisions': [{ - 'entity': { - 'authorized_access_point': 'sub_default', - 'authorized_access_point_fr': 'sub_fr' - } - }], - 'type': EntityType.TOPIC + 'authorized_access_point': 'subject topic' } } - assert doc_entity_label(data['entity'], 'fr') == 'topic_default - sub_fr' - assert doc_entity_label( - data['entity'], 'en') == 'topic_default - sub_default' - assert doc_entity_label( - data['entity'], None) == 'topic_default - sub_default' - - data = {'entity': {'pid': entity_person.pid}} - assert doc_entity_label(data['entity'], 'fr') == 'Loy, Georg, 1885-19..' - assert doc_entity_label(data['entity'], 'de') == 'Loy, Georg, 1885' + entity_type, value, label = doc_entity_label(data['entity'], None) + assert 'textual' == entity_type + assert 'subject topic' == value + assert 'subject topic' == label + + entity_type, value, label = doc_entity_label(data['entity'], 'fr') + assert 'textual' == entity_type + assert 'subject topic' == value + assert 'subject topic' == label + + # Textual with subdivision + data['entity']['subdivisions'] = [ + { + 'entity': { + 'authorized_access_point': 'Sub 1', + 'type': EntityType.TOPIC + } + }, + { + 'entity': { + 'authorized_access_point': 'Sub 2', + 'type': EntityType.TOPIC + } + } + ] + entity_type, value, label = doc_entity_label(data['entity'], 'fr') + assert 'textual' == entity_type + assert 'subject topic' == value + assert 'subject topic - Sub 1 - Sub 2' == label diff --git a/tests/ui/entities/remote_entities/test_remote_entities_api.py b/tests/ui/entities/remote_entities/test_remote_entities_api.py index 4ffc13edce..311a117a3b 100644 --- a/tests/ui/entities/remote_entities/test_remote_entities_api.py +++ b/tests/ui/entities/remote_entities/test_remote_entities_api.py @@ -125,6 +125,10 @@ def test_sync_contribution( ) flush_index(DocumentsSearch.Meta.index) + # Test that entity could not be deleted + assert pers.get_links_to_me(True)['documents'] == [doc.pid] + assert pers.reasons_not_to_delete()['links']['documents'] == 1 + # === nothing to update sync_entity._get_latest = mock.MagicMock( return_value=entity_person_data_tmp diff --git a/tests/ui/entities/remote_entities/test_remote_entities_filter.py b/tests/ui/entities/remote_entities/test_remote_entities_filter.py deleted file mode 100644 index 6080a26cd0..0000000000 --- a/tests/ui/entities/remote_entities/test_remote_entities_filter.py +++ /dev/null @@ -1,108 +0,0 @@ -# -*- coding: utf-8 -*- -# -# RERO ILS -# Copyright (C) 2019-2023 RERO -# Copyright (C) 2019-2023 UCLouvain -# -# 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 . - -"""Jinja2 filters tests.""" - -from rero_ils.modules.entities.remote_entities.views import entity_label, \ - entity_merge_data_values - - -def test_remote_entity_label(app, entity_person_data): - """Test entity label.""" - app.config['RERO_ILS_AGENTS_LABEL_ORDER'] = { - 'fallback': 'fr', - 'fr': ['rero', 'idref', 'gnd'], - 'de': ['gnd', 'rero', 'idref'], - } - label = entity_label(entity_person_data, 'fr') - assert label == 'Loy, Georg, 1885-19..' - label = entity_label(entity_person_data, 'it') - assert label == 'Loy, Georg, 1885-19..' - - -def test_remote_entity_merge_data_values(app, entity_person_data): - """Test entities merge data.""" - app.config['RERO_ILS_AGENTS_SOURCES'] = ['idref', 'gnd', 'rero'] - data = entity_merge_data_values(entity_person_data) - assert data == { - '$schema': { - 'https://mef.test.rero.ch/schemas/gnd/' - 'gnd-contribution-v0.0.1.json': ['gnd'], - 'https://mef.test.rero.ch/schemas/idref/' - 'idref-contribution-v0.0.1.json': ['idref'], - 'https://mef.test.rero.ch/schemas/rero/' - 'rero-contribution-v0.0.1.json': ['rero'] - }, - 'authorized_access_point': { - 'Loy, Georg, 1885': ['gnd'], - 'Loy, Georg, 1885-19..': ['idref', 'rero'] - }, - 'bf:Agent': { - 'bf:Person': ['idref', 'gnd', 'rero'] - }, - 'biographical_information': { - 'Diss. philosophische Fakultät': ['gnd'] - }, - 'country_associated': { - 'gw': ['idref', 'rero'] - }, - 'date_of_birth': { - '1885': ['gnd'], - '1885-05-14': ['idref', 'rero'] - }, - 'date_of_death': { - '19..': ['idref', 'rero'] - }, - 'identifier': { - 'http://d-nb.info/gnd/13343771X': ['gnd'], - 'http://www.idref.fr/223977268': ['idref'], - 'http://data.rero.ch/02-A017671081': ['rero'] - }, - 'language': { - 'ger': ['idref', 'rero'] - }, - 'md5': { - '3dd3788c64af4200676a35a5ea35b180': ['idref'], - '3dd3788c64af4200676a35a5ea35b181': ['rero'], - '5dad1e77d5a47d39e87bb0ec37aaf51e': ['gnd'] - }, - 'pid': { - '13343771X': ['gnd'], - '223977268': ['idref'], - 'A017671081': ['rero'] - }, - 'preferred_name': { - 'Loy, Georg': ['idref', 'gnd', 'rero'] - }, - 'variant_name': { - 'Loy, George, di Madeiros': ['gnd'] - }, - 'gnd': { - 'identifier': 'http://d-nb.info/gnd/13343771X', - 'pid': '13343771X' - }, - 'idref': { - 'identifier': 'http://www.idref.fr/223977268', - 'pid': '223977268' - }, - 'rero': { - 'identifier': 'http://data.rero.ch/02-A017671081', - 'pid': 'A017671081' - } - - } diff --git a/tests/ui/entities/remote_entities/test_remote_entities_ui.py b/tests/ui/entities/remote_entities/test_remote_entities_ui.py index 3303ff713d..51a0a04a91 100644 --- a/tests/ui/entities/remote_entities/test_remote_entities_ui.py +++ b/tests/ui/entities/remote_entities/test_remote_entities_ui.py @@ -16,22 +16,19 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -"""Tests UI view for entities.""" +"""Jinja2 filters tests.""" -from flask import url_for +from rero_ils.modules.entities.views import entity_label -def test_remote_entity_person_detailed_view(client, entity_person): - """Test entity person detailed view.""" - res = client.get(url_for( - 'remote_entities.persons_proxy', - viewcode='global', pid=entity_person.pid)) - assert res.status_code == 200 - - -def test_remote_entity_organisation_detailed_view(client, entity_organisation): - """Test entity organisation detailed view.""" - res = client.get(url_for( - 'remote_entities.corporate_bodies_proxy', - viewcode='global', pid='ent_org')) - assert res.status_code == 200 +def test_remote_entity_label(app, entity_person_data): + """Test entity label.""" + app.config['RERO_ILS_AGENTS_LABEL_ORDER'] = { + 'fallback': 'fr', + 'fr': ['rero', 'idref', 'gnd'], + 'de': ['gnd', 'rero', 'idref'], + } + label = entity_label(entity_person_data, 'fr') + assert label == 'Loy, Georg, 1885-19..' + label = entity_label(entity_person_data, 'it') + assert label == 'Loy, Georg, 1885-19..' diff --git a/tests/ui/entities/test_entities_ui.py b/tests/ui/entities/test_entities_ui.py new file mode 100644 index 0000000000..1a040238f1 --- /dev/null +++ b/tests/ui/entities/test_entities_ui.py @@ -0,0 +1,137 @@ +# -*- coding: utf-8 -*- +# +# RERO ILS +# Copyright (C) 2019-2023 RERO +# Copyright (C) 2019-2023 UCLouvain +# +# 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 . + +"""Tests UI view for entities.""" + +from flask import url_for +from invenio_i18n.ext import current_i18n + +from rero_ils.modules.entities.models import EntityType +from rero_ils.modules.entities.views import entity_icon, \ + extract_data_from_remote_entity, search_link, sources_link + + +def test_view(client, entity_person, local_entity_person): + """Entity detailed view test.""" + + # Check unauthorized type value in url + res = client.get(url_for( + 'entities.entity_detailed_view', + viewcode='global', + type='foo', + pid='foo' + )) + assert res.status_code == 404 + + # Check 404 error if entity does not exist + res = client.get(url_for( + 'entities.entity_detailed_view', + viewcode='global', + type='remote', + pid='foo' + )) + assert res.status_code == 404 + + # Remote entity + res = client.get(url_for( + 'entities.entity_detailed_view', + viewcode='global', + type='remote', + pid=entity_person.get('pid') + )) + assert res.status_code == 200 + + # Local entity + res = client.get(url_for( + 'entities.entity_detailed_view', + viewcode='global', + type='local', + pid=local_entity_person.get('pid') + )) + assert res.status_code == 200 + + +def test_entity_icon(): + """Entity icon test.""" + assert 'fa-building-o' == entity_icon(EntityType.ORGANISATION) + # Default icon if type not found + assert 'fa-question-circle-o' == entity_icon('foo') + + +def test_extract_data_from_record(app): + """Extract data from record test.""" + contrib_data = { + 'idref': {'data': 'idref'}, + 'rero': {'data': 'rero'}, + 'gnd': {'data': 'gnd'} + } + current_i18n.locale.language = 'fr' + source, data = extract_data_from_remote_entity(contrib_data) + assert source == 'idref' + assert contrib_data.get(source) == data + + current_i18n.locale.language = 'de' + source, data = extract_data_from_remote_entity(contrib_data) + assert source == 'gnd' + assert contrib_data.get(source) == data + + # Fallback test + current_i18n.locale.language = 'it' + source, data = extract_data_from_remote_entity(contrib_data) + assert source == 'idref' + assert contrib_data.get(source) == data + + # Control the selection cascade + contrib_data.pop('idref') + contrib_data.pop('gnd') + source, data = extract_data_from_remote_entity(contrib_data) + assert source == 'rero' + assert contrib_data.get(source) == data + + +def test_sources_link(app): + """Sources link test.""" + data = { + 'idref': {'identifier': 'http://www.idref.fr/066924502'}, + 'gnd': {'identifier': 'http://d-nb.info/gnd/118754688'}, + 'rero': {'identifier': 'http://data.rero.ch/02-A003795108'}, + 'sources': ['idref', 'gnd', 'rero'] + } + result = { + 'idref': 'http://www.idref.fr/066924502', + 'gnd': 'http://d-nb.info/gnd/118754688' + } + assert result == sources_link(data) + assert {} == sources_link({}) + + +def test_search_link(app, entity_organisation, local_entity_org): + """Search link test.""" + + # test remote link + link = search_link(entity_organisation) + assert link == 'contribution.entity.pids.rero:A027711299 ' \ + 'OR subjects.entity.pids.rero:A027711299 ' \ + 'OR genreForm.entity.pids.rero:A027711299' \ + '&simple=0' + # test local link + link = search_link(local_entity_org) + assert link == 'contribution.entity.pids.local:locent_org ' \ + 'OR subjects.entity.pids.local:locent_org ' \ + 'OR genreForm.entity.pids.local:locent_org' \ + '&simple=0' diff --git a/tests/ui/test_filters.py b/tests/ui/test_filters.py index b4cef0d6c8..7af95a3dd4 100644 --- a/tests/ui/test_filters.py +++ b/tests/ui/test_filters.py @@ -31,7 +31,7 @@ def test_get_record_by_ref(document_data, document): def test_date_filter_format_timestamp_en(app): """Test full english date and tile filter.""" datestring = format_date_filter('2018-06-06T09:29:55.947149+00:00') - assert 'Wednesday, June 6, 2018, 11:29:55 AM' in datestring + assert 'Wednesday, 6 June 2018, 11:29:55' in datestring datestring = format_date_filter( '2018-06-06T09:29:55.947149+00:00', locale='fr') @@ -46,28 +46,28 @@ def test_date_filter_format_default_en(app): """Test medium english date filter.""" datestring = format_date_filter( '1950-01-01', date_format='short', time_format=None) - assert '1/1/50' in datestring + assert '01/01/1950' in datestring def test_date_filter_timezone(app): """Test medium english date filter.""" datestring = format_date_filter( '2018-06-06T09:29:55.947149+00:00', timezone='Europe/Helsinki') - assert 'Wednesday, June 6, 2018, 12:29:55 PM' in datestring + assert 'Wednesday, 6 June 2018, 12:29:55' in datestring def test_date_filter_format_medium_date_en(app): """Test medium_date english date filter.""" datestring = format_date_filter( '1950-01-01', date_format='medium', time_format=None) - assert 'Jan 1, 1950' in datestring + assert '1 Jan 1950' in datestring def test_date_filter_format_full_en(app): """Test full english date filter.""" datestring = format_date_filter( '1950-01-01', date_format='full', time_format=None) - assert 'Sunday, January 1, 1950' in datestring + assert 'Sunday, 1 January 1950' in datestring def test_date_filter_format_full_fr(app): @@ -88,7 +88,7 @@ def test_time_filter_format_default(app): """Test default time.""" datestring = format_date_filter( '2018-06-06T09:29:55.947149+00:00', date_format=None) - assert datestring == '11:29:55 AM' + assert datestring == '11:29:55' def test_time_filter_format_fr(app): @@ -102,7 +102,7 @@ def test_time_filter_format_delimiter(app): """Test default time.""" datestring = format_date_filter( '2018-06-06T09:29:55.947149+00:00', delimiter=' - ') - assert datestring == 'Wednesday, June 6, 2018 - 11:29:55 AM' + assert datestring == 'Wednesday, 6 June 2018 - 11:29:55' def test_to_pretty():