77 lines
2.3 KiB
Python
77 lines
2.3 KiB
Python
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/<start>/to/<end>/')
|
|
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()
|