commit 451f5028e4c15584c5ca602a460261e92154a388
parent 74e6e2ac35359713fe7e5c2f5996202dd41b094a
Author: Andreas Gruhler <agruhl@gmx.ch>
Date: Sun, 17 Oct 2021 23:17:13 +0200
confirm and write to files
Diffstat:
4 files changed, 146 insertions(+), 12 deletions(-)
diff --git a/src/import.c b/src/import.c
@@ -1,8 +1,14 @@
#include "import.h"
/* Import journal entries from an ics file */
-void ics_import(const char* ics_input) {
+void ics_import(const char* ics_input, WINDOW* header, WINDOW* cal, WINDOW* aside, int* pad_pos, struct tm* curs_date, struct tm* cal_start, struct tm* cal_end) {
+ pthread_t progress_tid;
+
FILE* pfile = fopen(ics_input, "r");
+ if (pfile == NULL) {
+ perror("Error opening file");
+ return;
+ }
fseek(pfile, 0, SEEK_END);
long ics_bytes = ftell(pfile) + 1;
@@ -15,30 +21,96 @@ void ics_import(const char* ics_input) {
ics[ics_bytes] = 0;
// fprintf(stderr, "Import ICS file: %s\n", ics);
- // find all VEVENTs
+ int conf_ch = 0;
+ char dstr[16];
+ struct tm date;
long search_pos = 0;
char *i = ics;
char* vevent;
- char* date;
- char* desc;
+ char* vevent_date;
+ char* vevent_desc;
+ // find all VEVENTs and write to files
for (;;) {
vevent = extract_ical_field(i, "BEGIN:VEVENT", &search_pos, false);
+ vevent_date = extract_ical_field(i, "DTSTART", &search_pos, false);
+ vevent_desc = extract_ical_field(i, "DESCRIPTION", &search_pos, true);
if (vevent == NULL) {
break;
}
- // date = extract_ical_field((ics+search_pos), "DTSTART", &search_pos, false);
- desc = extract_ical_field(i, "DESCRIPTION", &search_pos, true);
+
+ i += search_pos;
+
+ fprintf(stderr, "VEVENT DESCRIPTION: \n\n%s\n\n", vevent_desc);
+
+ // parse date
+ strptime(vevent_date, "%Y%m%dT%H%M%SZ", &date);
+ strftime(dstr, sizeof dstr, CONFIG.fmt, &date);
+
+ // get path of entry
+ char path[100];
+ char* ppath = path;
+ fpath(CONFIG.dir, strlen(CONFIG.dir), &date, &ppath, sizeof path);
+ fprintf(stderr, "Import date file path: %s\n", path);
+
+ if (conf_ch != 'a') {
+ // prepare header for confirmation dialogue
+ curs_set(2);
+ noecho();
+ wclear(header);
+
+ // ask for confirmation
+ mvwprintw(header, 0, 0, "Import entry '%s' and overwrite local file? [(Y)es/(a)ll/(n)o/(c)ancel] ", dstr);
+ conf_ch = wgetch(header);
+ }
+
+ if (conf_ch == 'y' || conf_ch == 'Y' || conf_ch == 'a' || conf_ch == '\n') {
+ pthread_create(&progress_tid, NULL, show_progress, (void*)header);
+
+ // persist VEVENT to local file
+ FILE* cursordate_file = fopen(path, "wb");
+ if (cursordate_file == NULL) {
+ perror("Failed to open import date file");
+ } else {
+ for (char* j = vevent_desc; *j != '\0'; j++) {
+ if (vevent_desc[j-vevent_desc] == 0x5C) { // backslash
+ switch (*(j+1)) {
+ case 'n':
+ fputc('\n', cursordate_file);
+ j++;
+ break;
+ case 0x5c: // preserve real backslash
+ fputc(0x5c, cursordate_file);
+ j++;
+ break;
+ }
+ } else {
+ fputc(*j, cursordate_file);
+ }
+ }
+ fclose(cursordate_file);
+
+ // add new entry highlight
+ go_to(cal, aside, mktime(&date), pad_pos, curs_date, cal_start, cal_end);
+ // update_date(header, curs_date);
+ chtype atrs = winch(cal) & A_ATTRIBUTES;
+ wchgat(cal, 2, atrs | A_BOLD, 0, NULL);
+ prefresh(cal, *pad_pos, 0, 1, ASIDE_WIDTH, LINES - 1, ASIDE_WIDTH + CAL_WIDTH);
+ pthread_cancel(progress_tid);
+ }
+ } else if (conf_ch == 'c') {
+ // cancel all
+ break;
+ }
+
// fprintf(stderr, "Import DTSTART: %s\n", desc);
// fprintf(stderr, "Import DESCRIPTION: %s\n", desc);
fprintf(stderr, "* * * * * * * * * * * * * \n");
free(vevent);
- // free(date);
- free(desc);
-
- i += search_pos;
+ free(vevent_date);
+ free(vevent_desc);
}
free(ics);
}
\ No newline at end of file
diff --git a/src/import.h b/src/import.h
@@ -1,12 +1,16 @@
#ifndef DIARY_IMPORT_H
#define DIARY_IMPORT_H
+#define __USE_XOPEN
+#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <regex.h>
#include <stdbool.h>
+#include <time.h>
+#include <pthread.h>
#include "utils.h"
-void ics_import(const char* ics_input);
+void ics_import(const char* ics_input, WINDOW* header, WINDOW* cal, WINDOW* aside, int* pad_pos, struct tm* curs_date, struct tm* cal_start, struct tm* cal_end);
#endif
\ No newline at end of file
diff --git a/src/utils.c b/src/utils.c
@@ -272,7 +272,7 @@ char* extract_ical_field(const char* ics, char* key, long* start_pos, bool multi
// empty remote value
buf = NULL;
} else if (multiline) {
- buf = unfold(icscp + *start_pos);
+ buf = unfold(ics + *start_pos);
} else {
buf = malloc(strlen(res) + 1);
if (buf == NULL) {
@@ -350,6 +350,61 @@ void fpath(const char* dir, size_t dir_size, const struct tm* date, char** rpath
strcat(*rpath, dstr);
}
+bool go_to(WINDOW* calendar, WINDOW* aside, time_t date, int* cur_pad_pos, struct tm* curs_date, struct tm* cal_start, struct tm* cal_end) {
+ if (date < mktime(cal_start) || date > mktime(cal_end))
+ return false;
+
+ int diff_seconds = date - mktime(cal_start);
+ int diff_days = diff_seconds / 60 / 60 / 24;
+ int diff_weeks = diff_days / 7;
+ int diff_wdays = diff_days % 7;
+
+ localtime_r(&date, curs_date);
+
+ int cy, cx;
+ getyx(calendar, cy, cx);
+
+ // remove the STANDOUT attribute from the day we are leaving
+ chtype current_attrs = mvwinch(calendar, cy, cx) & A_ATTRIBUTES;
+ // leave every attr as is, but turn off STANDOUT
+ current_attrs &= ~A_STANDOUT;
+ mvwchgat(calendar, cy, cx, 2, current_attrs, 0, NULL);
+
+ // add the STANDOUT attribute to the day we are entering
+ chtype new_attrs = mvwinch(calendar, diff_weeks, diff_wdays * 3) & A_ATTRIBUTES;
+ new_attrs |= A_STANDOUT;
+ mvwchgat(calendar, diff_weeks, diff_wdays * 3, 2, new_attrs, 0, NULL);
+
+ if (diff_weeks < *cur_pad_pos)
+ *cur_pad_pos = diff_weeks;
+ if (diff_weeks > *cur_pad_pos + LINES - 2)
+ *cur_pad_pos = diff_weeks - LINES + 2;
+ prefresh(aside, *cur_pad_pos, 0, 1, 0, LINES - 1, ASIDE_WIDTH);
+ prefresh(calendar, *cur_pad_pos, 0, 1, ASIDE_WIDTH, LINES - 1, ASIDE_WIDTH + CAL_WIDTH);
+
+ return true;
+}
+
+
+void* show_progress(void* vargp){
+ WINDOW* header = (WINDOW*) vargp;
+ mvwprintw(header, 0, COLS - CAL_WIDTH - ASIDE_WIDTH - 11, " syncing ");
+ for(;;) {
+ mvwprintw(header, 0, COLS - CAL_WIDTH - ASIDE_WIDTH - 10, "|");
+ wrefresh(header);
+ usleep(200000);
+ mvwprintw(header, 0, COLS - CAL_WIDTH - ASIDE_WIDTH - 10, "/");
+ wrefresh(header);
+ usleep(200000);
+ mvwprintw(header, 0, COLS - CAL_WIDTH - ASIDE_WIDTH - 10, "-");
+ wrefresh(header);
+ usleep(200000);
+ mvwprintw(header, 0, COLS - CAL_WIDTH - ASIDE_WIDTH - 10, "\\");
+ wrefresh(header);
+ usleep(200000);
+ }
+}
+
config CONFIG = {
.range = 1,
.weekday = 1,
diff --git a/src/utils.h b/src/utils.h
@@ -3,6 +3,7 @@
#include <regex.h>
#include <stdio.h>
+#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
@@ -30,6 +31,8 @@ char* extract_ical_field(const char* ical, char* key, long* start_pos, bool mult
char* expand_path(const 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);
+bool go_to(WINDOW* calendar, WINDOW* aside, time_t date, int* cur_pad_pos, struct tm* curs_date, struct tm* cal_start, struct tm* cal_end);
+void* show_progress(void* vargp);
typedef struct
{