ical_dezonify.c

00001 /* 
00002  * $Id: ical_dezonify.c 5160 2007-05-11 20:38:53Z ajc $ 
00003  */
00016 
00017 #include "webcit.h"
00018 #include "webserver.h"
00019 
00020 
00021 #ifdef WEBCIT_WITH_CALENDAR_SERVICE
00022 
00023 
00024 /*
00025  * Figure out which time zone needs to be used for timestamps that are
00026  * not UTC and do not have a time zone specified.
00027  *
00028  * FIXME - most sites are not in New York :)
00029  */
00030 icaltimezone *get_default_icaltimezone(void) {
00031 
00032         icaltimezone *zone = NULL;
00033 
00034         if (!zone) {
00035                 zone = icaltimezone_get_builtin_timezone(serv_info.serv_default_cal_zone);
00036         }
00037         if (!zone) {
00038                 zone = icaltimezone_get_utc_timezone();
00039         }
00040         return zone;
00041 }
00042 
00043 
00044 /*
00045  * Back end function for ical_dezonify()
00046  *
00047  * We supply this with the master component, the relevant component,
00048  * and the property (which will be a DTSTART, DTEND, etc.)
00049  * which we want to convert to UTC.
00050  */
00051 void ical_dezonify_backend(icalcomponent *cal,
00052                         icalcomponent *rcal,
00053                         icalproperty *prop) {
00054 
00055         icaltimezone *t = NULL;
00056         icalparameter *param;
00057         const char *tzid = NULL;
00058         struct icaltimetype TheTime;
00059         int utc_declared_as_tzid = 0;   
00061         /* Give me nothing and I will give you nothing in return. */
00062         if (cal == NULL) return;
00063 
00064         /* Hunt for a TZID parameter in this property. */
00065         param = icalproperty_get_first_parameter(prop, ICAL_TZID_PARAMETER);
00066 
00067         /* Get the stringish name of this TZID. */
00068         if (param != NULL) {
00069                 tzid = icalparameter_get_tzid(param);
00070 
00071                 /* Convert it to an icaltimezone type. */
00072                 if (tzid != NULL) {
00073                         lprintf(9, "                * Stringy supplied timezone is: '%s'\n", tzid);
00074                         if ( (!strcasecmp(tzid, "UTC")) || (!strcasecmp(tzid, "GMT")) ) {
00075                                 utc_declared_as_tzid = 1;
00076                                 lprintf(9, "                * ...and we handle that internally.\n");
00077                         }
00078                         else {
00079                                 t = icalcomponent_get_timezone(cal, tzid);
00080                                 lprintf(9, "                * ...and I %s have tzdata for that zone.\n",
00081                                         (t ? "DO" : "DO NOT")
00082                                 );
00083                         }
00084                 }
00085 
00086         }
00087 
00088         /* Now we know the timezone.  Convert to UTC. */
00089 
00090         if (icalproperty_isa(prop) == ICAL_DTSTART_PROPERTY) {
00091                 TheTime = icalproperty_get_dtstart(prop);
00092         }
00093         else if (icalproperty_isa(prop) == ICAL_DTEND_PROPERTY) {
00094                 TheTime = icalproperty_get_dtend(prop);
00095         }
00096         else if (icalproperty_isa(prop) == ICAL_DUE_PROPERTY) {
00097                 TheTime = icalproperty_get_due(prop);
00098         }
00099         else if (icalproperty_isa(prop) == ICAL_EXDATE_PROPERTY) {
00100                 TheTime = icalproperty_get_exdate(prop);
00101         }
00102         else {
00103                 return;
00104         }
00105 
00106         lprintf(9, "                * Was: %s\n", icaltime_as_ical_string(TheTime));
00107 
00108         if (TheTime.is_utc) {
00109                 lprintf(9, "                * This property is ALREADY UTC.\n");
00110         }
00111 
00112         else if (utc_declared_as_tzid) {
00113                 lprintf(9, "                * Replacing '%s' TZID with 'Z' suffix.\n", tzid);
00114                 TheTime.is_utc = 1;
00115         }
00116 
00117         else {
00118                 /* Do the conversion. */
00119                 if (t != NULL) {
00120                         lprintf(9, "                * Timezone prop found.  Converting to UTC.\n");
00121                 }
00122                 else {
00123                         lprintf(9, "                * Converting default timezone to UTC.\n");
00124                 }
00125 
00126                 if (t == NULL) {
00127                         t = get_default_icaltimezone();
00128                 }
00129 
00130                 icaltimezone_convert_time(&TheTime,
00131                                         t,
00132                                         icaltimezone_get_utc_timezone()
00133                 );
00134                 TheTime.is_utc = 1;
00135         }
00136 
00137         icalproperty_remove_parameter_by_kind(prop, ICAL_TZID_PARAMETER);
00138         lprintf(9, "                * Now: %s\n", icaltime_as_ical_string(TheTime));
00139 
00140         /* Now add the converted property back in. */
00141         if (icalproperty_isa(prop) == ICAL_DTSTART_PROPERTY) {
00142                 icalproperty_set_dtstart(prop, TheTime);
00143         }
00144         else if (icalproperty_isa(prop) == ICAL_DTEND_PROPERTY) {
00145                 icalproperty_set_dtend(prop, TheTime);
00146         }
00147         else if (icalproperty_isa(prop) == ICAL_DUE_PROPERTY) {
00148                 icalproperty_set_due(prop, TheTime);
00149         }
00150         else if (icalproperty_isa(prop) == ICAL_EXDATE_PROPERTY) {
00151                 icalproperty_set_exdate(prop, TheTime);
00152         }
00153 }
00154 
00155 
00156 /*
00157  * Recursive portion of ical_dezonify()
00158  */
00159 void ical_dezonify_recurse(icalcomponent *cal, icalcomponent *rcal) {
00160         icalcomponent *c;
00161         icalproperty *p;
00162 
00163         /*
00164          * Recurse through all subcomponents *except* VTIMEZONE ones.
00165          */
00166         for (c=icalcomponent_get_first_component(
00167                                         rcal, ICAL_ANY_COMPONENT);
00168                 c != NULL;
00169                 c = icalcomponent_get_next_component(
00170                                         rcal, ICAL_ANY_COMPONENT)
00171         ) {
00172                 if (icalcomponent_isa(c) != ICAL_VTIMEZONE_COMPONENT) {
00173                         ical_dezonify_recurse(cal, c);
00174                 }
00175         }
00176 
00177         /*
00178          * Now look for DTSTART and DTEND properties
00179          */
00180         for (p=icalcomponent_get_first_property(rcal, ICAL_ANY_PROPERTY);
00181                 p != NULL;
00182                 p = icalcomponent_get_next_property(rcal, ICAL_ANY_PROPERTY)
00183         ) {
00184                 if (
00185                         (icalproperty_isa(p) == ICAL_DTSTART_PROPERTY)
00186                         || (icalproperty_isa(p) == ICAL_DTEND_PROPERTY)
00187                         || (icalproperty_isa(p) == ICAL_DUE_PROPERTY)
00188                         || (icalproperty_isa(p) == ICAL_EXDATE_PROPERTY)
00189                    ) {
00190                         ical_dezonify_backend(cal, rcal, p);
00191                 }
00192         }
00193 }
00194 
00195 
00196 /*
00197  * Convert all DTSTART and DTEND properties in all subcomponents to UTC.
00198  * This function will search any VTIMEZONE subcomponents to learn the
00199  * relevant timezone information.
00200  */
00201 void ical_dezonify(icalcomponent *cal) {
00202         icalcomponent *vt = NULL;
00203 
00204         lprintf(9, "ical_dezonify() started\n");
00205 
00206         /* Convert all times to UTC */
00207         ical_dezonify_recurse(cal, cal);
00208 
00209         /* Strip out VTIMEZONE subcomponents -- we don't need them anymore */
00210         while (vt = icalcomponent_get_first_component(
00211                         cal, ICAL_VTIMEZONE_COMPONENT), vt != NULL) {
00212                 icalcomponent_remove_component(cal, vt);
00213                 icalcomponent_free(vt);
00214         }
00215 
00216         lprintf(9, "ical_dezonify() completed\n");
00217 }
00218 
00219 
00220 #endif /* WEBCIT_WITH_CALENDAR_SERVICE */

Generated on Wed Jun 20 23:13:08 2007 for webcit by  doxygen 1.5.2