from datetime import datetime, date, timedelta, timezone from caldav.objects import Event as CaldavEvent import dataclasses from icalendar import Event as IcEvent from icalendar import Calendar as Icalendar @dataclasses.dataclass class Event(): summary: str dtstart: datetime dtend: datetime is_all_day: bool @classmethod def fromCalDavEvents(cls, caldav_events: [CaldavEvent]) -> list['Event']: events = [] for event in caldav_events: date_value = event.vobject_instance.vevent.dtstart.value if isinstance(date_value, datetime): dt_start = date_value is_all_day = False elif isinstance(date_value, date): d_start = date_value dt_start = datetime(d_start.year, d_start.month, d_start.day, tzinfo=datetime.now(timezone.utc).astimezone().tzinfo) is_all_day = True else: raise Exception date_value = event.vobject_instance.vevent.dtend.value if isinstance(date_value, datetime): dt_end = date_value elif isinstance(date_value, date): d_end = date_value dt_end = datetime(d_end.year, d_end.month, d_end.day,tzinfo=datetime.now(timezone.utc).astimezone().tzinfo) date_value = dt_end else: raise Exception events.append(Event( summary=event.vobject_instance.vevent.summary.value, dtstart=dt_start, dtend=dt_end, is_all_day = is_all_day )) return events @classmethod def fromIcalendar(cls, icalendar: Icalendar) -> list['Event']: events = [] for event in [e for e in icalendar.subcomponents if isinstance(e, IcEvent)]: date_value = event['DTSTART'].dt if isinstance(date_value, datetime): dt_start = date_value is_all_day = False elif isinstance(date_value, date): d_start = date_value dt_start = datetime(d_start.year, d_start.month, d_start.day, tzinfo=datetime.now(timezone.utc).astimezone().tzinfo) is_all_day = True else: raise Exception date_value = event['DTEND'].dt if event.get('DTEND') else event['DTSTART'].dt if isinstance(date_value, datetime): dt_end = date_value elif isinstance(date_value, date): d_end = date_value dt_end = datetime(d_end.year, d_end.month, d_end.day,tzinfo=datetime.now(timezone.utc).astimezone().tzinfo) else: raise Exception events.append(Event( summary=event['summary'], dtstart=dt_start, dtend=dt_end, is_all_day = is_all_day )) return events @property def range_str(self) -> str: start_time_str = self.dtstart.strftime('%-I') end_time_str = self.dtend.strftime('%-I') if not(self.dtstart.hour and self.dtend.hour): return "" if self.dtstart.minute: start_time_str += self.dtstart.strftime(':%M') if self.dtend.minute: end_time_str += self.dtend.strftime(':%M') if not ((self.dtstart.hour < 12 and self.dtend.hour < 12) or (self.dtstart.hour > 12 and self.dtend.hour > 12)): start_time_str += self.dtstart.strftime("%p") end_time_str += self.dtend.strftime("%p") return f"{start_time_str}-{end_time_str}"