diff --git a/api/ovdashboard_api/dav_calendar.py b/api/ovdashboard_api/dav_calendar.py index 9376955..e0209ec 100644 --- a/api/ovdashboard_api/dav_calendar.py +++ b/api/ovdashboard_api/dav_calendar.py @@ -5,7 +5,7 @@ from typing import Iterator from caldav import Calendar from pydantic import BaseModel -from vobject.base import VBase +from vobject.icalendar import VEvent from . import caldav_principal, get_ttl_hash, run_in_executor, timed_alru_cache @@ -26,14 +26,43 @@ async def _get_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() +@timed_alru_cache(maxsize=20) +async def _get_calendar_events( + calendar_name: str, +) -> list[CalEvent]: + + @run_in_executor + def _inner() -> Iterator[VEvent]: + _logger.info(f"updating {calendar_name}") + print(f"updating {calendar_name}") + + calendar = caldav_principal().calendar(calendar_name) + 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 _inner() + ] + + @dataclass(frozen=True) class DavCalendar: calendar_name: str @@ -46,27 +75,8 @@ class DavCalendar: ) @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() + async def events(self) -> list[CalEvent]: + return await _get_calendar_events( + ttl_hash=get_ttl_hash(20), + calendar_name=self.calendar_name, )