E-Paper-Calendar/Calendar/IcalEvents.py

122 lines
4.3 KiB
Python
Raw Normal View History

2019-02-26 22:08:19 +01:00
from CalendarInterface import CalendarInterface
from CalendarEvent import CalendarEvent
from ics import Calendar
from datetime import datetime, timedelta, timezone
import re
2019-02-26 22:08:19 +01:00
from settings import week_starts_on
2019-04-17 16:42:28 +02:00
from urllib.request import urlopen
2019-02-26 22:08:19 +01:00
2019-07-13 08:05:35 +02:00
2019-02-26 22:08:19 +01:00
class IcalEvents(CalendarInterface):
"""Fetches events from ical addresses."""
2019-07-13 08:05:35 +02:00
def __init__(self, urls, highlighted_urls=None):
2019-02-26 22:08:19 +01:00
self.urls = urls
self.highlighted_urls = highlighted_urls
super(IcalEvents, self).__init__()
2019-02-26 22:08:19 +01:00
2019-04-18 08:30:08 +02:00
def is_available(self):
for url in self.urls + self.highlighted_urls:
try:
urlopen(url)
return True
except:
pass
return False
2019-04-18 08:30:08 +02:00
def __get_events__(self):
events = self.__get_events_from_urls__(self.urls)
highlighted = self.__get_events_from_urls__(self.highlighted_urls)
2019-03-10 19:09:37 +01:00
highlighted = map(self.__highlight_event__, highlighted)
events.extend(highlighted)
return events
def __highlight_event__(self, event):
event.highlight = True
return event
def __get_events_from_urls__(self, urls):
loaded_events = []
if urls is None:
return loaded_events
for calendar in urls:
try:
2019-02-26 22:08:19 +01:00
decode = str(urlopen(calendar).read().decode())
2019-03-27 17:48:28 +01:00
decode = self.__remove_alarms__(decode)
2019-02-26 22:08:19 +01:00
ical = Calendar(decode)
2019-02-26 22:08:19 +01:00
for event in ical.events:
cal_event = CalendarEvent()
2019-04-02 10:48:15 +02:00
cal_event.fetch_datetime = datetime.now(timezone.utc)
cal_event.begin_datetime = event.begin.datetime
cal_event.end_datetime = event.end.datetime
2019-03-16 18:50:52 +01:00
cal_event.duration = event.duration
2019-02-26 22:08:19 +01:00
cal_event.title = event.name
cal_event.description = event.description
cal_event.location = event.location
2019-03-10 13:24:37 +01:00
cal_event.allday = event.all_day
cal_event.rrule = self.__extract_rrule__(event)
2019-02-26 22:08:19 +01:00
2019-07-13 08:05:35 +02:00
cal_event.begin_datetime = cal_event.begin_datetime.astimezone(
None)
cal_event.end_datetime = cal_event.end_datetime.astimezone(
None)
2019-04-02 19:36:09 +02:00
if cal_event.allday:
cal_event = self.__fix_allday__(cal_event)
cal_event.multiday = self.__is_multiday__(cal_event)
loaded_events.append(cal_event)
except BaseException as ex:
print("ICal-Error [" + calendar + "]")
print(ex)
return loaded_events
def __fix_allday__(self, event):
local_tzinfo = datetime.now(timezone.utc).astimezone().tzinfo
begin_utc = event.begin_datetime.astimezone(timezone.utc)
end_utc = event.end_datetime.astimezone(timezone.utc)
2019-07-13 08:05:35 +02:00
event.begin_datetime = datetime(
begin_utc.year, begin_utc.month, begin_utc.day, 0, 0, 0, 0, local_tzinfo)
event.end_datetime = datetime(
end_utc.year, end_utc.month, end_utc.day, 0, 0, 0, 0, local_tzinfo) - timedelta(1)
2019-04-29 18:35:45 +02:00
event.duration = event.end_datetime - event.begin_datetime
return event
2019-02-26 22:08:19 +01:00
def __remove_alarms__(self, decode):
alarm_begin = 'BEGIN:VALARM'
alarm_end = 'END:VALARM'
lineseparation = '\r\n'
beginAlarmIndex = 0
while beginAlarmIndex >= 0:
beginAlarmIndex = decode.find(alarm_begin)
if beginAlarmIndex >= 0:
endAlarmIndex = decode.find(alarm_end, beginAlarmIndex)
2019-07-13 08:05:35 +02:00
decode = decode[:beginAlarmIndex] + \
decode[endAlarmIndex +
len(alarm_end) + len(lineseparation):]
return decode
def __extract_rrule__(self, event):
2019-07-13 08:05:35 +02:00
if re.search('RRULE', str(event)) is None:
return None
2019-07-13 08:05:35 +02:00
return re.search('RRULE:(.+?)\n', str(event)).group(1).rstrip()
2019-07-13 08:05:35 +02:00
def __is_multiday__(self, event):
if event.allday and event.duration == timedelta(1):
return False
return event.begin_datetime.day != event.end_datetime.day or \
event.begin_datetime.month != event.end_datetime.month or \
2019-07-13 08:05:35 +02:00
event.begin_datetime.year != event.end_datetime.year