Readloop remove special cases
[citadel.git] / webcit / calendar.c
index 9211b2bc05609d121740f44aaf1164ceb50ea1a9..2897ba20188d9a007eeb1623af1fee2709f5e3e7 100644 (file)
@@ -1,14 +1,12 @@
 /*
- * $Id$
- *
  * Functions which handle calendar objects and their processing/display.
  *
- * Copyright (c) 1996-2010 by the citadel.org team
+ * Copyright (c) 1996-2011 by the citadel.org team
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
+ * This program is open source software.  You can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -17,7 +15,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #include "webcit.h"
@@ -50,6 +48,7 @@ void cal_process_object(StrBuf *Target,
        int is_update = 0;
        char divname[32];
        static int divcount = 0;
+       const char *ch;
 
        sprintf(divname, "rsvp%04x", ++divcount);
 
@@ -76,7 +75,7 @@ void cal_process_object(StrBuf *Target,
                the_method = icalproperty_get_method(method);
 
                StrBufAppendPrintf(Target, "<div id=\"%s_title\">", divname);
-               StrBufAppendPrintf(Target, "<img src=\"static/calarea_48x.gif\">");
+               StrBufAppendPrintf(Target, "<img src=\"static/webcit_icons/essen/32x32/calendar.png\">");
                StrBufAppendPrintf(Target, "<span>");
                switch(the_method) {
                case ICAL_METHOD_REQUEST:
@@ -184,11 +183,11 @@ void cal_process_object(StrBuf *Target,
                StrBufAppendPrintf(Target, "<dt>");
                StrBufAppendPrintf(Target, _("Attendee:"));
                StrBufAppendPrintf(Target, "</dt><dd>");
-               safestrncpy(buf, icalproperty_get_attendee(p), sizeof buf);
-               if (!strncasecmp(buf, "MAILTO:", 7)) {
+               ch = icalproperty_get_attendee(p);
+               if ((ch != NULL) && !strncasecmp(buf, "MAILTO:", 7)) {
 
                        /** screen name or email address */
-                       strcpy(buf, &buf[7]);
+                       safestrncpy(buf, ch + 7, sizeof(buf));
                        striplt(buf);
                        StrEscAppend(Target, NULL, buf, 0, 0);
                        StrBufAppendPrintf(Target, " ");
@@ -212,7 +211,7 @@ void cal_process_object(StrBuf *Target,
        if (the_method == ICAL_METHOD_REQUEST) {
 
                /* Check for conflicts */
-               lprintf(9, "Checking server calendar for conflicts...\n");
+               syslog(9, "Checking server calendar for conflicts...\n");
                serv_printf("ICAL conflicts|%ld|%s|", msgnum, cal_partnum);
                serv_getln(buf, sizeof buf);
                if (buf[0] == '1') {
@@ -240,7 +239,7 @@ void cal_process_object(StrBuf *Target,
                                StrBufAppendPrintf(Target, "</dd>\n");
                        }
                }
-               lprintf(9, "...done.\n");
+               syslog(9, "...done.\n");
 
                StrBufAppendPrintf(Target, "</dl>");
 
@@ -300,7 +299,7 @@ void cal_process_attachment(wc_mime_attachment *Mime)
        FlushStrBuf(Mime->Data);
        if (cal == NULL) {
                StrBufAppendPrintf(Mime->Data, _("There was an error parsing this calendar item."));
-               StrBufAppendPrintf(Mime->Data, "<br />\n");
+               StrBufAppendPrintf(Mime->Data, "<br>\n");
                return;
        }
 
@@ -330,7 +329,7 @@ void respond_to_request(void)
        serv_getln(buf, sizeof buf);
 
        if (buf[0] == '2') {
-               wc_printf("<img src=\"static/calarea_48x.gif\"><span>");
+               wc_printf("<img src=\"static/webcit_icons/essen/32x32/calendar.png\"><span>");
                if (!strcasecmp(bstr("sc"), "accept")) {
                        wc_printf(_("You have accepted this meeting invitation.  "
                                "It has been entered into your calendar.")
@@ -348,7 +347,7 @@ void respond_to_request(void)
                wc_printf(_("A reply has been sent to the meeting organizer."));
                wc_printf("</span>");
        } else {
-               wc_printf("<img align=\"center\" src=\"static/error.gif\"><span>");
+               wc_printf("<img align=\"center\" src=\"static/webcit_icons/error.gif\"><span>");
                wc_printf("%s\n", &buf[4]);
                wc_printf("</span>");
        }
@@ -375,8 +374,11 @@ void handle_rsvp(void)
        serv_getln(buf, sizeof buf);
 
        if (buf[0] == '2') {
-               wc_printf("<img src=\"static/calarea_48x.gif\"><span>");
+               wc_printf("<img src=\"static/webcit_icons/calendar.png\"><span>");
                if (!strcasecmp(bstr("sc"), "update")) {
+                       /* Translators: RSVP aka Répondez s'il-vous-plaît Is the term 
+                          that the recipient of an ical-invitation should please 
+                          answer this request. */                                        
                        wc_printf(_("Your calendar has been updated to reflect this RSVP."));
                } else if (!strcasecmp(bstr("sc"), "ignore")) {
                        wc_printf(_("You have chosen to ignore this RSVP. "
@@ -385,7 +387,7 @@ void handle_rsvp(void)
                }
                wc_printf("</span>");
        } else {
-               wc_printf("<img src=\"static/error.gif\"><span> %s\n", &buf[4]);
+               wc_printf("<img src=\"static/webcit_icons/error.gif\"><span> %s\n", &buf[4]);
                wc_printf("</span>");
        }
 
@@ -412,7 +414,7 @@ void delete_cal(void *vCal)
  * any iCalendar objects and store them in a hash table.  Later on, the second phase will
  * use this hash table to render the calendar for display.
  */
-void display_individual_cal(icalcomponent *cal, long msgnum, char *from, int unread, calview *calv)
+void display_individual_cal(icalcomponent *event, long msgnum, char *from, int unread, calview *calv)
 {
        icalproperty *ps = NULL;
        struct icaltimetype dtstart, dtend;
@@ -431,22 +433,29 @@ void display_individual_cal(icalcomponent *cal, long msgnum, char *from, int unr
        int num_recur = 0;
        int stop_rr = 0;
 
+       /* first and foremost, check for bogosity.  bail if we see no DTSTART property */
+
+       if (icalcomponent_get_first_property(icalcomponent_get_first_component(
+               event, ICAL_VEVENT_COMPONENT), ICAL_DTSTART_PROPERTY) == NULL)
+       {
+               return;
+       }
+
+       /* ok, chances are we've got a live one here.  let's try to figure out where it goes. */
+
        dtstart = icaltime_null_time();
        dtend = icaltime_null_time();
        
-       if (WCC->disp_cal_items == NULL)
+       if (WCC->disp_cal_items == NULL) {
                WCC->disp_cal_items = NewHash(0, Flathash);
+       }
 
        /* Note: anything we do here, we also have to do below for the recurrences. */
        Cal = (disp_cal*) malloc(sizeof(disp_cal));
        memset(Cal, 0, sizeof(disp_cal));
-       Cal->cal = icalcomponent_new_clone(cal);
+       Cal->cal = icalcomponent_new_clone(event);
 
        /* Dezonify and decapsulate at the very last moment */
-       /* lprintf(9, "INITIAL: %s\n", icaltime_as_ical_string(icalproperty_get_dtstart(
-               icalcomponent_get_first_property(icalcomponent_get_first_component(
-               Cal->cal, ICAL_VEVENT_COMPONENT), ICAL_DTSTART_PROPERTY)))
-       ); */
        ical_dezonify(Cal->cal);
        if (icalcomponent_isa(Cal->cal) != ICAL_VEVENT_COMPONENT) {
                cptr = icalcomponent_get_first_component(Cal->cal, ICAL_VEVENT_COMPONENT);
@@ -481,6 +490,7 @@ void display_individual_cal(icalcomponent *cal, long msgnum, char *from, int unr
        }
 
        /* Store it in the hash list. */
+       /* syslog(LOG_DEBUG, "INITIAL: %s", ctime(&Cal->event_start)); */
        Put(WCC->disp_cal_items, 
            (char*) &Cal->event_start,
            sizeof(Cal->event_start), 
@@ -500,7 +510,7 @@ void display_individual_cal(icalcomponent *cal, long msgnum, char *from, int unr
         * adding new hash entries that all point back to the same msgnum, until either the iteration
         * stops or some outer bound is reached.  The display code will automatically do the Right Thing.
         */
-       cptr = cal;
+       cptr = event;
        if (icalcomponent_isa(cptr) != ICAL_VEVENT_COMPONENT) {
                cptr = icalcomponent_get_first_component(cptr, ICAL_VEVENT_COMPONENT);
        }
@@ -518,12 +528,11 @@ void display_individual_cal(icalcomponent *cal, long msgnum, char *from, int unr
                ++num_recur;
                if (num_recur > 1) {            /* Skip the first one.  We already did it at the root. */
                        icalcomponent *cptr;
-                       /* lprintf(9, "REPEATS: %s\n", icaltime_as_ical_string(next)); */
 
                        /* Note: anything we do here, we also have to do above for the root event. */
                        Cal = (disp_cal*) malloc(sizeof(disp_cal));
                        memset(Cal, 0, sizeof(disp_cal));
-                       Cal->cal = icalcomponent_new_clone(cal);
+                       Cal->cal = icalcomponent_new_clone(event);
                        Cal->unread = unread;
                        len = strlen(from);
                        Cal->from = (char*)malloc(len+ 1);
@@ -537,27 +546,31 @@ void display_individual_cal(icalcomponent *cal, long msgnum, char *from, int unr
                                cptr = icalcomponent_get_first_component(Cal->cal, ICAL_VEVENT_COMPONENT);
                        }
                        if (cptr) {
-                               ps = icalcomponent_get_first_property(cptr, ICAL_DTSTART_PROPERTY);
-                               if (ps != NULL) {
+
+                               /* Remove any existing DTSTART properties */
+                               while ( ps = icalcomponent_get_first_property(cptr, ICAL_DTSTART_PROPERTY),
+                                       ps != NULL
+                               ) {
                                        icalcomponent_remove_property(cptr, ps);
-                                       ps = icalproperty_new_dtstart(next);
-                                       icalcomponent_add_property(cptr, ps);
-       
-                                       Cal->event_start = icaltime_as_timet(next);
-                                       final_recurrence = Cal->event_start;
                                }
 
-                               ps = icalcomponent_get_first_property(cptr, ICAL_DTEND_PROPERTY);
-                               if (ps != NULL) {
+                               /* Add our shiny new DTSTART property from the iteration */
+                               ps = icalproperty_new_dtstart(next);
+                               icalcomponent_add_property(cptr, ps);
+                               Cal->event_start = icaltime_as_timet(next);
+                               final_recurrence = Cal->event_start;
+
+                               /* Remove any existing DTEND properties */
+                               while ( ps = icalcomponent_get_first_property(cptr, ICAL_DTEND_PROPERTY),
+                                       (ps != NULL)
+                               ) {
                                        icalcomponent_remove_property(cptr, ps);
-       
-                                       /* Make a new dtend */
-                                       ps = icalproperty_new_dtend(icaltime_add(next, dur));
-               
-                                       /* and stick it somewhere */
-                                       icalcomponent_add_property(cptr, ps);
                                }
 
+                               /* Add our shiny new DTEND property from the iteration */
+                               ps = icalproperty_new_dtend(icaltime_add(next, dur));
+                               icalcomponent_add_property(cptr, ps);
+
                        }
 
                        /* Dezonify and decapsulate at the very last moment */
@@ -571,8 +584,10 @@ void display_individual_cal(icalcomponent *cal, long msgnum, char *from, int unr
                                }
                        }
 
-                       if ( (Cal->event_start > calv->lower_bound)
-                          && (Cal->event_start < calv->upper_bound) ) {
+                       if (    (Cal->event_start > calv->lower_bound)
+                               && (Cal->event_start < calv->upper_bound)
+                       ) {
+                               /* syslog(LOG_DEBUG, "REPEATS: %s", ctime(&Cal->event_start)); */
                                Put(WCC->disp_cal_items, 
                                        (char*) &Cal->event_start,
                                        sizeof(Cal->event_start), 
@@ -589,8 +604,7 @@ void display_individual_cal(icalcomponent *cal, long msgnum, char *from, int unr
                }
        }
        icalrecur_iterator_free(ritr);
-       /* lprintf(9, "Performed %d recurrences; final one is %s", num_recur, ctime(&final_recurrence)); */
-
+       /* syslog(9, "Performed %d recurrences; final one is %s", num_recur, ctime(&final_recurrence)); */
 }
 
 
@@ -659,7 +673,6 @@ void load_ical_object(long msgnum, int unread,
        char mime_filename[256];
        char mime_content_type[256];
        char mime_disposition[256];
-       int mime_length;
        char relevant_partnum[256];
        char *relevant_source = NULL;
        int phase = 0;                          /* 0 = citadel headers, 1 = mime headers, 2 = body */
@@ -689,7 +702,7 @@ void load_ical_object(long msgnum, int unread,
                                extract_token(mime_partnum, &bptr[5], 2, '|', sizeof mime_partnum);
                                extract_token(mime_disposition, &bptr[5], 3, '|', sizeof mime_disposition);
                                extract_token(mime_content_type, &bptr[5], 4, '|', sizeof mime_content_type);
-                               mime_length = extract_int(&bptr[5], 5);
+                               /* do we care? mime_length = */extract_int(&bptr[5], 5);
 
                                if (  (!strcasecmp(mime_content_type, "text/calendar"))
                                      || (!strcasecmp(mime_content_type, "application/ics"))
@@ -848,7 +861,7 @@ void do_freebusy(void)
                who[len-4] = 0;
        }
 
-       lprintf(9, "freebusy requested for <%s>\n", who);
+       syslog(9, "freebusy requested for <%s>\n", who);
        serv_printf("ICAL freebusy|%s", who);
        serv_getln(buf, sizeof buf);
 
@@ -902,6 +915,7 @@ InitModule_CALENDAR
                calendar_GetParamsGetServerCall,
                NULL,
                NULL,
+               NULL,
                calendar_LoadMsgFromServer,
                calendar_RenderView_or_Tail,
                calendar_Cleanup);
@@ -911,6 +925,7 @@ InitModule_CALENDAR
                calendar_GetParamsGetServerCall,
                NULL,
                NULL,
+               NULL,
                calendar_LoadMsgFromServer,
                calendar_RenderView_or_Tail,
                calendar_Cleanup);