mirror of
https://code.lenaisten.de/Lenaisten/advent22.git
synced 2024-11-26 17:33:00 +00:00
141 lines
3.4 KiB
Python
141 lines
3.4 KiB
Python
from io import BytesIO
|
|
from typing import cast
|
|
|
|
from fastapi import Depends
|
|
from PIL import Image, ImageFont
|
|
|
|
from .advent_image import _XY, AdventImage
|
|
from .calendar_config import CalendarConfig, get_calendar_config
|
|
from .config import Config, get_config
|
|
from .helpers import Random, list_images_auto, load_image, set_len
|
|
from .webdav import WebDAV
|
|
|
|
|
|
async def get_all_days(
|
|
cal_cfg: CalendarConfig = Depends(get_calendar_config),
|
|
) -> list[int]:
|
|
"""
|
|
Alle Tage, für die es ein Türchen gibt
|
|
"""
|
|
|
|
return sorted(set(door.day for door in cal_cfg.doors))
|
|
|
|
|
|
async def get_all_parts(
|
|
cfg: Config = Depends(get_config),
|
|
days: list[int] = Depends(get_all_days),
|
|
) -> dict[int, str]:
|
|
"""
|
|
Lösung auf vorhandene Tage aufteilen
|
|
"""
|
|
|
|
solution_length = len(cfg.puzzle.solution)
|
|
num_days = len(days)
|
|
|
|
rnd = await Random.get()
|
|
solution_days = [
|
|
*rnd.shuffled(days * (solution_length // num_days)),
|
|
*rnd.sample(days, solution_length % num_days),
|
|
]
|
|
|
|
result: dict[int, str] = {}
|
|
for day, letter in zip(solution_days, cfg.puzzle.solution):
|
|
result[day] = result.get(day, "")
|
|
result[day] += letter
|
|
|
|
return result
|
|
|
|
|
|
async def get_day_part(
|
|
day: int,
|
|
parts: dict[int, str] = Depends(get_all_parts),
|
|
) -> str:
|
|
"""
|
|
Heute angezeigter Teil der Lösung
|
|
"""
|
|
|
|
return parts[day]
|
|
|
|
|
|
async def get_all_auto_image_names(
|
|
days: list[int] = Depends(get_all_days),
|
|
images: list[str] = Depends(list_images_auto),
|
|
) -> dict[int, str]:
|
|
"""
|
|
Bilder: Reihenfolge zufällig bestimmen
|
|
"""
|
|
|
|
rnd = await Random.get()
|
|
ls = set_len(images, len(days))
|
|
|
|
return dict(zip(days, rnd.shuffled(ls)))
|
|
|
|
|
|
async def get_all_image_names(
|
|
auto_image_names: dict[int, str] = Depends(get_all_auto_image_names),
|
|
) -> dict[int, str]:
|
|
"""
|
|
Bilder "auto" und "manual" zu Tagen zuordnen
|
|
"""
|
|
|
|
# TODO penner
|
|
# "manual"-Bilder erkennen (hier neue variable anlegen)
|
|
|
|
return auto_image_names
|
|
|
|
|
|
async def gen_day_auto_image(
|
|
day: int,
|
|
cfg: Config = Depends(get_config),
|
|
auto_image_names: list[str] = Depends(get_all_auto_image_names),
|
|
day_part: str = Depends(get_day_part),
|
|
) -> Image.Image:
|
|
"""
|
|
Automatisch generiertes Bild erstellen
|
|
"""
|
|
|
|
# Datei existiert garantiert!
|
|
img = await load_image(auto_image_names[day])
|
|
image = await AdventImage.from_img(img)
|
|
|
|
rnd = await Random.get(day)
|
|
|
|
font = ImageFont.truetype(
|
|
font=BytesIO(await WebDAV.read_bytes(f"files/{cfg.server.font}")),
|
|
size=50,
|
|
)
|
|
|
|
# Buchstaben verstecken
|
|
for letter in day_part:
|
|
await image.hide_text(
|
|
xy=cast(_XY, tuple(rnd.choices(range(30, 470), k=2))),
|
|
text=letter,
|
|
font=font,
|
|
)
|
|
|
|
return image.img
|
|
|
|
|
|
async def get_day_image(
|
|
day: int,
|
|
cfg: Config = Depends(get_config),
|
|
auto_image_names: list[str] = Depends(get_all_auto_image_names),
|
|
day_part: str = Depends(get_day_part),
|
|
) -> Image.Image:
|
|
"""
|
|
Bild für einen Tag abrufen
|
|
"""
|
|
|
|
try:
|
|
# Versuche, aus "manual"-Ordner zu laden
|
|
img = await load_image(f"images_manual/{day}.jpg")
|
|
|
|
# Als AdventImage verarbeiten
|
|
image = await AdventImage.from_img(img)
|
|
return image.img
|
|
|
|
except RuntimeError:
|
|
# Erstelle automatisch generiertes Bild
|
|
return await gen_day_auto_image(
|
|
day=day, cfg=cfg, auto_image_names=auto_image_names, day_part=day_part
|
|
)
|