From 7e960881ae6cbcd709538dcd73e4fd89e33507d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Zapke-Gru=CC=88ndemann?= Date: Wed, 4 Jan 2012 23:58:44 +0100 Subject: Added model, admin, tests and tasks for calendarium. --- sublab_project/calendarium/tasks.py | 82 +++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 sublab_project/calendarium/tasks.py (limited to 'sublab_project/calendarium/tasks.py') diff --git a/sublab_project/calendarium/tasks.py b/sublab_project/calendarium/tasks.py new file mode 100644 index 0000000..9174105 --- /dev/null +++ b/sublab_project/calendarium/tasks.py @@ -0,0 +1,82 @@ +"""Celery tasks. +""" +from datetime import datetime, timedelta +from dateutil.relativedelta import relativedelta +import urllib2 + +from celery.task import PeriodicTask +from django.conf import settings +from dateutil.rrule import rrulestr +import icalendar + +from models import Event + + +class CalendariumImport(PeriodicTask): + """Periodic task for importing calendar events. + """ + run_every = timedelta(hours=1) + ignore_result = True + + def flush(self): + """Flushes all previously imported events. + """ + Event.objects.filter(source=Event.SOURCE_IMPORT).delete() + self.logger.info('Flushed all previously imported events.') + + def fetch_calendar(self): + """Fetches the calendar events and returns a icalendar.Calendar instance. + """ + response = urllib2.urlopen(settings.CALENDARIUM_IMPORT_URL) + self.logger.info('Fetched calendar from %s' % settings.CALENDARIUM_IMPORT_URL) + return icalendar.Calendar.from_string(response.read()) + + def get_events(self, calendar, after, before): + """Yields all events in calendar as dictionary. + + Only events after (including) after will be shown. Recurring events + til before (inclusively) will be shown. + """ + for event in calendar.walk('vevent'): + event_fields = [ + # dest, src, default + ('name', 'summary', 'unknown Event'), + ('description', 'description', ''), + ] + event_info = {} + for fieldinfo in event_fields: + try: + event_info[fieldinfo[0]] = str(event[fieldinfo[1]]) + except KeyError: + event_info[fieldinfo[0]] = fieldinfo[2] + start = icalendar.vDatetime.from_ical(event['dtstart'].ical()) + end = icalendar.vDatetime.from_ical(event['dtend'].ical()) + if 'rrule' in event: + rrule = rrulestr(event['rrule'].ical(), dtstart=start) + duration = end - start + for occurence in rrule.between(after, before, True): + event_info['start'] = occurence + event_info['end'] = occurence + duration + yield event_info + else: + if start >= after: + event_info['start'] = start + event_info['end'] = end + yield event_info + + def run(self, **kwargs): + """Imports all events. + """ + self.logger = self.get_logger(**kwargs) + now = datetime.now() + after = now - relativedelta(days=1) + before = now + relativedelta(months=+2) + self.logger.info('Importing events from %s to %s' % (after, before)) + try: + calendar = self.fetch_calendar() + self.flush() + for event_info in self.get_events(calendar, after, before): + event = Event.objects.create(**event_info) + self.logger.info('Added event "%s".' % event) + except urllib2.URLError, error: + self.logger.error(error) -- cgit v1.2.1