# processors/cleaner.py import os import shutil from core.constants import TRASH_FILES, IMAGE_EXTENSIONS, FOREIGN_ALLOWED from core.result import StepResult def clean_directory(work_dir: str) -> StepResult: """ Elimina TRASH_FILES del directorio ya extraído. Elimina tanto ficheros como directorios de basura (e.g. __MACOSX). Sin I/O de archivo de cómic; trabaja sobre el directorio temporal. """ removed = [] for root, dirs, files in os.walk(work_dir, topdown=False): for f in files: if f.lower() in TRASH_FILES: full = os.path.join(root, f) os.remove(full) removed.append(os.path.relpath(full, work_dir)) elif os.path.splitext(f)[1].lower() not in IMAGE_EXTENSIONS \ and f.lower() not in FOREIGN_ALLOWED: full = os.path.join(root, f) os.remove(full) removed.append(os.path.relpath(full, work_dir)) for d in dirs: if d.lower() in TRASH_FILES: full = os.path.join(root, d) shutil.rmtree(full, ignore_errors=True) removed.append(os.path.relpath(full, work_dir) + "/") # Eliminar subdirectorios que hayan quedado vacíos for root, dirs, files in os.walk(work_dir, topdown=False): if root == work_dir: continue if not os.listdir(root): os.rmdir(root) removed.append(os.path.relpath(root, work_dir) + "/") details = [f"Eliminado: {r}" for r in removed] return StepResult( step="clean", changed=bool(removed), details=details, ) def flatten_directory(work_dir: str) -> StepResult: """ Mueve imágenes de un único subdirectorio a la raíz de work_dir. Precondición: solo existe 1 subdir con imágenes (validado antes de llamar). """ moved = [] for entry in os.listdir(work_dir): subdir = os.path.join(work_dir, entry) if not os.path.isdir(subdir): continue for root, _dirs, files in os.walk(subdir): for f in files: src = os.path.join(root, f) dst = os.path.join(work_dir, f) if os.path.exists(dst): base, ext = os.path.splitext(f) counter = 1 while os.path.exists(dst): dst = os.path.join(work_dir, f"{base}_{counter}{ext}") counter += 1 shutil.move(src, dst) moved.append(f) shutil.rmtree(subdir, ignore_errors=True) details = [f"Aplanado: {f}" for f in moved] return StepResult(step="flatten", changed=bool(moved), details=details)