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
 | 
			
		||||
from typing import TypeAlias
 | 
			
		||||
 | 
			
		||||
import tomli_w
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -13,45 +11,34 @@ class User(BaseModel):
 | 
			
		|||
    password: str
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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 Puzzle(BaseModel):
 | 
			
		||||
    # Dateiname Hintergrundbild
 | 
			
		||||
    background: str
 | 
			
		||||
 | 
			
		||||
class Server(BaseModel):
 | 
			
		||||
    # Dateiname Schriftart
 | 
			
		||||
    font: str
 | 
			
		||||
 | 
			
		||||
    # Türen für die UI
 | 
			
		||||
    doors: DoorsSaved = []
 | 
			
		||||
 | 
			
		||||
    # Lösungswort
 | 
			
		||||
    solution: str
 | 
			
		||||
 | 
			
		||||
    # Monat, während dem der Kalender läuft
 | 
			
		||||
    month: int = 12
 | 
			
		||||
 | 
			
		||||
    # Letzter Tag des Kalenders
 | 
			
		||||
    max_day: int = 24
 | 
			
		||||
 | 
			
		||||
    # Alle Türen bleiben noch so viele Monate offen
 | 
			
		||||
    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):
 | 
			
		||||
    admin: User
 | 
			
		||||
    server: Server
 | 
			
		||||
    puzzle: Puzzle
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -59,17 +46,3 @@ async def get_config() -> Config:
 | 
			
		|||
    txt = await dav_get_textfile_content(path=SETTINGS.config_filename)
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
    async def get(cls, bonus_salt: Any = "") -> Self:
 | 
			
		||||
        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:
 | 
			
		||||
| 
						 | 
				
			
			@ -96,7 +96,7 @@ async def get_auto_image(
 | 
			
		|||
    image = await load_image(images[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)
 | 
			
		||||
 | 
			
		||||
    # Buchstabe verstecken
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,12 @@ from fastapi import APIRouter, Depends
 | 
			
		|||
from fastapi.responses import StreamingResponse
 | 
			
		||||
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 ._misc import api_return_image
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -14,39 +19,39 @@ router = APIRouter(prefix="/general", tags=["general"])
 | 
			
		|||
    response_class=StreamingResponse,
 | 
			
		||||
)
 | 
			
		||||
async def get_image_for_day(
 | 
			
		||||
    cfg: Config = Depends(get_config),
 | 
			
		||||
    cal_cfg: CalendarConfig = Depends(get_calendar_config),
 | 
			
		||||
) -> StreamingResponse:
 | 
			
		||||
    """
 | 
			
		||||
    Hintergrundbild laden
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    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")
 | 
			
		||||
async def get_doors(
 | 
			
		||||
    cfg: Config = Depends(get_config),
 | 
			
		||||
    cal_cfg: CalendarConfig = Depends(get_calendar_config),
 | 
			
		||||
) -> DoorsSaved:
 | 
			
		||||
    """
 | 
			
		||||
    Türchen lesen
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    return cfg.puzzle.doors
 | 
			
		||||
    return cal_cfg.doors
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@router.put("/doors")
 | 
			
		||||
async def put_doors(
 | 
			
		||||
    doors: DoorsSaved,
 | 
			
		||||
    cfg: Config = Depends(get_config),
 | 
			
		||||
    cal_cfg: CalendarConfig = Depends(get_calendar_config),
 | 
			
		||||
) -> None:
 | 
			
		||||
    """
 | 
			
		||||
    Türchen setzen
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    cfg.puzzle.doors = sorted(
 | 
			
		||||
    cal_cfg.doors = sorted(
 | 
			
		||||
        doors,
 | 
			
		||||
        key=lambda door: door.day,
 | 
			
		||||
    )
 | 
			
		||||
    await set_config(cfg)
 | 
			
		||||
    await set_calendar_config(cal_cfg)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue