Skip to content

Commit

Permalink
entities: public view for local and remote
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
Co-Authored-by: Renaud Michotte <[email protected]>
  • Loading branch information
Garfield-fr and zannkukai committed Sep 5, 2023
1 parent fc5b1ce commit a5996ca
Show file tree
Hide file tree
Showing 58 changed files with 1,055 additions and 680 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
15 changes: 8 additions & 7 deletions rero_ils/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
ItemOnLoanToItemReturned, PendingToItemAtDesk, \
PendingToItemInTransitPickup, ToCancelled, ToItemOnLoan
from invenio_records_rest.facets import range_filter, terms_filter
from invenio_records_rest.utils import deny_all, allow_all
from invenio_records_rest.utils import allow_all, deny_all

from rero_ils.modules.acquisition.acq_accounts.api import AcqAccount
from rero_ils.modules.acquisition.acq_accounts.permissions import \
Expand All @@ -63,6 +63,12 @@
from rero_ils.modules.acquisition.budgets.api import Budget
from rero_ils.modules.acquisition.budgets.permissions import \
BudgetPermissionPolicy
from rero_ils.modules.entities.local_entities.api import LocalEntity
from rero_ils.modules.entities.local_entities.permissions import \
LocalEntityPermissionPolicy
from rero_ils.modules.entities.remote_entities.api import RemoteEntity
from rero_ils.modules.entities.remote_entities.permissions import \
RemoteEntityPermissionPolicy

from .modules.circ_policies.api import CircPolicy
from .modules.circ_policies.permissions import \
Expand All @@ -73,9 +79,6 @@
from .modules.documents.permissions import DocumentPermissionPolicy
from .modules.documents.query import acquisition_filter, \
nested_identified_filter
from rero_ils.modules.entities.remote_entities.api import RemoteEntity
from rero_ils.modules.entities.remote_entities.permissions import \
RemoteEntityPermissionPolicy
from .modules.holdings.api import Holding
from .modules.holdings.models import HoldingCirculationAction
from .modules.holdings.permissions import HoldingsPermissionPolicy
Expand All @@ -98,9 +101,6 @@
get_extension_params, is_item_available_for_checkout, \
loan_build_document_ref, loan_build_item_ref, loan_build_patron_ref, \
validate_item_pickup_transaction_locations, validate_loan_duration
from rero_ils.modules.entities.local_entities.api import LocalEntity
from rero_ils.modules.entities.local_entities.permissions import \
LocalEntityPermissionPolicy
from .modules.local_fields.api import LocalField
from .modules.local_fields.permissions import LocalFieldPermissionPolicy
from .modules.locations.api import Location
Expand Down Expand Up @@ -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'],
Expand Down
21 changes: 21 additions & 0 deletions rero_ils/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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}')
25 changes: 25 additions & 0 deletions rero_ils/modules/documents/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand Down Expand Up @@ -244,6 +268,7 @@ def index_contributions(self, bulk=False):
"""Index all attached contributions."""
from rero_ils.modules.entities.remote_entities.api import \
RemoteEntitiesIndexer, RemoteEntity

from ..tasks import process_bulk_queue
contributions_ids = []
for contribution in self.get('contribution', []):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
from rero_ils.modules.documents.utils import display_alternate_graphic_first
from rero_ils.modules.documents.views import create_title_responsibilites
from rero_ils.modules.entities.models import EntityType
from rero_ils.modules.entities.remote_entities.api import RemoteEntity, \
RemoteEntitiesSearch
from rero_ils.modules.entities.remote_entities.api import \
RemoteEntitiesSearch, RemoteEntity
from rero_ils.modules.holdings.api import Holding, HoldingsSearch
from rero_ils.modules.items.api import Item, ItemsSearch
from rero_ils.modules.libraries.api import Library
Expand Down
3 changes: 1 addition & 2 deletions rero_ils/modules/documents/dumpers/replace_refs.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@
from invenio_records.dumpers import Dumper

from rero_ils.modules.commons.exceptions import RecordNotFound
from rero_ils.modules.entities.dumpers import \
document_dumper
from rero_ils.modules.entities.dumpers import document_dumper
from rero_ils.modules.entities.remote_entities.utils import \
extract_data_from_mef_uri
from rero_ils.modules.utils import extracted_data_from_ref
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
from invenio_records.extensions import RecordExtension

from rero_ils.dojson.utils import remove_trailing_punctuation
from rero_ils.modules.entities.models import EntityType

from ..utils import display_alternate_graphic_first
from rero_ils.modules.entities.models import EntityType


class ProvisionActivitiesExtension(RecordExtension):
Expand Down
2 changes: 1 addition & 1 deletion rero_ils/modules/documents/serializers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@

from rero_ils.modules.commons.identifiers import IdentifierFactory, \
IdentifierStatus, IdentifierType
from rero_ils.modules.entities.models import EntityType
from rero_ils.modules.utils import get_base_url

from ..api import DocumentsSearch
from rero_ils.modules.entities.models import EntityType

CREATOR_ROLES = [
'aut', 'cmp', 'cre', 'dub', 'pht', 'ape', 'aqt', 'arc', 'art', 'aus',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -218,7 +219,18 @@ <h3>
{% for subject in record.subjects %}
<span class="badge badge-secondary my-0" title="{{ _(subject.type) }}">
{% if 'entity' in subject %}
<i class="fa fa-tag"></i> {{ 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 %}
<i class="fa fa-tag"></i>
{% if query %}
<a class="text-white" href="{{ url_for('rero_ils.search', viewcode=viewcode, recordType='documents', q=query, simple=0) }}">{{ label }}</a>
{% else %}
{{ label }}
{% endif %}
{% endif %}
</span>
{% endfor %}
Expand All @@ -230,16 +242,25 @@ <h3>
<div class="pt-2">
{% 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 %}
<span class="mr-1">
<i class="fa fa-tag"></i>
{{ genreForm.entity | doc_entity_label(language=current_i18n.language) }}
{% if query %}
<a href="{{ url_for('rero_ils.search', viewcode=viewcode, recordType='documents', q=query, simple=0) }}">{{ label }}</a>
{% else %}
{{ label }}
{% endif %}
</span>
{% endif %}
{% endfor %}
</div>
{% endif %}


<!-- LINKED DOCUMENTS -->
{% if linked_documents_count and linked_documents_count > 0 %}
<a
Expand Down
59 changes: 37 additions & 22 deletions rero_ils/modules/documents/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -274,21 +275,27 @@ def contribution_format(contributions, language, viewcode, with_roles=False):
f'{entity.pid}',
'simple': 0
}
url = url_for('rero_ils.search', **args)
label = f'<a href="{url}">{text}</a>'
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'<a href="{url}">{text}</a>'

if with_roles:
if roles := [_(role) for role in contrib.get('role', [])]:
roles_str = ', '.join(roles)
label += f'<span class="text-secondary"> ({roles_str})</span>'
output.append(label)

return '&#8239;; '.join(output)
return ' ; '.join(output)


@blueprint.app_template_filter()
Expand All @@ -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()
Expand Down
Loading

0 comments on commit a5996ca

Please sign in to comment.