diff options
Diffstat (limited to 'mail/importers')
-rw-r--r-- | mail/importers/.cvsignore | 12 | ||||
-rw-r--r-- | mail/importers/GNOME_Evolution_Mail_Mbox_Importer.oaf.in | 29 | ||||
-rw-r--r-- | mail/importers/GNOME_Evolution_Mail_Outlook_Importer.oaf.in | 29 | ||||
-rw-r--r-- | mail/importers/Makefile.am | 54 | ||||
-rw-r--r-- | mail/importers/elm-importer.c | 382 | ||||
-rw-r--r-- | mail/importers/evolution-mbox-importer.c | 728 | ||||
-rw-r--r-- | mail/importers/evolution-outlook-importer.c | 318 | ||||
-rw-r--r-- | mail/importers/mail-importer.c | 415 | ||||
-rw-r--r-- | mail/importers/mail-importer.h | 77 | ||||
-rw-r--r-- | mail/importers/mozilla-status-headers.h | 29 | ||||
-rw-r--r-- | mail/importers/pine-importer.c | 478 |
11 files changed, 1785 insertions, 766 deletions
diff --git a/mail/importers/.cvsignore b/mail/importers/.cvsignore deleted file mode 100644 index ee1568b9e0..0000000000 --- a/mail/importers/.cvsignore +++ /dev/null @@ -1,12 +0,0 @@ -.deps -.libs -.pure -Makefile -Makefile.in -*.bb -*.bbg -*.da -*.gcov -*.oaf -*.lo -*.la
\ No newline at end of file diff --git a/mail/importers/GNOME_Evolution_Mail_Mbox_Importer.oaf.in b/mail/importers/GNOME_Evolution_Mail_Mbox_Importer.oaf.in deleted file mode 100644 index b9da9ce3c8..0000000000 --- a/mail/importers/GNOME_Evolution_Mail_Mbox_Importer.oaf.in +++ /dev/null @@ -1,29 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:GNOME_Evolution_Mail_Mbox_ImporterFactory" - type="exe" - location="evolution-mail"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/ObjectFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - _value="Factory to import mbox into Evolution"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Mail_Mbox_Importer" - type="factory" - location="OAFIID:GNOME_Evolution_Mail_Mbox_ImporterFactory"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/Importer:1.0"/> - </oaf_attribute> - - <oaf_attribute name="evolution:menu-name" type="string" - value="MBox (mbox)"/> - <oaf_attribute name="description" type="string" - _value="Imports mbox files into Evolution"/> -</oaf_server> - -</oaf_info> diff --git a/mail/importers/GNOME_Evolution_Mail_Outlook_Importer.oaf.in b/mail/importers/GNOME_Evolution_Mail_Outlook_Importer.oaf.in deleted file mode 100644 index 66317e3d7a..0000000000 --- a/mail/importers/GNOME_Evolution_Mail_Outlook_Importer.oaf.in +++ /dev/null @@ -1,29 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:GNOME_Evolution_Mail_Outlook_ImporterFactory" - type="exe" - location="evolution-mail"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/ObjectFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - _value="Factory to import Outlook Express 4 mails into Evolution"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Mail_Outlook_Importer" - type="factory" - location="OAFIID:GNOME_Evolution_Mail_Outlook_ImporterFactory"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/Importer:1.0"/> - </oaf_attribute> - - <oaf_attribute name="evolution:menu-name" type="string" - value="Outlook Express 4 (.mbx)"/> - <oaf_attribute name="description" type="string" - _value="Imports Outlook Express 4 files into Evolution"/> -</oaf_server> - -</oaf_info> diff --git a/mail/importers/Makefile.am b/mail/importers/Makefile.am index 915f665d93..540a7f889d 100644 --- a/mail/importers/Makefile.am +++ b/mail/importers/Makefile.am @@ -1,30 +1,32 @@ -importersdir = $(privlibdir)/evolution-mail-importers +privsolib_LTLIBRARIES = libevolution-mail-importers.la -importers_LTLIBRARIES = liboutlook.la libmbox.la - -INCLUDES = -I.. \ +libevolution_mail_importers_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -I.. \ -I$(srcdir)/.. \ -I$(top_srcdir) \ - -I$(top_srcdir)/shell \ - -I$(top_builddir)/shell \ - -I$(includedir) \ -DG_LOG_DOMAIN=\"evolution-mail-importer\" \ - $(IMPORTERS_CFLAGS) - -liboutlook_la_SOURCES = \ - evolution-outlook-importer.c -liboutlook_la_LDFLAGS = -avoid-version -module - -libmbox_la_SOURCES = evolution-mbox-importer.c \ - mozilla-status-headers.h -libmbox_la_LDFLAGS = -avoid-version -module - -oafdir = $(datadir)/oaf -oaf_in_files = GNOME_Evolution_Mail_Mbox_Importer.oaf.in \ - GNOME_Evolution_Mail_Outlook_Importer.oaf.in - -oaf_DATA = $(oaf_in_files:.oaf.in=.oaf) - -EXTRA_DIST = $(oaf_in_files) $(oaf_DATA) - -@XML_I18N_MERGE_OAF_RULE@ + -DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \ + $(EVOLUTION_DATA_SERVER_CFLAGS) \ + $(GNOME_PLATFORM_CFLAGS) \ + $(GTKHTML_CFLAGS) + +libevolution_mail_importers_la_SOURCES = \ + mail-importer.c \ + mail-importer.h \ + elm-importer.c \ + pine-importer.c \ + evolution-mbox-importer.c + +libevolution_mail_importers_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) + +libevolution_mail_importers_la_LIBADD = \ + $(top_builddir)/e-util/libevolution-util.la \ + $(top_builddir)/mail/libevolution-mail.la \ + $(top_builddir)/shell/libevolution-shell.la \ + $(top_builddir)/libemail-engine/libemail-engine.la \ + $(EVOLUTION_DATA_SERVER_LIBS) \ + $(GNOME_PLATFORM_LIBS) \ + $(GTKHTML_LIBS) + +-include $(top_srcdir)/git.mk diff --git a/mail/importers/elm-importer.c b/mail/importers/elm-importer.c new file mode 100644 index 0000000000..6a20bf4120 --- /dev/null +++ b/mail/importers/elm-importer.c @@ -0,0 +1,382 @@ +/* + * 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 <http://www.gnu.org/licenses/> + * + * + * Authors: + * Iain Holmes <iain@ximian.com> + * Michael Zucchi <notzed@ximian.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <dirent.h> +#include <string.h> + +#include <gtk/gtk.h> +#include <glib/gi18n.h> + +#include "mail-importer.h" + +#include "libemail-engine/mail-mt.h" +#include "mail/e-mail-backend.h" +#include "shell/e-shell.h" + +#define d(x) + +struct _elm_import_msg { + MailMsg base; + + EImport *import; + EImportTargetHome *target; + + GMutex status_lock; + gchar *status_what; + gint status_pc; + gint status_timeout_id; + GCancellable *status; +}; + +static GHashTable * +parse_elm_rc (const gchar *elmrc) +{ + gchar line[4096]; + FILE *handle; + GHashTable *prefs; + + prefs = g_hash_table_new_full ( + g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_free); + + if (!g_file_test (elmrc, G_FILE_TEST_IS_REGULAR)) + return prefs; + + handle = fopen (elmrc, "r"); + if (handle == NULL) + return prefs; + + while (fgets (line, 4096, handle) != NULL) { + gchar *linestart, *end; + gchar *key, *value; + if (*line == '#' && + (line[1] != '#' && line[2] != '#')) { + continue; + } else if (*line == '\n') { + continue; + } else if (*line == '#' && line[1] == '#' && line[2] == '#') { + linestart = line + 4; + } else { + linestart = line; + } + + end = strstr (linestart, " = "); + if (end == NULL) { + g_warning ("Broken line"); + continue; + } + + *end = 0; + key = g_strdup (linestart); + + linestart = end + 3; + end = strchr (linestart, '\n'); + if (end == NULL) { + g_warning ("Broken line"); + g_free (key); + continue; + } + + *end = 0; + value = g_strdup (linestart); + + g_hash_table_insert (prefs, key, value); + } + + fclose (handle); + + return prefs; +} + +static gchar * +elm_get_rc (EImport *ei, + const gchar *name) +{ + GHashTable *prefs; + gchar *elmrc; + + prefs = g_object_get_data ((GObject *) ei, "elm-rc"); + if (prefs == NULL) { + elmrc = g_build_filename (g_get_home_dir (), ".elm/elmrc", NULL); + prefs = parse_elm_rc (elmrc); + g_free (elmrc); + g_object_set_data ((GObject *) ei, "elm-rc", prefs); + } + + if (prefs == NULL) + return NULL; + else + return g_hash_table_lookup (prefs, name); +} + +static gboolean +elm_supported (EImport *ei, + EImportTarget *target, + EImportImporter *im) +{ + const gchar *maildir; + gchar *elmdir; + gboolean mailexists, exists; + + if (target->type != E_IMPORT_TARGET_HOME) + return FALSE; + + elmdir = g_build_filename (g_get_home_dir (), ".elm", NULL); + exists = g_file_test (elmdir, G_FILE_TEST_IS_DIR); + g_free (elmdir); + if (!exists) + return FALSE; + + maildir = elm_get_rc (ei, "maildir"); + if (maildir == NULL) + maildir = "Mail"; + + if (!g_path_is_absolute (maildir)) + elmdir = g_build_filename (g_get_home_dir (), maildir, NULL); + else + elmdir = g_strdup (maildir); + + mailexists = g_file_test (elmdir, G_FILE_TEST_IS_DIR); + g_free (elmdir); + + return mailexists; +} + +static gchar * +elm_import_desc (struct _elm_import_msg *m) +{ + return g_strdup (_("Importing Elm data")); +} + +static MailImporterSpecial elm_special_folders[] = { + { "received", "Inbox" }, + { NULL }, +}; + +static void +elm_import_exec (struct _elm_import_msg *m, + GCancellable *cancellable, + GError **error) +{ + EShell *shell; + EShellBackend *shell_backend; + EMailSession *session; + const gchar *maildir; + gchar *elmdir; + + /* 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)); + + maildir = elm_get_rc (m->import, "maildir"); + if (maildir == NULL) + maildir = "Mail"; + + if (!g_path_is_absolute (maildir)) + elmdir = g_build_filename (g_get_home_dir (), maildir, NULL); + else + elmdir = g_strdup (maildir); + + mail_importer_import_folders_sync ( + session, elmdir, elm_special_folders, 0, m->status); + g_free (elmdir); +} + +static void +elm_import_done (struct _elm_import_msg *m) +{ + e_import_complete (m->import, (EImportTarget *) m->target); +} + +static void +elm_import_free (struct _elm_import_msg *m) +{ + g_object_unref (m->status); + + g_free (m->status_what); + g_mutex_clear (&m->status_lock); + + g_source_remove (m->status_timeout_id); + m->status_timeout_id = 0; + + g_object_unref (m->import); +} + +static void +elm_status (CamelOperation *op, + const gchar *what, + gint pc, + gpointer data) +{ + struct _elm_import_msg *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 +elm_status_timeout (gpointer data) +{ + struct _elm_import_msg *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 MailMsgInfo elm_import_info = { + sizeof (struct _elm_import_msg), + (MailMsgDescFunc) elm_import_desc, + (MailMsgExecFunc) elm_import_exec, + (MailMsgDoneFunc) elm_import_done, + (MailMsgFreeFunc) elm_import_free +}; + +static gint +mail_importer_elm_import (EImport *ei, + EImportTarget *target) +{ + struct _elm_import_msg *m; + gint id; + + m = mail_msg_new (&elm_import_info); + g_datalist_set_data (&target->data, "elm-msg", m); + m->import = ei; + g_object_ref (m->import); + m->target = (EImportTargetHome *) target; + m->status_timeout_id = g_timeout_add (100, elm_status_timeout, m); + g_mutex_init (&m->status_lock); + m->status = camel_operation_new (); + + g_signal_connect ( + m->status, "status", + G_CALLBACK (elm_status), m); + + id = m->base.seq; + + mail_msg_fast_ordered_push (m); + + return id; +} + +static void +checkbox_toggle_cb (GtkToggleButton *tb, + EImportTarget *target) +{ + g_datalist_set_data ( + &target->data, "elm-do-mail", + GINT_TO_POINTER (gtk_toggle_button_get_active (tb))); +} + +static GtkWidget * +elm_getwidget (EImport *ei, + EImportTarget *target, + EImportImporter *im) +{ + GtkWidget *box, *w; + + g_datalist_set_data ( + &target->data, "elm-do-mail", GINT_TO_POINTER (TRUE)); + + box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 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); + gtk_widget_show_all (box); + + return box; +} + +static void +elm_import (EImport *ei, + EImportTarget *target, + EImportImporter *im) +{ + if (GPOINTER_TO_INT (g_datalist_get_data (&target->data, "elm-do-mail"))) + mail_importer_elm_import (ei, target); + else + e_import_complete (ei, target); +} + +static void +elm_cancel (EImport *ei, + EImportTarget *target, + EImportImporter *im) +{ + struct _elm_import_msg *m = g_datalist_get_data (&target->data, "elm-msg"); + + if (m) + g_cancellable_cancel (m->status); +} + +static EImportImporter elm_importer = { + E_IMPORT_TARGET_HOME, + 0, + elm_supported, + elm_getwidget, + elm_import, + elm_cancel, + NULL, /* get_preview */ +}; + +EImportImporter * +elm_importer_peek (void) +{ + elm_importer.name = _("Evolution Elm importer"); + elm_importer.description = _("Import mail from Elm."); + + return &elm_importer; +} diff --git a/mail/importers/evolution-mbox-importer.c b/mail/importers/evolution-mbox-importer.c index faeadbcf34..1e8a09460e 100644 --- a/mail/importers/evolution-mbox-importer.c +++ b/mail/importers/evolution-mbox-importer.c @@ -1,408 +1,490 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* evolution-mbox-importer.c - * - * Authors: Iain Holmes <iain@ximian.com> - * - * Copyright (C) 2001 Ximian, Inc. - * +/* * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 <http://www.gnu.org/licenses/> + * + * + * Authors: + * Iain Holmes <iain@ximian.com> + * Michael Zucchi <notzed@ximian.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * 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. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + #include <stdio.h> #include <ctype.h> +#include <string.h> +#include <errno.h> -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-generic-factory.h> - -#include <camel/camel-exception.h> -#include <camel/camel-mime-message.h> -#include <camel/camel-mime-parser.h> -#include <camel/camel-mime-part.h> - -#include <importer/evolution-importer.h> -#include <importer/GNOME_Evolution_Importer.h> +#include <gtk/gtk.h> +#include <glib/gi18n.h> +#include <glib/gstdio.h> -#include "mozilla-status-headers.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/mail-importer.h" -#include "mail-tools.h" +#include "libemail-engine/mail-mt.h" -#include "e-util/e-path.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" -/* #define IMPORTER_DEBUG */ -#ifdef IMPORTER_DEBUG -#define IN g_print ("=====> %s (%d)\n", __FUNCTION__, __LINE__) -#define OUT g_print ("<==== %s (%d)\n", __FUNCTION__, __LINE__) -#else -#define IN -#define OUT -#endif - -#define MBOX_FACTORY_IID "OAFIID:GNOME_Evolution_Mail_Mbox_ImporterFactory" +#include "mail-importer.h" typedef struct { - MailImporter importer; /* Parent */ + EImport *import; + EImportTarget *target; - char *filename; - int num; - CamelMimeParser *mp; - gboolean is_folder; -} MboxImporter; - -void mail_importer_module_init (void); - -/* EvolutionImporter methods */ + GMutex status_lock; + gchar *status_what; + gint status_pc; + gint status_timeout_id; + GCancellable *cancellable; /* cancel/status port */ + gchar *uri; +} MboxImporter; -static CamelMessageInfo * -get_info_from_mozilla (const char *mozilla_status, - gboolean *deleted) +static void +folder_selected (EMFolderSelectionButton *button, + EImportTargetURI *target) { - unsigned int status; - CamelMessageInfo *info; - - *deleted = FALSE; - - status = strtoul (mozilla_status, NULL, 16); - if (status == 0) { - return camel_message_info_new (); - } - - if (status & MSG_FLAG_EXPUNGED) { - *deleted = TRUE; - - return NULL; - } - - info = camel_message_info_new (); - - if (status & MSG_FLAG_READ) - info->flags |= CAMEL_MESSAGE_SEEN; - - if (status & MSG_FLAG_MARKED) - info->flags |= CAMEL_MESSAGE_FLAGGED; - - if (status & MSG_FLAG_REPLIED) - info->flags |= CAMEL_MESSAGE_ANSWERED; - - return info; + g_free (target->uri_dest); + target->uri_dest = g_strdup (em_folder_selection_button_get_folder_uri (button)); } -static void -process_item_fn (EvolutionImporter *eimporter, - CORBA_Object listener, - void *closure, - CORBA_Environment *ev) +static GtkWidget * +mbox_getwidget (EImport *ei, + EImportTarget *target, + EImportImporter *im) { - MboxImporter *mbi = (MboxImporter *) closure; - MailImporter *importer = (MailImporter *) mbi; - gboolean done = FALSE; - CamelException *ex; - const char *mozilla_status; - - if (importer->folder == NULL) { - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_NOT_READY, - TRUE, ev); - return; + 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 (mbi->is_folder == TRUE) { - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_OK, - FALSE, ev); - return; + 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); } - - ex = camel_exception_new (); - if (camel_mime_parser_step (mbi->mp, 0, 0) == HSCAN_FROM) { - /* Import the next message */ - CamelMimeMessage *msg; - CamelMessageInfo *info; - gboolean deleted; - - IN; - msg = camel_mime_message_new (); - if (camel_mime_part_construct_from_parser (CAMEL_MIME_PART (msg), mbi->mp) == -1) { - g_warning ("Failed message %d", mbi->num); - camel_object_unref (CAMEL_OBJECT (msg)); - done = TRUE; - } else { - mozilla_status = camel_medium_get_header (CAMEL_MEDIUM (msg), "X-Mozilla-Status"); - if (mozilla_status != NULL) { - g_print ("Got Mozilla status header: %s\n", mozilla_status); - info = get_info_from_mozilla (mozilla_status, &deleted); - } else { - deleted = FALSE; - info = camel_message_info_new (); - } - - if (deleted == FALSE) { - /* write the mesg */ - camel_folder_append_message (importer->folder, msg, info, NULL, ex); - } - - if (info) - camel_message_info_free (info); - - camel_object_unref (CAMEL_OBJECT (msg)); - if (camel_exception_is_set (ex)) { - g_warning ("Failed message %d", mbi->num); - done = TRUE; - } - } - OUT; - } else { - IN; - /* all messages have now been imported */ - camel_folder_sync (importer->folder, FALSE, ex); - camel_folder_thaw (importer->folder); - importer->frozen = FALSE; - done = TRUE; - OUT; - } - - if (!done) - camel_mime_parser_step (mbi->mp, 0, 0); - - camel_exception_free (ex); - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_OK, - !done, ev); - return; + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 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_box_new (GTK_ORIENTATION_VERTICAL, 0); + gtk_box_pack_start ((GtkBox *) w, hbox, FALSE, FALSE, 0); + gtk_widget_show_all (w); + + g_free (select_uri); + + return w; } static gboolean -support_format_fn (EvolutionImporter *importer, - const char *filename, - void *closure) +mbox_supported (EImport *ei, + EImportTarget *target, + EImportImporter *im) { - char signature[6]; + gchar signature[6]; gboolean ret = FALSE; - int fd, n; + gint fd, n; + EImportTargetURI *s; + gchar *filename; - fd = open (filename, O_RDONLY); - if (fd == -1) + if (target->type != E_IMPORT_TARGET_URI) return FALSE; - n = read (fd, signature, 5); - if (n > 0) { - signature[n] = '\0'; - if (!g_strncasecmp (signature, "From ", 5)) - ret = TRUE; - } + s = (EImportTargetURI *) target; + if (s->uri_src == NULL) + return TRUE; - close (fd); + if (strncmp (s->uri_src, "file:///", strlen ("file:///")) != 0) + return FALSE; + + filename = g_filename_from_uri (s->uri_src, NULL, NULL); + fd = g_open (filename, O_RDONLY, 0); + g_free (filename); + if (fd != -1) { + n = read (fd, signature, 5); + ret = n == 5 && memcmp (signature, "From ", 5) == 0; + close (fd); + } - return ret; + return ret; } static void -importer_destroy_cb (GtkObject *object, - MboxImporter *mbi) +mbox_status (CamelOperation *op, + const gchar *what, + gint pc, + gpointer data) { - MailImporter *importer; + MboxImporter *importer = data; - importer = (MailImporter *) mbi; - if (importer->frozen) { - camel_folder_sync (importer->folder, FALSE, NULL); - camel_folder_thaw (importer->folder); + 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 +mbox_status_timeout (gpointer data) +{ + MboxImporter *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); } - if (importer->folder) - camel_object_unref (CAMEL_OBJECT (importer->folder)); + return TRUE; +} + +static void +mbox_import_done (gpointer data, + GError **error) +{ + MboxImporter *importer = data; - g_free (mbi->filename); - if (mbi->mp) - camel_object_unref (CAMEL_OBJECT (mbi->mp)); + g_source_remove (importer->status_timeout_id); + g_free (importer->status_what); + g_mutex_clear (&importer->status_lock); + g_object_unref (importer->cancellable); - g_free (mbi); + e_import_complete (importer->import, importer->target); + g_free (importer); } static void -folder_created_cb (BonoboListener *listener, - const char *event_name, - const BonoboArg *event_data, - CORBA_Environment *ev, - MailImporter *importer) +mbox_import (EImport *ei, + EImportTarget *target, + EImportImporter *im) { - char *fullpath; - GNOME_Evolution_Storage_FolderResult *result; - CamelException *ex; + EShell *shell; + EShellBackend *shell_backend; + EMailSession *session; + MboxImporter *importer; + gchar *filename; + + /* 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, "mbox-data", importer); + importer->import = ei; + importer->target = target; + g_mutex_init (&importer->status_lock); + importer->status_timeout_id = g_timeout_add (100, mbox_status_timeout, importer); + importer->cancellable = camel_operation_new (); + + g_signal_connect ( + importer->cancellable, "status", + G_CALLBACK (mbox_status), importer); + + filename = g_filename_from_uri ( + ((EImportTargetURI *) target)->uri_src, NULL, NULL); + mail_importer_import_mbox ( + session, filename, ((EImportTargetURI *) target)->uri_dest, + importer->cancellable, mbox_import_done, importer); + g_free (filename); +} - if (strcmp (event_name, "evolution-shell:folder_created") != 0) { - return; /* Unknown event */ - } +static void +mbox_cancel (EImport *ei, + EImportTarget *target, + EImportImporter *im) +{ + MboxImporter *importer = g_datalist_get_data (&target->data, "mbox-data"); - result = event_data->_value; - fullpath = g_strconcat ("file://", result->path, NULL); + if (importer) + g_cancellable_cancel (importer->cancellable); +} - ex = camel_exception_new (); - importer->folder = mail_tool_uri_to_folder (fullpath, CAMEL_STORE_FOLDER_CREATE, ex); - if (camel_exception_is_set (ex)) { - g_warning ("Error opening %s", fullpath); - camel_exception_free (ex); +static MboxImporterCreatePreviewFunc create_preview_func = NULL; +static MboxImporterFillPreviewFunc fill_preview_func = NULL; - g_free (fullpath); - return; - } +void +mbox_importer_set_preview_funcs (MboxImporterCreatePreviewFunc create_func, + MboxImporterFillPreviewFunc fill_func) +{ + create_preview_func = create_func; + fill_preview_func = fill_func; +} + +static void +preview_selection_changed_cb (GtkTreeSelection *selection, + EWebViewPreview *preview) +{ + GtkTreeIter iter; + GtkTreeModel *model = NULL; + gboolean found = FALSE; + + g_return_if_fail (selection != NULL); + g_return_if_fail (preview != NULL); + g_return_if_fail (fill_preview_func != NULL); + + if (gtk_tree_selection_get_selected (selection, &model, &iter) && model) { + CamelMimeMessage *msg = NULL; + + gtk_tree_model_get (model, &iter, 2, &msg, -1); - camel_folder_freeze (importer->folder); - importer->frozen = TRUE; + if (msg) { + found = TRUE; + fill_preview_func (G_OBJECT (preview), msg); + g_object_unref (msg); + } + } - g_free (fullpath); - bonobo_object_unref (BONOBO_OBJECT (listener)); + if (!found) { + e_web_view_preview_begin_update (preview); + e_web_view_preview_end_update (preview); + } } -static gboolean -load_file_fn (EvolutionImporter *eimporter, - const char *filename, - const char *folderpath, - void *closure) +static GtkWidget * +mbox_get_preview (EImport *ei, + EImportTarget *target, + EImportImporter *im) { - MboxImporter *mbi; - MailImporter *importer; - gboolean delayed = FALSE; - struct stat buf; - int fd; + GtkWidget *preview = NULL; + EImportTargetURI *s = (EImportTargetURI *) target; + gchar *filename; + gint fd; + CamelMimeParser *mp; + GtkListStore *store = NULL; + GtkTreeIter iter; + GtkWidget *preview_widget = NULL; - mbi = (MboxImporter *) closure; - importer = (MailImporter *) mbi; + if (!create_preview_func || !fill_preview_func) + return NULL; - mbi->filename = g_strdup (filename); + filename = g_filename_from_uri (s->uri_src, NULL, NULL); + if (!filename) { + g_message (G_STRLOC ": Couldn't get filename from URI '%s'", s->uri_src); + return NULL; + } - fd = open (filename, O_RDONLY); + fd = g_open (filename, O_RDONLY | O_BINARY, 0); if (fd == -1) { - g_warning ("Cannot open file"); - return FALSE; + g_warning ( + "Cannot find source file to import '%s': %s", + filename, g_strerror (errno)); + g_free (filename); + return NULL; } - fstat (fd, &buf); - if (S_ISREG (buf.st_mode)) { - mbi->mp = camel_mime_parser_new (); - camel_mime_parser_scan_from (mbi->mp, TRUE); - if (camel_mime_parser_init_with_fd (mbi->mp, fd) == -1) { - g_warning ("Unable to process spool folder"); - goto fail; - } - mbi->is_folder = FALSE; - } else { - mbi->is_folder = TRUE; + g_free (filename); + + mp = camel_mime_parser_new (); + camel_mime_parser_scan_from (mp, TRUE); + if (camel_mime_parser_init_with_fd (mp, fd) == -1) { + g_object_unref (mp); + return NULL; } - importer->mstream = NULL; - if (folderpath == NULL || *folderpath == '\0') { - importer->folder = mail_tool_get_local_inbox (NULL); - } else { - char *parent, *tmp, *fullpath, *homedir; - const char *name; - BonoboListener *listener; - CamelException *ex; - - tmp = gnome_util_prepend_user_home ("evolution/local"); - homedir = g_strconcat ("file://", tmp, NULL); - g_free (tmp); - - fullpath = e_path_to_physical (homedir, folderpath); - ex = camel_exception_new (); - importer->folder = mail_tool_uri_to_folder (fullpath, 0, ex); - g_free (homedir); - - if (camel_exception_is_set (ex) || importer->folder == NULL) { - /* Make a new directory */ - name = strrchr (folderpath, '/'); - if (name == NULL) { - parent = g_strdup ("/"); - name = folderpath; - } else { - name += 1; - parent = g_dirname (folderpath); - } - - listener = bonobo_listener_new (NULL, NULL); - gtk_signal_connect (GTK_OBJECT (listener), "event-notify", - GTK_SIGNAL_FUNC (folder_created_cb), - importer); - - mail_importer_create_folder (parent, name, NULL, listener); - camel_exception_free (ex); - ex = camel_exception_new (); - importer->folder = NULL; - g_print ("No folder yet\n"); - delayed = TRUE; - g_free (parent); + while (camel_mime_parser_step (mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM) { + CamelMimeMessage *msg; + gchar *from; + + msg = camel_mime_message_new (); + if (!camel_mime_part_construct_from_parser_sync ( + (CamelMimePart *) msg, mp, NULL, NULL)) { + g_object_unref (msg); + break; } - camel_exception_free (ex); - g_free (fullpath); - } - if (importer->folder == NULL && delayed == FALSE){ - g_warning ("Bad folder\n"); - goto fail; - } + if (!store) + store = gtk_list_store_new ( + 3, G_TYPE_STRING, G_TYPE_STRING, + CAMEL_TYPE_MIME_MESSAGE); - if (importer->folder != NULL) { - camel_folder_freeze (importer->folder); - importer->frozen = TRUE; + from = NULL; + if (camel_mime_message_get_from (msg)) + from = camel_address_encode ( + CAMEL_ADDRESS ( + camel_mime_message_get_from (msg))); + + gtk_list_store_append (store, &iter); + gtk_list_store_set ( + store, &iter, + 0, camel_mime_message_get_subject (msg) ? + camel_mime_message_get_subject (msg) : "", + 1, from ? from : "", 2, msg, -1); + + g_object_unref (msg); + g_free (from); + + camel_mime_parser_step (mp, NULL, NULL); } - return TRUE; + if (store) { + GtkTreeView *tree_view; + GtkTreeSelection *selection; + gboolean valid; - fail: - camel_object_unref (CAMEL_OBJECT (mbi->mp)); - mbi->mp = NULL; + preview = e_web_view_preview_new (); + gtk_widget_show (preview); - return FALSE; -} + tree_view = e_web_view_preview_get_tree_view ( + E_WEB_VIEW_PREVIEW (preview)); + g_return_val_if_fail (tree_view != NULL, NULL); -static BonoboObject * -mbox_factory_fn (BonoboGenericFactory *_factory, - void *closure) -{ - EvolutionImporter *importer; - MboxImporter *mbox; - - mbox = g_new0 (MboxImporter, 1); - importer = evolution_importer_new (support_format_fn, load_file_fn, - process_item_fn, NULL, mbox); - gtk_signal_connect (GTK_OBJECT (importer), "destroy", - GTK_SIGNAL_FUNC (importer_destroy_cb), mbox); - - return BONOBO_OBJECT (importer); -} + gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (store)); + g_object_unref (store); -/* Entry point */ -void -mail_importer_module_init (void) -{ - static gboolean initialised = FALSE; - BonoboGenericFactory *factory; - - if (initialised == TRUE) - return; + /* Translators: Column header for a message subject */ + gtk_tree_view_insert_column_with_attributes ( + tree_view, -1, C_("mboxImp", "Subject"), + gtk_cell_renderer_text_new (), "text", 0, NULL); + + /* Translators: Column header for a message From address */ + gtk_tree_view_insert_column_with_attributes ( + tree_view, -1, C_("mboxImp", "From"), + gtk_cell_renderer_text_new (), "text", 1, NULL); + + if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) > 1) + e_web_view_preview_show_tree_view ( + E_WEB_VIEW_PREVIEW (preview)); + + create_preview_func (G_OBJECT (preview), &preview_widget); + g_return_val_if_fail (preview_widget != NULL, NULL); - factory = bonobo_generic_factory_new (MBOX_FACTORY_IID, - mbox_factory_fn, NULL); + e_web_view_preview_set_preview ( + E_WEB_VIEW_PREVIEW (preview), preview_widget); + gtk_widget_show (preview_widget); - if (factory == NULL) - g_warning ("Could not initialise Outlook importer factory."); + selection = gtk_tree_view_get_selection (tree_view); + valid = gtk_tree_model_get_iter_first ( + GTK_TREE_MODEL (store), &iter); + g_return_val_if_fail (valid, NULL); + gtk_tree_selection_select_iter (selection, &iter); - initialised = TRUE; + g_signal_connect ( + selection, "changed", + G_CALLBACK (preview_selection_changed_cb), preview); + + preview_selection_changed_cb ( + selection, E_WEB_VIEW_PREVIEW (preview)); + } + + return preview; } +static EImportImporter mbox_importer = { + E_IMPORT_TARGET_URI, + 0, + mbox_supported, + mbox_getwidget, + mbox_import, + mbox_cancel, + mbox_get_preview, +}; + +EImportImporter * +mbox_importer_peek (void) +{ + mbox_importer.name = _("Berkeley Mailbox (mbox)"); + mbox_importer.description = _("Importer Berkeley Mailbox format folders"); + + return &mbox_importer; +} diff --git a/mail/importers/evolution-outlook-importer.c b/mail/importers/evolution-outlook-importer.c deleted file mode 100644 index 977d610055..0000000000 --- a/mail/importers/evolution-outlook-importer.c +++ /dev/null @@ -1,318 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* evolution-outlook-importer.c - * - * Authors: Iain Holmes <iain@ximian.com> - * - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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. - */ - - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-generic-factory.h> - -#include <stdio.h> - -#include <importer/evolution-importer.h> -#include <importer/GNOME_Evolution_Importer.h> - -#include <camel/camel-exception.h> - -#include "e-util/e-memory.h" - -#include "mail-importer.h" -#include "mail-tools.h" - - -#define OUTLOOK_FACTORY_IID "OAFIID:GNOME_Evolution_Mail_Outlook_ImporterFactory" - -extern char *evolution_dir; -typedef struct { - MailImporter importer; - - char *filename; - gboolean oe4; /* Is file OE4 or not? */ - FILE *handle; - long pos; - off_t size; - - gboolean busy; -} OutlookImporter; - -struct oe_msg_segmentheader { - int self; - int increase; - int include; - int next; - int usenet; -}; - -typedef struct oe_msg_segmentheader oe_msg_segmentheader; - -/* Prototype */ - -void mail_importer_module_init (void); - - -/* EvolutionImporter methods */ - -/* Based on code from liboe 0.92 (STABLE) - Copyright (C) 2000 Stephan B. Nedregård (stephan@micropop.com) - Modified 2001 Iain Holmes <iain@ximian.com> - Copyright (C) 2001 Ximian, Inc. */ - -static void -process_item_fn (EvolutionImporter *eimporter, - CORBA_Object listener, - void *closure, - CORBA_Environment *ev) -{ - OutlookImporter *oli = (OutlookImporter *) closure; - MailImporter *importer = (MailImporter *) oli; - oe_msg_segmentheader *header; - gboolean more = TRUE; - char *cb, *sfull, *s; - long end_pos = 0; - int i; - - if (oli->busy == TRUE) { - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_BUSY, - more, ev); - return; - } - - oli->busy = TRUE; - header = g_new (oe_msg_segmentheader, 1); - fread (header, 16, 1, oli->handle); - - /* Write a From line */ - mail_importer_add_line (importer, - "From evolution-outlook-importer", FALSE); - end_pos = oli->pos + header->include; - if (end_pos >= oli->size) { - end_pos = oli->size; - more = FALSE; - } - - oli->pos += 4; - - cb = g_new (char, 4); - sfull = g_new (char, 65536); - s = sfull; - - while (oli->pos < end_pos) { - fread (cb, 1, 4, oli->handle); - for (i = 0; i < 4; i++, oli->pos++) { - if (*(cb + i ) != 0x0d) { - *s++ = *(cb + i); - - if (*(cb + i) == 0x0a) { - *s = '\0'; - mail_importer_add_line (importer, - sfull, FALSE); - s = sfull; - } - } - } - } - - if (s != sfull) { - *s = '\0'; - mail_importer_add_line (importer, sfull, FALSE); - s = sfull; - } - - mail_importer_add_line (importer, "\n", TRUE); - - oli->pos = end_pos; - fseek (oli->handle, oli->pos, SEEK_SET); - - g_free (header); - g_free (sfull); - g_free (cb); - - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_OK, - more, ev); - if (more == FALSE) { - CamelException *ex; - - ex = camel_exception_new (); - camel_folder_thaw (importer->folder); - camel_folder_sync (importer->folder, FALSE, ex); - camel_exception_free (ex); - fclose (oli->handle); - oli->handle = NULL; - } - - oli->busy = FALSE; - return; -} - - -/* EvolutionImporterFactory methods */ - -static gboolean -support_format_fn (EvolutionImporter *importer, - const char *filename, - void *closure) -{ - FILE *handle; - int signature[4]; - - /* Outlook Express sniffer. - Taken from liboe 0.92 (STABLE) - Copyright (C) 2000 Stephan B. Nedregård (stephan@micropop.com) */ - - handle = fopen (filename, "rb"); - if (handle == NULL) - return FALSE; /* Can't open file: Can't support it :) */ - - /* SIGNATURE */ - fread (&signature, 16, 1, handle); - if ((signature[0]!=0xFE12ADCF) || /* OE 5 & OE 5 BETA SIGNATURE */ - (signature[1]!=0x6F74FDC5) || - (signature[2]!=0x11D1E366) || - (signature[3]!=0xC0004E9A)) { - if ((signature[0]==0x36464D4A) && - (signature[1]==0x00010003)) /* OE4 SIGNATURE */ { - fclose (handle); - return TRUE; /* OE 4 */ - } - fclose (handle); - return FALSE; /* Not Outlook 4 or 5 */ - } - - fclose (handle); - return FALSE; /* Can't handle OE 5 yet */ -} - -static void -importer_destroy_cb (GtkObject *object, - OutlookImporter *oli) -{ - MailImporter *importer; - - importer = (MailImporter *) oli; - if (importer->folder) - camel_object_unref (CAMEL_OBJECT (importer->folder)); - - g_free (oli->filename); - if (oli->handle) - fclose (oli->handle); - - g_free (oli); -} - -static gboolean -load_file_fn (EvolutionImporter *eimporter, - const char *filename, - const char *folderpath, - void *closure) -{ - OutlookImporter *oli; - MailImporter *importer; - struct stat buf; - long pos = 0x54; - - oli = (OutlookImporter *) closure; - importer = (MailImporter *) oli; - - oli->filename = g_strdup (filename); - /* Will return TRUE if oe4 format */ - oli->oe4 = support_format_fn (NULL, filename, NULL); - if (oli->oe4 == FALSE) { - g_warning ("Not OE4 format"); - return FALSE; - } - - oli->handle = fopen (filename, "rb"); - if (oli->handle == NULL) { - g_warning ("Cannot open the file"); - return FALSE; - } - - /* Get size of file */ - if (stat (filename, &buf) == -1) { - g_warning ("Cannot stat file"); - return FALSE; - } - - oli->size = buf.st_size; - - /* Set the fposition to the begining */ - fseek (oli->handle, pos, SEEK_SET); - oli->pos = pos; - - importer->mstream = NULL; - - if (folderpath == NULL || *folderpath == '\0') - importer->folder = mail_tool_get_local_inbox (NULL); - else - importer->folder = mail_tool_uri_to_folder (folderpath, CAMEL_STORE_FOLDER_CREATE, NULL); - - if (importer->folder == NULL){ - g_warning ("Bad folder"); - return FALSE; - } - - camel_folder_freeze (importer->folder); - oli->busy = FALSE; - return TRUE; -} - -static BonoboObject * -outlook_factory_fn (BonoboGenericFactory *_factory, - void *closure) -{ - EvolutionImporter *importer; - OutlookImporter *oli; - - oli = g_new0 (OutlookImporter, 1); - - importer = evolution_importer_new (support_format_fn, load_file_fn, - process_item_fn, NULL, oli); - gtk_signal_connect (GTK_OBJECT (importer), "destroy", - GTK_SIGNAL_FUNC (importer_destroy_cb), oli); - - return BONOBO_OBJECT (importer); -} - -/* Entry point */ -void -mail_importer_module_init (void) -{ - static gboolean initialised = FALSE; - BonoboGenericFactory *factory; - - if (initialised == TRUE) - return; - - factory = bonobo_generic_factory_new (OUTLOOK_FACTORY_IID, - outlook_factory_fn, NULL); - - if (factory == NULL) - g_warning ("Could not initialise Outlook importer factory."); - - initialised = TRUE; -} - - diff --git a/mail/importers/mail-importer.c b/mail/importers/mail-importer.c new file mode 100644 index 0000000000..19df23d03c --- /dev/null +++ b/mail/importers/mail-importer.c @@ -0,0 +1,415 @@ +/* + * 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 <http://www.gnu.org/licenses/> + * + * + * Authors: + * Iain Holmes <iain@ximian.com> + * Michael Zucchi <notzed@ximian.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <string.h> +#include <sys/types.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> + +#include <glib/gstdio.h> +#include <glib/gi18n.h> + +#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 "mail-importer.h" + +struct _import_mbox_msg { + MailMsg base; + + EMailSession *session; + gchar *path; + gchar *uri; + GCancellable *cancellable; + + void (*done)(gpointer data, GError **error); + gpointer done_data; +}; + +static gchar * +import_mbox_desc (struct _import_mbox_msg *m) +{ + return g_strdup (_("Importing mailbox")); +} + +static struct { + gchar tag; + guint32 mozflag; + guint32 flag; +} status_flags[] = { + { 'F', MSG_FLAG_MARKED, CAMEL_MESSAGE_FLAGGED }, + { 'A', MSG_FLAG_REPLIED, CAMEL_MESSAGE_ANSWERED }, + { 'D', MSG_FLAG_EXPUNGED, CAMEL_MESSAGE_DELETED }, + { 'R', MSG_FLAG_READ, CAMEL_MESSAGE_SEEN }, +}; + +static guint32 +decode_status (const gchar *status) +{ + const gchar *p; + guint32 flags = 0; + gint i; + + p = status; + while ((*p++)) { + for (i = 0; i < G_N_ELEMENTS (status_flags); i++) + if (status_flags[i].tag == *p) + flags |= status_flags[i].flag; + } + + return flags; +} + +static guint32 +decode_mozilla_status (const gchar *tmp) +{ + gulong status = strtoul (tmp, NULL, 16); + guint32 flags = 0; + gint i; + + for (i = 0; i < G_N_ELEMENTS (status_flags); i++) + if (status_flags[i].mozflag & status) + flags |= status_flags[i].flag; + return flags; +} + +static void +import_mbox_exec (struct _import_mbox_msg *m, + GCancellable *cancellable, + GError **error) +{ + CamelFolder *folder; + CamelMimeParser *mp = NULL; + struct stat st; + gint fd; + CamelMessageInfo *info; + + if (g_stat (m->path, &st) == -1) { + g_warning ( + "cannot find source file to import '%s': %s", + m->path, g_strerror (errno)); + return; + } + + if (m->uri == NULL || m->uri[0] == 0) + folder = e_mail_session_get_local_folder ( + m->session, E_MAIL_LOCAL_FOLDER_INBOX); + else + folder = e_mail_session_uri_to_folder_sync ( + m->session, m->uri, CAMEL_STORE_FOLDER_CREATE, + cancellable, error); + + if (folder == NULL) + return; + + if (S_ISREG (st.st_mode)) { + fd = g_open (m->path, O_RDONLY | O_BINARY, 0); + if (fd == -1) { + g_warning ( + "cannot find source file to import '%s': %s", + m->path, g_strerror (errno)); + goto fail1; + } + + mp = camel_mime_parser_new (); + camel_mime_parser_scan_from (mp, TRUE); + if (camel_mime_parser_init_with_fd (mp, fd) == -1) { + /* will never happen - 0 is unconditionally returned */ + goto fail2; + } + + camel_operation_push_message ( + m->cancellable, _("Importing '%s'"), + camel_folder_get_display_name (folder)); + camel_folder_freeze (folder); + while (camel_mime_parser_step (mp, NULL, NULL) == + CAMEL_MIME_PARSER_STATE_FROM) { + + CamelMimeMessage *msg; + const gchar *tmp; + gint pc = 0; + guint32 flags = 0; + + if (st.st_size > 0) + pc = (gint) (100.0 * ((gdouble) + camel_mime_parser_tell (mp) / + (gdouble) st.st_size)); + camel_operation_progress (m->cancellable, pc); + + msg = camel_mime_message_new (); + if (!camel_mime_part_construct_from_parser_sync ( + (CamelMimePart *) msg, mp, NULL, NULL)) { + /* set exception? */ + g_object_unref (msg); + break; + } + + info = camel_message_info_new (NULL); + + tmp = camel_medium_get_header ((CamelMedium *) msg, "X-Mozilla-Status"); + if (tmp) + flags |= decode_mozilla_status (tmp); + tmp = camel_medium_get_header ((CamelMedium *) msg, "Status"); + if (tmp) + flags |= decode_status (tmp); + tmp = camel_medium_get_header ((CamelMedium *) msg, "X-Status"); + if (tmp) + flags |= decode_status (tmp); + + 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); + + if (error && *error != NULL) + break; + + camel_mime_parser_step (mp, NULL, NULL); + } + /* FIXME Not passing a GCancellable or GError here. */ + camel_folder_synchronize_sync (folder, FALSE, NULL, NULL); + camel_folder_thaw (folder); + camel_operation_pop_message (m->cancellable); + fail2: + g_object_unref (mp); + } +fail1: + /* FIXME Not passing a GCancellable or GError here. */ + camel_folder_synchronize_sync (folder, FALSE, NULL, NULL); + g_object_unref (folder); +} + +static void +import_mbox_done (struct _import_mbox_msg *m) +{ + if (m->done) + m->done (m->done_data, &m->base.error); +} + +static void +import_mbox_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, + (MailMsgExecFunc) import_mbox_exec, + (MailMsgDoneFunc) import_mbox_done, + (MailMsgFreeFunc) import_mbox_free +}; + +gint +mail_importer_import_mbox (EMailSession *session, + const gchar *path, + const gchar *folderuri, + GCancellable *cancellable, + void (*done) (gpointer data, + GError **error), + gpointer data) +{ + struct _import_mbox_msg *m; + gint id; + + m = mail_msg_new (&import_mbox_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_mbox_sync (EMailSession *session, + const gchar *path, + const gchar *folderuri, + GCancellable *cancellable) +{ + struct _import_mbox_msg *m; + + m = mail_msg_new (&import_mbox_info); + m->session = g_object_ref (session); + m->path = g_strdup (path); + m->uri = g_strdup (folderuri); + if (cancellable) + m->base.cancellable = cancellable; + + cancellable = m->base.cancellable; + + import_mbox_exec (m, cancellable, &m->base.error); + import_mbox_done (m); + mail_msg_unref (m); +} + +struct _import_folders_data { + MailImporterSpecial *special_folders; + EMailSession *session; + GCancellable *cancellable; + + guint elmfmt : 1; +}; + +static void +import_folders_rec (struct _import_folders_data *m, + const gchar *filepath, + const gchar *folderparent) +{ + GDir *dir; + const gchar *d; + struct stat st; + const gchar *data_dir; + gchar *filefull, *foldersub, *uri, *utf8_filename; + const gchar *folder; + + dir = g_dir_open (filepath, 0, NULL); + if (dir == NULL) + return; + + data_dir = mail_session_get_data_dir (); + + utf8_filename = g_filename_to_utf8 (filepath, -1, NULL, NULL, NULL); + camel_operation_push_message (m->cancellable, _("Scanning %s"), utf8_filename); + g_free (utf8_filename); + + while ((d = g_dir_read_name (dir))) { + if (d[0] == '.') + continue; + + filefull = g_build_filename (filepath, d, NULL); + + /* skip non files and directories, and skip directories in mozilla mode */ + if (g_stat (filefull, &st) == -1 + || !(S_ISREG (st.st_mode) + || (m->elmfmt && S_ISDIR (st.st_mode)))) { + g_free (filefull); + continue; + } + + folder = d; + if (folderparent == NULL) { + gint i; + + for (i = 0; m->special_folders[i].orig; i++) + if (strcmp (m->special_folders[i].orig, folder) == 0) { + folder = m->special_folders[i].new; + break; + } + /* FIXME: need a better way to get default store location */ + uri = g_strdup_printf ( + "mbox:%s/local#%s", data_dir, folder); + } else { + uri = g_strdup_printf ( + "mbox:%s/local#%s/%s", + data_dir, folderparent, folder); + } + + printf ("importing to uri %s\n", uri); + mail_importer_import_mbox_sync ( + m->session, filefull, uri, m->cancellable); + g_free (uri); + + /* This little gem re-uses the stat buffer and filefull + * to automagically scan mozilla-format folders. */ + if (!m->elmfmt) { + gchar *tmp = g_strdup_printf ("%s.sbd", filefull); + + g_free (filefull); + filefull = tmp; + if (g_stat (filefull, &st) == -1) { + g_free (filefull); + continue; + } + } + + if (S_ISDIR (st.st_mode)) { + foldersub = folderparent ? + g_strdup_printf ( + "%s/%s", folderparent, folder) : + g_strdup (folder); + import_folders_rec (m, filefull, foldersub); + g_free (foldersub); + } + + g_free (filefull); + } + g_dir_close (dir); + + camel_operation_pop_message (m->cancellable); +} + +/** + * mail_importer_import_folders_sync: + * @filepath: + * @: + * @flags: + * @cancel: + * + * import from a base path @filepath into the root local folder tree, + * scanning all sub-folders. + * + * if @flags is MAIL_IMPORTER_MOZFMT, then subfolders are assumed to + * be in mozilla/evolutoin 1.5 format, appending '.sbd' to the + * directory name. Otherwise they are in elm/mutt/pine format, using + * standard unix directories. + **/ +void +mail_importer_import_folders_sync (EMailSession *session, + const gchar *filepath, + MailImporterSpecial special_folders[], + gint flags, + GCancellable *cancellable) +{ + struct _import_folders_data m; + + m.special_folders = special_folders; + m.elmfmt = (flags & MAIL_IMPORTER_MOZFMT) == 0; + m.session = g_object_ref (session); + m.cancellable = cancellable; + + import_folders_rec (&m, filepath, NULL); +} diff --git a/mail/importers/mail-importer.h b/mail/importers/mail-importer.h new file mode 100644 index 0000000000..11e97955d6 --- /dev/null +++ b/mail/importers/mail-importer.h @@ -0,0 +1,77 @@ +/* + * + * 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 <http://www.gnu.org/licenses/> + * + * + * Authors: + * Iain Holmes <iain@ximian.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef __MAIL_IMPORTER_H__ +#define __MAIL_IMPORTER_H__ + +#include <camel/camel.h> +#include <e-util/e-util.h> +#include <libemail-engine/e-mail-session.h> + +EImportImporter *mbox_importer_peek (void); + +typedef void (*MboxImporterCreatePreviewFunc)(GObject *preview, GtkWidget **preview_widget); +typedef void (*MboxImporterFillPreviewFunc)(GObject *preview, CamelMimeMessage *msg); + +/* 'create_func' is a function to create a view. 'fill_func' is to fill view with a preview of a message 'msg' + * (mail importer cannot link to em-format-html-display directly) */ +void mbox_importer_set_preview_funcs (MboxImporterCreatePreviewFunc create_func, MboxImporterFillPreviewFunc fill_func); + +EImportImporter *elm_importer_peek (void); +EImportImporter *pine_importer_peek (void); + +/* Defines copied from nsMsgMessageFlags.h in Mozilla source. */ +/* Evolution only cares about these headers I think */ +#define MSG_FLAG_READ 0x0001 +#define MSG_FLAG_REPLIED 0x0002 +#define MSG_FLAG_MARKED 0x0004 +#define MSG_FLAG_EXPUNGED 0x0008 + +gint mail_importer_import_mbox (EMailSession *session, + const gchar *path, + const gchar *folderuri, + GCancellable *cancellable, + void (*done)(gpointer data, GError **), + gpointer data); +void mail_importer_import_mbox_sync (EMailSession *session, + const gchar *path, + const gchar *folderuri, + GCancellable *cancellable); + +struct _MailImporterSpecial { + const gchar *orig, *new; +}; +typedef struct _MailImporterSpecial MailImporterSpecial; + +/* mozilla format subdirs */ +#define MAIL_IMPORTER_MOZFMT (1<<0) + +/* api in flux */ +void mail_importer_import_folders_sync + (EMailSession *session, + const gchar *filepath, + MailImporterSpecial special_folders[], + gint flags, + GCancellable *cancellable); + +#endif diff --git a/mail/importers/mozilla-status-headers.h b/mail/importers/mozilla-status-headers.h deleted file mode 100644 index f459d6ec8f..0000000000 --- a/mail/importers/mozilla-status-headers.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* mozilla-status-headers.h - * - * Authors: Iain Holmes <iain@ximian.com> - * - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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. - */ - -/* Defines copied from nsMsgMessageFlags.h in Mozilla source. */ - -/* Evolution only cares about these headers I think */ -#define MSG_FLAG_READ 0x0001 -#define MSG_FLAG_REPLIED 0x0002 -#define MSG_FLAG_MARKED 0x0004 -#define MSG_FLAG_EXPUNGED 0x0008 diff --git a/mail/importers/pine-importer.c b/mail/importers/pine-importer.c new file mode 100644 index 0000000000..c37d3bd809 --- /dev/null +++ b/mail/importers/pine-importer.c @@ -0,0 +1,478 @@ +/* + * 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 <http://www.gnu.org/licenses/> + * + * + * Authors: + * Iain Holmes <iain@ximian.com> + * Michael Zucchi <notzed@ximian.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <dirent.h> +#include <string.h> + +#include <gtk/gtk.h> +#include <glib/gi18n.h> + +#include <libebook/libebook.h> + +#include "mail-importer.h" + +#include "libemail-engine/mail-mt.h" +#include "mail/e-mail-backend.h" +#include "shell/e-shell.h" + +#define d(x) + +struct _pine_import_msg { + MailMsg base; + + EImport *import; + EImportTarget *target; + + GMutex status_lock; + gchar *status_what; + gint status_pc; + gint status_timeout_id; + GCancellable *cancellable; +}; + +static gboolean +pine_supported (EImport *ei, + EImportTarget *target, + EImportImporter *im) +{ + gchar *maildir, *addrfile; + gboolean md_exists, addr_exists; + + if (target->type != E_IMPORT_TARGET_HOME) + return FALSE; + + maildir = g_build_filename (g_get_home_dir (), "mail", NULL); + md_exists = g_file_test (maildir, G_FILE_TEST_IS_DIR); + g_free (maildir); + + addrfile = g_build_filename (g_get_home_dir (), ".addressbook", NULL); + addr_exists = g_file_test (addrfile, G_FILE_TEST_IS_REGULAR); + g_free (addrfile); + + return md_exists || addr_exists; +} + +/* + * See: http://www.washington.edu/pine/tech-notes/low-level.html + * + * addressbook line is: + * <nickname>TAB<fullname>TAB<address>TAB<fcc>TAB<comments> + * lists, address is: + * "(" <address>, <address>, <address>, ... ")" + * + * <address> is rfc822 address, or alias address. + * if rfc822 address includes a phrase, then that overrides <fullname> + * + * FIXME: we dont handle aliases in lists. + */ + +static void +import_contact (EBookClient *book_client, + gchar *line) +{ + gchar **strings, *addr, **addrs; + gint i; + GList *list; + /*EContactName *name;*/ + EContact *card; + gsize len; + GError *error = NULL; + + card = e_contact_new (); + strings = g_strsplit (line, "\t", 5); + if (strings[0] && strings[1] && strings[2]) { + gchar *new_uid = NULL; + + e_contact_set (card, E_CONTACT_NICKNAME, strings[0]); + e_contact_set (card, E_CONTACT_FULL_NAME, strings[1]); + + addr = strings[2]; + len = strlen (addr); + if (addr[0] == '(' && addr[len - 1] == ')') { + addr[0] = 0; + addr[len - 1] = 0; + addrs = g_strsplit (addr + 1, ",", 0); + list = NULL; + /* XXX So ... this api is just insane ... we set + * plain strings as the contact email if it + * is a normal contact, but need to do this + * XML crap for mailing lists. */ + for (i = 0; addrs[i]; i++) { + EDestination *d; + EVCardAttribute *attr; + + d = e_destination_new (); + e_destination_set_email (d, addrs[i]); + + attr = e_vcard_attribute_new (NULL, EVC_EMAIL); + e_destination_export_to_vcard_attribute (d, attr); + list = g_list_append (list, attr); + g_object_unref (d); + } + e_contact_set_attributes (card, E_CONTACT_EMAIL, list); + g_list_foreach (list, (GFunc) e_vcard_attribute_free, NULL); + g_list_free (list); + g_strfreev (addrs); + e_contact_set (card, E_CONTACT_IS_LIST, GINT_TO_POINTER (TRUE)); + } else { + e_contact_set (card, E_CONTACT_EMAIL_1, strings[2]); + } + + /*name = e_contact_name_from_string(strings[1]);*/ + + if (strings[3] && strings[4]) + e_contact_set (card, E_CONTACT_NOTE, strings[4]); + + e_book_client_add_contact_sync ( + book_client, card, &new_uid, NULL, &error); + + if (error != NULL) { + g_warning ( + "%s: Failed to add contact: %s", + G_STRFUNC, error->message); + g_error_free (error); + } else { + g_free (new_uid); + } + + g_object_unref (card); + } + g_strfreev (strings); +} + +static void +import_contacts (void) +{ + EShell *shell; + ESourceRegistry *registry; + EClient *client = NULL; + GList *list; + gchar *name; + GString *line; + FILE *fp; + gsize offset; + const gchar *extension_name; + GError *error = NULL; + + printf ("importing pine addressbook\n"); + + shell = e_shell_get_default (); + registry = e_shell_get_registry (shell); + extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK; + + name = g_build_filename (g_get_home_dir (), ".addressbook", NULL); + fp = fopen (name, "r"); + g_free (name); + if (fp == NULL) + return; + + list = e_source_registry_list_sources (registry, extension_name); + + if (list != NULL) { + ESource *source; + + source = E_SOURCE (list->data); + client = e_book_client_connect_sync (source, NULL, &error); + } + + g_list_free_full (list, (GDestroyNotify) g_object_unref); + + if (error != NULL) { + g_warning ( + "%s: Failed to open book client: %s", + G_STRFUNC, error ? error->message : "Unknown error"); + g_clear_error (&error); + fclose (fp); + return; + } + + line = g_string_new (""); + g_string_set_size (line, 256); + offset = 0; + while (fgets (line->str + offset, 256, fp)) { + gsize len; + + len = strlen (line->str + offset) + offset; + if (line->str[len - 1] == '\n') + g_string_truncate (line, len - 1); + else if (!feof (fp)) { + offset = len; + g_string_set_size (line, len + 256); + continue; + } else { + g_string_truncate (line, len); + } + + import_contact (E_BOOK_CLIENT (client), line->str); + offset = 0; + } + + g_string_free (line, TRUE); + fclose (fp); + g_object_unref (client); +} + +static gchar * +pine_import_desc (struct _pine_import_msg *m) +{ + return g_strdup (_("Importing Pine data")); +} + +static MailImporterSpecial pine_special_folders[] = { + { "sent-mail", "Sent" }, /* pine */ + { "saved-messages", "Drafts" }, /* pine */ + { NULL }, +}; + +static void +pine_import_exec (struct _pine_import_msg *m, + GCancellable *cancellable, + GError **error) +{ + EShell *shell; + EShellBackend *shell_backend; + EMailSession *session; + + /* 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)); + + if (GPOINTER_TO_INT (g_datalist_get_data (&m->target->data, "pine-do-addr"))) + import_contacts (); + + if (GPOINTER_TO_INT (g_datalist_get_data (&m->target->data, "pine-do-mail"))) { + gchar *path; + + path = g_build_filename (g_get_home_dir (), "mail", NULL); + mail_importer_import_folders_sync ( + session, path, pine_special_folders, 0, m->cancellable); + g_free (path); + } +} + +static void +pine_import_done (struct _pine_import_msg *m) +{ + e_import_complete (m->import, (EImportTarget *) m->target); +} + +static void +pine_import_free (struct _pine_import_msg *m) +{ + g_object_unref (m->cancellable); + + g_free (m->status_what); + g_mutex_clear (&m->status_lock); + + g_source_remove (m->status_timeout_id); + m->status_timeout_id = 0; + + g_object_unref (m->import); +} + +static void +pine_status (CamelOperation *op, + const gchar *what, + gint pc, + gpointer data) +{ + struct _pine_import_msg *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 +pine_status_timeout (struct _pine_import_msg *importer) +{ + 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 MailMsgInfo pine_import_info = { + sizeof (struct _pine_import_msg), + (MailMsgDescFunc) pine_import_desc, + (MailMsgExecFunc) pine_import_exec, + (MailMsgDoneFunc) pine_import_done, + (MailMsgFreeFunc) pine_import_free +}; + +static gint +mail_importer_pine_import (EImport *ei, + EImportTarget *target) +{ + struct _pine_import_msg *m; + gint id; + + m = mail_msg_new (&pine_import_info); + g_datalist_set_data (&target->data, "pine-msg", m); + m->import = ei; + g_object_ref (m->import); + m->target = target; + m->status_timeout_id = g_timeout_add ( + 100, (GSourceFunc) pine_status_timeout, m); + g_mutex_init (&m->status_lock); + m->cancellable = camel_operation_new (); + + g_signal_connect ( + m->cancellable, "status", + G_CALLBACK (pine_status), m); + + id = m->base.seq; + + mail_msg_fast_ordered_push (m); + + return id; +} + +static void +checkbox_mail_toggle_cb (GtkToggleButton *tb, + EImportTarget *target) +{ + gboolean active; + + active = gtk_toggle_button_get_active (tb); + + g_datalist_set_data ( + &target->data, "pine-do-mail", + GINT_TO_POINTER (active)); +} + +static void +checkbox_addr_toggle_cb (GtkToggleButton *tb, + EImportTarget *target) +{ + gboolean active; + + active = gtk_toggle_button_get_active (tb); + + g_datalist_set_data ( + &target->data, "pine-do-addr", + GINT_TO_POINTER (active)); +} + +static GtkWidget * +pine_getwidget (EImport *ei, + EImportTarget *target, + EImportImporter *im) +{ + GtkWidget *box, *w; + + g_datalist_set_data ( + &target->data, "pine-do-mail", + GINT_TO_POINTER (TRUE)); + g_datalist_set_data ( + &target->data, "pine-do-addr", + GINT_TO_POINTER (TRUE)); + + box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 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_mail_toggle_cb), target); + gtk_box_pack_start ((GtkBox *) box, w, FALSE, FALSE, 0); + + w = gtk_check_button_new_with_label (_("Address Book")); + gtk_toggle_button_set_active ((GtkToggleButton *) w, TRUE); + g_signal_connect ( + w, "toggled", + G_CALLBACK (checkbox_addr_toggle_cb), target); + gtk_box_pack_start ((GtkBox *) box, w, FALSE, FALSE, 0); + + gtk_widget_show_all (box); + + return box; +} + +static void +pine_import (EImport *ei, + EImportTarget *target, + EImportImporter *im) +{ + if (GPOINTER_TO_INT (g_datalist_get_data (&target->data, "pine-do-mail")) + || GPOINTER_TO_INT (g_datalist_get_data (&target->data, "pine-do-addr"))) + mail_importer_pine_import (ei, target); + else + e_import_complete (ei, target); +} + +static void +pine_cancel (EImport *ei, + EImportTarget *target, + EImportImporter *im) +{ + struct _pine_import_msg *m = g_datalist_get_data (&target->data, "pine-msg"); + + if (m) + g_cancellable_cancel (m->cancellable); +} + +static EImportImporter pine_importer = { + E_IMPORT_TARGET_HOME, + 0, + pine_supported, + pine_getwidget, + pine_import, + pine_cancel, + NULL, /* get_preview */ +}; + +EImportImporter * +pine_importer_peek (void) +{ + pine_importer.name = _("Evolution Pine importer"); + pine_importer.description = _("Import mail from Pine."); + + return &pine_importer; +} |