aboutsummaryrefslogtreecommitdiffstats
path: root/mail/importers
diff options
context:
space:
mode:
Diffstat (limited to 'mail/importers')
-rw-r--r--mail/importers/.cvsignore12
-rw-r--r--mail/importers/GNOME_Evolution_Mail_Mbox_Importer.oaf.in29
-rw-r--r--mail/importers/GNOME_Evolution_Mail_Outlook_Importer.oaf.in29
-rw-r--r--mail/importers/Makefile.am54
-rw-r--r--mail/importers/elm-importer.c382
-rw-r--r--mail/importers/evolution-mbox-importer.c728
-rw-r--r--mail/importers/evolution-outlook-importer.c318
-rw-r--r--mail/importers/mail-importer.c415
-rw-r--r--mail/importers/mail-importer.h77
-rw-r--r--mail/importers/mozilla-status-headers.h29
-rw-r--r--mail/importers/pine-importer.c478
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;
+}