Some minor implementations and cleanups. Evolution support now works with a slight adjustment.
* Clean up little typo in bongo-standalone. * Implement GET properly, even with some error handling. * Make OPTIONS require auth, otherwise the current auth handling system will fail miserably. This really should be off, but the authenhandler will be updated soon, and modernised. * Implement C:is-defined filter, if I can call that an implementation. * Add a TODO about different URL support in Evolution.
This commit is contained in:
@@ -220,7 +220,7 @@ class DragonflyHandler(SimpleHTTPRequestHandler):
|
||||
|
||||
if handler.NeedsAuth(rp):
|
||||
if req.user == None:
|
||||
self.req.headers_out["WWW-Authenticate"] = "Basic realm=\"Bongo\""#
|
||||
self.req.headers_out["WWW-Authenticate"] = "Basic realm=\"Bongo\""
|
||||
self.send_error(bongo.commonweb.HTTP_UNAUTHORIZED)
|
||||
return bongo.commonweb.HTTP_UNAUTHORIZED
|
||||
else:
|
||||
|
||||
@@ -32,112 +32,34 @@ class GetHandler(SundialHandler):
|
||||
# @param req The HttpRequest instance for the current request.
|
||||
# @param rp The SundialPath instance for the current request.
|
||||
def do_GET(self, req, rp):
|
||||
if req.uri == "/dav/abcd2.ics":
|
||||
data = """BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
BEGIN:VTIMEZONE
|
||||
LAST-MODIFIED:20040110T032845Z
|
||||
TZID:US/Eastern
|
||||
BEGIN:DAYLIGHT
|
||||
DTSTART:20000404T020000
|
||||
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
|
||||
TZNAME:EDT
|
||||
TZOFFSETFROM:-0500
|
||||
TZOFFSETTO:-0400
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
DTSTART:20001026T020000
|
||||
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
|
||||
TZNAME:EST
|
||||
TZOFFSETFROM:-0400
|
||||
TZOFFSETTO:-0500
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
DTSTART;TZID=US/Eastern:20060102T120000
|
||||
DURATION:PT1H
|
||||
RRULE:FREQ=DAILY;COUNT=5
|
||||
SUMMARY:Event #2
|
||||
UID:00959BC664CA650E933C892C@example.com
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
DTSTART;TZID=US/Eastern:20060104T140000
|
||||
DURATION:PT1H
|
||||
RECURRENCE-ID;TZID=US/Eastern:20060104T120000
|
||||
SUMMARY:Event #2 bis
|
||||
UID:00959BC664CA650E933C892C@example.com
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
DTSTART;TZID=US/Eastern:20060106T140000
|
||||
DURATION:PT1H
|
||||
RECURRENCE-ID;TZID=US/Eastern:20060106T120000
|
||||
SUMMARY:Event #2 bis bis
|
||||
UID:00959BC664CA650E933C892C@example.com
|
||||
END:VEVENT
|
||||
END:VCALENDAR"""
|
||||
elif req.uri == "/dav/abcd3.ics":
|
||||
data = """BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Example Corp.//CalDAV Client//EN
|
||||
BEGIN:VTIMEZONE
|
||||
LAST-MODIFIED:20040110T032845Z
|
||||
TZID:US/Eastern
|
||||
BEGIN:DAYLIGHT
|
||||
DTSTART:20000404T020000
|
||||
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
|
||||
TZNAME:EDT
|
||||
TZOFFSETFROM:-0500
|
||||
TZOFFSETTO:-0400
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
DTSTART:20001026T020000
|
||||
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
|
||||
TZNAME:EST
|
||||
TZOFFSETFROM:-0400
|
||||
TZOFFSETTO:-0500
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
DTSTART;TZID=US/Eastern:20060104T100000
|
||||
DURATION:PT1H
|
||||
SUMMARY:Event #3
|
||||
UID:DC6C50A017428C5216A2F1CD@example.com
|
||||
END:VEVENT
|
||||
END:VCALENDAR"""
|
||||
# req.uri should be something like:
|
||||
# /dav/username/calendarname/00000000000000115.ics
|
||||
filename = req.uri.split('/')[-1]
|
||||
|
||||
filename_parts = filename.split('.')
|
||||
|
||||
# Any filename with more than one "." can get lost, and this shop only
|
||||
# serves up iCalendar.
|
||||
if len(filename_parts) != 2 or filename_parts[-1] != 'ics':
|
||||
return bongo.commonweb.HTTP_NOT_FOUND
|
||||
|
||||
# Get the nmap document from the store.
|
||||
# A CommandError exception is thrown when the item does not exist.
|
||||
try:
|
||||
doc = self.store.Read(filename_parts[0])
|
||||
except CommandError:
|
||||
return bongo.commonweb.HTTP_NOT_FOUND
|
||||
|
||||
jsob = bongojson.ParseString(doc.strip())
|
||||
|
||||
if jsob:
|
||||
data = cal.JsonToIcal(jsob)
|
||||
else:
|
||||
data = ""
|
||||
|
||||
# Get rid of the boring headers, and data.
|
||||
req.headers_out["Content-Length"] = str(len(data))
|
||||
req.content_type = "text/calendar"
|
||||
|
||||
req.write(data)
|
||||
return bongo.commonweb.HTTP_OK
|
||||
|
||||
|
||||
|
||||
|
||||
# start = end = None
|
||||
# eventProps = ["nmap.document", "nmap.event.calendars"]
|
||||
#
|
||||
# events = list(self.store.Events(None, eventProps, query=None, start=start, end=end))
|
||||
#
|
||||
# wholeJsob = None
|
||||
# for event in events:
|
||||
# doc = event.props["nmap.document"].strip()
|
||||
# jsob = bongojson.ParseString(doc)
|
||||
# if wholeJsob:
|
||||
# wholeJsob = cal.Merge(wholeJsob, jsob)
|
||||
# else:
|
||||
# wholeJsob = jsob
|
||||
#
|
||||
# if wholeJsob:
|
||||
# data = cal.JsonToIcal(wholeJsob)
|
||||
# else:
|
||||
# data = ""
|
||||
#
|
||||
# req.headers_out["Content-Length"] = str(len(data))
|
||||
# req.content_type = "text/calendar"
|
||||
#
|
||||
# req.write(data)
|
||||
# return bongo.commonweb.HTTP_OK
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class OptionsHandler(SundialHandler):
|
||||
# @param self The object pointer.
|
||||
# @param rp The SundialPath instance for the current request.
|
||||
def NeedsAuth(self, rp):
|
||||
return False
|
||||
return True
|
||||
|
||||
## The default entry point for the handler.
|
||||
# @param self The object pointer.
|
||||
|
||||
@@ -52,6 +52,9 @@ class ReportHandler(SundialHandler):
|
||||
for response in events:
|
||||
response_tag = ET.SubElement(multistatus_tag, 'D:response') # <D:response>
|
||||
# TODO Update this URL scheme.
|
||||
# REALLY REALLY IMPORTANT TODO: Evolution does not support relative URLs, even though
|
||||
# they're clearly The Right Way. Therefore, a switch between relative and definite URLs
|
||||
# depending on the client. A rather boring task, if you ask me.
|
||||
ET.SubElement(response_tag, 'D:href').text = "/dav/%s.ics" % response.uid # <D:href>url</D:href>
|
||||
|
||||
propstat_tag = ET.SubElement(response_tag, 'D:propstat') # <D:propstat>
|
||||
@@ -115,10 +118,14 @@ class ReportHandler(SundialHandler):
|
||||
output['start'] = parse(f.get('start'))
|
||||
output['end'] = parse(f.get('end'))
|
||||
|
||||
elif normalize(f.tag) == 'urn:ietf:params:xml:ns:caldav:is-defined':
|
||||
# This means nothing as all events in the store are "defined".
|
||||
pass
|
||||
|
||||
elif filter.get('name') == 'VTODO':
|
||||
output['type'] = 'VTODO'
|
||||
pass
|
||||
# TODO Implement this, perhaps.
|
||||
pass
|
||||
|
||||
# Generate <D:multistatus xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
|
||||
multistatus_tag = ET.Element('D:multistatus')
|
||||
|
||||
Reference in New Issue
Block a user