99 lines
3.5 KiB
Python
99 lines
3.5 KiB
Python
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 - timedelta(days=1)
|
|
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.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}"
|