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