commit b229389638c730d80b7f7243fb2616c050784ed1 Author: Tomek Dubrownik Date: Sun Oct 7 22:14:37 2012 +0200 initial diff --git a/config.cfg b/config.cfg new file mode 100644 index 0000000..5c2b535 --- /dev/null +++ b/config.cfg @@ -0,0 +1,4 @@ +SERVER = 'http://public.calendar.hackerspace.pl/' +CALENDAR = 'shared/calendar.ics' +TIMEZONE = 'Europe/Warsaw' +INDENT = 4 diff --git a/hs_cal.py b/hs_cal.py new file mode 100644 index 0000000..94d04ee --- /dev/null +++ b/hs_cal.py @@ -0,0 +1,77 @@ +import caldav +import vobject +import copy # ugh +from cStringIO import StringIO +from datetime import datetime, timedelta, date +from dateutil import zoneinfo +from flask import Flask, g, json, make_response + +app = Flask('hs_cal') +app.config.from_pyfile('config.cfg') + +server = app.config['SERVER'] +location = app.config['CALENDAR'] +tz = zoneinfo.gettz(app.config['TIMEZONE']) + +@app.before_request +def connect(): + client = caldav.DAVClient(server) + g.calendar = caldav.Calendar(client, server + location) + +def shift_date(event, rec_dtstart): + orig_st = event.dtstart.value + orig_et = event.dtend.value + duration = orig_et - orig_st + event.dtstart.value = rec_dtstart + event.dtend.value = rec_dtstart + duration + +# shim-o-rama +def expand_recurrences(event, start, end): + rrs = event.getrruleset() + print event.__dict__ + if rrs: + return [fix_date(copy.deepcopy(event), dts) + for dts in rrs.between(start, end, inc=True)] + else: + return [event] + +def objectify_event(event): + def nullable(event, attr): + a = getattr(event, attr, None) + return a and a.value + return dict((attr, nullable(event, attr)) for attr in + ['summary', 'description', 'dtstart', 'dtend', 'categories']) + +def jsonify_events(events): + def encode(o): + if isinstance(o, datetime) : + return o.strftime('%d/%m/%Y %H:%M') + if isinstance(o, date): + return o.strftime('%d/%m/%Y') + raise TypeError(type(o)) + return make_response(json.dumps(dict(events=events), + default=encode, indent=app.config.get('INDENT'))) + +@app.route('/') +def get_events_range(start=None, end=None): + start = start or datetime.today() + if not end or (end - start).days > 31: + end = start + timedelta(days=31) + start = start.replace(tzinfo=tz) + end = end.replace(tzinfo=tz) + res = [] + for event in g.calendar.date_search(start, end): + vev = event.instance.vevent + res.extend(expand_recurrences(vev, start, end)) + return jsonify_events(map(objectify_event, res)) + + +@app.route('/from//to//') +def range_query(start, end): + fstring = '%d-%m-%Y' + return get_events_range(datetime.strptime(start, fstring), + datetime.strptime(end, fstring)) + +if __name__ == '__main__': + app.debug = True + app.run()