diff --git a/src/www/bongo/sundial/PropfindView.py b/src/www/bongo/sundial/PropfindView.py index bca0dd4..ff7b68d 100644 --- a/src/www/bongo/sundial/PropfindView.py +++ b/src/www/bongo/sundial/PropfindView.py @@ -35,7 +35,7 @@ class PropfindHandler(SundialHandler): try: info = store.Info("/calendars/" + rp.calendar) - except CommandError: + except: return bongo.commonweb.HTTP_NOT_FOUND multistatus_tag = ET.Element('D:multistatus') # @@ -43,8 +43,7 @@ class PropfindHandler(SundialHandler): 'C' : 'urn:ietf:params:xml:ns:caldav' }) response_tag = ET.SubElement(multistatus_tag, 'D:response') # - # TODO Update this URL scheme. - ET.SubElement(response_tag, 'D:href').text = req.uri # req.uri + ET.SubElement(response_tag, 'D:href').text = rp.get_hostname() + "dav/" + rp.user + "/" + rp.calendar + "/" # href propstat_tag = ET.SubElement(response_tag, 'D:propstat') # prop_tag = ET.SubElement(propstat_tag, 'D:prop') # diff --git a/src/www/bongo/sundial/ReportView.py b/src/www/bongo/sundial/ReportView.py index e151561..42e3ff0 100644 --- a/src/www/bongo/sundial/ReportView.py +++ b/src/www/bongo/sundial/ReportView.py @@ -28,28 +28,14 @@ class ReportHandler(SundialHandler): def NeedsAuth(self, rp): return True - ## Returns hostname based on HTTP_HOST. - # @param self The object pointer. - # - # Evolution does not support relative URLs in dav::href, therefore - # This function returns to ideal form of value prefix. Defaulting - # to relative, but using definite when Evolution is the User-Agent. - def _get_hostname(self): - if self.req.headers_in.get('User-Agent').startswith('Evolution'): - # TODO This doesn't support https. - return 'http://' + self.req.headers_in.get('Host') + self.rp.davpath - else: - return self.rp.davpath - ## Creates appropriate XML tags for requested VEVENTS. # @param self The object pointer. # @param output Dictionary of some information needed for the request. - # @param multistatus_tag The tag so SubElements can be created. # # First, events are pulled from the store based on the collection/calendar and also # the filters used. Then, tags are created, satisfying all the # requests, one-by-one. - def _vevent_filter(self, output, prop_tags, multistatus_tag): + def _vevent_filter(self, output, prop_tags): try: start = output['start'] end = output['end'] @@ -69,9 +55,8 @@ class ReportHandler(SundialHandler): # Loop through each VEVENT that was returned. for response in events: - response_tag = ET.SubElement(multistatus_tag, 'D:response') # - # TODO Update this URL scheme. - ET.SubElement(response_tag, 'D:href').text = self._get_hostname() + "dav/" + self.rp.user + "/" + self.rp.calendar + "/" + "%s.ics" % response.uid # url + response_tag = ET.SubElement(self.multistatus_tag, 'D:response') # + ET.SubElement(response_tag, 'D:href').text = self.rp.get_hostname() + "dav/" + self.rp.user + "/" + self.rp.calendar + "/" + "%s.ics" % response.uid # url propstat_tag = ET.SubElement(response_tag, 'D:propstat') # prop_tag = ET.SubElement(propstat_tag, 'D:prop') # @@ -96,15 +81,13 @@ class ReportHandler(SundialHandler): ET.SubElement(propstat_tag, 'D:status').text = "HTTP/1.1 200 OK" - # D:multistatus tag instance pointer has been messed with, so just the status to return. - return bongo.commonweb.HTTP_OK + return bongo.commonweb.HTTP_OK ## Handles the D:calendar-query request. # @param self The object pointer. # @param req The HttpRequest instance for the current request. # @param rp The SundialPath instance for the current request. def calendar_query(self, req, rp): - self.req = req self.rp = rp output = {} @@ -128,37 +111,37 @@ class ReportHandler(SundialHandler): if filter.get('name') == 'VEVENT': output['type'] = 'VEVENT' - - # Loop through different ranges and whatnot. - for f in filter.getchildren(): - if normalize(f.tag) == 'urn:ietf:params:xml:ns:caldav:time-range': - # C:time-range -- only events between two times. - 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' - # TODO Implement this, perhaps. + # Nothing to implement for the moment. Bongo doesn't support tasks. pass + + # Loop through different ranges and whatnot. + for f in filter.getchildren(): + if normalize(f.tag) == 'urn:ietf:params:xml:ns:caldav:time-range': + # C:time-range -- only events between two times. + 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 in Bongo as all events in the store are "defined". + pass + # Generate - multistatus_tag = ET.Element('D:multistatus') - bongo.commonweb.ElementTree.set_prefixes(multistatus_tag, {'D' : 'DAV:', + self.multistatus_tag = ET.Element('D:multistatus') + bongo.commonweb.ElementTree.set_prefixes(self.multistatus_tag, {'D' : 'DAV:', 'C' : 'urn:ietf:params:xml:ns:caldav' }) if output['type'] == 'VEVENT': - ret = self._vevent_filter(output, prop_tags, multistatus_tag) + ret = self._vevent_filter(output, prop_tags) if ret != bongo.commonweb.HTTP_OK: return ret # Throw out the output. req.content_type = 'text/xml; charset="utf-8"' - req.write(ET.tostring(multistatus_tag)) + req.write(ET.tostring(self.multistatus_tag)) return bongo.commonweb.HTTP_MULTI_STATUS ## The default entry point for the handler. diff --git a/src/www/bongo/sundial/SundialPath.py b/src/www/bongo/sundial/SundialPath.py index c6d0500..d45773c 100644 --- a/src/www/bongo/sundial/SundialPath.py +++ b/src/www/bongo/sundial/SundialPath.py @@ -8,6 +8,7 @@ import bongo.commonweb from bongo.commonweb.HttpError import HttpError import re import cElementTree +import urllib import GetView import PropfindView @@ -45,14 +46,13 @@ class SundialPath: self.davpath = '/' + '/'.join(davparts) if len(splituri) != 3: - pass - # TODO Return a 404, or something. + raise HttpError(404) # The user the calendar belongs to. self.user = splituri[0] # The calendar name. - self.calendar = splituri[1] + self.calendar = urllib.unquote(splituri[1]) # The file name (only used in GET at the time of writing). self.filename = splituri[2] @@ -95,3 +95,13 @@ class SundialPath: def GetHandler(self, req, rp): return views[req.method](req, rp) + ## Returns hostname based on HTTP_HOST. + # @param self The object pointer. + # + # Evolution does not support relative URLs in dav::href, therefore + def get_hostname(self): + if self.req.headers_in.get('User-Agent').startswith('Evolution'): + # TODO This doesn't support https. + return 'http://' + self.req.headers_in.get('Host') + self.davpath + else: + return self.davpath