From 31dd7131d2f9194fa944a6435d64e1d77db7c72f Mon Sep 17 00:00:00 2001 From: Cole Herman Date: Mon, 27 Jul 2026 16:18:48 -0700 Subject: [PATCH 1/5] First working version --- zip_files.py | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 zip_files.py diff --git a/zip_files.py b/zip_files.py new file mode 100644 index 0000000..4f33641 --- /dev/null +++ b/zip_files.py @@ -0,0 +1,72 @@ +import yaml +import zipfile +from pathlib import Path + + +# Simpler version that doesn't give progress count + +# def zip_files(files: list[Path], name: str, dir: Path) -> None: +# """Create a zip from a list of file names. Input only names and not filepaths""" +# # Add zip to end if no extension +# if not name.endswith('.zip'): +# name += '.zip' + +# output_path = dir / name + +# # Zip the files +# with zipfile.ZipFile(output_path, "w") as zipf: +# for path in files: +# if path.is_dir(): +# for file in path.rglob("*"): +# if file.is_file(): +# print(f"Zipping files...") +# zipf.write(file, arcname=file.relative_to(dir)) +# else: +# print("Zipping files...") +# zipf.write(path, arcname=path.relative_to(dir)) +# print("Done") + + +# More complicated version that gives progress count +def collect_files(paths: list[Path]) -> list[Path]: + all_files = [] + for path in paths: + if path.is_dir(): + all_files.extend(file for file in path.rglob('*') if file.is_file()) + else: + all_files.append(path) + return all_files + +def zip_files(files: list[Path], name: str, dir: Path) -> None: + if not name.endswith(".zip"): + name += ".zip" + + output_path = dir / name + all_files = collect_files(files) + total = len(all_files) + + with zipfile.ZipFile(output_path, "w") as zipf: + for idx, file in enumerate(all_files, start=1): + print(f"Zipping {idx}/{total}: {file}") + zipf.write(file, arcname=file.relative_to(dir)) + + print("Done") + +def main(): + with open('filepaths.yaml') as file: + f = yaml.safe_load(file) + f1 = Path(f['metadata'][0]) + print(f"F1: {f1}") + f2 = Path(f['assets']) + print(f"F2: {f2}") + + target_dir = Path(str(f2).replace("\\files", '')) + print(target_dir) + + # Can rename test to desired folder name. In future could have it be a filepaths field. + # Could try to extract it from filepaths but this will be annoying and hard to verify + zip_files([f1, f2], "test", target_dir) + + +if __name__ == "__main__": + main() \ No newline at end of file From 5e5bbd966f585f9a242bab30f281f6c3b8928ac5 Mon Sep 17 00:00:00 2001 From: coleherman43 Date: Fri, 31 Jul 2026 13:22:31 -0700 Subject: [PATCH 2/5] Comments --- zip_files.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/zip_files.py b/zip_files.py index 4f33641..58f746b 100644 --- a/zip_files.py +++ b/zip_files.py @@ -30,6 +30,8 @@ # More complicated version that gives progress count def collect_files(paths: list[Path]) -> list[Path]: all_files = [] + + # Loop through paths and add files to list for path in paths: if path.is_dir(): all_files.extend(file for file in path.rglob('*') if file.is_file()) @@ -38,13 +40,16 @@ def collect_files(paths: list[Path]) -> list[Path]: return all_files def zip_files(files: list[Path], name: str, dir: Path) -> None: + # Add zip extension if missing in name argument if not name.endswith(".zip"): name += ".zip" + # Make output path and get file list output_path = dir / name all_files = collect_files(files) total = len(all_files) + # Zip the files into chosen location with zipfile.ZipFile(output_path, "w") as zipf: for idx, file in enumerate(all_files, start=1): print(f"Zipping {idx}/{total}: {file}") @@ -53,6 +58,7 @@ def zip_files(files: list[Path], name: str, dir: Path) -> None: print("Done") def main(): + # Get directory structure from filepaths.yaml with open('filepaths.yaml') as file: f = yaml.safe_load(file) f1 = Path(f['metadata'][0]) @@ -60,6 +66,7 @@ def main(): f2 = Path(f['assets']) print(f"F2: {f2}") + # Write where directory to put zip is target_dir = Path(str(f2).replace("\\files", '')) print(target_dir) From 7873c92e8da54c7a07b53779ab1ceb36fd2ccd27 Mon Sep 17 00:00:00 2001 From: coleherman43 Date: Fri, 7 Aug 2026 14:33:15 -0700 Subject: [PATCH 3/5] Fixed version, uses parent to work on any OS, and automatically guesses name from csv name --- zip_files.py | 52 ++++++++++++++++------------------------------------ 1 file changed, 16 insertions(+), 36 deletions(-) diff --git a/zip_files.py b/zip_files.py index 58f746b..d22ec7c 100644 --- a/zip_files.py +++ b/zip_files.py @@ -1,34 +1,13 @@ +"""Automatically zip files/ and metadata csv""" import yaml import zipfile from pathlib import Path +#FIXME: This will zip hidden files, like .DS_Store on mac. Users should just check that that doesn't show in the logs, or +# we could add a bigger fix by filtering for it in collect_files. -# Simpler version that doesn't give progress count - -# def zip_files(files: list[Path], name: str, dir: Path) -> None: -# """Create a zip from a list of file names. Input only names and not filepaths""" -# # Add zip to end if no extension -# if not name.endswith('.zip'): -# name += '.zip' - -# output_path = dir / name - -# # Zip the files -# with zipfile.ZipFile(output_path, "w") as zipf: -# for path in files: -# if path.is_dir(): -# for file in path.rglob("*"): -# if file.is_file(): -# print(f"Zipping files...") -# zipf.write(file, arcname=file.relative_to(dir)) -# else: -# print("Zipping files...") -# zipf.write(path, arcname=path.relative_to(dir)) -# print("Done") - - -# More complicated version that gives progress count def collect_files(paths: list[Path]) -> list[Path]: + """Return all files (counting recursively) from a given list of paths""" all_files = [] # Loop through paths and add files to list @@ -39,21 +18,22 @@ def collect_files(paths: list[Path]) -> list[Path]: all_files.append(path) return all_files -def zip_files(files: list[Path], name: str, dir: Path) -> None: +def zip_files(csv_and_metadata_files: list[Path], name: str, root_dir: Path) -> None: + """Zip all files from a list of paths with given name inside the root directory""" # Add zip extension if missing in name argument if not name.endswith(".zip"): name += ".zip" # Make output path and get file list - output_path = dir / name - all_files = collect_files(files) + output_path = root_dir / name + all_files = collect_files(csv_and_metadata_files) total = len(all_files) # Zip the files into chosen location with zipfile.ZipFile(output_path, "w") as zipf: for idx, file in enumerate(all_files, start=1): print(f"Zipping {idx}/{total}: {file}") - zipf.write(file, arcname=file.relative_to(dir)) + zipf.write(file, arcname=file.relative_to(root_dir)) print("Done") @@ -66,14 +46,14 @@ def main(): f2 = Path(f['assets']) print(f"F2: {f2}") - # Write where directory to put zip is - target_dir = Path(str(f2).replace("\\files", '')) - print(target_dir) - - # Can rename test to desired folder name. In future could have it be a filepaths field. - # Could try to extract it from filepaths but this will be annoying and hard to verify - zip_files([f1, f2], "test", target_dir) + # Write where directory to put zip is (root of all our operations, likely the work folder) + root_dir = f2.parent + print(root_dir) + # Guess desired zip name from the yaml file input + zip_folder_name = f1.stem + # Save assets/ and metadata csv (f1 and f2) to a folder in the root directory + zip_files([f1, f2], zip_folder_name, root_dir) if __name__ == "__main__": main() \ No newline at end of file From 9f332c7e106cceb4133547bddecad96d88e83c5a Mon Sep 17 00:00:00 2001 From: coleherman43 Date: Mon, 17 Aug 2026 15:27:37 -0700 Subject: [PATCH 4/5] More comments, zip mode set to create --- zip_files.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/zip_files.py b/zip_files.py index d22ec7c..cd1826d 100644 --- a/zip_files.py +++ b/zip_files.py @@ -24,16 +24,22 @@ def zip_files(csv_and_metadata_files: list[Path], name: str, root_dir: Path) -> if not name.endswith(".zip"): name += ".zip" - # Make output path and get file list + # Make output path output_path = root_dir / name + + # Get file list before zipping so we can count progress all_files = collect_files(csv_and_metadata_files) total = len(all_files) # Zip the files into chosen location - with zipfile.ZipFile(output_path, "w") as zipf: - for idx, file in enumerate(all_files, start=1): - print(f"Zipping {idx}/{total}: {file}") - zipf.write(file, arcname=file.relative_to(root_dir)) + try: + with zipfile.ZipFile(output_path, "x") as zipf: + for idx, file in enumerate(all_files, start=1): + print(f"Zipping {idx}/{total}: {file}") + zipf.write(file, arcname=file.relative_to(root_dir)) + except FileExistsError: + print(f"\nFailure: zip file already exists: {output_path}\n") + return print("Done") From 1534c7379d8b5d250c23833ad3daccff89c21784 Mon Sep 17 00:00:00 2001 From: coleherman43 Date: Fri, 4 Sep 2026 13:41:55 -0700 Subject: [PATCH 5/5] Clarifying module comment --- zip_files.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zip_files.py b/zip_files.py index cd1826d..a95de16 100644 --- a/zip_files.py +++ b/zip_files.py @@ -1,4 +1,4 @@ -"""Automatically zip files/ and metadata csv""" +"""Automatically zip files/ and metadata csv (and only these two values) from the filepaths.yaml""" import yaml import zipfile from pathlib import Path