ovdashboard/api/ovdashboard_api/routers/v1/image.py

107 lines
2.4 KiB
Python

"""
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 fastapi import APIRouter, Depends
from fastapi.responses import StreamingResponse
from PIL import Image
from ...core.config import Config, ImageUIConfig, get_config
from ...core.dav_common import webdav_ensure_files, webdav_ensure_path
from ...core.webdav import WebDAV
from ._common import filter_prefix, filter_prefix_unique, get_remote_path, list_files
_logger = getLogger(__name__)
_PATH_NAME = "image_dir"
router = APIRouter(prefix="/image", tags=["image"])
_ls = list_files(
path_name=_PATH_NAME,
re=re.compile(
r"\.(gif|jpe?g|tiff?|png|bmp)$",
flags=re.IGNORECASE,
),
)
_rp = get_remote_path(path_name=_PATH_NAME)
_fp = filter_prefix(_ls.func)
_fpu = filter_prefix_unique(_fp.func)
@router.on_event("startup")
async def start_router() -> None:
_logger.debug(f"{router.prefix} router starting.")
remote_path = await _rp.func()
if not webdav_ensure_path(remote_path):
webdav_ensure_files(
remote_path,
"img1.jpg",
"img2.jpg",
"img3.jpg",
)
@router.get(
"/list",
response_model=list[str],
responses=_ls.responses,
)
async def list_all_images(
names: list[str] = Depends(_ls.func),
) -> list[str]:
return names
@router.get(
"/find/{prefix}",
response_model=list[str],
responses=_fp.responses,
)
async def find_images_by_prefix(
names: list[str] = Depends(_fp.func),
) -> list[str]:
return names
@router.get(
"/get/{prefix}",
response_class=StreamingResponse,
responses=_fpu.responses,
)
async def get_image_by_prefix(
prefix: str,
remote_path: str = Depends(_rp.func),
name: str = Depends(_fpu.func),
) -> StreamingResponse:
cfg = await get_config()
img = Image.open(BytesIO(await WebDAV.read_bytes(f"{remote_path}/{name}")))
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(get_config),
) -> ImageUIConfig:
return cfg.image