diff --git a/src/planner.c b/src/planner.c index 655bd4c..209c087 100644 --- a/src/planner.c +++ b/src/planner.c @@ -31,6 +31,7 @@ void llistPrintT(llist *head) { c = c->next; } } +int exportiCal(llist *ev_ll); // print Event to stdout void printEvent(Event *s) { char st[26]; @@ -254,8 +255,117 @@ llist *genPlan(llist *head, time_t timeAvail) { planLog("END GEN PLAN", 0); + exportiCal(events_ll); // llistFreeT(head); // send updated tasks to db for storage return events_ll; } + +const char *iCalHeader = "BEGIN:VCALENDAR\r\n" + "VERSION:2.0\r\n" + "PRODID:-//hacksw/handcal//NONSGML v1.0//EN\r\n"; +const char *iCalEvent = "BEGIN:VEVENT\r\n" + "UID:%s%d\r\n" + "DTSTAMP:%s\r\n" + "DTSTART:%s\r\n" + "DTEND:%s\r\n" + "SUMMARY:%s\r\n" + "END:VEVENT\r\n"; + +const char *iCalFileExtension = "ics"; + +/* + * + * + *The body of the iCalendar object (the icalbody) contains single-line Calendar + * Properties that apply to the entire calendar, as well as one or more blocks + * of multiple lines that each define a Calendar Component such as an event, + * journal entry, alarm, or one of several other types. Here is a simple example + * of an iCalendar object with a single calendar containing a single Calendar + * Component, a "Bastille Day Party" event starting at 5pm on July 14, 1997, and + * ending at 4am the following morning:[10] + + + +BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//hacksw/handcal//NONSGML v1.0//EN +BEGIN:VEVENT +UID:uid1@example.com +ORGANIZER;CN=John Doe:MAILTO:john.doe@example.com +DTSTART:19970714T170000Z +DTEND:19970715T040000Z +SUMMARY:Bastille Day Party +GEO:48.85299;2.36885 +END:VEVENT +END:VCALENDAR + + +The UID field distributes updates when a scheduled event changes. When the event +is first generated a globally unique identifier is created. If a later event is +distributed with the same UID, it replaces the original one. An example UID +might be Y2007S2C131M5@example.edu, for the 5th meeting of class 131 in semester +2 at a hypothetical college. Email-style UIDs are now considered bad practice, +with a UUID recommended instead.[11] + +The most common representation of date and time is a tz timestamp such as +20010911T124640Z with the format TZ for a total fixed length of 16 characters. Z +indicates the use of UTC (referring to its Zulu time zone).[12] When used in +DTSTART and DTEND properties, start times are inclusive while end times are not. +This allows an event's end time to be the same as a consecutive event's start +without those events overlapping and potentially creating (false) scheduling +conflicts.[13] + + + */ + +int exportiCal(llist *events_ll) { + + llist *ev_ll = events_ll; + + printf("%s", iCalHeader); + + time_t now = time(NULL); + struct tm *lc = localtime(&now); + + // gen filename & open for write + char nameBuf[32]; + strftime(nameBuf, 32 - 12, "%F", lc); + strcat(nameBuf, "dayplan.ics"); + FILE *fp = fopen(nameBuf, "w"); + if (fp == NULL) { + planLog("fopen failed!!", 1); + return 1; + } + // write iCal header to file + fprintf(fp, "%s", iCalHeader); + + // for every event in events_ll create VEVENT str and write to fp + int count = 0; + while (ev_ll != NULL) { + // gen iCal compatible time str + Event *current = ev_ll->data; + struct tm *startlc = localtime(¤t->plannedStartTime); + struct tm *endlc = localtime(¤t->plannedEndTime); + char timeStartBuf[17]; + char timeEndBuf[17]; + char timeStamp[17]; + strftime(timeStamp, 17, "%Y%m%dT%k%M%SZ", lc); + strftime(timeStartBuf, 17, "%Y%m%dT%k%M%SZ", startlc); + strftime(timeEndBuf, 17, "%Y%m%dT%k%M%SZ", endlc); + + fprintf(fp, iCalEvent, current->task->name, count, timeStamp, timeStartBuf, + timeEndBuf, current->task->name); + ev_ll = ev_ll->next; + count += 1; + } + + // after all events are written end cal with + // END:VCALENDAR + fprintf(fp, "END:VCALENDAR\r\n"); + fclose(fp); + + return 0; +} diff --git a/src/test.c b/src/test.c index b2fde59..09d66a2 100644 --- a/src/test.c +++ b/src/test.c @@ -39,7 +39,7 @@ int main() { // gnerate plan from task list in time struct tm *lc = localtime(&now); - lc->tm_hour += 4; // add available time; + lc->tm_hour += 7; // add available time; time_t maxTime = mktime(lc); // create timestamp llist *l1 = genPlan(list1, maxTime); // return inked list of event; llistPrintE(l1);