46 lines
1.5 KiB
Python
46 lines
1.5 KiB
Python
"""Saved thumbnail rendering parameters; source pixels are never decorated."""
|
|
|
|
from pydantic import Field
|
|
|
|
from pigway_frame_flow.errors import ErrorCode as E
|
|
from pigway_frame_flow.errors import FlowError
|
|
from pigway_frame_flow.models import StrictModel
|
|
from pigway_frame_flow.renderers.images import convert
|
|
from pigway_frame_flow.storage.database import encode
|
|
|
|
|
|
class ThumbnailPlan(StrictModel):
|
|
name: str = Field(min_length=1, max_length=120)
|
|
width: int = Field(default=410, ge=16, le=2048)
|
|
height: int = Field(default=502, ge=16, le=2048)
|
|
fit: str = Field(default="cover", pattern="^(cover|contain)$")
|
|
center_x: float = Field(default=0.5, ge=0, le=1, allow_inf_nan=False)
|
|
center_y: float = Field(default=0.5, ge=0, le=1, allow_inf_nan=False)
|
|
quality: int = Field(default=85, ge=40, le=95)
|
|
|
|
|
|
def get_plan(service, plan_id):
|
|
row = service.db.one(
|
|
"SELECT payload FROM app_config WHERE key=?", ("thumbnail-plan:" + plan_id,)
|
|
)
|
|
if not row:
|
|
raise FlowError(E.NOT_FOUND, "Thumbnail plan not found", 404)
|
|
return ThumbnailPlan.model_validate_json(row["payload"])
|
|
|
|
|
|
def render(data, plan):
|
|
return convert(
|
|
data,
|
|
plan.fit,
|
|
size=(plan.width, plan.height),
|
|
centering=(plan.center_x, plan.center_y),
|
|
quality=plan.quality,
|
|
)
|
|
|
|
|
|
def save_plan(service, plan_id, plan):
|
|
service.db.execute(
|
|
"INSERT OR REPLACE INTO app_config VALUES(?,?)",
|
|
("thumbnail-plan:" + plan_id, encode(plan.model_dump())),
|
|
)
|