# processors/validator.py import os import zipfile import rarfile from core.constants import IMAGE_EXTENSIONS, TRASH_FILES IMAGE_EXTENSIONS = {".jpg", ".jpeg", ".png", ".webp"} TRASH_FILES = {"thumbs.db", ".ds_store"} class ValidationResult: def __init__(self, path): self.path = path self.is_valid = True self.errors = [] self.warnings = [] self.images = [] self.real_format = None # "rar", "zip", None def add_error(self, msg): self.is_valid = False self.errors.append(msg) def add_warning(self, msg): self.warnings.append(msg) def __str__(self): status = "OK" if self.is_valid else "ERROR" return f"[{status}] {self.path}" def try_open_rar(path): try: archive = rarfile.RarFile(path, "r") archive.namelist() # fuerza lectura return archive except: return None def try_open_zip(path): try: archive = zipfile.ZipFile(path, "r") archive.namelist() return archive except: return None def validate_comic(path): result = ValidationResult(path) ext = os.path.splitext(path)[1].lower() archive = None # 1) Intentar abrir como RAR if ext == ".cbr": archive = try_open_rar(path) if archive: result.real_format = "rar" else: # 2) Intentar abrir como ZIP (CBZ renombrado) archive = try_open_zip(path) if archive: result.real_format = "zip" result.add_warning("El archivo tiene extensión .cbr pero es un ZIP (CBZ renombrado)") else: result.add_error("No se pudo abrir como RAR ni como ZIP") return result # 3) Si es CBZ, abrir como ZIP elif ext == ".cbz": archive = try_open_zip(path) if archive: result.real_format = "zip" else: result.add_error("No se pudo abrir el archivo ZIP") return result else: result.add_error("Extensión no reconocida") return result # 4) Validar contenido file_list = archive.namelist() for f in file_list: name = f.lower() _, fext = os.path.splitext(name) if fext in IMAGE_EXTENSIONS: result.images.append(f) if os.path.basename(name) in TRASH_FILES: result.add_warning(f"Archivo basura encontrado: {f}") if not result.images: result.add_error("No contiene imágenes válidas") return result