diary

Text-based journaling program
git clone https://git.in0rdr.ch/diary.git
Log | Files | Refs | Pull requests | README | LICENSE

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 "&#13;" 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:
Msrc/caldav.c | 31+++++++++++++++++++------------
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);