pywaybackup 1.2.0__tar.gz → 1.2.2__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.
- {pywaybackup-1.2.0 → pywaybackup-1.2.2}/PKG-INFO +1 -1
- pywaybackup-1.2.2/pywaybackup/__version__.py +1 -0
- {pywaybackup-1.2.0 → pywaybackup-1.2.2}/pywaybackup/archive.py +24 -21
- {pywaybackup-1.2.0 → pywaybackup-1.2.2}/pywaybackup.egg-info/PKG-INFO +1 -1
- pywaybackup-1.2.0/pywaybackup/__version__.py +0 -1
- {pywaybackup-1.2.0 → pywaybackup-1.2.2}/LICENSE +0 -0
- {pywaybackup-1.2.0 → pywaybackup-1.2.2}/README.md +0 -0
- {pywaybackup-1.2.0 → pywaybackup-1.2.2}/pywaybackup/Exception.py +0 -0
- {pywaybackup-1.2.0 → pywaybackup-1.2.2}/pywaybackup/SnapshotCollection.py +0 -0
- {pywaybackup-1.2.0 → pywaybackup-1.2.2}/pywaybackup/Verbosity.py +0 -0
- {pywaybackup-1.2.0 → pywaybackup-1.2.2}/pywaybackup/__init__.py +0 -0
- {pywaybackup-1.2.0 → pywaybackup-1.2.2}/pywaybackup/arguments.py +0 -0
- {pywaybackup-1.2.0 → pywaybackup-1.2.2}/pywaybackup/helper.py +0 -0
- {pywaybackup-1.2.0 → pywaybackup-1.2.2}/pywaybackup/main.py +0 -0
- {pywaybackup-1.2.0 → pywaybackup-1.2.2}/pywaybackup.egg-info/SOURCES.txt +0 -0
- {pywaybackup-1.2.0 → pywaybackup-1.2.2}/pywaybackup.egg-info/dependency_links.txt +0 -0
- {pywaybackup-1.2.0 → pywaybackup-1.2.2}/pywaybackup.egg-info/entry_points.txt +0 -0
- {pywaybackup-1.2.0 → pywaybackup-1.2.2}/pywaybackup.egg-info/requires.txt +0 -0
- {pywaybackup-1.2.0 → pywaybackup-1.2.2}/pywaybackup.egg-info/top_level.txt +0 -0
- {pywaybackup-1.2.0 → pywaybackup-1.2.2}/setup.cfg +0 -0
- {pywaybackup-1.2.0 → pywaybackup-1.2.2}/setup.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.2.2"
|
|
@@ -11,6 +11,8 @@ import http.client
|
|
|
11
11
|
from urllib.parse import urljoin
|
|
12
12
|
from datetime import datetime, timezone
|
|
13
13
|
|
|
14
|
+
from socket import timeout
|
|
15
|
+
|
|
14
16
|
from pywaybackup.helper import url_get_timestamp, url_split, move_index, sanitize_filename
|
|
15
17
|
|
|
16
18
|
from pywaybackup.SnapshotCollection import SnapshotCollection as sc
|
|
@@ -130,7 +132,9 @@ def query_list(url: str, range: int, start: int, end: int, explicit: bool, mode:
|
|
|
130
132
|
try:
|
|
131
133
|
cdxResult = requests.get(cdxQuery).text
|
|
132
134
|
except requests.exceptions.ConnectionError as e:
|
|
133
|
-
|
|
135
|
+
vb.write("\nCONNECTION REFUSED -> could not query cdx server (max retries exceeded)\n")
|
|
136
|
+
os._exit(1)
|
|
137
|
+
#ex.exception("Could not query snapshots", e)
|
|
134
138
|
|
|
135
139
|
if cdxbackup:
|
|
136
140
|
os.makedirs(cdxbackup, exist_ok=True)
|
|
@@ -220,11 +224,13 @@ def download_loop(snapshot_queue, output, worker, retry, no_redirect, skipset=No
|
|
|
220
224
|
vb.write(progress=1)
|
|
221
225
|
if failed_urls:
|
|
222
226
|
if not attempt > max_attempt:
|
|
227
|
+
attempt += 1
|
|
223
228
|
vb.write(f"\n-----> Worker: {worker} - Retry Timeout: 15 seconds")
|
|
224
229
|
time.sleep(15)
|
|
225
|
-
download_loop(
|
|
230
|
+
download_loop(snapshot_queue, output, worker, retry, no_redirect, skipset, attempt, connection, failed_urls)
|
|
226
231
|
except Exception as e:
|
|
227
232
|
ex.exception(f"Worker: {worker} - Exception", e)
|
|
233
|
+
snapshot_queue.put(snapshot) # requeue snapshot if worker crashes
|
|
228
234
|
|
|
229
235
|
|
|
230
236
|
|
|
@@ -293,7 +299,6 @@ def download(output, snapshot_entry, connection, status_message, no_redirect=Fal
|
|
|
293
299
|
f"FILENAME TOO LONG -> HTTP: {response_status} - {response_status_message}\n" + \
|
|
294
300
|
f" -> URL: {download_url}"
|
|
295
301
|
vb.write(status_message)
|
|
296
|
-
#skip_write(skipset, snapshot_entry["url_archive"]) if skipset is not None else None
|
|
297
302
|
return True
|
|
298
303
|
|
|
299
304
|
if not os.path.isfile(output_file):
|
|
@@ -314,7 +319,6 @@ def download(output, snapshot_entry, connection, status_message, no_redirect=Fal
|
|
|
314
319
|
f" -> FILE: {output_file}"
|
|
315
320
|
vb.write(status_message)
|
|
316
321
|
sc.snapshot_entry_modify(snapshot_entry, "file", output_file)
|
|
317
|
-
#skip_write(skipset, snapshot_entry["url_archive"], output_file) if skipset is not None else None
|
|
318
322
|
return True
|
|
319
323
|
|
|
320
324
|
else:
|
|
@@ -330,20 +334,8 @@ def download(output, snapshot_entry, connection, status_message, no_redirect=Fal
|
|
|
330
334
|
f" -> {e}"
|
|
331
335
|
vb.write(status_message)
|
|
332
336
|
return False
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
status_message = f"{status_message}\n" + \
|
|
336
|
-
f"TIMEOUT -> ({i+1}/{max_retries}), reconnect in {sleep_time} seconds...\n" + \
|
|
337
|
-
f" -> {e}"
|
|
338
|
-
vb.write(status_message)
|
|
339
|
-
time.sleep(sleep_time)
|
|
340
|
-
# connection refused waits and retries
|
|
341
|
-
except ConnectionRefusedError as e:
|
|
342
|
-
status_message = f"{status_message}\n" + \
|
|
343
|
-
f"REFUSED -> ({i+1}/{max_retries}), reconnect in {sleep_time} seconds...\n" + \
|
|
344
|
-
f" -> {e}"
|
|
345
|
-
vb.write(status_message)
|
|
346
|
-
time.sleep(sleep_time)
|
|
337
|
+
except (timeout, ConnectionRefusedError, ConnectionResetError) as e:
|
|
338
|
+
download_exception(type, e, i, max_retries, sleep_time, status_message)
|
|
347
339
|
vb.write(f"FAILED -> download, append to failed_urls: {download_url}")
|
|
348
340
|
return False
|
|
349
341
|
|
|
@@ -358,6 +350,16 @@ RESPONSE_CODE_DICT = {
|
|
|
358
350
|
503: "Service Unavailable"
|
|
359
351
|
}
|
|
360
352
|
|
|
353
|
+
def download_exception(type, e, i, max_retries, sleep_time, status_message):
|
|
354
|
+
"""
|
|
355
|
+
Handle exceptions during the download process.
|
|
356
|
+
"""
|
|
357
|
+
type = e.__class__.__name__.upper()
|
|
358
|
+
status_message = f"{status_message}\n" + \
|
|
359
|
+
f"{type} -> ({i+1}/{max_retries}), reconnect in {sleep_time} seconds...\n" + \
|
|
360
|
+
vb.write(status_message)
|
|
361
|
+
time.sleep(sleep_time)
|
|
362
|
+
|
|
361
363
|
def parse_response_code(response_code: int):
|
|
362
364
|
"""
|
|
363
365
|
Parse the response code of the Wayback Machine and return a human-readable message.
|
|
@@ -384,20 +386,21 @@ def csv_close(csv_path: str, url: str):
|
|
|
384
386
|
with open(csv_path, mode='a') as file: # append new rows
|
|
385
387
|
row = csv.DictWriter(file, sc.SNAPSHOT_COLLECTION[0].keys())
|
|
386
388
|
for snapshot in sc.SNAPSHOT_COLLECTION:
|
|
387
|
-
if snapshot["url_archive"] not in existing_rows:
|
|
389
|
+
if snapshot["response"] is not False and snapshot["url_archive"] not in existing_rows: # only append handled snapshots
|
|
388
390
|
row.writerow(snapshot)
|
|
389
391
|
else: # create new file
|
|
390
392
|
with open(csv_path, mode='w') as file:
|
|
391
393
|
row = csv.DictWriter(file, sc.SNAPSHOT_COLLECTION[0].keys())
|
|
392
394
|
row.writeheader()
|
|
393
395
|
for snapshot in sc.SNAPSHOT_COLLECTION:
|
|
394
|
-
|
|
396
|
+
if snapshot["response"] is not False: # only append handled snapshots
|
|
397
|
+
row.writerow(snapshot)
|
|
395
398
|
except Exception as e:
|
|
396
399
|
ex.exception("Could not save CSV-file", e)
|
|
397
400
|
|
|
398
401
|
def csv_read(csv_file: object) -> list:
|
|
399
402
|
"""
|
|
400
|
-
Read the CSV file and return a list of existing snapshot urls
|
|
403
|
+
Read the CSV file and return a list of existing snapshot urls with a status (any status means file was handled)
|
|
401
404
|
"""
|
|
402
405
|
try:
|
|
403
406
|
csv_reader = csv.reader(csv_file)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.2.0"
|
|
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
|