diff --git a/README.md b/README.md index c594d7a..f1486c5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,84 @@ # comic_manager -Utilitat per a escanejar i reparar coleccions de comics \ No newline at end of file +CLI para escanear y reparar colecciones de cómics en formato CBR/CBZ. + +## Instalación + +```bash +python -m venv .venv +source .venv/bin/activate +pip install -r requirements.txt +# Dependencia de sistema para leer archivos RAR: +sudo apt install unrar +``` + +## Uso + +```bash +python main.py --ruta [opciones] +``` + +`--ruta` es obligatorio. Se puede combinar con uno o más flags de operación. + +--- + +## Opciones de inspección + +| Flag | Descripción | +|------|-------------| +| `--listar` | Lista todos los ficheros CBR/CBZ encontrados bajo `--ruta`. | +| `--validar` | Valida cada cómic: detecta extensión incorrecta, ficheros basura, páginas mal numeradas, imágenes de formatos mezclados y ausencia de `ComicInfo.xml`. Solo muestra los cómics con problemas. | + +--- + +## Operaciones + +Modifican los ficheros directamente. Se pueden combinar entre sí. + +Las operaciones que tocan el contenido del archivo piden confirmación por defecto, mostrando una preview de los cambios antes de aplicarlos. Usa `--no-preguntar` para desactivar este comportamiento. + +| Flag | Descripción | Pide confirmación | +|------|-------------|-------------------| +| `--limpiar` | Elimina ficheros basura (`thumbs.db`, `.ds_store`, `__MACOSX`, `desktop.ini`) y reempaqueta como CBZ. | Sí | +| `--convertir` | Convierte al formato indicado por `--formato` (por defecto CBZ). | No | +| `--estandarizar` | Equivale a `--limpiar` + `--convertir` en secuencia. | Solo para limpieza | +| `--renumerar` | Renombra las páginas a numeración secuencial con zero-padding (`001.jpg`, `002.jpg`…). | Sí | +| `--uniformizar-imagenes` | Convierte todas las imágenes al formato indicado por `--formato-imagen`. | Sí | + +### Opciones de formato + +| Flag | Valores | Por defecto | Descripción | +|------|---------|-------------|-------------| +| `--formato` | `cbz`, `cbr` | `cbz` | Formato de archivo destino para `--convertir` y `--estandarizar`. | +| `--formato-imagen` | `jpg`, `png`, `webp` | `png` | Formato de imagen destino para `--uniformizar-imagenes`. | +| `--no-preguntar` | — | — | Desactiva la confirmación interactiva: aplica todas las operaciones automáticamente. | + +--- + +## Ejemplos + +```bash +# Ver qué cómics hay en la colección +python main.py --ruta ~/Comics --listar + +# Revisar problemas sin modificar nada +python main.py --ruta ~/Comics --validar + +# Limpiar basura (pide confirmación por cada cómic) +python main.py --ruta ~/Comics --limpiar + +# Limpiar basura sin preguntar (modo automático) +python main.py --ruta ~/Comics --limpiar --no-preguntar + +# Limpiar y convertir todo a CBZ (pide confirmación para la limpieza) +python main.py --ruta ~/Comics --estandarizar + +# Convertir todo a CBZ sin confirmación +python main.py --ruta ~/Comics --convertir + +# Renumerar páginas de todos los cómics (pide confirmación) +python main.py --ruta ~/Comics --renumerar + +# Convertir imágenes a WebP (pide confirmación) +python main.py --ruta ~/Comics --uniformizar-imagenes --formato-imagen webp +``` diff --git a/main.py b/main.py index 41e9cfa..e5984ab 100644 --- a/main.py +++ b/main.py @@ -41,12 +41,11 @@ def _print_preview(step: str, preview: dict, formato: str) -> None: print(f" {orig:<{_COL_W}} {final}") print(f"Formato final del archivo: {fmt}") - elif step == "convert": - print(f"Conversión de formato de archivo a {preview['target_format']}.") - def make_confirm_fn(args): def confirm_fn(step: str, preview: dict) -> bool: + if step == "convert": + return True # No destructivo, no necesita confirmación print() _print_preview(step, preview, args.formato) answer = input("¿Aplicar? [s/N] ").strip().lower() @@ -68,11 +67,6 @@ def parse_args(): parser.add_argument("--uniformizar-imagenes", action="store_true") parser.add_argument("--formato-imagen", choices=["jpg", "png", "webp"], default="png") - # Fix flags (interactivos) - parser.add_argument("--fix_remove_trash", action="store_true") - parser.add_argument("--fix_page_numbering", action="store_true") - parser.add_argument("--fix_image_extensions", action="store_true") - parser.add_argument("--fix_all", action="store_true") parser.add_argument("--no-preguntar", action="store_true") return parser.parse_args() @@ -96,29 +90,7 @@ def main(): print() return - # --- Fix flags (interactivos) --- - fix_steps = [] - if args.fix_remove_trash or args.fix_all: - fix_steps.append("clean") - if args.fix_page_numbering or args.fix_all: - fix_steps.append("normalize_pages") - if args.fix_image_extensions or args.fix_all: - fix_steps.append("normalize_images") - - if fix_steps: - confirm_fn = None if args.no_preguntar else make_confirm_fn(args) - pipeline = Pipeline( - steps=fix_steps, - desired_format=args.formato, - desired_image_format="." + args.formato_imagen, - ) - for f in comic_files: - print(f"\n=== {f} ===") - result = pipeline.run(f, confirm_fn=confirm_fn) - print(result.summary()) - return - - # --- Flags clásicos (sin confirmación) --- + # --- Construir steps --- steps = [] if args.limpiar or args.estandarizar: steps.append("clean") @@ -130,13 +102,15 @@ def main(): steps.append("convert") if steps: + confirm_fn = None if args.no_preguntar else make_confirm_fn(args) pipeline = Pipeline( steps=steps, desired_format=args.formato, desired_image_format="." + args.formato_imagen, ) for f in comic_files: - result = pipeline.run(f) + print(f"\n=== {f} ===") + result = pipeline.run(f, confirm_fn=confirm_fn) print(result.summary())