Files
imagepipeline/imagepipeline/core/log.py
T
Frank Schwenk a60a18a253 chore: add Ruff and apply formatting across codebase
Introduce ruff lint/format config, expand .gitignore, and reformat Python sources.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 17:34:14 +02:00

83 lines
2.6 KiB
Python

from __future__ import annotations
import sys
from typing import TextIO
def _format_eta(seconds: float) -> str:
seconds = max(0, int(seconds))
minutes, secs = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
if hours:
return f"{hours}h{minutes:02d}m"
if minutes:
return f"{minutes}m{secs:02d}s"
return f"{secs}s"
class PipelineLogger:
"""Simple stdout logger for pipeline progress."""
def __init__(self, *, verbose: bool = True, stream: TextIO | None = None) -> None:
self.verbose = verbose
self.stream = stream or sys.stdout
def info(self, message: str) -> None:
if self.verbose:
print(message, file=self.stream, flush=True)
def step_start(
self,
step_index: int,
step_total: int,
step_id: str,
module_name: str,
*,
inputs: list[str],
params: dict,
) -> None:
self.info(f"Step {step_index}/{step_total}: {step_id} ({module_name})")
self.info(f" inputs: {', '.join(inputs)}")
if params:
rendered = ", ".join(f"{key}={value!r}" for key, value in params.items())
self.info(f" params: {rendered}")
def image(self, module_name: str, index: int, total: int, filename: str) -> None:
self.info(f" Applying module {module_name} to image [{index}/{total}]: {filename}")
def skipped(self, module_name: str, index: int, total: int, filename: str) -> None:
self.info(f" Skipped module {module_name} [{index}/{total}] {filename} (output exists)")
def image_done(
self,
module_name: str,
index: int,
total: int,
filename: str,
elapsed: float,
*,
eta_seconds: float | None = None,
) -> None:
eta_part = ""
if eta_seconds is not None and eta_seconds > 0:
eta_part = f" (ETA ~{_format_eta(eta_seconds)})"
self.info(
f" Finished module {module_name} [{index}/{total}] {filename} "
f"in {elapsed:.1f}s{eta_part}"
)
def warning(self, message: str) -> None:
self.info(f" Warning: {message}")
def step_done(self, step_id: str, output_dir: str, count: int) -> None:
self.info(f" Done: {count} image(s) -> {output_dir}/")
def step_skipped(self, step_id: str, count: int) -> None:
self.info(f" Skipped step {step_id} ({count} existing output(s))")
def step_reused(self, step_id: str, source_dir: str, count: int) -> None:
self.info(f" Reused external output for {step_id}: {source_dir} ({count} file(s))")
def blank(self) -> None:
self.info("")