/* * Copyright (C) 2008 Collabora Ltd. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * Authors: Jonny Lamb * */ #include #include #include #include #include #include #include #include #include "empathy-import-dialog.h" #define DEBUG_FLAG EMPATHY_DEBUG_OTHER #include typedef enum { EMPATHY_IMPORT_SETTING_TYPE_STRING, EMPATHY_IMPORT_SETTING_TYPE_BOOL, EMPATHY_IMPORT_SETTING_TYPE_INT, } EmpathyImportSettingType; typedef struct { gpointer value; EmpathyImportSettingType type; } EmpathyImportSetting; /* Pidgin to MC map */ typedef struct { gchar *protocol; gchar *pidgin_name; gchar *mc_name; } PidginMcMapItem; static PidginMcMapItem pidgin_mc_map[] = { { "msn", "server", "server" }, { "msn", "port", "port" }, { "jabber", "connect_server", "server" }, { "jabber", "port", "port" }, { "jabber", "require_tls", "require-encryption" }, { "jabber", "old_ssl", "old-ssl" }, { "aim", "server", "server" }, { "aim", "port", "port" }, { "salut", "first", "first-name" }, { "salut", "last", "last-name" }, { "salut", "jid", "jid" }, { "salut", "email", "email" }, { "groupwise", "server", "server" }, { "groupwise", "port", "port" }, { "icq", "server", "server" }, { "icq", "port", "port" }, { "irc", "realname", "fullname" }, { "irc", "ssl", "use-ssl" }, { "irc", "port", "port" }, { "yahoo", "server", "server" }, { "yahoo", "port", "port" }, { "yahoo", "xfer_port", "xfer-port" }, { "yahoo", "ignore_invites", "ignore-invites" }, { "yahoo", "yahoojp", "yahoojp" }, { "yahoo", "xferjp_host", "xferjp-host" }, { "yahoo", "serverjp", "serverjp" }, { "yahoo", "xfer_host", "xfer-host" }, }; typedef struct { GtkWidget *window; GtkWidget *label_select; GtkWidget *combo; } EmpathyImportDialog; #define PIDGIN_ACCOUNT_TAG_NAME "name" #define PIDGIN_ACCOUNT_TAG_ACCOUNT "account" #define PIDGIN_ACCOUNT_TAG_PROTOCOL "protocol" #define PIDGIN_ACCOUNT_TAG_PASSWORD "password" #define PIDGIN_ACCOUNT_TAG_SETTINGS "settings" #define PIDGIN_SETTING_PROP_TYPE "type" #define PIDGIN_PROTOCOL_BONJOUR "bonjour" #define PIDGIN_PROTOCOL_NOVELL "novell" static void empathy_import_dialog_add_setting (GHashTable *settings, gchar *key, gpointer value, EmpathyImportSettingType type); static gboolean empathy_import_dialog_add_account (gchar *protocol_name, GHashTable *settings); static void empathy_import_dialog_pidgin_parse_setting (gchar *protocol, xmlNodePtr setting, GHashTable *settings); static void empathy_import_dialog_pidgin_import_accounts (); static void empathy_import_dialog_response_cb (GtkDialog *dialog_window, gint response, EmpathyImportDialog *dialog); static void empathy_import_dialog_add_setting (GHashTable *settings, gchar *key, gpointer value, EmpathyImportSettingType type) { EmpathyImportSetting *set = g_slice_new0 (EmpathyImportSetting); set->value = value; set->type = type; g_hash_table_insert (settings, key, set); } static gboolean empathy_import_dialog_add_account (gchar *protocol_name, GHashTable *settings) { McProfile *profile; McAccount *account; gchar *key_char; GHashTableIter iter; gpointer key, value; EmpathyImportSetting *set; gchar *display_name; gchar *username; DEBUG ("Looking up profile with protocol '%s'", protocol_name); profile = mc_profile_lookup (protocol_name); if (profile == NULL) return FALSE; account = mc_account_create (profile); g_hash_table_iter_init (&iter, settings); while (g_hash_table_iter_next (&iter, &key, &value)) { set = (EmpathyImportSetting *) value; key_char = (gchar *) key; switch (((EmpathyImportSetting *) value)->type) { case EMPATHY_IMPORT_SETTING_TYPE_STRING: DEBUG ("Setting %s to (string) %s", key_char, (gchar *) set->value); mc_account_set_param_string (account, key_char, (gchar *) set->value); break; case EMPATHY_IMPORT_SETTING_TYPE_BOOL: DEBUG ("Setting %s to (bool) %i", key_char, (gboolean) set->value); mc_account_set_param_boolean (account, key_char, (gboolean) set->value); break; case EMPATHY_IMPORT_SETTING_TYPE_INT: DEBUG ("Setting %s to (int) %i", key_char, (gint) set->value); mc_account_set_param_int (account, key_char, (gint) set->value); break; } } mc_account_get_param_string (account, "account", &username); display_name = g_strdup_printf ("%s (%s)", username, mc_profile_get_display_name (profile)); mc_account_set_display_name (account, display_name); g_free (username); g_free (display_name); g_object_unref (account); g_object_unref (profile); return TRUE; } static void empathy_import_dialog_pidgin_parse_setting (gchar *protocol, xmlNodePtr setting, GHashTable *settings) { int i; if (!xmlHasProp (setting, PIDGIN_ACCOUNT_TAG_NAME)) return; for (i = 0; i < G_N_ELEMENTS (pidgin_mc_map); i++) { if (strcmp(protocol, pidgin_mc_map[i].protocol) != 0) continue; if (strcmp ((gchar *) xmlGetProp (setting, PIDGIN_ACCOUNT_TAG_NAME), pidgin_mc_map[i].pidgin_name) == 0) { gint arg; gchar *type = NULL; type = (gchar *) xmlGetProp (setting, PIDGIN_SETTING_PROP_TYPE); if (strcmp (type, "bool") == 0) { sscanf ((gchar *) xmlNodeGetContent (setting),"%i", &arg); empathy_import_dialog_add_setting (settings, pidgin_mc_map[i].mc_name, (gpointer) arg, EMPATHY_IMPORT_SETTING_TYPE_BOOL); } else if (strcmp (type, "int") == 0) { sscanf ((gchar *) xmlNodeGetContent (setting), "%i", &arg); empathy_import_dialog_add_setting (settings, pidgin_mc_map[i].mc_name, (gpointer) arg, EMPATHY_IMPORT_SETTING_TYPE_INT); } else if (strcmp (type, "string") == 0) { empathy_import_dialog_add_setting (settings, pidgin_mc_map[i].mc_name, (gpointer) xmlNodeGetContent (setting), EMPATHY_IMPORT_SETTING_TYPE_STRING); } } } } static void empathy_import_dialog_pidgin_import_accounts () { xmlNodePtr rootnode, node, child, setting; xmlParserCtxtPtr ctxt; xmlDocPtr doc; gchar *filename; gchar *protocol = NULL; gchar *name = NULL; gchar *username = NULL; GHashTable *settings; ctxt = xmlNewParserCtxt (); filename = g_build_filename (g_get_home_dir (), ".purple", "accounts.xml", NULL); doc = xmlCtxtReadFile (ctxt, filename, NULL, 0); g_free (filename); rootnode = xmlDocGetRootElement (doc); if (rootnode == NULL) return; node = rootnode->children; while (node) { if (strcmp ((gchar *) node->name, PIDGIN_ACCOUNT_TAG_ACCOUNT) == 0) { child = node->children; settings = g_hash_table_new (g_str_hash, g_str_equal); while (child) { if (strcmp ((gchar *) child->name, PIDGIN_ACCOUNT_TAG_PROTOCOL) == 0) { protocol = (gchar *) xmlNodeGetContent (child); if (g_str_has_prefix (protocol, "prpl-")) protocol = strchr (protocol, '-') + 1; if (strcmp (protocol, PIDGIN_PROTOCOL_BONJOUR) == 0) protocol = "salut"; else if (strcmp (protocol, PIDGIN_PROTOCOL_NOVELL) == 0) protocol = "groupwise"; empathy_import_dialog_add_setting (settings, "protocol", (gpointer) protocol, EMPATHY_IMPORT_SETTING_TYPE_STRING); } else if (strcmp ((gchar *) child->name, PIDGIN_ACCOUNT_TAG_NAME) == 0) { name = (gchar *) xmlNodeGetContent (child); if (g_strrstr (name, "/") != NULL) { gchar **name_resource; name_resource = g_strsplit (name, "/", 2); username = g_strdup(name_resource[0]); g_free (name_resource); } else username = name; if (strstr (name, "@") && strcmp (protocol, "irc") == 0) { gchar **nick_server; nick_server = g_strsplit (name, "@", 2); username = nick_server[0]; empathy_import_dialog_add_setting (settings, "server", (gpointer) nick_server[1], EMPATHY_IMPORT_SETTING_TYPE_STRING); } empathy_import_dialog_add_setting (settings, "account", (gpointer) username, EMPATHY_IMPORT_SETTING_TYPE_STRING); } else if (strcmp ((gchar *) child->name, PIDGIN_ACCOUNT_TAG_PASSWORD) == 0) { empathy_import_dialog_add_setting (settings, "password", (gpointer) xmlNodeGetContent (child), EMPATHY_IMPORT_SETTING_TYPE_STRING); } else if (strcmp ((gchar *) child->name, PIDGIN_ACCOUNT_TAG_SETTINGS) == 0) { setting = child->children; while (setting) { empathy_import_dialog_pidgin_parse_setting (protocol, setting, settings); setting = setting->next; } } child = child->next; } if (g_hash_table_size (settings) > 0) empathy_import_dialog_add_account (protocol, settings); g_free (username); g_hash_table_unref (settings); } node = node->next; } xmlFreeDoc(doc); xmlFreeParserCtxt (ctxt); } static void empathy_import_dialog_response_cb (GtkDialog *dialog_window, gint response, EmpathyImportDialog *dialog) { gchar *from = NULL; if (response == GTK_RESPONSE_OK) { from = gtk_combo_box_get_active_text (GTK_COMBO_BOX (dialog->combo)); if (strcmp (from, "Pidgin") == 0) empathy_import_dialog_pidgin_import_accounts (); } gtk_widget_hide (GTK_WIDGET (dialog_window)); } void empathy_import_dialog_show (GtkWindow *parent) { static EmpathyImportDialog *dialog = NULL; if (dialog) { gtk_window_present (GTK_WINDOW (dialog->window)); return; } dialog = g_slice_new0 (EmpathyImportDialog); dialog->window = gtk_dialog_new_with_buttons (_("Import accounts"), NULL, GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); g_signal_connect (G_OBJECT (dialog->window), "response", G_CALLBACK (empathy_import_dialog_response_cb), dialog); dialog->label_select = gtk_label_new ( _("Select the program to import accounts from:")); dialog->combo = gtk_combo_box_new_text (); gtk_combo_box_append_text (GTK_COMBO_BOX (dialog->combo), "Pidgin"); gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->combo), 0); gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (dialog->window)->vbox), dialog->label_select); gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (dialog->window)->vbox), dialog->combo); if (parent) gtk_window_set_transient_for (GTK_WINDOW (dialog->window), parent); gtk_widget_show_all (dialog->window); }