refac: fix calendar router
This commit is contained in:
parent
fc2388dd12
commit
cdf4ce4d16
4 changed files with 71 additions and 72 deletions
|
@ -21,8 +21,8 @@ class CalDAV:
|
||||||
password=SETTINGS.caldav.password,
|
password=SETTINGS.caldav.password,
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@property
|
||||||
def principal(cls) -> Principal:
|
def principal(cls) -> Principal:
|
||||||
"""
|
"""
|
||||||
Gets the `Principal` object of the main CalDAV client.
|
Gets the `Principal` object of the main CalDAV client.
|
||||||
|
@ -31,6 +31,7 @@ class CalDAV:
|
||||||
_logger.debug("principal")
|
_logger.debug("principal")
|
||||||
return cls._caldav_client.principal()
|
return cls._caldav_client.principal()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
@property
|
@property
|
||||||
@AsyncTTL(
|
@AsyncTTL(
|
||||||
time_to_live=SETTINGS.caldav.cache_ttl,
|
time_to_live=SETTINGS.caldav.cache_ttl,
|
||||||
|
@ -38,7 +39,6 @@ class CalDAV:
|
||||||
skip_args=1,
|
skip_args=1,
|
||||||
)
|
)
|
||||||
@asyncify
|
@asyncify
|
||||||
@classmethod
|
|
||||||
def calendars(cls) -> list[str]:
|
def calendars(cls) -> list[str]:
|
||||||
"""
|
"""
|
||||||
Asynchroneously lists all calendars using the main WebDAV client.
|
Asynchroneously lists all calendars using the main WebDAV client.
|
||||||
|
|
|
@ -7,7 +7,7 @@ This file: Main API router definition.
|
||||||
from fastapi import APIRouter
|
from fastapi import APIRouter
|
||||||
|
|
||||||
# from . import aggregate, calendar, file, image, misc, text, ticker
|
# from . import aggregate, calendar, file, image, misc, text, ticker
|
||||||
from . import file, image, misc, text, ticker
|
from . import calendar, file, image, misc, text, ticker
|
||||||
|
|
||||||
router = APIRouter(prefix="/api/v1")
|
router = APIRouter(prefix="/api/v1")
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ router.include_router(ticker.router)
|
||||||
router.include_router(image.router)
|
router.include_router(image.router)
|
||||||
router.include_router(file.router)
|
router.include_router(file.router)
|
||||||
|
|
||||||
# router.include_router(calendar.router)
|
router.include_router(calendar.router)
|
||||||
# router.include_router(aggregate.router)
|
# router.include_router(aggregate.router)
|
||||||
|
|
||||||
__all__ = ["router"]
|
__all__ = ["router"]
|
||||||
|
|
|
@ -3,19 +3,17 @@ Dependables for defining Routers.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass, field
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
from typing import Awaitable, Callable, Generic, ParamSpec, TypeVar
|
from typing import Awaitable, Callable, Generic, ParamSpec, Self, TypeVar
|
||||||
|
|
||||||
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.config import get_config
|
from ...core.config import get_config
|
||||||
from ...core.webdav import WebDAV
|
from ...core.webdav import WebDAV
|
||||||
|
|
||||||
# from ...core.caldav import CalDAV
|
|
||||||
# from ...core.config import Config, get_config
|
|
||||||
|
|
||||||
_logger = getLogger(__name__)
|
_logger = getLogger(__name__)
|
||||||
|
|
||||||
_RESPONSE_OK = {
|
_RESPONSE_OK = {
|
||||||
|
@ -33,42 +31,34 @@ type _Dependable[**Params, Return] = Callable[Params, Awaitable[Return]]
|
||||||
@dataclass(slots=True, frozen=True)
|
@dataclass(slots=True, frozen=True)
|
||||||
class Dependable(Generic[Params, Return]):
|
class Dependable(Generic[Params, Return]):
|
||||||
func: _Dependable[Params, Return]
|
func: _Dependable[Params, Return]
|
||||||
responses: dict
|
responses: dict = field(default_factory=lambda: _RESPONSE_OK.copy())
|
||||||
|
|
||||||
|
|
||||||
@dataclass(init=False, slots=True, frozen=True)
|
@dataclass(slots=True, frozen=True)
|
||||||
class ListManager:
|
class ListManager:
|
||||||
lister: Dependable[[], list[str]]
|
lister: Dependable[[], list[str]]
|
||||||
filter: Dependable[[str], list[str]]
|
filter: Dependable[[str], list[str]]
|
||||||
getter: Dependable[[str], str]
|
getter: Dependable[[str], str]
|
||||||
|
|
||||||
def __init__(
|
@classmethod
|
||||||
self,
|
def from_lister(cls, lister: Dependable[[], list[str]]) -> Self:
|
||||||
lister: Dependable[[], list[str]],
|
async def _filter_fn(
|
||||||
) -> None:
|
|
||||||
object.__setattr__(self, "lister", lister)
|
|
||||||
|
|
||||||
async def _filter(
|
|
||||||
prefix: str,
|
prefix: str,
|
||||||
names: list[str] = Depends(self.lister.func),
|
names: list[str] = Depends(lister.func),
|
||||||
) -> list[str]:
|
) -> list[str]:
|
||||||
if isinstance(names, params.Depends):
|
if isinstance(names, params.Depends):
|
||||||
names = await self.lister.func()
|
names = await lister.func()
|
||||||
|
|
||||||
_logger.debug("filter %s from %s", repr(prefix), repr(names))
|
_logger.debug("filter %s from %s", repr(prefix), repr(names))
|
||||||
|
|
||||||
return [item for item in names if item.lower().startswith(prefix.lower())]
|
return [item for item in names if item.lower().startswith(prefix.lower())]
|
||||||
|
|
||||||
object.__setattr__(
|
async def _getter_fn(
|
||||||
self, "filter", Dependable(func=_filter, responses=_RESPONSE_OK)
|
|
||||||
)
|
|
||||||
|
|
||||||
async def _getter(
|
|
||||||
prefix: str,
|
prefix: str,
|
||||||
names: list[str] = Depends(self.filter.func),
|
names: list[str] = Depends(_filter_fn),
|
||||||
) -> str:
|
) -> str:
|
||||||
if isinstance(names, params.Depends):
|
if isinstance(names, params.Depends):
|
||||||
names = await self.filter.func(prefix)
|
names = await _filter_fn(prefix)
|
||||||
|
|
||||||
_logger.debug("get %s from %s", repr(prefix), repr(names))
|
_logger.debug("get %s from %s", repr(prefix), repr(names))
|
||||||
|
|
||||||
|
@ -82,11 +72,11 @@ class ListManager:
|
||||||
case _:
|
case _:
|
||||||
raise HTTPException(status_code=status.HTTP_409_CONFLICT)
|
raise HTTPException(status_code=status.HTTP_409_CONFLICT)
|
||||||
|
|
||||||
object.__setattr__(
|
return cls(
|
||||||
self,
|
lister=lister,
|
||||||
"getter",
|
filter=Dependable(_filter_fn),
|
||||||
Dependable(
|
getter=Dependable(
|
||||||
func=_getter,
|
func=_getter_fn,
|
||||||
responses={
|
responses={
|
||||||
**_RESPONSE_OK,
|
**_RESPONSE_OK,
|
||||||
status.HTTP_404_NOT_FOUND: {
|
status.HTTP_404_NOT_FOUND: {
|
||||||
|
@ -101,6 +91,10 @@ class ListManager:
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_lister_fn(cls, lister_fn: _Dependable[[], list[str]]) -> Self:
|
||||||
|
return cls.from_lister(Dependable(lister_fn))
|
||||||
|
|
||||||
|
|
||||||
def get_remote_path(
|
def get_remote_path(
|
||||||
path_name: str,
|
path_name: str,
|
||||||
|
@ -153,23 +147,28 @@ def get_file_lister(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
LM_FILE = ListManager(
|
LM_FILE = ListManager.from_lister(
|
||||||
get_file_lister(rp=RP_FILE, re=re.compile(r"[^/]$", flags=re.IGNORECASE))
|
get_file_lister(rp=RP_FILE, re=re.compile(r"[^/]$", flags=re.IGNORECASE))
|
||||||
)
|
)
|
||||||
LM_IMAGE = ListManager(
|
LM_IMAGE = ListManager.from_lister(
|
||||||
get_file_lister(
|
get_file_lister(
|
||||||
rp=RP_IMAGE, re=re.compile(r"\.(gif|jpe?g|tiff?|png|bmp)$", flags=re.IGNORECASE)
|
rp=RP_IMAGE, re=re.compile(r"\.(gif|jpe?g|tiff?|png|bmp)$", flags=re.IGNORECASE)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
LM_TEXT = ListManager(
|
LM_TEXT = ListManager.from_lister(
|
||||||
get_file_lister(rp=RP_TEXT, re=re.compile(r"\.(txt|md)$", flags=re.IGNORECASE))
|
get_file_lister(rp=RP_TEXT, re=re.compile(r"\.(txt|md)$", flags=re.IGNORECASE))
|
||||||
)
|
)
|
||||||
|
|
||||||
# async def list_calendar_names() -> list[str]:
|
|
||||||
# """
|
async def list_calendar_names() -> list[str]:
|
||||||
# List calendar names
|
"""
|
||||||
# """
|
List calendar names
|
||||||
# return await CalDAV.calendars
|
"""
|
||||||
|
|
||||||
|
return await CalDAV.calendars
|
||||||
|
|
||||||
|
|
||||||
|
LM_CALENDARS = ListManager.from_lister_fn(list_calendar_names)
|
||||||
|
|
||||||
|
|
||||||
# async def list_aggregate_names(
|
# async def list_aggregate_names(
|
||||||
|
@ -178,4 +177,8 @@ LM_TEXT = ListManager(
|
||||||
# """
|
# """
|
||||||
# List aggregate calendar names
|
# List aggregate calendar names
|
||||||
# """
|
# """
|
||||||
|
|
||||||
# return list(cfg.calendar.aggregates.keys())
|
# return list(cfg.calendar.aggregates.keys())
|
||||||
|
|
||||||
|
|
||||||
|
# LM_AGGREGATES = ListManager.from_lister_fn(list_aggregate_names)
|
||||||
|
|
|
@ -7,54 +7,50 @@ Router "calendar" provides:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
from typing import Iterator
|
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends
|
from fastapi import APIRouter, Depends
|
||||||
|
|
||||||
from ...config import CalendarUIConfig, Config
|
from ...core.caldav import CalDAV, CalEvent
|
||||||
from ...dav_calendar import CalEvent, DavCalendar
|
from ...core.config import CalendarUIConfig, Config, get_config
|
||||||
from ._common import CalendarNameLister, PrefixFinder, PrefixUnique
|
from ._common import LM_CALENDARS
|
||||||
|
|
||||||
_logger = getLogger(__name__)
|
_logger = getLogger(__name__)
|
||||||
|
|
||||||
router = APIRouter(prefix="/calendar", tags=["calendar"])
|
router = APIRouter(prefix="/calendar", tags=["calendar"])
|
||||||
|
|
||||||
calendar_lister = CalendarNameLister()
|
|
||||||
calendar_finder = PrefixFinder(calendar_lister)
|
|
||||||
calendar_unique = PrefixUnique(calendar_finder)
|
|
||||||
|
|
||||||
|
|
||||||
@router.on_event("startup")
|
@router.on_event("startup")
|
||||||
async def start_router() -> None:
|
async def start_router() -> None:
|
||||||
_logger.debug(f"{router.prefix} router starting.")
|
_logger.debug(f"{router.prefix} router starting.")
|
||||||
|
|
||||||
|
|
||||||
@router.get("/list", response_model=list[str])
|
|
||||||
async def list_calendars(
|
|
||||||
names: Iterator[str] = Depends(calendar_lister),
|
|
||||||
) -> list[str]:
|
|
||||||
return list(names)
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/find/{prefix}", response_model=list[str])
|
|
||||||
async def find_calendars(
|
|
||||||
names: Iterator[str] = Depends(calendar_finder),
|
|
||||||
) -> list[str]:
|
|
||||||
return list(names)
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/get/{prefix}", response_model=list[CalEvent])
|
|
||||||
async def get_calendar(
|
|
||||||
name: str = Depends(calendar_unique),
|
|
||||||
) -> list[CalEvent]:
|
|
||||||
return list(await DavCalendar(name).events)
|
|
||||||
|
|
||||||
|
|
||||||
@router.get(
|
@router.get(
|
||||||
"/config",
|
"/list",
|
||||||
response_model=CalendarUIConfig,
|
responses=LM_CALENDARS.lister.responses,
|
||||||
)
|
)
|
||||||
|
async def list_all_calendars(
|
||||||
|
names: list[str] = Depends(LM_CALENDARS.lister.func),
|
||||||
|
) -> list[str]:
|
||||||
|
return names
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/find/{prefix}")
|
||||||
|
async def find_calendars(
|
||||||
|
names: list[str] = Depends(LM_CALENDARS.filter.func),
|
||||||
|
) -> list[str]:
|
||||||
|
return names
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/get/{prefix}")
|
||||||
|
async def get_calendar(
|
||||||
|
name: str = Depends(LM_CALENDARS.getter.func),
|
||||||
|
cfg: Config = Depends(get_config),
|
||||||
|
) -> list[CalEvent]:
|
||||||
|
return CalDAV.get_events(name, cfg)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/config")
|
||||||
async def get_ui_config(
|
async def get_ui_config(
|
||||||
cfg: Config = Depends(Config.get),
|
cfg: Config = Depends(get_config),
|
||||||
) -> CalendarUIConfig:
|
) -> CalendarUIConfig:
|
||||||
return cfg.calendar
|
return cfg.calendar
|
||||||
|
|
Loading…
Reference in a new issue