diary

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

import.c (4125B)


      1 #include "import.h"
      2 
      3 /* Import journal entries from an ics file */
      4 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) {
      5     pthread_t progress_tid;
      6 
      7     FILE* pfile = fopen(ics_input, "r");
      8     if (pfile == NULL) {
      9         perror("Error opening file");
     10         return;
     11     }
     12 
     13     fseek(pfile, 0, SEEK_END);
     14     long ics_bytes = ftell(pfile);
     15     rewind(pfile);
     16 
     17     char* ics = malloc(ics_bytes + 1);
     18     size_t read = fread(ics, 1, ics_bytes, pfile);
     19     if (read != ics_bytes) {
     20         perror("Error while reading in ics_import()");
     21         fclose(pfile);
     22         return;
     23     }
     24     fclose(pfile);
     25 
     26     ics[ics_bytes] = '\0';
     27 
     28     int conf_ch = 0;
     29     char dstr[16];
     30     time_t current_time = time(NULL);
     31     struct tm date = *localtime(&current_time);
     32 
     33     long search_pos = 0;
     34     char* vevent;
     35     char* vevent_date;
     36     char* vevent_desc;
     37 
     38     // find all VEVENTs and write to files
     39     char *i = ics;
     40     char* j;
     41     while (i < ics + ics_bytes) {
     42         vevent = extract_ical_field(i, "BEGIN:VEVENT", &search_pos, false);
     43         vevent_date = extract_ical_field(i, "DTSTART", &search_pos, false);
     44         vevent_desc = extract_ical_field(i, "DESCRIPTION", &search_pos, true);
     45         if (vevent == NULL || vevent_desc == NULL) {
     46             free(vevent);
     47             free(vevent_date);
     48             free(vevent_desc);
     49             break;
     50         }
     51 
     52         // parse date
     53         strptime(vevent_date, "%Y%m%d", &date);
     54         strftime(dstr, sizeof dstr, CONFIG.fmt, &date);
     55 
     56         // get path of entry
     57         char path[100];
     58         char* ppath = path;
     59         fpath(CONFIG.dir, strlen(CONFIG.dir), &date, &ppath, sizeof path);
     60 
     61         if (conf_ch == 'c') {
     62             free(vevent);
     63             free(vevent_date);
     64             free(vevent_desc);
     65             break;
     66         }
     67 
     68         if (conf_ch != 'a') {
     69             // prepare header for confirmation dialogue
     70             curs_set(2);
     71             noecho();
     72             wclear(header);
     73 
     74             // ask for confirmation
     75             mvwprintw(header, 0, 0, "Import entry '%s' and overwrite local file? [(Y)es/(a)ll/(s)kip/(c)ancel] ", dstr);
     76             conf_ch = wgetch(header);
     77         }
     78 
     79         if (conf_ch == 'y' || conf_ch == 'Y' || conf_ch == 'a' || conf_ch == '\n') {
     80             pthread_create(&progress_tid, NULL, show_progress, (void*)header);
     81             pthread_detach(progress_tid);
     82 
     83             // persist VEVENT to local file
     84             FILE* cursordate_file = fopen(path, "wb");
     85             if (cursordate_file == NULL) {
     86                 perror("Failed to open import date file");
     87             } else {
     88                 for (j = vevent_desc; *j != '\0'; j++) {
     89                     if (vevent_desc[j-vevent_desc] == 0x5C) { // backslash
     90                         switch (*(j+1)) {
     91                             case 'n':
     92                                 fputc('\n', cursordate_file);
     93                                 j++;
     94                                 break;
     95                             case 0x5c: // preserve real backslash
     96                                 fputc(0x5c, cursordate_file);
     97                                 j++;
     98                                 break;
     99                         }
    100                     } else {
    101                         fputc(*j, cursordate_file);
    102                     }
    103                 }
    104                 fclose(cursordate_file);
    105 
    106                 bool mv_valid = go_to(cal, aside, mktime(&date), pad_pos, curs_date, cal_start, cal_end);
    107                 if (mv_valid) {
    108                     // add new entry highlight
    109                     chtype atrs = winch(cal) & A_ATTRIBUTES;
    110                     wchgat(cal, 2, atrs | A_BOLD, 0, NULL);
    111                     prefresh(cal, *pad_pos, 0, 1, ASIDE_WIDTH, LINES - 1, ASIDE_WIDTH + CAL_WIDTH);
    112                 }
    113             }
    114             pthread_cancel(progress_tid);
    115 
    116             i += search_pos;
    117         } else if (conf_ch == 's') {
    118             i += search_pos;
    119         }
    120 
    121         free(vevent);
    122         free(vevent_date);
    123         free(vevent_desc);
    124     }
    125     free(ics);
    126 }