/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2006 Hiroyuki Yamamoto & The Sylpheed Claws Team
+ * Copyright (C) 1999-2007 Hiroyuki Yamamoto & The Claws Mail Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "filtering.h"
#include "prefs_gtk.h"
#include "compose.h"
+#include "prefs_common.h"
#define PREFSBUFSIZE 1024
void filteringaction_free(FilteringAction * action)
{
g_return_if_fail(action);
- if (action->destination)
- g_free(action->destination);
+ g_free(action->destination);
g_free(action);
}
-FilteringProp * filteringprop_new(const gchar *name,
+FilteringProp * filteringprop_new(gboolean enabled,
+ const gchar *name,
+ gint account_id,
MatcherList * matchers,
GSList * action_list)
{
FilteringProp * filtering;
filtering = g_new0(FilteringProp, 1);
+ filtering->enabled = enabled;
filtering->name = name ? g_strdup(name): NULL;
+ filtering->account_id = account_id;
filtering->matchers = matchers;
filtering->action_list = action_list;
filteringaction_copy(filtering_action));
}
+ new->enabled = src->enabled;
new->name = g_strdup(src->name);
return new;
GSList *messages = g_slist_copy(msgs);
FolderItem *last_item = NULL;
gboolean is_copy = FALSE, is_move = FALSE;
-
+ debug_print("checking %d messages\n", g_slist_length(msgs));
while (messages) {
GSList *batch = NULL, *cur;
gint found = 0;
- debug_print("%d messages to filter\n", g_slist_length(messages));
for (cur = messages; cur; cur = cur->next) {
MsgInfo *info = (MsgInfo *)cur->data;
if (last_item == NULL) {
}
if (last_item == NULL)
continue;
- debug_print("for %s\n", folder_item_get_path(last_item));
if (!is_copy && !is_move) {
if (info->is_copy)
is_copy = TRUE;
if (info->to_filter_folder == last_item
&& info->is_copy == is_copy
&& info->is_move == is_move) {
- batch = g_slist_append(batch, info);
+ batch = g_slist_prepend(batch, info);
}
}
if (found == 0) {
debug_print("no more messages to move/copy\n");
break;
+ } else {
+ debug_print("%d messages to %s in %s\n", found,
+ is_copy ? "copy":"move", last_item->name ? last_item->name:"(noname)");
}
for (cur = batch; cur; cur = cur->next) {
MsgInfo *info = (MsgInfo *)cur->data;
messages = g_slist_remove(messages, info);
}
+ batch = g_slist_reverse(batch);
if (g_slist_length(batch)) {
MsgInfo *info = (MsgInfo *)batch->data;
- debug_print("%s %d messages to %s\n",
- is_copy?"copying":"moving",
- g_slist_length(batch),
- folder_item_get_path(last_item));
if (is_copy && last_item != info->folder) {
folder_item_copy_msgs(last_item, batch);
} else if (is_move && last_item != info->folder) {
last_item = NULL;
is_copy = FALSE;
is_move = FALSE;
- debug_print("%d messages remaining\n", g_slist_length(messages));
}
/* we don't reference the msginfos, because caller will do */
g_slist_free(messages);
return FALSE;
}
+ /* check if mail is set to copy already,
+ * in which case we have to do it */
+ if (info->is_copy && info->to_filter_folder) {
+ debug_print("should cp and mv !\n");
+ folder_item_copy_msg(info->to_filter_folder, info);
+ info->is_copy = FALSE;
+ }
/* mark message to be moved */
info->is_move = TRUE;
info->to_filter_folder = dest_folder;
- debug_print("set to move to %s\n", folder_item_get_path(dest_folder));
return TRUE;
case MATCHACTION_COPY:
return FALSE;
}
+ /* check if mail is set to copy already,
+ * in which case we have to do it */
+ if (info->is_copy && info->to_filter_folder) {
+ debug_print("should cp and mv !\n");
+ folder_item_copy_msg(info->to_filter_folder, info);
+ info->is_copy = FALSE;
+ }
/* mark message to be copied */
info->is_copy = TRUE;
info->to_filter_folder = dest_folder;
- debug_print("set to copy to %s\n", folder_item_get_path(dest_folder));
return TRUE;
case MATCHACTION_DELETE:
procmsg_msginfo_set_flags(info, MSG_UNREAD | MSG_NEW, 0);
return TRUE;
+ case MATCHACTION_MARK_AS_SPAM:
+ procmsg_spam_learner_learn(info, NULL, TRUE);
+ procmsg_msginfo_change_flags(info, MSG_SPAM, 0, MSG_NEW|MSG_UNREAD, 0);
+ if (procmsg_spam_get_folder(info)) {
+ info->is_move = TRUE;
+ info->to_filter_folder = procmsg_spam_get_folder(info);
+ }
+ return TRUE;
+
+ case MATCHACTION_MARK_AS_HAM:
+ procmsg_spam_learner_learn(info, NULL, FALSE);
+ procmsg_msginfo_unset_flags(info, MSG_SPAM, 0);
+ return TRUE;
+
case MATCHACTION_COLOR:
procmsg_msginfo_unset_flags(info, MSG_CLABEL_FLAG_MASK, 0);
procmsg_msginfo_set_flags(info, MSG_COLORLABEL_TO_FLAGS(action->labelcolor), 0);
account = account_find_from_id(action->account_id);
compose = compose_forward(account, info,
action->type == MATCHACTION_FORWARD ? FALSE : TRUE,
- NULL, TRUE);
+ NULL, TRUE, TRUE);
compose_entry_append(compose, action->destination,
compose->account->protocol == A_NNTP
? COMPOSE_NEWSGROUPS
case MATCHACTION_REDIRECT:
account = account_find_from_id(action->account_id);
- compose = compose_redirect(account, info);
+ compose = compose_redirect(account, info, TRUE);
if (compose->account->protocol == A_NNTP)
break;
else
info->hidden = TRUE;
return TRUE;
+ case MATCHACTION_IGNORE:
+ procmsg_msginfo_set_flags(info, MSG_IGNORE_THREAD, 0);
+ return TRUE;
+
default:
break;
}
return TRUE;
}
-static gboolean filtering_match_condition(FilteringProp *filtering, MsgInfo *info)
+static gboolean filtering_match_condition(FilteringProp *filtering, MsgInfo *info,
+ PrefsAccount *ac_prefs)
{
- return matcherlist_match(filtering->matchers, info);
+ gboolean matches = FALSE;
+
+ if (ac_prefs != NULL) {
+ matches = ((filtering->account_id == 0)
+ || (filtering->account_id == ac_prefs->account_id));
+ } else {
+ switch (prefs_common.apply_per_account_filtering_rules) {
+ case FILTERING_ACCOUNT_RULES_FORCE:
+ /* apply filtering rules regardless to the account info */
+ matches = TRUE;
+ break;
+ case FILTERING_ACCOUNT_RULES_SKIP:
+ /* don't apply filtering rules that belong to an account */
+ matches = (filtering->account_id == 0);
+ break;
+ case FILTERING_ACCOUNT_RULES_USE_CURRENT:
+ matches = ((filtering->account_id == 0)
+ || (filtering->account_id == cur_account->account_id));
+ break;
+ }
+ }
+
+ return matches && matcherlist_match(filtering->matchers, info);
}
/*!
gboolean * final)
{
gboolean result = TRUE;
- gchar buf[50];
+ gchar buf[256];
GSList * tmp;
* final = FALSE;
case MATCHACTION_MOVE:
case MATCHACTION_DELETE:
case MATCHACTION_STOP:
+ case MATCHACTION_MARK_AS_SPAM:
return TRUE; /* MsgInfo invalid for message */
default:
return FALSE;
}
}
-static gboolean filter_msginfo(GSList * filtering_list, MsgInfo * info)
+static gboolean filter_msginfo(GSList * filtering_list, MsgInfo * info, PrefsAccount* ac_prefs)
{
GSList *l;
gboolean final;
for (l = filtering_list, final = FALSE, apply_next = FALSE; l != NULL; l = g_slist_next(l)) {
FilteringProp * filtering = (FilteringProp *) l->data;
- if (filtering_match_condition(filtering, info)) {
+ if (filtering->enabled && filtering_match_condition(filtering, info, ac_prefs)) {
apply_next = filtering_apply_rule(filtering, info, &final);
if (final)
break;
* processing. E.g. \ref inc.c::inc_start moves the
* message to the inbox.
*/
-gboolean filter_message_by_msginfo(GSList *flist, MsgInfo *info)
+gboolean filter_message_by_msginfo(GSList *flist, MsgInfo *info, PrefsAccount* ac_prefs)
{
- return filter_msginfo(flist, info);
+ return filter_msginfo(flist, info, ac_prefs);
}
gchar *filteringaction_to_string(gchar *dest, gint destlen, FilteringAction *action)
case MATCHACTION_UNLOCK:
case MATCHACTION_MARK_AS_READ:
case MATCHACTION_MARK_AS_UNREAD:
+ case MATCHACTION_MARK_AS_SPAM:
+ case MATCHACTION_MARK_AS_HAM:
case MATCHACTION_STOP:
case MATCHACTION_HIDE:
+ case MATCHACTION_IGNORE:
g_snprintf(dest, destlen, "%s", command_str);
return dest;
/* FIXME: Note folder settings were changed, where the updates? */
}
+gboolean filtering_peek_per_account_rules(GSList *filtering_list)
+/* return TRUE if there's at least one per-account filtering rule */
+{
+ GSList *l;
+
+ for (l = filtering_list; l != NULL; l = g_slist_next(l)) {
+ FilteringProp * filtering = (FilteringProp *) l->data;
+
+ if (filtering->enabled && (filtering->account_id != 0)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}