summaryrefslogtreecommitdiff
path: root/main.py
blob: cb870c9f146d33077678047996d4d2f1a6ae6063 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
from datetime import datetime, timedelta, time
from dateutil.relativedelta import relativedelta
import urllib2

import json
import logging
import sys
import copy

from dateutil.rrule import rrulestr
import icalendar

def fetch_calendar(logger):
    """Fetches the calendar events and returns a icalendar.Calendar instance.
    """
    response = urllib2.urlopen(CALENDARIUM_IMPORT_URL)
    logger.debug('Fetched calendar from %s' % CALENDARIUM_IMPORT_URL)
    return icalendar.Calendar.from_ical(response.read())

def get_events(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]] = event[fieldinfo[1]].format().encode("utf-8")
                event_info[fieldinfo[0]] = event_info[fieldinfo[0]].decode("string-escape")
            except KeyError:
                event_info[fieldinfo[0]] = fieldinfo[2]
        start = icalendar.vDDDTypes.from_ical(event['dtstart'].to_ical())
        end = icalendar.vDDDTypes.from_ical(event['dtend'].to_ical())
        if not isinstance(start, datetime):
            start = datetime.combine(start, time())
        if not isinstance(end, datetime):
            end = datetime.combine(end, time())

        if 'rrule' in event:
            rrule = rrulestr(event['rrule'].to_ical(), dtstart=start)
            duration = end - start
            for occurence in rrule.between(after, before, True):
                event_info['start'] = occurence
                event_info['end'] = occurence + duration
                yield copy.deepcopy(event_info)
        else:
            if start >= after:
                event_info['start'] = start
                event_info['end'] = end
                yield event_info

class DatetimeEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.isoformat()
        return json.JSONEncoder.default(self,obj)

CALENDARIUM_IMPORT_URL = 'https://sublab.org:5232/calendars/events'
if __name__ == '__main__':
    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
    logger = logging.getLogger('calendar_feed')
    calendar = fetch_calendar(logger)
    now = datetime.now()
    after = now - relativedelta(days=1)
    before = now + relativedelta(months=+2)

    events = []
    for event in get_events(calendar, after, before):
        event['start'] = event['start'].isoformat()
        event['end'] = event['end'].isoformat()
        events.append(event)
    print json.dumps(events)