From 7808b16946ccf781aee7334d1bf3c30f50c3a846 Mon Sep 17 00:00:00 2001 From: Claus Lohmar Date: Tue, 21 Jul 2026 18:58:13 +0000 Subject: [PATCH] fix: prevent double-nested directory on archive extraction Archives like 64bit.7z that already contain a 64bit/ top-level dir were extracted into STAGING_IN/64bit/, creating 64bit/64bit/ nesting. Now extract into STAGING_IN root, then: - If the archive produced a single dir matching the stem, use it - Otherwise, collect scattered files into a stem-named subdirectory Removes the need for nested path: 64bit/Debian.vmdk instead of 64bit/64bit/Debian.vmdk --- backend/converter.py | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/backend/converter.py b/backend/converter.py index 3ec0e78..2a5b1f1 100644 --- a/backend/converter.py +++ b/backend/converter.py @@ -75,13 +75,34 @@ def extract_if_needed(filename: str) -> Path: if stem.endswith(e): stem = stem[:-len(e)] break - out_dir = STAGING_IN / stem - out_dir.mkdir(parents=True, exist_ok=True) - result = subprocess.run(cmd, cwd=str(out_dir), capture_output=True, text=True, timeout=600) + # Snapshot STAGING_IN before extraction + before = set(STAGING_IN.iterdir()) if STAGING_IN.exists() else set() + + # Extract into STAGING_IN root (not a subdir) to avoid double nesting + # when the archive already has a top-level directory + result = subprocess.run(cmd, cwd=str(STAGING_IN), capture_output=True, text=True, timeout=600) if result.returncode != 0: raise RuntimeError(f"{tool} failed: {result.stderr.strip()[:500]}") + # Determine what was created + after = set(STAGING_IN.iterdir()) + new_items = after - before + + # If the archive had a single top-level directory matching the stem, use it + expected_dir = STAGING_IN / stem + if expected_dir in new_items and expected_dir.is_dir(): + return expected_dir + + # Otherwise, collect scattered files into a subdirectory + out_dir = STAGING_IN / stem + out_dir.mkdir(parents=True, exist_ok=True) + for item in new_items: + dest = out_dir / item.name + if item.is_dir(): + shutil.move(str(item), str(dest)) + else: + shutil.move(str(item), str(dest)) return out_dir