diary

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

commit 8b53d98157d6610eb55d31c2e1304625c1c49616
parent 3f582f78e7fcd5169b6243d5951581a0d9f2015a
Author: Andreas Gruhler <agruhl@gmx.ch>
Date:   Wed, 26 May 2021 22:14:28 +0200

unfold ical TEXT

Diffstat:
Mcaldav.c | 21+++++++++++++++------
Mutils.c | 72+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Mutils.h | 3++-
3 files changed, 76 insertions(+), 20 deletions(-)

diff --git a/caldav.c b/caldav.c @@ -598,7 +598,7 @@ void caldav_sync(struct tm* date, WINDOW* header, WINDOW* cal, int pad_pos) { time_t remote_date; // check remote LAST-MODIFIED:20210521T212441Z of remote event - char* remote_last_mod = extract_ical_field(event, "LAST-MODIFIED"); + char* remote_last_mod = extract_ical_field(event, "LAST-MODIFIED", false); fprintf(stderr, "Remote last modified: %s\n", remote_last_mod); if (remote_last_mod == NULL) { remote_file_exists = false; @@ -629,14 +629,14 @@ void caldav_sync(struct tm* date, WINDOW* header, WINDOW* cal, int pad_pos) { //put_event(date); } - char* remote_desc; + char* rmt_desc; if (timediff < 0 && remote_file_exists) { //todo: Warn - really sync? remote is more recent and will overwrite //fprintf(stderr, "Remote file is newer, extracting description from remote...\n"); - remote_desc = extract_ical_field(event, "DESCRIPTION"); - fprintf(stderr, "Remote event description:%s\n", remote_desc); - if (remote_desc == NULL) { + rmt_desc = extract_ical_field(event, "DESCRIPTION", true); + fprintf(stderr, "Remote event description:%s\n", rmt_desc); + if (rmt_desc == NULL) { fprintf(stderr, "Failed to fetch description of remote event.\n"); return; } @@ -646,7 +646,16 @@ void caldav_sync(struct tm* date, WINDOW* header, WINDOW* cal, int pad_pos) { if (cursordate_file == NULL) { perror("Failed to open cursor date file"); } else { - fprintf(cursordate_file, remote_desc); + for (char* i = rmt_desc; *i != '\0'; i++) { + if (rmt_desc[i-rmt_desc] == 0x5C) { // backslash + if (*(i+1) == 'n') { + fputc('\n', cursordate_file); + i++; + } + } else { + fputc(*i, cursordate_file); + } + } } fclose(cursordate_file); diff --git a/utils.c b/utils.c @@ -24,24 +24,70 @@ char* extract_json_value(char* json, char* key, bool quoted) { return tok; } -char* extract_ical_field(char* ical, char* key) { +char* unfold(const char* str) { + // work on a copy of the str + char* res = (char *) malloc(strlen(str) * sizeof(char)); + strcpy(res, str); + + res = strtok(res, "\n"); + + char* buf = malloc(strlen(res)); + strcpy(buf, res); + + regex_t re; + regmatch_t pm[1]; + + if (regcomp(&re, "^[^ \t]", 0) != 0) { + perror("Failed to compile regex"); + return NULL; + } + + while (res != NULL) { + res = strtok(NULL, "\n"); + + if (regexec(&re, res, 1, pm, 0) == 0) { + // Stop unfolding if line does not start with white space/tab: + // https://datatracker.ietf.org/doc/html/rfc2445#section-4.1 + break; + } + + buf = realloc(buf, strlen(buf) + strlen(res)); + if (buf != NULL) { + strcat(buf, res + 1); + } else { + perror("realloc failed"); + return NULL; + } + } + + regfree(&re); + //free(buf); + return buf; +} + +char* extract_ical_field(const char* ics, char* key, bool multiline) { // work on a copy of the ical xml response - char* field = (char *) malloc(strlen(ical) * sizeof(char)); - strcpy(field, ical); - - field = strtok(field, "\n"); - while (field != NULL) { - if (strstr(field, key) != NULL) { - fprintf(stderr, "field: %s\n", field); - field = strstr(field, ":"); // value - field++; // strip the ":" + char* field = (char *) malloc(strlen(ics) * sizeof(char)); + strcpy(field, ics); + + char* res = strtok(field, "\n"); + + while (res != NULL) { + if (strstr(res, key) != NULL) { + res = strstr(res, ":"); // value + res++; // strip the ":" break; } - // key was not in this field, advance field - field = strtok(NULL, "\n"); + // key not in this line, advance line + res = strtok(NULL, "\n"); + } + + if (multiline) { + res = unfold(ics + (res - field)); } - return field; + free(field); + return res; } // Return expanded file path diff --git a/utils.h b/utils.h @@ -1,6 +1,7 @@ #ifndef DIARY_UTILS_H #define DIARY_UTILS_H +#include <regex.h> #include <stdio.h> #include <stdlib.h> #include <time.h> @@ -21,7 +22,7 @@ #define MAX_MONTH_HEIGHT 6 char* extract_json_value(char* json, char* key, bool quoted); -char* extract_ical_field(char* ical, char* key); +char* extract_ical_field(const char* ical, char* key, bool multline); char* expand_path(char* str); char* strrstr(char *haystack, char *needle); void fpath(const char* dir, size_t dir_size, const struct tm* date, char** rpath, size_t rpath_size);