summaryrefslogtreecommitdiff
path: root/app/backend/fetch_cals.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/backend/fetch_cals.py')
-rw-r--r--app/backend/fetch_cals.py91
1 files changed, 91 insertions, 0 deletions
diff --git a/app/backend/fetch_cals.py b/app/backend/fetch_cals.py
new file mode 100644
index 0000000..8b53254
--- /dev/null
+++ b/app/backend/fetch_cals.py
@@ -0,0 +1,91 @@
+import datetime
+
+import dateutil.parser as dateparser
+import ics
+import pytz
+import requests
+from rcal.db import Session
+from rcal.model import Calendar, Entry
+
+
+def update_event_data(db_event, ical_event):
+ db_event.name = ical_event.name
+ db_event.location = ical_event.location
+ db_event.begin_date = ical_event.begin.datetime
+ db_event.end_date = ical_event.end.datetime
+ db_event.all_day = (
+ (db_event.end_date - db_event.begin_date).seconds % 86400 == 0
+ ) and (
+ db_event.begin_date.time() == datetime.time.min)
+ db_event.last_modified = get_last_modification_time(ical_event)
+ return db_event
+
+
+def update_event(db_event, ical_event):
+ update_event_data(db_event, ical_event)
+
+
+def add_event(event, calendar, session):
+ entry = Entry()
+ entry.uid = event.uid
+ entry.calendar = calendar
+ entry = update_event_data(entry, event)
+ session.add(entry)
+
+
+def remove_event(event, session):
+ session.delete(event)
+
+
+def get_last_modification_time(event):
+ for unused in event.__dict__['_unused']:
+ if unused.name == 'LAST-MODIFIED':
+ return dateparser.parse(unused.value)
+ return None
+
+
+def fetch_calendar(calendar, session):
+ cal_data = requests.get(calendar.url)
+ cal_object = ics.Calendar(cal_data.content.decode(cal_data.encoding))
+ cal_events = {e.uid: e for e in cal_object.events}
+ db_events = {e.uid: e for e in calendar.entries}
+ new_events = [e for u, e in cal_events.iteritems()
+ if u not in db_events.keys()]
+ old_events = [e for u, e in db_events.iteritems()
+ if u not in cal_events.keys()]
+ mod_events = [{'ics': cal_events[u], 'db': e}
+ for u, e in db_events.iteritems() if u in cal_events.keys()]
+ changes_present = False
+ for event in mod_events:
+ modified_date = get_last_modification_time(event['ics'])
+ if not modified_date or \
+ not event['db'].last_modified or \
+ modified_date > event['db'].last_modified.replace(tzinfo=pytz.UTC):
+ print 'Updating event %s' % event['db'].uid
+ update_event(event['db'], event['ics'])
+ changes_present = True
+ for event in new_events:
+ print 'Adding event %s' % event.uid
+ add_event(event, calendar, session)
+ changes_present = True
+ for event in old_events:
+ print 'Removing event %s' % event.uid
+ remove_event(event, session)
+ changes_present = True
+ if changes_present:
+ calendar.last_updated = datetime.datetime.now()
+
+
+def main():
+ session = Session.create()
+
+ calendars = session.query(Calendar).all()
+ for calendar in calendars:
+ # print 'Fetching %s' % calendar.url
+ fetch_calendar(calendar, session)
+
+ session.commit()
+
+
+if __name__ == '__main__':
+ main()