diff --git a/radicale.py b/radicale.py index 3ad856cd..e9b3afc2 100755 --- a/radicale.py +++ b/radicale.py @@ -21,10 +21,7 @@ # TODO: Manage smart and configurable logs # TODO: Manage authentication -# TODO: remove this hack import sys -sys.path.append("/usr/local/lib/python2.5/site-packages") - from twisted.web import server from twisted.internet import reactor from twisted.python import log diff --git a/radicale/acl/fake.py b/radicale/acl/fake.py new file mode 100644 index 00000000..050b8afb --- /dev/null +++ b/radicale/acl/fake.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8; indent-tabs-mode: nil; -*- +# +# This file is part of Radicale Server - Calendar Server +# Copyright © 2008 The Radicale Team +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Radicale. If not, see . + +from .. import config + +def users(): + """ + Get the List of all Users + """ + return [config.get("acl", "defaultUser")] diff --git a/radicale/config.py b/radicale/config.py index 90dc5177..98a00986 100644 --- a/radicale/config.py +++ b/radicale/config.py @@ -35,7 +35,7 @@ _initial = { "certificate": "/etc/apache2/ssl/server.crt", "privatekey": "/etc/apache2/ssl/server.key", "log": "/var/www/radicale/server.log", - "port": "1001", + "port": "5232", }, "encoding": { "request": "utf-8", @@ -48,14 +48,17 @@ _initial = { }, "status": { "200": "HTTP/1.1 200 OK", + "204": "HTTP/1.1 204 No Content", }, "acl": { - "type": "htpasswd", + "type": "fake", "filename": "/etc/radicale/users", + "defaultUser": "radicale", }, "support": { "type": "plain", - "folder": "/var/local/radicale", + "folder": "~/.config/radicale", + "defaultCalendar": "radicale/calendar", }, } diff --git a/radicale/ical.py b/radicale/ical.py index ea454113..7624771f 100644 --- a/radicale/ical.py +++ b/radicale/ical.py @@ -21,18 +21,21 @@ import calendar -def writeCalendar(headers=[], timezones=[], todos=[], events=[]): +def writeCalendar(headers=[calendar.Header("PRODID:-//The Radicale Team//NONSGML Radicale Server//EN"), + calendar.Header("VERSION:2.0")], + timezones=[], todos=[], events=[]): """ Create calendar from headers, timezones, todos, events """ # TODO: Manage encoding and EOL - return "\n".join(( + 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 events(vcalendar): """ diff --git a/radicale/support/__init__.py b/radicale/support/__init__.py index 5351db28..a2ee403b 100644 --- a/radicale/support/__init__.py +++ b/radicale/support/__init__.py @@ -22,5 +22,6 @@ _support = __import__(config.get("support", "type"), locals(), globals()) append = _support.append calendars =_support.calendars +mkcalendar =_support.mkcalendar read = _support.read remove = _support.remove diff --git a/radicale/support/plain.py b/radicale/support/plain.py index 8a8cbaf0..f102433b 100644 --- a/radicale/support/plain.py +++ b/radicale/support/plain.py @@ -22,23 +22,35 @@ import posixpath from .. import ical from .. import config +_folder = os.path.expanduser(config.get("support", "folder")) + def calendars(): """ List Available Calendars Paths """ calendars = [] - for folder in os.listdir(config.get("support", "folder")): - for cal in os.listdir(os.path.join(config.get("support", "folder"), folder)): + for folder in os.listdir(_folder): + for cal in os.listdir(os.path.join(_folder, folder)): calendars.append(posixpath.join(folder, cal)) return calendars +def mkcalendar(name): + """ + Write new calendar + """ + 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.writeCalendar()) + def read(cal): """ Read cal """ - path = os.path.join(config.get("support", "folder"), cal.replace(posixpath.sep, os.path.sep)) + path = os.path.join(_folder, cal.replace(posixpath.sep, os.path.sep)) return open(path).read() def append(cal, vcalendar): @@ -47,7 +59,7 @@ def append(cal, vcalendar): """ oldCalendar = read(cal) oldTzs = [tz.tzid for tz in ical.timezones(oldCalendar)] - path = os.path.join(config.get("support", "folder"), cal.replace(posixpath.sep, os.path.sep)) + path = os.path.join(_folder, cal.replace(posixpath.sep, os.path.sep)) oldObjects = [] oldObjects.extend([event.etag() for event in ical.events(oldCalendar)]) @@ -89,7 +101,7 @@ def remove(cal, etag): """ Remove object named uid from cal """ - path = os.path.join(config.get("support", "folder"), cal.replace(posixpath.sep, os.path.sep)) + path = os.path.join(_folder, cal.replace(posixpath.sep, os.path.sep)) cal = read(cal) @@ -102,3 +114,8 @@ def remove(cal, etag): fd.write(ical.writeCalendar(headers, timezones, todos, events)) fd.close() +if config.get("support", "defaultCalendar"): + user, cal = config.get("support", "defaultCalendar").split(posixpath.sep) + if not os.path.exists(os.path.join(_folder, user, cal)): + mkcalendar(config.get("support", "defaultCalendar")) + diff --git a/radicale/xmlutils.py b/radicale/xmlutils.py index 63949601..557705cf 100644 --- a/radicale/xmlutils.py +++ b/radicale/xmlutils.py @@ -171,6 +171,19 @@ def report(xmlRequest, calendar, url): objects.extend(ical.events(calendar.vcalendar())) objects.extend(ical.todos(calendar.vcalendar())) + if not objects: + # TODO: Read rfc4791-9.[6|10] to find a right answer + response = ET.Element(_tag("D", "response")) + multistatus.append(response) + + href = ET.Element(_tag("D", "href")) + href.text = url + response.append(href) + + status = ET.Element(_tag("D", "status")) + status.text = config.get("status", "204") + response.append(status) + for obj in objects: # TODO: Use the hreference to read data and create href.text # We assume here that hreference is url