updated changelog
[platform/upstream/evolution-data-server.git] / modules / yahoo-backend / module-yahoo-backend.c
1 /*
2  * module-yahoo-backend.c
3  *
4  * This library is free software you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation.
7  *
8  * This library is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this library; if not, see <http://www.gnu.org/licenses/>.
15  *
16  */
17
18 #include <config.h>
19 #include <glib/gi18n-lib.h>
20
21 #include <libebackend/libebackend.h>
22
23 /* Standard GObject macros */
24 #define E_TYPE_YAHOO_BACKEND \
25         (e_yahoo_backend_get_type ())
26 #define E_YAHOO_BACKEND(obj) \
27         (G_TYPE_CHECK_INSTANCE_CAST \
28         ((obj), E_TYPE_YAHOO_BACKEND, EYahooBackend))
29
30 /* Just for readability... */
31 #define METHOD(x) (CAMEL_NETWORK_SECURITY_METHOD_##x)
32
33 /* IMAP Configuration Details */
34 #define YAHOO_IMAP_BACKEND_NAME         "imapx"
35 #define YAHOO_IMAP_HOST                 "imap.mail.yahoo.com"
36 #define YAHOO_IMAP_PORT                 993
37 #define YAHOO_IMAP_SECURITY_METHOD      METHOD (SSL_ON_ALTERNATE_PORT)
38
39 /* SMTP Configuration Details */
40 #define YAHOO_SMTP_BACKEND_NAME         "smtp"
41 #define YAHOO_SMTP_HOST                 "smtp.mail.yahoo.com"
42 #define YAHOO_SMTP_PORT                 465
43 #define YAHOO_SMTP_SECURITY_METHOD      METHOD (SSL_ON_ALTERNATE_PORT)
44
45 /* Calendar Configuration Details */
46 #define YAHOO_CALENDAR_BACKEND_NAME     "caldav"
47 #define YAHOO_CALENDAR_HOST             "caldav.calendar.yahoo.com"
48 #define YAHOO_CALENDAR_CALDAV_PATH      "/dav/%s/Calendar/%s"
49 #define YAHOO_CALENDAR_RESOURCE_ID      "Calendar"
50
51 /* Tasks Configuration Details
52  * (mostly the same as calendar) */
53 #define YAHOO_TASKS_RESOURCE_ID         "Tasks"
54
55 typedef struct _EYahooBackend EYahooBackend;
56 typedef struct _EYahooBackendClass EYahooBackendClass;
57
58 typedef struct _EYahooBackendFactory EYahooBackendFactory;
59 typedef struct _EYahooBackendFactoryClass EYahooBackendFactoryClass;
60
61 struct _EYahooBackend {
62         ECollectionBackend parent;
63         GWeakRef mail_identity_source;
64 };
65
66 struct _EYahooBackendClass {
67         ECollectionBackendClass parent_class;
68 };
69
70 struct _EYahooBackendFactory {
71         ECollectionBackendFactory parent;
72 };
73
74 struct _EYahooBackendFactoryClass {
75         ECollectionBackendFactoryClass parent_class;
76 };
77
78 /* Module Entry Points */
79 void e_module_load (GTypeModule *type_module);
80 void e_module_unload (GTypeModule *type_module);
81
82 /* Forward Declarations */
83 GType e_yahoo_backend_get_type (void);
84 GType e_yahoo_backend_factory_get_type (void);
85
86 G_DEFINE_DYNAMIC_TYPE (
87         EYahooBackend,
88         e_yahoo_backend,
89         E_TYPE_COLLECTION_BACKEND)
90
91 G_DEFINE_DYNAMIC_TYPE (
92         EYahooBackendFactory,
93         e_yahoo_backend_factory,
94         E_TYPE_COLLECTION_BACKEND_FACTORY)
95
96 static void
97 yahoo_backend_config_calendar_child (ECollectionBackend *backend,
98                                      ESource *source)
99 {
100         EYahooBackend *yahoo_backend;
101         ESource *collection_source;
102         ESource *mail_identity_source;
103         ESourceExtension *extension;
104         ESourceCollection *collection_extension;
105         const gchar *extension_name;
106         const gchar *identity;
107         gchar *display_name = NULL;
108
109         /* FIXME As a future enhancement, we should query Yahoo!
110          *       for a list of user calendars and add them to the
111          *       collection with matching display names and colors. */
112
113         yahoo_backend = E_YAHOO_BACKEND (backend);
114
115         collection_source = e_backend_get_source (E_BACKEND (backend));
116
117         collection_extension = e_source_get_extension (
118                 collection_source, E_SOURCE_EXTENSION_COLLECTION);
119
120         identity = e_source_collection_get_identity (collection_extension);
121
122         /* XXX Assume the calendar's display name can be derived from
123          *     the user's mail identity.  As mentioned above, we should
124          *     really just query Yahoo! for a list of user calendars. */
125         mail_identity_source =
126                 g_weak_ref_get (&yahoo_backend->mail_identity_source);
127         if (mail_identity_source != NULL) {
128                 extension = e_source_get_extension (
129                         mail_identity_source,
130                         E_SOURCE_EXTENSION_MAIL_IDENTITY);
131                 display_name = e_source_mail_identity_dup_name (
132                         E_SOURCE_MAIL_IDENTITY (extension));
133                 if (display_name != NULL)
134                         g_strdelimit (display_name, " ", '_');
135                 g_object_unref (mail_identity_source);
136         }
137
138         extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
139         extension = e_source_get_extension (source, extension_name);
140
141         e_source_authentication_set_host (
142                 E_SOURCE_AUTHENTICATION (extension),
143                 YAHOO_CALENDAR_HOST);
144
145         g_object_bind_property (
146                 collection_extension, "identity",
147                 extension, "user",
148                 G_BINDING_SYNC_CREATE);
149
150         extension_name = E_SOURCE_EXTENSION_SECURITY;
151         extension = e_source_get_extension (source, extension_name);
152
153         e_source_security_set_secure (
154                 E_SOURCE_SECURITY (extension), TRUE);
155
156         extension_name = E_SOURCE_EXTENSION_WEBDAV_BACKEND;
157         extension = e_source_get_extension (source, extension_name);
158
159         e_source_webdav_set_display_name (
160                 E_SOURCE_WEBDAV (extension), display_name);
161
162         if (identity != NULL && display_name != NULL) {
163                 gchar *resource_path;
164
165                 resource_path = g_strdup_printf (
166                         YAHOO_CALENDAR_CALDAV_PATH, identity, display_name);
167                 e_source_webdav_set_resource_path (
168                         E_SOURCE_WEBDAV (extension), resource_path);
169                 g_free (resource_path);
170         }
171
172         g_free (display_name);
173 }
174
175 static void
176 yahoo_backend_add_calendar (ECollectionBackend *backend)
177 {
178         ESource *source;
179         ESourceBackend *extension;
180         ESourceRegistryServer *server;
181         const gchar *backend_name;
182         const gchar *extension_name;
183         const gchar *resource_id;
184
185         /* XXX We could just stick a [Calendar] and [Task List] extension
186          *     into the same ESource since all other settings are exactly
187          *     the same.  But it might be confusing if tweaking a setting
188          *     in your Yahoo! Calendar also gets applied to your Yahoo!
189          *     Task List in Evolution. */
190
191         backend_name = YAHOO_CALENDAR_BACKEND_NAME;
192
193         server = e_collection_backend_ref_server (backend);
194
195         /* Add Yahoo! Calendar */
196
197         resource_id = YAHOO_CALENDAR_RESOURCE_ID;
198         source = e_collection_backend_new_child (backend, resource_id);
199         e_source_set_display_name (source, _("Calendar"));
200
201         extension_name = E_SOURCE_EXTENSION_CALENDAR;
202         extension = e_source_get_extension (source, extension_name);
203         e_source_backend_set_backend_name (extension, backend_name);
204
205         extension_name = E_SOURCE_EXTENSION_ALARMS;
206         extension = e_source_get_extension (source, extension_name);
207         if (!e_source_alarms_get_last_notified (E_SOURCE_ALARMS (extension))) {
208                 GTimeVal today_tv;
209                 gchar *today;
210
211                 g_get_current_time (&today_tv);
212                 today = g_time_val_to_iso8601 (&today_tv);
213                 e_source_alarms_set_last_notified (E_SOURCE_ALARMS (extension), today);
214                 g_free (today);
215         }
216
217         yahoo_backend_config_calendar_child (backend, source);
218         e_source_registry_server_add_source (server, source);
219
220         g_object_unref (source);
221
222         /* Add Yahoo! Tasks */
223
224         resource_id = YAHOO_TASKS_RESOURCE_ID;
225         source = e_collection_backend_new_child (backend, resource_id);
226         e_source_set_display_name (source, _("Tasks"));
227
228         extension_name = E_SOURCE_EXTENSION_TASK_LIST;
229         extension = e_source_get_extension (source, extension_name);
230         e_source_backend_set_backend_name (extension, backend_name);
231
232         yahoo_backend_config_calendar_child (backend, source);
233         e_source_registry_server_add_source (server, source);
234
235         g_object_unref (source);
236
237         g_object_unref (server);
238 }
239
240 static void
241 yahoo_backend_populate (ECollectionBackend *backend)
242 {
243         GList *list;
244
245         /* Chain up to parent's populate() method. */
246         E_COLLECTION_BACKEND_CLASS (e_yahoo_backend_parent_class)->
247                 populate (backend);
248
249         /* Chain up first so we pick up the mail identity source. */
250         list = e_collection_backend_list_calendar_sources (backend);
251         if (list == NULL)
252                 yahoo_backend_add_calendar (backend);
253         g_list_free_full (list, (GDestroyNotify) g_object_unref);
254 }
255
256 static gchar *
257 yahoo_backend_dup_resource_id (ECollectionBackend *backend,
258                                ESource *child_source)
259 {
260         const gchar *extension_name;
261
262         /* XXX This is trival for now since we only
263          *     add one calendar and one task list. */
264
265         extension_name = E_SOURCE_EXTENSION_CALENDAR;
266         if (e_source_has_extension (child_source, extension_name))
267                 return g_strdup (YAHOO_CALENDAR_RESOURCE_ID);
268
269         extension_name = E_SOURCE_EXTENSION_TASK_LIST;
270         if (e_source_has_extension (child_source, extension_name))
271                 return g_strdup (YAHOO_TASKS_RESOURCE_ID);
272
273         return NULL;
274 }
275
276 static void
277 yahoo_backend_child_added (ECollectionBackend *backend,
278                            ESource *child_source)
279 {
280         EYahooBackend *yahoo_backend;
281         ESource *collection_source;
282         const gchar *extension_name;
283         gboolean is_mail = FALSE;
284
285         yahoo_backend = E_YAHOO_BACKEND (backend);
286         collection_source = e_backend_get_source (E_BACKEND (backend));
287
288         extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
289         is_mail |= e_source_has_extension (child_source, extension_name);
290
291         /* Take special note of the mail identity source.
292          * We need it to build the calendar CalDAV path. */
293         extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
294         if (e_source_has_extension (child_source, extension_name)) {
295                 GWeakRef *weak_ref;
296
297                 weak_ref = &yahoo_backend->mail_identity_source;
298                 g_weak_ref_set (weak_ref, child_source);
299                 is_mail = TRUE;
300         }
301
302         extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
303         is_mail |= e_source_has_extension (child_source, extension_name);
304
305         /* Synchronize mail-related user with the collection identity. */
306         extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
307         if (is_mail && e_source_has_extension (child_source, extension_name)) {
308                 ESourceAuthentication *auth_child_extension;
309                 ESourceCollection *collection_extension;
310                 const gchar *collection_identity;
311                 const gchar *auth_child_user;
312
313                 extension_name = E_SOURCE_EXTENSION_COLLECTION;
314                 collection_extension = e_source_get_extension (
315                         collection_source, extension_name);
316                 collection_identity = e_source_collection_get_identity (
317                         collection_extension);
318
319                 extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
320                 auth_child_extension = e_source_get_extension (
321                         child_source, extension_name);
322                 auth_child_user = e_source_authentication_get_user (
323                         auth_child_extension);
324
325                 /* XXX Do not override an existing user name setting.
326                  *     The IMAP or (especially) SMTP configuration may
327                  *     have been modified to use a non-Yahoo! server. */
328                 if (auth_child_user == NULL)
329                         e_source_authentication_set_user (
330                                 auth_child_extension,
331                                 collection_identity);
332         }
333
334         /* Chain up to parent's child_added() method. */
335         E_COLLECTION_BACKEND_CLASS (e_yahoo_backend_parent_class)->
336                 child_added (backend, child_source);
337 }
338
339 static void
340 e_yahoo_backend_class_init (EYahooBackendClass *class)
341 {
342         ECollectionBackendClass *backend_class;
343
344         backend_class = E_COLLECTION_BACKEND_CLASS (class);
345         backend_class->populate = yahoo_backend_populate;
346         backend_class->dup_resource_id = yahoo_backend_dup_resource_id;
347         backend_class->child_added = yahoo_backend_child_added;
348 }
349
350 static void
351 e_yahoo_backend_class_finalize (EYahooBackendClass *class)
352 {
353 }
354
355 static void
356 e_yahoo_backend_init (EYahooBackend *backend)
357 {
358 }
359
360 static void
361 yahoo_backend_prepare_mail_account_source (ESource *source)
362 {
363         ESourceCamel *camel_extension;
364         ESourceExtension *extension;
365         CamelSettings *settings;
366         const gchar *backend_name;
367         const gchar *extension_name;
368
369         backend_name = YAHOO_IMAP_BACKEND_NAME;
370
371         extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
372         extension = e_source_get_extension (source, extension_name);
373
374         e_source_backend_set_backend_name (
375                 E_SOURCE_BACKEND (extension), backend_name);
376
377         extension_name = e_source_camel_get_extension_name (backend_name);
378         camel_extension = e_source_get_extension (source, extension_name);
379         settings = e_source_camel_get_settings (camel_extension);
380
381         /* The "auth-mechanism" should be determined elsewhere. */
382
383         camel_network_settings_set_host (
384                 CAMEL_NETWORK_SETTINGS (settings),
385                 YAHOO_IMAP_HOST);
386
387         camel_network_settings_set_port (
388                 CAMEL_NETWORK_SETTINGS (settings),
389                 YAHOO_IMAP_PORT);
390
391         camel_network_settings_set_security_method (
392                 CAMEL_NETWORK_SETTINGS (settings),
393                 YAHOO_IMAP_SECURITY_METHOD);
394 }
395
396 static void
397 yahoo_backend_prepare_mail_transport_source (ESource *source)
398 {
399         ESourceCamel *camel_extension;
400         ESourceExtension *extension;
401         CamelSettings *settings;
402         const gchar *backend_name;
403         const gchar *extension_name;
404
405         /* Configure the mail transport source. */
406
407         backend_name = YAHOO_SMTP_BACKEND_NAME;
408
409         extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
410         extension = e_source_get_extension (source, extension_name);
411
412         e_source_backend_set_backend_name (
413                 E_SOURCE_BACKEND (extension), backend_name);
414
415         extension_name = e_source_camel_get_extension_name (backend_name);
416         camel_extension = e_source_get_extension (source, extension_name);
417         settings = e_source_camel_get_settings (camel_extension);
418
419         /* The "auth-mechanism" should be determined elsewhere. */
420
421         camel_network_settings_set_host (
422                 CAMEL_NETWORK_SETTINGS (settings),
423                 YAHOO_SMTP_HOST);
424
425         camel_network_settings_set_port (
426                 CAMEL_NETWORK_SETTINGS (settings),
427                 YAHOO_SMTP_PORT);
428
429         camel_network_settings_set_security_method (
430                 CAMEL_NETWORK_SETTINGS (settings),
431                 YAHOO_SMTP_SECURITY_METHOD);
432 }
433
434 static void
435 yahoo_backend_factory_prepare_mail (ECollectionBackendFactory *factory,
436                                     ESource *mail_account_source,
437                                     ESource *mail_identity_source,
438                                     ESource *mail_transport_source)
439 {
440         ECollectionBackendFactoryClass *parent_class;
441
442         /* Chain up to parent's prepare_mail() method. */
443         parent_class =
444                 E_COLLECTION_BACKEND_FACTORY_CLASS (
445                 e_yahoo_backend_factory_parent_class);
446         parent_class->prepare_mail (
447                 factory,
448                 mail_account_source,
449                 mail_identity_source,
450                 mail_transport_source);
451
452         yahoo_backend_prepare_mail_account_source (mail_account_source);
453         yahoo_backend_prepare_mail_transport_source (mail_transport_source);
454 }
455
456 static void
457 e_yahoo_backend_factory_class_init (EYahooBackendFactoryClass *class)
458 {
459         ECollectionBackendFactoryClass *factory_class;
460
461         factory_class = E_COLLECTION_BACKEND_FACTORY_CLASS (class);
462         factory_class->factory_name = "yahoo";
463         factory_class->backend_type = E_TYPE_YAHOO_BACKEND;
464         factory_class->prepare_mail = yahoo_backend_factory_prepare_mail;
465 }
466
467 static void
468 e_yahoo_backend_factory_class_finalize (EYahooBackendFactoryClass *class)
469 {
470 }
471
472 static void
473 e_yahoo_backend_factory_init (EYahooBackendFactory *factory)
474 {
475 }
476
477 G_MODULE_EXPORT void
478 e_module_load (GTypeModule *type_module)
479 {
480         e_yahoo_backend_register_type (type_module);
481         e_yahoo_backend_factory_register_type (type_module);
482 }
483
484 G_MODULE_EXPORT void
485 e_module_unload (GTypeModule *type_module)
486 {
487 }
488