From 5e5e5e1023f745fb48e00b4212b97cde8a23bae4 Mon Sep 17 00:00:00 2001 From: Guillaume Ayoub Date: Sun, 10 Jan 2010 18:55:32 +0100 Subject: [PATCH] Remove Twisted dependency. --- radicale.py | 28 ++-------- radicale/__init__.py | 123 +++++++++++++++++-------------------------- setup.py | 1 - 3 files changed, 54 insertions(+), 98 deletions(-) diff --git a/radicale.py b/radicale.py index b94292c1..cd3876c5 100755 --- a/radicale.py +++ b/radicale.py @@ -23,7 +23,6 @@ # TODO: Manage smart and configurable logs # TODO: Manage authentication # TODO: Magage command-line options -# TODO: Forget twisted? """ Radicale Server entry point. @@ -32,29 +31,12 @@ Launch the Radicale Serve according to the configuration. """ import sys -from twisted.web import server -from twisted.internet import reactor -from twisted.python import log +import BaseHTTPServer import radicale -class ServerContextFactory(object): - """SSL context factory.""" - def get_context(self): - """Get SSL context for the HTTP server.""" - from OpenSSL import SSL - context = SSL.Context(SSL.SSLv23_METHOD) - context.use_certificate_file(radicale.config.get("server", "certificate")) - context.use_privatekey_file(radicale.config.get("server", "privatekey")) - return context - -log.startLogging(sys.stdout) -#log.startLogging(open(radicale.config.get("server", "log"), "w")) -factory = server.Site(radicale.HttpResource()) - if radicale.config.get("server", "type") == "http": - reactor.listenTCP(radicale.config.getint("server", "port"), factory) -elif radicale.config.get("server", "type") == "https": - reactor.listenSSL(radicale.config.getint("server", "port"), factory, ServerContextFactory()) - -reactor.run() + server = BaseHTTPServer.HTTPServer( + ("", radicale.config.getint("server", "port")), + radicale.CalendarHandler) + server.serve_forever() diff --git a/radicale/__init__.py b/radicale/__init__.py index 81e4bdc8..1b65d96b 100644 --- a/radicale/__init__.py +++ b/radicale/__init__.py @@ -19,11 +19,10 @@ # along with Radicale. If not, see . # TODO: Manage errors (see xmlutils) -# TODO: Forget twisted? -from twisted.web.resource import Resource -from twisted.web import http import posixpath +import httplib +import BaseHTTPServer import config import support @@ -34,90 +33,66 @@ import calendar _users = acl.users() _calendars = support.calendars() -class CalendarResource(Resource): - """Twisted resource for requests at calendar depth (/user/calendar).""" - # Tell twisted this is a leaf for requests - isLeaf = True +class CalendarHandler(BaseHTTPServer.BaseHTTPRequestHandler): + """HTTP requests handler for calendars.""" + def _parse_path(self): + path = self.path.strip("/").split("/") + if len(path) >= 2: + cal = "%s/%s" % (path[0], path[1]) + self.calendar = calendar.Calendar(_users[0], cal) - def __init__(self, user, cal): - """Initialize by creating a calendar object. - - The calendar object corresponds to the stocked calendar named - ``user``/``cal``. - """ - Resource.__init__(self) - self.calendar = calendar.Calendar(user, cal) - - def render_DELETE(self, request): + def do_DELETE(self): """Manage DELETE ``request``.""" - obj = request.getHeader("if-match") - answer = xmlutils.delete(obj, self.calendar, str(request.URLPath())) - request.setResponseCode(http.NO_CONTENT) - return answer + self._parse_path() + obj = self.headers.get("if-match", None) + answer = xmlutils.delete(obj, self.calendar, self.path) - def render_OPTIONS(self, request): + self.send_response(httplib.NO_CONTENT) + self.send_header("Content-Length", len(answer)) + self.end_headers() + self.wfile.write(answer) + + def do_OPTIONS(self): """Manage OPTIONS ``request``.""" - request.setHeader("Allow", "DELETE, OPTIONS, PROPFIND, PUT, REPORT") - request.setHeader("DAV", "1, calendar-access") - request.setResponseCode(http.OK) - return "" + self.send_response(httplib.OK) + self.send_header("Allow", "DELETE, OPTIONS, PROPFIND, PUT, REPORT") + self.send_header("DAV", "1, calendar-access") + self.end_headers() - def render_PROPFIND(self, request): + def do_PROPFIND(self): """Manage PROPFIND ``request``.""" - xml_request = request.content.read() - answer = xmlutils.propfind(xml_request, self.calendar, str(request.URLPath())) - request.setResponseCode(http.MULTI_STATUS) - return answer + self._parse_path() + xml_request = self.rfile.read(int(self.headers["Content-Length"])) + answer = xmlutils.propfind(xml_request, self.calendar, self.path) - def render_PUT(self, request): + self.send_response(httplib.MULTI_STATUS) + self.send_header("DAV", "1, calendar-access") + self.send_header("Content-Length", len(answer)) + self.end_headers() + self.wfile.write(answer) + + def do_PUT(self): """Manage PUT ``request``.""" # TODO: Improve charset detection - contentType = request.getHeader("content-type") + self._parse_path() + contentType = self.headers["content-type"] if contentType and "charset=" in contentType: charset = contentType.split("charset=")[1].strip() else: charset = config.get("encoding", "request") - ical_request = request.content.read().decode(charset) - obj = request.getHeader("if-match") - xmlutils.put(ical_request, self.calendar, str(request.URLPath()), obj) - request.setResponseCode(http.CREATED) - return "" + ical_request = self.rfile.read(int(self.headers["Content-Length"])).decode(charset) + obj = self.headers.get("if-match", None) + xmlutils.put(ical_request, self.calendar, self.path, obj) - def render_REPORT(self, request): + self.send_response(httplib.CREATED) + + def do_REPORT(self): """Manage REPORT ``request``.""" - xml_request = request.content.read() - answer = xmlutils.report(xml_request, self.calendar, str(request.URLPath())) - request.setResponseCode(http.MULTI_STATUS) - return answer + self._parse_path() + xml_request = self.rfile.read(int(self.headers["Content-Length"])) + answer = xmlutils.report(xml_request, self.calendar, self.path) -class UserResource(Resource): - """Twisted resource for requests at user depth (/user).""" - def __init__(self, user): - """Initialize by connecting requests to ``user`` calendars resources.""" - Resource.__init__(self) - for cal in _calendars: - if cal.startswith("%s%s"%(user, posixpath.sep)): - cal_name = cal.split(posixpath.sep)[1] - self.putChild(cal_name, CalendarResource(user, cal)) - - def getChild(self, cal, request): - """Get calendar resource if ``cal`` exists.""" - if cal in _calendars: - return Resource.getChild(self, cal, request) - else: - return self - -class HttpResource(Resource): - """Twisted resource for requests at root depth (/).""" - def __init__(self): - """Initialize by connecting requests to the users resources.""" - Resource.__init__(self) - for user in _users: - self.putChild(user, UserResource(user)) - - def getChild(self, user, request): - """Get user resource if ``user`` exists.""" - if user in _users: - return Resource.getChild(self, user, request) - else: - return self + self.send_response(httplib.MULTI_STATUS) + self.send_header("Content-Length", len(answer)) + self.end_headers() + self.wfile.write(answer) diff --git a/setup.py b/setup.py index e5e479b0..1e7309d2 100755 --- a/setup.py +++ b/setup.py @@ -69,7 +69,6 @@ setup( author_email="guillaume.ayoub@kozea.fr", url="http://www.radicale.org/", license="GNU GPL v3", - requires=["twisted.web"], packages=["radicale", "radicale.acl", "radicale.support"], scripts=["radicale.py"], cmdclass={'clean': Clean,