millores en el resum del final
el resum del final ix sempre, inclus despres de fer control-c Millores en presentació per pantalla
This commit is contained in:
+67
-1
@@ -1,5 +1,8 @@
|
|||||||
# core/summary.py
|
# core/summary.py
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import os
|
||||||
|
|
||||||
from core.result import ComicResult
|
from core.result import ComicResult
|
||||||
|
|
||||||
_CORRUPT_PATTERNS = ("BadRarFile", "BadZipFile", "corrupto", "Failed to read")
|
_CORRUPT_PATTERNS = ("BadRarFile", "BadZipFile", "corrupto", "Failed to read")
|
||||||
@@ -21,7 +24,7 @@ class SummaryCollector:
|
|||||||
for pattern in _CORRUPT_PATTERNS
|
for pattern in _CORRUPT_PATTERNS
|
||||||
)
|
)
|
||||||
|
|
||||||
def render(self) -> str:
|
def render(self, _max=10) -> str:
|
||||||
results = self._results
|
results = self._results
|
||||||
total = len(results)
|
total = len(results)
|
||||||
if total == 0:
|
if total == 0:
|
||||||
@@ -93,4 +96,67 @@ class SummaryCollector:
|
|||||||
all_errs = [e for s in r.steps for e in s.errors]
|
all_errs = [e for s in r.steps for e in s.errors]
|
||||||
lines.append(f" {r.original_path} — {'; '.join(all_errs)}")
|
lines.append(f" {r.original_path} — {'; '.join(all_errs)}")
|
||||||
|
|
||||||
|
warn_categories = self._warning_categories(results)
|
||||||
|
if warn_categories:
|
||||||
|
lines.append("")
|
||||||
|
lines.append("Advertencias por categoría:")
|
||||||
|
for label, entries in warn_categories:
|
||||||
|
lines.append(f"\n {label} ({len(entries)}):")
|
||||||
|
shown = entries[:_max] if _max is not None else entries
|
||||||
|
for path, msg, annotation in shown:
|
||||||
|
suffix = f" ({annotation})" if annotation else ""
|
||||||
|
if msg:
|
||||||
|
lines.append(f" {path} — {msg}{suffix}")
|
||||||
|
else:
|
||||||
|
lines.append(f" {path}{suffix}")
|
||||||
|
if _max is not None and len(entries) > _max:
|
||||||
|
lines.append(f" ... y {len(entries) - _max} más")
|
||||||
|
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
def full_log(self) -> str:
|
||||||
|
parts = [self.render(_max=None)]
|
||||||
|
issues = [r for r in self._results if r.has_issues()]
|
||||||
|
if issues:
|
||||||
|
parts.append("")
|
||||||
|
parts.append("")
|
||||||
|
parts.append("Detalle por fichero:")
|
||||||
|
parts.append(_BORDER)
|
||||||
|
for r in issues:
|
||||||
|
parts.append(r.full_report())
|
||||||
|
parts.append("")
|
||||||
|
return "\n".join(parts)
|
||||||
|
|
||||||
|
def _warning_categories(self, results):
|
||||||
|
categories = [
|
||||||
|
("Extensión incorrecta", "validate", lambda w: "Extensión incorrecta" in w, ["convert"], "convertido"),
|
||||||
|
("Basura detectada", "check_trash", lambda w: True, ["clean"], "limpiado"),
|
||||||
|
("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),
|
||||||
|
]
|
||||||
|
output = []
|
||||||
|
for label, step_name, predicate, resolver_steps, fix_label in categories:
|
||||||
|
entries = []
|
||||||
|
for r in results:
|
||||||
|
msgs = [
|
||||||
|
w for s in r.steps
|
||||||
|
if s.step == step_name
|
||||||
|
for w in s.warnings
|
||||||
|
if predicate(w)
|
||||||
|
]
|
||||||
|
if msgs:
|
||||||
|
resolved = bool(resolver_steps) and any(
|
||||||
|
s.step in resolver_steps and s.changed for s in r.steps
|
||||||
|
)
|
||||||
|
annotation = fix_label if resolved else ""
|
||||||
|
if step_name == "check_comicinfo":
|
||||||
|
entries.append((r.original_path, "", annotation))
|
||||||
|
elif step_name == "check_trash":
|
||||||
|
items = [w.removeprefix("Basura detectada: ") for w in msgs]
|
||||||
|
entries.append((r.original_path, ", ".join(items), annotation))
|
||||||
|
else:
|
||||||
|
entries.append((r.original_path, msgs[0], annotation))
|
||||||
|
if entries:
|
||||||
|
output.append((label, entries))
|
||||||
|
return output
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
# main.py
|
# main.py
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import datetime
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
from core.scanner import find_comic_files
|
from core.scanner import find_comic_files
|
||||||
from core.pipeline import Pipeline
|
from core.pipeline import Pipeline
|
||||||
from core.summary import SummaryCollector
|
from core.summary import SummaryCollector
|
||||||
@@ -8,6 +11,26 @@ from core.collision import CollisionPolicy
|
|||||||
|
|
||||||
_COL_W = 30
|
_COL_W = 30
|
||||||
_SEP = "─" * 44
|
_SEP = "─" * 44
|
||||||
|
_BOLD = "\033[1m"
|
||||||
|
_DIM = "\033[2m"
|
||||||
|
_RST = "\033[0m"
|
||||||
|
|
||||||
|
|
||||||
|
def _human_size(size: int) -> str:
|
||||||
|
if size >= 1_073_741_824:
|
||||||
|
return f"{size / 1_073_741_824:.1f} GB"
|
||||||
|
if size >= 1_048_576:
|
||||||
|
return f"{size / 1_048_576:.1f} MB"
|
||||||
|
return f"{size / 1024:.1f} KB"
|
||||||
|
|
||||||
|
|
||||||
|
def _print_file_header(path: str, i: int = 0, total: int = 0) -> None:
|
||||||
|
name = os.path.basename(path)
|
||||||
|
size_str = _human_size(os.path.getsize(path))
|
||||||
|
counter = f"{_DIM}[{i}/{total}]{_RST} " if i and total else ""
|
||||||
|
term_w = shutil.get_terminal_size(fallback=(80, 24)).columns
|
||||||
|
print(f"\n{'─' * term_w}")
|
||||||
|
print(f" {counter}{_BOLD}{name}{_RST} {_DIM}({size_str}){_RST}")
|
||||||
|
|
||||||
|
|
||||||
def _print_preview(step: str, preview: dict, formato: str) -> None:
|
def _print_preview(step: str, preview: dict, formato: str) -> None:
|
||||||
@@ -44,6 +67,16 @@ def _print_preview(step: str, preview: dict, formato: str) -> None:
|
|||||||
print(f"Formato final del archivo: {fmt}")
|
print(f"Formato final del archivo: {fmt}")
|
||||||
|
|
||||||
|
|
||||||
|
def _save_log(collector, script_dir):
|
||||||
|
log_dir = os.path.join(script_dir, "validaciones")
|
||||||
|
os.makedirs(log_dir, exist_ok=True)
|
||||||
|
ts = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
log_path = os.path.join(log_dir, f"{ts}.log")
|
||||||
|
with open(log_path, "w", encoding="utf-8") as fh:
|
||||||
|
fh.write(collector.full_log())
|
||||||
|
return log_path
|
||||||
|
|
||||||
|
|
||||||
def make_confirm_fn(args):
|
def make_confirm_fn(args):
|
||||||
def confirm_fn(step: str, preview: dict) -> bool:
|
def confirm_fn(step: str, preview: dict) -> bool:
|
||||||
if step == "convert":
|
if step == "convert":
|
||||||
@@ -93,13 +126,24 @@ def main():
|
|||||||
if args.validar:
|
if args.validar:
|
||||||
pipeline = Pipeline(steps=[])
|
pipeline = Pipeline(steps=[])
|
||||||
collector = SummaryCollector()
|
collector = SummaryCollector()
|
||||||
for f in comic_files:
|
total = len(comic_files)
|
||||||
result = pipeline.run(f)
|
try:
|
||||||
collector.add(result)
|
for i, f in enumerate(comic_files, 1):
|
||||||
if result.has_issues():
|
size_str = _human_size(os.path.getsize(f))
|
||||||
print(result.full_report())
|
name = os.path.basename(f)
|
||||||
|
term_w = shutil.get_terminal_size(fallback=(80, 24)).columns
|
||||||
|
line = f" [{i}/{total}] {name} ({size_str})"
|
||||||
|
print(f"\r{line[:term_w]:<{term_w}}", end="", flush=True)
|
||||||
|
result = pipeline.run(f)
|
||||||
|
collector.add(result)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n (interrumpido)")
|
||||||
|
finally:
|
||||||
|
if collector._results:
|
||||||
print()
|
print()
|
||||||
print(collector.render())
|
print(collector.render())
|
||||||
|
log_path = _save_log(collector, os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
print(f" Log completo: {log_path}")
|
||||||
return
|
return
|
||||||
|
|
||||||
# --- Construir steps ---
|
# --- Construir steps ---
|
||||||
@@ -125,12 +169,20 @@ def main():
|
|||||||
collision_policy=collision,
|
collision_policy=collision,
|
||||||
)
|
)
|
||||||
collector = SummaryCollector()
|
collector = SummaryCollector()
|
||||||
for f in comic_files:
|
try:
|
||||||
print(f"\n=== {f} ===")
|
total = len(comic_files)
|
||||||
result = pipeline.run(f, confirm_fn=confirm_fn)
|
for i, f in enumerate(comic_files, 1):
|
||||||
print(result.summary())
|
_print_file_header(f, i, total)
|
||||||
collector.add(result)
|
result = pipeline.run(f, confirm_fn=confirm_fn)
|
||||||
print(f"\n{collector.render()}")
|
print(result.summary())
|
||||||
|
collector.add(result)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n (interrumpido)")
|
||||||
|
finally:
|
||||||
|
if collector._results:
|
||||||
|
print(f"\n{collector.render()}")
|
||||||
|
log_path = _save_log(collector, os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
print(f" Log completo: {log_path}")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
Reference in New Issue
Block a user