""" Router "image" provides: - listing image files - finding image files by name prefix - getting image files in a uniform format by name prefix """ import logging from io import BytesIO from fastapi import APIRouter, Depends from fastapi.responses import StreamingResponse from PIL import Image from ...core.config import Config, ImageUIConfig from ...core.dav.webdav import WebDAV from ...core.dav_common import webdav_ensure_files, webdav_ensure_path from ._common import LM_IMAGE, RP_IMAGE, get_config _logger = logging.getLogger(__name__) router = APIRouter(prefix="/image", tags=["image"]) @router.on_event("startup") async def start_router() -> None: _logger.debug(f"{router.prefix} router starting.") remote_path = await RP_IMAGE() if not webdav_ensure_path(remote_path): webdav_ensure_files( remote_path, "img1.jpg", "img2.jpg", "img3.jpg", ) @router.get( "/list", responses=LM_IMAGE.lister.responses, ) async def list_images( names: list[str] = Depends(LM_IMAGE.lister.func), ) -> list[str]: return names @router.get( "/find/{prefix}", responses=LM_IMAGE.filter.responses, ) async def find_images_by_prefix( names: list[str] = Depends(LM_IMAGE.filter.func), ) -> list[str]: return names @router.get( "/get/{prefix}", responses=LM_IMAGE.getter.responses, response_class=StreamingResponse, ) async def get_image_by_prefix( cfg: Config = Depends(get_config), remote_path: str = Depends(RP_IMAGE), name: str = Depends(LM_IMAGE.getter.func), ) -> StreamingResponse: img = Image.open(BytesIO(await WebDAV.read_bytes(f"{remote_path}/{name}"))) img_buffer = BytesIO() width, height = img.size target_height = cfg.image.height target_width = int(width * target_height / height) img = img.resize( size=(target_width, target_height), resample=Image.LANCZOS, ) img.save(img_buffer, **cfg.image.save_params) img_buffer.seek(0) return StreamingResponse( content=img_buffer, media_type="image/jpeg", headers={"Content-Disposition": f"filename={name}.jpg"}, ) @router.get("/config") async def get_ui_config( cfg: Config = Depends(get_config), ) -> ImageUIConfig: return cfg.image