Re: [Evolution-hackers] Remove duplicate

2009-10-14 Thread Kip Warner
On Thu, 2009-10-15 at 04:25 +0530, ritz wrote:
> 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

This looks great and will definitely help me clear the crud out of my
IMAP folders. Hopefully this will eventually get merged mainline.

-- 
Kip Warner -- Software Developer
President & CEO Kshatra Corp.
OpenPGP encrypted/signed mail preferred
http://www.thevertigo.com


signature.asc
Description: This is a digitally signed message part
___
Evolution-hackers mailing list
Evolution-hackers@gnome.org
http://mail.gnome.org/mailman/listinfo/evolution-hackers


[Evolution-hackers] Remove duplicate

2009-10-14 Thread ritz
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 
+#include 
 
 #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;
+	CamelExceptionex;
+	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