From 2dd6f4d7deacc0410411b47d77c1ba60cc927af0 Mon Sep 17 00:00:00 2001 From: Not Zed Date: Wed, 5 Feb 2003 04:25:40 +0000 Subject: update from ../../importers/. (main): Removed. 2003-02-05 Not Zed * importers/netscape-importer.c: update from ../../importers/. (main): Removed. (mail_importer_module_init): Setup module init fn. (factory_fn): api changes. (is_dir_empty): deprecated changes, and clean up logic. (importer_cb): pulse progress bar, use idle function for processing next item. (import_next): Remove link before recursing, also fix memleak, and api changes. (netscape_import_file): dont release importer. (*): gconf'ify * importers/elm-importer.c (elm_factory_fn): Track the evolution_intelligent_importer, so we can unref it when done. (*): gconf'ify. * importers/pine-importer.c (parse_line): use gobject stuff rather than gtkobject. (import_addressfile): close down 'properly' when finished. (importer_timeout_fn): Do most processing decisions here, either from a timeout or idle function. This prevents us getting 1 stack frame per message and per folder. Close down properly also. (importer_cb): Add a timeout, ignore the callback, or add an idle function to process the next item. (pine_import_file): dont release the importer if we can't load it, its released elsewhere, i think. (import_addressfile): step the progress bar as we go. (factory_fn): Track the evolution_intelligent_importer, so we can unref when done. (*): gconf'ify 2003-01-31 Not Zed * importers/elm-importer.c (elm_can_import): g_file_exists -> lstat, and g_build_filename api changes. * importers/pine-importer.c: moved from ../../importers/pine-importer.c (factory_fn): oaf->bonobo_activation (mail_importer_module_init): setup factory. (main): Removed. (*): REemove bonobo config stuff. (factory_fn): destroy signal -> weak ref. (pine_destroy_cb): Fix signature for weak ref notify. (import_addressfile): use new glib filename stuff. (import_addressbook): same. (pine_can_import): and here. (import_next): and here. (scan_dir): and here (pine_create_structure): And here. (pine_can_import): g_file_exists -> lstat. (importer_cb): If there are more items, use an idle handler to drop back a few stack frames rather than recursing for each message. (import_next): unlink data from dir_list before recursing, and fix leak. 2003-01-30 Not Zed * importers/elm-importer.c (elm_destroy_cb): Change for weak ref setup. (elm_factory_fn): destroy -> weak ref. 2003-01-29 Not Zed * importers/elm-importer.c (importer_cb): Pass processItem off to an idle handler, so we dont blow our stacks. Also update to use progress_bar_pulse(). (import_item_idle): Get the next message here instead. (import_next): Fix a glist leak. Unlink the file before we import it too. And close the dialogue and clean up when we've run out of folders to import. 2003-01-17 Not Zed * importers/elm-importer.c (elm_create_structure): use/free elmdir rather than double-free maildir. 2003-01-16 Not Zed * importers/elm-importer.c: update from ../importers/elm-importer.c svn path=/trunk/; revision=19752 --- mail/importers/elm-importer.c | 593 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 593 insertions(+) create mode 100644 mail/importers/elm-importer.c (limited to 'mail/importers/elm-importer.c') diff --git a/mail/importers/elm-importer.c b/mail/importers/elm-importer.c new file mode 100644 index 0000000000..439a6a69b9 --- /dev/null +++ b/mail/importers/elm-importer.c @@ -0,0 +1,593 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* elm-importer.c + * + * Authors: + * Iain Holmes + * + * Copyright 2001 Ximian, Inc. (www.ximian.com) + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#define ELM_INTELLIGENT_IMPORTER_IID "OAFIID:GNOME_Evolution_Mail_Elm_Intelligent_Importer_Factory" +#define MBOX_IMPORTER_IID "OAFIID:GNOME_Evolution_Mail_Mbox_Importer" +#define KEY "elm-mail-imported" + +/*#define SUPER_IMPORTER_DEBUG*/ +#ifdef SUPER_IMPORTER_DEBUG +#define d(x) x +#else +#define d(x) +#endif + +typedef struct { + EvolutionIntelligentImporter *ii; + + GList *dir_list; + + int num; + int progress_count; + int import_id; + + GNOME_Evolution_Importer importer; + EvolutionImporterListener *listener; + + GtkWidget *mail; + gboolean do_mail; + + GtkWidget *dialog; + GtkWidget *label; + GtkWidget *progressbar; +} ElmImporter; + +typedef struct { + char *parent; + char *foldername; + char *path; +} ElmFolder; + +static GHashTable *elm_prefs = NULL; + +static void import_next (ElmImporter *importer); + +static GtkWidget * +create_importer_gui (ElmImporter *importer) +{ + GtkWidget *dialog; + + dialog = gnome_message_box_new (_("Evolution is importing your old Elm mail"), GNOME_MESSAGE_BOX_INFO, NULL); + gtk_window_set_title (GTK_WINDOW (dialog), _("Importing...")); + + importer->label = gtk_label_new (_("Please wait")); + importer->progressbar = gtk_progress_bar_new (); + gtk_progress_set_activity_mode (GTK_PROGRESS (importer->progressbar), TRUE); + gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), importer->label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), importer->progressbar, FALSE, FALSE, 0); + + return dialog; +} + +static void +elm_store_settings (ElmImporter *importer) +{ + GConfClient *gconf; + + gconf = gconf_client_get_default (); + gconf_client_set_bool (gconf, "/apps/evolution/importer/elm/mail", importer->do_mail, NULL); +} + +static void +elm_restore_settings (ElmImporter *importer) +{ + GConfClient *gconf = gconf_client_get_default (); + + importer->do_mail = gconf_client_get_bool (gconf, "/apps/evolution/importer/elm/mail", NULL); +} + +static gboolean +import_item_idle(void *data) +{ + ElmImporter *importer = data; + CORBA_Environment ev; + + importer->import_id = 0; + + CORBA_exception_init (&ev); + GNOME_Evolution_Importer_processItem (importer->importer, + bonobo_object_corba_objref (BONOBO_OBJECT (importer->listener)), + &ev); + if (ev._major != CORBA_NO_EXCEPTION) + g_warning ("Exception: %s", CORBA_exception_id (&ev)); + + CORBA_exception_free (&ev); + + return FALSE; +} + +static void +importer_cb (EvolutionImporterListener *listener, + EvolutionImporterResult result, + gboolean more_items, + void *data) +{ + ElmImporter *importer = (ElmImporter *) data; + CORBA_Object objref; + CORBA_Environment ev; + + if (more_items) { + g_assert(importer->import_id == 0); + importer->progress_count++; + if ((importer->progress_count & 0xf) == 0) + gtk_progress_bar_pulse(GTK_PROGRESS_BAR(importer->progressbar)); + importer->import_id = g_idle_add(import_item_idle, importer); + } else { + import_next (importer); + } +} + +static gboolean +elm_import_file (ElmImporter *importer, + const char *path, + const char *folderpath) +{ + CORBA_boolean result; + CORBA_Environment ev; + CORBA_Object objref; + char *str; + + CORBA_exception_init (&ev); + + str = g_strdup_printf (_("Importing %s as %s"), path, folderpath); + gtk_label_set_text (GTK_LABEL (importer->label), str); + g_free (str); + while (gtk_events_pending ()) { + gtk_main_iteration (); + } + + result = GNOME_Evolution_Importer_loadFile (importer->importer, path, + folderpath, &ev); + if (ev._major != CORBA_NO_EXCEPTION || result == FALSE) { + g_warning ("Exception here: %s", CORBA_exception_id (&ev)); + CORBA_exception_free (&ev); + return FALSE; + } + + importer->listener = evolution_importer_listener_new (importer_cb, + importer); + objref = bonobo_object_corba_objref (BONOBO_OBJECT (importer->listener)); + GNOME_Evolution_Importer_processItem (importer->importer, objref, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Exception: %s", CORBA_exception_id (&ev)); + CORBA_exception_free (&ev); + return FALSE; + } + CORBA_exception_free (&ev); + + return TRUE; +} + +static void +parse_elm_rc (const char *elmrc) +{ + static gboolean parsed = FALSE; + char line[4096]; + FILE *handle; + gboolean exists; + + if (parsed == TRUE) + return; + + elm_prefs = g_hash_table_new (g_str_hash, g_str_equal); + + exists = g_file_exists (elmrc); + if (exists == FALSE) { + parsed = TRUE; + return; + } + + handle = fopen (elmrc, "r"); + if (handle == NULL) { + parsed = TRUE; + return; + } + + while (fgets (line, 4096, handle) != NULL) { + char *linestart, *end; + char *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 (elm_prefs, key, value); + } + + parsed = TRUE; + fclose (handle); +} + +static char * +elm_get_rc_value (const char *value) +{ + if (elm_prefs == NULL) + return NULL; + + return g_hash_table_lookup (elm_prefs, value); +} + +static gboolean +elm_can_import (EvolutionIntelligentImporter *ii, + void *closure) +{ + ElmImporter *importer = closure; + char *elmdir, *maildir, *aliasfile; + char *elmrc; + gboolean exists, mailexists, aliasexists; + gboolean mail, alias; + struct stat st; + GConfClient *gconf = gconf_client_get_default(); + + mail = gconf_client_get_bool(gconf, "/apps/evolution/importer/elm/mail-imported", NULL); + if (mail) + return FALSE; + + importer->do_mail = !mail; + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (importer->mail), + importer->do_mail); + + elmdir = gnome_util_prepend_user_home (".elm"); + exists = lstat(elmdir, &st) == 0 && S_ISDIR(st.st_mode); + + g_free (elmdir); + if (exists == FALSE) + return FALSE; + + elmrc = gnome_util_prepend_user_home (".elm/elmrc"); + parse_elm_rc (elmrc); + + maildir = elm_get_rc_value ("maildir"); + if (maildir == NULL) { + maildir = g_strdup ("Mail"); + } else { + maildir = g_strdup (maildir); + } + + if (!g_path_is_absolute (maildir)) { + elmdir = gnome_util_prepend_user_home (maildir); + } else { + elmdir = g_strdup (maildir); + } + + g_free (maildir); + + mailexists = lstat(elmdir, &st) == 0 && S_ISDIR(st.st_mode); + g_free (elmdir); + + aliasfile = gnome_util_prepend_user_home (".elm/aliases"); + aliasexists = lstat(aliasfile, &st) == 0 && S_ISREG(st.st_mode); + g_free (aliasfile); + + exists = (aliasexists || mailexists); + + return exists; +} + +static void +import_next (ElmImporter *importer) +{ + ElmFolder *data; + + if (importer->dir_list) { + char *folder; + GList *l; + + l = importer->dir_list; + data = l->data; + + folder = g_concat_dir_and_file (data->parent, data->foldername); + + importer->dir_list = l->next; + g_list_free_1(l); + + elm_import_file (importer, data->path, folder); + g_free (folder); + g_free (data->parent); + g_free (data->path); + g_free (data->foldername); + g_free (data); + } else { + bonobo_object_unref((BonoboObject *)importer->ii); + } +} + +static void +scan_dir (ElmImporter *importer, + const char *orig_parent, + const char *dirname) +{ + DIR *maildir; + struct stat buf; + struct dirent *current; + char *str; + + maildir = opendir (dirname); + if (maildir == NULL) { + g_warning ("Could not open %s\nopendir returned: %s", + dirname, g_strerror (errno)); + return; + } + + str = g_strdup_printf (_("Scanning %s"), dirname); + gtk_label_set_text (GTK_LABEL (importer->label), str); + g_free (str); + + while (gtk_events_pending ()) { + gtk_main_iteration (); + } + + current = readdir (maildir); + while (current) { + ElmFolder *pf; + char *fullname; + + /* Ignore . and .. */ + if (current->d_name[0] == '.') { + if (current->d_name[1] == '\0' || + (current->d_name[1] == '.' && current->d_name[2] == '\0')) { + current = readdir (maildir); + continue; + } + } + + fullname = g_concat_dir_and_file (dirname, current->d_name); + if (stat (fullname, &buf) == -1) { + g_warning ("Could not stat %s\nstat returned: %s", + fullname, g_strerror (errno)); + current = readdir (maildir); + g_free (fullname); + continue; + } + + if (S_ISREG (buf.st_mode)) { + pf = g_new (ElmFolder, 1); + pf->path = g_strdup (fullname); + pf->parent = g_strdup (orig_parent); + pf->foldername = g_strdup (current->d_name); + importer->dir_list = g_list_append (importer->dir_list, pf); + } else if (S_ISDIR (buf.st_mode)) { + char *subdir; + + pf = g_new (ElmFolder, 1); + pf->path = NULL; + pf->parent = g_strdup (orig_parent); + pf->foldername = g_strdup (current->d_name); + importer->dir_list = g_list_append (importer->dir_list, pf); + + subdir = g_concat_dir_and_file (orig_parent, current->d_name); + scan_dir (importer, subdir, fullname); + g_free (subdir); + } + + g_free (fullname); + current = readdir (maildir); + } +} + +static void +elm_create_structure (EvolutionIntelligentImporter *ii, + void *closure) +{ + CORBA_Environment ev; + ElmImporter *importer = closure; + char *maildir; + + /* Reference our object so when the shell release_unrefs us + we will still exist and not go byebye */ + bonobo_object_ref (BONOBO_OBJECT (ii)); + + elm_store_settings (importer); + + if (importer->do_mail == TRUE) { + char *elmdir; + GConfClient *gconf = gconf_client_get_default(); + + importer->dialog = create_importer_gui (importer); + gtk_widget_show_all (importer->dialog); + while (gtk_events_pending ()) { + gtk_main_iteration (); + } + + gconf_client_set_bool(gconf, "/apps/evolution/importer/elm/mail-imported", TRUE, NULL); + + maildir = elm_get_rc_value ("maildir"); + if (maildir == NULL) { + maildir = g_strdup ("Mail"); + } else { + maildir = g_strdup (maildir); + } + + if (!g_path_is_absolute (maildir)) { + elmdir = gnome_util_prepend_user_home (maildir); + } else { + elmdir = g_strdup (maildir); + } + + g_free (maildir); + + scan_dir (importer, "/", elmdir); + g_free (elmdir); + + /* Import them */ + import_next (importer); + } + + bonobo_object_unref (BONOBO_OBJECT (ii)); +} + +static void +elm_destroy_cb (ElmImporter *importer, GtkObject *object) +{ + CORBA_Environment ev; + + elm_store_settings (importer); + + if (importer->dialog) + gtk_widget_destroy(importer->dialog); + + bonobo_object_release_unref (importer->importer, NULL); +} + +/* Fun initialisation stuff */ +/* Fun control stuff */ +static void +checkbox_toggle_cb (GtkToggleButton *tb, + gboolean *do_item) +{ + *do_item = gtk_toggle_button_get_active (tb); +} + +static BonoboControl * +create_checkboxes_control (ElmImporter *importer) +{ + GtkWidget *hbox; + BonoboControl *control; + + hbox = gtk_vbox_new (FALSE, 2); + + importer->mail = gtk_check_button_new_with_label (_("Mail")); + gtk_signal_connect (GTK_OBJECT (importer->mail), "toggled", + GTK_SIGNAL_FUNC (checkbox_toggle_cb), + &importer->do_mail); + + gtk_box_pack_start (GTK_BOX (hbox), importer->mail, FALSE, FALSE, 0); + + gtk_widget_show_all (hbox); + control = bonobo_control_new (hbox); + return control; +} + +static BonoboObject * +elm_factory_fn (BonoboGenericFactory *_factory, + const char *id, + void *closure) +{ + EvolutionIntelligentImporter *importer; + BonoboControl *control; + ElmImporter *elm; + CORBA_Environment ev; + char *message = N_("Evolution has found Elm mail files\n" + "Would you like to import them into Evolution?"); + + elm = g_new0 (ElmImporter, 1); + + CORBA_exception_init (&ev); + + elm_restore_settings (elm); + + elm->importer = bonobo_activation_activate_from_id (MBOX_IMPORTER_IID, 0, NULL, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_free (elm); + g_warning ("Could not start MBox importer\n%s", + CORBA_exception_id (&ev)); + CORBA_exception_free (&ev); + return NULL; + } + CORBA_exception_free (&ev); + + importer = evolution_intelligent_importer_new (elm_can_import, + elm_create_structure, + _("Elm"), + _(message), elm); + g_object_weak_ref(G_OBJECT (importer), (GWeakNotify)elm_destroy_cb, elm); + elm->ii = importer; + + control = create_checkboxes_control (elm); + bonobo_object_add_interface (BONOBO_OBJECT (importer), + BONOBO_OBJECT (control)); + return BONOBO_OBJECT (importer); +} + +void +mail_importer_module_init (void) +{ + static gboolean initialised = FALSE; + BonoboGenericFactory *factory; + + if (initialised == TRUE) + return; + + factory = bonobo_generic_factory_new (ELM_INTELLIGENT_IMPORTER_IID, + elm_factory_fn, NULL); + if (factory == NULL) + g_warning ("Could not initialise Elm Intelligent Mail Importer."); + initialised = TRUE; +} -- cgit v1.2.3