From 779978ae6480dd5f677c9e5a5a97dbb7c0b3546d Mon Sep 17 00:00:00 2001 From: Mat Kelly Date: Tue, 17 May 2022 13:18:13 -0400 Subject: [PATCH 01/11] Add preliminary support for ingesting WACZ files Re:#710 --- ipwb/indexer.py | 13 +++++++++++++ ipwb/util.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/ipwb/indexer.py b/ipwb/indexer.py index 835ded4..66d7cd9 100755 --- a/ipwb/indexer.py +++ b/ipwb/indexer.py @@ -33,6 +33,7 @@ from six import PY3 from ipwb.util import iso8601_to_digits14, ipfs_client +from ipwb.util import is_wacz, extract_warcs_from_wacz import requests import datetime @@ -123,6 +124,18 @@ def index_file_at(warc_paths, encryption_key=None, for warc_path in warc_paths: verify_file_exists(warc_path) + warc_paths_to_append = [] + warc_paths_to_remove = [] + for warc_path in warc_paths: + if is_wacz(warc_path): + warc_paths_to_append.append( + extract_warcs_from_wacz(warc_path)) + warc_paths_to_remove.append(warc_path) + + # Manipulate list of WARCs extracted from WACZ + warc_paths.remove(warc_paths_to_remove) + warc_paths += warc_paths_to_append + cdxj_lines = [] if outfile: diff --git a/ipwb/util.py b/ipwb/util.py index dbbf12b..b27dc61 100644 --- a/ipwb/util.py +++ b/ipwb/util.py @@ -13,6 +13,10 @@ import logging import platform +# For extracting WARCs from WACZ +import glob +from zipfile import ZipFile, is_zipfile + from urllib.request import urlopen from urllib.error import URLError @@ -336,3 +340,28 @@ def check_for_update(_): print("The installed version of ipwb is outdated.") print(f"* Installed: {current}\n* Latest: {latest}") print("Please run `pip install --upgrade ipwb` to upgrade.") + + +def is_wacz(path): + # TODO: add logic to check if wacz + # the py-wacz validator inherits many dependencies, + # so ad hoc here for now + return is_zipfile(path) + + +def get_warc_paths_in_wacz(wacz_path): + with ZipFile(wacz_path) as z: + return [w for w in z.namelist() if w.startswith('archive/')] + + +def extract_warcs_to_disk(wac_paths): + for warc in warc_paths: + with ZipFile(sample_wacz) as z: + z.extract(warc) + + +def extract_warcs_from_wacz(wacz_path): + warc_paths = get_warc_paths_in_wacz(wacz_path) + extract_warcs_to_disk(warc_paths) + + return glob.glob('archive/*') From e82a4f72d2087dd6dd7a7ce7f7c81454d243de0c Mon Sep 17 00:00:00 2001 From: Mat Kelly Date: Tue, 17 May 2022 13:20:35 -0400 Subject: [PATCH 02/11] Fix typo in argument --- ipwb/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipwb/util.py b/ipwb/util.py index b27dc61..101d1f3 100644 --- a/ipwb/util.py +++ b/ipwb/util.py @@ -354,7 +354,7 @@ def get_warc_paths_in_wacz(wacz_path): return [w for w in z.namelist() if w.startswith('archive/')] -def extract_warcs_to_disk(wac_paths): +def extract_warcs_to_disk(warc_paths): for warc in warc_paths: with ZipFile(sample_wacz) as z: z.extract(warc) From 133a9e421da2fd8d9de234ed12dcd23e0f7df19c Mon Sep 17 00:00:00 2001 From: Mat Kelly Date: Tue, 17 May 2022 13:21:39 -0400 Subject: [PATCH 03/11] Replace sample var in WARC path --- ipwb/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipwb/util.py b/ipwb/util.py index 101d1f3..b52cad9 100644 --- a/ipwb/util.py +++ b/ipwb/util.py @@ -356,7 +356,7 @@ def get_warc_paths_in_wacz(wacz_path): def extract_warcs_to_disk(warc_paths): for warc in warc_paths: - with ZipFile(sample_wacz) as z: + with ZipFile(warc) as z: z.extract(warc) From 9436999fc977509427064b6b838f46e342f3360f Mon Sep 17 00:00:00 2001 From: Mat Kelly Date: Tue, 17 May 2022 13:51:47 -0400 Subject: [PATCH 04/11] File list of warc appending for #710 --- ipwb/indexer.py | 8 ++++---- ipwb/util.py | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ipwb/indexer.py b/ipwb/indexer.py index 66d7cd9..ecb904b 100755 --- a/ipwb/indexer.py +++ b/ipwb/indexer.py @@ -128,13 +128,13 @@ def index_file_at(warc_paths, encryption_key=None, warc_paths_to_remove = [] for warc_path in warc_paths: if is_wacz(warc_path): - warc_paths_to_append.append( - extract_warcs_from_wacz(warc_path)) + warc_paths_to_append += extract_warcs_from_wacz(warc_path) warc_paths_to_remove.append(warc_path) # Manipulate list of WARCs extracted from WACZ - warc_paths.remove(warc_paths_to_remove) - warc_paths += warc_paths_to_append + for ptr in warc_paths_to_remove: + warc_paths.remove(ptr) + warc_paths = warc_paths + warc_paths_to_append cdxj_lines = [] diff --git a/ipwb/util.py b/ipwb/util.py index b52cad9..98c0f7b 100644 --- a/ipwb/util.py +++ b/ipwb/util.py @@ -354,14 +354,14 @@ def get_warc_paths_in_wacz(wacz_path): return [w for w in z.namelist() if w.startswith('archive/')] -def extract_warcs_to_disk(warc_paths): +def extract_warcs_to_disk(wacz_path, warc_paths): for warc in warc_paths: - with ZipFile(warc) as z: + with ZipFile(wacz_path) as z: z.extract(warc) def extract_warcs_from_wacz(wacz_path): warc_paths = get_warc_paths_in_wacz(wacz_path) - extract_warcs_to_disk(warc_paths) + extract_warcs_to_disk(wacz_path, warc_paths) return glob.glob('archive/*') From a422b4731640e11c85fc2ce1d4df87ce2212eb66 Mon Sep 17 00:00:00 2001 From: Mat Kelly Date: Tue, 24 May 2022 15:46:58 -0400 Subject: [PATCH 05/11] Add sample wacz file, derived from samples in warc samples --- samples/wacz/my-collection.wacz | Bin 0 -> 79181 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 samples/wacz/my-collection.wacz diff --git a/samples/wacz/my-collection.wacz b/samples/wacz/my-collection.wacz new file mode 100644 index 0000000000000000000000000000000000000000..cef06b79a8f34c9f237102c2c3041895d9909cf5 GIT binary patch literal 79181 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 KHPjpv-Twhm!7vN} literal 0 HcmV?d00001 From 25e91ad07c14c1c1e42677ef0a55656ab32d16fe Mon Sep 17 00:00:00 2001 From: Mat Kelly Date: Tue, 24 May 2022 15:54:56 -0400 Subject: [PATCH 06/11] Add test for wacz --- tests/testUtil.py | 7 +++++-- tests/test_replay.py | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/testUtil.py b/tests/testUtil.py index d292722..a9d1446 100644 --- a/tests/testUtil.py +++ b/tests/testUtil.py @@ -57,11 +57,14 @@ def count_cdxj_entries(cdxj_data): return urim_count -def start_replay(warc_filename): +def start_replay(filename, samples_dir='warc'): global p + if filename.endswith('.wacz'): + samples_dir = 'wacz' + path_of_warc = os.path.join( Path(os.path.dirname(__file__)).parent, - 'samples', 'warcs', warc_filename) + 'samples', samples_dir, filename) fh, tempfile_path = tempfile.mkstemp(suffix='.cdxj') os.close(fh) diff --git a/tests/test_replay.py b/tests/test_replay.py index bb894bd..7caf34c 100644 --- a/tests/test_replay.py +++ b/tests/test_replay.py @@ -49,6 +49,7 @@ def test_replay_404(warc, lookup, has_md_header): ('2mementos_queryString.warc', '/memento/20130202100000/memento.us/' + 'index.php?anotherval=ipsum&someval=lorem', 200, None), + ('my-collection.wacz', 'memento/*/memento.us', 200, None), ]) def test_replay_search(warc, lookup, status, location): ipwb_test.start_replay(warc) From f9447d2c9be46c825f62bd8cd31d6faa1075c1c3 Mon Sep 17 00:00:00 2001 From: Mat Kelly Date: Wed, 25 May 2022 09:10:07 -0400 Subject: [PATCH 07/11] Tweak warc path for testing re:#710 --- tests/testUtil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testUtil.py b/tests/testUtil.py index a9d1446..0b363a5 100644 --- a/tests/testUtil.py +++ b/tests/testUtil.py @@ -57,7 +57,7 @@ def count_cdxj_entries(cdxj_data): return urim_count -def start_replay(filename, samples_dir='warc'): +def start_replay(filename, samples_dir='warcs'): global p if filename.endswith('.wacz'): samples_dir = 'wacz' From 2566b7cfc47667c78de532ee7d9bcbed340ac16c Mon Sep 17 00:00:00 2001 From: Mat Kelly Date: Thu, 2 Jun 2022 15:49:52 -0400 Subject: [PATCH 08/11] Delete WARCs extracted from WACZ for cleanup post-indexing Re:#770 Re:#710 --- ipwb/indexer.py | 5 +++++ ipwb/util.py | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/ipwb/indexer.py b/ipwb/indexer.py index ecb904b..7d0a9c3 100755 --- a/ipwb/indexer.py +++ b/ipwb/indexer.py @@ -34,6 +34,7 @@ from ipwb.util import iso8601_to_digits14, ipfs_client from ipwb.util import is_wacz, extract_warcs_from_wacz +from ipwb.util import cleanup_warc_files_extracted_from_wacz import requests import datetime @@ -126,9 +127,11 @@ def index_file_at(warc_paths, encryption_key=None, warc_paths_to_append = [] warc_paths_to_remove = [] + warcs_to_cleanup_post_indexing = [] for warc_path in warc_paths: if is_wacz(warc_path): warc_paths_to_append += extract_warcs_from_wacz(warc_path) + warcs_to_cleanup_post_indexing = warc_paths_to_append warc_paths_to_remove.append(warc_path) # Manipulate list of WARCs extracted from WACZ @@ -184,6 +187,8 @@ def index_file_at(warc_paths, encryption_key=None, cdxj_metadata_lines = generate_cdxj_metadata(cdxj_lines) cdxj_lines = cdxj_metadata_lines + cdxj_lines + cleanup_warc_files_extracted_from_wacz(warcs_to_cleanup_post_indexing) + if quiet: return cdxj_lines diff --git a/ipwb/util.py b/ipwb/util.py index 98c0f7b..ede0847 100644 --- a/ipwb/util.py +++ b/ipwb/util.py @@ -365,3 +365,13 @@ def extract_warcs_from_wacz(wacz_path): extract_warcs_to_disk(wacz_path, warc_paths) return glob.glob('archive/*') + + +def cleanup_warc_files_extracted_from_wacz(warc_paths): + for temporary_warc in warc_paths: + try: + if os.path.isfile(temporary_warc): + print(f'Deleting tempporary WARC at {temporary_warc}') + os.remove(temporary_warc) + except OSError as e: + print(f'Error: {e.filename}, {e.strerror}') From e4b9998f82f7cb75f63ed808ec5080c0e7449074 Mon Sep 17 00:00:00 2001 From: Mat Kelly Date: Thu, 2 Jun 2022 17:03:30 -0400 Subject: [PATCH 09/11] Store extracted WARCs in WACZ to temp location Re:#770, #710 --- ipwb/indexer.py | 11 +++++------ ipwb/util.py | 17 +++++++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/ipwb/indexer.py b/ipwb/indexer.py index 7d0a9c3..8aa0215 100755 --- a/ipwb/indexer.py +++ b/ipwb/indexer.py @@ -125,17 +125,16 @@ def index_file_at(warc_paths, encryption_key=None, for warc_path in warc_paths: verify_file_exists(warc_path) + # Extract WARCs from any WACZ files warc_paths_to_append = [] - warc_paths_to_remove = [] - warcs_to_cleanup_post_indexing = [] + wacz_paths = [] for warc_path in warc_paths: if is_wacz(warc_path): warc_paths_to_append += extract_warcs_from_wacz(warc_path) - warcs_to_cleanup_post_indexing = warc_paths_to_append - warc_paths_to_remove.append(warc_path) + wacz_paths.append(warc_path) # Manipulate list of WARCs extracted from WACZ - for ptr in warc_paths_to_remove: + for ptr in wacz_paths: warc_paths.remove(ptr) warc_paths = warc_paths + warc_paths_to_append @@ -187,7 +186,7 @@ def index_file_at(warc_paths, encryption_key=None, cdxj_metadata_lines = generate_cdxj_metadata(cdxj_lines) cdxj_lines = cdxj_metadata_lines + cdxj_lines - cleanup_warc_files_extracted_from_wacz(warcs_to_cleanup_post_indexing) + cleanup_warc_files_extracted_from_wacz(warc_paths_to_append) if quiet: return cdxj_lines diff --git a/ipwb/util.py b/ipwb/util.py index ede0847..d132d46 100644 --- a/ipwb/util.py +++ b/ipwb/util.py @@ -12,6 +12,7 @@ import datetime import logging import platform +import tempfile # For extracting WARCs from WACZ import glob @@ -354,24 +355,28 @@ def get_warc_paths_in_wacz(wacz_path): return [w for w in z.namelist() if w.startswith('archive/')] -def extract_warcs_to_disk(wacz_path, warc_paths): +def extract_warcs_to_disk(wacz_path, warc_paths) -> list: + extracted_warc_paths = [] for warc in warc_paths: with ZipFile(wacz_path) as z: - z.extract(warc) + ph = z.extract(warc, tempfile.mkdtemp()) + extracted_warc_paths.append(ph) + + return extracted_warc_paths def extract_warcs_from_wacz(wacz_path): - warc_paths = get_warc_paths_in_wacz(wacz_path) - extract_warcs_to_disk(wacz_path, warc_paths) + warc_paths_in_wacz = get_warc_paths_in_wacz(wacz_path) + warc_paths_on_disk = extract_warcs_to_disk( + wacz_path, warc_paths_in_wacz) - return glob.glob('archive/*') + return warc_paths_on_disk def cleanup_warc_files_extracted_from_wacz(warc_paths): for temporary_warc in warc_paths: try: if os.path.isfile(temporary_warc): - print(f'Deleting tempporary WARC at {temporary_warc}') os.remove(temporary_warc) except OSError as e: print(f'Error: {e.filename}, {e.strerror}') From 7e2589d2e8b6a5184f49a41e8f2a578289c45ce6 Mon Sep 17 00:00:00 2001 From: Mat Kelly Date: Mon, 27 Jun 2022 17:46:53 -0400 Subject: [PATCH 10/11] Rm temp path created for WARC, be a good citizen Re:#770 --- ipwb/indexer.py | 9 ++++++++- ipwb/util.py | 15 +++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/ipwb/indexer.py b/ipwb/indexer.py index 8aa0215..420a98a 100755 --- a/ipwb/indexer.py +++ b/ipwb/indexer.py @@ -17,6 +17,7 @@ import zlib import surt import ntpath +import shutil import traceback import tempfile @@ -130,12 +131,14 @@ def index_file_at(warc_paths, encryption_key=None, wacz_paths = [] for warc_path in warc_paths: if is_wacz(warc_path): - warc_paths_to_append += extract_warcs_from_wacz(warc_path) + (new_warc_paths, dirs_to_cleanup) = extract_warcs_from_wacz(warc_path) + warc_paths_to_append += new_warc_paths wacz_paths.append(warc_path) # Manipulate list of WARCs extracted from WACZ for ptr in wacz_paths: warc_paths.remove(ptr) + warc_paths = warc_paths + warc_paths_to_append cdxj_lines = [] @@ -201,6 +204,10 @@ def index_file_at(warc_paths, encryption_key=None, else: print('\n'.join(cdxj_lines)) + # Cleanup, e.g., dirs for WARCs from WACZ + for dir_to_cleanup in dirs_to_cleanup: + shutil.rmtree(dir_to_cleanup) + def sanitize_cdxj_line(cdxj_line): return cdxj_line diff --git a/ipwb/util.py b/ipwb/util.py index d132d46..031855f 100644 --- a/ipwb/util.py +++ b/ipwb/util.py @@ -356,21 +356,28 @@ def get_warc_paths_in_wacz(wacz_path): def extract_warcs_to_disk(wacz_path, warc_paths) -> list: + ''' + Extract WARCs and retain reference to temp path + for later deletion + ''' extracted_warc_paths = [] + tmp_dirs = [] for warc in warc_paths: with ZipFile(wacz_path) as z: - ph = z.extract(warc, tempfile.mkdtemp()) + tmp_dir = tempfile.mkdtemp() + ph = z.extract(warc, tmp_dir) extracted_warc_paths.append(ph) + tmp_dirs.append(tmp_dir) # For later dir deletion - return extracted_warc_paths + return (extracted_warc_paths, tmp_dirs) def extract_warcs_from_wacz(wacz_path): warc_paths_in_wacz = get_warc_paths_in_wacz(wacz_path) - warc_paths_on_disk = extract_warcs_to_disk( + (warc_paths_on_disk, dirs_to_cleanup) = extract_warcs_to_disk( wacz_path, warc_paths_in_wacz) - return warc_paths_on_disk + return (warc_paths_on_disk, dirs_to_cleanup) def cleanup_warc_files_extracted_from_wacz(warc_paths): From 038d2bb4f98aac9f7d93e687eb6c8310899f172e Mon Sep 17 00:00:00 2001 From: Mat Kelly Date: Mon, 27 Jun 2022 17:55:32 -0400 Subject: [PATCH 11/11] Fix pep8 length issue --- ipwb/indexer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ipwb/indexer.py b/ipwb/indexer.py index 420a98a..841b6d5 100755 --- a/ipwb/indexer.py +++ b/ipwb/indexer.py @@ -131,8 +131,8 @@ def index_file_at(warc_paths, encryption_key=None, wacz_paths = [] for warc_path in warc_paths: if is_wacz(warc_path): - (new_warc_paths, dirs_to_cleanup) = extract_warcs_from_wacz(warc_path) - warc_paths_to_append += new_warc_paths + (w_paths, dirs_to_cleanup) = extract_warcs_from_wacz(warc_path) + warc_paths_to_append += w_paths wacz_paths.append(warc_path) # Manipulate list of WARCs extracted from WACZ