folio-migration-tools 1.10.0b3__py3-none-any.whl → 1.10.0b6__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.
@@ -99,6 +99,7 @@ class MigrationTaskBase:
99
99
  raise NotImplementedError()
100
100
 
101
101
  def clean_out_empty_logs(self):
102
+ _close_handler(self.data_issue_file_handler)
102
103
  if (
103
104
  self.folder_structure.data_issue_file_path.is_file()
104
105
  and os.stat(self.folder_structure.data_issue_file_path).st_size == 0
@@ -260,13 +261,13 @@ class MigrationTaskBase:
260
261
 
261
262
  # Data issue file formatter
262
263
  data_issue_file_formatter = logging.Formatter("%(message)s")
263
- data_issue_file_handler = logging.FileHandler(
264
+ self.data_issue_file_handler = logging.FileHandler(
264
265
  filename=str(self.folder_structure.data_issue_file_path), mode="w"
265
266
  )
266
- data_issue_file_handler.addFilter(LevelFilter(26))
267
- data_issue_file_handler.setFormatter(data_issue_file_formatter)
268
- data_issue_file_handler.setLevel(26)
269
- logging.getLogger().addHandler(data_issue_file_handler)
267
+ self.data_issue_file_handler.addFilter(LevelFilter(26))
268
+ self.data_issue_file_handler.setFormatter(data_issue_file_formatter)
269
+ self.data_issue_file_handler.setLevel(26)
270
+ logging.getLogger().addHandler(self.data_issue_file_handler)
270
271
  logger.info("Logging set up")
271
272
 
272
273
  def setup_records_map(self, mapping_file_path):
@@ -553,3 +554,10 @@ class LevelFilter(logging.Filter):
553
554
 
554
555
  def filter(self, record):
555
556
  return record.levelno == self.level
557
+
558
+
559
+ def _close_handler(handler: logging.Handler | None):
560
+ if handler is None:
561
+ return
562
+ handler.flush()
563
+ handler.close()
@@ -101,6 +101,16 @@ class UserTransformer(MigrationTaskBase):
101
101
  ),
102
102
  ),
103
103
  ] = False
104
+ remove_username: Annotated[
105
+ Optional[bool],
106
+ Field(
107
+ title="Remove username",
108
+ description=(
109
+ "Specify whether to remove username. Resulting objects are not compatible with"
110
+ " the mod-user-import. Optional, by default is False"
111
+ ),
112
+ ),
113
+ ] = False
104
114
 
105
115
  @staticmethod
106
116
  def get_object_type() -> FOLIONamespaces:
@@ -24,7 +24,6 @@
24
24
  "Aged to lost and checked out": "Aged to lost and checked out",
25
25
  "Already set to %{value}. %{leader_key} was %{leader}": "Already set to %{value}. %{leader_key} was %{leader}",
26
26
  "An Unmapped": "An Unmapped",
27
- "Authority records transformation report": "Authority records transformation report",
28
27
  "BW Items found tied to previously created BW Holdings": "BW Items found tied to previously created BW Holdings",
29
28
  "Bib identifier not in instances_id_map, no instance linked": "Bib identifier not in instances_id_map, no instance linked",
30
29
  "Bib ids referenced in bound-with items": "Bib ids referenced in bound-with items",
@@ -264,12 +263,6 @@
264
263
  "blurbs.AcquisitionMethodMapping.title": "POL Acquisition Method Mapping",
265
264
  "blurbs.AddedValueFromParameter.description": "",
266
265
  "blurbs.AddedValueFromParameter.title": "Added value from parameter since value is empty",
267
- "blurbs.AuthorityEncodingLevel.description": "Library action: **All values that are not n or o will be set to n. If this is not what you want, you need to correct these values in your system. **<br/>An overview of the Encoding levels (Leader position 17) present in your source data. Allowed values according to the MARC standard are n or o",
268
- "blurbs.AuthorityEncodingLevel.title": "Encoding level (leader pos 17)",
269
- "blurbs.AuthoritySourceFileMapping.description": "Mappings based on FOLIO authority `naturalId` alpha prefix",
270
- "blurbs.AuthoritySourceFileMapping.title": "Authority Source File Mapping Results",
271
- "blurbs.AuthoritySources.description": "",
272
- "blurbs.AuthoritySources.title": "Authorization sources and related information",
273
266
  "blurbs.BoundWithMappings.description": "",
274
267
  "blurbs.BoundWithMappings.title": "Bound-with mapping",
275
268
  "blurbs.CallNumberTypeMapping.description": "Call number types in MFHDs are mapped from 852, Indicator 1 according to a certain scheme. (LOC documentation)[https://www.loc.gov/marc/holdings/hd852.html]",
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: folio-migration-tools
3
- Version: 1.10.0b3
3
+ Version: 1.10.0b6
4
4
  Summary: A tool allowing you to migrate data from legacy ILS:s (Library systems) into FOLIO LSP
5
5
  Keywords: FOLIO,ILS,LSP,Library Systems,MARC21,Library data
6
6
  Author: Theodor Tolstoy, Lisa Sjögren, Brooks Travis, Jeremy Nelson, Clinton Bradford
7
7
  Author-email: Theodor Tolstoy <github.teddes@tolstoy.se>, Brooks Travis <brooks.travis@gmail.com>
8
8
  License-Expression: MIT
9
- Requires-Dist: folioclient>=1.0.1
9
+ Requires-Dist: folioclient>=1.0.4
10
10
  Requires-Dist: pyhumps>=3.7.3,<4.0.0
11
11
  Requires-Dist: defusedxml>=0.7.1,<1.0.0
12
12
  Requires-Dist: python-dateutil>=2.8.2,<3.0.0
@@ -1,12 +1,12 @@
1
1
  folio_migration_tools/__init__.py,sha256=lnYgqA47l0iA-iORkVH3dgevk7gyGxVwg3MnLltA-U8,223
2
- folio_migration_tools/__main__.py,sha256=MlF8Fj_E4EcW6rU0posfj3ZyPzSWzSm6zXz2jlN7OGw,8835
2
+ folio_migration_tools/__main__.py,sha256=KJdmLkKwAygTKuIKfvDL3M0JdVgsCbf2_LTL1FP6GxU,9233
3
3
  folio_migration_tools/circulation_helper.py,sha256=r1zpOKy47VFRHyXHvwUEjPfQ4jyJpjMAYc1IktJ94WU,14661
4
4
  folio_migration_tools/colors.py,sha256=GP0wdI_GZ2WD5SjrbPN-S3u8vvN_u6rGQIBBcWv_0ZM,227
5
5
  folio_migration_tools/config_file_load.py,sha256=zHHa6NDkN6EJiQE4DgjrFQPVKsd70POsfbGkB8308jg,2822
6
6
  folio_migration_tools/custom_dict.py,sha256=rRd9_RQqI85171p7wTfpMM0Mladh-LChbgMSmLvN7N0,680
7
7
  folio_migration_tools/custom_exceptions.py,sha256=BLP1gMPbTHSN-rqxzTawT4sRLiyAU3blBdkUBwiiPRk,2642
8
8
  folio_migration_tools/extradata_writer.py,sha256=fuchNcMc6BYb9IyfAcvXg7X4J2TfX6YiROfT2hr0JMw,1678
9
- folio_migration_tools/folder_structure.py,sha256=yqeeB1uADw9J6TCHUxKOv7wrTglfAeX9KpwNgOHjTg0,6917
9
+ folio_migration_tools/folder_structure.py,sha256=ExrXNEWvCB5QMH17kQSyTDQ04thq--t8_p3F_iuyf0k,6776
10
10
  folio_migration_tools/helper.py,sha256=Jb-9PrMkgOUGYScRf8jMmGGTcPIohm3eFHenGSi3cUA,2979
11
11
  folio_migration_tools/holdings_helper.py,sha256=yJpz6aJrKRBiJ1MtT5bs2vXAc88uJuGh2_KDuCySOKc,7559
12
12
  folio_migration_tools/i18n_config.py,sha256=3AH_2b9zTsxE4XTe4isM_zYtPJSlK0ix6eBmV7kAYUM,228
@@ -22,22 +22,20 @@ folio_migration_tools/mapping_file_transformation/notes_mapper.py,sha256=vCmZmjr
22
22
  folio_migration_tools/mapping_file_transformation/order_mapper.py,sha256=VUcbeBGlQ7KsDPgJlaOOe8bO0y5IRLTCBH_IQKcaqiA,18267
23
23
  folio_migration_tools/mapping_file_transformation/organization_mapper.py,sha256=MKlN3doQ_R-Y3klkbCFL4qHUfhMATBsIhvq1jpmajqQ,14641
24
24
  folio_migration_tools/mapping_file_transformation/ref_data_mapping.py,sha256=rROcBiL5TE7bWsJ95A6shurPZ1e4In6PTwR5BN9amzU,8991
25
- folio_migration_tools/mapping_file_transformation/user_mapper.py,sha256=13cvFr7Vp6uxZNpAmLxGvPVLC1_En2NVvLtuP75HAzU,8846
25
+ folio_migration_tools/mapping_file_transformation/user_mapper.py,sha256=nqyoSQAo3IGAAzXVRM-R0M5Q83zS3uU6jvKx4_c1mt8,8940
26
26
  folio_migration_tools/marc_rules_transformation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
- folio_migration_tools/marc_rules_transformation/conditions.py,sha256=zzl18PsqUaXsT5mcolPC89ar4RpQTs_beKAgVg4bttI,48190
27
+ folio_migration_tools/marc_rules_transformation/conditions.py,sha256=-5U6nBGcBO49C9MMyxOL2wMhHGxUawkIM9e-MwNaM_4,46938
28
28
  folio_migration_tools/marc_rules_transformation/holdings_statementsparser.py,sha256=-mOGtoPa3qmEqGWtyBTN-fQ743ZmT8caDLc9ES9J74Y,13667
29
29
  folio_migration_tools/marc_rules_transformation/hrid_handler.py,sha256=WudBOzCwcJAuhEm4urLhAk5OQWGfbKz9_4Ou8fmjm1E,10022
30
30
  folio_migration_tools/marc_rules_transformation/loc_language_codes.xml,sha256=ztn2_yKws6qySL4oSsZh7sOjxq5bCC1PhAnXJdtgmJ0,382912
31
31
  folio_migration_tools/marc_rules_transformation/marc_file_processor.py,sha256=o03d_G-4MR4e5VPfu7ljxAVDl79o2ONpQIqQ-V2RCdA,12523
32
32
  folio_migration_tools/marc_rules_transformation/marc_reader_wrapper.py,sha256=9ATjYMRAjy0QcXtmNZaHVhHLJ5hE1WUgOcF6KMJjbgo,5309
33
- folio_migration_tools/marc_rules_transformation/rules_mapper_authorities.py,sha256=fhe1vTt9F5u5PJliklSGP3TPZHRO3KV8GHeb-pdLdnA,9622
34
- folio_migration_tools/marc_rules_transformation/rules_mapper_base.py,sha256=ijOs9r0Mcx0XyNhDAq7fw1aFJ-JnAEhHx98-t262uRo,46158
33
+ folio_migration_tools/marc_rules_transformation/rules_mapper_base.py,sha256=KxyZjizbLwwAY2PfMSyh6u_mVTpfhyvdaii_PlpLscw,45857
35
34
  folio_migration_tools/marc_rules_transformation/rules_mapper_bibs.py,sha256=F8tKn59zHUV3Gqa9NY-JvTbWgfDjNTcPvQONk8gzwGs,30428
36
35
  folio_migration_tools/marc_rules_transformation/rules_mapper_holdings.py,sha256=YILyEfO-LkQPk-4OjiuY68X5xDA0LlI7UUp7_mvzLUE,29184
37
36
  folio_migration_tools/migration_report.py,sha256=B8e4tMfT0xCJ3BxkSg7ZZJYmg0VLQVXmmVnWwmojZD4,4260
38
37
  folio_migration_tools/migration_tasks/__init__.py,sha256=ZkbY_yGyB84Ke8OMlYUzyyBj4cxxNrhMTwQlu_GbdDs,211
39
- folio_migration_tools/migration_tasks/authority_transformer.py,sha256=tB9XBJn5BPJ1Xa79R9blDz31jN4UvLB1VFbyFjFjfM4,4228
40
- folio_migration_tools/migration_tasks/batch_poster.py,sha256=x3DQPrI1QnRtg9Bdf-e3ztv4llWPt5JpeCIyE7mMNWU,50634
38
+ folio_migration_tools/migration_tasks/batch_poster.py,sha256=rbSx3dyF4UbNdFiAhBRDpBTvAwQI3BR4s4_sIBsM-70,46214
41
39
  folio_migration_tools/migration_tasks/bibs_transformer.py,sha256=zPxh2tjyqx88fuH1FuKLwhT6lhZ5fVTQAqE08IggYgM,6351
42
40
  folio_migration_tools/migration_tasks/courses_migrator.py,sha256=sKIeyUlc7o189lw88XbGILVkwnR9krqO0PgS-vLCCm8,7039
43
41
  folio_migration_tools/migration_tasks/holdings_csv_transformer.py,sha256=JzOufqjSR2V-gUvOq0pdQFsXjpxk1ldGJBQWIWGfCps,21915
@@ -45,20 +43,20 @@ folio_migration_tools/migration_tasks/holdings_marc_transformer.py,sha256=b1lWbY
45
43
  folio_migration_tools/migration_tasks/items_transformer.py,sha256=gIJ9SKUENE3OaEouGAFTsGjciN_YxwRoUAAEKJlfG-E,19498
46
44
  folio_migration_tools/migration_tasks/loans_migrator.py,sha256=6mwtA9-6B_pU1GKS9VD7Wu5stZ8YLlyeliFJhyPuho0,38785
47
45
  folio_migration_tools/migration_tasks/manual_fee_fines_transformer.py,sha256=CnmlTge7nChUJ10EiUkriQtJlVxWqglgfhjgneh2_yM,7247
48
- folio_migration_tools/migration_tasks/migration_task_base.py,sha256=yg96RuRHgapDHNjLE-1Fg_gpRmaRmVx7GUm45lHTIBY,22339
46
+ folio_migration_tools/migration_tasks/migration_task_base.py,sha256=rhIYFZ_dYWEyopkR2shht5ybKk4JQzxctSlBizml50g,22551
49
47
  folio_migration_tools/migration_tasks/orders_transformer.py,sha256=h8EyRbvbtwDZJq1y73J7oZFRdI1U4vq1Vrlay4GLf4M,13885
50
48
  folio_migration_tools/migration_tasks/organization_transformer.py,sha256=5s-ACb9-R8JLlPnROOq1ZnDIRCLQeWaxORDn0SrhQqs,16747
51
49
  folio_migration_tools/migration_tasks/requests_migrator.py,sha256=Q7sWOxqq73Fdg3Q1tmpvRxU9qhhG1BV3AGMoCMwh2cE,14768
52
50
  folio_migration_tools/migration_tasks/reserves_migrator.py,sha256=jdiwWAlMydXE2vlv0lgHRUljarslveyVOu-TCnymAEs,9953
53
- folio_migration_tools/migration_tasks/user_transformer.py,sha256=fWfcO9Njwpyt0-De3nhC_gMu_lHOEkhMdCRryXz3xcc,12241
51
+ folio_migration_tools/migration_tasks/user_transformer.py,sha256=apgVCoJQ4sB5aFp7p8FdSQrDfXSIzgEbEQ3C-6dG568,12621
54
52
  folio_migration_tools/task_configuration.py,sha256=6eqbjjSWfi-qgp0bhCsuBVE3gTK4HaXzXsAo68JPGc0,1146
55
53
  folio_migration_tools/transaction_migration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
54
  folio_migration_tools/transaction_migration/legacy_loan.py,sha256=A5qvThfP3g62YnykLyti_tqTY7dq1SbLi3WZz7QXk6s,7399
57
55
  folio_migration_tools/transaction_migration/legacy_request.py,sha256=Kv7jpBIuZ_qyay8BdaeCPJID67l43Cl6x-ws9Lt49NI,6121
58
56
  folio_migration_tools/transaction_migration/legacy_reserve.py,sha256=qzw0okg4axAE_ezXopP9gFsQ_e60o0zh7zqRzFBSWHY,1806
59
57
  folio_migration_tools/transaction_migration/transaction_result.py,sha256=cTdCN0BnlI9_ZJB2Z3Fdkl9gpymIi-9mGZsRFlQcmDk,656
60
- folio_migration_tools/translations/en.json,sha256=4Ac66PR5Y78ll4_grhBm2IdTMsoZUv0q3IJvX8SQiJI,41778
61
- folio_migration_tools-1.10.0b3.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
62
- folio_migration_tools-1.10.0b3.dist-info/entry_points.txt,sha256=mJRRiCNP9j7_NpVXamHEiW8pDEjWQs1vEqD89G354cM,79
63
- folio_migration_tools-1.10.0b3.dist-info/METADATA,sha256=SgteVRYKSUGrgKVAHV8y4706ylBe7LiFsp4tXtyBxOg,7162
64
- folio_migration_tools-1.10.0b3.dist-info/RECORD,,
58
+ folio_migration_tools/translations/en.json,sha256=pS7dhHmj4XBqTcFNIcqFgRMY557fQan1RomdNg6PtdA,40941
59
+ folio_migration_tools-1.10.0b6.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
60
+ folio_migration_tools-1.10.0b6.dist-info/entry_points.txt,sha256=mJRRiCNP9j7_NpVXamHEiW8pDEjWQs1vEqD89G354cM,79
61
+ folio_migration_tools-1.10.0b6.dist-info/METADATA,sha256=EcDMNh4diSH6vDbrIQWdk-kcTdM2W2Agw3X4lo22h2Y,7162
62
+ folio_migration_tools-1.10.0b6.dist-info/RECORD,,
@@ -1,242 +0,0 @@
1
- """The default mapper, responsible for parsing MARC21 records acording to the
2
- FOLIO community specifications"""
3
-
4
- import logging
5
- import re
6
- import time
7
- import uuid
8
- from typing import List
9
-
10
- import i18n
11
- import pymarc
12
- from folio_uuid.folio_namespaces import FOLIONamespaces
13
- from folio_uuid.folio_uuid import FolioUUID
14
- from folioclient import FolioClient
15
- from pymarc import Leader, Record
16
-
17
- from folio_migration_tools.custom_exceptions import TransformationProcessError
18
- from folio_migration_tools.helper import Helper
19
- from folio_migration_tools.library_configuration import (
20
- FileDefinition,
21
- IlsFlavour,
22
- LibraryConfiguration,
23
- )
24
- from folio_migration_tools.marc_rules_transformation.conditions import Conditions
25
- from folio_migration_tools.marc_rules_transformation.hrid_handler import HRIDHandler
26
- from folio_migration_tools.marc_rules_transformation.rules_mapper_base import (
27
- RulesMapperBase,
28
- )
29
-
30
-
31
- class AuthorityMapper(RulesMapperBase):
32
- non_repatable_fields = [
33
- "100",
34
- "110",
35
- "111",
36
- "130",
37
- "147",
38
- "148",
39
- "150",
40
- "151",
41
- "155",
42
- "162",
43
- "180",
44
- "181",
45
- "182",
46
- "185",
47
- "378",
48
- "384",
49
- ]
50
- """_summary_
51
-
52
- Args:
53
- RulesMapperBase (_type_): _description_
54
- """
55
-
56
- def __init__(
57
- self,
58
- folio_client,
59
- library_configuration: LibraryConfiguration,
60
- task_configuration,
61
- ):
62
- super().__init__(
63
- folio_client,
64
- library_configuration,
65
- task_configuration,
66
- None,
67
- self.get_authority_json_schema(folio_client, library_configuration),
68
- Conditions(folio_client, self, "auth", library_configuration.folio_release),
69
- )
70
- self.srs_recs: list = []
71
- logging.info("Fetching mapping rules from the tenant")
72
- rules_endpoint = "/mapping-rules/marc-authority"
73
- self.mappings = self.folio_client.folio_get_single_object(rules_endpoint)
74
- self.source_file_mapping: dict = {}
75
- self.setup_source_file_mapping()
76
- self.start = time.time()
77
-
78
- def get_legacy_ids(self, marc_record: Record, idx: int) -> List[str]:
79
- ils_flavour: IlsFlavour = self.task_configuration.ils_flavour
80
- if ils_flavour in {IlsFlavour.sierra, IlsFlavour.millennium}:
81
- raise TransformationProcessError("", f"ILS {ils_flavour} not configured")
82
- elif ils_flavour == IlsFlavour.tag907y:
83
- return RulesMapperBase.get_bib_id_from_907y(marc_record, idx)
84
- elif ils_flavour == IlsFlavour.tagf990a:
85
- return RulesMapperBase.get_bib_id_from_990a(marc_record, idx)
86
- elif ils_flavour == IlsFlavour.aleph:
87
- raise TransformationProcessError("", f"ILS {ils_flavour} not configured")
88
- elif ils_flavour in {IlsFlavour.voyager, "voyager", IlsFlavour.tag001}:
89
- return RulesMapperBase.get_bib_id_from_001(marc_record, idx)
90
- elif ils_flavour == IlsFlavour.koha:
91
- raise TransformationProcessError("", f"ILS {ils_flavour} not configured")
92
- elif ils_flavour == IlsFlavour.none:
93
- return [str(uuid.uuid4())]
94
- else:
95
- raise TransformationProcessError("", f"ILS {ils_flavour} not configured")
96
-
97
- def parse_record(
98
- self, marc_record: pymarc.Record, file_def: FileDefinition, legacy_ids: List[str]
99
- ) -> list[dict]:
100
- """Parses an auth recod into a FOLIO Authority object
101
- This is the main function
102
-
103
- Args:
104
- legacy_ids (_type_): _description_
105
- marc_record (Record): _description_
106
- file_def (FileDefinition): _description_
107
-
108
- Returns:
109
- dict: _description_
110
- """
111
- self.print_progress()
112
- ignored_subsequent_fields: set = set()
113
- bad_tags = set(self.task_configuration.tags_to_delete) # "907"
114
- folio_authority = self.perform_initial_preparation(marc_record, legacy_ids)
115
- for marc_field in marc_record:
116
- self.report_marc_stats(marc_field, bad_tags, legacy_ids, ignored_subsequent_fields)
117
- if marc_field.tag not in ignored_subsequent_fields:
118
- self.process_marc_field(
119
- folio_authority,
120
- marc_field,
121
- ignored_subsequent_fields,
122
- legacy_ids,
123
- )
124
-
125
- self.perform_additional_parsing(folio_authority)
126
- clean_folio_authority = self.validate_required_properties(
127
- "-".join(legacy_ids), folio_authority, self.schema, FOLIONamespaces.instances
128
- )
129
- self.dedupe_rec(clean_folio_authority)
130
- marc_record.remove_fields(*list(bad_tags))
131
- self.report_folio_mapping(clean_folio_authority, self.schema)
132
- return [clean_folio_authority]
133
-
134
- def perform_initial_preparation(self, marc_record: pymarc.Record, legacy_ids):
135
- folio_authority = {}
136
- folio_authority["id"] = str(
137
- FolioUUID(
138
- self.base_string_for_folio_uuid,
139
- FOLIONamespaces.authorities,
140
- str(legacy_ids[-1]),
141
- )
142
- )
143
- HRIDHandler.handle_035_generation(
144
- marc_record, legacy_ids, self.migration_report, False, False
145
- )
146
- self.map_source_file_and_natural_id(marc_record, folio_authority)
147
- self.handle_leader_17(marc_record, legacy_ids)
148
- return folio_authority
149
-
150
- def map_source_file_and_natural_id(self, marc_record, folio_authority):
151
- """Implement source file and natural ID mappings according to MODDICORE-283"""
152
- match_prefix_patt = re.compile("^[A-Za-z]+")
153
- natural_id = None
154
- source_file_id = None
155
- has_010 = marc_record.get("010")
156
- if has_010 and (has_010a := has_010.get_subfields("a")):
157
- for a_subfield in has_010a:
158
- natural_id_prefix = match_prefix_patt.match(a_subfield)
159
- if natural_id_prefix and (
160
- source_file := self.source_file_mapping.get(natural_id_prefix.group(0), None)
161
- ):
162
- natural_id = "".join(a_subfield.split())
163
- source_file_id = source_file["id"]
164
- self.migration_report.add_general_statistics(
165
- i18n.t("naturalId mapped from %{fro}", fro="010$a")
166
- )
167
- self.migration_report.add(
168
- "AuthoritySourceFileMapping",
169
- f"{source_file['name']} -- {natural_id_prefix.group(0)} -- 010$a",
170
- number=1,
171
- )
172
- break
173
- if not source_file_id:
174
- natural_id = "".join(marc_record["001"].data.split())
175
- self.migration_report.add_general_statistics(
176
- i18n.t("naturalId mapped from %{fro}", fro="001")
177
- )
178
- natural_id_prefix = match_prefix_patt.match(natural_id)
179
- if natural_id_prefix:
180
- if source_file := self.source_file_mapping.get(natural_id_prefix.group(0), None):
181
- source_file_id = source_file["id"]
182
- self.migration_report.add(
183
- "AuthoritySourceFileMapping",
184
- f"{source_file['name']} -- {natural_id_prefix.group(0)} -- 001",
185
- number=1,
186
- )
187
- folio_authority["naturalId"] = natural_id
188
- if source_file_id:
189
- folio_authority["sourceFileId"] = source_file_id
190
-
191
- def setup_source_file_mapping(self):
192
- if self.folio_client.authority_source_files:
193
- logging.info(
194
- f"{len(self.folio_client.authority_source_files)} \tAuthority source files"
195
- )
196
- for source_file in self.folio_client.authority_source_files:
197
- for sf_code in source_file.get("codes", []):
198
- self.source_file_mapping[sf_code] = source_file
199
-
200
- def handle_leader_17(self, marc_record, legacy_ids):
201
- leader_17 = marc_record.leader[17] or "Empty"
202
- self.migration_report.add(
203
- "AuthorityEncodingLevel", i18n.t("Original value") + f": {leader_17}"
204
- )
205
- if leader_17 not in ["n", "o"]:
206
- Helper.log_data_issue(
207
- legacy_ids,
208
- f"LDR pos. 17 is '{leader_17}'. Is this correct? Value has been changed to 'n'.",
209
- marc_record.leader,
210
- )
211
- marc_record.leader = Leader(f"{marc_record.leader[:17]}n{marc_record.leader[18:]}")
212
- self.migration_report.add(
213
- "AuthorityEncodingLevel", i18n.t("Changed %{a} to %{b}", a=leader_17, b="n")
214
- )
215
-
216
- def perform_additional_parsing(
217
- self,
218
- folio_authority: dict,
219
- ) -> None:
220
- """Do stuff not easily captured by the mapping rules
221
-
222
- Args:
223
- folio_authority (dict): _description_
224
- """
225
- folio_authority["source"] = "MARC"
226
-
227
- def get_authority_json_schema(self, folio_client: FolioClient, library_configuration):
228
- """Fetches the JSON Schema for autorities"""
229
- if library_configuration.folio_release.name.lower()[0] < "p":
230
- schema = folio_client.get_from_github(
231
- "folio-org", "mod-inventory-storage", "/ramls/authorities/authority.json"
232
- )
233
- else:
234
- schema = folio_client.get_from_github(
235
- "folio-org",
236
- "mod-entities-links",
237
- "/src/main/resources/swagger.api/schemas/authority-storage/authorityDto.yaml",
238
- )
239
- return schema
240
-
241
- def wrap_up(self):
242
- logging.info("Mapper wrapping up")
@@ -1,118 +0,0 @@
1
- import logging
2
- from typing import Annotated
3
- from typing import List
4
- import i18n
5
-
6
- from folio_uuid.folio_namespaces import FOLIONamespaces
7
- from pydantic import Field
8
-
9
- from folio_migration_tools.helper import Helper
10
- from folio_migration_tools.library_configuration import FileDefinition
11
- from folio_migration_tools.library_configuration import IlsFlavour
12
- from folio_migration_tools.library_configuration import LibraryConfiguration
13
- from folio_migration_tools.marc_rules_transformation.marc_file_processor import (
14
- MarcFileProcessor,
15
- )
16
- from folio_migration_tools.marc_rules_transformation.rules_mapper_authorities import (
17
- AuthorityMapper,
18
- )
19
- from folio_migration_tools.migration_tasks.migration_task_base import MigrationTaskBase
20
- from folio_migration_tools.task_configuration import AbstractTaskConfiguration
21
-
22
-
23
- class AuthorityTransformer(MigrationTaskBase):
24
- class TaskConfiguration(AbstractTaskConfiguration):
25
- name: Annotated[
26
- str,
27
- Field(
28
- description=(
29
- "Name of this migration task. The name is being used to call the specific "
30
- "task, and to distinguish tasks of similar types"
31
- )
32
- ),
33
- ]
34
- migration_task_type: Annotated[
35
- str,
36
- Field(
37
- title="Migration task type",
38
- description=("The type of migration task you want to perform"),
39
- ),
40
- ]
41
- files: Annotated[
42
- List[FileDefinition],
43
- Field(
44
- title="Source files", description=("List of MARC21 files with authority records")
45
- ),
46
- ]
47
- ils_flavour: Annotated[
48
- IlsFlavour,
49
- Field(
50
- title="ILS flavour", description="The type of ILS you are migrating records from."
51
- ),
52
- ]
53
- tags_to_delete: Annotated[
54
- List[str],
55
- Field(
56
- title="Tags to delete from MARC record",
57
- description=(
58
- "Tags in the incoming MARC authority that the process should remove "
59
- "before adding them into FOLIO. These tags will be used in the "
60
- "transformation before getting removed."
61
- ),
62
- ),
63
- ] = []
64
- create_source_records: Annotated[
65
- bool,
66
- Field(
67
- title="Create source records",
68
- description=(
69
- "Controls wheter or not to retain the MARC records in Source Record Storage."
70
- ),
71
- ),
72
- ] = True
73
-
74
- @staticmethod
75
- def get_object_type() -> FOLIONamespaces:
76
- return FOLIONamespaces.authorities
77
-
78
- def __init__(
79
- self,
80
- task_config: TaskConfiguration,
81
- library_config: LibraryConfiguration,
82
- use_logging: bool = True,
83
- ):
84
- super().__init__(library_config, task_config, use_logging)
85
- self.processor: MarcFileProcessor
86
- self.check_source_files(
87
- self.folder_structure.legacy_records_folder, self.task_configuration.files
88
- )
89
- self.mapper: AuthorityMapper = AuthorityMapper(
90
- self.folio_client, library_config, task_config
91
- )
92
- self.auth_ids: set = set()
93
- logging.info("Init done")
94
-
95
- def do_work(self):
96
- self.do_work_marc_transformer()
97
-
98
- def wrap_up(self):
99
- logging.info("Done. Transformer Wrapping up...")
100
- self.extradata_writer.flush()
101
- self.processor.wrap_up()
102
- with open(self.folder_structure.migration_reports_file, "w+") as report_file:
103
- self.mapper.migration_report.write_migration_report(
104
- i18n.t("Authority records transformation report"),
105
- report_file,
106
- self.start_datetime,
107
- )
108
- Helper.print_mapping_report(
109
- report_file,
110
- self.mapper.parsed_records,
111
- self.mapper.mapped_folio_fields,
112
- self.mapper.mapped_legacy_fields,
113
- )
114
- logging.info(
115
- "Done. Transformation report written to %s",
116
- self.folder_structure.migration_reports_file.name,
117
- )
118
- self.clean_out_empty_logs()