diff -Npur evolution-3.10.2-old/mail/importers/kmail-importer.c evolution-3.10.2-new/mail/importers/kmail-importer.c --- evolution-3.10.2-old/mail/importers/kmail-importer.c 1970-01-01 08:00:00.000000000 +0800 +++ evolution-3.10.2-new/mail/importers/kmail-importer.c 2014-01-21 16:06:07.368848069 +0800 @@ -0,0 +1,372 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + * + * Authors: + * Iain Holmes + * Michael Zucchi + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "kmail-libs.h" +#include "mail-importer.h" + +#include "libemail-engine/mail-mt.h" +#include "mail/e-mail-backend.h" +#include "e-util/e-util.h" +#include "shell/e-shell.h" +#include "shell/e-shell-window.h" +#include "shell/e-shell-view.h" +#include "shell/e-shell-sidebar.h" + +#include "mail/e-mail-backend.h" +#include "mail/em-folder-selection-button.h" +#include "mail/em-folder-tree-model.h" +#include "mail/em-folder-tree.h" +#include "libemail-engine/mail-mt.h" + +#define ENABLE_SELECT 0 +#define d(x) + + +typedef struct { + EImport *import; + EImportTarget *target; + + GMutex *status_lock; + gchar *status_what; + gint status_pc; + gint status_timeout_id; + GCancellable *cancellable; /* cancel/status port */ + + gchar *uri; +} MaildirImporter; + +static gboolean +kmail_supported (EImport *ei, + EImportTarget *target, + EImportImporter *im) +{ + return is_kmail_supported (); +} + +static MailImporterSpecial kmail_special_folders[] = { + { "received", "Inbox" }, + { NULL }, +}; + +static void +maildir_import_done (gpointer data, + GError **error) +{ + MaildirImporter *importer = data; + + g_source_remove (importer->status_timeout_id); + if (importer->status_what) + g_free (importer->status_what); + g_mutex_free (importer->status_lock); + g_object_unref (importer->cancellable); + + e_import_complete (importer->import, importer->target); + g_free (importer); +} + +static void +maildir_status (CamelOperation *op, + const gchar *what, + gint pc, + gpointer data) +{ + MaildirImporter *importer = data; + g_mutex_lock (importer->status_lock); + g_free (importer->status_what); + importer->status_what = g_strdup (what); + importer->status_pc = pc; + g_mutex_unlock (importer->status_lock); +} + +static gboolean +maildir_status_timeout (gpointer data) +{ + MaildirImporter *importer = data; + gint pc; + gchar *what; + if (importer->status_what) { + g_mutex_lock (importer->status_lock); + what = importer->status_what; + importer->status_what = NULL; + pc = importer->status_pc; + g_mutex_unlock (importer->status_lock); + + e_import_status ( + importer->import, (EImportTarget *) + importer->target, what, pc); + } + + return TRUE; +} + +static void +checkbox_toggle_cb (GtkToggleButton *tb, + EImportTarget *target) +{ + g_datalist_set_data ( + &target->data, "kmail-do-mail", + GINT_TO_POINTER (gtk_toggle_button_get_active (tb))); +} + +#if ENABLE_SELECT +static void +folder_selected (EMFolderSelectionButton *button, + EImportTargetURI *target) +{ + if (target->uri_dest) + g_free (target->uri_dest); + target->uri_dest = g_strdup (em_folder_selection_button_get_folder_uri (button)); +} + + +static GtkWidget * +import_folder_getwidget (EImport *ei, + EImportTarget *target, + EImportImporter *im) +{ + EShell *shell; + EShellBackend *shell_backend; + EMailBackend *backend; + EMailSession *session; + GtkWindow *window; + GtkWidget *hbox, *w; + GtkLabel *label; + gchar *select_uri = NULL; + + /* XXX Dig up the mail backend from the default EShell. + * Since the EImport framework doesn't allow for user + * data, I don't see how else to get to it. */ + shell = e_shell_get_default (); + shell_backend = e_shell_get_backend_by_name (shell, "mail"); + + backend = E_MAIL_BACKEND (shell_backend); + session = e_mail_backend_get_session (backend); + + /* preselect the folder selected in a mail view */ + window = e_shell_get_active_window (shell); + if (E_IS_SHELL_WINDOW (window)) { + EShellWindow *shell_window; + const gchar *view; + + shell_window = E_SHELL_WINDOW (window); + view = e_shell_window_get_active_view (shell_window); + + if (view && g_str_equal (view, "mail")) { + EShellView *shell_view; + EShellSidebar *shell_sidebar; + EMFolderTree *folder_tree = NULL; + + shell_view = e_shell_window_get_shell_view ( + shell_window, view); + + shell_sidebar = + e_shell_view_get_shell_sidebar (shell_view); + + g_object_get ( + shell_sidebar, "folder-tree", + &folder_tree, NULL); + + select_uri = + em_folder_tree_get_selected_uri (folder_tree); + + g_object_unref (folder_tree); + } + } + + if (!select_uri) { + const gchar *uri; + uri = e_mail_session_get_local_folder_uri ( + session, E_MAIL_LOCAL_FOLDER_INBOX); + select_uri = g_strdup (uri); + } + + hbox = gtk_hbox_new (FALSE, 0); + + w = gtk_label_new_with_mnemonic (_("_Destination folder:")); + gtk_box_pack_start ((GtkBox *) hbox, w, FALSE, TRUE, 6); + + label = GTK_LABEL (w); + + w = em_folder_selection_button_new ( + session, _("Select folder"), + _("Select folder to import into")); + gtk_label_set_mnemonic_widget (label, w); + em_folder_selection_button_set_folder_uri ( + EM_FOLDER_SELECTION_BUTTON (w), select_uri); + folder_selected ( + EM_FOLDER_SELECTION_BUTTON (w), (EImportTargetURI *) target); + g_signal_connect ( + w, "selected", + G_CALLBACK (folder_selected), target); + gtk_box_pack_start ((GtkBox *) hbox, w, FALSE, TRUE, 6); + + w = gtk_vbox_new (FALSE, 0); + gtk_box_pack_start ((GtkBox *) w, hbox, FALSE, FALSE, 0); + gtk_widget_show_all (w); + + g_free (select_uri); + + return w; +} +#endif + +static GtkWidget * +kmail_getwidget (EImport *ei, + EImportTarget *target, + EImportImporter *im) +{ + GtkWidget *box, *w; + GSList *contact_list; + gint count; + gchar *contact_str; + + + g_datalist_set_data ( + &target->data, "kmail-do-mail", GINT_TO_POINTER (TRUE)); + + box = gtk_vbox_new (FALSE, 2); + + w = gtk_check_button_new_with_label (_("Mail")); + gtk_toggle_button_set_active ((GtkToggleButton *) w, TRUE); + g_signal_connect ( + w, "toggled", + G_CALLBACK (checkbox_toggle_cb), target); + + gtk_box_pack_start ((GtkBox *) box, w, FALSE, FALSE, 0); + + /*TODO: this should merget to the target struct */ + contact_list = get_kcontact_list (); + count = g_slist_length (contact_list); + contact_str = g_strdup_printf (_("%d Address"), count); + w = gtk_check_button_new_with_label (contact_str); + gtk_toggle_button_set_active ((GtkToggleButton *) w, TRUE); + g_signal_connect ( + w, "toggled", + G_CALLBACK (checkbox_toggle_cb), target); + + gtk_box_pack_start ((GtkBox *) box, w, FALSE, FALSE, 0); + +/* for now, we don't allow to select a folder */ +#if ENABLE_SELECT + w = import_folder_getwidget (ei, target, im); + gtk_box_pack_start ((GtkBox *) box, w, FALSE, FALSE, 0); +#endif + + gtk_widget_show_all (box); + g_slist_free_full (contact_list, g_free); + g_free (contact_str); + + return box; +} + +static void +kmail_import (EImport *ei, + EImportTarget *target, + EImportImporter *im) +{ + EShell *shell; + EShellBackend *shell_backend; + EMailSession *session; + MaildirImporter *importer; + gchar *path; + GSList *contact_list; + + /* XXX Dig up the EMailSession from the default EShell. + * Since the EImport framework doesn't allow for user + * data, I don't see how else to get to it. */ + shell = e_shell_get_default (); + shell_backend = e_shell_get_backend_by_name (shell, "mail"); + session = e_mail_backend_get_session (E_MAIL_BACKEND (shell_backend)); + + /* TODO: do we validate target? */ + importer = g_malloc0 (sizeof (*importer)); + g_datalist_set_data (&target->data, "maildir-data", importer); + importer->status_what = NULL; + importer->import = ei; + importer->target = target; + importer->cancellable = camel_operation_new (); + importer->status_lock = g_mutex_new (); + importer->status_timeout_id = g_timeout_add (100, maildir_status_timeout, importer); + + g_signal_connect ( + importer->cancellable, "status", + G_CALLBACK (maildir_status), importer); + + /* import emails */ + path = get_kmail_base_dir (); + mail_importer_import_maildir ( + session, path, NULL, + importer->cancellable, maildir_import_done, importer); + g_free (path); + + /* import contacts */ + + contact_list = get_kcontact_list (); + load_kcontact (contact_list); + g_slist_free_full (contact_list, g_free); +} + +static void +kmail_cancel (EImport *ei, + EImportTarget *target, + EImportImporter *im) +{ + MaildirImporter *m = g_datalist_get_data (&target->data, "maildir-data"); + + if (m) + g_cancellable_cancel (m->cancellable); +} + +static EImportImporter kmail_importer = { + E_IMPORT_TARGET_HOME, + 0, + kmail_supported, + kmail_getwidget, + kmail_import, + kmail_cancel, + NULL, /* get_preview */ +}; + +EImportImporter * +kmail_importer_peek (void) +{ + kmail_importer.name = _("Evolution Kmail importer"); + kmail_importer.description = _("Import mail from Kmail."); + + return &kmail_importer; +} diff -Npur evolution-3.10.2-old/mail/importers/kmail-libs.c evolution-3.10.2-new/mail/importers/kmail-libs.c --- evolution-3.10.2-old/mail/importers/kmail-libs.c 1970-01-01 08:00:00.000000000 +0800 +++ evolution-3.10.2-new/mail/importers/kmail-libs.c 2014-01-22 14:34:21.370733525 +0800 @@ -0,0 +1,499 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + + +#include "kmail-libs.h" + +const CamelStore * +evolution_get_local_store () +{ + EShell *shell; + EShellBackend *shell_backend; + EMailBackend *backend; + EMailSession *session; + static CamelStore *local_store = NULL; + + if (local_store) + return local_store; + /* XXX Dig up the mail backend from the default EShell. + * Since the EImport framework doesn't allow for user + * data, I don't see how else to get to it. */ + shell = e_shell_get_default (); + shell_backend = e_shell_get_backend_by_name (shell, "mail"); + + backend = E_MAIL_BACKEND (shell_backend); + session = e_mail_backend_get_session (backend); + + local_store = e_mail_session_get_local_store (session); +//FIXME: need to unref all the objects + return local_store; +} + +gboolean +is_kmail_box (const gchar *k_folder) +{ + const gchar *special_folders []= {"cur", "tmp", "new", NULL}; + gchar *source_dir; + GDir *dir; + gint i; + + for (i = 0; special_folders[i]; i++) { + source_dir = g_build_filename (k_folder, special_folders[i], NULL); + dir = g_dir_open (source_dir, 0, NULL); + if (!dir) { + /*If we did not find the subdir with 'cur' 'tmp' and 'new', + we don't take it as the kmail box */ + g_free (source_dir); + return FALSE; + } + g_dir_close (dir); + g_free (source_dir); + } + + /*No matter whether the folder was empty, we return it to the importer */ + return TRUE; +} + +gboolean +is_kmail_directory (const gchar *folder) +{ + if (g_str_has_prefix (folder, ".") && g_str_has_suffix (folder, ".directory")) + return TRUE; + else + return FALSE; +} + +gchar * +get_kmail_base_dir () +{ + gchar *base_dir; + + base_dir = g_build_filename (g_get_home_dir (), KMAIL_4_3_DIR, NULL); + + return base_dir; +} + +gchar * +kuri_to_euri (const gchar *k_uri) +{ +/* +/home/ktoe/.local/share/local-mail/.inbox.directory/.aaaa.directory + folder://local/inbox/aaaa +*/ + gchar *base_dir; + gchar *p; + gchar **folders; + GString *e_folder = NULL; + gchar *val; + gint i; + gboolean dropped = FALSE; + + e_folder = g_string_new (EVOLUTION_LOCAL_BASE); + base_dir = g_build_filename (g_get_home_dir (), KMAIL_4_3_DIR, NULL); + p = (gchar *) k_uri + strlen (base_dir) + 1; + folders = g_strsplit (p, "/", -1); + + for (i = 0; folders[i]; i++) { + gchar *folder = folders[i]; + if (g_str_has_prefix (folder, ".") && g_str_has_suffix (folder, ".directory")) { + folder ++; + p = g_strrstr (folder, ".directory"); + *p = '\0'; + } + if (i == 0) { + /*Some local folders*/ + if ((strcasecmp (folder, "Inbox") == 0) || (strcmp (folder, _("Inbox")) == 0)) { + folder = (gchar *)"Inbox"; + } else if ((strcasecmp (folder, "Outbox") == 0) || (strcmp (folder, _("Outbox")) == 0)) { + folder = (gchar *)"Outbox"; + } else if ((strcasecmp (folder, "sent-mail") == 0) || (strcmp (folder, _("Sent")) == 0)) { + folder = (gchar *)"Sent"; + } else if ((strcasecmp (folder, "drafts") == 0) || (strcmp (folder, _("Drafts")) == 0)) { + folder = (gchar *)"Drafts"; + } else if ((strcasecmp (folder, "templates") == 0) || (strcmp (folder, _("Templates")) == 0)) { + folder = (gchar *)"Templates"; + break; + } else if ((strcasecmp (folder, "trash") == 0) || (strcmp (folder, _("Trash")) == 0)) { + dropped = TRUE; + break; + } + } + g_string_append_printf (e_folder, "/%s", folder); + } + + if (dropped) { + val = NULL; + g_string_free (e_folder, TRUE); + } else { + val = e_folder->str; + g_string_free (e_folder, FALSE); + } + g_strfreev (folders); + return val; +} + +#if 0 +gchar * +get_real_evolution_folder (gchar *e_folder) +{ +/*FIXME: i18n? + evolution bug: for example: _(inbox) is 收件箱 + if we create inbox, it is not allowed, + if we create 收件箱, that is OK +*/ +/* "folder://local/Inbox" -- /home/ktoe/.local/share/evolution/mail/local + "folder://local/Inbox/aaaa" -- /home/ktoe/.local/share/evolution/mail/local/..aaaa + "folder://local/Inbox/aaaa/bb" -- /home/ktoe/.local/share/evolution/mail/local/..aaaa.bb + "folder://local/Inbox/fs" -- /home/ktoe/.local/share/evolution/mail/local/.fs + "folder://local/Outbox" -- /home/ktoe/.local/share/evolution/mail/local/.Outbox + "folder://local/Outbox/ba -- /home/ktoe/.local/share/evolution/mail/local/.Outbox.ba + "folder://local/aa/ba -- /home/ktoe/.local/share/evolution/mail/local/.aa.ba +*/ + GString *real_e_folder = NULL; + gchar *base_dir; + gchar *val; + gchar **folders; + gchar *p; + gint i; + gboolean is_in_inbox = FALSE; + gboolean dropped = FALSE; + + base_dir = g_build_filename (g_get_home_dir (), EVOLUTION_DIR, NULL); + real_e_folder = g_string_new (base_dir); + p = e_folder + strlen (EVOLUTION_LOCAL_BASE) + 1; + + folders = g_strsplit (p, "/", -1); + + for (i = 0; folders[i]; i++) { + const gchar *folder = folders[i]; + if (i == 0) { + /*Sometimes, the kmail po is different with evolution po, there is no way other than fix in i18n... */ + if ((strcasecmp (folder, "Inbox") == 0) || (strcmp (folder, _("Inbox")) == 0)) { + is_in_inbox = TRUE; + continue; + } else if ((strcasecmp (folder, "Outbox") == 0) || (strcmp (folder, _("Outbox")) == 0)) { + folder = "Outbox"; + } else if ((strcasecmp (folder, "sent-mail") == 0) || (strcmp (folder, _("Sent")) == 0)) { + folder = "Sent"; + } else if ((strcasecmp (folder, "drafts") == 0) || (strcmp (folder, _("Drafts")) == 0)) { + folder = "Drafts"; + } else if ((strcasecmp (folder, "templates") == 0) || (strcmp (folder, _("Templates")) == 0)) { + dropped = TRUE; + break; + } else if ((strcasecmp (folder, "trash") == 0) || (strcmp (folder, _("Trash")) == 0)) { + dropped = TRUE; + break; + } + } else { + if (is_in_inbox) { + g_string_append (real_e_folder, "."); + } + is_in_inbox = FALSE; + } + if (!is_in_inbox) + g_string_append_printf (real_e_folder, ".%s", folder); + } + + g_free (base_dir); + if (dropped) { + val = NULL; + g_string_free (real_e_folder, TRUE); + } else { + val = real_e_folder->str; + g_string_free (real_e_folder, FALSE); + } + g_strfreev (folders); + + return val; +} +#endif + +GSList * +read_kmail_folder (const gchar *path, GSList *kmail_list) +{ + GDir *dir; + gchar *filename; + const gchar *d; + struct stat st; + + dir = g_dir_open (path, 0, NULL); + + while ((d = g_dir_read_name (dir))) { + if ((strcmp (d, ".") == 0) || (strcmp (d, "..") == 0)) { + continue; + } + + filename = g_build_filename (path, d, NULL); + /* skip non files and directories, and skip directories in mozilla mode */ + if (g_stat (filename, &st) == -1) { + g_free (filename); + continue; + } + if (S_ISDIR (st.st_mode)) { + if (is_kmail_directory (d)) { + kmail_list = read_kmail_folder (filename, kmail_list); + } else if (is_kmail_box (filename)) { + kmail_list = g_slist_prepend (kmail_list, g_strdup (filename)); + } + } + g_free (filename); + } + g_dir_close (dir); + + return kmail_list; +} + +GSList * +get_kmail_folders (gchar *path) +{ + GSList *list = NULL; + + list = read_kmail_folder (path, list); + + return list; +} + +/* Copied from camel_strstrcase */ +static gchar * +eab_strstrcase (const gchar *haystack, + const gchar *needle) +{ + /* find the needle in the haystack neglecting case */ + const gchar *ptr; + guint len; + + g_return_val_if_fail (haystack != NULL, NULL); + g_return_val_if_fail (needle != NULL, NULL); + + len = strlen (needle); + if (len > strlen (haystack)) + return NULL; + + if (len == 0) + return (gchar *) haystack; + + for (ptr = haystack; *(ptr + len - 1) != '\0'; ptr++) + if (!g_ascii_strncasecmp (ptr, needle, len)) + return (gchar *) ptr; + + return NULL; +} + +static GSList * +eab_contact_list_from_string (const gchar *str) +{ + GSList *contacts = NULL; + GString *gstr = g_string_new (NULL); + gchar *str_stripped; + gchar *p = (gchar *) str; + gchar *q; + if (!p) + return NULL; + + if (!strncmp (p, "Book: ", 6)) { + p = strchr (p, '\n'); + if (!p) { + g_warning (G_STRLOC ": Got book but no newline!"); + return NULL; + } + p++; + } + + while (*p) { + if (*p != '\r') g_string_append_c (gstr, *p); + + p++; + } + + p = str_stripped = g_string_free (gstr, FALSE); + + for (p = eab_strstrcase (p, "BEGIN:VCARD"); p; p = eab_strstrcase (q, "\nBEGIN:VCARD")) { + gchar *card_str; + + if (*p == '\n') + p++; + + for (q = eab_strstrcase (p, "END:VCARD"); q; q = eab_strstrcase (q, "END:VCARD")) { + gchar *temp; + + q += 9; + temp = q; + if (*temp) + temp += strspn (temp, "\r\n\t "); + + if (*temp == '\0' || !g_ascii_strncasecmp (temp, "BEGIN:VCARD", 11)) + break; /* Found the outer END:VCARD */ + } + + if (!q) + break; + card_str = g_strndup (p, q - p); + contacts = g_slist_prepend (contacts, e_contact_new_from_vcard (card_str)); + g_free (card_str); + } + + g_free (str_stripped); + + return g_slist_reverse (contacts); +} + +static gchar * +get_kcontact_folder (void) +{ + gchar *folder; + + folder = g_build_filename (g_get_home_dir (), KCONTACT_4_3_DIR, NULL); + + return folder; +} + +GSList * +get_kcontact_list (void) +{ + GSList *list = NULL; + gchar *foldername = NULL; + gchar *filename; + const gchar *d; + GDir *dir; + struct stat st; + + foldername = get_kcontact_folder (); + if (!foldername) + return NULL; + dir = g_dir_open (foldername, 0, NULL); + + while ((d = g_dir_read_name (dir))) { + if ((strcmp (d, ".") == 0) || (strcmp (d, "..") == 0)) { + continue; + } + if (!g_str_has_suffix (d, ".vcf")) { + continue; + } + filename = g_build_filename (foldername, d, NULL); + if (g_stat (filename, &st) == -1) { + g_free (filename); + continue; + } + if (S_ISREG (st.st_mode)) { + list = g_slist_prepend (list, filename); + } + } + + g_free (foldername); + g_dir_close (dir); + + return list; +} + +void +load_kcontact (GSList *files) +{ + GList *source_list; + GSList *contactlist = NULL; + GSList *l; + + GError *error = NULL; + GString *vcards = NULL; + EBookClient *book_client; + EShell *shell; + ESourceRegistry *registry; + ESource *primary; + + if (!files) + return; + + shell = e_shell_get_default (); + registry = e_shell_get_registry (shell); + + source_list = e_source_registry_list_sources (registry, E_SOURCE_EXTENSION_ADDRESS_BOOK); + if (source_list != NULL) { + primary = g_object_ref (source_list->data); + g_list_free_full (source_list, (GDestroyNotify) g_object_unref); + } else { + printf ("Source list is empty\n"); + return; + } + + book_client = e_book_client_new (primary, NULL); + + for (l = files; l; l = l->next) { + const gchar *filename; + gchar *contents = NULL; + + filename = (gchar *) l->data; + if (g_file_get_contents (filename, &contents, NULL, NULL)) { + if (vcards == NULL) { + vcards = g_string_new (contents); + } else { + g_string_append_c (vcards, '\n'); + g_string_append (vcards, contents); + } + g_free (contents); + } + } + + if (vcards) { + /*WARNING: eab_contact_list_from_string did not recognize all the contacts. + so, maybe I should add contact from file one by one. + */ + contactlist = eab_contact_list_from_string (vcards->str); + } + + if (contactlist) { + e_book_client_add_contacts_sync (book_client, contactlist, NULL, NULL, &error); + if (error) { + printf ("error is %s\n", error->message); + g_error_free (error); + } + } + + if (vcards) + g_string_free (vcards, TRUE); + if (contactlist) + e_client_util_free_object_slist (contactlist); + g_object_unref (primary); + g_object_unref (book_client); +} + +gboolean +is_kmail_supported (void) +{ + gchar *kmaildir; + gboolean exists; + + kmaildir = g_build_filename (g_get_home_dir (), KMAIL_4_3_DIR, NULL); + exists = g_file_test (kmaildir, G_FILE_TEST_IS_DIR); + g_free (kmaildir); + + if (!exists) + return FALSE; + + return TRUE; +} + +#if 0 +int main () +{ + gchar *kmaildir; + g_type_init(); + kmaildir = g_build_filename (g_get_home_dir (), KMAIL_DIR, NULL); + + read_kmail_folder (kmaildir, EVOLUTION_LOCAL_BASE); + + return 0; +} +#endif diff -Npur evolution-3.10.2-old/mail/importers/kmail-libs.h evolution-3.10.2-new/mail/importers/kmail-libs.h --- evolution-3.10.2-old/mail/importers/kmail-libs.h 1970-01-01 08:00:00.000000000 +0800 +++ evolution-3.10.2-new/mail/importers/kmail-libs.h 2014-01-22 14:34:24.516738201 +0800 @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "libemail-engine/e-mail-store-utils.h" +#include "libemail-engine/e-mail-utils.h" +#include "shell/e-shell.h" +#include "mail/e-mail-backend.h" + +#include + + +#define EVOLUTION_LOCAL_BASE "folder://local" +#define EVOLUTION_DIR ".local/share/evolution/mail/local/" +#define KMAIL_4_10_DIR ".local/share/local-mail" +#define KMAIL_4_3_DIR ".kde4/share/apps/kmail/mail" +#define KCONTACT_4_3_DIR ".kde4/share/apps/kabc" + +gboolean is_kmail_supported (void); +const CamelStore * evolution_get_local_store (void); +gboolean is_kmail_folder (const gchar *folder); +gchar * get_kmail_base_dir (void); +gchar * kuri_to_euri (const gchar *k_uri); +GSList * get_kmail_folders (gchar *path); +GSList * read_kmail_folder (const gchar *path, GSList *list); +GSList * get_kcontact_list (void); +void load_kcontact (GSList *files); + +void load_kmail (void); + + diff -Npur evolution-3.10.2-old/mail/importers/mail-importer.c evolution-3.10.2-new/mail/importers/mail-importer.c --- evolution-3.10.2-old/mail/importers/mail-importer.c 2014-01-21 16:04:54.664763307 +0800 +++ evolution-3.10.2-new/mail/importers/mail-importer.c 2014-01-22 14:35:08.243803038 +0800 @@ -39,10 +39,11 @@ #include "e-util/e-util-private.h" #include "shell/e-shell-backend.h" -#include "libemail-engine/e-mail-session.h" #include "libemail-engine/mail-mt.h" #include "libemail-engine/mail-tools.h" +#include "libemail-engine/e-mail-session.h" +#include "kmail-libs.h" #include "mail-importer.h" struct _import_mbox_msg { @@ -63,6 +64,12 @@ import_mbox_desc (struct _import_mbox_ms return g_strdup (_("Importing mailbox")); } +static gchar * +import_maildir_desc (struct _import_mbox_msg *m) +{ + return g_strdup (_("Importing maildir")); +} + static struct { gchar tag; guint32 mozflag; @@ -105,6 +112,145 @@ decode_mozilla_status (const gchar *tmp) } static void +import_maildir_folder (struct _import_mbox_msg *m, + gchar *k_path, + GCancellable *cancellable, + GError **error) +{ + const gchar *special_folders []= {"cur", "tmp", "new", NULL}; + gchar *special_path; + const CamelStore *store; + CamelFolder *folder; + CamelMimeParser *mp = NULL; + CamelMessageInfo *info; + CamelMimeMessage *msg; + guint32 flags = 0; + + gchar *e_uri, *e_path; + + const gchar *d; + gchar *mail_url; + GDir *dir; + struct stat st; + gint fd, i; + + e_uri = kuri_to_euri (k_path); + /* we need to drop some folders, like: Trash */ + if (!e_uri) + return; + + store = evolution_get_local_store (); + e_path = e_uri + strlen (EVOLUTION_LOCAL_BASE) + 1; + e_mail_store_create_folder_sync ((CamelStore *)store, e_path, NULL, NULL); + + folder = e_mail_session_uri_to_folder_sync ( + m->session, e_uri, CAMEL_STORE_FOLDER_CREATE, + cancellable, NULL); + + if (folder == NULL) { + g_warning ("evolution error: cannot get the folder\n"); + return; + } + + + camel_operation_push_message ( + m->cancellable, _("Importing '%s'"), + camel_folder_get_display_name (folder)); + camel_folder_freeze (folder); + + for (i = 0; special_folders [i]; i++) { + camel_operation_progress (m->cancellable, 100*i/3); + special_path = g_build_filename (k_path, special_folders[i], NULL); + dir = g_dir_open (special_path, 0, NULL); + while ((d = g_dir_read_name (dir))) { + if ((strcmp (d, ".") == 0) || (strcmp (d, "..") == 0)) { + continue; + } + mail_url = g_build_filename (special_path, d, NULL); + if (g_stat (mail_url, &st) == -1) { + g_free (mail_url); + continue; + } + if (S_ISREG (st.st_mode)) { + fd = g_open (mail_url, O_RDONLY | O_BINARY, 0); + g_free (mail_url); + if (fd == -1) { + continue; + } + mp = camel_mime_parser_new (); + camel_mime_parser_scan_from (mp, FALSE); + if (camel_mime_parser_init_with_fd (mp, fd) == -1) { + /* will never happen - 0 is unconditionally returned */ + g_object_unref (mp); + continue; + } + + msg = camel_mime_message_new (); + if (!camel_mime_part_construct_from_parser_sync ( + (CamelMimePart *) msg, mp, NULL, NULL)) { + /* set exception? */ + g_object_unref (mp); + g_object_unref (msg); + continue; + + } + info = camel_message_info_new (NULL); + if (strcmp (special_folders[i], "cur") == 0) { + flags |= CAMEL_MESSAGE_SEEN; + } else if (strcmp (special_folders[i], "tmp") == 0) { + flags |= CAMEL_MESSAGE_DELETED; /* FIXME */ + } + camel_message_info_set_flags (info, flags, ~0); + + camel_folder_append_message_sync ( + folder, msg, info, NULL, + cancellable, error); + + camel_message_info_free (info); + g_object_unref (msg); + g_object_unref (mp); + } else { + g_free (mail_url); + } + } + } + camel_operation_progress (m->cancellable, 100); + camel_folder_synchronize_sync (folder, FALSE, NULL, NULL); + camel_folder_thaw (folder); + camel_operation_pop_message (m->cancellable); +} + +static void +import_maildir_exec (struct _import_mbox_msg *m, + GCancellable *cancellable, + GError **error) +{ + GSList *list, *l; + gchar *folder; + struct stat st; + + if (g_stat (m->path, &st) == -1) { + g_warning ( + "cannot find source file to import '%s': %s", + m->path, g_strerror (errno)); + return; + } + if (!S_ISDIR (st.st_mode)) { + g_warning ( + "the source path '%s' is not a directory.", + m->path); + return; + } + + list = get_kmail_folders (m->path); + for (l = list; l; l = l->next) { + folder = (gchar *) l->data; + import_maildir_folder (m, folder, cancellable, NULL); + } +} + + +static void import_mbox_exec (struct _import_mbox_msg *m, GCancellable *cancellable, GError **error) @@ -229,6 +375,23 @@ import_mbox_free (struct _import_mbox_ms g_free (m->path); } +static void +import_maildir_done (struct _import_mbox_msg *m) +{ + if (m->done) + m->done (m->done_data, &m->base.error); +} + +static void +import_maildir_free (struct _import_mbox_msg *m) +{ + g_object_unref (m->session); + if (m->cancellable) + g_object_unref (m->cancellable); + g_free (m->uri); + g_free (m->path); +} + static MailMsgInfo import_mbox_info = { sizeof (struct _import_mbox_msg), (MailMsgDescFunc) import_mbox_desc, @@ -237,6 +400,16 @@ static MailMsgInfo import_mbox_info = { (MailMsgFreeFunc) import_mbox_free }; +/*only difference with mbox_info is: _exec + but I put it into to different info. */ +static MailMsgInfo import_maildir_info = { + sizeof (struct _import_mbox_msg), + (MailMsgDescFunc) import_maildir_desc, + (MailMsgDescFunc) import_maildir_exec, + (MailMsgDoneFunc) import_maildir_done, + (MailMsgFreeFunc) import_maildir_free +}; + gint mail_importer_import_mbox (EMailSession *session, const gchar *path, @@ -286,6 +458,57 @@ mail_importer_import_mbox_sync (EMailSes mail_msg_unref (m); } +gint +mail_importer_import_maildir (EMailSession *session, + const gchar *path, /* path is basedir */ + const gchar *folderuri, /* not used now, use it when the user want to port to a certain folder */ + GCancellable *cancellable, + void (*done) (gpointer data, + GError **error), + gpointer data) +{ + struct _import_mbox_msg *m; + gint id; + + m = mail_msg_new (&import_maildir_info); + m->session = g_object_ref (session); + m->path = g_strdup (path); + m->uri = g_strdup (folderuri); + m->done = done; + m->done_data = data; + if (cancellable) + m->cancellable = g_object_ref (cancellable); + + id = m->base.seq; + mail_msg_fast_ordered_push (m); + + return id; +} + +void +mail_importer_import_maildir_sync (EMailSession *session, + const gchar *path, + const gchar *folderuri, + GCancellable *cancellable) +{ + struct _import_mbox_msg *m; + + m = mail_msg_new (&import_maildir_info); + m->session = g_object_ref (session); + m->path = g_strdup (path); + if (folderuri) + m->uri = g_strdup (folderuri); + else + m->uri = NULL; + if (cancellable) + m->base.cancellable = cancellable; + + cancellable = m->base.cancellable; + import_maildir_exec (m, cancellable, &m->base.error); + import_maildir_done (m); + mail_msg_unref (m); +} + struct _import_folders_data { MailImporterSpecial *special_folders; EMailSession *session; diff -Npur evolution-3.10.2-old/mail/importers/mail-importer.h evolution-3.10.2-new/mail/importers/mail-importer.h --- evolution-3.10.2-old/mail/importers/mail-importer.h 2014-01-21 16:04:54.664763307 +0800 +++ evolution-3.10.2-new/mail/importers/mail-importer.h 2014-01-21 16:06:07.368848069 +0800 @@ -24,8 +24,8 @@ #ifndef __MAIL_IMPORTER_H__ #define __MAIL_IMPORTER_H__ +#include #include -#include #include EImportImporter *mbox_importer_peek (void); @@ -38,6 +38,7 @@ typedef void (*MboxImporterFillPreviewFu void mbox_importer_set_preview_funcs (MboxImporterCreatePreviewFunc create_func, MboxImporterFillPreviewFunc fill_func); EImportImporter *elm_importer_peek (void); +EImportImporter *kmail_importer_peek (void); EImportImporter *pine_importer_peek (void); /* Defines copied from nsMsgMessageFlags.h in Mozilla source. */ @@ -58,6 +59,16 @@ void mail_importer_import_mbox_sync (EM const gchar *folderuri, GCancellable *cancellable); +gint mail_importer_import_maildir (EMailSession *session, + const gchar *path, + const gchar *folderuri, + GCancellable *cancellable, + void (*done)(gpointer data, GError **), + gpointer data); +void mail_importer_import_maildir_sync (EMailSession *session, + const gchar *path, + const gchar *folderuri, + GCancellable *cancellable); struct _MailImporterSpecial { const gchar *orig, *new; }; diff -Npur evolution-3.10.2-old/mail/importers/Makefile.am evolution-3.10.2-new/mail/importers/Makefile.am --- evolution-3.10.2-old/mail/importers/Makefile.am 2014-01-21 16:04:54.664763307 +0800 +++ evolution-3.10.2-new/mail/importers/Makefile.am 2014-01-21 16:06:07.368848069 +0800 @@ -12,6 +12,9 @@ libevolution_mail_importers_la_CPPFLAGS $(GTKHTML_CFLAGS) libevolution_mail_importers_la_SOURCES = \ + kmail-importer.c \ + kmail-libs.c \ + kmail-libs.h \ mail-importer.c \ mail-importer.h \ elm-importer.c \ diff -Npur evolution-3.10.2-old/mail/importers/Makefile.in evolution-3.10.2-new/mail/importers/Makefile.in --- evolution-3.10.2-old/mail/importers/Makefile.in 2014-01-21 16:04:54.664763307 +0800 +++ evolution-3.10.2-new/mail/importers/Makefile.in 2014-01-21 16:06:07.368848069 +0800 @@ -109,6 +109,8 @@ libevolution_mail_importers_la_DEPENDENC $(am__DEPENDENCIES_1) am_libevolution_mail_importers_la_OBJECTS = \ libevolution_mail_importers_la-mail-importer.lo \ + libevolution_mail_importers_la-kmail-importer.lo \ + libevolution_mail_importers_la-kmail-libs.lo \ libevolution_mail_importers_la-elm-importer.lo \ libevolution_mail_importers_la-pine-importer.lo \ libevolution_mail_importers_la-evolution-mbox-importer.lo @@ -418,6 +420,9 @@ libevolution_mail_importers_la_CPPFLAGS $(GTKHTML_CFLAGS) libevolution_mail_importers_la_SOURCES = \ + kmail-importer.c \ + kmail-libs.c \ + kmail-libs.c \ mail-importer.c \ mail-importer.h \ elm-importer.c \ @@ -514,6 +519,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_mail_importers_la-elm-importer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_mail_importers_la-evolution-mbox-importer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_mail_importers_la-mail-importer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_mail_importers_la-kmail-importer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_mail_importers_la-kmail-libs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_mail_importers_la-pine-importer.Plo@am__quote@ .c.o: @@ -537,10 +544,17 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -libevolution_mail_importers_la-mail-importer.lo: mail-importer.c +libevolution_mail_importers_la-kmail-libs.lo: kmail-libs.c kmail-libs.h +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_mail_importers_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_mail_importers_la-kmail-libs.lo -MD -MP -MF $(DEPDIR)/libevolution_mail_importers_la-kmail-libs.Tpo -c -o libevolution_mail_importers_la-kmail-libs.lo `test -f 'kmail-libs.c' || echo '$(srcdir)/'`kmail-libs.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_mail_importers_la-kmail-libs.Tpo $(DEPDIR)/libevolution_mail_importers_la-kmail-libs.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kmail-libs.c kmail-libs.h' object='libevolution_mail_importers_la-kmail-libs.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_mail_importers_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_mail_importers_la-kmail-libs.lo `test -f 'kmail-libs.c' || echo '$(srcdir)/'`kmail-libs.c + +libevolution_mail_importers_la-mail-importer.lo: mail-importer.c kmail-libs.c kmail-libs.h @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_mail_importers_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_mail_importers_la-mail-importer.lo -MD -MP -MF $(DEPDIR)/libevolution_mail_importers_la-mail-importer.Tpo -c -o libevolution_mail_importers_la-mail-importer.lo `test -f 'mail-importer.c' || echo '$(srcdir)/'`mail-importer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_mail_importers_la-mail-importer.Tpo $(DEPDIR)/libevolution_mail_importers_la-mail-importer.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mail-importer.c' object='libevolution_mail_importers_la-mail-importer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mail-importer.c kmail-libs.c kmail-libs.h' object='libevolution_mail_importers_la-mail-importer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_mail_importers_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_mail_importers_la-mail-importer.lo `test -f 'mail-importer.c' || echo '$(srcdir)/'`mail-importer.c @@ -551,6 +565,13 @@ libevolution_mail_importers_la-elm-impor @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_mail_importers_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_mail_importers_la-elm-importer.lo `test -f 'elm-importer.c' || echo '$(srcdir)/'`elm-importer.c +libevolution_mail_importers_la-kmail-importer.lo: kmail-importer.c kmail-libs.c kmail-libs.h +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_mail_importers_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_mail_importers_la-kmail-importer.lo -MD -MP -MF $(DEPDIR)/libevolution_mail_importers_la-kmail-importer.Tpo -c -o libevolution_mail_importers_la-kmail-importer.lo `test -f 'kmail-importer.c' || echo '$(srcdir)/'`kmail-importer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_mail_importers_la-kmail-importer.Tpo $(DEPDIR)/libevolution_mail_importers_la-kmail-importer.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kmail-importer.c kmail-libs.c kmail-libs.h' object='libevolution_mail_importers_la-kmail-importer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_mail_importers_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_mail_importers_la-kmail-importer.lo `test -f 'kmail-importer.c' || echo '$(srcdir)/'`kmail-importer.c + libevolution_mail_importers_la-pine-importer.lo: pine-importer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_mail_importers_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_mail_importers_la-pine-importer.lo -MD -MP -MF $(DEPDIR)/libevolution_mail_importers_la-pine-importer.Tpo -c -o libevolution_mail_importers_la-pine-importer.lo `test -f 'pine-importer.c' || echo '$(srcdir)/'`pine-importer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_mail_importers_la-pine-importer.Tpo $(DEPDIR)/libevolution_mail_importers_la-pine-importer.Plo