Files
espresso_frame/server/app/config.py
T
tfaour 42d7c09f97
Build and push server image / build-and-push (push) Successful in 42s
Make the upcoming-photos queue length user-configurable
Adds "Upcoming photos to show" to the config UI (queue_target_len, 5-50,
default 20, replacing the hardcoded QUEUE_TARGET_LEN constant). Lowering
it trims the queue immediately on next page load rather than waiting for
enough advances to consume the excess naturally; raising it tops back up
the same way, via a new photo_queue.sync_queue_length() called from
GET /api/queue.
2026-07-19 01:03:05 -04:00

60 lines
1.9 KiB
Python

"""JSON-file-backed config: Immich connection, selected album, and cursor
state (which photo /frame/image serves next)."""
from __future__ import annotations
import json
import os
from pathlib import Path
from threading import Lock
from pydantic import BaseModel
CONFIG_PATH = Path(os.environ.get("CONFIG_PATH", "/data/config.json"))
_lock = Lock()
class FrameConfig(BaseModel):
immich_url: str = ""
immich_api_key: str = ""
album_id: str = ""
order: str = "sequential" # or "shuffle"
refresh_interval_s: int = 3600
smart_crop_faces: bool = True
# Current photo + upcoming queue (see app/photo_queue.py). current_asset_set_at
# is what lets the server decide "has it been long enough to advance" on its
# own clock, independent of how/why the device asked for a photo.
current_asset_id: str = ""
current_asset_set_at: float = 0.0
queue: list[str] = []
queue_cursor: int = 0 # internal bookkeeping for sequential queue top-up; not user-facing
queue_target_len: int = 20 # how many upcoming photos to keep queued/shown in the web UI
def load() -> FrameConfig:
with _lock:
if not CONFIG_PATH.exists():
cfg = FrameConfig()
else:
cfg = FrameConfig(**json.loads(CONFIG_PATH.read_text()))
# IMMICH_URL/IMMICH_API_KEY set in the environment (e.g. docker-compose.yml,
# see docker-compose.yml.example) take precedence over whatever's saved
# in CONFIG_PATH, so credentials never need to go through the web UI.
env_url = os.environ.get("IMMICH_URL")
env_key = os.environ.get("IMMICH_API_KEY")
if env_url:
cfg.immich_url = env_url
if env_key:
cfg.immich_api_key = env_key
return cfg
def save(cfg: FrameConfig) -> None:
with _lock:
CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
CONFIG_PATH.write_text(cfg.model_dump_json(indent=2))