]> www.infradead.org Git - users/dwmw2/ews-sync.git/commitdiff
Attempt to process timezones using ical
authorDavid Woodhouse <dwmw2@infradead.org>
Sun, 18 Jul 2010 12:55:51 +0000 (13:55 +0100)
committerDavid Woodhouse <dwmw2@infradead.org>
Sun, 18 Jul 2010 12:55:51 +0000 (13:55 +0100)
Makefile
ews2ical.c

index ffab257c13f01544f81839b0617a479c9d0ebd93..b5f712075b11463fc565c9f6e50d8ce663c3526a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -17,8 +17,15 @@ ifeq ($(SOUP_LDFLAGS),)
 $(error "No libsoup support. Cannot continue");
 endif
 
+ICAL_CFLAGS += $(shell pkg-config libical --cflags)
+ICAL_LDFLAGS += $(shell pkg-config libical --libs)
+ifeq ($(ICAL_LDFLAGS),)
+$(error "No libical support. Cannot continue");
+endif
+
 CFLAGS := $(OPT_FLAGS) $(XML2_CFLAGS)
 CFLAGS_ews_autodiscover.o := $(SOUP_CFLAGS)
+CFLAGS_ews2ical.o := $(ICAL_CFLAGS)
 
 %.o: %.c
        $(CC) -c -o $@ $(CFLAGS) $(CFLAGS_$@) $< -MD -MF .$@.dep
@@ -26,7 +33,7 @@ CFLAGS_ews_autodiscover.o := $(SOUP_CFLAGS)
 all: ews_autodiscover ews2ical
 
 ews2ical: ews2ical.o
-       $(CC) -o $@ $< $(LDFLAGS) $(XML2_LDFLAGS)
+       $(CC) -o $@ $< $(LDFLAGS) $(XML2_LDFLAGS) $(ICAL_LDFLAGS)
 
 ews_autodiscover: ews_autodiscover.o
        $(CC) -o $@ $< $(LDFLAGS) $(XML2_LDFLAGS) $(SOUP_LDFLAGS)
index 5688112c7e420820501714cff28534681c0e3a5f..42417285369fcdf746cf1f175bc330a19da09b5e 100644 (file)
@@ -9,26 +9,27 @@
 #include <string.h>
 #include <ctype.h>
 #include <time.h>
-
+#include <libical/icaltime.h>
+#include <libical/icaltimezone.h>
 FILE *calfile;
 
 
 int process_organizer(xmlNode *xml_node);
 int process_required_attendees(xmlNode *xml_node);
-int process_start(xmlNode *xml_node, const char *zone);
-int process_end(xmlNode *xml_node, const char *zone);
+int process_start(xmlNode *xml_node, icaltimezone *zone);
+int process_end(xmlNode *xml_node, icaltimezone *zone);
 int process_location(xmlNode *xml_node);
 int process_body(xmlNode *xml_node);
 int process_subject(xmlNode *xml_node);
 int process_recurrence(xmlNode *xml_node);
 int process_itemid(xmlNode *xmlnode);
-const char *set_timezone(xmlNode *xmlnode);
+icaltimezone *get_timezone(xmlNode *xmlnode);
 
 int main(int argc, char **argv)
 {
        xmlDocPtr xml_doc;
        xmlNode *xml_node;
-       const char *tzname;
+       icaltimezone *icaltz;
        int xmlfd = 0; /* stdin */
        char buf[1];
 
@@ -127,9 +128,15 @@ int main(int argc, char **argv)
        fprintf(calfile, "BEGIN:VCALENDAR\n");
        fprintf(calfile, "METHOD:PUBLISH\n");
        fprintf(calfile, "VERSION:2.0\n");
-       fprintf(calfile, "BEGIN:VEVENT\n");
 
-       tzname = set_timezone(xml_node);
+       icaltz = get_timezone(xml_node);
+       if (icaltz) {
+               icalcomponent *comp = icaltimezone_get_component(icaltz);
+               char *vtz = icalcomponent_as_ical_string_r(comp);
+               printf("%s", vtz);
+               free(vtz);
+       }
+       fprintf(calfile, "BEGIN:VEVENT\n");
 
        for (xml_node = xml_node->children; xml_node; xml_node = xml_node->next) {
                if (xml_node->type != XML_ELEMENT_NODE)
@@ -139,9 +146,9 @@ int main(int argc, char **argv)
                else if (!strcmp((char *)xml_node->name, "RequiredAttendees"))
                        process_required_attendees(xml_node);
                else if (!strcmp((char *)xml_node->name, "Start"))
-                       process_start(xml_node, tzname);
+                       process_start(xml_node, icaltz);
                else if (!strcmp((char *)xml_node->name, "End"))
-                       process_end(xml_node, tzname);
+                       process_end(xml_node, icaltz);
                else if (!strcmp((char *)xml_node->name, "Body"))
                        process_body(xml_node);
                else if (!strcmp((char *)xml_node->name, "Location"))
@@ -232,9 +239,10 @@ int process_required_attendees(xmlNode *xml_node)
        return 0;
 }
 
-int process_time(xmlNode *xml_node, const char *name, const char *zone)
+int process_time(xmlNode *xml_node, const char *name, icaltimezone *zone)
 {
        char *ews_time = (char *)xmlNodeGetContent(xml_node);
+       struct icaltimetype ical_time;
        struct tm tm_time;
        time_t t;
 
@@ -250,38 +258,33 @@ int process_time(xmlNode *xml_node, const char *name, const char *zone)
 
        memset(&tm_time, 0, sizeof(tm_time));
        tm_time.tm_year = strtol(ews_time, NULL, 10);
-       tm_time.tm_mon  = strtol(ews_time + 5, NULL, 10);
+       tm_time.tm_mon  = strtol(ews_time + 5, NULL, 10) - 1;
        tm_time.tm_mday = strtol(ews_time + 8, NULL, 10);
        tm_time.tm_hour = strtol(ews_time + 11, NULL, 10);
        tm_time.tm_min = strtol(ews_time + 14, NULL, 10);
        tm_time.tm_sec = strtol(ews_time + 17, NULL, 10);
 
        t = timegm(&tm_time);
-
-       /* Now we have a number of seconds since epoch in UTC; convert
-          to the time zone we're using. Would be nice if there was a
-          sane way to do this which didn't involve setting $TZ for the
-          whole application -- we'll care about that when we're a plugin
-          for something else rather than running standalone. */
-
-       localtime_r(&t, &tm_time);
+       ical_time = icaltime_from_timet_with_zone(t, 0, zone?:icaltimezone_get_utc_timezone());
+       ical_time.year -= 1900;
 
        fprintf(calfile, "%s", name);
+
        if (zone)
-               fprintf(calfile, ";TZID=%s", zone);
+               fprintf(calfile, ";TZID=%s", icaltimezone_get_tzid(zone));
        fprintf(calfile, ":%04d%02d%02d%02d%02d%02d%s\n",
-               tm_time.tm_year, tm_time.tm_mon, tm_time.tm_mday,
-               tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec,
+               ical_time.year, ical_time.month, ical_time.day,
+               ical_time.hour, ical_time.minute, ical_time.second,
                zone?"":"Z");
        return 0;
 }
 
-int process_start(xmlNode *xml_node, const char *zone)
+int process_start(xmlNode *xml_node, icaltimezone *zone)
 {
        return process_time(xml_node, "DTSTART", zone);
 }
 
-int process_end(xmlNode *xml_node, const char *zone)
+int process_end(xmlNode *xml_node, icaltimezone *zone)
 {
        return process_time(xml_node, "DTEND", zone);
 }
@@ -659,6 +662,10 @@ static const char *ews_tz_to_ical(const char *ewstz)
                { "(UTC-10:00) Hawaii", "Pacific/Honolulu" },
                { "(UTC-11:00) Midway Island, Samoa", "Pacific/Midway" },
        /* ? */ { "(UTC-12:00) International Date Line West", "Pacific/Apia" },
+
+
+
+//             { "Pacific Standard Time", "America/Los_Angeles" },
        };
        int i;
        int offset = 0;
@@ -680,23 +687,37 @@ static const char *ews_tz_to_ical(const char *ewstz)
        
 }
 
-const char *set_timezone(xmlNode *xml_node)
+icaltimezone *get_timezone(xmlNode *xml_node)
 {
+       icaltimezone *zone = NULL;
+       const char *ews_tzname = NULL;
        const char *tzname = NULL;
-#if 0
+
        for (xml_node = xml_node->children; xml_node; xml_node = xml_node->next) {
                if (xml_node->type != XML_ELEMENT_NODE)
                        continue;
                else if (!strcmp((char *)xml_node->name, "TimeZone"))
                        break;
        }
-       if (xml_node)
-               tzname = ews_tz_to_ical((char *)xmlNodeGetContent(xml_node));
-#endif
-       if (tzname)
-               setenv("TZ", tzname, 1);
-       else
-               setenv("TZ", "UTC", 1);
-       tzset();
-       return tzname;
+       if (!xml_node) {
+               fprintf(stderr, "Failed to find TimeZone element; falling back to UTC\n");
+               return NULL;
+       }
+
+       ews_tzname = (char *)xmlNodeGetContent(xml_node);
+
+       /* FIXME: Look for manual timezone definitions in the XML and compare against
+          those first, before using the standard Windows ones */
+
+       tzname = ews_tz_to_ical(ews_tzname);
+       if (!tzname)
+               return NULL;
+
+       zone = icaltimezone_get_builtin_timezone(tzname);
+       if (zone)
+               return zone;
+
+       fprintf(stderr, "Failed to load ical timezone for '%s' (%s)\n", tzname,
+               ews_tzname);
+       return NULL;
 }