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 logging
import tomllib
from typing import Any from typing import Any
from pydantic import BaseModel 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__) _logger = logging.getLogger(__name__)
@ -107,28 +101,3 @@ class Config(BaseModel):
server: ServerUIConfig = ServerUIConfig() server: ServerUIConfig = ServerUIConfig()
ticker: TickerConfig = TickerConfig() ticker: TickerConfig = TickerConfig()
calendar: CalendarConfig = CalendarConfig() 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 logging
import re import re
from dataclasses import dataclass, field import tomllib
from typing import Awaitable, Callable, Generic, ParamSpec, Self, TypeVar
import tomli_w
from fastapi import Depends, HTTPException, params, status from fastapi import Depends, HTTPException, params, status
from webdav3.exceptions import RemoteResourceNotFound from webdav3.exceptions import RemoteResourceNotFound
from ...core.caldav import CalDAV 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 ...core.webdav import WebDAV
from ._list_manager import Dependable, DependableFn, ListManager
_logger = logging.getLogger(__name__) _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) except RemoteResourceNotFound:
class Dependable(Generic[Params, Return]): _logger.warning(
func: DependableFn[Params, Return] f"Config file {SETTINGS.webdav.config_filename!r} not found, creating ..."
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 cfg = Config()
def from_lister_fn(cls, lister_fn: DependableFn[[], list[str]]) -> Self: cfg.calendar.aggregates["All Events"] = list(await CalDAV.calendars)
return cls.from_lister(Dependable(lister_fn))
await WebDAV.write_str(
SETTINGS.webdav.config_filename,
tomli_w.dumps(cfg.model_dump()),
)
return cfg
def get_remote_path( 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.caldav import CalDAV
from ...core.calevent import CalEvent from ...core.calevent import CalEvent
from ...core.config import Config, get_config from ...core.config import Config
from ._common import LM_AGGREGATES, LM_CALENDARS from ._common import LM_AGGREGATES, LM_CALENDARS, get_config
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)

View file

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

View file

@ -13,10 +13,10 @@ from fastapi import APIRouter, Depends
from fastapi.responses import StreamingResponse from fastapi.responses import StreamingResponse
from PIL import Image 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.dav_common import webdav_ensure_files, webdav_ensure_path
from ...core.webdav import WebDAV 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__) _logger = logging.getLogger(__name__)

View file

@ -11,8 +11,9 @@ from socket import AF_INET, SOCK_DGRAM, socket
from fastapi import APIRouter, Depends 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 ...core.settings import SETTINGS
from ._common import get_config
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)

View file

@ -12,10 +12,10 @@ from typing import Iterator
import markdown import markdown
from fastapi import APIRouter, Depends 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.dav_common import webdav_ensure_files, webdav_ensure_path
from ...core.webdav import WebDAV 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__) _logger = logging.getLogger(__name__)