import tomllib from typing import cast import tomli_w from fastapi import Depends from PIL import Image, ImageFont from .advent_image import _XY, AdventImage from .calendar_config import CalendarConfig from .config import Config from .image_helpers import list_images_auto, load_image from .sequence_helpers import Random, set_len, shuffle from .settings import SETTINGS from .webdav import WebDAV class AllTime: @staticmethod async def get_config() -> Config: """ Globale Konfiguration lesen """ txt = await WebDAV.read_str(path=SETTINGS.config_filename) return Config.model_validate(tomllib.loads(txt)) @staticmethod async def get_calendar_config( cfg: Config = Depends(get_config), ) -> CalendarConfig: """ Kalender Konfiguration lesen """ txt = await WebDAV.read_str(path=f"files/{cfg.puzzle.calendar}") return CalendarConfig.model_validate(tomllib.loads(txt)) @staticmethod async def set_calendar_config( cal_cfg: CalendarConfig, cfg: Config = Depends(get_config), ) -> None: """ Kalender Konfiguration ändern """ await WebDAV.write_str( path=f"files/{cfg.puzzle.calendar}", content=tomli_w.dumps( cal_cfg.model_dump( exclude_defaults=True, exclude_unset=True, ) ), ) @staticmethod async def shuffle_solution( cfg: Config = Depends(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(AllTime.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=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(AllTime.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 )