* All OS-level includes are now included from webcit.h instead of from
[citadel.git] / webcit / ical_dezonify.c
1 /* 
2  * $Id$ 
3  *
4  * Function to go through an ical component set and convert all non-UTC
5  * date/time properties to UTC.  It also strips out any VTIMEZONE
6  * subcomponents afterwards, because they're irrelevant.
7  *
8  * Everything here will work on both a fully encapsulated VCALENDAR component
9  * or any type of subcomponent.
10  *
11  */
12
13
14 #include "webcit.h"
15 #include "webserver.h"
16
17
18 #ifdef WEBCIT_WITH_CALENDAR_SERVICE
19
20
21 /*
22  * Back end function for ical_dezonify()
23  *
24  * We supply this with the master component, the relevant component,
25  * and the property (which will be a DTSTART, DTEND, etc.)
26  * which we want to convert to UTC.
27  */
28 void ical_dezonify_backend(icalcomponent *cal,
29                         icalcomponent *rcal,
30                         icalproperty *prop) {
31
32         icaltimezone *t = NULL;
33         icalparameter *param;
34         const char *tzid;
35         struct icaltimetype TheTime;
36
37         /* Give me nothing and I will give you nothing in return. */
38         if (cal == NULL) return;
39
40         /* Hunt for a TZID parameter in this property. */
41         param = icalproperty_get_first_parameter(prop, ICAL_TZID_PARAMETER);
42
43         /* Get the stringish name of this TZID. */
44         if (param != NULL) {
45                 tzid = icalparameter_get_tzid(param);
46
47                 /* Convert it to an icaltimezone type. */
48                 if (tzid != NULL) {
49                         t = icalcomponent_get_timezone(cal, tzid);
50                 }
51
52         }
53
54         /* Now we know the timezone.  Convert to UTC. */
55
56         if (icalproperty_isa(prop) == ICAL_DTSTART_PROPERTY) {
57                 TheTime = icalproperty_get_dtstart(prop);
58         }
59         else if (icalproperty_isa(prop) == ICAL_DTEND_PROPERTY) {
60                 TheTime = icalproperty_get_dtend(prop);
61         }
62         else if (icalproperty_isa(prop) == ICAL_DUE_PROPERTY) {
63                 TheTime = icalproperty_get_due(prop);
64         }
65         else if (icalproperty_isa(prop) == ICAL_EXDATE_PROPERTY) {
66                 TheTime = icalproperty_get_exdate(prop);
67         }
68         else {
69                 return;
70         }
71
72         /* Do the conversion. */
73         if (t != NULL) {
74                 icaltimezone_convert_time(&TheTime,
75                                         t,
76                                         icaltimezone_get_utc_timezone()
77                 );
78         }
79         TheTime.is_utc = 1;
80         icalproperty_remove_parameter_by_kind(prop, ICAL_TZID_PARAMETER);
81
82         /* Now add the converted property back in. */
83         if (icalproperty_isa(prop) == ICAL_DTSTART_PROPERTY) {
84                 icalproperty_set_dtstart(prop, TheTime);
85         }
86         else if (icalproperty_isa(prop) == ICAL_DTEND_PROPERTY) {
87                 icalproperty_set_dtend(prop, TheTime);
88         }
89         else if (icalproperty_isa(prop) == ICAL_DUE_PROPERTY) {
90                 icalproperty_set_due(prop, TheTime);
91         }
92         else if (icalproperty_isa(prop) == ICAL_EXDATE_PROPERTY) {
93                 icalproperty_set_exdate(prop, TheTime);
94         }
95 }
96
97
98 /*
99  * Recursive portion of ical_dezonify()
100  */
101 void ical_dezonify_recur(icalcomponent *cal, icalcomponent *rcal) {
102         icalcomponent *c;
103         icalproperty *p;
104
105         /*
106          * Recurse through all subcomponents *except* VTIMEZONE ones.
107          */
108         for (c=icalcomponent_get_first_component(
109                                         rcal, ICAL_ANY_COMPONENT);
110                 c != NULL;
111                 c = icalcomponent_get_next_component(
112                                         rcal, ICAL_ANY_COMPONENT)
113         ) {
114                 if (icalcomponent_isa(c) != ICAL_VTIMEZONE_COMPONENT) {
115                         ical_dezonify_recur(cal, c);
116                 }
117         }
118
119         /*
120          * Now look for DTSTART and DTEND properties
121          */
122         for (p=icalcomponent_get_first_property(
123                                 rcal, ICAL_ANY_PROPERTY);
124                 p != NULL;
125                 p = icalcomponent_get_next_property(
126                                 rcal, ICAL_ANY_PROPERTY)
127         ) {
128                 if (
129                         (icalproperty_isa(p) == ICAL_DTSTART_PROPERTY)
130                         || (icalproperty_isa(p) == ICAL_DTEND_PROPERTY)
131                         || (icalproperty_isa(p) == ICAL_DUE_PROPERTY)
132                         || (icalproperty_isa(p) == ICAL_EXDATE_PROPERTY)
133                    ) {
134                         ical_dezonify_backend(cal, rcal, p);
135                 }
136         }
137 }
138
139
140 /*
141  * Convert all DTSTART and DTEND properties in all subcomponents to UTC.
142  * This function will search any VTIMEZONE subcomponents to learn the
143  * relevant timezone information.
144  */
145 void ical_dezonify(icalcomponent *cal) {
146         icalcomponent *vt = NULL;
147
148         /* Convert all times to UTC */
149         ical_dezonify_recur(cal, cal);
150
151         /* Strip out VTIMEZONE subcomponents -- we don't need them anymore */
152         while (vt = icalcomponent_get_first_component(
153                         cal, ICAL_VTIMEZONE_COMPONENT), vt != NULL) {
154                 icalcomponent_remove_component(cal, vt);
155                 icalcomponent_free(vt);
156         }
157
158 }
159
160
161 #endif /* WEBCIT_WITH_CALENDAR_SERVICE */