PIMp my calendar, part 3

My efforts to put a server-backed calendar on my Android phone entered a new phase. I had Radicale on the server and the CalDAV adapater on the phone but they seemed to talk past each other. My phone would set up a CalDAV account successfully but then tell me "You have no calendar" when I tried to create events.

Radicale documentation says calendars are created automagically based on a URL convention, i.e. simply accessing a non-existent calendar should bring it into existence. I tried it with the Mozilla Lightning client and it worked as advertised. The Android adapter, however, still wouldn't see the new calendar nor its events.

WireShark revealed that a CalDAV client apparently enjoys a lot of freedom when formulating requests. A PROPFIND request from Lightning looked like this:

<D:propfind xmlns:D="DAV:"
    xmlns:CS="http://calendarserver.org/ns/"
    xmlns:C="urn:ietf:params:xml:ns:caldav">
  <D:prop>
    <D:resourcetype/>
    <D:owner/>
    <D:supported-report-set/>
    <C:supported-calendar-component-set/>
    <CS:getctag/>
  </D:prop>
</D:propfind>

whereas the Android adapter was sending

<d:propfind xmlns:d="DAV:"
    xmlns:c="urn:ietf:params:xml:ns:caldav"
    xmlns:cs="http://calendarserver.org/ns/"
    xmlns:ic="http://apple.com/ns/ical/">
  <d:prop>
    <d:displayname />
    <d:resourcetype />
    <cs:getctag />
  </d:prop>
</d:propfind>

and it seemed Radicale was not happy with the displayname bit:

...
<propstat>
  <prop>
    <displayname />
  </prop>
  <status>HTTP/1.1 404 Not Found</status>
</propstat>
...

Server-side source code revealed that Radicale returns 404 for properties which it does not recognize (see the final else in the long if-elif chain in _propfind_response() in xmlutils.py). My installed version of Radicale was 0.7. I downloaded the most recent stable release (0.7.1) from the project site and tried that instead. Lo and behold, it finally said

<multistatus xmlns="DAV:"
    xmlns:C="urn:ietf:params:xml:ns:caldav"
    xmlns:CS="http://calendarserver.org/ns/">
  <response>
    <href>/jh/calendar/</href>
    <propstat>
      <prop>
        <displayname>calendar</displayname>
        <resourcetype>
          <C:calendar />
          <collection />
        </resourcetype>
        <CS:getctag>"0"</CS:getctag>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
</multistatus>

The Calendar app on my phone, however, still insisted I had no calendar. Continued in part 4.

Proudly powered by Pelican, which takes great advantage of Python.