feat: unify source libraries, generation plans and terminal bindings
Community checks / verify (push) Skipped
Verify Frame Flow / verify (push) Failing after 6m24s

This commit is contained in:
渡口浪人
2026-10-23 17:45:30 +08:00
parent 081d8b6ee0
commit 6277c9d563
25 changed files with 5731 additions and 45 deletions
+57 -4
View File
@@ -15,6 +15,7 @@ from pigway_frame_flow.models import (
ImageContent,
JobInput,
Options,
PhotoSourceContent,
PlaylistInput,
RestoreContent,
)
@@ -86,17 +87,64 @@ class Scheduler:
row["last_result"] = operation["status"]
return rows
def save_job(self, job, id=None):
self.service.registry.get(job.device_id)
def validate_job(self, job):
if not job.library_pipeline:
self.service.registry.get(job.device_id)
if job.library_pipeline and not self.db.one(
"SELECT terminal_id FROM terminal_bindings WHERE source_id=?",
(job.source.source_id,),
):
raise FlowError(
E.CONFLICT,
"Bind terminals to the source library before saving this task",
409,
{"reason": "libraryBindFirst"},
)
if job.generate_thumbnail:
from pigway_frame_flow.display.thumbnail_plans import get_plan
get_plan(self.service, job.thumbnail_plan_id)
if job.source.type != "restore":
if job.library_pipeline:
self.service.photo_sources.get(job.source.source_id)
elif job.source.type != "restore":
self.service.validate(
DisplayRequest(device_id=job.device_id, content=job.source),
writing=False,
)
def set_library_mode(self, job_id, enabled):
with self.service.lock:
row = self.db.one("SELECT payload FROM jobs WHERE id=?", (job_id,))
if not row:
raise FlowError(E.NOT_FOUND, "Job not found", 404)
values = json.loads(row["payload"])
if enabled and values.get("source", {}).get("type") != "photo_source":
raise FlowError(
E.INVALID_REQUEST,
"Only photo-source tasks support source-library mode",
422,
)
values["library_pipeline"] = enabled
if enabled:
values.update(
generate_thumbnail=False,
thumbnail_plan_id=None,
cleanup_unstarred=False,
)
job = JobInput.model_validate(values)
self.validate_job(job)
self.db.execute(
"UPDATE jobs SET payload=?,updated_at=? WHERE id=?",
(
encode(self.service.settings.sanitize(job.model_dump(mode="json"))),
now_iso(),
job_id,
),
)
return next(j for j in self.jobs() if j["id"] == job_id)
def save_job(self, job, id=None):
self.validate_job(job)
upcoming = next_run(job.schedule)
if job.enabled and upcoming is None:
raise FlowError(E.INVALID_REQUEST, "One-time task must be in the future")
@@ -192,6 +240,8 @@ class Scheduler:
),
).model_dump(mode="json")
)
if job.library_pipeline:
action = "library-generate"
if action == "display":
payload = self.upload_retries.scheduled_payload(
row["id"], payload
@@ -199,7 +249,10 @@ class Scheduler:
operation_id = self.service.submit(
action,
payload,
job.device_id,
("source:" + job.source.source_id)
if job.library_pipeline
and isinstance(job.source, PhotoSourceContent)
else job.device_id,
"scheduler",
"schedule-" + uuid4().hex,
"job-" + row["id"] + "-" + slot,