]> Pileus Git - lackey/commitdiff
Working iCalendar parsing
authorAndy Spencer <andy753421@gmail.com>
Fri, 12 Oct 2012 22:22:44 +0000 (22:22 +0000)
committerAndy Spencer <andy753421@gmail.com>
Fri, 12 Oct 2012 22:22:44 +0000 (22:22 +0000)
cal/dummy.c
cal/ical.c
src/date.c
src/event.c
src/event.h
view/week.c

index 1e40fec5c5c6dc3be96b36e5ddc6f7a19f40560e..fb870639d12f00adc0d9d5ef9f59a84f4b8763ab 100644 (file)
@@ -43,8 +43,8 @@ static event_t events[8];
 event_t *dummy_get(cal_t *cal, year_t year, month_t month, day_t day, int days)
 {
        for (int i = 0; i < N_ELEMENTS(events); i++) {
-               datetime_t *s = &events[i].start;
-               datetime_t *e = &events[i].end;
+               date_t *s = &events[i].start;
+               date_t *e = &events[i].end;
                events[i] = event;
                add_days(&s->year, &s->month, &s->day, 7*i);
                add_days(&e->year, &e->month, &e->day, 7*i);
index f4709a93d16dbdbdd94c274c84c4a173d4fb7d4d..23844a335bcac64e1483c04abb966747431665d9 100644 (file)
 #include "date.h"
 #include "event.h"
 
+/* Local types */
+typedef struct {
+       icalcomponent *comp;
+       struct icaltimetype start;
+       struct icaltimetype end;
+} ical_inst;
+
 /* Helper functions */
-static event_t *to_event(icalcomponent *comp)
+static int ical_compare(const void *_a, const void *_b)
+{
+       const ical_inst *a = _a;
+       const ical_inst *b = _b;
+       int scomp = icaltime_compare(a->start, b->start);
+       int ecomp = icaltime_compare(a->end,   b->end);
+       return scomp != 0 ? scomp :
+              ecomp != 0 ? ecomp : 0 ;
+}
+
+static date_t to_date(struct icaltimetype time)
+{
+       return (date_t){
+               .year  = time.year,
+               .month = time.month-1,
+               .day   = time.day-1,
+               .hour  = time.hour,
+               .min   = time.minute,
+       };
+}
+
+static event_t *to_event(ical_inst *inst)
 {
-       event_t *event = calloc(1, sizeof(event));
+       event_t *event = calloc(1, sizeof(event_t));
+       event->name  = icalcomponent_get_summary(inst->comp);
+       event->desc  = icalcomponent_get_description(inst->comp);
+       event->start = to_date(inst->start);
+       event->end   = to_date(inst->end);
        return event;
 }
 
+static event_t *to_list(icalarray *array)
+{
+       event_t  list = {};
+       event_t *tail = &list;
+       for (int i = 0; i < array->num_elements; i++) {
+                ical_inst *inst = icalarray_element_at(array, i);
+                tail->next = to_event(inst);
+                tail = tail->next;
+       }
+       return list.next;
+}
+
+static void print_list(event_t *start)
+{
+       for (event_t *cur = start; cur; cur = cur->next)
+               printf("%04d-%02d-%02d %02d:%02d - %s\n",
+                       cur->start.year, cur->start.month, cur->start.day,
+                       cur->start.hour, cur->start.min,
+                       cur->name ?: cur->desc ?: "[no summary]");
+}
+
+static void add_events(icalarray *array, icalcomponent *comp,
+               icaltimetype start, icaltimetype end)
+{
+       icalcomponent_kind kind = icalcomponent_isa(comp);
+
+       if (kind == ICAL_VEVENT_COMPONENT ||
+           kind == ICAL_VTODO_COMPONENT) {
+               /* Get recurrence data */
+               struct icaltimetype cstart, cend; // Component times
+               struct icaltimetype istart, iend; // Instance times
+               struct icaldurationtype length;   // Duration
+
+               icalproperty             *rrule;
+               struct icalrecurrencetype recur;
+               icalrecur_iterator       *iter;
+
+               cstart = icalcomponent_get_dtstart(comp);
+               cend   = icalcomponent_get_dtend(comp);
+               length = icaltime_subtract(cend, cstart);
+
+               rrule  = icalcomponent_get_first_property(comp, ICAL_RRULE_PROPERTY);
+               recur  = icalproperty_get_rrule(rrule);
+               iter   = icalrecur_iterator_new(recur, cstart);
+
+               /* Add recurrences */
+               while (1) {
+                       istart = icalrecur_iterator_next(iter);
+                       if (icaltime_is_null_time(istart))
+                               break;    // no more instances
+                       iend   = icaltime_add(istart, length);
+                       if (icaltime_compare(iend, start) <= 0)
+                               continue; // instance ends before start time
+                       if (icaltime_compare(istart, end) >= 0)
+                               break;    // instance begins after stop time
+                       icalarray_append(array, &(ical_inst){
+                               .comp  = comp,
+                               .start = istart,
+                               .end   = iend,
+                       });
+               }
+       }
+
+       /* Add children */
+       icalcomponent_kind find = ICAL_ANY_COMPONENT;
+       icalcomponent *child = icalcomponent_get_first_component(comp, find);
+       while (child) {
+               add_events(array, child, start, end);
+               child = icalcomponent_get_next_component(comp, find);
+       }
+}
+
 /* Event functions */
 event_t *ical_get(cal_t *cal, year_t year, month_t month, day_t day, int days)
 {
-       (void)to_event;
-       return NULL;
+       /* Load ical */
+       FILE *file = fopen("data/all.ics", "r");
+       icalparser *parser = icalparser_new();
+       icalparser_set_gen_data(parser, file);
+       icalcomponent *ical = icalparser_parse(parser, (void*)fgets);
+
+       /* Add events */
+       icalarray *array = icalarray_new(sizeof(ical_inst), 1);
+       icaltimetype start = {.year = 2000};
+       icaltimetype end   = {.year = 2020};
+       add_events(array, ical, start, end);
+       icalarray_sort(array, ical_compare);
+       return to_list(array);
+
+       /* Todo, memory management */
 }
 
 /* Test functions */
@@ -60,10 +177,24 @@ void ical_printr(icalcomponent *comp, int depth)
 
 void ical_test(void)
 {
+       /* Load ical */
        FILE *file = fopen("data/all.ics", "r");
        icalparser *parser = icalparser_new();
        icalparser_set_gen_data(parser, file);
        icalcomponent *ical = icalparser_parse(parser, (void*)fgets);
+
+       /* Test print */
        ical_printr(ical, 0);
+
+       /* Test Add */
+       icalarray *array = icalarray_new(sizeof(ical_inst), 1);
+       icaltimetype start = {.year = 2000};
+       icaltimetype end   = {.year = 2020};
+       add_events(array, ical, start, end);
+       icalarray_sort(array, ical_compare);
+       event_t *events = to_list(array);
+       print_list(events);
+
+       /* Cleanup */
        icalparser_free(parser);
 }
index ec71579d359380fe9054ad2dbfba6811437b6661..965f15a4a6c4e8a4e8e3481e2828bc1e25f7eab4 100644 (file)
@@ -36,6 +36,11 @@ void date_init(void)
        YEAR  = tm->tm_year+1900;
        MONTH = tm->tm_mon;
        DAY   = tm->tm_mday-1;
+
+       // Testing */
+       YEAR  = 2009;
+       MONTH = MAY;
+       DAY   = 1;
 }
 
 /* Time functions */
index 76d33cef4f6d174a753b86a2e0f8df581edf6a3f..e4dfe798fcb089acb24645bedab878b4f73ec0be 100644 (file)
@@ -37,5 +37,6 @@ void event_init(void)
 /* Event get */
 event_t *event_get(year_t year, month_t month, day_t day, int days)
 {
-       return dummy_get(0, year, month, day, days);
+       //return dummy_get(0, year, month, day, days);
+       return ical_get(0, year, month, day, days);
 }
index b75f890f43a86633d29c7745e64f41a4fe221d6a..43e50b27869ae6d0d2a9ed478d9cd3445678a65d 100644 (file)
@@ -29,14 +29,14 @@ typedef struct {
        day_t   day;
        hour_t  hour;
        min_t   min;
-} datetime_t;
+} date_t;
 
 typedef struct event_t {
        const cal_t    *cal;
-       datetime_t      start;
-       datetime_t      end;
        const char     *name;
        const char     *desc;
+       date_t          start;
+       date_t          end;
        struct event_t *next;
 } event_t;
 
index 230a7c58778f9eb94f51bdd93420a0c3e9d712b4..9f8419db1dfefe43d86596f18cc48a79857ee2e2 100644 (file)
@@ -37,7 +37,7 @@ static void print_event(event_t *event, wday_t day, hour_t hour, min_t min, floa
        (void)l;
 }
 
-static int before(datetime_t *start, int year, int month, int day, int hour, int min)
+static int before(date_t *start, int year, int month, int day, int hour, int min)
 {
        int rval = start->year  < year  ? 1 : start->year  > year ? 0 :
                   start->month < month ? 1 : start->month > month? 0 :