feat: unify source libraries, generation plans and terminal bindings
This commit is contained in:
@@ -54,6 +54,9 @@ class DisplayService:
|
||||
self.cloud_library = CloudLibrary(self)
|
||||
self.recovery = RecoveryMonitor(self)
|
||||
self.upload_reconciliation = UploadReconciliation(self)
|
||||
from pigway_frame_flow.display.libraries import Libraries
|
||||
|
||||
self.libraries = Libraries(self)
|
||||
self.expiration_checked: dict[str, float] = {}
|
||||
self.unknown_checked: dict[str, float] = {}
|
||||
# A killed write cannot be replayed safely; pre-write work can resume.
|
||||
@@ -67,6 +70,14 @@ class DisplayService:
|
||||
|
||||
def validate(self, request, writing=True):
|
||||
self.registry.get(request.device_id)
|
||||
if (
|
||||
writing
|
||||
and isinstance(request.content, ImageContent)
|
||||
and request.content.asset_id
|
||||
):
|
||||
self.libraries.validate_asset_binding(
|
||||
request.device_id, request.content.asset_id
|
||||
)
|
||||
if request.options.thumbnail_plan_id:
|
||||
from pigway_frame_flow.display.thumbnail_plans import get_plan
|
||||
|
||||
@@ -120,7 +131,14 @@ class DisplayService:
|
||||
)
|
||||
return existing["operation_id"]
|
||||
if (
|
||||
action not in ("display", "render", "render-ai", "local-upload")
|
||||
action
|
||||
not in (
|
||||
"display",
|
||||
"render",
|
||||
"render-ai",
|
||||
"local-upload",
|
||||
"library-generate",
|
||||
)
|
||||
and tx.execute(
|
||||
"SELECT id FROM operations WHERE device_id=? AND status='UNKNOWN' AND write_started=1 AND action!='render-ai' LIMIT 1",
|
||||
(device_id,),
|
||||
@@ -281,6 +299,8 @@ class DisplayService:
|
||||
*,
|
||||
staging=False,
|
||||
source_image=None,
|
||||
source_only=False,
|
||||
source_size=None,
|
||||
):
|
||||
if isinstance(content, AutoCollageContent):
|
||||
from pigway_frame_flow.extensions.auto_collage import prepare
|
||||
@@ -323,10 +343,15 @@ class DisplayService:
|
||||
return asset
|
||||
if isinstance(content, PhotoSourceContent):
|
||||
source = self.photo_sources.get(content.source_id)
|
||||
display = (
|
||||
self.registry.get(device_id or self.settings.device_id).device().display
|
||||
)
|
||||
size = frame_canvas(display, source.orientation)
|
||||
if source_only:
|
||||
size = source_size or (1200, 1600)
|
||||
else:
|
||||
display = (
|
||||
self.registry.get(device_id or self.settings.device_id)
|
||||
.device()
|
||||
.display
|
||||
)
|
||||
size = frame_canvas(display, source.orientation)
|
||||
import random
|
||||
|
||||
items = self.photo_sources.catalog(content.source_id, target_size=size)
|
||||
@@ -406,6 +431,17 @@ class DisplayService:
|
||||
),
|
||||
),
|
||||
)
|
||||
if source_only:
|
||||
selected = self.libraries.ingest(
|
||||
content.source_id, item["id"], data, name, caption
|
||||
)
|
||||
attempt["status"] = "PREPARED"
|
||||
if operation_id:
|
||||
self.db.execute(
|
||||
"UPDATE operations SET result=? WHERE id=?",
|
||||
(encode({"photo_attempts": attempts}), operation_id),
|
||||
)
|
||||
return selected
|
||||
rendered = (
|
||||
render_captioned_photo(
|
||||
data,
|
||||
@@ -565,13 +601,20 @@ class DisplayService:
|
||||
"render",
|
||||
"render-ai",
|
||||
"local-upload",
|
||||
"library-generate",
|
||||
) and self.blocked(op["device_id"]):
|
||||
continue
|
||||
payload = json.loads(op["payload"])
|
||||
if (
|
||||
op["action"] in ("display", "delete", "restore")
|
||||
and op["client_id"]
|
||||
in ("scheduler", "scheduler-retry", "cloud-library", "retention")
|
||||
in (
|
||||
"scheduler",
|
||||
"scheduler-retry",
|
||||
"library-terminal",
|
||||
"cloud-library",
|
||||
"retention",
|
||||
)
|
||||
and self.db.one(
|
||||
"SELECT id FROM operations WHERE device_id=? AND action='display' "
|
||||
"AND status='SYNCING' AND write_started=1 AND updated_at>? LIMIT 1",
|
||||
@@ -633,6 +676,9 @@ class DisplayService:
|
||||
|
||||
def _execute(self, op, payload):
|
||||
id, device_id, action = op["id"], op["device_id"], op["action"]
|
||||
# A source run can generate watch versions without any frame driver.
|
||||
if action == "library-generate":
|
||||
return self.operation_handlers[action](op, payload)
|
||||
driver = self.registry.get(device_id)
|
||||
if action in self.operation_handlers:
|
||||
return self.operation_handlers[action](op, payload)
|
||||
@@ -787,6 +833,8 @@ class DisplayService:
|
||||
|
||||
get_plan(self, request.options.thumbnail_plan_id)
|
||||
content = request.content
|
||||
if isinstance(content, ImageContent) and content.asset_id:
|
||||
self.libraries.validate_asset_binding(device_id, content.asset_id)
|
||||
self.update(id, "RENDERING")
|
||||
asset = None
|
||||
source_image = {}
|
||||
|
||||
Reference in New Issue
Block a user