refac: move stuff to and from _common

This commit is contained in:
Jörn-Michael Miehe 2023-10-26 18:26:51 +02:00
parent 3a255db15a
commit 9551ee7729
8 changed files with 120 additions and 110 deletions

View file

@ -3,15 +3,9 @@ Python representation of the "config.txt" file inside the WebDAV directory.
"""
import logging
import tomllib
from typing import Any
from pydantic import BaseModel
from webdav3.exceptions import RemoteResourceNotFound
# from .caldav import CalDAV
from .settings import SETTINGS
from .webdav import WebDAV
_logger = logging.getLogger(__name__)
@ -107,28 +101,3 @@ class Config(BaseModel):
server: ServerUIConfig = ServerUIConfig()
ticker: TickerConfig = TickerConfig()
calendar: CalendarConfig = CalendarConfig()
async def get_config() -> Config:
"""
Load the configuration instance from the server using `TOML`.
"""
try:
cfg_str = await WebDAV.read_str(SETTINGS.webdav.config_filename)
cfg = Config.model_validate(tomllib.loads(cfg_str))
except RemoteResourceNotFound:
_logger.warning(
f"Config file {SETTINGS.webdav.config_filename!r} not found, creating ..."
)
cfg = Config()
# cfg.calendar.aggregates["All Events"] = list(await CalDAV.calendars)
# await WebDAV.write_str(
# SETTINGS.webdav.config_filename,
# tomli_w.dumps(cfg.model_dump()),
# )
return cfg

View file

@ -4,15 +4,17 @@ Dependables for defining Routers.
import logging
import re
from dataclasses import dataclass, field
from typing import Awaitable, Callable, Generic, ParamSpec, Self, TypeVar
import tomllib
import tomli_w
from fastapi import Depends, HTTPException, params, status
from webdav3.exceptions import RemoteResourceNotFound
from ...core.caldav import CalDAV
from ...core.config import Config, get_config
from ...core.config import Config
from ...core.settings import SETTINGS
from ...core.webdav import WebDAV
from ._list_manager import Dependable, DependableFn, ListManager
_logger = logging.getLogger(__name__)
@ -22,78 +24,30 @@ _RESPONSE_OK = {
},
}
Params = ParamSpec("Params")
Return = TypeVar("Return")
type DependableFn[**Params, Return] = Callable[Params, Awaitable[Return]]
async def get_config() -> Config:
"""
Load the configuration instance from the server using `TOML`.
"""
try:
cfg_str = await WebDAV.read_str(SETTINGS.webdav.config_filename)
cfg = Config.model_validate(tomllib.loads(cfg_str))
@dataclass(slots=True, frozen=True)
class Dependable(Generic[Params, Return]):
func: DependableFn[Params, Return]
responses: dict = field(default_factory=lambda: _RESPONSE_OK.copy())
@dataclass(slots=True, frozen=True)
class ListManager:
lister: Dependable[[], list[str]]
filter: Dependable[[str], list[str]]
getter: Dependable[[str], str]
@classmethod
def from_lister(cls, lister: Dependable[[], list[str]]) -> Self:
async def _filter_fn(
prefix: str,
names: list[str] = Depends(lister.func),
) -> list[str]:
if isinstance(names, params.Depends):
names = await lister.func()
_logger.debug("filter %s from %s", repr(prefix), repr(names))
return [item for item in names if item.lower().startswith(prefix.lower())]
async def _getter_fn(
prefix: str,
names: list[str] = Depends(_filter_fn),
) -> str:
if isinstance(names, params.Depends):
names = await _filter_fn(prefix)
_logger.debug("get %s from %s", repr(prefix), repr(names))
match names:
case [name]:
return name
case []:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
case _:
raise HTTPException(status_code=status.HTTP_409_CONFLICT)
return cls(
lister=lister,
filter=Dependable(_filter_fn),
getter=Dependable(
func=_getter_fn,
responses={
**_RESPONSE_OK,
status.HTTP_404_NOT_FOUND: {
"description": "Prefix not found",
"content": None,
},
status.HTTP_409_CONFLICT: {
"description": "Ambiguous prefix",
"content": None,
},
},
),
except RemoteResourceNotFound:
_logger.warning(
f"Config file {SETTINGS.webdav.config_filename!r} not found, creating ..."
)
@classmethod
def from_lister_fn(cls, lister_fn: DependableFn[[], list[str]]) -> Self:
return cls.from_lister(Dependable(lister_fn))
cfg = Config()
cfg.calendar.aggregates["All Events"] = list(await CalDAV.calendars)
await WebDAV.write_str(
SETTINGS.webdav.config_filename,
tomli_w.dumps(cfg.model_dump()),
)
return cfg
def get_remote_path(

View file

@ -0,0 +1,86 @@
import logging
from dataclasses import dataclass, field
from typing import Awaitable, Callable, Generic, ParamSpec, Self, TypeVar
from fastapi import Depends, HTTPException, params, status
_logger = logging.getLogger(__name__)
_RESPONSE_OK = {
status.HTTP_200_OK: {
"description": "Operation successful",
},
}
Params = ParamSpec("Params")
Return = TypeVar("Return")
type DependableFn[**Params, Return] = Callable[Params, Awaitable[Return]]
@dataclass(slots=True, frozen=True)
class Dependable(Generic[Params, Return]):
func: DependableFn[Params, Return]
responses: dict = field(default_factory=lambda: _RESPONSE_OK.copy())
@dataclass(slots=True, frozen=True)
class ListManager:
lister: Dependable[[], list[str]]
filter: Dependable[[str], list[str]]
getter: Dependable[[str], str]
@classmethod
def from_lister(cls, lister: Dependable[[], list[str]]) -> Self:
async def _filter_fn(
prefix: str,
names: list[str] = Depends(lister.func),
) -> list[str]:
if isinstance(names, params.Depends):
names = await lister.func()
_logger.debug("filter %s from %s", repr(prefix), repr(names))
return [item for item in names if item.lower().startswith(prefix.lower())]
async def _getter_fn(
prefix: str,
names: list[str] = Depends(_filter_fn),
) -> str:
if isinstance(names, params.Depends):
names = await _filter_fn(prefix)
_logger.debug("get %s from %s", repr(prefix), repr(names))
match names:
case [name]:
return name
case []:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
case _:
raise HTTPException(status_code=status.HTTP_409_CONFLICT)
return cls(
lister=lister,
filter=Dependable(_filter_fn),
getter=Dependable(
func=_getter_fn,
responses={
**_RESPONSE_OK,
status.HTTP_404_NOT_FOUND: {
"description": "Prefix not found",
"content": None,
},
status.HTTP_409_CONFLICT: {
"description": "Ambiguous prefix",
"content": None,
},
},
),
)
@classmethod
def from_lister_fn(cls, lister_fn: DependableFn[[], list[str]]) -> Self:
return cls.from_lister(Dependable(lister_fn))

View file

@ -12,8 +12,8 @@ from fastapi import APIRouter, Depends
from ...core.caldav import CalDAV
from ...core.calevent import CalEvent
from ...core.config import Config, get_config
from ._common import LM_AGGREGATES, LM_CALENDARS
from ...core.config import Config
from ._common import LM_AGGREGATES, LM_CALENDARS, get_config
_logger = logging.getLogger(__name__)

View file

@ -11,8 +11,8 @@ import logging
from fastapi import APIRouter, Depends
from ...core.caldav import CalDAV, CalEvent
from ...core.config import CalendarUIConfig, Config, get_config
from ._common import LM_CALENDARS
from ...core.config import CalendarUIConfig, Config
from ._common import LM_CALENDARS, get_config
_logger = logging.getLogger(__name__)

View file

@ -13,10 +13,10 @@ from fastapi import APIRouter, Depends
from fastapi.responses import StreamingResponse
from PIL import Image
from ...core.config import Config, ImageUIConfig, get_config
from ...core.config import Config, ImageUIConfig
from ...core.dav_common import webdav_ensure_files, webdav_ensure_path
from ...core.webdav import WebDAV
from ._common import LM_IMAGE, RP_IMAGE
from ._common import LM_IMAGE, RP_IMAGE, get_config
_logger = logging.getLogger(__name__)

View file

@ -11,8 +11,9 @@ from socket import AF_INET, SOCK_DGRAM, socket
from fastapi import APIRouter, Depends
from ...core.config import Config, LogoUIConfig, ServerUIConfig, get_config
from ...core.config import Config, LogoUIConfig, ServerUIConfig
from ...core.settings import SETTINGS
from ._common import get_config
_logger = logging.getLogger(__name__)

View file

@ -12,10 +12,10 @@ from typing import Iterator
import markdown
from fastapi import APIRouter, Depends
from ...core.config import Config, TickerUIConfig, get_config
from ...core.config import Config, TickerUIConfig
from ...core.dav_common import webdav_ensure_files, webdav_ensure_path
from ...core.webdav import WebDAV
from ._common import LM_TEXT, RP_TEXT
from ._common import LM_TEXT, RP_TEXT, get_config
_logger = logging.getLogger(__name__)