# processors/cleaner.py import os import zipfile import rarfile import tempfile import shutil from core.constants import TRASH_FILES from processors.validator import validate_comic class CleanResult: def __init__(self, original_path): self.original_path = original_path self.cleaned_path = None self.removed_files = [] self.repacked = False def __str__(self): msg = f"Limpieza de: {self.original_path}\n" msg += f" Archivos eliminados: {len(self.removed_files)}\n" msg += f" Resultado final: {self.cleaned_path}\n" return msg def clean_comic(path): validation = validate_comic(path) if validation.errors: raise Exception(f"Archivo corrupto: {path}") real = validation.real_format # Abrir según formato real archive = zipfile.ZipFile(path, "r") if real == "zip" else rarfile.RarFile(path, "r") temp_dir = tempfile.mkdtemp() archive.extractall(temp_dir) archive.close() removed = [] for root, _, files in os.walk(temp_dir): 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, temp_dir)) # Si no se eliminó nada → no reconstruir if not removed: shutil.rmtree(temp_dir) result = CleanResult(path) result.cleaned_path = path return result # Reconstruir como CBZ base, _ = os.path.splitext(path) final_path = base + ".cbz" with zipfile.ZipFile(final_path, "w", zipfile.ZIP_DEFLATED) as new_zip: for root, _, files in os.walk(temp_dir): for f in files: full = os.path.join(root, f) rel = os.path.relpath(full, temp_dir) new_zip.write(full, rel) shutil.rmtree(temp_dir) # Mover original a backup from core.backup import move_to_backup move_to_backup(path) result = CleanResult(path) result.cleaned_path = final_path result.removed_files = removed result.repacked = True return result