dengste / org-caldav

Caldav sync for Emacs orgmode
GNU General Public License v3.0
718 stars 105 forks source link

No child nodes in DAV:prop #126

Open erjoalgo opened 7 years ago

erjoalgo commented 7 years ago

May be similar to #74 , I get No child nodes in DAV:prop after org-caldav-sync.

My calendar is not empty and I have been able to sync with Thunderbird, evolution, an android client, etc. Yet my org-caldav-inbox file is empty.

Any idea on how to troubleshoot further?

rgemulla commented 7 years ago

Same problem here. The reason seems to be that some CalDAV servers send multi-status responses, and org-caldav picks the first one instead of the "right" one.

rgemulla commented 7 years ago

I looked at the output from the CalDAV server: the first DAV:response node does not contain a calendar entry and has subtrees with empty DAV:prop nodes. These node make url-dav-dispatch-node fail with the error that you mentioned. Starting from the second node, the calendar entries show up.

  <DAV:response>
    <DAV:href>/somewhere
    </DAV:href>
    <DAV:propstat>
      <DAV:prop/>
      <DAV:status>HTTP/1.1 200 OK
      </DAV:status>
    </DAV:propstat>
    <DAV:propstat>
      <DAV:prop>
        <DAV:getetag/>
      </DAV:prop>
      <DAV:status>HTTP/1.1 404 Not Found
      </DAV:status>
    </DAV:propstat>
  </DAV:response>
rgemulla commented 7 years ago

This patch fixes the issue for me. It's quite a hack, though.

(defun org-caldav-url-dav-get-properties (url property)
  "Retrieve PROPERTY from URL.
Output is the same as `url-dav-get-properties'.  This switches to
OAuth2 if necessary."
  (let ((request-data (concat "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
                  "<DAV:propfind xmlns:DAV='DAV:'>\n<DAV:prop>"
                  "<DAV:" property "/></DAV:prop></DAV:propfind>\n"))
    (extra '(("Depth" . "1") ("Content-type" . "text/xml"))))
    (let ((resultbuf (org-caldav-url-retrieve-synchronously
              url "PROPFIND" request-data extra)))
      (org-caldav-namespace-bug-workaround resultbuf)
      ;; HACK: remove DAV:responses with empty properties
      (with-current-buffer resultbuf
        (save-excursion 
          (while (re-search-forward "<DAV:response>" nil t)
            (let ((begin (point))
                  (end (progn (re-search-forward "</DAV:response>" nil t) (+ (point) 15))))
              (when (and begin end)
                (goto-char begin)
                (if (and (re-search-forward "<DAV:prop/>" nil t) (< (point) end))
                    (progn
                      (goto-char end)
                      (delete-region begin end))
                  (goto-char end)))))))
      (url-dav-process-response resultbuf url))))
erjoalgo commented 6 years ago

I tried your org-caldav-url-dav-get-properties but I'm still getting the same issue:

url-dav-process-DAV:prop: No child nodes in DAV:prop

erjoalgo commented 6 years ago

Here's the response I get from the server:

HTTP/1.1 207 Multi-Status
Date: Thu, 07 Sep 2017 17:46:26 GMT
Content-Type: text/xml; charset="utf-8"
Content-Length: 1479
Connection: close
Server: 1.1
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule
DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy
ETag: "5096556021c2cc19cc1b241e23a3f00c"
X-DAViCal-Version: DAViCal/1.1.3; DB/1.2.11

<?xml version="1.0" encoding="utf-8" ?>
<DAV:multistatus xmlns:DAV="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
 <DAV:response>
  <DAV:href>/caldav.php/erjoalgo/calendar/</DAV:href>
  <DAV:propstat>
   <DAV:prop>
    <DAV:resourcetype>
     <DAV:collection/>
     <DAV:C:calendar/>
    </DAV:resourcetype>
   </DAV:prop>
   <DAV:status>HTTP/1.1 200 OK</DAV:status>
  </DAV:propstat>
 </DAV:response>
 <DAV:response>
  <DAV:href>/caldav.php/erjoalgo/calendar/dd501b64-a8ce-4395-be90-d247956d5833.ics</DAV:href>
  <DAV:propstat>
   <DAV:prop>
    <DAV:resourcetype/>
   </DAV:prop>
   <DAV:status>HTTP/1.1 200 OK</DAV:status>
  </DAV:propstat>
 </DAV:response>
 <DAV:response>
  <DAV:href>/caldav.php/erjoalgo/calendar/3e28d960-470a-45e2-99ff-b751e9e4aaa6.ics</DAV:href>
  <DAV:propstat>
   <DAV:prop>
    <DAV:resourcetype/>
   </DAV:prop>
   <DAV:status>HTTP/1.1 200 OK</DAV:status>
  </DAV:propstat>
 </DAV:response>
 <DAV:response>
  <DAV:href>/caldav.php/erjoalgo/calendar/20170904T181819Z-10940-1000-32227-0_debian-x1-20170904T181821Z.ics</DAV:href>
  <DAV:propstat>
   <DAV:prop>
    <DAV:resourcetype/>
   </DAV:prop>
   <DAV:status>HTTP/1.1 200 OK</DAV:status>
  </DAV:propstat>
 </DAV:response>
 <DAV:response>
  <DAV:href>/caldav.php/erjoalgo/calendar/20170904T215421Z-b7a941ae0457909f.ics</DAV:href>
  <DAV:propstat>
   <DAV:prop>
    <DAV:resourcetype/>
   </DAV:prop>
   <DAV:status>HTTP/1.1 200 OK</DAV:status>
  </DAV:propstat>
 </DAV:response>
 <DAV:response>
  <DAV:href>/caldav.php/erjoalgo/calendar/20170904T220648Z-10940-1000-32227-13_debian-x1-20170904T220741Z.ics</DAV:href>
  <DAV:propstat>
   <DAV:prop>
    <DAV:resourcetype/>
   </DAV:prop>
   <DAV:status>HTTP/1.1 200 OK</DAV:status>
  </DAV:propstat>
 </DAV:response>
</DAV:multistatus>
rgemulla commented 6 years ago

Strange, all your DAV:prop nodes seem to have children. Anyway, in this response, the DAV:getetag node within each DAV:prop node is missing... I do not know how to fix this.