]> www.infradead.org Git - users/dwmw2/ews-sync.git/commitdiff
Not entirely sober attempt at relative monthly/annual recurrence
authorDavid Woodhouse <dwmw2@infradead.org>
Sat, 17 Jul 2010 21:15:50 +0000 (22:15 +0100)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Sat, 17 Jul 2010 21:16:12 +0000 (22:16 +0100)
Need to work out how to handle 'Day', 'Weekday', etc.

ews2ical.c

index 980536303d59164e38e785956aa80a379bd0dd14..338b21e3eec932d86cd9d3a9e5745bf9b904f9ed 100644 (file)
@@ -304,19 +304,81 @@ int process_subject(xmlNode *xml_node)
        return 0;
 }
 
-char *months[] = {
-       "January", "February", "March", "April", "May", "June", "July", 
-       "August", "September", "October", "November", "December"
-};
 
+static int month_to_number(const char *month)
+{
+       static char *months[] = {
+               "January", "February", "March", "April", "May", "June", "July", 
+               "August", "September", "October", "November", "December"
+       };
+       int monthnr;
+       for (monthnr = 0; monthnr < 12; monthnr++) {
+               if (!strcmp(month, months[monthnr]))
+                       return monthnr + 1;
+       }
+
+       fprintf(stderr, "Unrecognised month name '%s'\n", month);
+       return 0;
+}
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+static const char *weekday_to_ical(const char *weekday)
+{
+       static struct {
+               const char *exch;
+               const char *ical;
+       } table[] = {
+               { "Sunday", "SO" },
+               { "Monday", "MO" },
+               { "Tuesday", "TU" },
+               { "Wednesday", "WE" },
+               { "Thursday", "TH" },
+               { "Friday", "FR" },
+               { "Day", "SU,MO,TU,WE,TH,FR,SA" },
+               { "Weekday", "MO,TU,WE,TH,FR" },
+               { "WeekendDay", "SA,SU" },
+       };
+       int i;
+
+       for (i=0 ; i < ARRAY_SIZE(table); i++) {
+               if (!strcmp(weekday, table[i].exch))
+                       return table[i].ical;
+       }
+       fprintf(stderr, "Unrecognised DaysOfWeek '%s'\n", weekday);
+       return NULL;
+}
+
+static int weekindex_to_ical(const char *week)
+{
+       static struct {
+               char *exch;
+               int week;
+       } table[] = {
+               { "First", 1 },
+               { "Second", 2 },
+               { "Third", 3 },
+               { "Fourth", 4 },
+               { "Last", -1 }
+       };
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(table); i++) {
+               if (!strcmp(week, table[i].exch))
+                       return table[i].week;
+       }
+       fprintf(stderr, "Unrecognised DayOfWeekIndex '%s'\n", week);
+       return 0;
+}      
+               
 int process_recurrence(xmlNode *xml_node)
 {
        xmlNode *xml_node2;
        const char *weekly_interval = NULL;
        const char *weekday = NULL;
        const char *daily_interval = NULL;
+       const char *monthly_interval = NULL;
        const char *day_of_month = NULL;
        const char *month = NULL;
+       const char *week_index = NULL;
        const char *end_date = NULL;
        const char *nr_recurrences = NULL;
 
@@ -352,11 +414,41 @@ int process_recurrence(xmlNode *xml_node)
                                        month = (char *)xmlNodeGetContent(xml_node2);
                        }
                } else if (!strcmp((char *)xml_node->name, "RelativeYearlyRecurrence")) {
-                       fprintf(stderr, "Cannot yet handle %s\n", xml_node->name);
+                       for (xml_node2 = xml_node->children; xml_node2;
+                            xml_node2 = xml_node2->next) {
+                               if (xml_node2->type != XML_ELEMENT_NODE)
+                                       continue;
+                               if (!strcmp((char *)xml_node2->name, "DaysOfWeek"))
+                                       weekday = (char *)xmlNodeGetContent(xml_node2);
+                               else if (!strcmp((char *)xml_node2->name, "Interval"))
+                                       monthly_interval = (char *)xmlNodeGetContent(xml_node2);
+                               else if (!strcmp((char *)xml_node2->name, "DayOfWeekIndex"))
+                                       week_index = (char *)xmlNodeGetContent(xml_node2);
+                       }
                } else if (!strcmp((char *)xml_node->name, "AbsoluteMonthlyRecurrence")) {
-                       fprintf(stderr, "Cannot yet handle %s\n", xml_node->name);
+                       for (xml_node2 = xml_node->children; xml_node2;
+                            xml_node2 = xml_node2->next) {
+                               if (xml_node2->type != XML_ELEMENT_NODE)
+                                       continue;
+                               if (!strcmp((char *)xml_node2->name, "DayOfMonth"))
+                                       day_of_month = (char *)xmlNodeGetContent(xml_node2);
+                               else if (!strcmp((char *)xml_node2->name, "DayOfWeekIndex"))
+                                       week_index = (char *)xmlNodeGetContent(xml_node2);
+                               else if (!strcmp((char *)xml_node2->name, "Month"))
+                                       month = (char *)xmlNodeGetContent(xml_node2);
+                       }
                } else if (!strcmp((char *)xml_node->name, "RelativeMonthlyRecurrence")) {
-                       fprintf(stderr, "Cannot yet handle %s\n", xml_node->name);
+                       for (xml_node2 = xml_node->children; xml_node2;
+                            xml_node2 = xml_node2->next) {
+                               if (xml_node2->type != XML_ELEMENT_NODE)
+                                       continue;
+                               if (!strcmp((char *)xml_node2->name, "DaysOfWeek"))
+                                       weekday = (char *)xmlNodeGetContent(xml_node2);
+                               else if (!strcmp((char *)xml_node2->name, "Interval"))
+                                       monthly_interval = (char *)xmlNodeGetContent(xml_node2);
+                               else if (!strcmp((char *)xml_node2->name, "DayOfWeekIndex"))
+                                       week_index = (char *)xmlNodeGetContent(xml_node2);
+                       }
                } else if (!strcmp((char *)xml_node->name, "EndDateRecurrence")) {
                        for (xml_node2 = xml_node->children; xml_node2;
                             xml_node2 = xml_node2->next) {
@@ -377,17 +469,32 @@ int process_recurrence(xmlNode *xml_node)
        }
        if (daily_interval) {
                fprintf(calfile, "RRULE:FREQ=DAILY;INTERVAL=%s", daily_interval);
+       } else if (weekday && month && week_index) {
+               int monthnr = month_to_number(month);
+               int week = weekindex_to_ical(week_index);
+               const char *weekday_ical = weekday_to_ical(weekday);
+               if (!monthnr || !week || !weekday_ical)
+                       return -1;
+
+               fprintf(calfile, "RRULE:FREQ=YEARLY;MONTH=%d;BYDAY=%d%s",
+                       monthnr, week, weekday_ical);
+               /* Relative Yearly */
+       } else if (monthly_interval && weekday && week_index) {
+               int week = weekindex_to_ical(week_index);
+               const char *weekday_ical = weekday_to_ical(weekday);
+               if (!week || !weekday_ical)
+                       return -1;
+               fprintf(calfile, "RRULE:FREQ=MONTHLY;INTERVAL=%s;BYDAY=%d%s",
+                       monthly_interval, week, weekday_ical);
        } else if (day_of_month && month) {
-               int monthnr;
-               for (monthnr = 0; monthnr < 12; monthnr++)
-                       if (!strcmp(month, months[monthnr]))
-                               break;
-               if (monthnr == 12) {
-                       fprintf(stderr, "Unrecognised month name '%s'\n", month);
+               int monthnr = month_to_number(month);
+               if (!monthnr)
                        return -1;
-               }
                fprintf(calfile, "RRULE:FREQ=YEARLY;BYMONTH=%d;BYMONTHDAY=%s",
-                       monthnr+1, day_of_month);
+                       monthnr, day_of_month);
+       } else if (monthly_interval && day_of_month) {
+               fprintf(calfile, "RRULE:FREQ=MONTHLY;INTERVAL=%s;BYMONTHDAY=%s",
+                       monthly_interval, day_of_month);
        } else if (weekly_interval && weekday) {
                char day[3];
                day[0] = toupper(weekday[0]);