initial
This commit is contained in:
commit
b229389638
2 changed files with 81 additions and 0 deletions
4
config.cfg
Normal file
4
config.cfg
Normal file
|
@ -0,0 +1,4 @@
|
|||
SERVER = 'http://public.calendar.hackerspace.pl/'
|
||||
CALENDAR = 'shared/calendar.ics'
|
||||
TIMEZONE = 'Europe/Warsaw'
|
||||
INDENT = 4
|
77
hs_cal.py
Normal file
77
hs_cal.py
Normal file
|
@ -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/<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()
|
Loading…
Reference in a new issue