Python 3 support and minor fixes.
This commit is contained in:
parent
4a0d3936e8
commit
4ee09cf817
@ -30,13 +30,10 @@ Radicale Server entry point.
|
||||
Launch the Radicale Serve according to the configuration.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import BaseHTTPServer
|
||||
|
||||
import radicale
|
||||
|
||||
if radicale.config.get("server", "type") == "http":
|
||||
server = BaseHTTPServer.HTTPServer(
|
||||
server = radicale.server.HTTPServer(
|
||||
("", radicale.config.getint("server", "port")),
|
||||
radicale.CalendarHandler)
|
||||
server.serve_forever()
|
||||
|
@ -21,25 +21,21 @@
|
||||
# TODO: Manage errors (see xmlutils)
|
||||
|
||||
import posixpath
|
||||
import httplib
|
||||
import BaseHTTPServer
|
||||
try:
|
||||
from http import client, server
|
||||
except ImportError:
|
||||
import httplib as client
|
||||
import BaseHTTPServer as server
|
||||
|
||||
import config
|
||||
import support
|
||||
import acl
|
||||
import xmlutils
|
||||
import calendar
|
||||
from radicale import config, support, xmlutils
|
||||
|
||||
_users = acl.users()
|
||||
_calendars = support.calendars()
|
||||
|
||||
class CalendarHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
class CalendarHandler(server.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)
|
||||
self.calendar = calendar.Calendar("radicale", cal)
|
||||
|
||||
def do_DELETE(self):
|
||||
"""Manage DELETE ``request``."""
|
||||
@ -47,14 +43,14 @@ class CalendarHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
obj = self.headers.get("if-match", None)
|
||||
answer = xmlutils.delete(obj, self.calendar, self.path)
|
||||
|
||||
self.send_response(httplib.NO_CONTENT)
|
||||
self.send_response(client.NO_CONTENT)
|
||||
self.send_header("Content-Length", len(answer))
|
||||
self.end_headers()
|
||||
self.wfile.write(answer)
|
||||
|
||||
def do_OPTIONS(self):
|
||||
"""Manage OPTIONS ``request``."""
|
||||
self.send_response(httplib.OK)
|
||||
self.send_response(client.OK)
|
||||
self.send_header("Allow", "DELETE, OPTIONS, PROPFIND, PUT, REPORT")
|
||||
self.send_header("DAV", "1, calendar-access")
|
||||
self.end_headers()
|
||||
@ -65,7 +61,7 @@ class CalendarHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
xml_request = self.rfile.read(int(self.headers["Content-Length"]))
|
||||
answer = xmlutils.propfind(xml_request, self.calendar, self.path)
|
||||
|
||||
self.send_response(httplib.MULTI_STATUS)
|
||||
self.send_response(client.MULTI_STATUS)
|
||||
self.send_header("DAV", "1, calendar-access")
|
||||
self.send_header("Content-Length", len(answer))
|
||||
self.end_headers()
|
||||
@ -84,7 +80,7 @@ class CalendarHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
obj = self.headers.get("if-match", None)
|
||||
xmlutils.put(ical_request, self.calendar, self.path, obj)
|
||||
|
||||
self.send_response(httplib.CREATED)
|
||||
self.send_response(client.CREATED)
|
||||
|
||||
def do_REPORT(self):
|
||||
"""Manage REPORT ``request``."""
|
||||
@ -92,7 +88,7 @@ class CalendarHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
xml_request = self.rfile.read(int(self.headers["Content-Length"]))
|
||||
answer = xmlutils.report(xml_request, self.calendar, self.path)
|
||||
|
||||
self.send_response(httplib.MULTI_STATUS)
|
||||
self.send_response(client.MULTI_STATUS)
|
||||
self.send_header("Content-Length", len(answer))
|
||||
self.end_headers()
|
||||
self.wfile.write(answer)
|
||||
|
@ -25,7 +25,7 @@ This module loads a list of users with access rights, according to the acl
|
||||
configuration.
|
||||
"""
|
||||
|
||||
from .. import config
|
||||
from radicale import config
|
||||
|
||||
_acl = __import__(config.get("acl", "type"), locals(), globals())
|
||||
|
||||
|
@ -24,7 +24,7 @@ Fake ACL.
|
||||
Just load the default user set in configuration, with no rights management.
|
||||
"""
|
||||
|
||||
from .. import config
|
||||
from radicale import config
|
||||
|
||||
def users():
|
||||
"""Get the list of all users."""
|
||||
|
@ -26,7 +26,7 @@ Load the list of users according to the htpasswd configuration.
|
||||
|
||||
# TODO: Manage rights
|
||||
|
||||
from .. import config
|
||||
from radicale import config
|
||||
|
||||
def users():
|
||||
"""Get the list of all users."""
|
||||
|
@ -24,7 +24,7 @@ Radicale calendar classes.
|
||||
Define the main classes of a calendar as seen from the server.
|
||||
"""
|
||||
|
||||
import support
|
||||
from radicale import support
|
||||
|
||||
hash_tag = lambda vcalendar: str(hash(vcalendar))
|
||||
|
||||
@ -33,8 +33,9 @@ class Calendar(object):
|
||||
def __init__(self, user, cal):
|
||||
"""Initialize the calendar with ``cal`` and ``user`` parameters."""
|
||||
# TODO: Use properties from the calendar configuration
|
||||
self.support = support.load()
|
||||
self.encoding = "utf-8"
|
||||
self.owner = "lize"
|
||||
self.owner = "radicale"
|
||||
self.user = user
|
||||
self.cal = cal
|
||||
self.version = "2.0"
|
||||
@ -43,22 +44,22 @@ class Calendar(object):
|
||||
def append(self, vcalendar):
|
||||
"""Append vcalendar to the calendar."""
|
||||
self.ctag = hash_tag(self.vcalendar())
|
||||
support.append(self.cal, vcalendar)
|
||||
self.support.append(self.cal, vcalendar)
|
||||
|
||||
def remove(self, uid):
|
||||
"""Remove object named ``uid`` from the calendar."""
|
||||
self.ctag = hash_tag(self.vcalendar())
|
||||
support.remove(self.cal, uid)
|
||||
self.support.remove(self.cal, uid)
|
||||
|
||||
def replace(self, uid, vcalendar):
|
||||
"""Replace objet named ``uid`` by ``vcalendar`` in the calendar."""
|
||||
self.ctag = hash_tag(self.vcalendar())
|
||||
support.remove(self.cal, uid)
|
||||
support.append(self.cal, vcalendar)
|
||||
self.support.remove(self.cal, uid)
|
||||
self.support.append(self.cal, vcalendar)
|
||||
|
||||
def vcalendar(self):
|
||||
"""Return unicode calendar from the calendar."""
|
||||
return unicode(support.read(self.cal), self.encoding)
|
||||
return self.support.read(self.cal)
|
||||
|
||||
def etag(self):
|
||||
"""Return etag from calendar."""
|
||||
|
@ -24,7 +24,10 @@ Radicale configuration module.
|
||||
Give a configparser-like interface to read and write configuration.
|
||||
"""
|
||||
|
||||
from ConfigParser import RawConfigParser as ConfigParser
|
||||
try:
|
||||
from configparser import RawConfigParser as ConfigParser
|
||||
except ImportError:
|
||||
from ConfigParser import RawConfigParser as ConfigParser
|
||||
|
||||
_config = ConfigParser()
|
||||
get = _config.get
|
||||
@ -68,9 +71,9 @@ _initial = {
|
||||
},
|
||||
}
|
||||
|
||||
for section, values in _initial.iteritems():
|
||||
for section, values in _initial.items():
|
||||
_config.add_section(section)
|
||||
for key, value in values.iteritems():
|
||||
for key, value in values.items():
|
||||
_config.set(section, key, value)
|
||||
|
||||
# TODO: Use abstract filename for other platforms
|
||||
|
@ -24,7 +24,7 @@ iCal parsing functions.
|
||||
|
||||
# TODO: Manage filters (see xmlutils)
|
||||
|
||||
import calendar
|
||||
from radicale import calendar
|
||||
|
||||
def write_calendar(headers=[
|
||||
calendar.Header("PRODID:-//Radicale//NONSGML Radicale Server//EN"),
|
||||
@ -32,14 +32,14 @@ def write_calendar(headers=[
|
||||
timezones=[], todos=[], events=[]):
|
||||
"""Create calendar from ``headers``, ``timezones``, ``todos``, ``events``."""
|
||||
# TODO: Manage encoding and EOL
|
||||
cal = u"\n".join((
|
||||
u"BEGIN:VCALENDAR",
|
||||
u"\n".join([header.text for header in headers]),
|
||||
u"\n".join([timezone.text for timezone in timezones]),
|
||||
u"\n".join([todo.text for todo in todos]),
|
||||
u"\n".join([event.text for event in events]),
|
||||
u"END:VCALENDAR"))
|
||||
return u"\n".join([line for line in cal.splitlines() if line])
|
||||
cal = "\n".join((
|
||||
"BEGIN:VCALENDAR",
|
||||
"\n".join([header.text for header in headers]),
|
||||
"\n".join([timezone.text for timezone in timezones]),
|
||||
"\n".join([todo.text for todo in todos]),
|
||||
"\n".join([event.text for event in events]),
|
||||
"END:VCALENDAR"))
|
||||
return "\n".join([line for line in cal.splitlines() if line])
|
||||
|
||||
def headers(vcalendar):
|
||||
"""Find Headers items in ``vcalendar``."""
|
||||
|
@ -22,12 +22,9 @@
|
||||
Calendar storage support configuration.
|
||||
"""
|
||||
|
||||
from .. import config
|
||||
from radicale import config
|
||||
|
||||
_support = __import__(config.get("support", "type"), locals(), globals())
|
||||
|
||||
append = _support.append
|
||||
calendars =_support.calendars
|
||||
mkcalendar =_support.mkcalendar
|
||||
read = _support.read
|
||||
remove = _support.remove
|
||||
def load():
|
||||
module = __import__("radicale.support", globals(), locals(),
|
||||
[config.get("support", "type")])
|
||||
return getattr(module, config.get("support", "type"))
|
||||
|
@ -24,12 +24,15 @@ Plain text storage.
|
||||
|
||||
import os
|
||||
import posixpath
|
||||
import codecs
|
||||
|
||||
from .. import ical
|
||||
from .. import config
|
||||
from radicale import config, ical
|
||||
|
||||
_folder = os.path.expanduser(config.get("support", "folder"))
|
||||
|
||||
def _open(path, mode="r"):
|
||||
return codecs.open(path, mode, config.get("encoding", "stock"))
|
||||
|
||||
def calendars():
|
||||
"""List available calendars paths."""
|
||||
calendars = []
|
||||
@ -45,17 +48,17 @@ def mkcalendar(name):
|
||||
user, cal = name.split(posixpath.sep)
|
||||
if not os.path.exists(os.path.join(_folder, user)):
|
||||
os.makedirs(os.path.join(_folder, user))
|
||||
fd = open(os.path.join(_folder, user, cal), "w")
|
||||
fd.write(ical.write_calendar().encode(config.get("encoding", "stock")))
|
||||
fd = _open(os.path.join(_folder, user, cal), "w")
|
||||
fd.write(ical.write_calendar())
|
||||
|
||||
def read(cal):
|
||||
"""Read calendar ``cal``."""
|
||||
path = os.path.join(_folder, cal.replace(posixpath.sep, os.path.sep))
|
||||
return open(path).read()
|
||||
return _open(path).read()
|
||||
|
||||
def append(cal, vcalendar):
|
||||
"""Append ``vcalendar`` to ``cal``."""
|
||||
old_calendar = unicode(read(cal), config.get("encoding", "stock"))
|
||||
old_calendar = read(cal)
|
||||
old_tzs = [tz.tzid for tz in ical.timezones(old_calendar)]
|
||||
path = os.path.join(_folder, cal.replace(posixpath.sep, os.path.sep))
|
||||
|
||||
@ -69,29 +72,29 @@ def append(cal, vcalendar):
|
||||
|
||||
for tz in ical.timezones(vcalendar):
|
||||
if tz.tzid not in old_tzs:
|
||||
# TODO: Manage position, encoding and EOL
|
||||
fd = open(path)
|
||||
# TODO: Manage position and EOL
|
||||
fd = _open(path)
|
||||
lines = [line for line in fd.readlines() if line]
|
||||
fd.close()
|
||||
|
||||
for i,line in enumerate(tz.text.splitlines()):
|
||||
lines.insert(2+i, line.encode(config.get("encoding", "stock"))+"\n")
|
||||
lines.insert(2 + i, line + "\n")
|
||||
|
||||
fd = open(path, "w")
|
||||
fd = _open(path, "w")
|
||||
fd.writelines(lines)
|
||||
fd.close()
|
||||
|
||||
for obj in objects:
|
||||
if obj.etag() not in old_objects:
|
||||
# TODO: Manage position, encoding and EOL
|
||||
fd = open(path)
|
||||
# TODO: Manage position and EOL
|
||||
fd = _open(path)
|
||||
lines = [line for line in fd.readlines() if line]
|
||||
fd.close()
|
||||
|
||||
for line in obj.text.splitlines():
|
||||
lines.insert(-1, line.encode(config.get("encoding", "stock"))+"\n")
|
||||
lines.insert(-1, line + "\n")
|
||||
|
||||
fd = open(path, "w")
|
||||
fd = _open(path, "w")
|
||||
fd.writelines(lines)
|
||||
fd.close()
|
||||
|
||||
@ -99,15 +102,15 @@ def remove(cal, etag):
|
||||
"""Remove object named ``etag`` from ``cal``."""
|
||||
path = os.path.join(_folder, cal.replace(posixpath.sep, os.path.sep))
|
||||
|
||||
cal = unicode(read(cal), config.get("encoding", "stock"))
|
||||
cal = read(cal)
|
||||
|
||||
headers = ical.headers(cal)
|
||||
timezones = ical.timezones(cal)
|
||||
todos = [todo for todo in ical.todos(cal) if todo.etag() != etag]
|
||||
events = [event for event in ical.events(cal) if event.etag() != etag]
|
||||
|
||||
fd = open(path, "w")
|
||||
fd.write(ical.write_calendar(headers, timezones, todos, events).encode(config.get("encoding", "stock")))
|
||||
fd = _open(path, "w")
|
||||
fd.write(ical.write_calendar(headers, timezones, todos, events))
|
||||
fd.close()
|
||||
|
||||
if config.get("support", "calendar"):
|
||||
|
@ -31,8 +31,7 @@ in them for XML requests (all but PUT).
|
||||
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
import config
|
||||
import ical
|
||||
from radicale import 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
|
||||
|
Loading…
Reference in New Issue
Block a user