feat: initial live.f12.rocks SFTP → gmic/rembg → web pipeline
Event pep stack with SFTPGo inbox, sequential worker, FastAPI gallery/remix, and Traefik-ready compose. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
"""Remix: create one additional variant for an existing job, using the
|
||||
cached original + rembg output and user-chosen filters/blends/opacity."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from . import pipeline
|
||||
from .pipeline import FilterAssets, JobPaths, PipelineError
|
||||
|
||||
|
||||
@dataclass
|
||||
class RemixChoice:
|
||||
bg_filter: str
|
||||
bg_blend: str
|
||||
fg_filter: str
|
||||
fg_blend: str
|
||||
opacity: str
|
||||
|
||||
|
||||
def build_remix_options(assets: FilterAssets) -> dict[str, list[str]]:
|
||||
return {
|
||||
"background_filters": sorted(assets.background_names),
|
||||
"foreground_filters": sorted(assets.foreground_names),
|
||||
"blend_modes": sorted(assets.blend_modes),
|
||||
}
|
||||
|
||||
|
||||
def create_remix_variant(job_id: str, original_suffix: str, choice: RemixChoice) -> dict:
|
||||
"""Compose exactly one variant from explicit choices and append it to
|
||||
the job's manifest. Raises PipelineError on failure (caller should show
|
||||
it to the user, no half-written manifest entries are ever created)."""
|
||||
paths: JobPaths = pipeline.job_paths(job_id, original_suffix)
|
||||
if not paths.original.exists() or not paths.rembg.exists():
|
||||
raise PipelineError("Original oder Rembg-Bild fehlt fuer diesen Job — Remix nicht moeglich.")
|
||||
|
||||
assets = pipeline.load_assets()
|
||||
if choice.bg_filter not in assets.commands:
|
||||
raise PipelineError(f"Unbekannter Background-Filter: {choice.bg_filter}")
|
||||
if choice.fg_filter not in assets.commands:
|
||||
raise PipelineError(f"Unbekannter Foreground-Filter: {choice.fg_filter}")
|
||||
if choice.bg_blend not in assets.blend_modes or choice.fg_blend not in assets.blend_modes:
|
||||
raise PipelineError("Unbekannter Blend-Modus.")
|
||||
|
||||
manifest = pipeline.read_manifest(job_id) or {
|
||||
"job_id": job_id,
|
||||
"original_file": paths.original.name,
|
||||
"rembg_file": paths.rembg.name,
|
||||
"created_at": pipeline.now_iso(),
|
||||
"variants": [],
|
||||
}
|
||||
variant_id = pipeline.next_variant_id(manifest)
|
||||
|
||||
entry = pipeline.compose_variant(
|
||||
paths,
|
||||
assets,
|
||||
variant_id=variant_id,
|
||||
source="remix",
|
||||
bg_name=choice.bg_filter,
|
||||
bg_mode=choice.bg_blend,
|
||||
fg_name=choice.fg_filter,
|
||||
fg_mode=choice.fg_blend,
|
||||
opacity=choice.opacity,
|
||||
)
|
||||
manifest["variants"].append(entry)
|
||||
pipeline.write_manifest(paths, manifest)
|
||||
return entry
|
||||
Reference in New Issue
Block a user