]> git.0d.be Git - empathy.git/blob - src/empathy-import-dialog.c
Name imported accounts in the same way as a new account does. (Jonny Lamb)
[empathy.git] / src / empathy-import-dialog.c
1 /*
2  * Copyright (C) 2008 Collabora Ltd.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
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  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public
15  * License along with this program; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  *
19  * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk>
20  * */
21
22 #include <config.h>
23
24 #include <string.h>
25
26 #include <glib.h>
27 #include <gtk/gtk.h>
28 #include <glib/gi18n.h>
29
30 #include <libxml/parser.h>
31 #include <libxml/tree.h>
32
33 #include <libmissioncontrol/mc-account.h>
34
35 #include "empathy-import-dialog.h"
36
37 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
38 #include <libempathy/empathy-debug.h>
39
40 typedef enum
41 {
42   EMPATHY_IMPORT_SETTING_TYPE_STRING,
43   EMPATHY_IMPORT_SETTING_TYPE_BOOL,
44   EMPATHY_IMPORT_SETTING_TYPE_INT,
45 } EmpathyImportSettingType;
46
47 typedef struct
48 {
49   gpointer     value;
50   EmpathyImportSettingType  type;
51 } EmpathyImportSetting;
52
53
54 /* Pidgin to MC map */
55 typedef struct
56 {
57   gchar *protocol;
58   gchar *pidgin_name;
59   gchar *mc_name;
60 } PidginMcMapItem;
61
62 static PidginMcMapItem pidgin_mc_map[] =
63 {
64   { "msn", "server", "server" },
65   { "msn", "port", "port" },
66
67   { "jabber", "connect_server", "server" },
68   { "jabber", "port", "port" },
69   { "jabber", "require_tls", "require-encryption" },
70   { "jabber", "old_ssl", "old-ssl" },
71
72   { "aim", "server", "server" },
73   { "aim", "port", "port" },
74
75   { "salut", "first", "first-name" },
76   { "salut", "last", "last-name" },
77   { "salut", "jid", "jid" },
78   { "salut", "email", "email" },
79
80   { "groupwise", "server", "server" },
81   { "groupwise", "port", "port" },
82
83   { "icq", "server", "server" },
84   { "icq", "port", "port" },
85
86   { "irc", "realname", "fullname" },
87   { "irc", "ssl", "use-ssl" },
88   { "irc", "port", "port" },
89
90   { "yahoo", "server", "server" },
91   { "yahoo", "port", "port" },
92   { "yahoo", "xfer_port", "xfer-port" },
93   { "yahoo", "ignore_invites", "ignore-invites" },
94   { "yahoo", "yahoojp", "yahoojp" },
95   { "yahoo", "xferjp_host", "xferjp-host" },
96   { "yahoo", "serverjp", "serverjp" },
97   { "yahoo", "xfer_host", "xfer-host" },
98 };
99
100 typedef struct
101 {
102   GtkWidget *window;
103   GtkWidget *label_select;
104   GtkWidget *combo;
105 } EmpathyImportDialog;
106
107 #define PIDGIN_ACCOUNT_TAG_NAME "name"
108 #define PIDGIN_ACCOUNT_TAG_ACCOUNT "account"
109 #define PIDGIN_ACCOUNT_TAG_PROTOCOL "protocol"
110 #define PIDGIN_ACCOUNT_TAG_PASSWORD "password"
111 #define PIDGIN_ACCOUNT_TAG_SETTINGS "settings"
112 #define PIDGIN_SETTING_PROP_TYPE "type"
113 #define PIDGIN_PROTOCOL_BONJOUR "bonjour"
114 #define PIDGIN_PROTOCOL_NOVELL "novell"
115
116 static void empathy_import_dialog_add_setting (GHashTable *settings,
117     gchar *key, gpointer value, EmpathyImportSettingType  type);
118 static gboolean empathy_import_dialog_add_account (gchar *protocol_name,
119     GHashTable *settings);
120 static void empathy_import_dialog_pidgin_parse_setting (gchar *protocol,
121     xmlNodePtr setting, GHashTable *settings);
122 static void empathy_import_dialog_pidgin_import_accounts ();
123 static void empathy_import_dialog_response_cb (GtkDialog *dialog_window,
124     gint response, EmpathyImportDialog *dialog);
125
126 static void
127 empathy_import_dialog_add_setting (GHashTable *settings,
128                                    gchar *key,
129                                    gpointer value,
130                                    EmpathyImportSettingType type)
131 {
132   EmpathyImportSetting *set = g_slice_new0 (EmpathyImportSetting);
133
134   set->value = value;
135   set->type = type;
136
137   g_hash_table_insert (settings, key, set);
138 }
139
140 static gboolean
141 empathy_import_dialog_add_account (gchar *protocol_name,
142                                    GHashTable *settings)
143 {
144   McProfile *profile;
145   McAccount *account;
146   gchar *key_char;
147   GHashTableIter iter;
148   gpointer key, value;
149   EmpathyImportSetting *set;
150   gchar *display_name;
151   gchar *username;
152
153   DEBUG ("Looking up profile with protocol '%s'", protocol_name);
154   profile = mc_profile_lookup (protocol_name);
155
156   if (profile == NULL)
157     return FALSE;
158
159   account = mc_account_create (profile);
160
161   g_hash_table_iter_init (&iter, settings);
162   while (g_hash_table_iter_next (&iter, &key, &value))
163     {
164       set = (EmpathyImportSetting *) value;
165       key_char = (gchar *) key;
166       switch (((EmpathyImportSetting *) value)->type)
167         {
168           case EMPATHY_IMPORT_SETTING_TYPE_STRING:
169             DEBUG ("Setting %s to (string) %s",
170                 key_char, (gchar *) set->value);
171             mc_account_set_param_string (account,
172                 key_char, (gchar *) set->value);
173             break;
174
175           case EMPATHY_IMPORT_SETTING_TYPE_BOOL:
176             DEBUG ("Setting %s to (bool) %i",
177                 key_char, (gboolean) set->value);
178             mc_account_set_param_boolean (account,
179                 key_char, (gboolean) set->value);
180             break;
181
182           case EMPATHY_IMPORT_SETTING_TYPE_INT:
183             DEBUG ("Setting %s to (int) %i",
184                 key_char, (gint) set->value);
185             mc_account_set_param_int (account,
186                 key_char, (gint) set->value);
187             break;
188         }
189     }
190
191   mc_account_get_param_string (account, "account", &username);
192   display_name = g_strdup_printf ("%s (%s)", username,
193       mc_profile_get_display_name (profile));
194   mc_account_set_display_name (account, display_name);
195
196   g_free (username);
197   g_free (display_name);
198   g_object_unref (account);
199   g_object_unref (profile);
200   return TRUE;
201 }
202
203 static void
204 empathy_import_dialog_pidgin_parse_setting (gchar *protocol,
205                                             xmlNodePtr setting,
206                                             GHashTable *settings)
207 {
208   int i;
209
210   if (!xmlHasProp (setting, PIDGIN_ACCOUNT_TAG_NAME))
211     return;
212
213   for (i = 0; i < G_N_ELEMENTS (pidgin_mc_map); i++)
214     {
215       if (strcmp(protocol, pidgin_mc_map[i].protocol) != 0)
216         continue;
217
218       if (strcmp ((gchar *) xmlGetProp (setting, PIDGIN_ACCOUNT_TAG_NAME),
219         pidgin_mc_map[i].pidgin_name) == 0)
220         {
221           gint arg;
222           gchar *type = NULL;
223
224           type = (gchar *) xmlGetProp (setting, PIDGIN_SETTING_PROP_TYPE);
225
226           if (strcmp (type, "bool") == 0)
227             {
228               sscanf ((gchar *) xmlNodeGetContent (setting),"%i", &arg);
229               empathy_import_dialog_add_setting (settings,
230                   pidgin_mc_map[i].mc_name,
231                   (gpointer) arg,
232                   EMPATHY_IMPORT_SETTING_TYPE_BOOL);
233             }
234           else if (strcmp (type, "int") == 0)
235             {
236               sscanf ((gchar *) xmlNodeGetContent (setting),
237                   "%i", &arg);
238               empathy_import_dialog_add_setting (settings,
239                   pidgin_mc_map[i].mc_name,
240                   (gpointer) arg,
241                   EMPATHY_IMPORT_SETTING_TYPE_INT);
242             }
243           else if (strcmp (type, "string") == 0)
244             {
245               empathy_import_dialog_add_setting (settings,
246                   pidgin_mc_map[i].mc_name,
247                   (gpointer) xmlNodeGetContent (setting),
248                   EMPATHY_IMPORT_SETTING_TYPE_STRING);
249             }
250         }
251     }
252 }
253
254 static void
255 empathy_import_dialog_pidgin_import_accounts ()
256 {
257   xmlNodePtr rootnode, node, child, setting;
258   xmlParserCtxtPtr ctxt;
259   xmlDocPtr doc;
260   gchar *filename;
261   gchar *protocol = NULL;
262   gchar *name = NULL;
263   gchar *username = NULL;
264   GHashTable *settings;
265
266   ctxt = xmlNewParserCtxt ();
267   filename = g_build_filename (g_get_home_dir (), ".purple", "accounts.xml",
268       NULL);
269   doc = xmlCtxtReadFile (ctxt, filename, NULL, 0);
270   g_free (filename);
271
272   rootnode = xmlDocGetRootElement (doc);
273   if (rootnode == NULL)
274     return;
275
276   node = rootnode->children;
277   while (node)
278     {
279       if (strcmp ((gchar *) node->name, PIDGIN_ACCOUNT_TAG_ACCOUNT) == 0)
280         {
281           child = node->children;
282
283           settings = g_hash_table_new (g_str_hash, g_str_equal);
284
285           while (child)
286             {
287
288               if (strcmp ((gchar *) child->name,
289                   PIDGIN_ACCOUNT_TAG_PROTOCOL) == 0)
290                 {
291                   protocol = (gchar *) xmlNodeGetContent (child);
292
293                   if (g_str_has_prefix (protocol, "prpl-"))
294                     protocol = strchr (protocol, '-') + 1;
295
296                   if (strcmp (protocol, PIDGIN_PROTOCOL_BONJOUR) == 0)
297                     protocol = "salut";
298                   else if (strcmp (protocol, PIDGIN_PROTOCOL_NOVELL) == 0)
299                     protocol = "groupwise";
300
301                   empathy_import_dialog_add_setting (settings, "protocol",
302                       (gpointer) protocol,
303                       EMPATHY_IMPORT_SETTING_TYPE_STRING);
304
305                 }
306               else if (strcmp ((gchar *) child->name,
307                   PIDGIN_ACCOUNT_TAG_NAME) == 0)
308                 {
309                   name = (gchar *) xmlNodeGetContent (child);
310
311                   if (g_strrstr (name, "/") != NULL)
312                     {
313                       gchar **name_resource;
314                       name_resource = g_strsplit (name, "/", 2);
315                       username = g_strdup(name_resource[0]);
316                       g_free (name_resource);
317                     }
318                   else
319                     username = name;
320
321                  if (strstr (name, "@") && strcmp (protocol, "irc") == 0)
322                   {
323                     gchar **nick_server;
324                     nick_server = g_strsplit (name, "@", 2);
325                     username = nick_server[0];
326                     empathy_import_dialog_add_setting (settings,
327                         "server", (gpointer) nick_server[1],
328                         EMPATHY_IMPORT_SETTING_TYPE_STRING);
329                   }
330
331                   empathy_import_dialog_add_setting (settings, "account",
332                       (gpointer) username, EMPATHY_IMPORT_SETTING_TYPE_STRING);
333
334                 }
335               else if (strcmp ((gchar *) child->name,
336                   PIDGIN_ACCOUNT_TAG_PASSWORD) == 0)
337                 {
338                   empathy_import_dialog_add_setting (settings, "password",
339                       (gpointer) xmlNodeGetContent (child),
340                       EMPATHY_IMPORT_SETTING_TYPE_STRING);
341
342                 }
343               else if (strcmp ((gchar *) child->name,
344                   PIDGIN_ACCOUNT_TAG_SETTINGS) == 0)
345                 {
346                   setting = child->children;
347
348                   while (setting)
349                     {
350                       empathy_import_dialog_pidgin_parse_setting (protocol,
351                           setting, settings);
352                           setting = setting->next;
353                     }
354
355                 }
356               child = child->next;
357             }
358
359           if (g_hash_table_size (settings) > 0)
360               empathy_import_dialog_add_account (protocol, settings);
361
362           g_free (username);
363           g_hash_table_unref (settings);
364         }
365
366       node = node->next;
367     }
368
369   xmlFreeDoc(doc);
370   xmlFreeParserCtxt (ctxt);
371 }
372
373 static void
374 empathy_import_dialog_response_cb (GtkDialog *dialog_window,
375                                    gint response,
376                                    EmpathyImportDialog *dialog)
377 {
378   gchar *from = NULL;
379   if (response == GTK_RESPONSE_OK)
380     {
381       from = gtk_combo_box_get_active_text (GTK_COMBO_BOX (dialog->combo));
382
383       if (strcmp (from, "Pidgin") == 0)
384         empathy_import_dialog_pidgin_import_accounts ();
385     }
386
387   gtk_widget_destroy (GTK_WIDGET (dialog_window));
388   g_slice_free (EmpathyImportDialog, dialog);
389 }
390
391 void
392 empathy_import_dialog_show (GtkWindow *parent)
393 {
394   EmpathyImportDialog *dialog;
395
396   dialog = g_slice_new0 (EmpathyImportDialog);
397
398   dialog->window = gtk_dialog_new_with_buttons (_("Import accounts"),
399       NULL,
400       GTK_DIALOG_MODAL,
401       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
402       GTK_STOCK_OK, GTK_RESPONSE_OK,
403       NULL);
404
405   g_signal_connect (G_OBJECT (dialog->window), "response",
406       G_CALLBACK (empathy_import_dialog_response_cb),
407       dialog);
408
409   dialog->label_select = gtk_label_new (
410       _("Select the program to import accounts from:"));
411
412   dialog->combo = gtk_combo_box_new_text ();
413
414   gtk_combo_box_append_text (GTK_COMBO_BOX (dialog->combo), "Pidgin");
415   gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->combo), 0);
416
417   gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (dialog->window)->vbox),
418       dialog->label_select);
419
420   gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (dialog->window)->vbox),
421       dialog->combo);
422
423
424   if (parent)
425     gtk_window_set_transient_for (GTK_WINDOW (dialog->window), parent);
426
427   gtk_widget_show_all (dialog->window);
428 }