Remove Twisted dependency.

This commit is contained in:
Guillaume Ayoub 2010-01-10 18:55:32 +01:00
parent 330283ef94
commit 5e5e5e1023
3 changed files with 54 additions and 98 deletions

View File

@ -23,7 +23,6 @@
# TODO: Manage smart and configurable logs # TODO: Manage smart and configurable logs
# TODO: Manage authentication # TODO: Manage authentication
# TODO: Magage command-line options # TODO: Magage command-line options
# TODO: Forget twisted?
""" """
Radicale Server entry point. Radicale Server entry point.
@ -32,29 +31,12 @@ Launch the Radicale Serve according to the configuration.
""" """
import sys import sys
from twisted.web import server import BaseHTTPServer
from twisted.internet import reactor
from twisted.python import log
import radicale 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": if radicale.config.get("server", "type") == "http":
reactor.listenTCP(radicale.config.getint("server", "port"), factory) server = BaseHTTPServer.HTTPServer(
elif radicale.config.get("server", "type") == "https": ("", radicale.config.getint("server", "port")),
reactor.listenSSL(radicale.config.getint("server", "port"), factory, ServerContextFactory()) radicale.CalendarHandler)
server.serve_forever()
reactor.run()

View File

@ -19,11 +19,10 @@
# along with Radicale. If not, see <http://www.gnu.org/licenses/>. # along with Radicale. If not, see <http://www.gnu.org/licenses/>.
# TODO: Manage errors (see xmlutils) # TODO: Manage errors (see xmlutils)
# TODO: Forget twisted?
from twisted.web.resource import Resource
from twisted.web import http
import posixpath import posixpath
import httplib
import BaseHTTPServer
import config import config
import support import support
@ -34,90 +33,66 @@ import calendar
_users = acl.users() _users = acl.users()
_calendars = support.calendars() _calendars = support.calendars()
class CalendarResource(Resource): class CalendarHandler(BaseHTTPServer.BaseHTTPRequestHandler):
"""Twisted resource for requests at calendar depth (/user/calendar).""" """HTTP requests handler for calendars."""
# Tell twisted this is a leaf for requests def _parse_path(self):
isLeaf = True 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): def do_DELETE(self):
"""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):
"""Manage DELETE ``request``.""" """Manage DELETE ``request``."""
obj = request.getHeader("if-match") self._parse_path()
answer = xmlutils.delete(obj, self.calendar, str(request.URLPath())) obj = self.headers.get("if-match", None)
request.setResponseCode(http.NO_CONTENT) answer = xmlutils.delete(obj, self.calendar, self.path)
return answer
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``.""" """Manage OPTIONS ``request``."""
request.setHeader("Allow", "DELETE, OPTIONS, PROPFIND, PUT, REPORT") self.send_response(httplib.OK)
request.setHeader("DAV", "1, calendar-access") self.send_header("Allow", "DELETE, OPTIONS, PROPFIND, PUT, REPORT")
request.setResponseCode(http.OK) self.send_header("DAV", "1, calendar-access")
return "" self.end_headers()
def render_PROPFIND(self, request): def do_PROPFIND(self):
"""Manage PROPFIND ``request``.""" """Manage PROPFIND ``request``."""
xml_request = request.content.read() self._parse_path()
answer = xmlutils.propfind(xml_request, self.calendar, str(request.URLPath())) xml_request = self.rfile.read(int(self.headers["Content-Length"]))
request.setResponseCode(http.MULTI_STATUS) answer = xmlutils.propfind(xml_request, self.calendar, self.path)
return answer
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``.""" """Manage PUT ``request``."""
# TODO: Improve charset detection # TODO: Improve charset detection
contentType = request.getHeader("content-type") self._parse_path()
contentType = self.headers["content-type"]
if contentType and "charset=" in contentType: if contentType and "charset=" in contentType:
charset = contentType.split("charset=")[1].strip() charset = contentType.split("charset=")[1].strip()
else: else:
charset = config.get("encoding", "request") charset = config.get("encoding", "request")
ical_request = request.content.read().decode(charset) ical_request = self.rfile.read(int(self.headers["Content-Length"])).decode(charset)
obj = request.getHeader("if-match") obj = self.headers.get("if-match", None)
xmlutils.put(ical_request, self.calendar, str(request.URLPath()), obj) xmlutils.put(ical_request, self.calendar, self.path, obj)
request.setResponseCode(http.CREATED)
return ""
def render_REPORT(self, request): self.send_response(httplib.CREATED)
def do_REPORT(self):
"""Manage REPORT ``request``.""" """Manage REPORT ``request``."""
xml_request = request.content.read() self._parse_path()
answer = xmlutils.report(xml_request, self.calendar, str(request.URLPath())) xml_request = self.rfile.read(int(self.headers["Content-Length"]))
request.setResponseCode(http.MULTI_STATUS) answer = xmlutils.report(xml_request, self.calendar, self.path)
return answer
class UserResource(Resource): self.send_response(httplib.MULTI_STATUS)
"""Twisted resource for requests at user depth (/user).""" self.send_header("Content-Length", len(answer))
def __init__(self, user): self.end_headers()
"""Initialize by connecting requests to ``user`` calendars resources.""" self.wfile.write(answer)
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

View File

@ -69,7 +69,6 @@ setup(
author_email="guillaume.ayoub@kozea.fr", author_email="guillaume.ayoub@kozea.fr",
url="http://www.radicale.org/", url="http://www.radicale.org/",
license="GNU GPL v3", license="GNU GPL v3",
requires=["twisted.web"],
packages=["radicale", "radicale.acl", "radicale.support"], packages=["radicale", "radicale.acl", "radicale.support"],
scripts=["radicale.py"], scripts=["radicale.py"],
cmdclass={'clean': Clean, cmdclass={'clean': Clean,