folio-migration-tools 1.2.1__py3-none-any.whl → 1.9.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- folio_migration_tools/__init__.py +11 -0
- folio_migration_tools/__main__.py +169 -85
- folio_migration_tools/circulation_helper.py +96 -59
- folio_migration_tools/config_file_load.py +66 -0
- folio_migration_tools/custom_dict.py +6 -4
- folio_migration_tools/custom_exceptions.py +21 -19
- folio_migration_tools/extradata_writer.py +46 -0
- folio_migration_tools/folder_structure.py +63 -66
- folio_migration_tools/helper.py +29 -21
- folio_migration_tools/holdings_helper.py +57 -34
- folio_migration_tools/i18n_config.py +9 -0
- folio_migration_tools/library_configuration.py +173 -13
- folio_migration_tools/mapper_base.py +317 -106
- folio_migration_tools/mapping_file_transformation/courses_mapper.py +203 -0
- folio_migration_tools/mapping_file_transformation/holdings_mapper.py +83 -69
- folio_migration_tools/mapping_file_transformation/item_mapper.py +98 -94
- folio_migration_tools/mapping_file_transformation/manual_fee_fines_mapper.py +352 -0
- folio_migration_tools/mapping_file_transformation/mapping_file_mapper_base.py +702 -223
- folio_migration_tools/mapping_file_transformation/notes_mapper.py +90 -0
- folio_migration_tools/mapping_file_transformation/order_mapper.py +492 -0
- folio_migration_tools/mapping_file_transformation/organization_mapper.py +389 -0
- folio_migration_tools/mapping_file_transformation/ref_data_mapping.py +38 -27
- folio_migration_tools/mapping_file_transformation/user_mapper.py +149 -361
- folio_migration_tools/marc_rules_transformation/conditions.py +650 -246
- folio_migration_tools/marc_rules_transformation/holdings_statementsparser.py +292 -130
- folio_migration_tools/marc_rules_transformation/hrid_handler.py +244 -0
- folio_migration_tools/marc_rules_transformation/loc_language_codes.xml +20846 -0
- folio_migration_tools/marc_rules_transformation/marc_file_processor.py +300 -0
- folio_migration_tools/marc_rules_transformation/marc_reader_wrapper.py +136 -0
- folio_migration_tools/marc_rules_transformation/rules_mapper_authorities.py +241 -0
- folio_migration_tools/marc_rules_transformation/rules_mapper_base.py +681 -201
- folio_migration_tools/marc_rules_transformation/rules_mapper_bibs.py +395 -429
- folio_migration_tools/marc_rules_transformation/rules_mapper_holdings.py +531 -100
- folio_migration_tools/migration_report.py +85 -38
- folio_migration_tools/migration_tasks/__init__.py +1 -3
- folio_migration_tools/migration_tasks/authority_transformer.py +119 -0
- folio_migration_tools/migration_tasks/batch_poster.py +911 -198
- folio_migration_tools/migration_tasks/bibs_transformer.py +121 -116
- folio_migration_tools/migration_tasks/courses_migrator.py +192 -0
- folio_migration_tools/migration_tasks/holdings_csv_transformer.py +252 -247
- folio_migration_tools/migration_tasks/holdings_marc_transformer.py +321 -115
- folio_migration_tools/migration_tasks/items_transformer.py +264 -84
- folio_migration_tools/migration_tasks/loans_migrator.py +506 -195
- folio_migration_tools/migration_tasks/manual_fee_fines_transformer.py +187 -0
- folio_migration_tools/migration_tasks/migration_task_base.py +364 -74
- folio_migration_tools/migration_tasks/orders_transformer.py +373 -0
- folio_migration_tools/migration_tasks/organization_transformer.py +451 -0
- folio_migration_tools/migration_tasks/requests_migrator.py +130 -62
- folio_migration_tools/migration_tasks/reserves_migrator.py +253 -0
- folio_migration_tools/migration_tasks/user_transformer.py +180 -139
- folio_migration_tools/task_configuration.py +46 -0
- folio_migration_tools/test_infrastructure/__init__.py +0 -0
- folio_migration_tools/test_infrastructure/mocked_classes.py +406 -0
- folio_migration_tools/transaction_migration/legacy_loan.py +148 -34
- folio_migration_tools/transaction_migration/legacy_request.py +65 -25
- folio_migration_tools/transaction_migration/legacy_reserve.py +47 -0
- folio_migration_tools/transaction_migration/transaction_result.py +12 -1
- folio_migration_tools/translations/en.json +476 -0
- folio_migration_tools-1.9.10.dist-info/METADATA +169 -0
- folio_migration_tools-1.9.10.dist-info/RECORD +67 -0
- {folio_migration_tools-1.2.1.dist-info → folio_migration_tools-1.9.10.dist-info}/WHEEL +1 -2
- folio_migration_tools-1.9.10.dist-info/entry_points.txt +3 -0
- folio_migration_tools/generate_schemas.py +0 -46
- folio_migration_tools/mapping_file_transformation/mapping_file_mapping_base_impl.py +0 -44
- folio_migration_tools/mapping_file_transformation/user_mapper_base.py +0 -212
- folio_migration_tools/marc_rules_transformation/bibs_processor.py +0 -163
- folio_migration_tools/marc_rules_transformation/holdings_processor.py +0 -284
- folio_migration_tools/report_blurbs.py +0 -219
- folio_migration_tools/transaction_migration/legacy_fee_fine.py +0 -36
- folio_migration_tools-1.2.1.dist-info/METADATA +0 -134
- folio_migration_tools-1.2.1.dist-info/RECORD +0 -50
- folio_migration_tools-1.2.1.dist-info/top_level.txt +0 -1
- {folio_migration_tools-1.2.1.dist-info → folio_migration_tools-1.9.10.dist-info/licenses}/LICENSE +0 -0
|
@@ -1,47 +1,218 @@
|
|
|
1
|
-
'''Main "script."'''
|
|
2
1
|
import csv
|
|
3
2
|
import json
|
|
4
3
|
import logging
|
|
5
|
-
import
|
|
6
|
-
from os import listdir
|
|
7
|
-
from os.path import isfile
|
|
8
|
-
from typing import List, Optional
|
|
9
|
-
from pydantic import BaseModel
|
|
4
|
+
from typing import Annotated, List
|
|
10
5
|
|
|
6
|
+
import i18n
|
|
11
7
|
from folio_uuid.folio_namespaces import FOLIONamespaces
|
|
12
|
-
from
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
from pydantic import Field
|
|
9
|
+
|
|
10
|
+
from folio_migration_tools.custom_exceptions import TransformationProcessError
|
|
11
|
+
from folio_migration_tools.helper import Helper
|
|
16
12
|
from folio_migration_tools.library_configuration import (
|
|
17
13
|
FileDefinition,
|
|
18
14
|
HridHandling,
|
|
19
15
|
LibraryConfiguration,
|
|
20
16
|
)
|
|
21
|
-
from folio_migration_tools.marc_rules_transformation.holdings_processor import (
|
|
22
|
-
HoldingsProcessor,
|
|
23
|
-
)
|
|
24
17
|
from folio_migration_tools.marc_rules_transformation.rules_mapper_holdings import (
|
|
25
18
|
RulesMapperHoldings,
|
|
26
19
|
)
|
|
27
|
-
from
|
|
28
|
-
|
|
29
|
-
|
|
20
|
+
from folio_migration_tools.migration_tasks.migration_task_base import (
|
|
21
|
+
MarcTaskConfigurationBase,
|
|
22
|
+
MigrationTaskBase
|
|
23
|
+
)
|
|
30
24
|
|
|
31
25
|
|
|
32
26
|
class HoldingsMarcTransformer(MigrationTaskBase):
|
|
33
|
-
class TaskConfiguration(
|
|
34
|
-
name:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
27
|
+
class TaskConfiguration(MarcTaskConfigurationBase):
|
|
28
|
+
name: Annotated[
|
|
29
|
+
str,
|
|
30
|
+
Field(
|
|
31
|
+
description=(
|
|
32
|
+
"Name of this migration task. The name is being used to call the specific "
|
|
33
|
+
"task, and to distinguish tasks of similar types"
|
|
34
|
+
)
|
|
35
|
+
),
|
|
36
|
+
]
|
|
37
|
+
migration_task_type: Annotated[
|
|
38
|
+
str,
|
|
39
|
+
Field(
|
|
40
|
+
title="Migration task type",
|
|
41
|
+
description=(
|
|
42
|
+
"The type of migration task you want to perform"
|
|
43
|
+
),
|
|
44
|
+
),
|
|
45
|
+
]
|
|
46
|
+
files: Annotated[
|
|
47
|
+
List[FileDefinition],
|
|
48
|
+
Field(
|
|
49
|
+
title="Source files",
|
|
50
|
+
description=(
|
|
51
|
+
"List of MARC21 files with holdings records"
|
|
52
|
+
),
|
|
53
|
+
),
|
|
54
|
+
]
|
|
55
|
+
hrid_handling: Annotated[
|
|
56
|
+
HridHandling,
|
|
57
|
+
Field(
|
|
58
|
+
title="HRID Handling",
|
|
59
|
+
description=(
|
|
60
|
+
"Setting to default will make FOLIO generate HRIDs and move the existing "
|
|
61
|
+
"001:s into a 035, concatenated with the 003. Choosing preserve001 means "
|
|
62
|
+
"the 001:s will remain in place, and that they will also become the HRIDs"
|
|
63
|
+
),
|
|
64
|
+
),
|
|
65
|
+
] = HridHandling.default
|
|
66
|
+
holdings_type_uuid_for_boundwiths: Annotated[
|
|
67
|
+
str,
|
|
68
|
+
Field(
|
|
69
|
+
title="Holdings Type for Boundwith Holdings",
|
|
70
|
+
description=(
|
|
71
|
+
"UUID for a Holdings type (set in Settings->Inventory) "
|
|
72
|
+
"for Bound-with Holdings)"
|
|
73
|
+
),
|
|
74
|
+
),
|
|
75
|
+
] = ""
|
|
76
|
+
boundwith_relationship_file_path: Annotated[
|
|
77
|
+
str,
|
|
78
|
+
Field(
|
|
79
|
+
title="Boundwith relationship file path",
|
|
80
|
+
description=(
|
|
81
|
+
"Path to a file outlining Boundwith relationships, in the style of Voyager."
|
|
82
|
+
" A TSV file with MFHD_ID and BIB_ID headers and values"
|
|
83
|
+
),
|
|
84
|
+
),
|
|
85
|
+
] = ""
|
|
86
|
+
update_hrid_settings: Annotated[
|
|
87
|
+
bool,
|
|
88
|
+
Field(
|
|
89
|
+
title="Update HRID settings",
|
|
90
|
+
description="At the end of the run, update FOLIO with the HRID settings",
|
|
91
|
+
),
|
|
92
|
+
] = True
|
|
93
|
+
reset_hrid_settings: Annotated[
|
|
94
|
+
bool,
|
|
95
|
+
Field(
|
|
96
|
+
title="Reset HRID settings",
|
|
97
|
+
description=(
|
|
98
|
+
"Setting to true means the task will "
|
|
99
|
+
"reset the HRID counters for this particular record type"
|
|
100
|
+
),
|
|
101
|
+
),
|
|
102
|
+
] = False
|
|
103
|
+
legacy_id_marc_path: Annotated[
|
|
104
|
+
str,
|
|
105
|
+
Field(
|
|
106
|
+
title="Path to legacy id in the records",
|
|
107
|
+
description=(
|
|
108
|
+
"The path to the field where the legacy id is located. "
|
|
109
|
+
"Example syntax: '001' or '951$c'"
|
|
110
|
+
),
|
|
111
|
+
),
|
|
112
|
+
]
|
|
113
|
+
deduplicate_holdings_statements: Annotated[
|
|
114
|
+
bool,
|
|
115
|
+
Field(
|
|
116
|
+
title="Deduplicate holdings statements",
|
|
117
|
+
description=(
|
|
118
|
+
"If set to False, duplicate holding statements within the same record will "
|
|
119
|
+
"remain in place"
|
|
120
|
+
),
|
|
121
|
+
),
|
|
122
|
+
] = True
|
|
123
|
+
location_map_file_name: Annotated[
|
|
124
|
+
str,
|
|
125
|
+
Field(
|
|
126
|
+
title="Path to location map file",
|
|
127
|
+
description="Must be a TSV file located in the mapping_files folder",
|
|
128
|
+
),
|
|
129
|
+
]
|
|
130
|
+
default_call_number_type_name: Annotated[
|
|
131
|
+
str,
|
|
132
|
+
Field(
|
|
133
|
+
title="Default call_number type name",
|
|
134
|
+
description="The name of the call_number type that will be used as fallback",
|
|
135
|
+
),
|
|
136
|
+
]
|
|
137
|
+
fallback_holdings_type_id: Annotated[
|
|
138
|
+
str,
|
|
139
|
+
Field(
|
|
140
|
+
title="Fallback holdings type id",
|
|
141
|
+
description="The UUID of the Holdings type that will be used for unmapped values",
|
|
142
|
+
),
|
|
143
|
+
]
|
|
144
|
+
supplemental_mfhd_mapping_rules_file: Annotated[
|
|
145
|
+
str,
|
|
146
|
+
Field(
|
|
147
|
+
title="Supplemental MFHD mapping rules file",
|
|
148
|
+
description=(
|
|
149
|
+
"The name of the file in the mapping_files directory "
|
|
150
|
+
"containing supplemental MFHD mapping rules"
|
|
151
|
+
),
|
|
152
|
+
),
|
|
153
|
+
] = ""
|
|
154
|
+
include_mrk_statements: Annotated[
|
|
155
|
+
bool,
|
|
156
|
+
Field(
|
|
157
|
+
title="Include MARC statements (MRK-format) as staff-only Holdings notes",
|
|
158
|
+
description=(
|
|
159
|
+
"If set to true, the MARC statements "
|
|
160
|
+
"will be included in the output as MARC Maker format fields. "
|
|
161
|
+
"If set to false (default), the MARC statements "
|
|
162
|
+
"will not be included in the output."
|
|
163
|
+
),
|
|
164
|
+
),
|
|
165
|
+
] = False
|
|
166
|
+
mrk_holdings_note_type: Annotated[
|
|
167
|
+
str,
|
|
168
|
+
Field(
|
|
169
|
+
title="MARC Holdings Note type",
|
|
170
|
+
description=(
|
|
171
|
+
"The name of the note type to use for MARC (MRK) statements. "
|
|
172
|
+
),
|
|
173
|
+
),
|
|
174
|
+
] = "Original MARC holdings statements"
|
|
175
|
+
include_mfhd_mrk_as_note: Annotated[
|
|
176
|
+
bool,
|
|
177
|
+
Field(
|
|
178
|
+
title="Include MARC Record (as MARC Maker Representation) as note",
|
|
179
|
+
description=(
|
|
180
|
+
"If set to true, the MARC statements will be included in the output as a "
|
|
181
|
+
"(MRK) note. If set to false (default), the MARC statements will not be "
|
|
182
|
+
"included in the output."
|
|
183
|
+
),
|
|
184
|
+
),
|
|
185
|
+
] = False
|
|
186
|
+
mfhd_mrk_note_type: Annotated[
|
|
187
|
+
str,
|
|
188
|
+
Field(
|
|
189
|
+
title="MARC Record (as MARC Maker Representation) note type",
|
|
190
|
+
description=(
|
|
191
|
+
"The name of the note type to use for MFHD (MRK) note. "
|
|
192
|
+
),
|
|
193
|
+
),
|
|
194
|
+
] = "Original MFHD Record"
|
|
195
|
+
include_mfhd_mrc_as_note: Annotated[
|
|
196
|
+
bool,
|
|
197
|
+
Field(
|
|
198
|
+
title="Include MARC Record (as MARC21 decoded string) as note",
|
|
199
|
+
description=(
|
|
200
|
+
"If set to true, the MARC record will be included in the output as a "
|
|
201
|
+
"decoded binary MARC21 record. If set to false (default), "
|
|
202
|
+
"the MARC record will not be "
|
|
203
|
+
"included in the output."
|
|
204
|
+
),
|
|
205
|
+
),
|
|
206
|
+
] = False
|
|
207
|
+
mfhd_mrc_note_type: Annotated[
|
|
208
|
+
str,
|
|
209
|
+
Field(
|
|
210
|
+
title="MARC Record (as MARC21 decoded string) note type",
|
|
211
|
+
description=(
|
|
212
|
+
"The name of the note type to use for MFHD (MRC) note. "
|
|
213
|
+
),
|
|
214
|
+
),
|
|
215
|
+
] = "Original MFHD (MARC21)"
|
|
45
216
|
|
|
46
217
|
@staticmethod
|
|
47
218
|
def get_object_type() -> FOLIONamespaces:
|
|
@@ -51,11 +222,21 @@ class HoldingsMarcTransformer(MigrationTaskBase):
|
|
|
51
222
|
self,
|
|
52
223
|
task_config: TaskConfiguration,
|
|
53
224
|
library_config: LibraryConfiguration,
|
|
225
|
+
folio_client,
|
|
54
226
|
use_logging: bool = True,
|
|
55
227
|
):
|
|
56
228
|
csv.register_dialect("tsv", delimiter="\t")
|
|
57
|
-
super().__init__(library_config, task_config, use_logging)
|
|
58
|
-
self.
|
|
229
|
+
super().__init__(library_config, task_config, folio_client, use_logging)
|
|
230
|
+
if self.task_configuration.statistical_codes_map_file_name:
|
|
231
|
+
statcode_mapping = self.load_ref_data_mapping_file(
|
|
232
|
+
"statisticalCodeIds",
|
|
233
|
+
self.folder_structure.mapping_files_folder
|
|
234
|
+
/ self.task_configuration.statistical_codes_map_file_name,
|
|
235
|
+
[],
|
|
236
|
+
False,
|
|
237
|
+
)
|
|
238
|
+
else:
|
|
239
|
+
statcode_mapping = None
|
|
59
240
|
self.holdings_types = list(
|
|
60
241
|
self.folio_client.folio_get_all("/holdings-types", "holdingsTypes")
|
|
61
242
|
)
|
|
@@ -63,111 +244,136 @@ class HoldingsMarcTransformer(MigrationTaskBase):
|
|
|
63
244
|
(
|
|
64
245
|
h
|
|
65
246
|
for h in self.holdings_types
|
|
66
|
-
if h["id"] == self.
|
|
247
|
+
if h["id"] == self.task_configuration.fallback_holdings_type_id
|
|
67
248
|
),
|
|
68
|
-
"",
|
|
249
|
+
{"name": ""},
|
|
69
250
|
)
|
|
70
251
|
if not self.default_holdings_type:
|
|
71
252
|
raise TransformationProcessError(
|
|
72
253
|
"",
|
|
73
254
|
(
|
|
74
|
-
f"Holdings type with ID {self.
|
|
255
|
+
f"Holdings type with ID {self.task_configuration.fallback_holdings_type_id}"
|
|
75
256
|
" not found in FOLIO."
|
|
76
257
|
),
|
|
77
258
|
)
|
|
78
259
|
logging.info(
|
|
79
260
|
"%s will be used as default holdings type",
|
|
80
|
-
self.default_holdings_type
|
|
81
|
-
)
|
|
82
|
-
self.instance_id_map = self.load_id_map(
|
|
83
|
-
self.folder_structure.instance_id_map_path, True
|
|
261
|
+
self.default_holdings_type.get("name", ""),
|
|
84
262
|
)
|
|
85
|
-
logging.info("%s Instance ids in map", len(self.instance_id_map))
|
|
86
|
-
logging.info("Init done")
|
|
87
263
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
264
|
+
# Load Boundwith relationship map
|
|
265
|
+
self.boundwith_relationship_map_rows = []
|
|
266
|
+
if self.task_configuration.boundwith_relationship_file_path:
|
|
267
|
+
try:
|
|
268
|
+
with open(
|
|
269
|
+
self.folder_structure.legacy_records_folder
|
|
270
|
+
/ self.task_configuration.boundwith_relationship_file_path
|
|
271
|
+
) as boundwith_relationship_file:
|
|
272
|
+
self.boundwith_relationship_map_rows = list(
|
|
273
|
+
csv.DictReader(boundwith_relationship_file, dialect="tsv")
|
|
274
|
+
)
|
|
275
|
+
logging.info(
|
|
276
|
+
"Rows in Bound with relationship map: %s",
|
|
277
|
+
len(self.boundwith_relationship_map_rows),
|
|
278
|
+
)
|
|
279
|
+
except FileNotFoundError:
|
|
280
|
+
raise TransformationProcessError(
|
|
281
|
+
"",
|
|
282
|
+
i18n.t("Provided boundwith relationship file not found"),
|
|
283
|
+
self.task_configuration.boundwith_relationship_file_path,
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
location_map_path = (
|
|
91
287
|
self.folder_structure.mapping_files_folder
|
|
92
|
-
/ self.
|
|
288
|
+
/ self.task_configuration.location_map_file_name
|
|
93
289
|
)
|
|
94
|
-
|
|
95
|
-
self.
|
|
96
|
-
|
|
290
|
+
with open(location_map_path) as location_map_file:
|
|
291
|
+
self.location_map = list(csv.DictReader(location_map_file, dialect="tsv"))
|
|
292
|
+
logging.info("Locations in map: %s", len(self.location_map))
|
|
293
|
+
|
|
294
|
+
self.check_source_files(
|
|
295
|
+
self.folder_structure.legacy_records_folder, self.task_configuration.files
|
|
97
296
|
)
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
297
|
+
self.instance_id_map = self.load_instance_id_map(True)
|
|
298
|
+
self.mapper = RulesMapperHoldings(
|
|
299
|
+
self.folio_client,
|
|
300
|
+
self.location_map,
|
|
301
|
+
self.task_configuration,
|
|
302
|
+
self.library_configuration,
|
|
303
|
+
self.instance_id_map,
|
|
304
|
+
self.boundwith_relationship_map_rows,
|
|
305
|
+
statcode_mapping
|
|
306
|
+
)
|
|
307
|
+
self.add_supplemental_mfhd_mappings()
|
|
308
|
+
if (
|
|
309
|
+
self.task_configuration.reset_hrid_settings
|
|
310
|
+
and self.task_configuration.update_hrid_settings
|
|
311
|
+
):
|
|
312
|
+
self.mapper.hrid_handler.reset_holdings_hrid_counter()
|
|
313
|
+
logging.info("%s Instance ids in map", len(self.instance_id_map))
|
|
314
|
+
logging.info("Init done")
|
|
115
315
|
|
|
116
|
-
def
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
316
|
+
def add_supplemental_mfhd_mappings(self):
|
|
317
|
+
if self.task_configuration.supplemental_mfhd_mapping_rules_file:
|
|
318
|
+
try:
|
|
319
|
+
with open(
|
|
320
|
+
(
|
|
321
|
+
self.folder_structure.mapping_files_folder
|
|
322
|
+
/ self.task_configuration.supplemental_mfhd_mapping_rules_file
|
|
323
|
+
),
|
|
324
|
+
"r",
|
|
325
|
+
) as new_rules_file:
|
|
326
|
+
new_rules = json.load(new_rules_file)
|
|
327
|
+
if not isinstance(new_rules, dict):
|
|
328
|
+
raise TransformationProcessError(
|
|
329
|
+
"",
|
|
330
|
+
"Supplemental MFHD mapping rules file must contain a dictionary",
|
|
331
|
+
json.dumps(new_rules),
|
|
332
|
+
)
|
|
333
|
+
except FileNotFoundError:
|
|
334
|
+
raise TransformationProcessError(
|
|
335
|
+
"",
|
|
336
|
+
"Provided supplemental MFHD mapping rules file not found",
|
|
337
|
+
self.task_configuration.supplemental_mfhd_mapping_rules_file,
|
|
338
|
+
)
|
|
339
|
+
else:
|
|
340
|
+
new_rules = {}
|
|
341
|
+
self.mapper.integrate_supplemental_mfhd_mappings(new_rules)
|
|
128
342
|
|
|
129
|
-
|
|
343
|
+
def do_work(self):
|
|
344
|
+
self.do_work_marc_transformer()
|
|
130
345
|
|
|
131
|
-
def
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
346
|
+
def wrap_up(self):
|
|
347
|
+
logging.info("Done. Transformer Wrapping up...")
|
|
348
|
+
self.extradata_writer.flush()
|
|
349
|
+
self.processor.wrap_up()
|
|
350
|
+
if self.mapper.boundwith_relationship_map:
|
|
135
351
|
with open(
|
|
136
|
-
self.folder_structure.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
except TransformationProcessError as tpe:
|
|
145
|
-
logging.critical(tpe)
|
|
146
|
-
sys.exit(1)
|
|
147
|
-
except Exception:
|
|
148
|
-
logging.exception(
|
|
149
|
-
"Failure in Main: %s", file_def.file_name, stack_info=True
|
|
150
|
-
)
|
|
352
|
+
self.folder_structure.boundwith_relationships_map_path, "w+"
|
|
353
|
+
) as boundwith_relationship_file:
|
|
354
|
+
logging.info(
|
|
355
|
+
"Writing boundwiths relationship map to %s",
|
|
356
|
+
boundwith_relationship_file.name,
|
|
357
|
+
)
|
|
358
|
+
for key, val in self.mapper.boundwith_relationship_map.items():
|
|
359
|
+
boundwith_relationship_file.write(json.dumps((key, val)) + "\n")
|
|
151
360
|
|
|
152
|
-
|
|
153
|
-
|
|
361
|
+
with open(self.folder_structure.migration_reports_file, "w+") as report_file:
|
|
362
|
+
self.mapper.migration_report.write_migration_report(
|
|
363
|
+
i18n.t("Bibliographic records transformation report"),
|
|
364
|
+
report_file,
|
|
365
|
+
self.start_datetime,
|
|
366
|
+
)
|
|
367
|
+
Helper.print_mapping_report(
|
|
368
|
+
report_file,
|
|
369
|
+
self.mapper.parsed_records,
|
|
370
|
+
self.mapper.mapped_folio_fields,
|
|
371
|
+
self.mapper.mapped_legacy_fields,
|
|
372
|
+
)
|
|
154
373
|
|
|
374
|
+
logging.info(
|
|
375
|
+
"Done. Transformation report written to %s",
|
|
376
|
+
self.folder_structure.migration_reports_file.name,
|
|
377
|
+
)
|
|
155
378
|
|
|
156
|
-
|
|
157
|
-
for idx, record in enumerate(reader):
|
|
158
|
-
try:
|
|
159
|
-
if record is None:
|
|
160
|
-
processor.mapper.migration_report.add_general_statistics(
|
|
161
|
-
"Records with encoding errors. See data issues log for details"
|
|
162
|
-
)
|
|
163
|
-
raise TransformationRecordFailedError(
|
|
164
|
-
f"Index in file:{idx}",
|
|
165
|
-
f"MARC parsing error: {reader.current_exception}",
|
|
166
|
-
f"{reader.current_chunk}",
|
|
167
|
-
)
|
|
168
|
-
else:
|
|
169
|
-
processor.process_record(record, file_def)
|
|
170
|
-
except TransformationRecordFailedError as error:
|
|
171
|
-
error.log_it()
|
|
172
|
-
except ValueError as error:
|
|
173
|
-
logging.error(error)
|
|
379
|
+
self.clean_out_empty_logs()
|