Skip to content

Commit bcd09d9

Browse files
committed
Revert "Create parent marc mapper"
This reverts commit fc98ec4.
1 parent fc98ec4 commit bcd09d9

2 files changed

Lines changed: 179 additions & 183 deletions

File tree

metadata_mapper/mappers/marc/marc_mapper.py

Lines changed: 0 additions & 180 deletions
This file was deleted.

metadata_mapper/mappers/marc/ucb_tind_mapper.py

Lines changed: 179 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
from pymarc import parse_xml_to_array
66
from sickle import models
77

8-
from ..mapper import Vernacular, Validator
9-
from .marc_mapper import MarcRecord
8+
from ..mapper import Record, Vernacular, Validator
109

11-
class UcbTindRecord(MarcRecord):
10+
11+
class UcbTindRecord(Record):
1212

1313
def UCLDC_map(self):
1414
self.marc_880_fields = self.get_880_fields()
@@ -39,6 +39,182 @@ def UCLDC_map(self):
3939
"subject": self.map_subject,
4040
"type": self.get_marc_data_fields(["336"])
4141
}
42+
43+
def get_marc_control_field(self, field_tag: str, index: int = None) -> list:
44+
"""
45+
46+
See: https://www.loc.gov/marc/bibliographic/bd00x.html
47+
48+
Get MARC control field. Returns an empty string if:
49+
* Control field isn't set
50+
* No value exists at the requested index
51+
Otherwise it returns a value
52+
53+
:param field_tag: Field tag to retrieve.
54+
:param index: A specific index to fetch
55+
:return: List of values for the control fields.
56+
"""
57+
58+
# Don't let any data tags sneak in! They have subfields.
59+
data_field_tag = field_tag if field_tag.isnumeric() and int(
60+
field_tag) < 100 else ""
61+
62+
values = [v[0].value() for (k, v)
63+
in self.marc_tags_as_dict([data_field_tag]).items()
64+
if len(v) > 0]
65+
66+
if not values:
67+
return ""
68+
69+
value = values[0]
70+
71+
if index and len(value) > index + 1:
72+
return value[index]
73+
74+
if index:
75+
return ""
76+
77+
return value
78+
79+
80+
def get_880_fields(self) -> dict:
81+
'''
82+
Returns a dict of 880 fields for the record, e.g.:
83+
84+
marc_880_fields = {
85+
'01': [
86+
Subfield(code='6', value='700-01'),
87+
Subfield(code='a', value='雪谷.')
88+
],
89+
'02': [
90+
Subfield(code='6', value='245-02'),
91+
Subfield(code='a', value='保壽軒御茶銘雙六 ')
92+
],
93+
'03': [
94+
Subfield(code='6', value='246-03'),
95+
Subfield(code='a', value='保壽軒')
96+
],
97+
'04': [
98+
Subfield(code='6', value='260-04'),
99+
Subfield(code='a', value='横濱 '),
100+
Subfield(code='a', value='東京 '),
101+
Subfield(code='b', value='桝本保五郎'),
102+
Subfield(code='c', value='[between 1868 and 1912]')
103+
]
104+
}
105+
'''
106+
marc_880_fields = {}
107+
marc_data = self.source_metadata.get("marc")
108+
109+
for field in marc_data.get_fields("880"):
110+
for subfield in field.subfields:
111+
if self.subfield_matches(subfield.code, ['6'], False):
112+
field_880_key = subfield.value.split('-')[1]
113+
114+
marc_880_fields[field_880_key] = field.subfields
115+
116+
return marc_880_fields
117+
118+
119+
def subfield_matches(self, check_code: str, subfield_codes: list,
120+
exclude_subfields: bool) -> bool:
121+
"""
122+
:param check_code: The code to check against the subfield codes.
123+
:param subfield_codes: A list of subfield codes to include / exclude
124+
:param exclude_subfields: A boolean value indicating whether to exclude the
125+
specified subfield codes.
126+
:return: A boolean value indicating whether the check_code is included or
127+
excluded based on the subfield_codes and exclude_subfields parameters.
128+
"""
129+
130+
# Always exclude subfield 6 (Linkage,
131+
# see: https://www.loc.gov/marc/bibliographic/ecbdcntf.html) unless it is
132+
# explicitly listed. Not excluding this was producing results that
133+
# were not expected.
134+
if check_code == "6" and "6" not in subfield_codes:
135+
return False
136+
if not subfield_codes:
137+
return True
138+
if exclude_subfields:
139+
return check_code not in subfield_codes
140+
else:
141+
return check_code in subfield_codes
142+
143+
144+
def marc_tags_as_dict(self, field_tags: list) -> dict:
145+
"""
146+
Get the specified MARC fields from the source_metadata, mapping by field tag
147+
148+
:param field_tags: List of MARC fields to retrieve.
149+
:return: List of MARC fields from the source_metadata.
150+
"""
151+
return {field_tag: self.source_metadata.get("marc").get_fields(field_tag) for
152+
field_tag in field_tags}
153+
154+
155+
def get_marc_data_fields(self, field_tags: list, subfield_codes=[], get_880_values=True,
156+
exclude_subfields=False) -> list:
157+
"""
158+
In most cases, this returns the Cartesian product of the provided `field_tags`
159+
and `subfield codes`. If `get_880_values` is true, it will augment to include values
160+
from field 880. Note the special handling of code `6`.
161+
162+
Set the `exclude_subfields` kwarg to exclude the specified subfield_codes.
163+
164+
:param field_tags: A list of MARC fields.
165+
:param subfield_codes: A list of subfield codes to include / exclude
166+
:param get_880_values: Indicates whether alternate graphic representations
167+
(field 880) should be sought.
168+
:param exclude_subfields: A boolean value indicating whether to exclude the
169+
specified subfield codes.
170+
:return: A list of values of the specified subfields.
171+
"""
172+
values = []
173+
for tag in field_tags:
174+
for marc_field in self.source_metadata.get("marc").get_fields(tag):
175+
field_880_key = None
176+
# get 880 field key so we can look up corresponding 880 field
177+
if get_880_values:
178+
for subfield in marc_field.subfields:
179+
if self.subfield_matches(subfield.code, ['6'], False):
180+
field_880_key = subfield.value.split('-')[1]
181+
182+
# get subfield values, plus any corresponding 880 values
183+
for index, subfield in enumerate(marc_field.subfields):
184+
if self.subfield_matches(subfield.code, subfield_codes, exclude_subfields):
185+
values.append(subfield.value)
186+
if field_880_key:
187+
values.append(
188+
self.marc_880_fields[field_880_key][index].value
189+
)
190+
191+
return values
192+
193+
194+
def get_marc_leader(self, leader_key: str):
195+
"""
196+
Note: This is a stub. Leaving here in case it is needed in other marc mappers.
197+
198+
Retrieve the value of specified leader key from the MARC metadata.
199+
See: https://www.loc.gov/marc/bibliographic/bdleader.html
200+
201+
We're not accommodating passing a slice, which pymarc can handle should it be necessary
202+
203+
:param leader_key: The key of the leader field to retrieve.
204+
:type leader_key: str
205+
:return: The value of the specified leader key.
206+
:rtype: str or None
207+
"""
208+
leader = self.source_metadata.get("marc").leader
209+
210+
if str(leader_key).isnumeric():
211+
return leader[int(leader_key)]
212+
213+
if hasattr(leader, leader_key):
214+
return leader.getattr(leader_key, "")
215+
216+
return ""
217+
42218

43219
def map_is_shown_at(self):
44220
field_001 = self.get_marc_control_field("001")

0 commit comments

Comments
 (0)