summaryrefslogtreecommitdiff
path: root/sublab_project/calendarium/calendarium.py
blob: 2b04a50a0c4f5d44413ad0a1a87e1c2e005a895c (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
import urllib2
import icalendar
from dateutil.rrule import rrulestr

class Event(object):
    def __init__(self, name, description, start, end):
        self.name = name
        self.description = description
        self.start = start
        self.end = end

    def __repr__(self):
        return '<%s.%s (name=%s, start=%s, end=%s)>' % (
                __name__, self.__class__.__name__,
                repr(self.name), repr(self.start), repr(self.end))

class Calendarium(object):
    def __init__(self, string):
        """
        Loads a calendar from the string and provides a nice API to it.
        """

        self.calendar = icalendar.Calendar.from_string(string)

    def get_events(self, after, before):
        """
        This functions yields a list of events in the calendar.

        Only events after (including) after will be shown. Recurring
        events til before (inclusively) will be shown.
        """

        for event in self.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):
                    yield Event(
                            start=occurence,
                            end=occurence + duration,
                            **event_info)
            else:
                if start >= after:
                    yield Event(start=start, end=end, **event_info)

if __name__ == '__main__':
    # simple example

    from dateutil.relativedelta import relativedelta
    from datetime import datetime
    import urllib2

    calendar_request = urllib2.urlopen('https://sublab.org:5232/calendars/events')
    calendar = Calendarium(calendar_request.read())
    calendar_request.close()

    now = datetime.now()
    events = list(calendar.get_events(now-relativedelta(days=1), now+relativedelta(months=+2)))
    events.sort(key=lambda x:x.start)

    for event in events:
	print event