Remove empty directories after moving files
This commit is contained in:
+54
-1
@@ -378,6 +378,19 @@ def determine_working_dir(args: list[str]) -> Path:
|
||||
return common
|
||||
|
||||
|
||||
def cleanup_roots_from_args(args: list[str]) -> list[Path]:
|
||||
roots: list[Path] = []
|
||||
seen: set[Path] = set()
|
||||
for arg in args:
|
||||
path = Path(arg).expanduser()
|
||||
if path.is_dir():
|
||||
resolved = path.resolve()
|
||||
if resolved not in seen:
|
||||
seen.add(resolved)
|
||||
roots.append(resolved)
|
||||
return roots
|
||||
|
||||
|
||||
def require_exiftool() -> str:
|
||||
executable = which("exiftool")
|
||||
if executable:
|
||||
@@ -1151,7 +1164,35 @@ def unique_existing_target(path: Path, planned_sources: set[Path]) -> Path:
|
||||
raise RuntimeError(f"Could not find available target name for {path}")
|
||||
|
||||
|
||||
def apply_changes(executable: str, records: list[MediaRecord], choices: UserChoices) -> list[str]:
|
||||
def remove_empty_dirs(cleanup_roots: list[Path], keep_dirs: set[Path]) -> list[Path]:
|
||||
removed: list[Path] = []
|
||||
candidates: set[Path] = set()
|
||||
for root in cleanup_roots:
|
||||
if not root.exists() or not root.is_dir():
|
||||
continue
|
||||
for directory, subdirs, _files in os.walk(root, topdown=False):
|
||||
path = Path(directory).resolve()
|
||||
candidates.add(path)
|
||||
for subdir in subdirs:
|
||||
child = (Path(directory) / subdir).resolve()
|
||||
if child.exists() and child.is_dir():
|
||||
candidates.add(child)
|
||||
|
||||
for directory in sorted(candidates, key=lambda path: len(path.parts), reverse=True):
|
||||
if directory in keep_dirs:
|
||||
continue
|
||||
try:
|
||||
directory.rmdir()
|
||||
removed.append(directory)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
return removed
|
||||
|
||||
|
||||
def apply_changes(
|
||||
executable: str, records: list[MediaRecord], choices: UserChoices
|
||||
) -> list[str]:
|
||||
failures: list[str] = []
|
||||
planned_sources = {record.path.resolve() for record in records}
|
||||
|
||||
@@ -1178,6 +1219,14 @@ def apply_changes(executable: str, records: list[MediaRecord], choices: UserChoi
|
||||
return failures
|
||||
|
||||
|
||||
def print_removed_dirs(removed_dirs: list[Path]) -> None:
|
||||
if not removed_dirs:
|
||||
return
|
||||
print("\nRemoved empty director" + ("y:" if len(removed_dirs) == 1 else "ies:"))
|
||||
for directory in removed_dirs:
|
||||
print(f" - {directory}")
|
||||
|
||||
|
||||
def prepare_plan(records: list[MediaRecord], choices: UserChoices) -> list[list[MediaRecord]]:
|
||||
apply_time_offset(records, choices.time_offset)
|
||||
|
||||
@@ -1213,6 +1262,7 @@ def run(argv: list[str]) -> int:
|
||||
print(exc)
|
||||
return 1
|
||||
|
||||
cleanup_roots = cleanup_roots_from_args(argv[1:])
|
||||
files = collect_media_files(argv[1:])
|
||||
if not files:
|
||||
print("No supported media files found.")
|
||||
@@ -1252,6 +1302,9 @@ def run(argv: list[str]) -> int:
|
||||
return 0
|
||||
|
||||
failures = apply_changes(exiftool, records, choices)
|
||||
removed_dirs = remove_empty_dirs(cleanup_roots, keep_dirs={working_dir.resolve()})
|
||||
print_removed_dirs(removed_dirs)
|
||||
|
||||
if failures:
|
||||
print("\nSome files failed:")
|
||||
for failure in failures:
|
||||
|
||||
Reference in New Issue
Block a user