diff --git a/rero_ils/modules/documents/dojson/contrib/marc21tojson/dnb/model.py b/rero_ils/modules/documents/dojson/contrib/marc21tojson/dnb/model.py index 7cd76a5ce5..f908f0a1ad 100644 --- a/rero_ils/modules/documents/dojson/contrib/marc21tojson/dnb/model.py +++ b/rero_ils/modules/documents/dojson/contrib/marc21tojson/dnb/model.py @@ -490,7 +490,7 @@ def marc21_to_part_of(self, key, value): do_part_of(self, marc21, key, value) -@marc21.over('work_access_point', '(^130..|^700.2|^710.2|^730..)') +@marc21.over('work_access_point', '(^130..|^730..)') @utils.for_each_value @utils.ignore_value def marc21_to_work_access_point(self, key, value): diff --git a/rero_ils/modules/documents/dojson/contrib/marc21tojson/kul/model.py b/rero_ils/modules/documents/dojson/contrib/marc21tojson/kul/model.py index 3e100a7034..be118d5580 100644 --- a/rero_ils/modules/documents/dojson/contrib/marc21tojson/kul/model.py +++ b/rero_ils/modules/documents/dojson/contrib/marc21tojson/kul/model.py @@ -502,7 +502,7 @@ def marc21_to_part_of(self, key, value): do_part_of(self, marc21, key, value) -@marc21.over('work_access_point', '(^130..|^700.2|^710.2|^730..)') +@marc21.over('work_access_point', '(^130..|^730..)') @utils.for_each_value @utils.ignore_value def marc21_to_work_access_point(self, key, value): diff --git a/rero_ils/modules/documents/dojson/contrib/marc21tojson/rero/model.py b/rero_ils/modules/documents/dojson/contrib/marc21tojson/rero/model.py index b5c863bc83..3c0b3b83cb 100644 --- a/rero_ils/modules/documents/dojson/contrib/marc21tojson/rero/model.py +++ b/rero_ils/modules/documents/dojson/contrib/marc21tojson/rero/model.py @@ -28,8 +28,9 @@ get_field_items, not_repetitive, re_identified, \ remove_trailing_punctuation -from ..utils import _CONTRIBUTION_ROLE, do_acquisition_terms_from_field_037, \ - do_copyright_date, do_credits, do_dissertation, do_edition_statement, \ +from ..utils import _CONTRIBUTION_ROLE, do_abbreviated_title, \ + do_acquisition_terms_from_field_037, do_copyright_date, do_credits, \ + do_dissertation, do_edition_statement, \ do_electronic_locator_from_field_856, do_frequency_field_310_321, \ do_identified_by_from_field_020, do_identified_by_from_field_022, \ do_identified_by_from_field_024, do_identified_by_from_field_028, \ @@ -111,6 +112,13 @@ def marc21_to_title(self, key, value): @utils.ignore_value def marc21_to_contribution(self, key, value): """Get contribution.""" + # exclude work access points + if key[:3] in ['700', '710'] and value.get('t'): + work_access_point = do_work_access_point(marc21, key, value) + if work_access_point: + self.setdefault('work_access_point', []) + self['work_access_point'].append(work_access_point) + return None agent = {} subfields_0 = utils.force_list(value.get('0')) if subfields_0: @@ -267,6 +275,14 @@ def marc21_to_copyright_date(self, key, value): return copyright_dates or None +@marc21.over('title', '(^210|^222)..') +@utils.ignore_value +def marc21_to_abbreviated_title(self, key, value): + """Get abbreviated title data.""" + title_list = do_abbreviated_title(self, marc21, key, value) + return title_list or None + + @marc21.over('editionStatement', '^250..') @utils.for_each_value @utils.ignore_value @@ -1050,7 +1066,7 @@ def marc21_to_masked(self, key, value): return value.get('a') == 'masked' -@marc21.over('work_access_point', '(^130..|^700.2|^710.2|^730..)') +@marc21.over('work_access_point', '(^130..|^730..)') @utils.for_each_value @utils.ignore_value def marc21_to_work_access_point(self, key, value): diff --git a/rero_ils/modules/documents/dojson/contrib/marc21tojson/slsp/model.py b/rero_ils/modules/documents/dojson/contrib/marc21tojson/slsp/model.py index 6f3124b5d9..98a8c2e244 100644 --- a/rero_ils/modules/documents/dojson/contrib/marc21tojson/slsp/model.py +++ b/rero_ils/modules/documents/dojson/contrib/marc21tojson/slsp/model.py @@ -512,7 +512,7 @@ def marc21_to_part_of(self, key, value): do_part_of(self, marc21, key, value) -@marc21.over('work_access_point', '(^130..|^700.2|^710.2|^730..)') +@marc21.over('work_access_point', '(^130..|^730..)') @utils.for_each_value @utils.ignore_value def marc21_to_work_access_point(self, key, value): diff --git a/rero_ils/modules/documents/dojson/contrib/marc21tojson/utils.py b/rero_ils/modules/documents/dojson/contrib/marc21tojson/utils.py index bbb9c68d5c..d7a4c0ca14 100644 --- a/rero_ils/modules/documents/dojson/contrib/marc21tojson/utils.py +++ b/rero_ils/modules/documents/dojson/contrib/marc21tojson/utils.py @@ -363,7 +363,8 @@ def do_language(data, marc21): def do_abbreviated_title(data, marc21, key, value): """Get abbreviated title data. - * bf:Title = 210|222 + * bf:AbbreviatedTitle = 210 + * bf:KeyTitle = 222 * mainTitle = $a * subtitle = $e * responsibilityStatement = $f|$g @@ -376,8 +377,11 @@ def do_abbreviated_title(data, marc21, key, value): if value.get('a'): main_title = not_repetitive( marc21.bib_id, marc21.bib_id, key, value, 'a') + title_type = 'bf:AbbreviatedTitle' + if key[:3] == '222': + title_type = 'bf:KeyTitle' title = { - 'type': 'bf:AbbreviatedTitle', + 'type': title_type, 'mainTitle': [{'value': main_title}] } if value.get('b'): @@ -595,6 +599,10 @@ def build_agent(): # exclude work access points if key[:3] in ['700', '710'] and value.get('t'): + work_access_point = do_work_access_point(marc21, key, value) + if work_access_point: + data.setdefault('work_access_point', []) + data['work_access_point'].append(work_access_point) return None agent = {} @@ -614,23 +622,22 @@ def build_agent(): agent = build_agent() if value.get('4'): - roles = [] + roles = set() for role in utils.force_list(value.get('4')): - if len(role) != 3 and 'http' not in role: + role = role.split('/')[-1].lower() + if len(role) != 3: error_print('WARNING CONTRIBUTION ROLE LENGTH:', marc21.bib_id, marc21.rero_id, role) - role = role[:3] if role == 'sce': error_print('WARNING CONTRIBUTION ROLE SCE:', marc21.bib_id, marc21.rero_id, 'sce --> aus') role = 'aus' - role = role.lower() - if role not in _CONTRIBUTION_ROLE and 'http' not in role: + if role not in _CONTRIBUTION_ROLE: error_print('WARNING CONTRIBUTION ROLE DEFINITION:', marc21.bib_id, marc21.rero_id, role) role = 'ctb' - roles.append(role) + roles.add(role) else: if key[:3] == '100': roles = ['cre'] @@ -641,7 +648,7 @@ def build_agent(): if agent: return { 'agent': agent, - 'role': list(set(roles)) + 'role': list(roles) } return None @@ -1647,20 +1654,17 @@ def do_work_access_point(marc21, key, value): not_repetitive(marc21.bib_id, marc21.bib_id, key, value, 'b')) dates = not_repetitive(marc21.bib_id, marc21.bib_id, key, value, 'd') if dates: - dates = dates.rstrip(',') - dates = remove_trailing_punctuation(dates).split('-') + split_dates = dates.split('-') + date_of_birth = split_dates[0].strip() + if date_of_birth: + agent['date_of_birth'] = date_of_birth try: - date_of_birth = dates[0].strip() - if date_of_birth: - agent['date_of_birth'] = date_of_birth - except Exception: - pass - try: - date_of_death = dates[1].strip() + date_of_death = split_dates[1].strip() if date_of_death: agent['date_of_death'] = date_of_death except Exception: pass + if value.get('c'): agent['qualifier'] = remove_trailing_punctuation( not_repetitive(marc21.bib_id, marc21.bib_id, key, value, 'c')) @@ -1672,8 +1676,7 @@ def do_work_access_point(marc21, key, value): agent['preferred_name'] = not_repetitive( marc21.bib_id, marc21.bib_id, key, value, 'a') if value.get('b'): - agent['subordinate_unit'] = not_repetitive( - marc21.bib_id, marc21.bib_id, key, value, 'b') + agent['subordinate_unit'] = list(utils.force_list(value.get('b'))) if agent: work_access_point['agent'] = agent if value.get(title_tag): diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_work_access_point-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_work_access_point-v0.0.1.json index 05769083fe..85f22acbb0 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_work_access_point-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_work_access_point-v0.0.1.json @@ -108,7 +108,7 @@ "title": "Title", "description": "Title of the part, section, or supplement", "type": "string", - "minLength": 3 + "minLength": 1 } } } @@ -130,13 +130,13 @@ "items": { "title": "Medium of performance (music)", "type": "string", - "minLength": 3 + "minLength": 1 } }, "arranged_statement_for_music": { "title": "Arranged statement (music)", "type": "string", - "minLength": 3 + "minLength": 1 }, "key_for_music": { "title": "Key (music)", diff --git a/tests/unit/test_documents_dojson.py b/tests/unit/test_documents_dojson.py index d06a7306e7..7d957672ae 100644 --- a/tests/unit/test_documents_dojson.py +++ b/tests/unit/test_documents_dojson.py @@ -1349,6 +1349,11 @@ def test_marc21_to_contribution(mock_get): 1921-2014 edt + + Santamaría, Germán + No morirás + français + RERO @@ -5602,3 +5607,26 @@ def test_marc21_to_original_language(): marc21json = create_record(marc21xml) data = marc21.do(marc21json) assert data.get('originalLanguage') == ['eng'] + + +def test_abbreviated_title(app, marc21_record): + """Test abbreviated title to MARC21 transformation.""" + marc21xml = """ + + + Günter Gianni Piontek Skulpt. + + + Günter Gianni Piontek, Skulpturen + + + """ + marc21json = create_record(marc21xml) + data = marc21.do(marc21json) + assert data.get('title') == [{ + 'type': 'bf:AbbreviatedTitle', + 'mainTitle': [{'value': 'Günter Gianni Piontek Skulpt.'}] + }, { + 'type': 'bf:KeyTitle', + 'mainTitle': [{'value': 'Günter Gianni Piontek, Skulpturen'}] + }] diff --git a/tests/unit/test_documents_dojson_slsp.py b/tests/unit/test_documents_dojson_slsp.py new file mode 100644 index 0000000000..06ef600b9e --- /dev/null +++ b/tests/unit/test_documents_dojson_slsp.py @@ -0,0 +1,160 @@ +# -*- 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 . + +"""DOJSON module tests.""" + +from __future__ import absolute_import, print_function + +import mock +from dojson.contrib.marc21.utils import create_record + +from rero_ils.modules.documents.dojson.contrib.marc21tojson.slsp import marc21 + + +@mock.patch('requests.Session.get') +def test_marc21_to_contribution(mock_get): + """Test dojson marc21_to_contribution.""" + marc21xml = """ + + + Jean-Paul + II + Pape + 1954- + aut + + + Dumont, Jean + Historien + 1921-2014 + edt + + + Santamaría, Germán + No morirás + français + + + RERO + + + Biennale de céramique contemporaine + (17 : + 2003 : + Châteauroux) + + + Bible. + 000. + A.T. et N.T. : + Coréen + + + """ + + marc21json = create_record(marc21xml) + data = marc21.do(marc21json) + assert data.get('contribution') == [ + { + 'agent': { + 'type': 'bf:Person', + 'preferred_name': 'Jean-Paul', + 'numeration': 'II', + 'date_of_birth': '1954', + 'qualifier': 'Pape' + }, + 'role': ['aut'] + }, + { + 'agent': { + 'type': 'bf:Person', + 'preferred_name': 'Dumont, Jean', + 'date_of_birth': '1921', + 'date_of_death': '2014', + 'qualifier': 'Historien' + }, + 'role': ['edt'] + }, + { + 'agent': { + 'type': 'bf:Organisation', + 'preferred_name': 'RERO', + 'conference': False + }, + 'role': ['ctb'] + }, + { + 'agent': { + 'type': 'bf:Organisation', + 'preferred_name': 'Biennale de céramique contemporaine', + 'conference_date': '2003', + 'numbering': '17', + 'place': 'Châteauroux', + 'conference': True + }, + 'role': ['aut'] + } + ] + + assert data.get('work_access_point') == [{ + 'agent': { + 'preferred_name': 'Santamaría, Germán', + 'type': 'bf:Person' + }, + 'language': 'fre', + 'title': 'No morirás' + }, { + 'part': [{ + 'partName': 'A.T. et N.T. :', + 'partNumber': '000.' + }], + 'title': 'Bible.' + }] + + marc21xml = """ + + + Santamaría, Germán + No morirás + 1919-1990 + + + Santamaría, Germán + No morirás + 1919- + + + """ + + marc21json = create_record(marc21xml) + data = marc21.do(marc21json) + assert data.get('work_access_point') == [{ + 'agent': { + 'date_of_birth': '1919', + 'date_of_death': '1990', + 'preferred_name': 'Santamaría, Germán', + 'type': 'bf:Person' + }, + 'title': 'No morirás' + }, { + 'agent': { + 'date_of_birth': '1919', + 'preferred_name': 'Santamaría, Germán', + 'type': 'bf:Person' + }, + 'title': 'No morirás' + }]