aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--libsylph/filter.c100
-rw-r--r--libsylph/filter.h4
-rw-r--r--libsylph/libsylph-0.def1
-rw-r--r--libsylph/mbox.c26
-rw-r--r--libsylph/prefs_common.c79
-rw-r--r--libsylph/prefs_common.h4
-rw-r--r--src/inc.c38
-rw-r--r--src/inc.h2
-rw-r--r--src/main.c2
-rw-r--r--src/prefs_common_dialog.c1
-rw-r--r--src/summaryview.c21
-rw-r--r--src/summaryview.h3
13 files changed, 193 insertions, 101 deletions
diff --git a/ChangeLog b/ChangeLog
index 649a8d7c..53878427 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
2010-12-22
+ * libsylph/filter.[ch]
+ libsylph/prefs_common.[ch]
+ libsylph/mbox.c
+ src/inc.[ch]
+ src/main.c
+ src/summaryview.[ch]
+ src/prefs_common_dialog.c: refactored junk filter rule management.
+ Create junk filter rule on demand.
+ Deprecated prefs_common_junk_filter_list_set().
+ Automatically select appropriate Junk folder on filtering.
+
+2010-12-22
+
* src/addressbook.c: added menu 'Add to recipient/Cc/Bcc'.
2010-12-21
diff --git a/libsylph/filter.c b/libsylph/filter.c
index 6db89b20..288564a9 100644
--- a/libsylph/filter.c
+++ b/libsylph/filter.c
@@ -1453,6 +1453,106 @@ FilterInfo *filter_info_new(void)
return fltinfo;
}
+FilterRule *filter_junk_rule_create(PrefsAccount *account,
+ FolderItem *default_junk,
+ gboolean is_manual)
+{
+ FilterRule *rule;
+ FilterCond *cond;
+ FilterAction *action;
+ GSList *cond_list = NULL, *action_list = NULL;
+ gchar *junk_id = NULL;
+ FolderItem *item = NULL;
+
+ if (!prefs_common.junk_classify_cmd)
+ return NULL;
+
+ if (prefs_common.junk_folder)
+ item = folder_find_item_from_identifier(prefs_common.junk_folder);
+
+ if (!item && account) {
+ Folder *folder = NULL;
+ GList *list;
+
+ /* find most suitable Junk folder for account */
+
+ if (account->inbox && *account->inbox == '#') {
+ FolderItem *inbox;
+ inbox = folder_find_item_from_identifier(account->inbox);
+ if (inbox) {
+ folder = inbox->folder;
+ if (folder)
+ item = folder_get_junk(folder);
+ }
+ }
+ if (!item) {
+ folder = FOLDER(account->folder);
+ if (folder)
+ item = folder_get_junk(folder);
+ }
+ if (!item) {
+ for (list = folder_get_list(); list != NULL; list = list->next) {
+ folder = FOLDER(list->data);
+ if (FOLDER_IS_LOCAL(folder)) {
+ if (folder->account == account)
+ item = folder_get_junk(folder);
+ if (!item && folder->node) {
+ item = FOLDER_ITEM(folder->node->data);
+ if (item && item->account == account && item->folder)
+ item = folder_get_junk(item->folder);
+ else
+ item = NULL;
+ }
+ }
+ if (item)
+ break;
+ }
+ }
+ }
+
+ if (!item)
+ item = default_junk;
+ if (!item)
+ item = folder_get_default_junk();
+ if (!item)
+ return NULL;
+ junk_id = folder_item_get_identifier(item);
+ if (!junk_id)
+ return NULL;
+
+ debug_print("filter_junk_rule_create: junk folder: %s\n",
+ junk_id);
+
+ cond = filter_cond_new(FLT_COND_CMD_TEST, 0, 0, NULL,
+ prefs_common.junk_classify_cmd);
+ cond_list = g_slist_append(NULL, cond);
+ if (prefs_common.delete_junk_on_recv && !is_manual) {
+ action = filter_action_new(FLT_ACTION_COPY, junk_id);
+ action_list = g_slist_append(NULL, action);
+ action = filter_action_new(FLT_ACTION_DELETE, NULL);
+ action_list = g_slist_append(action_list, action);
+ } else {
+ action = filter_action_new(FLT_ACTION_MOVE, junk_id);
+ action_list = g_slist_append(NULL, action);
+ }
+
+ if (prefs_common.mark_junk_as_read) {
+ action = filter_action_new(FLT_ACTION_MARK_READ, NULL);
+ action_list = g_slist_append(action_list, action);
+ }
+
+ if (is_manual)
+ rule = filter_rule_new(_("Junk mail filter (manual)"), FLT_OR,
+ cond_list, action_list);
+ else
+ rule = filter_rule_new(_("Junk mail filter"), FLT_OR,
+ cond_list, action_list);
+
+ g_free(junk_id);
+
+ return rule;
+}
+
void filter_rule_rename_dest_path(FilterRule *rule, const gchar *old_path,
const gchar *new_path)
{
diff --git a/libsylph/filter.h b/libsylph/filter.h
index 35c43c70..bb98e570 100644
--- a/libsylph/filter.h
+++ b/libsylph/filter.h
@@ -213,6 +213,10 @@ FilterAction *filter_action_new (FilterActionType type,
const gchar *str);
FilterInfo *filter_info_new (void);
+FilterRule *filter_junk_rule_create (PrefsAccount *account,
+ FolderItem *default_junk,
+ gboolean is_manual);
+
void filter_rule_rename_dest_path (FilterRule *rule,
const gchar *old_path,
const gchar *new_path);
diff --git a/libsylph/libsylph-0.def b/libsylph/libsylph-0.def
index 8f7223b8..2c62f581 100644
--- a/libsylph/libsylph-0.def
+++ b/libsylph/libsylph-0.def
@@ -693,3 +693,4 @@ EXPORTS
socks4_connect @ 691
socks5_connect @ 692
folder_remote_folder_destroy_all_sessions @ 693
+ filter_junk_rule_create @ 694
diff --git a/libsylph/mbox.c b/libsylph/mbox.c
index 21beadb7..e2b7d053 100644
--- a/libsylph/mbox.c
+++ b/libsylph/mbox.c
@@ -73,6 +73,9 @@ gint proc_mbox_full(FolderItem *dest, const gchar *mbox,
gint new_msgs = 0;
gint count = 0;
Folder *folder;
+ FilterRule *junk_rule = NULL;
+ GSList junk_fltlist = {NULL, NULL};
+ FolderItem *junk;
g_return_val_if_fail(dest != NULL, -1);
g_return_val_if_fail(dest->folder != NULL, -1);
@@ -111,6 +114,12 @@ gint proc_mbox_full(FolderItem *dest, const gchar *mbox,
tmp_file = get_tmp_file();
+ if (filter_junk) {
+ junk = folder_get_junk(folder);
+ junk_rule = filter_junk_rule_create(NULL, junk, FALSE);
+ junk_fltlist.data = junk_rule;
+ }
+
do {
FILE *tmp_fp;
GSList *cur;
@@ -128,6 +137,7 @@ gint proc_mbox_full(FolderItem *dest, const gchar *mbox,
if ((tmp_fp = g_fopen(tmp_file, "wb")) == NULL) {
FILE_OP_ERROR(tmp_file, "fopen");
g_warning(_("can't open temporary file\n"));
+ filter_rule_free(junk_rule);
g_free(tmp_file);
fclose(mbox_fp);
return -1;
@@ -214,6 +224,7 @@ gint proc_mbox_full(FolderItem *dest, const gchar *mbox,
if (fclose(tmp_fp) == EOF) {
FILE_OP_ERROR(tmp_file, "fclose");
g_warning(_("can't write to temporary file\n"));
+ filter_rule_free(junk_rule);
g_unlink(tmp_file);
g_free(tmp_file);
fclose(mbox_fp);
@@ -229,6 +240,7 @@ gint proc_mbox_full(FolderItem *dest, const gchar *mbox,
if (!msginfo) {
g_warning("proc_mbox_full: procheader_parse_file failed");
filter_info_free(fltinfo);
+ filter_rule_free(junk_rule);
g_unlink(tmp_file);
g_free(tmp_file);
fclose(mbox_fp);
@@ -238,9 +250,8 @@ gint proc_mbox_full(FolderItem *dest, const gchar *mbox,
msginfo->file_path = g_strdup(tmp_file);
if (filter_junk && prefs_common.enable_junk &&
- prefs_common.filter_junk_before) {
- filter_apply_msginfo(prefs_common.junk_fltlist, msginfo,
- fltinfo);
+ prefs_common.filter_junk_before && junk_rule) {
+ filter_apply_msginfo(&junk_fltlist, msginfo, fltinfo);
if (fltinfo->drop_done)
is_junk = TRUE;
}
@@ -251,9 +262,8 @@ gint proc_mbox_full(FolderItem *dest, const gchar *mbox,
if (!fltinfo->drop_done &&
filter_junk && prefs_common.enable_junk &&
- !prefs_common.filter_junk_before) {
- filter_apply_msginfo(prefs_common.junk_fltlist, msginfo,
- fltinfo);
+ !prefs_common.filter_junk_before && junk_rule) {
+ filter_apply_msginfo(&junk_fltlist, msginfo, fltinfo);
if (fltinfo->drop_done)
is_junk = TRUE;
}
@@ -264,6 +274,7 @@ gint proc_mbox_full(FolderItem *dest, const gchar *mbox,
if (folder_item_add_msg_msginfo(dest, msginfo, FALSE) < 0) {
procmsg_msginfo_free(msginfo);
filter_info_free(fltinfo);
+ filter_rule_free(junk_rule);
g_unlink(tmp_file);
g_free(tmp_file);
fclose(mbox_fp);
@@ -301,6 +312,9 @@ gint proc_mbox_full(FolderItem *dest, const gchar *mbox,
g_unlink(tmp_file);
} while (from_line[0] != '\0');
+ if (junk_rule)
+ filter_rule_free(junk_rule);
+
g_free(tmp_file);
fclose(mbox_fp);
debug_print("%d new messages found.\n", new_msgs);
diff --git a/libsylph/prefs_common.c b/libsylph/prefs_common.c
index ee6040c6..1467db66 100644
--- a/libsylph/prefs_common.c
+++ b/libsylph/prefs_common.c
@@ -566,86 +566,8 @@ void prefs_common_write_config(void)
g_free(path);
}
-static FilterRule *prefs_common_junk_filter_rule_create(gboolean is_manual)
-{
- FilterRule *rule;
- FilterCond *cond;
- FilterAction *action;
- GSList *cond_list = NULL, *action_list = NULL;
- gchar *junk_id;
-
- if (prefs_common.junk_folder)
- junk_id = g_strdup(prefs_common.junk_folder);
- else {
- FolderItem *item;
- item = folder_get_default_junk();
- if (!item)
- return NULL;
- junk_id = folder_item_get_identifier(item);
- if (!junk_id)
- return NULL;
- }
-
- debug_print("prefs_common_junk_filter_rule_create: junk folder: %s\n",
- junk_id);
-
- cond = filter_cond_new(FLT_COND_CMD_TEST, 0, 0, NULL,
- prefs_common.junk_classify_cmd);
- cond_list = g_slist_append(NULL, cond);
- if (prefs_common.delete_junk_on_recv && !is_manual) {
- action = filter_action_new(FLT_ACTION_COPY, junk_id);
- action_list = g_slist_append(NULL, action);
- action = filter_action_new(FLT_ACTION_DELETE, NULL);
- action_list = g_slist_append(action_list, action);
- } else {
- action = filter_action_new(FLT_ACTION_MOVE, junk_id);
- action_list = g_slist_append(NULL, action);
- }
-
- if (prefs_common.mark_junk_as_read) {
- action = filter_action_new(FLT_ACTION_MARK_READ, NULL);
- action_list = g_slist_append(action_list, action);
- }
-
- if (is_manual)
- rule = filter_rule_new(_("Junk mail filter (manual)"), FLT_OR,
- cond_list, action_list);
- else
- rule = filter_rule_new(_("Junk mail filter"), FLT_OR,
- cond_list, action_list);
-
- g_free(junk_id);
-
- return rule;
-}
-
void prefs_common_junk_filter_list_set(void)
{
- FilterRule *rule;
-
- debug_print("prefs_common_junk_filter_list_set\n");
-
- if (prefs_common.junk_fltlist) {
- filter_rule_list_free(prefs_common.junk_fltlist);
- prefs_common.junk_fltlist = NULL;
- }
- if (prefs_common.manual_junk_fltlist) {
- filter_rule_list_free(prefs_common.manual_junk_fltlist);
- prefs_common.manual_junk_fltlist = NULL;
- }
-
- if (!prefs_common.junk_classify_cmd)
- return;
-
- rule = prefs_common_junk_filter_rule_create(FALSE);
- if (!rule)
- return;
- prefs_common.junk_fltlist = g_slist_append(NULL, rule);
-
- rule = prefs_common_junk_filter_rule_create(TRUE);
- if (!rule)
- return;
- prefs_common.manual_junk_fltlist = g_slist_append(NULL, rule);
}
void prefs_common_junk_folder_rename_path(const gchar *old_path,
@@ -677,6 +599,5 @@ void prefs_common_junk_folder_rename_path(const gchar *old_path,
dest_path);
g_free(prefs_common.junk_folder);
prefs_common.junk_folder = dest_path;
- prefs_common_junk_filter_list_set();
}
}
diff --git a/libsylph/prefs_common.h b/libsylph/prefs_common.h
index aac6c48d..ca0eb9d8 100644
--- a/libsylph/prefs_common.h
+++ b/libsylph/prefs_common.h
@@ -300,6 +300,8 @@ struct _PrefsCommon
/* Filtering */
GSList *fltlist;
+
+ /* deprecated: do not use */
GSList *junk_fltlist;
GSList *manual_junk_fltlist;
@@ -333,7 +335,9 @@ PrefParam *prefs_common_get_params (void);
void prefs_common_read_config (void);
void prefs_common_write_config (void);
+/* deprecated */
void prefs_common_junk_filter_list_set (void);
+
void prefs_common_junk_folder_rename_path (const gchar *old_path,
const gchar *new_path);
diff --git a/src/inc.c b/src/inc.c
index b62e2676..0bed04ac 100644
--- a/src/inc.c
+++ b/src/inc.c
@@ -253,12 +253,18 @@ static gint inc_remote_account_mail(MainWindow *mainwin, PrefsAccount *account)
FolderItem *inbox = FOLDER(account->folder)->inbox;
GSList *mlist, *cur;
FilterInfo *fltinfo;
+ GSList junk_fltlist = {NULL, NULL};
+ FilterRule *junk_rule;
gint n_filtered = 0;
debug_print("inc_remote_account_mail(): filtering IMAP4 INBOX\n");
mlist = folder_item_get_uncached_msg_list(inbox);
debug_print("inc_remote_account_mail(): uncached messages: %d\n", g_slist_length(mlist));
+ junk_rule = filter_junk_rule_create(account, NULL, TRUE);
+ if (junk_rule)
+ junk_fltlist.data = junk_rule;
+
for (cur = mlist; cur != NULL; cur = cur->next) {
MsgInfo *msginfo = (MsgInfo *)cur->data;
@@ -268,10 +274,9 @@ static gint inc_remote_account_mail(MainWindow *mainwin, PrefsAccount *account)
if (prefs_common.enable_junk &&
prefs_common.filter_junk_on_recv &&
- prefs_common.filter_junk_before) {
+ prefs_common.filter_junk_before && junk_rule) {
filter_apply_msginfo
- (prefs_common.manual_junk_fltlist,
- msginfo, fltinfo);
+ (&junk_fltlist, msginfo, fltinfo);
}
if (!fltinfo->drop_done) {
@@ -282,10 +287,9 @@ static gint inc_remote_account_mail(MainWindow *mainwin, PrefsAccount *account)
if (!fltinfo->drop_done &&
prefs_common.enable_junk &&
prefs_common.filter_junk_on_recv &&
- !prefs_common.filter_junk_before) {
+ !prefs_common.filter_junk_before && junk_rule) {
filter_apply_msginfo
- (prefs_common.manual_junk_fltlist,
- msginfo, fltinfo);
+ (&junk_fltlist, msginfo, fltinfo);
}
if (msginfo->flags.perm_flags !=
@@ -323,6 +327,9 @@ static gint inc_remote_account_mail(MainWindow *mainwin, PrefsAccount *account)
filter_info_free(fltinfo);
}
+ if (junk_rule)
+ filter_rule_free(junk_rule);
+
procmsg_msg_list_free(mlist);
debug_print("inc_remote_account_mail(): INBOX: %d new, %d filtered\n",
@@ -585,6 +592,7 @@ static void inc_progress_dialog_destroy(IncProgressDialog *inc_dialog)
static IncSession *inc_session_new(PrefsAccount *account)
{
IncSession *session;
+ FilterRule *rule;
g_return_val_if_fail(account != NULL, NULL);
@@ -611,6 +619,12 @@ static IncSession *inc_session_new(PrefsAccount *account)
session->folder_table = g_hash_table_new(NULL, NULL);
session->tmp_folder_table = g_hash_table_new(NULL, NULL);
+ rule = filter_junk_rule_create(account, NULL, FALSE);
+ if (rule)
+ session->junk_fltlist = g_slist_append(NULL, rule);
+ else
+ session->junk_fltlist = NULL;
+
session->cur_total_bytes = 0;
session->new_msgs = 0;
@@ -629,6 +643,8 @@ static void inc_session_destroy(IncSession *session)
session_destroy(session->session);
g_hash_table_destroy(session->folder_table);
g_hash_table_destroy(session->tmp_folder_table);
+ if (session->junk_fltlist)
+ filter_rule_list_free(session->junk_fltlist);
g_free(session);
}
@@ -1283,8 +1299,9 @@ static gint inc_drop_message(Pop3Session *session, const gchar *file)
if (prefs_common.enable_junk &&
prefs_common.filter_junk_on_recv &&
- prefs_common.filter_junk_before) {
- filter_apply_msginfo(prefs_common.junk_fltlist, msginfo,
+ prefs_common.filter_junk_before &&
+ inc_session->junk_fltlist) {
+ filter_apply_msginfo(inc_session->junk_fltlist, msginfo,
fltinfo);
if (fltinfo->drop_done)
is_junk = TRUE;
@@ -1306,8 +1323,9 @@ static gint inc_drop_message(Pop3Session *session, const gchar *file)
if (!fltinfo->drop_done) {
if (prefs_common.enable_junk &&
prefs_common.filter_junk_on_recv &&
- !prefs_common.filter_junk_before) {
- filter_apply_msginfo(prefs_common.junk_fltlist,
+ !prefs_common.filter_junk_before &&
+ inc_session->junk_fltlist) {
+ filter_apply_msginfo(inc_session->junk_fltlist,
msginfo, fltinfo);
if (fltinfo->drop_done)
is_junk = TRUE;
diff --git a/src/inc.h b/src/inc.h
index 4481120e..5f30c076 100644
--- a/src/inc.h
+++ b/src/inc.h
@@ -73,6 +73,8 @@ struct _IncSession
GHashTable *folder_table; /* table of destination folders */
GHashTable *tmp_folder_table; /* for progressive update */
+ GSList *junk_fltlist;
+
gint64 cur_total_bytes;
gint new_msgs;
diff --git a/src/main.c b/src/main.c
index 727f084a..36a18259 100644
--- a/src/main.c
+++ b/src/main.c
@@ -349,8 +349,6 @@ int main(int argc, char *argv[])
new_account = setup_account();
}
- prefs_common_junk_filter_list_set();
-
account_set_menu();
main_window_reflect_prefs_all();
diff --git a/src/prefs_common_dialog.c b/src/prefs_common_dialog.c
index 8399dec9..6e7f432b 100644
--- a/src/prefs_common_dialog.c
+++ b/src/prefs_common_dialog.c
@@ -4382,7 +4382,6 @@ static void prefs_common_ok(void)
static void prefs_common_apply(void)
{
prefs_set_data_from_dialog(prefs_common_get_params());
- prefs_common_junk_filter_list_set();
gtkut_stock_button_set_set_reverse(!prefs_common.comply_gnome_hig);
main_window_reflect_prefs_all();
compose_reflect_prefs_all();
diff --git a/src/summaryview.c b/src/summaryview.c
index 80e8adb9..0349f55c 100644
--- a/src/summaryview.c
+++ b/src/summaryview.c
@@ -4643,8 +4643,7 @@ static gboolean summary_filter_junk_func(GtkTreeModel *model, GtkTreePath *path,
fltinfo = filter_info_new();
fltinfo->flags = msginfo->flags;
- filter_apply_msginfo(prefs_common.manual_junk_fltlist,
- msginfo, fltinfo);
+ filter_apply_msginfo(summaryview->junk_fltlist, msginfo, fltinfo);
if (fltinfo->actions[FLT_ACTION_MOVE] ||
fltinfo->actions[FLT_ACTION_COPY] ||
@@ -4761,9 +4760,25 @@ void summary_filter(SummaryView *summaryview, gboolean selected_only)
void summary_filter_junk(SummaryView *summaryview, gboolean selected_only)
{
- if (prefs_common.manual_junk_fltlist)
+ FilterRule *rule;
+ GSList junk_fltlist = {NULL, NULL};
+ FolderItem *item = summaryview->folder_item;
+ FolderItem *junk = NULL;
+
+ if (!item)
+ return;
+
+ if (item->folder)
+ junk = folder_get_junk(item->folder);
+ rule = filter_junk_rule_create(NULL, junk, TRUE);
+ if (rule) {
+ junk_fltlist.data = rule;
+ summaryview->junk_fltlist = &junk_fltlist;
summary_filter_real(summaryview, summary_filter_junk_func,
selected_only);
+ summaryview->junk_fltlist = NULL;
+ filter_rule_free(rule);
+ }
}
void summary_filter_open(SummaryView *summaryview, FilterCreateType type)
diff --git a/src/summaryview.h b/src/summaryview.h
index 6c64fe7b..723b5b73 100644
--- a/src/summaryview.h
+++ b/src/summaryview.h
@@ -159,6 +159,9 @@ private:
GSList *pos_list;
guint write_lock_count;
+
+ /* junk filter list */
+ GSList *junk_fltlist;
};
SummaryView *summary_create(void);