config structure rework
This commit is contained in:
parent
a0268f52b9
commit
a5751c973a
4 changed files with 85 additions and 54 deletions
53
api/advent22_api/calendar_config.py
Normal file
53
api/advent22_api/calendar_config.py
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
import tomllib
|
||||||
|
from typing import TypeAlias
|
||||||
|
|
||||||
|
import tomli_w
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
from .config import get_config
|
||||||
|
from .dav_common import dav_get_textfile_content, dav_write_textfile_content
|
||||||
|
from .settings import SETTINGS
|
||||||
|
|
||||||
|
|
||||||
|
class DoorSaved(BaseModel):
|
||||||
|
# Tag, an dem die Tür aufgeht
|
||||||
|
day: int
|
||||||
|
|
||||||
|
# Koordinaten für zwei Eckpunkte
|
||||||
|
x1: int
|
||||||
|
y1: int
|
||||||
|
x2: int
|
||||||
|
y2: int
|
||||||
|
|
||||||
|
|
||||||
|
DoorsSaved: TypeAlias = list[DoorSaved]
|
||||||
|
|
||||||
|
|
||||||
|
class CalendarConfig(BaseModel):
|
||||||
|
# Dateiname Hintergrundbild
|
||||||
|
background: str = "adventskalender.jpg"
|
||||||
|
|
||||||
|
# Türen für die UI
|
||||||
|
doors: DoorsSaved = []
|
||||||
|
|
||||||
|
|
||||||
|
async def get_calendar_config() -> CalendarConfig:
|
||||||
|
cfg = await get_config()
|
||||||
|
|
||||||
|
txt = await dav_get_textfile_content(
|
||||||
|
path=f"files/{cfg.puzzle.calendar}",
|
||||||
|
)
|
||||||
|
|
||||||
|
return CalendarConfig.model_validate(tomllib.loads(txt))
|
||||||
|
|
||||||
|
|
||||||
|
async def set_calendar_config(cal_cfg: CalendarConfig) -> None:
|
||||||
|
await dav_write_textfile_content(
|
||||||
|
path=SETTINGS.config_filename,
|
||||||
|
content=tomli_w.dumps(
|
||||||
|
cal_cfg.model_dump(
|
||||||
|
exclude_defaults=True,
|
||||||
|
exclude_unset=True,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
|
@ -1,10 +1,8 @@
|
||||||
import tomllib
|
import tomllib
|
||||||
from typing import TypeAlias
|
|
||||||
|
|
||||||
import tomli_w
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from .dav_common import dav_get_textfile_content, dav_write_textfile_content
|
from .dav_common import dav_get_textfile_content
|
||||||
from .settings import SETTINGS
|
from .settings import SETTINGS
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,45 +11,34 @@ class User(BaseModel):
|
||||||
password: str
|
password: str
|
||||||
|
|
||||||
|
|
||||||
class DoorSaved(BaseModel):
|
class Server(BaseModel):
|
||||||
# Tag, an dem die Tür aufgeht
|
|
||||||
day: int
|
|
||||||
|
|
||||||
# Koordinaten für zwei Eckpunkte
|
|
||||||
x1: int
|
|
||||||
y1: int
|
|
||||||
x2: int
|
|
||||||
y2: int
|
|
||||||
|
|
||||||
|
|
||||||
DoorsSaved: TypeAlias = list[DoorSaved]
|
|
||||||
|
|
||||||
|
|
||||||
class Puzzle(BaseModel):
|
|
||||||
# Dateiname Hintergrundbild
|
|
||||||
background: str
|
|
||||||
|
|
||||||
# Dateiname Schriftart
|
# Dateiname Schriftart
|
||||||
font: str
|
font: str
|
||||||
|
|
||||||
# Türen für die UI
|
|
||||||
doors: DoorsSaved = []
|
|
||||||
|
|
||||||
# Lösungswort
|
|
||||||
solution: str
|
|
||||||
|
|
||||||
# Monat, während dem der Kalender läuft
|
# Monat, während dem der Kalender läuft
|
||||||
month: int = 12
|
month: int = 12
|
||||||
|
|
||||||
# Letzter Tag des Kalenders
|
|
||||||
max_day: int = 24
|
|
||||||
|
|
||||||
# Alle Türen bleiben noch so viele Monate offen
|
# Alle Türen bleiben noch so viele Monate offen
|
||||||
keep_open: int = 3
|
keep_open: int = 3
|
||||||
|
|
||||||
|
|
||||||
|
class Puzzle(BaseModel):
|
||||||
|
# Lösungswort
|
||||||
|
solution: str
|
||||||
|
|
||||||
|
# Länge des Kalenders
|
||||||
|
days: int = 24
|
||||||
|
|
||||||
|
# Kalenderdefinition
|
||||||
|
calendar: str = "default.toml"
|
||||||
|
|
||||||
|
# Serverseitiger zusätzlicher "random" seed
|
||||||
|
random_pepper: str = ""
|
||||||
|
|
||||||
|
|
||||||
class Config(BaseModel):
|
class Config(BaseModel):
|
||||||
admin: User
|
admin: User
|
||||||
|
server: Server
|
||||||
puzzle: Puzzle
|
puzzle: Puzzle
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,17 +46,3 @@ async def get_config() -> Config:
|
||||||
txt = await dav_get_textfile_content(path=SETTINGS.config_filename)
|
txt = await dav_get_textfile_content(path=SETTINGS.config_filename)
|
||||||
|
|
||||||
return Config.model_validate(tomllib.loads(txt))
|
return Config.model_validate(tomllib.loads(txt))
|
||||||
|
|
||||||
|
|
||||||
async def set_config(cfg: Config) -> None:
|
|
||||||
txt = tomli_w.dumps(
|
|
||||||
cfg.model_dump(
|
|
||||||
exclude_defaults=True,
|
|
||||||
exclude_unset=True,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
await dav_write_textfile_content(
|
|
||||||
path=SETTINGS.config_filename,
|
|
||||||
content=txt,
|
|
||||||
)
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ class Random(random.Random):
|
||||||
@classmethod
|
@classmethod
|
||||||
async def get(cls, bonus_salt: Any = "") -> Self:
|
async def get(cls, bonus_salt: Any = "") -> Self:
|
||||||
cfg = await get_config()
|
cfg = await get_config()
|
||||||
return cls(f"{cfg.puzzle.solution}{bonus_salt}")
|
return cls(f"{cfg.puzzle.solution}{bonus_salt}{cfg.puzzle.random_pepper}")
|
||||||
|
|
||||||
|
|
||||||
async def set_length(seq: Sequence, length: int) -> list:
|
async def set_length(seq: Sequence, length: int) -> list:
|
||||||
|
@ -96,7 +96,7 @@ async def get_auto_image(
|
||||||
image = await load_image(images[index])
|
image = await load_image(images[index])
|
||||||
rnd = await Random.get(index)
|
rnd = await Random.get(index)
|
||||||
|
|
||||||
font = await dav_get_file(f"files/{cfg.puzzle.font}")
|
font = await dav_get_file(f"files/{cfg.server.font}")
|
||||||
font.seek(0)
|
font.seek(0)
|
||||||
|
|
||||||
# Buchstabe verstecken
|
# Buchstabe verstecken
|
||||||
|
|
|
@ -2,7 +2,12 @@ from fastapi import APIRouter, Depends
|
||||||
from fastapi.responses import StreamingResponse
|
from fastapi.responses import StreamingResponse
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from ..config import Config, DoorsSaved, get_config, set_config
|
from ..calendar_config import (
|
||||||
|
CalendarConfig,
|
||||||
|
DoorsSaved,
|
||||||
|
get_calendar_config,
|
||||||
|
set_calendar_config,
|
||||||
|
)
|
||||||
from ..dav_common import dav_get_file
|
from ..dav_common import dav_get_file
|
||||||
from ._misc import api_return_image
|
from ._misc import api_return_image
|
||||||
|
|
||||||
|
@ -14,39 +19,39 @@ router = APIRouter(prefix="/general", tags=["general"])
|
||||||
response_class=StreamingResponse,
|
response_class=StreamingResponse,
|
||||||
)
|
)
|
||||||
async def get_image_for_day(
|
async def get_image_for_day(
|
||||||
cfg: Config = Depends(get_config),
|
cal_cfg: CalendarConfig = Depends(get_calendar_config),
|
||||||
) -> StreamingResponse:
|
) -> StreamingResponse:
|
||||||
"""
|
"""
|
||||||
Hintergrundbild laden
|
Hintergrundbild laden
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return await api_return_image(
|
return await api_return_image(
|
||||||
Image.open(await dav_get_file(f"files/{cfg.puzzle.background}"))
|
Image.open(await dav_get_file(f"files/{cal_cfg.background}"))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/doors")
|
@router.get("/doors")
|
||||||
async def get_doors(
|
async def get_doors(
|
||||||
cfg: Config = Depends(get_config),
|
cal_cfg: CalendarConfig = Depends(get_calendar_config),
|
||||||
) -> DoorsSaved:
|
) -> DoorsSaved:
|
||||||
"""
|
"""
|
||||||
Türchen lesen
|
Türchen lesen
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return cfg.puzzle.doors
|
return cal_cfg.doors
|
||||||
|
|
||||||
|
|
||||||
@router.put("/doors")
|
@router.put("/doors")
|
||||||
async def put_doors(
|
async def put_doors(
|
||||||
doors: DoorsSaved,
|
doors: DoorsSaved,
|
||||||
cfg: Config = Depends(get_config),
|
cal_cfg: CalendarConfig = Depends(get_calendar_config),
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Türchen setzen
|
Türchen setzen
|
||||||
"""
|
"""
|
||||||
|
|
||||||
cfg.puzzle.doors = sorted(
|
cal_cfg.doors = sorted(
|
||||||
doors,
|
doors,
|
||||||
key=lambda door: door.day,
|
key=lambda door: door.day,
|
||||||
)
|
)
|
||||||
await set_config(cfg)
|
await set_calendar_config(cal_cfg)
|
||||||
|
|
Loading…
Reference in a new issue