Explorar o código

Add support for PROPPATCH requests

Guillaume Ayoub %!s(int64=15) %!d(string=hai) anos
pai
achega
c1da6872dd
Modificáronse 2 ficheiros con 53 adicións e 1 borrados
  1. 13 1
      radicale/__init__.py
  2. 40 0
      radicale/xmlutils.py

+ 13 - 1
radicale/__init__.py

@@ -291,7 +291,7 @@ class CalendarHTTPHandler(server.BaseHTTPRequestHandler):
         self.send_response(client.OK)
         self.send_header(
             "Allow", "DELETE, HEAD, GET, MKCALENDAR, "
-            "OPTIONS, PROPFIND, PUT, REPORT")
+            "OPTIONS, PROPFIND, PROPPATCH, PUT, REPORT")
         self.send_header("DAV", "1, calendar-access")
         self.end_headers()
 
@@ -309,6 +309,18 @@ class CalendarHTTPHandler(server.BaseHTTPRequestHandler):
         self.end_headers()
         self.wfile.write(self._answer)
 
+    @log_request_content
+    def do_PROPPATCH(self):
+        """Manage PROPPATCH request."""
+        self._answer = xmlutils.proppatch()
+
+        self.send_response(client.MULTI_STATUS)
+        self.send_header("DAV", "1, calendar-access")
+        self.send_header("Content-Length", len(self._answer))
+        self.send_header("Content-Type", "text/xml")
+        self.end_headers()
+        self.wfile.write(self._answer)
+
     @log_request_content
     @check_rights
     def do_PUT(self):

+ 40 - 0
radicale/xmlutils.py

@@ -179,6 +179,46 @@ def propfind(path, xml_request, calendar, depth):
     return ET.tostring(multistatus, config.get("encoding", "request"))
 
 
+def proppatch(path, xml_request, calendar):
+    """Read and answer PROPPATCH requests.
+
+    Read rfc4918-9.2 for info.
+
+    """
+    # Reading request
+    root = ET.fromstring(xml_request)
+
+    prop_element = root.find(_tag("D", "prop"))
+    prop_list = prop_element.getchildren()
+    props = [prop.tag for prop in prop_list]
+
+    # Writing answer
+    multistatus = ET.Element(_tag("D", "multistatus"))
+
+    response = ET.Element(_tag("D", "response"))
+    multistatus.append(response)
+
+    href = ET.Element(_tag("D", "href"))
+    href.text = path
+    response.append(href)
+
+    propstat = ET.Element(_tag("D", "propstat"))
+    response.append(propstat)
+
+    prop = ET.Element(_tag("D", "prop"))
+    propstat.append(prop)
+
+    for tag in props:
+        element = ET.Element(tag)
+        prop.append(element)
+
+    status = ET.Element(_tag("D", "status"))
+    status.text = _response(200)
+    propstat.append(status)
+
+    return ET.tostring(multistatus, config.get("encoding", "request"))
+
+
 def put(path, ical_request, calendar):
     """Read PUT requests."""
     name = name_from_path(path, calendar)