# processors/page_normalizer.py import os import re from core.constants import IMAGE_EXTENSIONS from core.result import StepResult def _natural_sort_key(name: str): parts = re.split(r"(\d+)", name) return [int(p) if p.isdigit() else p.lower() for p in parts] def preview_normalize_pages(work_dir: str) -> list[tuple[str, str]]: """Devuelve lista de (nombre_actual, nombre_final) sin modificar nada.""" images = [] for root, _, files in os.walk(work_dir): for f in files: ext = os.path.splitext(f)[1].lower() if ext in IMAGE_EXTENSIONS: images.append(os.path.join(root, f)) images.sort(key=lambda p: _natural_sort_key(os.path.splitext(os.path.basename(p))[0])) total = len(images) if total == 0: return [] width = len(str(total)) result = [] for i, src in enumerate(images): ext = os.path.splitext(src)[1].lower() original_name = os.path.basename(src) final_name = f"{str(i + 1).zfill(width)}{ext}" if original_name != final_name: result.append((original_name, final_name)) return result def normalize_pages(work_dir: str) -> StepResult: """ Renombra las imágenes del cómic a una numeración secuencial con zero-padding. Fase 1: renombra a nombres temporales para evitar colisiones. Fase 2: renombra a 001.ext, 002.ext… con ancho = len(str(total)). """ # Recopilar imágenes con natural sort images = [] for root, _, files in os.walk(work_dir): for f in files: ext = os.path.splitext(f)[1].lower() if ext in IMAGE_EXTENSIONS: images.append(os.path.join(root, f)) images.sort(key=lambda p: _natural_sort_key(os.path.splitext(os.path.basename(p))[0])) total = len(images) if total == 0: return StepResult(step="normalize_pages", changed=False) width = len(str(total)) # Fase 1: renombrar a temporales para evitar colisiones intermedias temp_paths = [] for i, src in enumerate(images): ext = os.path.splitext(src)[1].lower() tmp = os.path.join(os.path.dirname(src), f".tmp_rename_{i}{ext}") os.rename(src, tmp) temp_paths.append(tmp) # Fase 2: renombrar a nombre final changed = False details = [] for i, tmp in enumerate(temp_paths): ext = os.path.splitext(tmp)[1].lower() final_name = f"{str(i + 1).zfill(width)}{ext}" final_path = os.path.join(os.path.dirname(tmp), final_name) os.rename(tmp, final_path) original_name = os.path.basename(images[i]) if original_name != final_name: details.append(f"{original_name} → {final_name}") changed = True return StepResult(step="normalize_pages", changed=changed, details=details)