ovdashboard/api/ovdashboard_api/dav_calendar.py

72 lines
1.8 KiB
Python

import logging
from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import Iterator
from caldav import Calendar
from pydantic import BaseModel
from vobject.base import VBase
from . import caldav_principal, get_ttl_hash, run_in_executor, timed_alru_cache
_logger = logging.getLogger(__name__)
class CalEvent(BaseModel):
summary: str
description: str
dtstart: datetime
dtend: datetime
@timed_alru_cache(maxsize=20)
async def _get_calendar(
calendar_name: str,
) -> Calendar:
@run_in_executor
def _get_calendar_inner() -> Calendar:
_logger.info(f"updating {calendar_name}")
print(f"updating {calendar_name}")
return caldav_principal().calendar(calendar_name)
return await _get_calendar_inner()
@dataclass(frozen=True)
class DavCalendar:
calendar_name: str
@property
async def calendar(self) -> Calendar:
return await _get_calendar(
ttl_hash=get_ttl_hash(20),
calendar_name=self.calendar_name,
)
@property
async def events(self) -> Iterator[CalEvent]:
async def _find_vevents() -> Iterator[VBase]:
calendar = await self.calendar
return (
vevent
for event in calendar.date_search(
start=datetime.now(),
end=datetime.now() + timedelta(days=365),
expand=True,
)
for vevent in event.vobject_instance.contents["vevent"]
)
return (
CalEvent(
summary=vevent.summary.value,
description=vevent.description.value,
dtstart=vevent.dtstart.value,
dtend=vevent.dtend.value,
)
for vevent in await _find_vevents()
)