Hi wrt http://bugzilla.gnome.org/show_bug.cgi?id=587011 , I have written a patch ( attached ) . I am not sure, where to stick the menu option ( above Expuge ? ), and believe that the plugin should select and mark the message as deleted. Is there any good reason to not do so ?
-- Ritesh Khadgaray Linux and Desktop Ph: +919970164885 blog: http://khadgaray.blogspot.com Eat Right, Exercise, Die Anyway.
diff --git a/modules/mail/Makefile.am b/modules/mail/Makefile.am index 962fc61..f304577 100644 --- a/modules/mail/Makefile.am +++ b/modules/mail/Makefile.am @@ -1,3 +1,9 @@ +error_DATA = remove-duplicates.error +errordir = $(privdatadir)/errors + +# provides error rule +...@evo_plugin_rule@ + module_LTLIBRARIES = libevolution-module-mail.la libevolution_module_mail_la_CPPFLAGS = \ @@ -58,7 +64,14 @@ libevolution_module_mail_la_LIBADD = \ $(top_builddir)/mail/importers/libevolution-mail-importers.la \ $(GNOME_PLATFORM_LIBS) -libevolution_module_mail_la_LDFLAGS = \ +EXTRA_DIST = remove-duplicates.error.xml + +BUILT_SOURCES = $(error_DATA) +CLEANFILES = $(BUILT_SOURCES) -avoid-version -module $(NO_UNDEFINED) + -include $(top_srcdir)/git.mk + + + diff --git a/modules/mail/e-mail-shell-view-actions.c b/modules/mail/e-mail-shell-view-actions.c index 22aa88e..9849e6d 100644 --- a/modules/mail/e-mail-shell-view-actions.c +++ b/modules/mail/e-mail-shell-view-actions.c @@ -18,8 +18,11 @@ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ +#include <libedataserver/md5-utils.h> +#include <camel/camel-stream-mem.h> #include "e-mail-shell-view-private.h" +#include "e-util/e-error.h" static void action_gal_save_custom_view_cb (GtkAction *action, @@ -396,6 +399,140 @@ action_mail_folder_select_all_cb (GtkAction *action, action_mail_folder_select_all_timeout_cb (message_list); } + +/* Helper for action_mail_folder_select_all_cb() */ +static const int hbucket = 16; + +static gint +run_dialog (gint n_duplicates) +{ + gchar *str; + gint response; + + str = g_strdup_printf ("%i", n_duplicates); + response = e_error_run (NULL, "remove-duplicates:delete-duplicates", str, NULL); + g_free (str); + + return response; +} + +static void +delete_message_foreach (gpointer value, gpointer data) +{ + gchar *uid = value; + CamelFolder *folder = data; + + camel_folder_delete_message (folder, uid); +} + +static guchar* +get_message_md5 (CamelFolder *folder, + const gchar *uid) +{ + CamelMimeMessage *msg; + CamelException ex; + CamelDataWrapper *content; + CamelStream *mem; + guchar *digest = NULL; + + camel_exception_init (&ex); + msg = camel_folder_get_message (folder, uid, &ex); + + if (camel_exception_is_set (&ex)) { + camel_exception_clear (&ex); + return NULL; + } + + /* get message contents */ + content = camel_medium_get_content_object ((CamelMedium *) msg); + if (!content) + return NULL; + + /* calculate MD5 */ + mem = camel_stream_mem_new (); + camel_data_wrapper_decode_to_stream (content, mem); + digest = g_new0 (guchar, hbucket); + + md5_get_digest (((CamelStreamMem *) mem)->buffer->data, + ((CamelStreamMem *) mem)->buffer->len, digest); + + camel_object_unref (mem); + camel_object_unref (msg); + + return digest; +} + +static gboolean +message_is_duplicated (GHashTable *messages, guint64 id, guchar *digest) +{ + guchar *hash_digest; + int i; + + hash_digest = g_hash_table_lookup (messages, &id); + + if (!hash_digest) + return FALSE; + + for (i = 0; i < hbucket; i++) + if (digest[i] != hash_digest[i]) + return FALSE; + + return TRUE; +} + +static void +action_mail_folder_select_duplicate (GtkAction *action, + EMailShellView *mail_shell_view) +{ + EShellView *shell_view; + EShellContent *shell_content; + EMailReader *reader; + MessageList *message_list; + GPtrArray *uids; + CamelFolder *folder; + GHashTable *messages; + GSList *duplicates = NULL; + gint i, n_duplicates; + + shell_view = E_SHELL_VIEW (mail_shell_view); + shell_content = e_shell_view_get_shell_content (shell_view); + + reader = (EMailReader *) (shell_content); + message_list = e_mail_reader_get_message_list (reader); + uids = message_list_get_uids(message_list); + folder = message_list->folder; + + messages = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, g_free); + + for (i = 0; i < uids->len; i++) { + CamelMessageInfo *msg_info = camel_folder_get_message_info (folder, uids->pdata[i]); + const CamelSummaryMessageID *mid = camel_message_info_message_id (msg_info); + guchar *digest = get_message_md5 (folder, uids->pdata[i]); + guint32 flags = camel_message_info_flags (msg_info); + + if (!(flags & CAMEL_MESSAGE_DELETED)) { + if (message_is_duplicated (messages, mid->id.id, digest)) { + duplicates = g_slist_prepend (duplicates, g_strdup (uids->pdata[i])); + } else { + guint64 *id; + id = g_new0 (guint64, 1); + *id = mid->id.id; + g_hash_table_insert (messages, id, digest); + } + } + camel_message_info_free (msg_info); + } + + n_duplicates = g_slist_length (duplicates); + + if (n_duplicates && (run_dialog (n_duplicates) == GTK_RESPONSE_OK)) + g_slist_foreach (duplicates, delete_message_foreach, folder); + + g_hash_table_destroy (messages); + g_slist_foreach (duplicates, (GFunc) g_free, NULL); + message_list_free_uids (message_list, uids); +} + static void action_mail_folder_select_thread_cb (GtkAction *action, EMailShellView *mail_shell_view) @@ -1139,6 +1276,13 @@ static GtkActionEntry mail_entries[] = { N_("Select all visible messages"), G_CALLBACK (action_mail_folder_select_all_cb) }, + { "mail-folder-select-duplicate", + NULL, + N_("Select and remove all Duplicate messages"), + "", + N_("Select and remove all duplicate messages"), + G_CALLBACK (action_mail_folder_select_duplicate) }, + { "mail-folder-select-thread", NULL, N_("Select Message _Thread"), diff --git a/modules/mail/e-mail-shell-view-actions.h b/modules/mail/e-mail-shell-view-actions.h index 99819f0..c5c9eb8 100644 --- a/modules/mail/e-mail-shell-view-actions.h +++ b/modules/mail/e-mail-shell-view-actions.h @@ -85,6 +85,8 @@ E_SHELL_WINDOW_ACTION ((window), "mail-folder-rename") #define E_SHELL_WINDOW_ACTION_MAIL_FOLDER_SELECT_ALL(window) \ E_SHELL_WINDOW_ACTION ((window), "mail-folder-select-all") +#define E_SHELL_WINDOW_ACTION_MAIL_FOLDER_SELECT_DUPLICATE(window) \ + E_SHELL_WINDOW_ACTION ((window), "mail-folder-select-duplicate") #define E_SHELL_WINDOW_ACTION_MAIL_FOLDER_SELECT_THREAD(window) \ E_SHELL_WINDOW_ACTION ((window), "mail-folder-select-thread") #define E_SHELL_WINDOW_ACTION_MAIL_FOLDER_SELECT_SUBTHREAD(window) \ diff --git a/ui/evolution-mail.ui b/ui/evolution-mail.ui index c35ddbc..6eaca9b 100644 --- a/ui/evolution-mail.ui +++ b/ui/evolution-mail.ui @@ -43,6 +43,7 @@ <menuitem action='mail-folder-move'/> <separator/> <menuitem action='mail-folder-select-all'/> + <menuitem action='mail-folder-select-duplicate'/> <menuitem action='mail-folder-select-thread'/> <menuitem action='mail-folder-select-subthread'/> <menuitem action='mail-folder-mark-all-as-read'/>
_______________________________________________ Evolution-hackers mailing list Evolution-hackers@gnome.org http://mail.gnome.org/mailman/listinfo/evolution-hackers