Skip to content

Commit 684fa8b

Browse files
committed
Emulate unzip in Python
1 parent f061c68 commit 684fa8b

4 files changed

Lines changed: 49 additions & 5 deletions

File tree

tests/integration/Snakefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@ rule download_netherlands_shapes:
1616
rule download_netherlands_protected_areas:
1717
message:
1818
"Download and unzip a dummy drop-in dataset for Netherlands protected areas (not based on WDPA)."
19+
input:
20+
script=workflow.source_path("../../workflow/scripts/unzip_like.py"),
1921
output:
2022
zipfile="results/module_area_potentials/resources/user/wdpa.gdb.zip",
2123
wdpa=directory("results/module_area_potentials/resources/user/wdpa.gdb"),
2224
shell:
2325
"""
2426
curl -sSLo {output.zipfile} https://surfdrive.surf.nl/files/index.php/s/msuXQETNbCWawDh/download
25-
unzip {output.zipfile} -d results/module_area_potentials/resources/user/
27+
python {input.script} {output.zipfile} -t results/module_area_potentials/resources/user/
2628
"""
2729

2830

workflow/envs/shell.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ channels:
33
- conda-forge
44
- nodefaults
55
dependencies:
6+
- python=3.13
7+
- click=8.2.1
68
- curl=8.9.1

workflow/rules/automatic.smk

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ rule unzip_globcover:
4646
params:
4747
target_file=internal["resources"]["automatic"]["globcover_landcover_tif"],
4848
input:
49-
rules.download_globcover.output,
49+
script=workflow.source_path("../scripts/unzip_like.py"),
50+
zipfile=rules.download_globcover.output,
5051
output:
5152
"resources/automatic/global/globcover-landcover.tif",
5253
log:
@@ -56,7 +57,7 @@ rule unzip_globcover:
5657
shell:
5758
"""
5859
temp_dir=$(mktemp -d)
59-
unzip -j {input} {params.target_file} -d $temp_dir
60+
python {input.script} {input.zipfile} -f {params.target_file} -t $temp_dir
6061
mv $temp_dir/{params.target_file} {output}
6162
rm -R $temp_dir
6263
"""
@@ -81,15 +82,16 @@ rule unzip_ghsl:
8182
params:
8283
target_file=internal["resources"]["automatic"]["ghsl_tif"],
8384
input:
84-
rules.download_ghsl.output,
85+
script=workflow.source_path("../scripts/unzip_like.py"),
86+
zipfile=rules.download_ghsl.output,
8587
output:
8688
"resources/automatic/global/ghsl_built_s.tif",
8789
conda:
8890
"../envs/shell.yaml"
8991
shell:
9092
"""
9193
temp_dir=$(mktemp -d)
92-
unzip -j {input} {params.target_file} -d $temp_dir
94+
python {input.script} {input.zipfile} -f {params.target_file} -t $temp_dir
9395
mv $temp_dir/{params.target_file} {output}
9496
rm -R $temp_dir
9597
"""

workflow/scripts/unzip_like.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import os
2+
import zipfile
3+
4+
import click
5+
6+
7+
@click.command()
8+
@click.argument("zip_path", type=click.Path(exists=True))
9+
@click.option(
10+
"--target",
11+
"-t",
12+
type=click.Path(),
13+
default=".",
14+
help="Target directory to extract to.",
15+
)
16+
@click.option("--file", "-f", help="Specific file inside the zip to extract.")
17+
def unzip(zip_path, target, file):
18+
"""Emulates the `unzip` command across platforms.
19+
20+
ZIP_PATH: Path to the .zip file
21+
"""
22+
os.makedirs(target, exist_ok=True)
23+
24+
with zipfile.ZipFile(zip_path, "r") as zip_ref:
25+
if file:
26+
# Check if file exists in zip
27+
if file not in zip_ref.namelist():
28+
click.echo(f"Error: '{file}' not found in archive.")
29+
return
30+
zip_ref.extract(file, target)
31+
click.echo(f"Extracted '{file}' to '{target}'.")
32+
else:
33+
zip_ref.extractall(target)
34+
click.echo(f"Extracted all files to '{target}'.")
35+
36+
37+
if __name__ == "__main__":
38+
unzip()

0 commit comments

Comments
 (0)