MKCALENDAR now actually creates the calendar.
This commit is contained in:
parent
b230601ee2
commit
85e283830a
@ -256,6 +256,11 @@ class Application(object):
|
||||
|
||||
def mkcalendar(self, environ, calendar, content):
|
||||
"""Manage MKCALENDAR request."""
|
||||
props = xmlutils.props_from_request(content)
|
||||
tz = props.get('C:calendar-timezone')
|
||||
if tz:
|
||||
calendar.replace('', tz)
|
||||
calendar.write()
|
||||
return client.CREATED, {}, None
|
||||
|
||||
def options(self, environ, calendar, content):
|
||||
|
@ -33,7 +33,7 @@ from radicale import config
|
||||
|
||||
|
||||
FOLDER = os.path.expanduser(config.get("storage", "folder"))
|
||||
|
||||
|
||||
|
||||
# This function overrides the builtin ``open`` function for this module
|
||||
# pylint: disable=W0622
|
||||
@ -242,7 +242,7 @@ class Calendar(object):
|
||||
# Create folder if absent
|
||||
if not os.path.exists(os.path.dirname(self.path)):
|
||||
os.makedirs(os.path.dirname(self.path))
|
||||
|
||||
|
||||
text = serialize(headers, items)
|
||||
return open(self.path, "w").write(text)
|
||||
|
||||
|
@ -27,6 +27,12 @@ in them for XML requests (all but PUT).
|
||||
|
||||
"""
|
||||
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
except ImportError:
|
||||
# Python 2.6
|
||||
OrderedDict = dict
|
||||
import re
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from radicale import client, config, ical
|
||||
@ -39,7 +45,11 @@ NAMESPACES = {
|
||||
"ICAL": "http://apple.com/ns/ical/"}
|
||||
|
||||
|
||||
NAMESPACES_REV = {}
|
||||
|
||||
|
||||
for short, url in NAMESPACES.items():
|
||||
NAMESPACES_REV[url] = short
|
||||
if hasattr(ET, "register_namespace"):
|
||||
# Register namespaces cleanly with Python 2.7+ and 3.2+ ...
|
||||
ET.register_namespace("" if short == "D" else short, url)
|
||||
@ -48,6 +58,14 @@ for short, url in NAMESPACES.items():
|
||||
ET._namespace_map[url] = short
|
||||
|
||||
|
||||
CLARK_TAG_REGEX = re.compile(r"""
|
||||
{ # {
|
||||
(?P<namespace>[^}]*) # namespace URL
|
||||
} # }
|
||||
(?P<tag>.*) # short tag name
|
||||
""", re.VERBOSE)
|
||||
|
||||
|
||||
def _pretty_xml(element, level=0):
|
||||
"""Indent an ElementTree ``element`` and its children."""
|
||||
i = "\n" + level * " "
|
||||
@ -87,6 +105,31 @@ def name_from_path(path, calendar):
|
||||
return path_parts[-1] if (len(path_parts) - len(calendar_parts)) else None
|
||||
|
||||
|
||||
def props_from_request(xml_request):
|
||||
"""Returns a list of properties as a dictionary."""
|
||||
|
||||
result = OrderedDict()
|
||||
root = ET.fromstring(xml_request.encode("utf8"))
|
||||
|
||||
set_element = root.find(_tag("D", "set"))
|
||||
if not set_element:
|
||||
set_element = root
|
||||
|
||||
prop_element = set_element.find(_tag("D", "prop"))
|
||||
if prop_element:
|
||||
for prop in prop_element:
|
||||
match = CLARK_TAG_REGEX.match(prop.tag)
|
||||
if match and match.group('namespace') in NAMESPACES_REV:
|
||||
args = {
|
||||
'ns': NAMESPACES_REV[match.group('namespace')],
|
||||
'tag': match.group('tag')}
|
||||
tag_name = '%(ns)s:%(tag)s' % args
|
||||
else:
|
||||
tag_name = prop.tag
|
||||
result[tag_name] = prop.text
|
||||
return result
|
||||
|
||||
|
||||
def delete(path, calendar):
|
||||
"""Read and answer DELETE requests.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user