feat: generate source-only watch thumbnails after photo uploads
Community checks / verify (push) Skipped
Verify Frame Flow / verify (push) Failing after 7m6s

This commit is contained in:
渡口浪人
2026-10-23 13:27:17 +08:00
parent fdc3a886f7
commit d94031eb50
6 changed files with 220 additions and 9 deletions
@@ -0,0 +1,57 @@
"""Source-only rendition for the current 410 × 502 watch display."""
import hashlib
import json
import logging
from datetime import datetime
from zoneinfo import ZoneInfo
from pigway_frame_flow.errors import FlowError
from pigway_frame_flow.renderers.images import convert
from pigway_frame_flow.storage.database import encode
logger = logging.getLogger(__name__)
SIZE = (410, 502)
def publish(service, device_id, asset_id, data=None):
# Templates and old gallery assets have no verified undecorated source.
row = service.db.one(
"SELECT payload FROM asset_sources WHERE asset_id=?", (asset_id,)
)
source = json.loads(row["payload"]) if row else {}
if source.get("type") != "photo_source":
return None
try:
if data is None:
data, _, _ = service.photo_sources.read(
source["source_id"], source["item_id"], target_size=SIZE
)
rendered = convert(data, "cover", "color", size=SIZE)
asset = service.assets.put(rendered, "watch.jpg", "cache")
now = datetime.now(ZoneInfo(service.settings.timezone))
result = {
"asset_id": asset["asset_id"],
"url": asset["url"],
"width": SIZE[0],
"height": SIZE[1],
"date": now.date().isoformat(),
"timezone": service.settings.timezone,
"generated_at": now.isoformat(),
"sha256": hashlib.sha256(rendered).hexdigest(),
"bytes": len(rendered),
"source": source,
"fit": "cover",
"source_rendition": "preview"
if service.photo_sources.get(source["source_id"]).kind == "synology-photos"
else "source",
}
service.db.execute(
"INSERT OR REPLACE INTO app_config VALUES(?,?)",
("wrist-thumbnail:" + device_id, encode(result)),
)
return result
except (FlowError, OSError, ValueError):
# An auxiliary rendition must never cause a successful upload to replay.
logger.warning("Watch thumbnail generation failed for asset %s", asset_id)
return None