Bug #587011 - Integrate remove-duplicates into evolution
This commit is contained in:
@ -472,5 +472,19 @@ You can choose to ignore this folder, overwrite or append its contents, or quit.
|
||||
<_primary>"Report Not Junk" Failed</_primary>
|
||||
<secondary xml:space="preserve">{0}</secondary>
|
||||
</error>
|
||||
|
||||
<error id="ask-remove-duplicates" type="question" default="GTK_RESPONSE_YES">
|
||||
<_primary>Remove duplicate messages?</_primary>
|
||||
<secondary>{0}</secondary>
|
||||
<button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
|
||||
<button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
|
||||
</error>
|
||||
|
||||
<error id="info-no-remove-duplicates" type="info" default="GTK_RESPONSE_OK">
|
||||
<_primary>No duplicate messages found.</_primary>
|
||||
<!-- Translators: {0} is replaced with a folder name -->
|
||||
<_secondary>Folder '{0}' doesn't contain any duplicate message.</_secondary>
|
||||
<button stock="gtk-ok" response="GTK_RESPONSE_OK"/>
|
||||
</error>
|
||||
</error-list>
|
||||
|
||||
|
||||
@ -413,6 +413,133 @@ action_mail_folder_rename_cb (GtkAction *action,
|
||||
em_folder_tree_edit_selected (folder_tree);
|
||||
}
|
||||
|
||||
static gchar*
|
||||
get_message_checksum (CamelFolder *folder, const gchar *uid)
|
||||
{
|
||||
static const GChecksumType duplicate_csum = G_CHECKSUM_SHA256;
|
||||
|
||||
CamelMimeMessage *msg;
|
||||
GError *error = NULL;
|
||||
CamelDataWrapper *content;
|
||||
CamelStream *mem;
|
||||
GByteArray *buffer;
|
||||
gchar *digest = NULL;
|
||||
|
||||
msg = camel_folder_get_message_sync (folder, uid, NULL, &error);
|
||||
|
||||
if (error || !msg) {
|
||||
if (error)
|
||||
g_error_free (error);;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get message contents */
|
||||
content = camel_medium_get_content ((CamelMedium *) msg);
|
||||
if (!content)
|
||||
return NULL;
|
||||
|
||||
/* calculate checksum */
|
||||
mem = camel_stream_mem_new ();
|
||||
camel_data_wrapper_decode_to_stream_sync (content, mem, NULL, NULL);
|
||||
|
||||
buffer = camel_stream_mem_get_byte_array (CAMEL_STREAM_MEM (mem));
|
||||
if (buffer)
|
||||
digest = g_compute_checksum_for_data (duplicate_csum, buffer->data, buffer->len);
|
||||
|
||||
g_object_unref (mem);
|
||||
g_object_unref (msg);
|
||||
|
||||
return digest;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
message_is_duplicated (GHashTable *messages, guint64 id, gchar *digest)
|
||||
{
|
||||
gchar *hash_digest = g_hash_table_lookup (messages, &id);
|
||||
|
||||
if (!hash_digest)
|
||||
return FALSE;
|
||||
|
||||
return g_str_equal (digest, hash_digest);
|
||||
}
|
||||
|
||||
static void
|
||||
action_mail_folder_remove_duplicates (GtkAction *action, EMailShellView *mail_shell_view)
|
||||
{
|
||||
EShellView *shell_view;
|
||||
EShellContent *shell_content;
|
||||
GtkWindow *parent;
|
||||
EMailReader *reader;
|
||||
MessageList *message_list;
|
||||
CamelFolder *folder;
|
||||
GHashTable *messages;
|
||||
GPtrArray *uids, *dups;
|
||||
gint i;
|
||||
|
||||
shell_view = E_SHELL_VIEW (mail_shell_view);
|
||||
shell_content = e_shell_view_get_shell_content (shell_view);
|
||||
parent = GTK_WINDOW (e_shell_view_get_shell_window (shell_view));
|
||||
|
||||
reader = E_MAIL_READER (shell_content);
|
||||
message_list = 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);
|
||||
dups = g_ptr_array_new();
|
||||
|
||||
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);
|
||||
guint32 flags = camel_message_info_flags (msg_info);
|
||||
|
||||
if (!(flags & CAMEL_MESSAGE_DELETED)) {
|
||||
gchar *digest = get_message_checksum (folder, uids->pdata[i]);
|
||||
|
||||
if (digest) {
|
||||
if (message_is_duplicated (messages, mid->id.id, digest)) {
|
||||
g_ptr_array_add (dups, uids->pdata[i]);
|
||||
g_free (digest);
|
||||
} 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);
|
||||
}
|
||||
|
||||
if (dups->len == 0) {
|
||||
em_utils_prompt_user (parent, NULL, "mail:info-no-remove-duplicates", camel_folder_get_name (folder), NULL);
|
||||
} else {
|
||||
gchar *msg = g_strdup_printf (ngettext (
|
||||
/* Translators: %s is replaced with a folder name
|
||||
%d with count of duplicate messages. */
|
||||
_("Folder '%s' contains %d duplicate message. Are you sure you want to delete it?"),
|
||||
_("Folder '%s' contains %d duplicate messages. Are you sure you want to delete them?"),
|
||||
dups->len),
|
||||
camel_folder_get_name (folder), dups->len);
|
||||
|
||||
if (em_utils_prompt_user (parent, NULL, "mail:ask-remove-duplicates", msg, NULL)) {
|
||||
gint ii;
|
||||
|
||||
camel_folder_freeze (folder);
|
||||
for (ii = 0; ii < dups->len; ii++)
|
||||
camel_folder_delete_message (folder, g_ptr_array_index (dups, ii));
|
||||
camel_folder_thaw (folder);
|
||||
}
|
||||
|
||||
g_free (msg);
|
||||
}
|
||||
|
||||
g_hash_table_destroy (messages);
|
||||
em_utils_uids_free (uids);
|
||||
g_ptr_array_free (dups, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
action_mail_folder_select_thread_cb (GtkAction *action,
|
||||
EMailShellView *mail_shell_view)
|
||||
@ -1074,6 +1201,13 @@ static GtkActionEntry mail_entries[] = {
|
||||
N_("Change the name of this folder"),
|
||||
G_CALLBACK (action_mail_folder_rename_cb) },
|
||||
|
||||
{ "mail-folder-remove-duplicates",
|
||||
NULL,
|
||||
N_("Remo_ve duplicate messages"),
|
||||
"",
|
||||
N_("Remove all duplicate messages"),
|
||||
G_CALLBACK (action_mail_folder_remove_duplicates) },
|
||||
|
||||
{ "mail-folder-select-thread",
|
||||
NULL,
|
||||
N_("Select Message _Thread"),
|
||||
|
||||
@ -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_REMOVE_DUPLICATES(window) \
|
||||
E_SHELL_WINDOW_ACTION ((window), "mail-folder-remove-duplicates")
|
||||
#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) \
|
||||
|
||||
@ -45,6 +45,7 @@
|
||||
<menuitem action='mail-folder-select-thread'/>
|
||||
<menuitem action='mail-folder-select-subthread'/>
|
||||
<menuitem action='mail-folder-mark-all-as-read'/>
|
||||
<menuitem action='mail-folder-remove-duplicates'/>
|
||||
<menuitem action='mail-folder-expunge'/>
|
||||
<separator/>
|
||||
<menuitem action='mail-folder-rename'/>
|
||||
|
||||
Reference in New Issue
Block a user