commit dc797245bbccdfaab4c6c0c145617c17ac2a2f78
parent a7291940cb1dec93c2eaf11d3f3ab98b8ce520d3
Author: Andreas Gruhler <andreas.gruhler@adfinis.com>
Date: Sat, 14 Sep 2024 14:34:31 +0200
fix(caldav): multistatus (#96) and cr escaping (#97)
This fixes two bugs:
* #96 Properly parse multistatus: A day can have multiple all-day
events, which will be returned as "calendar-data" entries in the XML.
By using libxml2 we can check the PRODID of the events and only sync
with the daily event of the diary.
* #97 GMX unfolding - escaped CR: The XML response for certain providers
has a character sequence " " at the end of each ics field. This is
an escaped carriage return. Properly parsing the XML with libxml2
automatically detects and converts that carriage return.
Diffstat:
1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/src/caldav.c b/src/caldav.c
@@ -392,19 +392,29 @@ int caldav_sync(struct tm* date,
// fetch event for the cursor date
sprintf(uri, "%s://%s%s", caldav_host_scheme, caldav_host, calendar_href);
- char* event = caldav_req(date, uri, "REPORT", caldata_postfields, 1, basicauth_enabled, "application/xml", 0);
- // todo: warn if multiple events,
- // multistatus has more than just one caldav:calendar-data elements
- // currently, the code below will just extract the first occurance of
- // DTSTAMP, UID and DESCRIPTION (from the first event)
+ char* events_xml = caldav_req(date, uri, "REPORT", caldata_postfields, 1, basicauth_enabled, "application/xml", 0);
- if (event == NULL) {
- tracepoint(diary, debug, "Event not found");
- pthread_cancel(progress_tid);
- wclear(header);
+ if (events_xml == NULL) {
+ tracepoint(diary, debug, "Events could not be fetched");
+ show_info(header, "Events could not be fetched", &progress_tid);
return -1;
}
+ // only fetch PRODID diary events
+ char* event = extract_xml_content(
+ events_xml,
+ "//*[local-name()='calendar-data' and contains(text(), 'PRODID:-//diary')]",
+ header,
+ &progress_tid);
+
+ free(events_xml);
+
+ // no remote event found
+ if (event == NULL) {
+ tracepoint(diary, debug, "No remote events found, continuing.");
+ event = "";
+ }
+
// get path of entry
char path[100];
char* ppath = path;
@@ -461,7 +471,6 @@ int caldav_sync(struct tm* date,
// free memory allocated to store curl response
curl_free(caldav_host_scheme);
curl_free(caldav_host);
- free(event);
free(remote_uid);
return 0;
} else if (timediff > 0) {
@@ -490,7 +499,6 @@ int caldav_sync(struct tm* date,
wclear(header);
curl_free(caldav_host_scheme);
curl_free(caldav_host);
- free(event);
free(remote_uid);
return -1;
}
@@ -550,7 +558,6 @@ int caldav_sync(struct tm* date,
// free memory allocated to store curl response
curl_free(caldav_host_scheme);
curl_free(caldav_host);
- free(event);
free(remote_uid);
free(calendar_href);
pthread_join(progress_tid, NULL);