libical, expat, and libsieve are now *required*.
[citadel.git] / webcit / calendar.c
index 79cf6d949a1f2af598e5c0999baf0d110761c8ab..bb1166d8babbed331965383e3fbc42dfe8a63526 100644 (file)
@@ -1,68 +1,14 @@
 /*
  * $Id$
+ *
+ * Functions which handle calendar objects and their processing/display.
  */
-/**
- * \defgroup calav Functions which handle calendar objects and their processing/display.
- * \ingroup Calendaring
- */
-/* @{ */
 
 #include "webcit.h"
 #include "webserver.h"
 
-#ifndef WEBCIT_WITH_CALENDAR_SERVICE
-
-/**
- * \brief get around non existing types
- * Handler stubs for builds with no calendar library available
- * \param part_source dummy pointer to the source
- * \param msgnum number of the mesage in the db
- * \param cal_partnum number of the calendar part
- */
-void cal_process_attachment(char *part_source, long msgnum, char *cal_partnum) {
-
-       wprintf(_("<I>This message contains calendaring/scheduling information,"
-               " but support for calendars is not available on this "
-               "particular system.  Please ask your system administrator to "
-               "install a new version of the Citadel web service with "
-               "calendaring enabled.</I><br />\n")
-       );
-
-}
-
-/**
- * \brief say we can't display calendar items
- * \param msgnum number of the mesage in our db
- */
-void display_calendar(long msgnum) {
-       wprintf(_("<i>"
-               "Cannot display calendar item.  You are seeing this error "
-               "because your WebCit service has not been installed with "
-               "calendar support.  Please contact your system administrator."
-               "</i><br />\n"));
-}
-
-/**
- * \brief say we can't display task items
- * \param msgnum number of the mesage in our db
- */
-void display_task(long msgnum) {
-       wprintf(_("<i>"
-               "Cannot display to-do item.  You are seeing this error "
-               "because your WebCit service has not been installed with "
-               "calendar support.  Please contact your system administrator."
-               "</i><br />\n"));
-}
-/** ok, we have calendaring available */
-#else /* WEBCIT_WITH_CALENDAR_SERVICE */
-
-
-/******   End of handler stubs.  Everything below this line is real.   ******/
-
 
-
-
-/**
+/*
  * \brief Process a calendar object
  * ...at this point it's already been deserialized by cal_process_attachment()
  * \param cal the calendar object
@@ -170,7 +116,7 @@ void cal_process_object(icalcomponent *cal,
                        }
                        else {
                                tt = icaltime_as_timet(t);
-                               fmt_date(buf, tt, 0);
+                               webcit_fmt_date(buf, tt, 0);
                                wprintf("<dt>");
                                wprintf(_("Starting date/time:"));
                                wprintf("</dt><dd>%s</dd>", buf);
@@ -181,7 +127,7 @@ void cal_process_object(icalcomponent *cal,
                if (p != NULL) {
                        t = icalproperty_get_dtend(p);
                        tt = icaltime_as_timet(t);
-                       fmt_date(buf, tt, 0);
+                       webcit_fmt_date(buf, tt, 0);
                        wprintf("<dt>");
                        wprintf(_("Ending date/time:"));
                        wprintf("</dt><dd>%s</dd>", buf);
@@ -264,14 +210,15 @@ void cal_process_object(icalcomponent *cal,
                wprintf("</dl>");
 
                /** Display the Accept/Decline buttons */
-               wprintf("<p id=\"%s_question\" class=\"buttons\">"
+               wprintf("<p id=\"%s_question\">"
                        "%s "
+                       "&nbsp;&nbsp;&nbsp;<span class=\"button_link\"> "
                        "<a href=\"javascript:RespondToInvitation('%s_question','%s_title','%ld','%s','Accept');\">%s</a>"
-                       "<span> | </span>"
+                       "</span>&nbsp;&nbsp;&nbsp;<span class=\"button_link\">"
                        "<a href=\"javascript:RespondToInvitation('%s_question','%s_title','%ld','%s','Tentative');\">%s</a>"
-                       "<span> | </span>"
+                       "</span>&nbsp;&nbsp;&nbsp;<span class=\"button_link\">"
                        "<a href=\"javascript:RespondToInvitation('%s_question','%s_title','%ld','%s','Decline');\">%s</a>"
-                       "</p>\n",
+                       "</span></p>\n",
                        divname,
                        _("How would you like to respond to this invitation?"),
                        divname, divname, msgnum, cal_partnum, _("Accept"),
@@ -292,12 +239,13 @@ void cal_process_object(icalcomponent *cal,
                 ***********/
 
                /** Display the update buttons */
-               wprintf("<p id=\"%s_question\" class=\"buttons\">"
-                       "%s"
+               wprintf("<p id=\"%s_question\" >"
+                       "%s "
+                       "&nbsp;&nbsp;&nbsp;<span class=\"button_link\"> "
                        "<a href=\"javascript:HandleRSVP('%s_question','%s_title','%ld','%s','Update');\">%s</a>"
-                       "<span> | </span>"
+                       "</span>&nbsp;&nbsp;&nbsp;<span class=\"button_link\">"
                        "<a href=\"javascript:HandleRSVP('%s_question','%s_title','%ld','%s','Ignore');\">%s</a>"
-                       "</p>\n",
+                       "</span></p>\n",
                        divname,
                        _("Click <i>Update</i> to accept this reply and update your calendar."),
                        divname, divname, msgnum, cal_partnum, _("Update"),
@@ -444,71 +392,18 @@ void handle_rsvp(void) {
  * \param cal Our calendar to process
  * \param msgnum number of the mesage in our db
  */
-void display_individual_cal(icalcomponent *cal, long msgnum
+void display_individual_cal(icalcomponent *cal, long msgnum, char *from, int unread)
 {
-       icalproperty *ps = NULL;
-       struct icaltimetype t;
-       struct wcsession *WCC;
-       struct disp_cal *Cal;
-       struct tm event;
-       time_t event_ts;
-
-       WCC = WC;
+       struct wcsession *WCC = WC;     /* stack this for faster access (WC is a function) */
 
        WCC->num_cal += 1;
-
-       WCC->disp_cal = realloc(WCC->disp_cal,
-                       (sizeof(struct disp_cal) * WCC->num_cal) );
-
-       Cal = &WCC->disp_cal[WCC->num_cal - 1];
-       Cal->cal = icalcomponent_new_clone(cal);
-
-       Cal->cal_msgnum = msgnum;
-
-       //! Precalculate some Values we can use for easy comparison later.
-       ps = icalcomponent_get_first_property(Cal->cal, ICAL_DTSTART_PROPERTY);
-       if (ps != NULL) {
-               t = icalproperty_get_dtstart(ps);
-               event_ts = icaltime_as_timet(t);
-               if (t.is_date) { //! calculate whether we are a day event.
-                       Cal->start_hour = -1;
-                       Cal->end_hour = -1;
-                       Cal->end_day = -1;
-                       gmtime_r(&event_ts, &event); 
-                       event.tm_sec = 0;
-                       event.tm_min = 0;
-                       event.tm_hour = 0; 
-                       Cal->start_day = mktime (&event);
-               }
-               else { //! Precalc start day and start day + hour
-                       localtime_r(&event_ts, &event);
-                       event.tm_sec = 0;
-                       event.tm_min = 0;
-                       Cal->start_hour = mktime (&event);
-                       event.tm_hour = 0;                      
-                       Cal->start_day = mktime (&event);
-       
-                       ps = icalcomponent_get_first_property(Cal->cal, ICAL_DTEND_PROPERTY);
-                       if (ps != NULL) { //!  Precalc the end day and end day + hour
-                               t = icalproperty_get_dtstart(ps);
-                               event_ts = icaltime_as_timet(t);
-                               localtime_r(&event_ts, &event);
-                               event.tm_sec = 0;
-                               event.tm_min = 0;
-                               Cal->end_hour = mktime (&event);
-                               event.tm_hour = 0;                      
-                               Cal->end_day = mktime (&event);
-                       }
-                       else
-                       {
-                               Cal->end_hour = -1;
-                               Cal->end_day = -1;
-                       }       
-               }
-
-
-       }
-       Cal->multi_day_event = Cal->start_day != Cal->end_day;
+       WCC->disp_cal = realloc(WC->disp_cal, (sizeof(struct disp_cal) * WCC->num_cal) );
+       WCC->disp_cal[WCC->num_cal - 1].cal = icalcomponent_new_clone(cal);
+       WCC->disp_cal[WCC->num_cal - 1].unread = unread;
+       WCC->disp_cal[WCC->num_cal - 1].from = malloc (strlen(from) + 1);
+       strcpy (WCC->disp_cal[WCC->num_cal - 1].from, from);
+       ical_dezonify(WCC->disp_cal[WCC->num_cal - 1].cal);
+       WCC->disp_cal[WCC->num_cal - 1].cal_msgnum = msgnum;
 }
 
 
@@ -519,7 +414,7 @@ void display_individual_cal(icalcomponent *cal, long msgnum)
  * \param supplied_vtodo the todo item we want to edit
  * \param msgnum number of the mesage in our db
  */
-void display_edit_individual_task(icalcomponent *supplied_vtodo, long msgnum) {
+void display_edit_individual_task(icalcomponent *supplied_vtodo, long msgnum, char *from, int unread) {
        icalcomponent *vtodo;
        icalproperty *p;
        struct icaltimetype t;
@@ -543,7 +438,9 @@ void display_edit_individual_task(icalcomponent *supplied_vtodo, long msgnum) {
                        display_edit_individual_task(
                                icalcomponent_get_first_component(
                                        vtodo, ICAL_VTODO_COMPONENT
-                               ), msgnum
+                                       ), 
+                               msgnum,
+                               from, unread
                        );
                        return;
                }
@@ -648,7 +545,7 @@ void display_edit_individual_task(icalcomponent *supplied_vtodo, long msgnum) {
  * \param supplied_vtodo the task to save
  * \param msgnum number of the mesage in our db
  */
-void save_individual_task(icalcomponent *supplied_vtodo, long msgnum) {
+void save_individual_task(icalcomponent *supplied_vtodo, long msgnum, char* from, int unread) {
        char buf[SIZ];
        int delete_existing = 0;
        icalproperty *prop;
@@ -671,8 +568,8 @@ void save_individual_task(icalcomponent *supplied_vtodo, long msgnum) {
                if (icalcomponent_isa(vtodo) == ICAL_VCALENDAR_COMPONENT) {
                        save_individual_task(
                                icalcomponent_get_first_component(
-                                       vtodo, ICAL_VTODO_COMPONENT
-                               ), msgnum
+                                       vtodo, ICAL_VTODO_COMPONENT), 
+                               msgnum, from, unread
                        );
                        return;
                }
@@ -817,12 +714,12 @@ void save_individual_task(icalcomponent *supplied_vtodo, long msgnum) {
  * \param callback a funcion \todo
  *
  */
-void display_using_handler(long msgnum,
-                       char *mimetype,
-                       icalcomponent_kind which_kind,
-                       void (*callback)(icalcomponent *, long)
+void display_using_handler(long msgnum, int unread,
+                          icalcomponent_kind which_kind,
+                          void (*callback)(icalcomponent *, long, char*, int)
        ) {
        char buf[1024];
+       char from[128] = "";
        char mime_partnum[256];
        char mime_filename[256];
        char mime_content_type[256];
@@ -833,7 +730,7 @@ void display_using_handler(long msgnum,
        icalcomponent *cal, *c;
 
        relevant_partnum[0] = '\0';
-       sprintf(buf, "MSG0 %ld|0", msgnum);     /* unfortunately we need the mime headers */
+       sprintf(buf, "MSG4 %ld", msgnum);       /* we need the mime headers */
        serv_puts(buf);
        serv_getln(buf, sizeof buf);
        if (buf[0] != '1') return;
@@ -846,13 +743,15 @@ void display_using_handler(long msgnum,
                        extract_token(mime_content_type, &buf[5], 4, '|', sizeof mime_content_type);
                        mime_length = extract_int(&buf[5], 5);
 
-                       if (!strcasecmp(mime_content_type, "text/calendar")) {
+                       if (  (!strcasecmp(mime_content_type, "text/calendar"))
+                          || (!strcasecmp(mime_content_type, "application/ics"))
+                          || (!strcasecmp(mime_content_type, "text/vtodo"))
+                       ) {
                                strcpy(relevant_partnum, mime_partnum);
                        }
-                       else if (!strcasecmp(mime_content_type, "text/vtodo")) {
-                               strcpy(relevant_partnum, mime_partnum);
-                       }
-
+               }
+               else if (!strncasecmp(buf, "from=", 4)) {
+                       extract_token(from, buf, 1, '=', sizeof(from));
                }
        }
 
@@ -867,7 +766,7 @@ void display_using_handler(long msgnum,
 
                                /** Simple components of desired type */
                                if (icalcomponent_isa(cal) == which_kind) {
-                                       callback(cal, msgnum);
+                                       callback(cal, msgnum, from, unread);
                                }
 
                                /** Subcomponents of desired type */
@@ -876,22 +775,22 @@ void display_using_handler(long msgnum,
                                    (c != 0);
                                    c = icalcomponent_get_next_component(cal,
                                    which_kind)) {
-                                       callback(c, msgnum);
+                                       callback(c, msgnum, from, unread);
                                }
                                icalcomponent_free(cal);
                        }
                        free(relevant_source);
                }
        }
-
+       icalmemory_free_ring();
 }
 
 /**
  * \brief display whole calendar
  * \param msgnum number of the mesage in our db
  */
-void display_calendar(long msgnum) {
-       display_using_handler(msgnum, "text/calendar",
+void display_calendar(long msgnum, int unread) {
+       display_using_handler(msgnum, unread,
                                ICAL_VEVENT_COMPONENT,
                                display_individual_cal);
 }
@@ -900,8 +799,8 @@ void display_calendar(long msgnum) {
  * \brief display whole taksview
  * \param msgnum number of the mesage in our db
  */
-void display_task(long msgnum) {
-       display_using_handler(msgnum, "text/calendar",
+void display_task(long msgnum, int unread) {
+       display_using_handler(msgnum, unread,
                                ICAL_VTODO_COMPONENT,
                                display_individual_cal);
 }
@@ -920,13 +819,13 @@ void display_edit_task(void) {
        msgnum = atol(bstr("msgnum"));
        if (msgnum > 0L) {
                /** existing task */
-               display_using_handler(msgnum, "text/calendar",
+               display_using_handler(msgnum, 0,
                                ICAL_VTODO_COMPONENT,
                                display_edit_individual_task);
        }
        else {
                /** new task */
-               display_edit_individual_task(NULL, 0L);
+               display_edit_individual_task(NULL, 0L, "", 0);
        }
 }
 
@@ -938,12 +837,12 @@ void save_task(void) {
 
        msgnum = atol(bstr("msgnum"));
        if (msgnum > 0L) {
-               display_using_handler(msgnum, "text/calendar",
+               display_using_handler(msgnum, 0,
                                ICAL_VTODO_COMPONENT,
                                save_individual_task);
        }
        else {
-               save_individual_task(NULL, 0L);
+               save_individual_task(NULL, 0L, "", 0);
        }
 }
 
@@ -956,13 +855,13 @@ void display_edit_event(void) {
        msgnum = atol(bstr("msgnum"));
        if (msgnum > 0L) {
                /* existing event */
-               display_using_handler(msgnum, "text/calendar",
+               display_using_handler(msgnum, 0,
                                ICAL_VEVENT_COMPONENT,
                                display_edit_individual_event);
        }
        else {
                /* new event */
-               display_edit_individual_event(NULL, 0L);
+               display_edit_individual_event(NULL, 0L, "", 0);
        }
 }
 
@@ -975,12 +874,12 @@ void save_event(void) {
        msgnum = atol(bstr("msgnum"));
 
        if (msgnum > 0L) {
-               display_using_handler(msgnum, "text/calendar",
+               display_using_handler(msgnum, 0,
                                ICAL_VEVENT_COMPONENT,
                                save_individual_event);
        }
        else {
-               save_individual_event(NULL, 0L);
+               save_individual_event(NULL, 0L, "", 0);
        }
 }
 
@@ -1030,8 +929,3 @@ void do_freebusy(char *req) {
 }
 
 
-
-#endif /* WEBCIT_WITH_CALENDAR_SERVICE */
-
-
-/*@}*/