diff --git a/rero_ils/dojson/utils.py b/rero_ils/dojson/utils.py
index 2b314204a9..727120d8c5 100644
--- a/rero_ils/dojson/utils.py
+++ b/rero_ils/dojson/utils.py
@@ -17,14 +17,18 @@
"""Dojson utils."""
+import os
import re
import sys
import traceback
from copy import deepcopy
import click
+import requests
from dojson import Overdo, utils
+from rero_ils.modules.utils import requests_retry_session
+
_UNIMARC_LANGUAGES_SCRIPTS = {
'ba': 'latn', # Latin
'ca': 'cyrl', # Cyrillic
@@ -286,6 +290,8 @@
'z': 'Not applicable'
}
+_CONTRIBUTION_TAGS = ['100', '600', '610', '611', '630', '650', '651',
+ '655', '700', '710', '711']
re_identified = re.compile(r'\((.*)\)(.*)')
@@ -379,6 +385,35 @@ def remove_trailing_punctuation(
'',
data.rstrip()).rstrip()
+def get_contribution_link(bibid, reroid, id, key):
+ """Get MEF contribution link.
+
+ :params bibid: Bib id from the record.
+ :params reroid: RERO id from the record.
+ :params id: $0 from the marc field.
+ :params key: Tag from the marc field.
+ :returns: MEF url.
+ """
+ # https://mef.test.rero.ch/api/mef/?q=rero.rero_pid:A012327677
+ prod_host = 'mef.rero.ch'
+ test_host = os.environ.get('RERO_ILS_MEF_HOST', 'mef.rero.ch')
+ mef_url = f'https://{test_host}/api/'
+
+ match = re_identified.search(id)
+ if match and len(match.groups()) == 2 and key[:3] in _CONTRIBUTION_TAGS:
+ match_type = match.group(1).lower()
+ match_value = match.group(2)
+ if match_type == 'idref':
+ url = f'{mef_url}{match_type}/{match_value}'
+ response = requests_retry_session().get(url)
+ status_code = response.status_code
+ if status_code == requests.codes.ok:
+ return url.replace(test_host, prod_host)
+ error_print('WARNING GET MEF CONTRIBUTION:',
+ bibid, reroid, key, id, url, status_code)
+ else:
+ error_print('ERROR GET MEF CONTRIBUTION:', bibid, reroid, key, id)
+
def add_note(new_note, data):
"""Add a new note to the data avoiding duplicate notes.
@@ -913,6 +948,7 @@ class ReroIlsMarc21Overdo(ReroIlsOverdo):
has_field_490 = False
has_field_580 = False
content_media_carrier_type = None
+ links_from_752 = []
def __init__(self, bases=None, entry_point_group=None):
"""Reroilsmarc21overdo init."""
@@ -962,8 +998,11 @@ def do(self, blob, ignore_missing=True, exception_handlers=None):
self.field_008_data = ''
self.date1_from_008 = None
self.date2_from_008 = None
+ self.original_date_from_008 = None
self.date_type_from_008 = ''
self.date = {'start_date': None}
+ self.serial_type = ''
+ self.is_top_level_record = False
fields_008 = self.get_fields(tag='008')
if fields_008:
self.field_008_data = self.get_control_field_data(
@@ -995,9 +1034,9 @@ def do(self, blob, ignore_missing=True, exception_handlers=None):
# identifiy a top level record (has 019 $a Niveau supérieur)
regexp = re.compile(r'Niveau sup[eé]rieur', re.IGNORECASE)
fields_019 = self.get_fields(tag='019')
- note = ''
notes_from_019_and_351 = []
for field_019 in fields_019:
+ note = ''
for subfield_a in self.get_subfields(field_019, 'a'):
note += ' | ' + subfield_a
if regexp.search(subfield_a):
@@ -1037,7 +1076,20 @@ def do(self, blob, ignore_missing=True, exception_handlers=None):
if description_conventions:
self.admin_meta_data['descriptionConventions'] = \
description_conventions
- # check presence of specific fields
+
+ # build the list of links from filed 752
+ self.links_from_752 = []
+ fields_752 = self.get_fields(tag='752')
+ for field_752 in fields_752:
+ subfields_d = self.get_subfields(field_752, 'd')
+ items = get_field_items(field_752['subfields'])
+
+ if subfields_d:
+ identifier = build_identifier(field_752['subfields'])
+ if identifier:
+ self.links_from_752.append(identifier)
+
+ # check presence of specific fields
self.has_field_490 = len(self.get_fields(tag='490')) > 0
self.has_field_580 = len(self.get_fields(tag='580')) > 0
result = super().do(
@@ -1107,7 +1159,7 @@ def init_lang_from(fields_041, code):
langs_from_041.append(lang_from_041)
return langs_from_041
- self.lang_from_008 = ''
+ self.lang_from_008 = None
self.langs_from_041_a = []
self.langs_from_041_h = []
try:
diff --git a/rero_ils/modules/documents/dojson/contrib/marc21tojson/model.py b/rero_ils/modules/documents/dojson/contrib/marc21tojson/model.py
index 66518073ce..088abd7824 100644
--- a/rero_ils/modules/documents/dojson/contrib/marc21tojson/model.py
+++ b/rero_ils/modules/documents/dojson/contrib/marc21tojson/model.py
@@ -17,20 +17,35 @@
"""rero-ils MARC21 model definition."""
-import os
import re
-import requests
from dojson import utils
from dojson.utils import GroupableOrderedDict
from rero_ils.dojson.utils import ReroIlsMarc21Overdo, TitlePartList, \
add_note, build_identifier, build_responsibility_data, \
build_string_from_subfields, error_print, \
- extract_subtitle_and_parallel_titles_from_field_245_b, get_field_items, \
- get_field_link_data, make_year, not_repetitive, re_identified, \
- remove_trailing_punctuation
-from rero_ils.modules.utils import requests_retry_session
+ extract_subtitle_and_parallel_titles_from_field_245_b, \
+ get_contribution_link, get_field_items, get_field_link_data, make_year, \
+ not_repetitive, remove_trailing_punctuation
+
+_DOCUMENT_RELATION_PER_TAG = {
+ '770': 'supplement',
+ '772': 'supplementTo',
+ '775': 'otherEdition',
+ '776': 'otherPhysicalFormat',
+ '777': 'IssuedWith',
+ '780': 'precededBy',
+ '785': 'succeededBy',
+ '787': 'relatedTo',
+ '533': 'hasReproduction',
+ '534': 'reproductionOf'
+}
+
+_REPRODUCTION_SUBFIELDS_PER_TAG = {
+ '533': 'abcdemn',
+ '534': 'cep'
+}
_ISSUANCE_MAIN_TYPE_PER_BIB_LEVEL = {
'a': 'rdami:1001',
@@ -211,41 +226,21 @@
_IDREF_REF_REGEX = re.compile(r'^(?i)\(IdRef\)(.*)?')
_RERO_REF_REGEX = re.compile(r'^(?i)\(RERO\)(.*)?')
-_CONTRIBUTION_TAGS = ['100', '600', '610', '611', '630', '650', '651',
- '655', '700', '710', '711']
-
marc21 = ReroIlsMarc21Overdo()
-
-def get_contribution_link(bibid, reroid, id, key):
- """Get MEF contribution link.
-
- :params bibid: Bib id from the record.
- :params reroid: RERO id from the record.
- :params id: $0 from the marc field.
- :params key: Tag from the marc field.
- :returns: MEF url.
- """
- # https://mef.test.rero.ch/api/mef/?q=rero.rero_pid:A012327677
- prod_host = 'mef.rero.ch'
- test_host = os.environ.get('RERO_ILS_MEF_HOST', 'mef.rero.ch')
- mef_url = f'https://{test_host}/api/'
-
- match = re_identified.search(id)
- if match and len(match.groups()) == 2 and key[:3] in _CONTRIBUTION_TAGS:
- match_type = match.group(1).lower()
- match_value = match.group(2)
- if match_type == 'idref':
- url = f'{mef_url}{match_type}/{match_value}'
- response = requests_retry_session().get(url)
- status_code = response.status_code
- if status_code == requests.codes.ok:
- return url.replace(test_host, prod_host)
- error_print('WARNING GET MEF CONTRIBUTION:',
- bibid, reroid, key, id, url, status_code)
- else:
- error_print('ERROR GET MEF CONTRIBUTION:', bibid, reroid, key, id)
+def build_place():
+ """Build place data for provisionActivity."""
+ place = {}
+ if marc21.cantons:
+ place['canton'] = marc21.cantons[0]
+ if marc21.country:
+ place['country'] = marc21.country
+ if place:
+ place['type'] = 'bf:Place'
+ if marc21.links_from_752:
+ place['identifyBy'] = marc21.links_from_752[0]
+ return place
@marc21.over('issuance', 'leader')
@@ -346,7 +341,26 @@ def marc21_to_language(self, key, value):
if fields_264:
error_print('WARNING INVALID 264', marc21.bib_id, marc21.rero_id,
fields_264)
- self['provisionActivity'] = [{'type': 'bf:Publication'}]
+ places = []
+ publication = {
+ 'type': 'bf:Publication'
+ }
+ place = build_place()
+ if place:
+ places.append(place)
+ # parce le link skipping the fist (already used by build_place)
+ for i in range(1, len(marc21.links_from_752)):
+ place = {
+ 'country': 'und',
+ 'type': 'bf:Place',
+ 'identifyBy': links_from_752[i]
+ }
+ places.append(place)
+
+ if places:
+ publication['place'] = places
+ self['provisionActivity'] = [publication]
+
if (marc21.date_type_from_008 == 'q' or
marc21.date_type_from_008 == 'n'):
self['provisionActivity'][0][
@@ -635,6 +649,33 @@ def marc21_to_contribution(self, key, value):
}
+@marc21.over('relation', '(770|772|775|776|777|780|785|787|533|534)..')
+@utils.for_each_value
+@utils.ignore_value
+def marc21_to_specific_document_relation(self, key, value):
+ """Get contribution."""
+ tag = key[:3]
+ relation = None
+ if tag in ['533', '534']:
+ label = build_string_from_subfields(
+ value,
+ _REPRODUCTION_SUBFIELDS_PER_TAG[tag]
+ )
+ relation = {'label': label}
+ else:
+ subfield_w = not_repetitive(marc21.bib_id, marc21.rero_id,
+ key, value, 'w', default='').strip()
+ if subfield_w:
+ match = re.compile(r'^REROILS:')
+ pid = match.sub('', subfield_w)
+ ref = f'https://bib.rero.ch/api/documents/{pid}'
+ relation = {'$ref': ref}
+ if relation:
+ relation_list = self.get(_DOCUMENT_RELATION_PER_TAG[tag], [])
+ relation_list.append(relation)
+ self[_DOCUMENT_RELATION_PER_TAG[tag]] = relation_list
+
+
@marc21.over('copyrightDate', '^264.4')
@utils.ignore_value
def marc21_to_copyright_date(self, key, value):
@@ -690,10 +731,12 @@ def marc21_to_edition_statement(self, key, value):
def marc21_to_provisionActivity(self, key, value):
"""Get publisher data.
+
publisher.name: 264 [$b repetitive] (without the , but keep the ;)
publisher.place: 264 [$a repetitive] (without the : but keep the ;)
publicationDate: 264 [$c repetitive] (but take only the first one)
"""
+
def build_statement(field_value, ind2):
def build_agent_data(code, label, index, link):
@@ -732,16 +775,6 @@ def build_agent_data(code, label, index, link):
index += 1
return statement
- def build_place():
- place = {}
- if marc21.cantons:
- place['canton'] = marc21.cantons[0]
- if marc21.country:
- place['country'] = marc21.country
- if place:
- place['type'] = 'bf:Place'
- return place
-
# the function marc21_to_provisionActivity start here
ind2 = key[4]
type_per_ind2 = {
@@ -763,9 +796,21 @@ def build_place():
publication['endDate'] = marc21.date['end_date']
if 'note' in marc21.date:
publication['note'] = marc21.date['note']
+
+ places = []
place = build_place()
if place:
- publication['place'] = [place]
+ places.append(place)
+ # parce le link skipping the fist (already used by build_place)
+ for i in range(1, len(marc21.links_from_752)):
+ place = {
+ 'country': 'und',
+ 'type': 'bf:Place',
+ 'identifyBy': marc21.links_from_752[i]
+ }
+ places.append(place)
+ if places:
+ publication['place'] = places
publication['statement'] = build_statement(value, ind2)
if subfields_c:
@@ -859,6 +904,47 @@ def marc21_to_summary(self, key, value):
self['tableOfContents'] = table_of_contents_list
+@marc21.over('usageAndAccessPolicy', '^(506|540)..')
+@utils.ignore_value
+def marc21_to_usage_and_access_policy_from_field_506_540(self, key, value):
+ """Get usageAndAccessPolicy from fields: 506, 540."""
+ subfield_a = not_repetitive(marc21.bib_id, marc21.rero_id,
+ key, value, 'a', default='').strip()
+ if subfield_a:
+ policy = {
+ 'type': 'bf:UsageAndAccessPolicy',
+ 'label': subfield_a
+ }
+ usage_and_access_policy = self.get('usageAndAccessPolicy', [])
+ usage_and_access_policy.append(policy)
+ return usage_and_access_policy or None
+
+
+@marc21.over('frequency', '^(310|321)..')
+@utils.ignore_value
+def marc21_to_frequency_field_310_321(self, key, value):
+ """Get frequency from fields: 310, 321."""
+ subfield_a = not_repetitive(
+ marc21.bib_id, marc21.rero_id,
+ key, value, 'a', default='missing_label').strip()
+ subfield_b = not_repetitive(
+ marc21.bib_id, marc21.rero_id,
+ key, value, 'b', default='').strip()
+
+ frequency = {
+ 'label': remove_trailing_punctuation(
+ data=subfield_a,
+ punctuation=',',
+ spaced_punctuation=','
+ )
+ }
+ if subfield_b:
+ frequency['date'] = subfield_b
+ frequency_list = self.get('frequency', [])
+ frequency_list.append(frequency)
+ return frequency_list or None
+
+
@marc21.over('dissertation', '^502..')
@utils.for_each_value
@utils.ignore_value
@@ -1308,7 +1394,7 @@ def marc21_to_identifiedBy_from_field_930(self, key, value):
return identifiedBy or None
-@marc21.over('note', '^(500|510|530|545|580)..')
+@marc21.over('note', '^(500|510|530|545|555|580)..')
@utils.for_each_value
@utils.ignore_value
def marc21_to_notes_and_original_title(self, key, value):
diff --git a/tests/unit/test_documents_dojson.py b/tests/unit/test_documents_dojson.py
index 7fa33d42d4..16867ada72 100644
--- a/tests/unit/test_documents_dojson.py
+++ b/tests/unit/test_documents_dojson.py
@@ -153,6 +153,41 @@ def test_marc21_to_admin_metadata():
'note': ['Société de publications romanes (pf/08.05.1985)'],
}
+ marc21xml = """
+
+ 00501naa a22001332a 4500
+ 160315s2015 cc ||| | ||||00| |chi d
+
+ Catalogué d'après la couverture
+ nebpun/12.2019
+
+
+ BPUN: Sandoz, Pellet, Rosselet, Bähler
+ nebpun/12.2019
+
+
+ !!!Bibliographie neuchâteloise!!!
+ necfbv/12.2019/3546
+
+
+ !!! Discographie neuchâteloise!!!
+ necfbv/02.2021/3502
+
+
+ """
+ marc21json = create_record(marc21xml)
+ data = marc21.do(marc21json)
+ assert data.get('adminMetadata') == {
+ 'encodingLevel': 'Less-than-full level, material not examined',
+ 'note': [
+ "Catalogué d'après la couverture (nebpun/12.2019)",
+ 'BPUN: Sandoz, Pellet, Rosselet, Bähler (nebpun/12.2019)',
+ '!!!Bibliographie neuchâteloise!!! (necfbv/12.2019/3546)',
+ '!!! Discographie neuchâteloise!!! (necfbv/02.2021/3502)'
+ ]
+ }
+
marc21xml = """
00501naa a22001332a 4500
@@ -393,16 +428,16 @@ def test_marc21_to_mode_of_issuance():
marc21xml = """
- 00604cam a2200205 a 4500
+ 01518ccm a2200337 a 4500
150707m20159999fr |||m|| ||||00|| 0fre d
+ "008">150414s1993 sz |||p|| |||| || 0fre d
"""
marc21json = create_record(marc21xml)
data = marc21.do(marc21json)
assert data.get('issuance') == {
- 'main_type': 'rdami:1002',
- 'subtype': 'set'
+ 'main_type': 'rdami:1001',
+ 'subtype': 'materialUnit'
}
@@ -1508,6 +1543,42 @@ def test_marc21_provisionActivity_without_264():
data = marc21.do(marc21json)
assert data.get('provisionActivity') == [{
'type': 'bf:Publication',
+ 'place': [{
+ 'country': 'sz',
+ 'type': 'bf:Place'
+ }],
+ 'startDate': 2006,
+ 'endDate': 2010
+ }]
+
+
+def test_marc21_provisionActivity_without_264_with_752():
+ """Test dojson publication statement.
+
+ A value should be here even 264 does not exists.
+ """
+ marc21xml = """
+
+ 070518s20062010sz ||| | ||||00| |fre d
+
+ Neuchâtel (1450-1800, lieu d'édition ou d'impression)
+ (IdRef)027401421
+
+ """
+ marc21json = create_record(marc21xml)
+ data = marc21.do(marc21json)
+ assert data.get('provisionActivity') == [{
+ 'type': 'bf:Publication',
+ 'place': [{
+ 'country': 'sz',
+ 'type': 'bf:Place',
+ 'identifyBy': {
+ 'type': 'IdRef',
+ 'value': '027401421'
+ }
+ }],
'startDate': 2006,
'endDate': 2010
}]
@@ -1526,6 +1597,10 @@ def test_marc21_provisionActivity_with_original_date():
data = marc21.do(marc21json)
assert data.get('provisionActivity') == [{
'type': 'bf:Publication',
+ 'place': [{
+ 'country': 'sz',
+ 'type': 'bf:Place'
+ }],
'startDate': 1997,
'original_date': 1849,
'endDate': 1849
@@ -1631,6 +1706,30 @@ def test_marc21_to_provisionActivity_canton():
}
]
+ marc21xml = """
+
+ 060831s1998 sz ||| | ||||00| |fre d
+
+ sz
+ ch-vd
+
+
+ """
+ marc21json = create_record(marc21xml)
+ data = marc21.do(marc21json)
+ assert data.get('provisionActivity') == [
+ {
+ 'type': 'bf:Publication',
+ 'place': [{
+ 'canton': 'vd',
+ 'country': 'sz',
+ 'type': 'bf:Place'
+ }],
+ 'startDate': 1998
+ }
+ ]
+
def test_marc21_to_provisionActivity_1_place_2_agents():
"""Test dojson publication statement.
@@ -1681,6 +1780,138 @@ def test_marc21_to_provisionActivity_1_place_2_agents():
]
+def test_marc21_to_provisionActivity_1_place_2_agents_with_one_752():
+ """Test dojson publication statement.
+ - 1 publication place and 2 agents from one field 264
+ - 1 field 752
+ """
+
+ marc21xml = """
+
+ 940202m19699999fr |||||| ||||00|| |fre d
+
+ [Paris] :
+ Desclée de Brouwer [puis]
+ Etudes augustiniennes,
+ 1969-
+
+
+ Neuchâtel (1450-1800, lieu d'édition ou d'impression)
+ (IdRef)027401421
+
+
+ """
+ marc21json = create_record(marc21xml)
+ data = marc21.do(marc21json)
+ assert data.get('provisionActivity') == [
+ {
+ 'type': 'bf:Publication',
+ 'place': [{
+ 'country': 'fr',
+ 'type': 'bf:Place',
+ 'identifyBy': {
+ 'type': 'IdRef',
+ 'value': '027401421'
+ }
+ }],
+ 'statement': [
+ {
+ 'label': [{'value': '[Paris]'}],
+ 'type': 'bf:Place'
+ },
+ {
+ 'label': [{'value': 'Desclée de Brouwer [puis]'}],
+ 'type': 'bf:Agent'
+ },
+ {
+ 'label': [{'value': 'Etudes augustiniennes'}],
+ 'type': 'bf:Agent'
+ },
+ {
+ 'label': [{'value': '1969-'}],
+ 'type': 'Date'
+ }
+ ],
+ 'startDate': 1969
+ }
+ ]
+
+
+def test_marc21_to_provisionActivity_1_place_2_agents_with_two_752():
+ """Test dojson publication statement.
+ - 1 publication place and 2 agents from one field 264
+ - 2 field 752
+ """
+
+ marc21xml = """
+
+ 940202m19699999fr |||||| ||||00|| |fre d
+
+ [Paris] :
+ Desclée de Brouwer [puis]
+ Etudes augustiniennes,
+ 1969-
+
+
+ Neuchâtel (1450-1800, lieu d'édition ou d'impression)
+ (IdRef)027401421
+
+
+ Neuchâtel lieu d'édition ou d'impression)
+ (RERO)A000000001
+
+
+ """
+ marc21json = create_record(marc21xml)
+ data = marc21.do(marc21json)
+ print('T1000', data)
+ assert data.get('provisionActivity') == [
+ {
+ 'type': 'bf:Publication',
+ 'place': [{
+ 'country': 'fr',
+ 'type': 'bf:Place',
+ 'identifyBy': {
+ 'type': 'IdRef',
+ 'value': '027401421'
+ }
+ }, {
+ 'country': 'und',
+ 'type': 'bf:Place',
+ 'identifyBy': {
+ 'type': 'RERO',
+ 'value': 'A000000001'
+ }
+ }
+ ],
+ 'statement': [
+ {
+ 'label': [{'value': '[Paris]'}],
+ 'type': 'bf:Place'
+ },
+ {
+ 'label': [{'value': 'Desclée de Brouwer [puis]'}],
+ 'type': 'bf:Agent'
+ },
+ {
+ 'label': [{'value': 'Etudes augustiniennes'}],
+ 'type': 'bf:Agent'
+ },
+ {
+ 'label': [{'value': '1969-'}],
+ 'type': 'Date'
+ }
+ ],
+ 'startDate': 1969
+ }
+ ]
+
+
def test_marc21_to_provisionActivity_unknown_place_2_agents():
"""Test dojson publication statement.
- unknown place and 2 agents from one field 264
@@ -3047,8 +3278,8 @@ def test_marc21_to_notes_from_510():
]
-def test_marc21_to_notes_from_530_545_580():
- """Test dojson notes from field 530, 545 and 580 (L35)."""
+def test_marc21_to_notes_from_530_545_555_580():
+ """Test dojson notes from field 530, 545, 555 and 580 (L35)."""
marc21xml = """
@@ -3058,6 +3289,9 @@ def test_marc21_to_notes_from_530_545_580():
note 545
+
+ note 555
+
note 580
@@ -3071,6 +3305,9 @@ def test_marc21_to_notes_from_530_545_580():
}, {
'noteType': 'general',
'label': 'note 545'
+ }, {
+ 'noteType': 'general',
+ 'label': 'note 555'
}, {
'noteType': 'general',
'label': 'note 580'
@@ -3333,6 +3570,79 @@ def test_marc21_to_classification_from_980_2_brp_and_dr_sys():
]
+def test_marc21_to_frequency():
+ """Test dojson frequency from field 310, 321 (L32)."""
+
+ # field 310, 321 ok
+ marc21xml = """
+
+
+ Annuel
+ 1982-
+
+
+ Irrégulier
+ 1953-1981
+
+
+ """
+ marc21json = create_record(marc21xml)
+ data = marc21.do(marc21json)
+ assert data.get('frequency') == [{
+ 'label': 'Annuel',
+ 'date': '1982-'
+ }, {
+ 'label': 'Irrégulier',
+ 'date': '1953-1981'
+ }
+ ]
+
+ # field 310 $a with trailing coma and missing $b, 321 ok
+ marc21xml = """
+
+
+ Annuel,
+
+
+ Irrégulier
+ 1953-1981
+
+
+ """
+ marc21json = create_record(marc21xml)
+ data = marc21.do(marc21json)
+ assert data.get('frequency') == [{
+ 'label': 'Annuel'
+ }, {
+ 'label': 'Irrégulier',
+ 'date': '1953-1981'
+ }
+ ]
+
+ # field 310 ok, field 321 without $a
+ marc21xml = """
+
+
+ Annuel
+ 1982-
+
+
+ 1953-1981
+
+
+ """
+ marc21json = create_record(marc21xml)
+ data = marc21.do(marc21json)
+ assert data.get('frequency') == [{
+ 'label': 'Annuel',
+ 'date': '1982-'
+ }, {
+ 'label': 'missing_label',
+ 'date': '1953-1981'
+ }
+ ]
+
+
def test_marc21_to_sequence_numbering_from_one_362():
"""Test dojson sequence_numbering from 362 (L39)."""
@@ -3391,6 +3701,61 @@ def test_marc21_to_table_of_contents_from_505():
]
+def test_marc21_to_usage_and_access_policy():
+ """Test dojson usageAndAccessPolicy from field 506, 540 (L74)."""
+
+ marc21xml = """
+
+
+ Les archives de C. Roussopoulos
+
+
+ """
+ marc21json = create_record(marc21xml)
+ data = marc21.do(marc21json)
+ assert data.get('usageAndAccessPolicy') == [{
+ 'type': 'bf:UsageAndAccessPolicy',
+ 'label': 'Les archives de C. Roussopoulos'
+ }
+ ]
+
+ marc21xml = """
+
+
+ Les archives de Carole Roussopoulos
+
+
+ """
+ marc21json = create_record(marc21xml)
+ data = marc21.do(marc21json)
+ assert data.get('usageAndAccessPolicy') == [{
+ 'type': 'bf:UsageAndAccessPolicy',
+ 'label': 'Les archives de Carole Roussopoulos'
+ }
+ ]
+
+ marc21xml = """
+
+
+ Les archives de C. Roussopoulos
+
+
+ Les archives de Carole Roussopoulos
+
+
+ """
+ marc21json = create_record(marc21xml)
+ data = marc21.do(marc21json)
+ assert data.get('usageAndAccessPolicy') == [{
+ 'type': 'bf:UsageAndAccessPolicy',
+ 'label': 'Les archives de C. Roussopoulos'
+ }, {
+ 'type': 'bf:UsageAndAccessPolicy',
+ 'label': 'Les archives de Carole Roussopoulos'
+ }
+ ]
+
+
def test_marc21_to_credits_from_508():
"""Test dojson credits from 508 (L41)."""
@@ -3610,6 +3975,90 @@ def test_marc21_to_part_of():
}]
+def test_marc21_to_specific_document_relation():
+ """Test dojson for generation the specific document relations."""
+
+ # one 770 with link and one 770 without link
+ marc21xml = """
+
+
+ Télé-top-Matin
+ REROILS:2000055
+
+
+ Télé-top
+
+
+ """
+ marc21json = create_record(marc21xml)
+ data = marc21.do(marc21json)
+ assert data.get('supplement') == [{
+ '$ref': 'https://bib.rero.ch/api/documents/2000055',
+ }
+ ]
+ # two 770 with link
+ marc21xml = """
+
+
+ Télé-top-Matin
+ REROILS:2000055
+
+
+ Télé-top
+ REROILS:2000056
+
+
+ """
+ marc21json = create_record(marc21xml)
+ data = marc21.do(marc21json)
+ assert data.get('supplement') == [{
+ '$ref': 'https://bib.rero.ch/api/documents/2000055',
+ }, {
+ '$ref': 'https://bib.rero.ch/api/documents/2000056',
+ }
+ ]
+
+ marc21xml = """
+
+
+ Master microfilm.
+ Lausanne :
+ BCU
+ 1998
+ 1 bobine ; 35 mm
+
+
+ """
+ marc21json = create_record(marc21xml)
+ data = marc21.do(marc21json)
+ assert data.get('hasReproduction') == [{
+ 'label': 'Master microfilm. Lausanne : BCU 1998 1 bobine ; 35 mm',
+ }
+ ]
+
+ marc21xml = """
+
+
+ Reproduction de l'édition de:
+ Paris : H. Champion, 1931
+
+
+ Repro. sur microfilm:
+ Ed. de Minuit, 1968. -
+ 189 pages
+
+
+ """
+ marc21json = create_record(marc21xml)
+ data = marc21.do(marc21json)
+ assert data.get('reproductionOf') == [{
+ 'label': "Reproduction de l'édition de: Paris : H. Champion, 1931",
+ }, {
+ 'label': "Repro. sur microfilm: Ed. de Minuit, 1968. - 189 pages"
+ }
+ ]
+
+
def test_marc21_to_part_of_without_link():
"""Test dojson partOf when no link is specified.