Files
imagepipeline/imagepipeline/core/resume.py
T
2026-06-21 10:26:10 +02:00

111 lines
3.1 KiB
Python

from __future__ import annotations
import json
import os
import shutil
from pathlib import Path
from imagepipeline.core.exceptions import StepError
from imagepipeline.core.step import StepDefinition
from imagepipeline.utils.files import is_image, list_images, stem_key
def expected_output_filenames(
step: StepDefinition,
*,
matched_groups: list[list[Path]],
input_paths: list[Path],
params: dict,
) -> list[str]:
if step.module_name == "composite":
output_ext = params.get("output_ext", ".png")
return [f"{group[-1].stem}{output_ext}" for group in matched_groups]
return [path.name for path in input_paths]
def expected_output_paths(
output_dir: Path,
step: StepDefinition,
*,
matched_groups: list[list[Path]],
input_paths: list[Path],
params: dict,
) -> list[Path]:
return [
output_dir / name
for name in expected_output_filenames(
step,
matched_groups=matched_groups,
input_paths=input_paths,
params=params,
)
]
def step_outputs_complete(expected_paths: list[Path]) -> bool:
return bool(expected_paths) and all(
path.is_file() and is_image(path) for path in expected_paths
)
def source_stems_for_step(
step: StepDefinition,
*,
matched_groups: list[list[Path]],
input_paths: list[Path],
) -> list[str]:
if step.module_name == "composite":
return [stem_key(group[-1]) for group in matched_groups]
return [stem_key(path) for path in input_paths]
def materialize_external_outputs(
external_dir: Path,
output_dir: Path,
step: StepDefinition,
*,
matched_groups: list[list[Path]],
input_paths: list[Path],
params: dict,
symlink: bool = True,
) -> list[Path]:
external_dir = external_dir.resolve()
if not external_dir.is_dir():
raise StepError(f"External output directory not found: {external_dir}")
external_by_stem = {stem_key(path): path for path in list_images(external_dir)}
output_names = expected_output_filenames(
step,
matched_groups=matched_groups,
input_paths=input_paths,
params=params,
)
stems = source_stems_for_step(
step,
matched_groups=matched_groups,
input_paths=input_paths,
)
output_dir.mkdir(parents=True, exist_ok=True)
output_paths: list[Path] = []
for output_name, stem in zip(output_names, stems, strict=True):
source = external_by_stem.get(stem)
if source is None:
raise StepError(
f"External output for step '{step.step_id}' is missing stem {stem!r} "
f"in {external_dir}"
)
destination = output_dir / output_name
if destination.exists() or destination.is_symlink():
destination.unlink()
if symlink:
os.symlink(source, destination)
else:
shutil.copy2(source, destination)
output_paths.append(destination)
return output_paths
def read_manifest(path: Path) -> dict:
return json.loads(path.read_text(encoding="utf-8"))