commit a5ccbcc1488aae3fbd986c85e0505b9cf63c01c4
parent f9a6bae9b6907e9f3c78fb3a4a1e6b89e2ea8aed
Author: Colin Leroy <colin@colino.net>
Date: Mon, 1 Sep 2008 16:58:02 +0000
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)
Diffstat:
8 files changed, 126 insertions(+), 28 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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) {