No issues found
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) version 3.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with the program; if not, see <http://www.gnu.org/licenses/>
14 *
15 *
16 * Authors:
17 * David Trowbridge <trowbrds@cs.colorado.edu>
18 *
19 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
20 *
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <string.h>
28 #include <glib/gi18n.h>
29
30 #include <shell/e-shell.h>
31
32 #include "publish-format-ical.h"
33
34 typedef struct {
35 GHashTable *zones;
36 ECalClient *client;
37 } CompTzData;
38
39 static void
40 insert_tz_comps (icalparameter *param,
41 gpointer cb_data)
42 {
43 const gchar *tzid;
44 CompTzData *tdata = cb_data;
45 icaltimezone *zone = NULL;
46 icalcomponent *tzcomp;
47 GError *error = NULL;
48
49 tzid = icalparameter_get_tzid (param);
50
51 if (g_hash_table_lookup (tdata->zones, tzid))
52 return;
53
54 if (!e_cal_client_get_timezone_sync (tdata->client, tzid, &zone, NULL, &error)) {
55 g_warning ("Could not get the timezone information for %s : %s \n", tzid, error->message);
56 g_error_free (error);
57 return;
58 }
59
60 tzcomp = icalcomponent_new_clone (icaltimezone_get_component (zone));
61 g_hash_table_insert (tdata->zones, (gpointer) tzid, (gpointer) tzcomp);
62 }
63
64 static void
65 append_tz_to_comp (gpointer key,
66 gpointer value,
67 icalcomponent *toplevel)
68 {
69 icalcomponent_add_component (toplevel, (icalcomponent *) value);
70 }
71
72 static gboolean
73 write_calendar (const gchar *uid,
74 GOutputStream *stream,
75 GError **error)
76 {
77 EShell *shell;
78 ESource *source;
79 ESourceRegistry *registry;
80 ECalClient *client = NULL;
81 GSList *objects;
82 icalcomponent *top_level;
83 gboolean res = FALSE;
84
85 shell = e_shell_get_default ();
86 registry = e_shell_get_registry (shell);
87 source = e_source_registry_ref_source (registry, uid);
88
89 if (source != NULL) {
90 client = e_cal_client_new (source, E_CAL_CLIENT_SOURCE_TYPE_EVENTS, error);
91 g_object_unref (source);
92 }
93 if (!client) {
94 if (error && !error)
95 *error = g_error_new (E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_NO_SUCH_CALENDAR, _("Could not publish calendar: Calendar backend no longer exists"));
96 return FALSE;
97 }
98
99 if (!e_client_open_sync (E_CLIENT (client), TRUE, NULL, error)) {
100 g_object_unref (client);
101 return FALSE;
102 }
103
104 top_level = e_cal_util_new_top_level ();
105
106 if (e_cal_client_get_object_list_sync (client, "#t", &objects, NULL, error)) {
107 GSList *iter;
108 gchar *ical_string;
109 CompTzData tdata;
110
111 tdata.zones = g_hash_table_new (g_str_hash, g_str_equal);
112 tdata.client = client;
113
114 for (iter = objects; iter; iter = iter->next) {
115 icalcomponent *icalcomp = icalcomponent_new_clone (iter->data);
116 icalcomponent_foreach_tzid (icalcomp, insert_tz_comps, &tdata);
117 icalcomponent_add_component (top_level, icalcomp);
118 }
119
120 g_hash_table_foreach (tdata.zones, (GHFunc) append_tz_to_comp, top_level);
121
122 g_hash_table_destroy (tdata.zones);
123 tdata.zones = NULL;
124
125 ical_string = icalcomponent_as_ical_string_r (top_level);
126 res = g_output_stream_write_all (stream, ical_string, strlen (ical_string), NULL, NULL, error);
127 g_free (ical_string);
128 e_cal_client_free_icalcomp_slist (objects);
129 }
130
131 g_object_unref (client);
132 icalcomponent_free (top_level);
133
134 return res;
135 }
136
137 void
138 publish_calendar_as_ical (GOutputStream *stream,
139 EPublishUri *uri,
140 GError **error)
141 {
142 GSList *l;
143
144 /* events */
145 l = uri->events;
146 while (l) {
147 gchar *uid = l->data;
148 if (!write_calendar (uid, stream, error))
149 break;
150 l = g_slist_next (l);
151 }
152 }