diff --git a/api/advent22_api/config.py b/api/advent22_api/config.py
index c4948d6..53e78c4 100644
--- a/api/advent22_api/config.py
+++ b/api/advent22_api/config.py
@@ -1,7 +1,10 @@
-import tomli
+import tomllib
+from typing import TypeAlias
+
+import tomli_w
from pydantic import BaseModel
-from .dav_common import dav_get_textfile_content
+from .dav_common import dav_get_textfile_content, dav_write_textfile_content
from .settings import SETTINGS
@@ -16,12 +19,33 @@ class Puzzle(BaseModel):
solution: str
+class Door(BaseModel):
+ day: int
+ x1: int
+ y1: int
+ x2: int
+ y2: int
+
+
+Doors: TypeAlias = list[Door] | None
+
+
class Config(BaseModel):
admin: User
puzzle: Puzzle
+ doors: Doors = []
async def get_config() -> Config:
txt = await dav_get_textfile_content(path=SETTINGS.config_filename)
- return Config.model_validate(tomli.loads(txt))
+ return Config.model_validate(tomllib.loads(txt))
+
+
+async def set_config(cfg: Config) -> None:
+ txt = tomli_w.dumps(cfg.model_dump())
+
+ await dav_write_textfile_content(
+ path=SETTINGS.config_filename,
+ content=txt,
+ )
diff --git a/api/advent22_api/dav_common.py b/api/advent22_api/dav_common.py
index 7903fe5..264182a 100644
--- a/api/advent22_api/dav_common.py
+++ b/api/advent22_api/dav_common.py
@@ -42,3 +42,14 @@ async def dav_get_textfile_content(path: str, encoding="utf-8") -> str:
tio = TextIOWrapper(buffer, encoding=encoding)
tio.seek(0)
return tio.read().strip()
+
+
+async def dav_write_file(path: str, buffer: BytesIO) -> None:
+ resource = _WEBDAV_CLIENT.resource(path)
+ resource.read_from(buffer)
+
+
+async def dav_write_textfile_content(path: str, content: str, encoding="utf-8") -> None:
+ buffer = BytesIO(content.encode(encoding=encoding))
+ buffer.seek(0)
+ await dav_write_file(path, buffer)
diff --git a/api/advent22_api/routers/general.py b/api/advent22_api/routers/general.py
index 9d1059d..49ac110 100644
--- a/api/advent22_api/routers/general.py
+++ b/api/advent22_api/routers/general.py
@@ -2,7 +2,7 @@ from fastapi import APIRouter, Depends
from fastapi.responses import StreamingResponse
from PIL import Image
-from ..config import Config, get_config
+from ..config import Config, Doors, get_config, set_config
from ..dav_common import dav_get_file
from ._misc import api_return_image
@@ -23,3 +23,27 @@ async def get_image_for_day(
return await api_return_image(
Image.open(await dav_get_file(f"files/{cfg.puzzle.background}"))
)
+
+
+@router.get("/doors")
+async def get_doors(
+ cfg: Config = Depends(get_config),
+) -> Doors:
+ """
+ Türchen lesen
+ """
+
+ return cfg.doors
+
+
+@router.put("/doors")
+async def put_doors(
+ doors: Doors,
+ cfg: Config = Depends(get_config),
+) -> None:
+ """
+ Türchen setzen
+ """
+
+ cfg.doors = doors
+ await set_config(cfg)
diff --git a/api/poetry.lock b/api/poetry.lock
index a23af90..24dcc1e 100644
--- a/api/poetry.lock
+++ b/api/poetry.lock
@@ -809,14 +809,14 @@ anyio = ">=3.4.0,<5"
full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyaml"]
[[package]]
-name = "tomli"
-version = "2.0.1"
-description = "A lil' TOML parser"
+name = "tomli-w"
+version = "1.0.0"
+description = "A lil' TOML writer"
optional = false
python-versions = ">=3.7"
files = [
- {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
- {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
+ {file = "tomli_w-1.0.0-py3-none-any.whl", hash = "sha256:9f2a07e8be30a0729e533ec968016807069991ae2fd921a78d42f429ae5f4463"},
+ {file = "tomli_w-1.0.0.tar.gz", hash = "sha256:f463434305e0336248cac9c2dc8076b707d8a12d019dd349f5c1e382dd1ae1b9"},
]
[[package]]
@@ -1047,4 +1047,4 @@ files = [
[metadata]
lock-version = "2.0"
python-versions = "^3.11"
-content-hash = "eeefab88869cda6b9d33e27e438365cdaa4ff191d34e8b0229364b00678a0fd4"
+content-hash = "c2a27f4ecbc1c234d1368320db111d6c51cd4278986e64e80398cad384037a8c"
diff --git a/api/pyproject.toml b/api/pyproject.toml
index fc47f21..c472e49 100644
--- a/api/pyproject.toml
+++ b/api/pyproject.toml
@@ -13,11 +13,11 @@ Pillow = "^10.0.0"
async-cache = "^1.1.1"
fastapi = "^0.103.1"
numpy = "^1.25.2"
+pydantic-settings = "^2.0.3"
python = "^3.11"
-tomli = "^2.0.1"
+tomli-w = "^1.0.0"
uvicorn = {extras = ["standard"], version = "^0.23.2"}
webdavclient3 = "^3.14.6"
-pydantic-settings = "^2.0.3"
[tool.poetry.group.dev.dependencies]
flake8 = "^6.1.0"
diff --git a/ui/src/components/DoorMapEditor.vue b/ui/src/components/DoorMapEditor.vue
index 6cd7b54..059421a 100644
--- a/ui/src/components/DoorMapEditor.vue
+++ b/ui/src/components/DoorMapEditor.vue
@@ -8,6 +8,13 @@
+
+ Laden
+
("/general/doors")
+ .then((data) => {
+ this.doors.length = 0;
+
+ for (const value of data) {
+ this.doors.push(Door.deserialize(value));
+ }
+ });
+ }
+
public save_doors() {
const data: DoorSerialized[] = [];
@@ -58,8 +77,7 @@ export default class extends Vue {
data.push(door.serialized);
}
- console.log(data);
- console.log(Door.deserialize(data[0]));
+ this.$advent22.api_put("/general/doors", data);
}
}
diff --git a/ui/src/plugins/advent22.ts b/ui/src/plugins/advent22.ts
index 64a6894..9b23b13 100644
--- a/ui/src/plugins/advent22.ts
+++ b/ui/src/plugins/advent22.ts
@@ -89,6 +89,19 @@ export class Advent22 {
public api_get_number(endpoint: string): Promise {
return this.api_get(endpoint);
}
+
+ public api_get_json(endpoint: string): Promise {
+ return this.api_get(endpoint);
+ }
+
+ public api_put(endpoint: string, data: unknown): Promise {
+ return new Promise((resolve, reject) =>
+ this.axios
+ .put(this.api_url(endpoint), data)
+ .then(() => resolve())
+ .catch(reject),
+ );
+ }
}
export const Advent22Plugin: Plugin = {