diff --git a/api/ovkiosk/__init__.py b/api/ovkiosk/__init__.py index e69de29..ed4b250 100644 --- a/api/ovkiosk/__init__.py +++ b/api/ovkiosk/__init__.py @@ -0,0 +1,9 @@ +from webdav3.client import Client + +from .config import SETTINGS + +CLIENT = Client({ + "webdav_hostname": SETTINGS.webdav_url, + "webdav_login": SETTINGS.dav_username, + "webdav_password": SETTINGS.dav_password, +}) diff --git a/api/ovkiosk/config.py b/api/ovkiosk/config.py index d70f7e7..0a641e6 100644 --- a/api/ovkiosk/config.py +++ b/api/ovkiosk/config.py @@ -24,11 +24,12 @@ class Settings(BaseSettings): redoc_url: Optional[str] = "/redoc" caldav_base_url: str = "/remote.php/dav" - webdav_base_url: str = "/remote.php/webdav" + webdav_base_url: str = "/remote.php/webdav/ovkiosk" dav_protocol: str = "https" dav_host: str = "example.com" dav_username: str = "ovkiosk" dav_password: str = "changeme" + dav_path: str = "ovkiosk" @property def caldav_url(self) -> str: diff --git a/api/ovkiosk/dav_file.py b/api/ovkiosk/dav_file.py new file mode 100644 index 0000000..e802f4e --- /dev/null +++ b/api/ovkiosk/dav_file.py @@ -0,0 +1,44 @@ +import logging +import threading +from io import BytesIO +from typing import Any + +from webdav3.client import Client, Resource + +_logger = logging.getLogger(__name__) + + +class DavFile: + def __init__(self, client: Client, path: Any) -> None: + self.__resource: Resource = client.resource(path) + self.__buffer = BytesIO() + self.__lock = threading.Lock() + + def update(self) -> None: + _logger.debug(f"updating {self.__resource}") + with self.__lock: + self.__buffer.seek(0) + self.__buffer.truncate(0) + self.__resource.write_to(self.__buffer) + + def refresh(self, refresh_interval: int = 5) -> threading.Event: + stop_handle = threading.Event() + + def refresh_loop() -> None: + while not stop_handle.wait(refresh_interval): + self.update() + + thread = threading.Thread(target=refresh_loop) + thread.daemon = True + thread.start() + + return stop_handle + + @property + def bytes(self) -> bytes: + with self.__lock: + self.__buffer.seek(0) + return self.__buffer.read() + + def __str__(self) -> str: + return self.bytes.decode(encoding="utf-8") diff --git a/api/ovkiosk/main.py b/api/ovkiosk/main.py index 64e2244..e79d2ef 100644 --- a/api/ovkiosk/main.py +++ b/api/ovkiosk/main.py @@ -10,7 +10,6 @@ If run directly, uses `uvicorn` to run the app. import uvicorn from fastapi import FastAPI -from webdav3.client import Client from .config import SETTINGS from .routers import main_router @@ -31,14 +30,6 @@ app.include_router(main_router) def main() -> None: - options = { - "webdav_hostname": SETTINGS.webdav_url, - "webdav_login": SETTINGS.dav_username, - "webdav_password": SETTINGS.dav_password, - } - client = Client(options) - print(client.list()) - uvicorn.run( app="ovkiosk.main:app", host="0.0.0.0", diff --git a/api/ovkiosk/routers/__init__.py b/api/ovkiosk/routers/__init__.py index 2c0400b..a99e554 100644 --- a/api/ovkiosk/routers/__init__.py +++ b/api/ovkiosk/routers/__init__.py @@ -7,8 +7,10 @@ This file: Main API router definition. from fastapi import APIRouter from ..config import SETTINGS +from . import text main_router = APIRouter(prefix=f"/{SETTINGS.api_v1_prefix}") +main_router.include_router(text.router) __all__ = [ "main_router", diff --git a/api/ovkiosk/routers/text.py b/api/ovkiosk/routers/text.py new file mode 100644 index 0000000..1f3d3f5 --- /dev/null +++ b/api/ovkiosk/routers/text.py @@ -0,0 +1,38 @@ +import logging + +from fastapi import APIRouter + +from .. import CLIENT +from ..dav_file import DavFile + +router = APIRouter(prefix="/text", tags=["text"]) + +_logger = logging.getLogger(__name__) + +_message = DavFile(client=CLIENT, path="message.txt") +_ticker = DavFile(client=CLIENT, path="ticker.txt") +_title = DavFile(client=CLIENT, path="title.txt") + + +@router.on_event("startup") +async def on_startup(): + _logger.debug("text router startup") + + _message.refresh() + _ticker.refresh() + _title.refresh() + + +@router.get("/message") +async def get_message(): + return str(_message) + + +@router.get("/ticker") +async def get_ticker(): + return str(_ticker) + + +@router.get("/title") +async def get_title(): + return str(_title)