configurable paths and names

This commit is contained in:
Jörn-Michael Miehe 2022-09-08 14:02:50 +00:00
parent baeff5c294
commit 43271bb6e3
5 changed files with 71 additions and 8 deletions

View file

@ -23,6 +23,7 @@ class TickerConfig(BaseModel):
Section "[ticker]" in "config.txt". Section "[ticker]" in "config.txt".
""" """
file_name: str = "ticker"
separator: str = " +++ " separator: str = " +++ "
comment_marker: str = "#" comment_marker: str = "#"
color: str = "primary" color: str = "primary"
@ -55,6 +56,9 @@ class Config(BaseModel):
Main representation of "config.txt". Main representation of "config.txt".
""" """
image_dir: str = "image"
text_dir: str = "text"
ticker: TickerConfig = TickerConfig() ticker: TickerConfig = TickerConfig()
image: ImageConfig = ImageConfig() image: ImageConfig = ImageConfig()
calendar: CalendarConfig = CalendarConfig() calendar: CalendarConfig = CalendarConfig()

View file

@ -68,6 +68,23 @@ def webdav_check() -> bool:
return True return True
def webdav_ensure_path(remote_path: str) -> None:
remote_path = f"{SETTINGS.webdav_prefix}/{remote_path}"
if _WEBDAV_CLIENT.check(remote_path):
_logger.debug(
"WebDAV path %s found.",
repr(remote_path),
)
return
_logger.info(
"WebDAV path %s not found, creating ...",
repr(remote_path),
)
_WEBDAV_CLIENT.mkdir(remote_path)
@lru_cache(maxsize=SETTINGS.cache_size) @lru_cache(maxsize=SETTINGS.cache_size)
def webdav_resource(remote_path: Any) -> WebDAVResource: def webdav_resource(remote_path: Any) -> WebDAVResource:
""" """

View file

@ -4,6 +4,7 @@ Dependables for defining Routers.
import re import re
from dataclasses import dataclass from dataclasses import dataclass
from logging import getLogger
from typing import Iterator, Protocol from typing import Iterator, Protocol
from fastapi import HTTPException, status from fastapi import HTTPException, status
@ -12,6 +13,8 @@ from webdav3.exceptions import RemoteResourceNotFound
from ..config import Config from ..config import Config
from ..dav_common import caldav_list, webdav_list from ..dav_common import caldav_list, webdav_list
_logger = getLogger(__name__)
class NameLister(Protocol): class NameLister(Protocol):
""" """
@ -37,7 +40,7 @@ class FileNameLister:
File names listed will be in `remote_path` and will match the RegEx `re`. File names listed will be in `remote_path` and will match the RegEx `re`.
""" """
remote_path: str path_name: str
re: re.Pattern[str] re: re.Pattern[str]
@property @property
@ -45,14 +48,20 @@ class FileNameLister:
return { return {
**_RESPONSE_OK, **_RESPONSE_OK,
status.HTTP_404_NOT_FOUND: { status.HTTP_404_NOT_FOUND: {
"description": f"{self.remote_path!r} not found", "description": f"{self.path_name!r} not found",
"content": None, "content": None,
}, },
} }
@property
async def remote_path(self) -> str:
cfg = await Config.get()
return str(cfg.dict()[self.path_name])
async def __call__(self) -> Iterator[str]: async def __call__(self) -> Iterator[str]:
try: try:
file_names = await webdav_list(self.remote_path) file_names = await webdav_list(await self.remote_path)
return ( return (
name name
@ -61,6 +70,10 @@ class FileNameLister:
) )
except RemoteResourceNotFound: except RemoteResourceNotFound:
_logger.error(
"WebDAV path %s lost!",
repr(await self.remote_path),
)
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND) raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)

View file

@ -8,6 +8,7 @@ Router "image" provides:
import re import re
from io import BytesIO from io import BytesIO
from logging import getLogger
from typing import Iterator from typing import Iterator
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
@ -15,13 +16,16 @@ from fastapi.responses import StreamingResponse
from PIL import Image from PIL import Image
from ..config import Config from ..config import Config
from ..dav_common import webdav_ensure_path
from ..dav_file import DavFile from ..dav_file import DavFile
from ._common import FileNameLister, PrefixFinder, PrefixUnique from ._common import FileNameLister, PrefixFinder, PrefixUnique
_logger = getLogger(__name__)
router = APIRouter(prefix="/image", tags=["image"]) router = APIRouter(prefix="/image", tags=["image"])
image_lister = FileNameLister( image_lister = FileNameLister(
remote_path="img", path_name="image_dir",
re=re.compile( re=re.compile(
r"\.(gif|jpe?g|tiff?|png|bmp)$", r"\.(gif|jpe?g|tiff?|png|bmp)$",
flags=re.IGNORECASE, flags=re.IGNORECASE,
@ -32,6 +36,13 @@ image_finder = PrefixFinder(image_lister)
image_unique = PrefixUnique(image_finder) image_unique = PrefixUnique(image_finder)
@router.on_event("startup")
async def start_router() -> None:
_logger.debug(f"{router.prefix} router starting.")
webdav_ensure_path(await image_lister.remote_path)
@router.get( @router.get(
"/list", "/list",
response_model=list[str], response_model=list[str],
@ -65,7 +76,7 @@ async def get_image(
) -> StreamingResponse: ) -> StreamingResponse:
cfg = await Config.get() cfg = await Config.get()
dav_file = DavFile(f"{image_lister.remote_path}/{name}") dav_file = DavFile(f"{await image_lister.remote_path}/{name}")
img = Image.open( img = Image.open(
BytesIO(await dav_file.as_bytes) BytesIO(await dav_file.as_bytes)
).convert( ).convert(

View file

@ -10,19 +10,23 @@ Router "text" provides:
""" """
import re import re
from logging import getLogger
from typing import Iterator from typing import Iterator
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from markdown import markdown from markdown import markdown
from ..config import Config from ..config import Config
from ..dav_common import webdav_ensure_path
from ..dav_file import DavFile from ..dav_file import DavFile
from ._common import FileNameLister, PrefixFinder, PrefixUnique from ._common import FileNameLister, PrefixFinder, PrefixUnique
_logger = getLogger(__name__)
router = APIRouter(prefix="/text", tags=["text"]) router = APIRouter(prefix="/text", tags=["text"])
text_lister = FileNameLister( text_lister = FileNameLister(
remote_path="text", path_name="text_dir",
re=re.compile( re=re.compile(
r"\.(txt|md)$", r"\.(txt|md)$",
flags=re.IGNORECASE, flags=re.IGNORECASE,
@ -33,8 +37,20 @@ text_finder = PrefixFinder(text_lister)
text_unique = PrefixUnique(text_finder) text_unique = PrefixUnique(text_finder)
@router.on_event("startup")
async def start_router() -> None:
_logger.debug(f"{router.prefix} router starting.")
webdav_ensure_path(await text_lister.remote_path)
async def get_ticker_lines() -> Iterator[str]: async def get_ticker_lines() -> Iterator[str]:
ticker = await DavFile("text/ticker.txt").as_string cfg = await Config.get()
file_name = await text_unique(cfg.ticker.file_name)
ticker = await DavFile(
f"{await text_lister.remote_path}/{file_name}",
).as_string
return ( return (
line.strip() line.strip()
@ -105,7 +121,9 @@ async def find_texts(
async def get_text_content( async def get_text_content(
name: str = Depends(text_unique), name: str = Depends(text_unique),
) -> str: ) -> str:
return await DavFile(f"{text_lister.remote_path}/{name}").as_string return await DavFile(
f"{await text_lister.remote_path}/{name}",
).as_string
@router.get( @router.get(