-
Notifications
You must be signed in to change notification settings - Fork 107
Description
Hello,
I noticed #198 regarding a request for limiting the date range for sync.
I was able to modify the org-caldav-url-dav-get-properties function to instead of using the PROPFIND method use the REPORT method like so
(defun org-caldav-url-dav-get-report (url)
"Retrieve PROPERTY from URL.
Output is the same as `url-dav-get-properties'. This switches to
OAuth2 if necessary."
(let* ((start-end-tag (and (boundp 'org-caldav-sync-start-date)
(not (string-empty-p org-caldav-sync-start-date))
(concat "<c:time-range start=\"" org-caldav-sync-start-date "\" end=\"20250801T000000Z\"/>")))
(request-data (concat "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
"<c:calendar-query xmlns=\"urn:ietf:params:xml:ns:caldav\" xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\" >"
"<d:prop>"
"<d:getetag/>"
"</d:prop>"
"<c:filter>"
"<c:comp-filter name=\"VCALENDAR\">"
"<c:comp-filter name=\"VEVENT\">"
start-end-tag
"</c:comp-filter>"
"</c:comp-filter>"
"</c:filter>"
"</c:calendar-query>"
))
(extra '(("Depth" . "1") ("Content-type" . "text/xml"))))
(let ((resultbuf (org-caldav-url-retrieve-synchronously
url "REPORT" request-data extra))
(retr 1))
(while (and (= 0 (buffer-size resultbuf)) (< retr org-caldav-retry-attempts))
(org-caldav-debug-print 1 (format "org-caldav-url-dav-get-properties: could not get data from url: %s\n trying again..." url))
(setq resultbuf (org-caldav-url-retrieve-synchronously
url "REPORT" request-data extra))
(setq retr (1+ retr)))
;; Check if we got a valid result for PROPFIND
(with-current-buffer resultbuf
(goto-char (point-min))
(when (not (re-search-forward "^HTTP[^ ]* \\([0-9]+ .*\\)$"
(line-end-position) t))
(switch-to-buffer resultbuf)
(error "No valid HTTP response from URL %s." url))
(let ((response (match-string 1)))
(when (not (string-match "2[0-9][0-9].*" response))
(switch-to-buffer resultbuf)
(error "Error while doing PROPFIND for '%s' at URL %s: %s" property url response))))
(org-caldav-namespace-bug-workaround resultbuf)
(let ((processed (url-dav-process-response resultbuf url)))
;; (org-caldav-debug-print 3 (format "\
;; ====Begin properties (%s)
;; %s
;; ====End properties (%s)"
;; property processed property))
processed))))
The end time can be removed.
And then defining a variable like.
(defcustom org-caldav-sync-start-date nil
"Starting date for sync operations. If not present then will fetch the entire calendar."
:type 'string)
This works with a call to org-calsav-url-dav-get-report inside of org-caldav-get-event-etag-list.
Questions
I noticed that using the PROPFIND method to caldav returns a first element of a kind of "metadata" xml item that just contains the calendar id. Therefore, a list of length 1 from the PROPFIND method really means there are no events. I addressed this in the new "report" method by taking away the ((> (length output) 1) line to ((> (length output) 0) (because REPORT does not return this additional item). Is this "metadata" xml item used elsewhere? I think in most other ways the REPORT method mimics the PROPFIND method with the added functionality of being able to limit how far back (or forward) you are syncing your events.
I would really appreciate any feedback on this. If the PROPFIND method can be replaced with the REPORT one I think this could add a really useful feature for people with huge calendars that don't want to sync everything.
Thanks!