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
|
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
response = urllib2.urlopen('https://sublab.org:5232/calendars/events')
calendar = Calendarium(response.read())
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
|