From f1c8497f3bcc14177bc7e0c091bdfc8ffbd2a74e Mon Sep 17 00:00:00 2001 From: Guillaume Ayoub Date: Sat, 16 Jan 2010 13:33:50 +0100 Subject: [PATCH] Configuration cleanup. --- TODO | 2 +- radicale.py | 7 ++++--- radicale/__init__.py | 12 +++++++++++- radicale/acl/fake.py | 4 ++-- radicale/config.py | 19 ++++++++----------- radicale/xmlutils.py | 18 +++++++++++------- 6 files changed, 37 insertions(+), 25 deletions(-) diff --git a/TODO b/TODO index c607b12..33e072a 100644 --- a/TODO +++ b/TODO @@ -30,6 +30,6 @@ === * [DONE] No Twisted dependency -* [IN PROGRESS] Python 3 support +* [DONE] Python 3 support * iCal filters and rights * Other CalDAV clients supports diff --git a/radicale.py b/radicale.py index e9afa62..406c58d 100755 --- a/radicale.py +++ b/radicale.py @@ -27,13 +27,14 @@ """ Radicale Server entry point. -Launch the Radicale Serve according to the configuration. +Launch the Radicale Server according to the configuration. """ import radicale -if radicale.config.get("server", "type") == "http": +if radicale.config.get("server", "protocol") == "http": server = radicale.server.HTTPServer( - ("", radicale.config.getint("server", "port")), + (radicale.config.get("server", "name"), + radicale.config.getint("server", "port")), radicale.CalendarHandler) server.serve_forever() diff --git a/radicale/__init__.py b/radicale/__init__.py index d8618b5..b16cc94 100644 --- a/radicale/__init__.py +++ b/radicale/__init__.py @@ -37,6 +37,16 @@ class CalendarHandler(server.BaseHTTPRequestHandler): cal = "%s/%s" % (path[0], path[1]) self.calendar = calendar.Calendar("radicale", cal) + def do_GET(self): + """Manage GET ``request``.""" + self._parse_path() + answer = self.calendar.vcalendar().encode(config.get("encoding", "request")) + + self.send_response(client.OK) + self.send_header("Content-Length", len(answer)) + self.end_headers() + self.wfile.write(answer) + def do_DELETE(self): """Manage DELETE ``request``.""" self._parse_path() @@ -51,7 +61,7 @@ class CalendarHandler(server.BaseHTTPRequestHandler): def do_OPTIONS(self): """Manage OPTIONS ``request``.""" self.send_response(client.OK) - self.send_header("Allow", "DELETE, OPTIONS, PROPFIND, PUT, REPORT") + self.send_header("Allow", "DELETE, GET, OPTIONS, PROPFIND, PUT, REPORT") self.send_header("DAV", "1, calendar-access") self.end_headers() diff --git a/radicale/acl/fake.py b/radicale/acl/fake.py index f2d5278..03da9dd 100644 --- a/radicale/acl/fake.py +++ b/radicale/acl/fake.py @@ -21,11 +21,11 @@ """ Fake ACL. -Just load the default user set in configuration, with no rights management. +Just load the default user "radicale", with no rights management. """ from radicale import config def users(): """Get the list of all users.""" - return [config.get("acl", "user")] + return ["radicale"] diff --git a/radicale/config.py b/radicale/config.py index 53e89f1..c54faae 100644 --- a/radicale/config.py +++ b/radicale/config.py @@ -24,6 +24,8 @@ Radicale configuration module. Give a configparser-like interface to read and write configuration. """ +# TODO: Use abstract filenames for other platforms + try: from configparser import RawConfigParser as ConfigParser except ImportError: @@ -40,11 +42,12 @@ items = _config.items _initial = { "server": { - "type": "http", - "certificate": "/etc/apache2/ssl/server.crt", - "privatekey": "/etc/apache2/ssl/server.key", - "log": "/var/www/radicale/server.log", + "protocol": "http", + "name": "", "port": "5232", + #"certificate": "/etc/apache2/ssl/server.crt", + #"privatekey": "/etc/apache2/ssl/server.key", + #"log": "/var/www/radicale/server.log", }, "encoding": { "request": "utf-8", @@ -55,14 +58,9 @@ _initial = { "D": "DAV:", "CS": "http://calendarserver.org/ns/", }, - "status": { - "200": "HTTP/1.1 200 OK", - "204": "HTTP/1.1 204 No Content", - }, "acl": { "type": "fake", - "filename": "/etc/radicale/users", - "user": "radicale", + #"filename": "/etc/radicale/users", }, "support": { "type": "plain", @@ -76,5 +74,4 @@ for section, values in _initial.items(): for key, value in values.items(): _config.set(section, key, value) -# TODO: Use abstract filename for other platforms _config.read("/etc/radicale/config") diff --git a/radicale/xmlutils.py b/radicale/xmlutils.py index 5212443..51e614e 100644 --- a/radicale/xmlutils.py +++ b/radicale/xmlutils.py @@ -31,17 +31,21 @@ in them for XML requests (all but PUT). import xml.etree.ElementTree as ET -from radicale import config, ical +from radicale import client, config, ical # TODO: This is a well-known and accepted hack for ET to avoid ET from renaming # namespaces, which is accepted in XML norm but often not in XML # readers. Is there another clean solution to force namespaces? -for key,value in config.items("namespace"): +for key, value in config.items("namespace"): ET._namespace_map[value] = key def _tag(short_name, local): """Get XML Clark notation {uri(``short_name``)}``local``.""" - return "{%s}%s"%(config.get("namespace", short_name), local) + return "{%s}%s" % (config.get("namespace", short_name), local) + +def _response(code): + """Return full W3C names from HTTP status codes.""" + return "HTTP/1.1 %i %s" % (code, client.responses[code]) def delete(obj, calendar, url): """Read and answer DELETE requests. @@ -61,7 +65,7 @@ def delete(obj, calendar, url): response.append(href) status = ET.Element(_tag("D", "status")) - status.text = config.get("status", "200") + status.text = _response(200) response.append(status) return ET.tostring(multistatus, config.get("encoding", "request")) @@ -119,7 +123,7 @@ def propfind(xml_request, calendar, url): prop.append(getctag) status = ET.Element(_tag("D", "status")) - status.text = config.get("status", "200") + status.text = _response(200) propstat.append(status) return ET.tostring(multistatus, config.get("encoding", "request")) @@ -186,7 +190,7 @@ def report(xml_request, calendar, url): response.append(href) status = ET.Element(_tag("D", "status")) - status.text = config.get("status", "204") + status.text = _response(204) response.append(status) for obj in objects: @@ -218,7 +222,7 @@ def report(xml_request, calendar, url): prop.append(cdata) status = ET.Element(_tag("D", "status")) - status.text = config.get("status", "200") + status.text = _response(200) propstat.append(status) return ET.tostring(multistatus, config.get("encoding", "request"))