From d228bcbad2662747ccdc51f10f9502149b86b5c4 Mon Sep 17 00:00:00 2001 From: Lukasz Langa Date: Wed, 11 May 2011 14:57:27 +0200 Subject: [PATCH 1/5] report needs a content-type as well. --- radicale/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/radicale/__init__.py b/radicale/__init__.py index fd7a772a..5742da62 100644 --- a/radicale/__init__.py +++ b/radicale/__init__.py @@ -296,7 +296,8 @@ class Application(object): def report(self, environ, calendar, content): """Manage REPORT request.""" + headers = {'Content-Type': 'text/xml'} answer = xmlutils.report(environ["PATH_INFO"], content, calendar) - return client.MULTI_STATUS, {}, answer + return client.MULTI_STATUS, headers, answer # pylint: enable=W0612,W0613,R0201 From afcfb11fdebb5298d86630bc044357e52f13d743 Mon Sep 17 00:00:00 2001 From: Lukasz Langa Date: Wed, 11 May 2011 15:05:23 +0200 Subject: [PATCH 2/5] Revert "Remove useless calls to _tag" This reverts commit 3b17ed296991112d34e6b782e94fb38cc5d415d2. --- radicale/xmlutils.py | 62 +++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/radicale/xmlutils.py b/radicale/xmlutils.py index dfc49ff4..ceb2a8f7 100644 --- a/radicale/xmlutils.py +++ b/radicale/xmlutils.py @@ -91,13 +91,15 @@ def delete(path, calendar): calendar.remove(name_from_path(path, calendar)) # Writing answer - multistatus = ET.Element("{D}multistatus") - response = ET.Element("{D}response") + multistatus = ET.Element(_tag("D", "multistatus")) + response = ET.Element(_tag("D", "response")) multistatus.append(response) + + href = ET.Element(_tag("D", "href")) href.text = path response.append(href) - status = ET.Element("{D}status") + status = ET.Element(_tag("D", "status")) status.text = _response(200) response.append(status) @@ -117,7 +119,7 @@ def propfind(path, xml_request, calendar, depth): props = [prop.tag for prop in prop_element] # Writing answer - multistatus = ET.Element("{D}multistatus") + multistatus = ET.Element(_tag("D", "multistatus")) if calendar: if depth == "0": @@ -132,25 +134,25 @@ def propfind(path, xml_request, calendar, depth): for item in items: is_calendar = isinstance(item, ical.Calendar) - response = ET.Element("{D}response") + response = ET.Element(_tag("D", "response")) multistatus.append(response) - href = ET.Element("{D}href") + href = ET.Element(_tag("D", "href")) href.text = path if is_calendar else path + item.name response.append(href) - propstat = ET.Element("{D}propstat") + propstat = ET.Element(_tag("D", "propstat")) response.append(propstat) - prop = ET.Element("{D}prop") + prop = ET.Element(_tag("D", "prop")) propstat.append(prop) for tag in props: element = ET.Element(tag) if tag == _tag("D", "resourcetype") and is_calendar: - tag = ET.Element("{C}calendar") + tag = ET.Element(_tag("C", "calendar")) element.append(tag) - tag = ET.Element("{D}collection") + tag = ET.Element(_tag("D", "collection")) element.append(tag) elif tag == _tag("D", "owner"): if calendar.owner: @@ -165,40 +167,40 @@ def propfind(path, xml_request, calendar, depth): element.text = calendar.name elif tag == _tag("D", "principal-URL"): # TODO: use a real principal URL, read rfc3744-4.2 for info - tag = ET.Element("{D}href") + tag = ET.Element(_tag("D", "href")) tag.text = path element.append(tag) elif tag in ( _tag("D", "principal-collection-set"), _tag("C", "calendar-user-address-set"), _tag("C", "calendar-home-set")): - tag = ET.Element("{D}href") + tag = ET.Element(_tag("D", "href")) tag.text = path element.append(tag) elif tag == _tag("C", "supported-calendar-component-set"): # This is not a Todo # pylint: disable=W0511 for component in ("VTODO", "VEVENT", "VJOURNAL"): - comp = ET.Element("{C}comp") + comp = ET.Element(_tag("C", "comp")) comp.set("name", component) element.append(comp) # pylint: enable=W0511 elif tag == _tag("D", "current-user-privilege-set"): - privilege = ET.Element("{D}privilege") - privilege.append(ET.Element("{D}all")) + privilege = ET.Element(_tag("D", "privilege")) + privilege.append(ET.Element(_tag("D", "all"))) element.append(privilege) elif tag == _tag("D", "supported-report-set"): for report_name in ( "principal-property-search", "sync-collection" "expand-property", "principal-search-property-set"): - supported = ET.Element("{D}supported-report") - report_tag = ET.Element("{D}report") + supported = ET.Element(_tag("D", "supported-report")) + report_tag = ET.Element(_tag("D", "report")) report_tag.text = report_name supported.append(report_tag) element.append(supported) prop.append(element) - status = ET.Element("{D}status") + status = ET.Element(_tag("D", "status")) status.text = _response(200) propstat.append(status) @@ -222,26 +224,26 @@ def proppatch(path, xml_request, calendar): props.extend(prop.tag for prop in prop_element) # Writing answer - multistatus = ET.Element("{D}multistatus") + multistatus = ET.Element(_tag("D", "multistatus")) - response = ET.Element("{D}response") + response = ET.Element(_tag("D", "response")) multistatus.append(response) - href = ET.Element("{D}href") + href = ET.Element(_tag("D", "href")) href.text = path response.append(href) - propstat = ET.Element("{D}propstat") + propstat = ET.Element(_tag("D", "propstat")) response.append(propstat) - prop = ET.Element("{D}prop") + prop = ET.Element(_tag("D", "prop")) propstat.append(prop) for tag in props: element = ET.Element(tag) prop.append(element) - status = ET.Element("{D}status") + status = ET.Element(_tag("D", "status")) status.text = _response(200) propstat.append(status) @@ -283,7 +285,7 @@ def report(path, xml_request, calendar): hreferences = () # Writing answer - multistatus = ET.Element("{D}multistatus") + multistatus = ET.Element(_tag("D", "multistatus")) for hreference in hreferences: # Check if the reference is an item or a calendar @@ -298,17 +300,17 @@ def report(path, xml_request, calendar): items = calendar.components for item in items: - response = ET.Element("{D}response") + response = ET.Element(_tag("D", "response")) multistatus.append(response) - href = ET.Element("{D}href") + href = ET.Element(_tag("D", "href")) href.text = path + item.name response.append(href) - propstat = ET.Element("{D}propstat") + propstat = ET.Element(_tag("D", "propstat")) response.append(propstat) - prop = ET.Element("{D}prop") + prop = ET.Element(_tag("D", "prop")) propstat.append(prop) for tag in props: @@ -321,7 +323,7 @@ def report(path, xml_request, calendar): calendar.headers, calendar.timezones + [item]) prop.append(element) - status = ET.Element("{D}status") + status = ET.Element(_tag("D", "status")) status.text = _response(200) propstat.append(status) From 663fda4ecba77dea62e5f43ad85acffc36a042bf Mon Sep 17 00:00:00 2001 From: Lukasz Langa Date: Wed, 11 May 2011 16:24:20 +0200 Subject: [PATCH 3/5] add the Apple iCal namespace to registry --- radicale/xmlutils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/radicale/xmlutils.py b/radicale/xmlutils.py index ceb2a8f7..3265d5c4 100644 --- a/radicale/xmlutils.py +++ b/radicale/xmlutils.py @@ -35,7 +35,9 @@ from radicale import client, config, ical NAMESPACES = { "C": "urn:ietf:params:xml:ns:caldav", "D": "DAV:", - "CS": "http://calendarserver.org/ns/"} + "CS": "http://calendarserver.org/ns/", + "ICAL": "http://apple.com/ns/ical/", +} for short, url in NAMESPACES.items(): From ae0851be3562cd289758d444c7676a7e07b1385b Mon Sep 17 00:00:00 2001 From: Lukasz Langa Date: Wed, 11 May 2011 16:24:55 +0200 Subject: [PATCH 4/5] treat the DAV namespace as default (XML output is nicer) --- radicale/xmlutils.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/radicale/xmlutils.py b/radicale/xmlutils.py index 3265d5c4..3c1d25aa 100644 --- a/radicale/xmlutils.py +++ b/radicale/xmlutils.py @@ -41,6 +41,8 @@ NAMESPACES = { for short, url in NAMESPACES.items(): + if short == "D": + short = "" ET._namespace_map[url] = short From 6ba69f22a49a1b0b5b3701f902efd5f88a029753 Mon Sep 17 00:00:00 2001 From: Lukasz Langa Date: Wed, 11 May 2011 17:09:44 +0200 Subject: [PATCH 5/5] Pretty formatting and filtering of environment variables. --- config | 4 +++- radicale/__init__.py | 14 +++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/config b/config index aaadc038..90c2e825 100644 --- a/config +++ b/config @@ -65,4 +65,6 @@ folder = ~/.config/radicale/calendars # http://docs.python.org/library/logging.config.html config = /etc/radicale/logging # Set the default logging level to debug -debug = False \ No newline at end of file +debug = False +# Store all environment variables (including those set in the shell) +full_environment = False diff --git a/radicale/__init__.py b/radicale/__init__.py index 5742da62..41ad59c2 100644 --- a/radicale/__init__.py +++ b/radicale/__init__.py @@ -30,6 +30,7 @@ should have been included in this package. import os import posixpath +import pprint import base64 import socket import ssl @@ -100,6 +101,16 @@ class Application(object): super(Application, self).__init__() self.acl = acl.load() self.encoding = config.get("encoding", "request") + if config.getboolean('logging', 'full_environment'): + self.headers_log = lambda environ: environ + + def headers_log(self, environ): + request_environ = dict(environ) + for shell_variable in os.environ: + #if shell_variable not in request_environ: + # continue + del request_environ[shell_variable] + return request_environ def decode(self, text, environ): """Try to magically decode ``text`` according to given ``environ``.""" @@ -128,7 +139,8 @@ class Application(object): """Manage a request.""" log.LOGGER.info("%s request at %s received" % ( environ["REQUEST_METHOD"], environ["PATH_INFO"])) - log.LOGGER.debug("Request headers:\n%s" % environ.items()) + headers = pprint.pformat(self.headers_log(environ)) + log.LOGGER.debug("Request headers:\n%s" % headers) # Get content content_length = int(environ.get("CONTENT_LENGTH") or 0)