From 2802b0465747f812a9dd6b6462ef31b13182ce27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn-Michael=20Miehe?= Date: Tue, 15 Nov 2022 22:58:04 +0000 Subject: [PATCH] Image-Methoden nach _misc --- api/advent22_api/routers/_misc.py | 95 ++++++++++++++++++++++++++++++- api/advent22_api/routers/days.py | 68 +--------------------- 2 files changed, 97 insertions(+), 66 deletions(-) diff --git a/api/advent22_api/routers/_misc.py b/api/advent22_api/routers/_misc.py index 619413a..9780670 100644 --- a/api/advent22_api/routers/_misc.py +++ b/api/advent22_api/routers/_misc.py @@ -1,8 +1,18 @@ import itertools import random +import re from typing import Any, Sequence -from ..config import get_config +from fastapi import Depends +from PIL import ImageFont + +from ..config import Config, get_config +from ..dav_common import dav_file_exists, dav_get_file, dav_list_files +from ._image import AdventImage + +########## +# RANDOM # +########## async def get_rnd(bonus_salt: Any = "") -> random.Random: @@ -24,3 +34,86 @@ async def shuffle(seq: Sequence, rnd: random.Random | None = None) -> list: # Elemente mischen return rnd.sample(seq, len(seq)) + +######### +# IMAGE # +######### + + +async def get_letter( + index: int, + cfg: Config = Depends(get_config), +) -> str: + return (await shuffle(cfg.solution))[index] + + +_RE_IMAGE_FILE = re.compile( + r"\.(gif|jpe?g|tiff?|png|bmp)$", + flags=re.IGNORECASE, +) + + +async def list_images_auto() -> list[str]: + """ + Finde alle Bilder im "automatisch"-Verzeichnis + """ + ls = await dav_list_files(_RE_IMAGE_FILE, "/images_auto") + ls = await set_length(ls, 24) + + return await shuffle(ls) + + +async def load_image( + file_name: str, +) -> AdventImage: + """ + Versuche, Bild aus Datei zu laden + """ + + if not await dav_file_exists(file_name): + raise RuntimeError(f"DAV-File {file_name} does not exist!") + + img_buffer = await dav_get_file(file_name) + img_buffer.seek(0) + return await AdventImage.load_standard(img_buffer) + + +async def get_auto_image( + index: int, + letter: str = Depends(get_letter), + images: list[str] = Depends(list_images_auto), +) -> AdventImage: + """ + Erstelle automatisch generiertes Bild + """ + + # hier niemals RuntimeError! + image = await load_image(images[index]) + rnd = await get_rnd(index) + + # Buchstabe verstecken + await image.hide_text( + xy=tuple(rnd.choices(range(30, 470), k=2)), + text=letter, + font=ImageFont.truetype("Lena.ttf", 50), + ) + + return image + + +async def get_image( + index: int, + letter: str = Depends(get_letter), + images: list[str] = Depends(list_images_auto), +) -> AdventImage: + """ + Bild für einen Tag erstellen + """ + + try: + # Versuche, aus "manual"-Ordner zu laden + return await load_image(f"images_manual/{index}.jpg") + + except RuntimeError: + # Erstelle automatisch generiertes Bild + return await get_auto_image(index=index, letter=letter, images=images) diff --git a/api/advent22_api/routers/days.py b/api/advent22_api/routers/days.py index e1dd90d..ef90fa6 100644 --- a/api/advent22_api/routers/days.py +++ b/api/advent22_api/routers/days.py @@ -1,15 +1,12 @@ -import re # from datetime import date from io import BytesIO from fastapi import APIRouter, Depends from fastapi.responses import StreamingResponse -from PIL import ImageFont from ..config import Config, get_config -from ..dav_common import dav_file_exists, dav_get_file, dav_list_files from ._image import AdventImage -from ._misc import get_rnd, set_length, shuffle +from ._misc import get_image, shuffle router = APIRouter(prefix="/days", tags=["days"]) @@ -54,77 +51,18 @@ async def get_letter( # media_type="image/png", # ) -_RE_IMAGE_FILE = re.compile( - r"\.(gif|jpe?g|tiff?|png|bmp)$", - flags=re.IGNORECASE, -) - - -async def list_images_auto() -> list[str]: - ls = await dav_list_files(_RE_IMAGE_FILE, "/images_auto") - ls = await set_length(ls, 24) - - return await shuffle(ls) - - -async def load_image( - file_name: str, -) -> AdventImage | None: - """ - Versuche, Bild aus Datei zu laden - """ - - if not await dav_file_exists(file_name): - return None - - img_buffer = await dav_get_file(file_name) - img_buffer.seek(0) - return await AdventImage.load_standard(img_buffer) - - -async def get_auto_image( - index: int, - letter: str = Depends(get_letter), - images: list[str] = Depends(list_images_auto), -) -> AdventImage: - - image = await load_image(images[index]) - assert image is not None - - rnd = await get_rnd(index) - - # Buchstabe verstecken - await image.hide_text( - xy=tuple(rnd.choices(range(30, 470), k=2)), - text=letter, - font=ImageFont.truetype("Lena.ttf", 50), - ) - - return image - @router.get( "/picture/{index}", response_class=StreamingResponse, ) -async def get_picture_for_day( - index: int, +async def get_image_for_day( + image: AdventImage = Depends(get_image), ) -> StreamingResponse: """ Bild für einen Tag erstellen """ - # Versuche, aus "manual"-Ordner zu laden - image = await load_image(f"images_manual/{index}.jpg") - - if image is None: - # Erstelle automatisch generiertes Bild - image = await get_auto_image( - index=index, - letter=await get_letter(index, await get_config()), - images=await list_images_auto() - ) - # Bilddaten in Puffer laden img_buffer = BytesIO() image.img.save(img_buffer, format="JPEG", quality=85)