normalizar-case
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
# core/constants.py
|
||||
|
||||
IMAGE_EXTENSIONS = {".jpg", ".jpeg", ".png", ".webp"}
|
||||
IMAGE_EXTENSIONS = {".jpg", ".jpeg", ".png", ".webp", ".gif"}
|
||||
|
||||
TRASH_FILES = {
|
||||
"thumbs.db",
|
||||
|
||||
@@ -20,6 +20,7 @@ from processors.checks import (
|
||||
check_comicinfo,
|
||||
check_foreign,
|
||||
check_nested,
|
||||
check_extension_case,
|
||||
)
|
||||
from processors.page_normalizer import normalize_pages, preview_normalize_pages
|
||||
from processors.image_normalizer import (
|
||||
@@ -28,6 +29,7 @@ from processors.image_normalizer import (
|
||||
uniformize_images,
|
||||
preview_uniformize_images,
|
||||
)
|
||||
from processors.case_normalizer import normalize_case, preview_normalize_case
|
||||
|
||||
|
||||
class Pipeline:
|
||||
@@ -38,12 +40,14 @@ class Pipeline:
|
||||
desired_image_format: str = ".jpg",
|
||||
collision_policy: str = CollisionPolicy.ABORT,
|
||||
dry_run: bool = False,
|
||||
case_mode: str = "lower",
|
||||
):
|
||||
self.steps = steps
|
||||
self.desired_format = desired_format
|
||||
self.desired_image_format = desired_image_format
|
||||
self.collision_policy = collision_policy
|
||||
self.dry_run = dry_run
|
||||
self.case_mode = case_mode
|
||||
|
||||
def _compute_preview(self, step: str, temp_dir: str, step_results: list) -> dict:
|
||||
if step == "clean":
|
||||
@@ -82,6 +86,10 @@ class Pipeline:
|
||||
conversions = preview_normalize_images(temp_dir, self.desired_image_format)
|
||||
return {"conversions": conversions, "target_ext": self.desired_image_format}
|
||||
|
||||
elif step == "normalize_case":
|
||||
renames = preview_normalize_case(temp_dir, self.case_mode)
|
||||
return {"renames": renames, "mode": self.case_mode}
|
||||
|
||||
elif step == "convert":
|
||||
return {"target_format": self.desired_format.upper()}
|
||||
|
||||
@@ -91,6 +99,10 @@ class Pipeline:
|
||||
for step in self.steps:
|
||||
if step in ("normalize_pages", "normalize_images", "convert_images"):
|
||||
return True
|
||||
if step == "normalize_case":
|
||||
case_r = next((r for r in step_results if r.step == "check_extension_case"), None)
|
||||
if case_r and case_r.warnings:
|
||||
return True
|
||||
if step == "convert":
|
||||
if needs_conversion(real_format, self.desired_format):
|
||||
return True
|
||||
@@ -134,8 +146,34 @@ class Pipeline:
|
||||
check_comicinfo(names),
|
||||
check_foreign(names),
|
||||
check_nested(names),
|
||||
check_extension_case(names, self.case_mode),
|
||||
]
|
||||
|
||||
# 3b. Corrección del case de la extensión exterior (renombrado en-sitio, sin repack)
|
||||
if "normalize_case" in self.steps:
|
||||
outer_ext = os.path.splitext(path)[1]
|
||||
target_outer_ext = outer_ext.lower() if self.case_mode == "lower" else outer_ext.upper()
|
||||
if outer_ext != target_outer_ext:
|
||||
base_no_ext = os.path.splitext(path)[0]
|
||||
new_outer_path = base_no_ext + target_outer_ext
|
||||
try:
|
||||
safe_outer = resolve_collision(new_outer_path, self.collision_policy)
|
||||
if not self.dry_run:
|
||||
os.rename(path, safe_outer)
|
||||
path = safe_outer
|
||||
step_results.append(StepResult(
|
||||
step="normalize_case_outer",
|
||||
changed=True,
|
||||
details=[f"Extensión exterior corregida: {outer_ext} → {target_outer_ext}"],
|
||||
))
|
||||
except (FileExistsError, OSError) as exc:
|
||||
step_results.append(StepResult(
|
||||
step="normalize_case_outer",
|
||||
changed=False,
|
||||
errors=[str(exc)],
|
||||
))
|
||||
return ComicResult(original_path=path, final_path=None, steps=step_results)
|
||||
|
||||
# 4. Pre-flight: si ningún step necesita extracción, salir sin tocar el archivo
|
||||
if not self._needs_extraction(step_results, real_format, path):
|
||||
return ComicResult(original_path=path, final_path=path, steps=step_results)
|
||||
@@ -198,6 +236,15 @@ class Pipeline:
|
||||
if img_result.changed:
|
||||
any_changed = True
|
||||
|
||||
if "normalize_case" in self.steps:
|
||||
preview = self._compute_preview("normalize_case", temp_dir, step_results)
|
||||
if preview.get("renames"):
|
||||
if confirm_fn is None or confirm_fn("normalize_case", preview):
|
||||
case_result = normalize_case(temp_dir, self.case_mode)
|
||||
step_results.append(case_result)
|
||||
if case_result.changed:
|
||||
any_changed = True
|
||||
|
||||
if "convert" in self.steps:
|
||||
preview = self._compute_preview("convert", temp_dir, step_results)
|
||||
if confirm_fn is None or confirm_fn("convert", preview):
|
||||
|
||||
@@ -58,6 +58,7 @@ class SummaryCollector:
|
||||
pages_normalized = count_step(["normalize_pages"])
|
||||
images_converted = count_step(["normalize_images", "convert_images"])
|
||||
format_converted = count_step(["convert"])
|
||||
case_normalized = count_step(["normalize_case", "normalize_case_outer"])
|
||||
|
||||
lines = [
|
||||
_BORDER,
|
||||
@@ -76,6 +77,8 @@ class SummaryCollector:
|
||||
lines.append(f" · Imágenes convertidas : {images_converted:>3}")
|
||||
if format_converted:
|
||||
lines.append(f" · Formato convertido : {format_converted:>3}")
|
||||
if case_normalized:
|
||||
lines.append(f" · Case normalizado : {case_normalized:>3}")
|
||||
lines.append(f" Advertencias : {len(warnings_only):>3}")
|
||||
lines.append(f" Errores : {len(errors):>3}")
|
||||
if errors:
|
||||
@@ -137,6 +140,7 @@ class SummaryCollector:
|
||||
("Numeración de páginas", "check_page_numbering", lambda w: True, ["normalize_pages"], "renumerado"),
|
||||
("Imágenes mezcladas", "check_image_extensions", lambda w: True, ["normalize_images", "convert_images"], "normalizado"),
|
||||
("Sin ComicInfo.xml", "check_comicinfo", lambda w: True, [], None),
|
||||
("Case de extensión", "check_extension_case", lambda w: True, ["normalize_case"], "normalizado"),
|
||||
]
|
||||
output = []
|
||||
for label, step_name, predicate, resolver_steps, fix_label in categories:
|
||||
|
||||
Reference in New Issue
Block a user