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)
|