151 lines
5.5 KiB
Python
151 lines
5.5 KiB
Python
import sys
|
|
import time
|
|
import logging
|
|
import collections
|
|
from os.path import exists
|
|
import json
|
|
import dateutil.rrule as rrule
|
|
|
|
import caldav
|
|
import pytz
|
|
from icalendar import Calendar, Event
|
|
import datetime
|
|
import caldav
|
|
|
|
|
|
class CaldavHandler:
|
|
def get_config(self, path):
|
|
with open(path) as f:
|
|
return json.load(f)
|
|
|
|
def __init__(self):
|
|
self._config_path = "./config.json"
|
|
self._event_reminder_path = "./event_reminders.json"
|
|
|
|
if not exists(self._config_path):
|
|
print("No config file found. Aborting.")
|
|
|
|
self._config = self.get_config(self._config_path)
|
|
self._event_reminder_config = self.get_config(self._event_reminder_path)
|
|
self._caldavclient = caldav.DAVClient(self._config["caldav"]["url"],
|
|
username=self._config["caldav"]["username"],
|
|
password=self._config["caldav"]["password"])
|
|
|
|
|
|
def get_event_map(self, events, time_span):
|
|
result = {}
|
|
for event in events:
|
|
event.load()
|
|
e = event.instance.vevent
|
|
|
|
list_of_occurences = []
|
|
|
|
if e.getChildValue('rrule') == None:
|
|
list_of_occurences.append(e.getChildValue('dtstart'))
|
|
else:
|
|
#recurring events only return with the date of the first recurring event ever created
|
|
#we have to use rrule manually to expand the dates to display them correctly
|
|
rule = rrule.rrulestr(e.getChildValue('rrule'), dtstart=e.getChildValue('dtstart'))
|
|
list_of_occurences = rule.between(datetime.datetime.now(datetime.timezone.utc),
|
|
datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=time_span),
|
|
inc=True)
|
|
|
|
for datetime_of_event in list_of_occurences:
|
|
datestr = datetime_of_event.strftime("%x")
|
|
eventstr = str( "(" + e.dtstart.value.strftime("%H:%M") + " - " + e.dtend.value.strftime("%H:%M") + ") " + e.summary.value)
|
|
|
|
if datestr in result:
|
|
result[datestr].append(eventstr)
|
|
else:
|
|
result[datestr] = [ eventstr ]
|
|
|
|
#sort start times
|
|
for key in result:
|
|
result[key].sort()
|
|
|
|
od = collections.OrderedDict(sorted(result.items()))
|
|
return od
|
|
|
|
def event_map_to_string(self, event_map):
|
|
result = ""
|
|
for k, v in event_map.items():
|
|
dt_string = k
|
|
format = "%x"
|
|
dt_object = datetime.datetime.strptime(dt_string, format)
|
|
result += "##### " + dt_object.strftime("%A, %d. of %B") + ":\n"
|
|
for event in v:
|
|
result += "* " + event + "\n"
|
|
|
|
return result
|
|
|
|
def event_to_string(self, event):
|
|
event.load()
|
|
e = event.instance.vevent
|
|
datestr = e.dtstart.value.strftime("%X")
|
|
return str( "(" + e.dtstart.value.strftime("%a, %-d. %b - %H:%M") + " - " + e.dtend.value.strftime("%H:%M") + ") " + e.summary.value)
|
|
|
|
def get_events(self, start_time, end_time):
|
|
cal = self._caldavclient.principal().calendars()
|
|
for ca in cal:
|
|
events = ca.date_search(start=start_time, end=end_time, expand=True)
|
|
return events
|
|
|
|
def send_events(self, events, time_span):
|
|
return self.event_map_to_string(self.get_event_map(events, time_span))
|
|
|
|
def print_month(self):
|
|
events = self.get_events(datetime.date.today(), datetime.date.today() + datetime.timedelta(days=30))
|
|
return self.send_events(events, 30)
|
|
|
|
def print_week(self):
|
|
events = self.get_events(datetime.date.today(), datetime.date.today() + datetime.timedelta(days=7))
|
|
return self.send_events(events, 7)
|
|
|
|
def time_to_remind(self, event_name, days_to_remind):
|
|
events = self.get_events(datetime.date.today(), datetime.date.today() + datetime.timedelta(days=days_to_remind + 1))
|
|
datetime_to_remind = datetime.date.today() + datetime.timedelta(days=days_to_remind)
|
|
|
|
datetime_to_remind = datetime_to_remind.strftime("%x")
|
|
print(datetime_to_remind)
|
|
|
|
#create a map where each day is a key and list of events are the values
|
|
event_map = self.get_event_map(events, days_to_remind + 1)
|
|
|
|
print(datetime_to_remind)
|
|
print(event_map)
|
|
if datetime_to_remind not in event_map:
|
|
return False
|
|
|
|
for real_event_name in event_map[datetime_to_remind]:
|
|
print("real_ev_name:")
|
|
print(real_event_name)
|
|
print("ev_name")
|
|
print(event_name)
|
|
if event_name in real_event_name:
|
|
print("found event!")
|
|
return True
|
|
|
|
return False
|
|
|
|
def send_reminders(self):
|
|
print(self._event_reminder_config)
|
|
|
|
result = []
|
|
for event_name in self._event_reminder_config:
|
|
print("iterating event configs")
|
|
print(event_name)
|
|
days = self._event_reminder_config[event_name]["days"]
|
|
print(days)
|
|
if not self.time_to_remind(event_name, days):
|
|
continue
|
|
reminder_message = self._event_reminder_config[event_name]["message"]
|
|
result.append(reminder_message)
|
|
print(reminder_message)
|
|
return result
|
|
|
|
|
|
def print_today(self):
|
|
events = self.get_events(datetime.date.today(), datetime.date.today() + datetime.timedelta(days=1))
|
|
#self.send_reminders()
|
|
return self.send_events(events, 1)
|