""" Router "image" provides: - listing image files - finding image files by name prefix - getting image files in a uniform format by name prefix """ import re from io import BytesIO from logging import getLogger from typing import Iterator from fastapi import APIRouter, Depends from fastapi.responses import StreamingResponse from PIL import Image from ...config import Config, ImageUIConfig from ...dav_common import webdav_ensure_files, webdav_ensure_path from ...dav_file import DavFile from ._common import FileNameLister, PrefixFinder, PrefixUnique _logger = getLogger(__name__) router = APIRouter(prefix="/image", tags=["image"]) image_lister = FileNameLister( path_name="image_dir", re=re.compile( r"\.(gif|jpe?g|tiff?|png|bmp)$", flags=re.IGNORECASE, ), ) image_finder = PrefixFinder(image_lister) image_unique = PrefixUnique(image_finder) @router.on_event("startup") async def start_router() -> None: _logger.debug(f"{router.prefix} router starting.") if not webdav_ensure_path(await image_lister.remote_path): webdav_ensure_files( await image_lister.remote_path, "img1.jpg", "img2.jpg", "img3.jpg", ) @router.get( "/list", response_model=list[str], responses=image_lister.responses, ) async def list_images( names: Iterator[str] = Depends(image_lister), ) -> list[str]: return list(names) @router.get( "/find/{prefix}", response_model=list[str], responses=image_finder.responses, ) async def find_images( names: Iterator[str] = Depends(image_finder), ) -> list[str]: return list(names) @router.get( "/get/{prefix}", response_class=StreamingResponse, responses=image_unique.responses, ) async def get_image( prefix: str, name: str = Depends(image_unique), ) -> StreamingResponse: cfg = await Config.get() dav_file = DavFile(f"{await image_lister.remote_path}/{name}") img = Image.open(BytesIO(await dav_file.as_bytes)).convert(cfg.image.mode) img_buffer = BytesIO() 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={prefix}.jpg"}, ) @router.get( "/config", response_model=ImageUIConfig, ) async def get_ui_config( cfg: Config = Depends(Config.get), ) -> ImageUIConfig: return cfg.image