diff --git a/rero_ils/dojson/utils.py b/rero_ils/dojson/utils.py index 2b314204a9..0bfff06ecd 100644 --- a/rero_ils/dojson/utils.py +++ b/rero_ils/dojson/utils.py @@ -962,8 +962,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 +998,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): @@ -1107,7 +1110,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 031e1962f8..4c03d2e079 100644 --- a/rero_ils/modules/documents/dojson/contrib/marc21tojson/model.py +++ b/rero_ils/modules/documents/dojson/contrib/marc21tojson/model.py @@ -217,6 +217,18 @@ marc21 = ReroIlsMarc21Overdo() +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' + return place + def get_contribution_link(bibid, reroid, id, key): """Get MEF contribution link. @@ -346,7 +358,14 @@ 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'}] + publication = { + 'type': 'bf:Publication' + } + place = build_place() + if place: + publication['place'] = [place] + self['provisionActivity'] = [publication] + if (marc21.date_type_from_008 == 'q' or marc21.date_type_from_008 == 'n'): self['provisionActivity'][0][ @@ -743,16 +762,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 = { @@ -870,6 +879,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 @@ -1329,7 +1379,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 ee031ec817..566e81c7dc 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' } @@ -1538,6 +1573,10 @@ 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 }] @@ -1556,6 +1595,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 @@ -1661,6 +1704,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. @@ -3081,8 +3148,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 = """ @@ -3092,6 +3159,9 @@ def test_marc21_to_notes_from_530_545_580(): note 545 + + note 555 + note 580 @@ -3105,6 +3175,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' @@ -3367,6 +3440,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).""" @@ -3425,6 +3571,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)."""