folio-migration-tools 1.9.0a6__tar.gz → 1.9.0a7__tar.gz
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-1.9.0a6 → folio_migration_tools-1.9.0a7}/PKG-INFO +1 -1
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/pyproject.toml +1 -1
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/__main__.py +14 -5
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/library_configuration.py +1 -6
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/mapper_base.py +1 -1
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/migration_tasks/batch_poster.py +30 -14
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/migration_tasks/loans_migrator.py +8 -29
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/LICENSE +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/README.md +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/__init__.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/circulation_helper.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/colors.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/config_file_load.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/custom_dict.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/custom_exceptions.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/extradata_writer.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/folder_structure.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/helper.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/holdings_helper.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/i18n_config.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/mapping_file_transformation/__init__.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/mapping_file_transformation/courses_mapper.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/mapping_file_transformation/holdings_mapper.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/mapping_file_transformation/item_mapper.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/mapping_file_transformation/manual_fee_fines_mapper.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/mapping_file_transformation/mapping_file_mapper_base.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/mapping_file_transformation/notes_mapper.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/mapping_file_transformation/order_mapper.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/mapping_file_transformation/organization_mapper.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/mapping_file_transformation/ref_data_mapping.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/mapping_file_transformation/user_mapper.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/marc_rules_transformation/__init__.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/marc_rules_transformation/conditions.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/marc_rules_transformation/holdings_statementsparser.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/marc_rules_transformation/hrid_handler.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/marc_rules_transformation/loc_language_codes.xml +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/marc_rules_transformation/marc_file_processor.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/marc_rules_transformation/marc_reader_wrapper.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/marc_rules_transformation/rules_mapper_authorities.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/marc_rules_transformation/rules_mapper_base.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/marc_rules_transformation/rules_mapper_bibs.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/marc_rules_transformation/rules_mapper_holdings.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/migration_report.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/migration_tasks/__init__.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/migration_tasks/authority_transformer.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/migration_tasks/bibs_transformer.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/migration_tasks/courses_migrator.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/migration_tasks/holdings_csv_transformer.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/migration_tasks/holdings_marc_transformer.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/migration_tasks/items_transformer.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/migration_tasks/manual_fee_fines_transformer.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/migration_tasks/migration_task_base.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/migration_tasks/orders_transformer.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/migration_tasks/organization_transformer.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/migration_tasks/requests_migrator.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/migration_tasks/reserves_migrator.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/migration_tasks/user_transformer.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/task_configuration.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/test_infrastructure/__init__.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/test_infrastructure/mocked_classes.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/transaction_migration/__init__.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/transaction_migration/legacy_loan.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/transaction_migration/legacy_request.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/transaction_migration/legacy_reserve.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/transaction_migration/transaction_result.py +0 -0
- {folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/translations/en.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "folio_migration_tools"
|
|
3
|
-
version = "1.9.
|
|
3
|
+
version = "1.9.0a7"
|
|
4
4
|
description = "A tool allowing you to migrate data from legacy ILS:s (Library systems) into FOLIO LSP"
|
|
5
5
|
authors = ["Theodor Tolstoy <github.teddes@tolstoy.se>", "Lisa Sjögren", "Brooks Travis", "Jeremy Nelson", "Clinton Bradford"]
|
|
6
6
|
license = "MIT"
|
|
@@ -3,6 +3,7 @@ import logging
|
|
|
3
3
|
import sys
|
|
4
4
|
from os import environ
|
|
5
5
|
from pathlib import Path
|
|
6
|
+
from sqlite3 import connect
|
|
6
7
|
|
|
7
8
|
import httpx
|
|
8
9
|
import humps
|
|
@@ -124,7 +125,8 @@ def main():
|
|
|
124
125
|
except TransformationProcessError as tpe:
|
|
125
126
|
logging.critical(tpe.message)
|
|
126
127
|
print(f"\n{tpe.message}: {tpe.data_value}")
|
|
127
|
-
|
|
128
|
+
print("Task failure. Halting.")
|
|
129
|
+
sys.exit(1)
|
|
128
130
|
logging.info("Work done. Shutting down")
|
|
129
131
|
sys.exit(0)
|
|
130
132
|
except json.decoder.JSONDecodeError as json_error:
|
|
@@ -148,10 +150,17 @@ def main():
|
|
|
148
150
|
print("Halting")
|
|
149
151
|
sys.exit("JSON Not Matching Spec")
|
|
150
152
|
except httpx.HTTPError as connection_error:
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
153
|
+
if hasattr(connection_error, "response"):
|
|
154
|
+
print(
|
|
155
|
+
f"\nHTTP Error when connecting to {connection_error.request.url}. "
|
|
156
|
+
f"Status code: {connection_error.response.status_code}. "
|
|
157
|
+
f"\nResponse: {connection_error.response.text}"
|
|
158
|
+
)
|
|
159
|
+
else:
|
|
160
|
+
print(
|
|
161
|
+
f"\nConnection Error when connecting to {connection_error.request.url}. "
|
|
162
|
+
"Are you connected to the Internet/VPN? Do you need to update DNS settings?"
|
|
163
|
+
)
|
|
155
164
|
sys.exit("HTTP Not Connecting")
|
|
156
165
|
except FileNotFoundError as fnf_error:
|
|
157
166
|
print(f"\n{fnf_error.strerror}: {fnf_error.filename}")
|
|
@@ -62,14 +62,9 @@ class IlsFlavour(str, Enum):
|
|
|
62
62
|
|
|
63
63
|
|
|
64
64
|
class FolioRelease(str, Enum):
|
|
65
|
-
lotus = "lotus"
|
|
66
|
-
morning_glory = "morning-glory"
|
|
67
|
-
nolana = "nolana"
|
|
68
|
-
orchid = "orchid"
|
|
69
|
-
poppy = "poppy"
|
|
70
|
-
quesnelia = "quesnelia"
|
|
71
65
|
ramsons = "ramsons"
|
|
72
66
|
sunflower = "sunflower"
|
|
67
|
+
trillium = "trillium"
|
|
73
68
|
|
|
74
69
|
|
|
75
70
|
class LibraryConfiguration(BaseModel):
|
|
@@ -444,7 +444,7 @@ class MapperBase:
|
|
|
444
444
|
except IndexError:
|
|
445
445
|
if call_numbers:
|
|
446
446
|
bound_with_holding["callNumber"] = call_numbers[0]
|
|
447
|
-
except SyntaxError:
|
|
447
|
+
except (SyntaxError, ValueError):
|
|
448
448
|
bound_with_holding["callNumber"] = call_number
|
|
449
449
|
else:
|
|
450
450
|
bound_with_holding["callNumber"] = call_number
|
|
@@ -5,6 +5,7 @@ import sys
|
|
|
5
5
|
import time
|
|
6
6
|
import traceback
|
|
7
7
|
from datetime import datetime
|
|
8
|
+
from math import log
|
|
8
9
|
from typing import Annotated, List
|
|
9
10
|
from uuid import uuid4
|
|
10
11
|
|
|
@@ -136,12 +137,12 @@ class BatchPoster(MigrationTaskBase):
|
|
|
136
137
|
def do_work(self):
|
|
137
138
|
with self.folio_client.get_folio_http_client() as httpx_client:
|
|
138
139
|
self.http_client = httpx_client
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
self.
|
|
143
|
-
|
|
144
|
-
for file_def in self.task_configuration.files:
|
|
140
|
+
with open(self.folder_structure.failed_recs_path, "w", encoding='utf-8') as failed_recs_file:
|
|
141
|
+
try:
|
|
142
|
+
batch = []
|
|
143
|
+
if self.task_configuration.object_type == "SRS":
|
|
144
|
+
self.create_snapshot()
|
|
145
|
+
for idx, file_def in enumerate(self.task_configuration.files):
|
|
145
146
|
path = self.folder_structure.results_folder / file_def.file_name
|
|
146
147
|
with open(path) as rows:
|
|
147
148
|
logging.info("Running %s", path)
|
|
@@ -172,9 +173,8 @@ class BatchPoster(MigrationTaskBase):
|
|
|
172
173
|
self.processed,
|
|
173
174
|
failed_recs_file,
|
|
174
175
|
)
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
sys.exit(1)
|
|
176
|
+
batch = []
|
|
177
|
+
raise
|
|
178
178
|
except TransformationRecordFailedError as exception:
|
|
179
179
|
self.handle_generic_exception(
|
|
180
180
|
exception,
|
|
@@ -184,7 +184,21 @@ class BatchPoster(MigrationTaskBase):
|
|
|
184
184
|
failed_recs_file,
|
|
185
185
|
)
|
|
186
186
|
batch = []
|
|
187
|
-
|
|
187
|
+
except (FileNotFoundError, PermissionError) as ose:
|
|
188
|
+
logging.error("Error reading file: %s", ose)
|
|
189
|
+
|
|
190
|
+
except Exception as ee:
|
|
191
|
+
if "idx" in locals() and self.task_configuration.files[idx:]:
|
|
192
|
+
for file in self.task_configuration.files[idx:]:
|
|
193
|
+
try:
|
|
194
|
+
with open(file, "r") as failed_file:
|
|
195
|
+
failed_file.seek(self.processed)
|
|
196
|
+
failed_recs_file.write(failed_file.read())
|
|
197
|
+
self.processed = 0
|
|
198
|
+
except (FileNotFoundError, PermissionError) as ose:
|
|
199
|
+
logging.error("Error reading file: %s", ose)
|
|
200
|
+
raise ee
|
|
201
|
+
finally:
|
|
188
202
|
if self.task_configuration.object_type != "Extradata" and any(batch):
|
|
189
203
|
try:
|
|
190
204
|
self.post_batch(batch, failed_recs_file, self.processed)
|
|
@@ -193,10 +207,8 @@ class BatchPoster(MigrationTaskBase):
|
|
|
193
207
|
exception, last_row, batch, self.processed, failed_recs_file
|
|
194
208
|
)
|
|
195
209
|
logging.info("Done posting %s records. ", (self.processed))
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
self.commit_snapshot()
|
|
199
|
-
raise ee
|
|
210
|
+
if self.task_configuration.object_type == "SRS":
|
|
211
|
+
self.commit_snapshot()
|
|
200
212
|
|
|
201
213
|
def post_record_batch(self, batch, failed_recs_file, row):
|
|
202
214
|
json_rec = json.loads(row.split("\t")[-1])
|
|
@@ -339,6 +351,10 @@ class BatchPoster(MigrationTaskBase):
|
|
|
339
351
|
|
|
340
352
|
def post_batch(self, batch, failed_recs_file, num_records, recursion_depth=0):
|
|
341
353
|
response = self.do_post(batch)
|
|
354
|
+
if response.status_code == 401:
|
|
355
|
+
logging.error("Authorization failed (%s). Fetching new auth token...", response.text)
|
|
356
|
+
self.folio_client.login()
|
|
357
|
+
response = self.do_post(batch)
|
|
342
358
|
if response.status_code == 201:
|
|
343
359
|
logging.info(
|
|
344
360
|
(
|
|
@@ -8,11 +8,11 @@ import traceback
|
|
|
8
8
|
from datetime import datetime, timedelta
|
|
9
9
|
from typing import Optional
|
|
10
10
|
from urllib.error import HTTPError
|
|
11
|
+
from zoneinfo import ZoneInfo
|
|
11
12
|
|
|
12
13
|
import i18n
|
|
13
14
|
from dateutil import parser as du_parser
|
|
14
15
|
from folio_uuid.folio_namespaces import FOLIONamespaces
|
|
15
|
-
from zoneinfo import ZoneInfo
|
|
16
16
|
|
|
17
17
|
from folio_migration_tools.circulation_helper import CirculationHelper
|
|
18
18
|
from folio_migration_tools.helper import Helper
|
|
@@ -131,34 +131,13 @@ class LoansMigrator(MigrationTaskBase):
|
|
|
131
131
|
logging.info("Init completed")
|
|
132
132
|
|
|
133
133
|
def check_smtp_config(self):
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
okapi_config_code = "EMAIL_SMTP_HOST_DISABLED"
|
|
142
|
-
smtp_config_path = (
|
|
143
|
-
okapi_config_base_path
|
|
144
|
-
+ "?"
|
|
145
|
-
+ str(okapi_config_limit)
|
|
146
|
-
+ "&query="
|
|
147
|
-
+ okapi_config_query.format(
|
|
148
|
-
okapi_config_module, okapi_config_name, okapi_config_code
|
|
149
|
-
)
|
|
150
|
-
)
|
|
151
|
-
smtp_config_disabled = self.folio_client.folio_get_single_object(smtp_config_path)[
|
|
152
|
-
"configs"
|
|
153
|
-
]
|
|
154
|
-
else:
|
|
155
|
-
try:
|
|
156
|
-
smtp_config = self.folio_client.folio_get_single_object("/smtp-configuration")[
|
|
157
|
-
"smtpConfigurations"
|
|
158
|
-
][0]
|
|
159
|
-
smtp_config_disabled = "disabled" in smtp_config["host"].lower()
|
|
160
|
-
except IndexError:
|
|
161
|
-
smtp_config_disabled = True
|
|
134
|
+
try:
|
|
135
|
+
smtp_config = self.folio_client.folio_get_single_object("/smtp-configuration")[
|
|
136
|
+
"smtpConfigurations"
|
|
137
|
+
][0]
|
|
138
|
+
smtp_config_disabled = "disabled" in smtp_config["host"].lower()
|
|
139
|
+
except IndexError:
|
|
140
|
+
smtp_config_disabled = True
|
|
162
141
|
print_smtp_warning()
|
|
163
142
|
if not smtp_config_disabled:
|
|
164
143
|
logging.warn("SMTP connection not disabled...")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/colors.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{folio_migration_tools-1.9.0a6 → folio_migration_tools-1.9.0a7}/src/folio_migration_tools/helper.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|