from io import BytesIO from typing import cast from fastapi import Depends from PIL import Image, ImageFont from .advent_image import _XY, AdventImage from .config import Config from .image_helpers import list_images_auto, load_image from .sequence_helpers import Random, set_len, shuffle from .webdav import WebDAV class AllTime: @staticmethod async def shuffle_solution( cfg: Config = Depends(Config.get_config), ) -> str: """ Lösung: Reihenfolge zufällig bestimmen """ return "".join(await shuffle(cfg.puzzle.solution)) @staticmethod async def shuffle_images_auto( images: list[str] = Depends(list_images_auto), ) -> list[str]: """ Bilder: Reihenfolge zufällig bestimmen """ ls = set_len(images, 24) return await shuffle(ls) class Today: @staticmethod async def get_part( day: int, shuffled_solution: str = Depends(AllTime.shuffle_solution), ) -> str: """ Heute angezeigter Teil der Lösung """ return shuffled_solution[day] @staticmethod async def get_random( day: int, ) -> Random: """ Tagesabhängige Zufallszahlen """ return await Random.get(day) @staticmethod async def gen_auto_image( day: int, images: list[str] = Depends(AllTime.shuffle_images_auto), cfg: Config = Depends(Config.get_config), rnd: Random = Depends(get_random), part: str = Depends(get_part), ) -> Image.Image: """ Automatisch generiertes Bild erstellen """ # Datei existiert garantiert! img = await load_image(images[day]) image = await AdventImage.from_img(img) font = ImageFont.truetype( font=BytesIO(await WebDAV.read_bytes(f"files/{cfg.server.font}")), size=50, ) # Buchstaben verstecken for letter in part: await image.hide_text( xy=cast(_XY, tuple(rnd.choices(range(30, 470), k=2))), text=letter, font=font, ) return image.img @staticmethod async def get_image( day: int, images: list[str] = Depends(AllTime.shuffle_images_auto), cfg: Config = Depends(Config.get_config), rnd: Random = Depends(get_random), part: str = Depends(get_part), ) -> Image.Image: """ Bild für einen Tag abrufen """ try: # Versuche, aus "manual"-Ordner zu laden return await load_image(f"images_manual/{day}.jpg") except RuntimeError: # Erstelle automatisch generiertes Bild return await Today.gen_auto_image( day=day, images=images, cfg=cfg, rnd=rnd, part=part )