From a5ccbcc1488aae3fbd986c85e0505b9cf63c01c4 Mon Sep 17 00:00:00 2001 From: Colin Leroy Date: Mon, 1 Sep 2008 16:58:02 +0000 Subject: [PATCH] 2008-09-01 [colin] 3.5.0cvs88 * src/imap.c * src/summaryview.c * src/common/tags.c * src/etpan/imap-thread.c * src/etpan/imap-thread.h Store spam flag on IMAP (Junk/NonJunk, as ThunderBird does - this is nonstandard) --- ChangeLog | 10 +++++++ PATCHSETS | 1 + configure.ac | 2 +- src/common/tags.c | 60 +++++++++++++++++++++++++++-------------- src/etpan/imap-thread.c | 20 ++++++++++++++ src/etpan/imap-thread.h | 5 +++- src/imap.c | 53 ++++++++++++++++++++++++++++++++---- src/summaryview.c | 3 ++- 8 files changed, 126 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index f9d570a36..9855cd37b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2008-09-01 [colin] 3.5.0cvs88 + + * src/imap.c + * src/summaryview.c + * src/common/tags.c + * src/etpan/imap-thread.c + * src/etpan/imap-thread.h + Store spam flag on IMAP (Junk/NonJunk, as + ThunderBird does - this is nonstandard) + 2008-08-31 [wwp] 3.5.0cvs87 * ChangeLog diff --git a/PATCHSETS b/PATCHSETS index a7f7d758c..fcdd298b2 100644 --- a/PATCHSETS +++ b/PATCHSETS @@ -3499,3 +3499,4 @@ ( cvs diff -u -r 1.274.2.270 -r 1.274.2.271 src/mainwindow.c; cvs diff -u -r 1.395.2.386 -r 1.395.2.387 src/summaryview.c; ) > 3.5.0cvs85.patchset ( cvs diff -u -r 1.60.2.123 -r 1.60.2.124 src/addressbook.c; ) > 3.5.0cvs86.patchset ( cvs diff -u -r 1.396.2.2646 -r 1.396.2.2647 ChangeLog; ) > 3.5.0cvs87.patchset +( cvs diff -u -r 1.179.2.226 -r 1.179.2.227 src/imap.c; cvs diff -u -r 1.395.2.387 -r 1.395.2.388 src/summaryview.c; cvs diff -u -r 1.1.2.7 -r 1.1.2.8 src/common/tags.c; cvs diff -u -r 1.1.4.103 -r 1.1.4.104 src/etpan/imap-thread.c; cvs diff -u -r 1.1.4.24 -r 1.1.4.25 src/etpan/imap-thread.h; ) > 3.5.0cvs88.patchset diff --git a/configure.ac b/configure.ac index 4b1cb895f..422d44531 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ MINOR_VERSION=5 MICRO_VERSION=0 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=87 +EXTRA_VERSION=88 EXTRA_RELEASE= EXTRA_GTK2_VERSION= diff --git a/src/common/tags.c b/src/common/tags.c index 1b1d5d65f..53aedb1bb 100644 --- a/src/common/tags.c +++ b/src/common/tags.c @@ -77,11 +77,17 @@ void tags_read_tags(void) continue; g_strstrip(tag_name); *(sep) = '\0'; - id = atoi(tmp); - g_hash_table_insert(tags_table, - GINT_TO_POINTER(id), g_strdup(tag_name)); - g_hash_table_insert(tags_reverse_table, - g_strdup(tag_name), GINT_TO_POINTER(id)); + if (strcmp(tag_name, "NonJunk") && + strcmp(tag_name, "NotJunk") && + strcmp(tag_name, "NoJunk") && + strcmp(tag_name, "$Forwarded") && + strcmp(tag_name, "Junk")) { + id = atoi(tmp); + g_hash_table_insert(tags_table, + GINT_TO_POINTER(id), g_strdup(tag_name)); + g_hash_table_insert(tags_reverse_table, + g_strdup(tag_name), GINT_TO_POINTER(id)); + } } fclose(fp); @@ -165,13 +171,21 @@ gint tags_add_tag(const gchar *tag) if (g_hash_table_lookup(tags_reverse_table, tag)) return -1; - tag_max_id++; - g_hash_table_insert(tags_table, GINT_TO_POINTER(tag_max_id), - g_strdup(tag)); - g_hash_table_insert(tags_reverse_table, g_strdup(tag), - GINT_TO_POINTER(tag_max_id)); - - return tag_max_id; + if (strcmp(tag, "NonJunk") && + strcmp(tag, "NotJunk") && + strcmp(tag, "NoJunk") && + strcmp(tag, "$Forwarded") && + strcmp(tag, "Junk")) { + tag_max_id++; + g_hash_table_insert(tags_table, GINT_TO_POINTER(tag_max_id), + g_strdup(tag)); + g_hash_table_insert(tags_reverse_table, g_strdup(tag), + GINT_TO_POINTER(tag_max_id)); + + return tag_max_id; + } else { + return -1; + } } void tags_remove_tag(gint id) @@ -191,15 +205,21 @@ void tags_update_tag(gint id, const gchar *tag) { gchar *old_tag = g_hash_table_lookup(tags_table, GINT_TO_POINTER(id)); - if (old_tag) { - prefs_filtering_rename_tag(old_tag, tag); - g_hash_table_remove(tags_reverse_table, old_tag); + if (strcmp(tag, "NonJunk") && + strcmp(tag, "NotJunk") && + strcmp(tag, "NoJunk") && + strcmp(tag, "$Forwarded") && + strcmp(tag, "Junk")) { + if (old_tag) { + prefs_filtering_rename_tag(old_tag, tag); + g_hash_table_remove(tags_reverse_table, old_tag); + } + + g_hash_table_replace(tags_table, GINT_TO_POINTER(id), + g_strdup(tag)); + g_hash_table_insert(tags_reverse_table, g_strdup(tag), + GINT_TO_POINTER(id)); } - - g_hash_table_replace(tags_table, GINT_TO_POINTER(id), - g_strdup(tag)); - g_hash_table_insert(tags_reverse_table, g_strdup(tag), - GINT_TO_POINTER(id)); } const gchar *tags_get_tag(gint id) diff --git a/src/etpan/imap-thread.c b/src/etpan/imap-thread.c index 5f4ec07e7..30f3a6014 100644 --- a/src/etpan/imap-thread.c +++ b/src/etpan/imap-thread.c @@ -1446,6 +1446,12 @@ int imap_threaded_select(Folder * folder, const char * mb, case MAILIMAP_FLAG_KEYWORD: if (!strcasecmp(flag->fl_flag->fl_data.fl_keyword, "$Forwarded")) c_flag = IMAP_FLAG_FORWARDED; + if (!strcasecmp(flag->fl_flag->fl_data.fl_keyword, "Junk")) + c_flag = IMAP_FLAG_SPAM; + if (!strcasecmp(flag->fl_flag->fl_data.fl_keyword, "NonJunk") || + !strcasecmp(flag->fl_flag->fl_data.fl_keyword, "NoJunk") || + !strcasecmp(flag->fl_flag->fl_data.fl_keyword, "NotJunk")) + c_flag = IMAP_FLAG_HAM; break; default: break; @@ -1672,6 +1678,14 @@ static void search_run(struct etpan_thread_op * op) NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL); break; + case IMAP_SEARCH_TYPE_SPAM: + search_type_key = mailimap_search_key_new(MAILIMAP_SEARCH_KEY_KEYWORD, + NULL, NULL, NULL, NULL, NULL, + strdup("Junk"), NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, 0, + NULL, NULL, NULL, NULL, NULL, + NULL, 0, NULL, NULL, NULL); + break; } if (search_type_key != NULL) { @@ -2530,6 +2544,12 @@ static int imap_flags_to_flags(struct mailimap_msg_att_dynamic * att_dyn, GSList case MAILIMAP_FLAG_KEYWORD: if (!strcasecmp(flag_fetch->fl_flag->fl_data.fl_keyword, "$Forwarded")) flags |= MSG_FORWARDED; + else if (!strcasecmp(flag_fetch->fl_flag->fl_data.fl_keyword, "Junk")) + flags |= MSG_SPAM; + else if (!strcasecmp(flag_fetch->fl_flag->fl_data.fl_keyword, "NonJunk") || + !strcasecmp(flag_fetch->fl_flag->fl_data.fl_keyword, "NoJunk") || + !strcasecmp(flag_fetch->fl_flag->fl_data.fl_keyword, "NotJunk")) + flags &= ~MSG_SPAM; else if (s_tags) tags = g_slist_prepend(tags, g_strdup(flag_fetch->fl_flag->fl_data.fl_keyword)); break; diff --git a/src/etpan/imap-thread.h b/src/etpan/imap-thread.h index 09be26d09..0e426ef50 100644 --- a/src/etpan/imap-thread.h +++ b/src/etpan/imap-thread.h @@ -33,7 +33,9 @@ typedef enum IMAP_FLAG_FLAGGED = 1 << 2, IMAP_FLAG_DELETED = 1 << 3, IMAP_FLAG_DRAFT = 1 << 4, - IMAP_FLAG_FORWARDED = 1 << 5 + IMAP_FLAG_FORWARDED = 1 << 5, + IMAP_FLAG_SPAM = 1 << 6, + IMAP_FLAG_HAM = 1 << 7 } IMAPFlags; void imap_main_set_timeout(int sec); @@ -96,6 +98,7 @@ enum { IMAP_SEARCH_TYPE_FLAGGED, IMAP_SEARCH_TYPE_DELETED, IMAP_SEARCH_TYPE_FORWARDED, + IMAP_SEARCH_TYPE_SPAM, }; int imap_threaded_search(Folder * folder, int search_type, diff --git a/src/imap.c b/src/imap.c index 5947a0fc4..1b50b767f 100644 --- a/src/imap.c +++ b/src/imap.c @@ -137,6 +137,8 @@ struct _IMAPNameSpace #define IMAP_IS_DELETED(flags) ((flags & IMAP_FLAG_DELETED) != 0) #define IMAP_IS_DRAFT(flags) ((flags & IMAP_FLAG_DRAFT) != 0) #define IMAP_IS_FORWARDED(flags) ((flags & IMAP_FLAG_FORWARDED) != 0) +#define IMAP_IS_SPAM(flags) ((flags & IMAP_FLAG_SPAM) != 0) +#define IMAP_IS_HAM(flags) ((flags & IMAP_FLAG_HAM) != 0) #define IMAP4_PORT 143 @@ -1338,7 +1340,8 @@ static void imap_commit_tags(FolderItem *item, MsgInfo *msginfo, GSList *tags_se for (cur = tags_set; cur; cur = cur->next) { gint cur_tag = GPOINTER_TO_INT(cur->data); const gchar *str = tags_get_tag(cur_tag); - list_set = g_slist_prepend(list_set, g_strdup(str)); + if (strcmp(str, "$Forwarded") && strcmp(str, "Junk") && strcmp(str, "NonJunk") && strcmp(str, "NotJunk") && strcmp(str, "NoJunk") && strcmp(str, "Junk") ) + list_set = g_slist_prepend(list_set, g_strdup(str)); } if (list_set) { ok = imap_set_message_flags(session, @@ -1353,7 +1356,8 @@ static void imap_commit_tags(FolderItem *item, MsgInfo *msginfo, GSList *tags_se for (cur = tags_unset; cur; cur = cur->next) { gint cur_tag = GPOINTER_TO_INT(cur->data); const gchar *str = tags_get_tag(cur_tag); - list_unset = g_slist_prepend(list_unset, g_strdup(str)); + if (strcmp(str, "$Forwarded") && strcmp(str, "Junk") && strcmp(str, "NonJunk") && strcmp(str, "NotJunk") && strcmp(str, "NoJunk") && strcmp(str, "Junk") ) + list_unset = g_slist_prepend(list_unset, g_strdup(str)); } if (list_unset) { ok = imap_set_message_flags(session, @@ -1596,6 +1600,10 @@ static gint imap_add_msgs(Folder *folder, FolderItem *dest, GSList *file_list, iflags |= IMAP_FLAG_ANSWERED; if (MSG_IS_FORWARDED(*fileinfo->flags)) iflags |= IMAP_FLAG_FORWARDED; + if (MSG_IS_SPAM(*fileinfo->flags)) + iflags |= IMAP_FLAG_SPAM; + else + iflags |= IMAP_FLAG_HAM; if (!MSG_IS_UNREAD(*fileinfo->flags)) iflags |= IMAP_FLAG_SEEN; @@ -4253,6 +4261,14 @@ void imap_change_flags(Folder *folder, FolderItem *item, MsgInfo *msginfo, MsgPe if ( MSG_IS_FORWARDED(msginfo->flags) && !(newflags & MSG_FORWARDED)) flags_unset |= IMAP_FLAG_FORWARDED; + if (!MSG_IS_SPAM(msginfo->flags) && (newflags & MSG_SPAM)) { + flags_set |= IMAP_FLAG_SPAM; + flags_unset |= IMAP_FLAG_HAM; + } + if ( MSG_IS_SPAM(msginfo->flags) && !(newflags & MSG_SPAM)) { + flags_set |= IMAP_FLAG_HAM; + flags_unset |= IMAP_FLAG_SPAM; + } if (!MSG_IS_DELETED(msginfo->flags) && (newflags & MSG_DELETED)) flags_set |= IMAP_FLAG_DELETED; if ( MSG_IS_DELETED(msginfo->flags) && !(newflags & MSG_DELETED)) @@ -4446,7 +4462,7 @@ static /*gint*/ void *imap_get_flags_thread(void *data) GHashTable *tags_hash = NULL; gboolean full_search = stuff->full_search; GSList *sorted_list = NULL; - GSList *unseen = NULL, *answered = NULL, *flagged = NULL, *deleted = NULL, *forwarded = NULL; + GSList *unseen = NULL, *answered = NULL, *flagged = NULL, *deleted = NULL, *forwarded = NULL, *spam = NULL; GSList *seq_list, *cur; gboolean reverse_seen = FALSE; gboolean selected_folder; @@ -4561,6 +4577,22 @@ static /*gint*/ void *imap_get_flags_thread(void *data) } } + if (flag_ok(IMAP_FOLDER_ITEM(fitem), IMAP_FLAG_SPAM)) { + r = imap_threaded_search(folder, IMAP_SEARCH_TYPE_SPAM, + full_search ? NULL:imapset, &lep_uidlist); + if (r == MAILIMAP_NO_ERROR) { + GSList * uidlist; + + uidlist = imap_uid_list_from_lep(lep_uidlist); + mailimap_search_result_free(lep_uidlist); + + spam = g_slist_concat(spam, uidlist); + } else { + imap_handle_error(SESSION(session), r); + goto bail; + } + } + r = imap_threaded_search(folder, IMAP_SEARCH_TYPE_DELETED, full_search ? NULL:imapset, &lep_uidlist); if (r == MAILIMAP_NO_ERROR) { @@ -4602,11 +4634,11 @@ bail: msginfo = (MsgInfo *) elem->data; flags = msginfo->flags.perm_flags; wasnew = (flags & MSG_NEW); - oldflags = flags & ~(MSG_NEW|MSG_UNREAD|MSG_REPLIED|MSG_FORWARDED|MSG_MARKED|MSG_DELETED); + oldflags = flags & ~(MSG_NEW|MSG_UNREAD|MSG_REPLIED|MSG_FORWARDED|MSG_MARKED|MSG_DELETED|MSG_SPAM); if (folder->account && folder->account->low_bandwidth) { if (fitem->opened || fitem->processing_pending || fitem == folder->inbox) { - flags &= ~((reverse_seen ? 0 : MSG_UNREAD | MSG_NEW) | MSG_REPLIED | MSG_FORWARDED | MSG_MARKED); + flags &= ~((reverse_seen ? 0 : MSG_UNREAD | MSG_NEW) | MSG_REPLIED | MSG_FORWARDED | MSG_MARKED | MSG_SPAM); } else { flags &= ~((reverse_seen ? 0 : MSG_UNREAD | MSG_NEW | MSG_MARKED)); } @@ -4634,6 +4666,10 @@ bail: flags |= MSG_FORWARDED; else flags &= ~MSG_FORWARDED; + if (gslist_find_next_num(&spam, msginfo->msgnum) == msginfo->msgnum) + flags |= MSG_SPAM; + else + flags &= ~MSG_SPAM; if (gslist_find_next_num(&deleted, msginfo->msgnum) == msginfo->msgnum) flags |= MSG_DELETED; else @@ -4698,6 +4734,7 @@ bail: g_slist_free(deleted); g_slist_free(answered); g_slist_free(forwarded); + g_slist_free(spam); g_slist_free(unseen); g_slist_free(sorted_list); @@ -5230,6 +5267,12 @@ static struct mailimap_flag_list * imap_flag_to_lep(IMAPFolderItem *item, IMAPFl if (IMAP_IS_FORWARDED(flags) && flag_ok(item, IMAP_FLAG_FORWARDED)) mailimap_flag_list_add(flag_list, mailimap_flag_new_flag_keyword(strdup("$Forwarded"))); + if (IMAP_IS_SPAM(flags) && flag_ok(item, IMAP_FLAG_SPAM)) + mailimap_flag_list_add(flag_list, + mailimap_flag_new_flag_keyword(strdup("Junk"))); + else if (IMAP_IS_HAM(flags) && flag_ok(item, IMAP_FLAG_HAM)) + mailimap_flag_list_add(flag_list, + mailimap_flag_new_flag_keyword(strdup("NonJunk"))); for (; cur; cur = cur->next) { gchar *enc_str = diff --git a/src/summaryview.c b/src/summaryview.c index 553c1fffe..58bb2934f 100644 --- a/src/summaryview.c +++ b/src/summaryview.c @@ -4106,6 +4106,7 @@ void summary_mark_as_spam(SummaryView *summaryview, guint action, GtkWidget *wid prefs_common.immediate_exec = FALSE; START_LONG_OPERATION(summaryview, FALSE); + folder_item_set_batch(summaryview->folder_item, TRUE); for (cur = GTK_CMCLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next) { GtkCMCTreeNode *row = GTK_CMCTREE_NODE(cur->data); MsgInfo *msginfo = gtk_cmctree_node_get_row_data(ctree, row); @@ -4138,7 +4139,7 @@ void summary_mark_as_spam(SummaryView *summaryview, guint action, GtkWidget *wid } prefs_common.immediate_exec = immediate_exec; - + folder_item_set_batch(summaryview->folder_item, FALSE); END_LONG_OPERATION(summaryview); if (prefs_common.immediate_exec && moved) { -- 2.25.1