From: Hoà Viêt Dinh Date: Tue, 15 May 2001 04:50:27 +0000 (+0000) Subject: new filtering X-Git-Tag: VERSION_0_5_0~156 X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=commitdiff_plain;h=8fd3feb036e25fc3eba0a950d52a8cf59acc4164;hp=44dd25fd00ecbbe4c9ee494b253979f426cacc3e new filtering --- diff --git a/src/Makefile.am b/src/Makefile.am index 6757ee7ee..d2b9564fd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -83,7 +83,8 @@ sylpheed_SOURCES = \ prefs_folder_item.c prefs_folder_item.h \ matcher.c matcher.h \ prefs_matcher.c prefs_matcher.h \ - prefs_scoring.c prefs_scoring.h + prefs_scoring.c prefs_scoring.h \ + filtering.c filtering.h EXTRA_DIST = \ pixmaps/clip.xpm \ diff --git a/src/filtering.c b/src/filtering.c new file mode 100644 index 000000000..a9440e032 --- /dev/null +++ b/src/filtering.c @@ -0,0 +1,601 @@ +#include +#include +#include +#include +#include +#include "intl.h" +#include "utils.h" +#include "defs.h" +#include "procheader.h" +#include "matcher.h" +#include "filtering.h" +#include "prefs.h" + +#define PREFSBUFSIZE 1024 + +GSList * prefs_filtering = NULL; + +FilteringAction * filteringaction_new(int type, gchar * dest_folder, + int account_id, gchar * address, + gchar * newsgroups) +{ + FilteringAction * action; + + action = g_new0(FilteringAction, 1); + + action->type = type;; + if (dest_folder) + action->dest_folder = g_strdup(dest_folder); + if (address) + action->address = address; + + return action; +} + +void filteringaction_free(FilteringAction * action) +{ + if (action->dest_folder) + g_free(action->dest_folder); + if (action->address) + g_free(action->address); + if (action->newsgroups) + g_free(action->newsgroups); + g_free(action); +} + +FilteringAction * filteringaction_parse(gchar ** str) +{ + FilteringAction * action; + gchar * tmp; + gchar * dest_folder = NULL; + gchar * address = NULL; + gchar * newsgroups = NULL; + gint account_id = 0; + gint key; + + tmp = * str; + + key = matcher_parse_keyword(&tmp); + + switch (key) { + case MATCHING_ACTION_MOVE: + dest_folder = matcher_parse_str(&tmp); + if (tmp == NULL) + return NULL; + + break; + case MATCHING_ACTION_COPY: + dest_folder = matcher_parse_str(&tmp); + break; + case MATCHING_ACTION_DELETE: + break; + case MATCHING_ACTION_MARK: + break; + case MATCHING_ACTION_MARK_AS_READ: + break; + case MATCHING_ACTION_UNMARK: + break; + case MATCHING_ACTION_MARK_AS_UNREAD: + break; + case MATCHING_ACTION_FORWARD: + account_id = matcher_parse_number(&tmp); + if (tmp == NULL) + return NULL; + + address = matcher_parse_str(&tmp); + if (tmp == NULL) + return NULL; + + break; + case MATCHING_ACTION_FORWARD_AS_ATTACHEMENT: + account_id = matcher_parse_number(&tmp); + if (tmp == NULL) + return NULL; + + address = matcher_parse_str(&tmp); + if (tmp == NULL) + return NULL; + + break; + case MATCHING_ACTION_FORWARD_NEWS: + account_id = matcher_parse_number(&tmp); + if (tmp == NULL) + return NULL; + + newsgroups = matcher_parse_str(&tmp); + if (tmp == NULL) + return NULL; + + break; + case MATCHING_ACTION_FORWARD_NEWS_AS_ATTACHEMENT: + account_id = matcher_parse_number(&tmp); + if (tmp == NULL) + return NULL; + + newsgroups = matcher_parse_str(&tmp); + if (tmp == NULL) + return NULL; + + break; + default: + * str = NULL; + return NULL; + } + + * str = tmp; + action = filteringaction_new(key, dest_folder, + account_id, address, newsgroups); + + return action; +} + +FilteringProp * filteringprop_parse(gchar ** str) +{ + gchar * tmp; + gint key; + FilteringProp * filtering; + MatcherList * matchers; + FilteringAction * action; + + tmp = * str; + + matchers = matcherlist_parse(&tmp); + if (tmp == NULL) { + * str = NULL; + return NULL; + } + + if (tmp == NULL) { + matcherlist_free(matchers); + * str = NULL; + return NULL; + } + + action = filteringaction_parse(&tmp); + if (tmp == NULL) { + matcherlist_free(matchers); + * str = NULL; + return NULL; + } + + filtering = filteringprop_new(matchers, action); + + * str = tmp; + return filtering; +} + + +FilteringProp * filteringprop_new(MatcherList * matchers, + FilteringAction * action) +{ + FilteringProp * filtering; + + filtering = g_new0(FilteringProp, 1); + filtering->matchers = matchers; + filtering->action = action; + + return filtering; +} + +void filteringprop_free(FilteringProp * prop) +{ + matcherlist_free(prop->matchers); + filteringaction_free(prop->action); + g_free(prop); +} + +static gboolean filteringaction_update_mark(MsgInfo * info) +{ + gchar * dest_path; + FILE * fp; + + dest_path = folder_item_get_path(info->folder); + if (dest_path == NULL) { + g_warning(_("Can't open mark file.\n")); + return FALSE; + } + + if ((fp = procmsg_open_mark_file(dest_path, TRUE)) + == NULL) { + g_warning(_("Can't open mark file.\n")); + return FALSE; + } + + procmsg_write_flags(info, fp); + fclose(fp); + return TRUE; +} + +/* + fitleringaction_apply + runs the action on one MsgInfo + return value : return TRUE if the action could be applied +*/ + +static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info, + GHashTable *folder_table) +{ + FolderItem * dest_folder; + gint val; + + switch(action->type) { + case MATCHING_ACTION_MOVE: + dest_folder = folder_find_item_from_path(action->dest_folder); + if (!dest_folder) + return FALSE; + + if (folder_item_move_msg(dest_folder, info) == -1) + return FALSE; + + info->flags = 0; + filteringaction_update_mark(info); + + val = GPOINTER_TO_INT(g_hash_table_lookup + (folder_table, dest_folder)); + if (val == 0) { + folder_item_scan(dest_folder); + g_hash_table_insert(folder_table, dest_folder, + GINT_TO_POINTER(1)); + } + val = GPOINTER_TO_INT(g_hash_table_lookup + (folder_table, info->folder)); + if (val == 0) { + folder_item_scan(info->folder); + g_hash_table_insert(folder_table, info->folder, + GINT_TO_POINTER(1)); + } + + return TRUE; + + case MATCHING_ACTION_COPY: + dest_folder = folder_find_item_from_path(action->dest_folder); + if (!dest_folder) + return FALSE; + + if (folder_item_copy_msg(dest_folder, info) == -1) + return FALSE; + + val = GPOINTER_TO_INT(g_hash_table_lookup + (folder_table, dest_folder)); + if (val == 0) { + folder_item_scan(dest_folder); + g_hash_table_insert(folder_table, dest_folder, + GINT_TO_POINTER(1)); + } + + return TRUE; + + case MATCHING_ACTION_DELETE: + if (folder_item_remove_msg(dest_folder, info->msgnum) == -1) + return FALSE; + + info->flags = 0; + filteringaction_update_mark(info); + + return TRUE; + + case MATCHING_ACTION_MARK: + MSG_SET_FLAGS(info->flags, MSG_MARKED); + filteringaction_update_mark(info); + + return TRUE; + + case MATCHING_ACTION_UNMARK: + MSG_UNSET_FLAGS(info->flags, MSG_MARKED); + filteringaction_update_mark(info); + + return TRUE; + + case MATCHING_ACTION_MARK_AS_READ: + MSG_UNSET_FLAGS(info->flags, MSG_UNREAD | MSG_NEW); + filteringaction_update_mark(info); + + return TRUE; + + case MATCHING_ACTION_MARK_AS_UNREAD: + MSG_SET_FLAGS(info->flags, MSG_UNREAD | MSG_NEW); + filteringaction_update_mark(info); + + return TRUE; + + case MATCHING_ACTION_FORWARD: + + return FALSE; + + case MATCHING_ACTION_FORWARD_AS_ATTACHEMENT: + + return FALSE; + + case MATCHING_ACTION_FORWARD_NEWS: + + return FALSE; + + case MATCHING_ACTION_FORWARD_NEWS_AS_ATTACHEMENT: + + return FALSE; + + default: + return FALSE; + } +} + +/* + filteringprop_apply + runs the action on one MsgInfo if it matches the criterium + return value : return TRUE if the action doesn't allow more actions +*/ + +static gboolean filteringprop_apply(FilteringProp * filtering, MsgInfo * info, + GHashTable *folder_table) +{ + if (matcherlist_match(filtering->matchers, info)) { + gint result; + gchar * action_str; + + result = TRUE; + + result = filteringaction_apply(filtering->action, info, + folder_table); + action_str = + filteringaction_to_string(filtering->action); + if (!result) { + g_warning(_("action %s could not be applied"), + action_str); + } + else { + debug_print(_("message %i %s..."), + info->msgnum, action_str); + } + + g_free(action_str); + + switch(filtering->action->type) { + case MATCHING_ACTION_MOVE: + case MATCHING_ACTION_DELETE: + return TRUE; + case MATCHING_ACTION_COPY: + case MATCHING_ACTION_MARK: + case MATCHING_ACTION_MARK_AS_READ: + case MATCHING_ACTION_UNMARK: + case MATCHING_ACTION_MARK_AS_UNREAD: + case MATCHING_ACTION_FORWARD: + case MATCHING_ACTION_FORWARD_AS_ATTACHEMENT: + case MATCHING_ACTION_FORWARD_NEWS: + case MATCHING_ACTION_FORWARD_NEWS_AS_ATTACHEMENT: + return FALSE; + default: + return FALSE; + } + } + else + return FALSE; +} + +void filter_msginfo(GSList * filtering_list, MsgInfo * info, + GHashTable *folder_table) +{ + GSList * l; + + if (info == NULL) { + g_warning(_("msginfo is not set")); + return; + } + + for(l = filtering_list ; l != NULL ; l = g_slist_next(l)) { + FilteringProp * filtering = (FilteringProp *) l->data; + + if (filteringprop_apply(filtering, info, folder_table)) + break; + } +} + +void filter_message(GSList * filtering_list, FolderItem * item, + gint msgnum, GHashTable *folder_table) +{ + MsgInfo * msginfo; + gchar * filename; + + if (item == NULL) { + g_warning(_("folderitem not set")); + return; + } + + filename = folder_item_fetch_msg(item, msgnum); + + if (filename == NULL) { + g_warning(_("filename is not set")); + return; + } + + msginfo = procheader_parse(filename, 0, TRUE); + + g_free(filename); + + if (msginfo == NULL) { + g_warning(_("could not get info for %s"), filename); + return; + } + + msginfo->folder = item; + msginfo->msgnum = msgnum; + + filter_msginfo(filtering_list, msginfo, folder_table); +} + +void prefs_filtering_read_config(void) +{ + gchar *rcpath; + FILE *fp; + gchar buf[PREFSBUFSIZE]; + + debug_print(_("Reading filtering configuration...\n")); + + rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, + FILTERING_RC, NULL); + if ((fp = fopen(rcpath, "r")) == NULL) { + if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen"); + g_free(rcpath); + prefs_filtering = NULL; + return; + } + g_free(rcpath); + + /* remove all filtering */ + while (prefs_filtering != NULL) { + FilteringProp * filtering = + (FilteringProp *) prefs_filtering->data; + filteringprop_free(filtering); + prefs_filtering = g_slist_remove(prefs_filtering, filtering); + } + + while (fgets(buf, sizeof(buf), fp) != NULL) { + FilteringProp * filtering; + gchar * tmp; + + g_strchomp(buf); + + if ((*buf != '#') && (*buf != '\0')) { + tmp = buf; + filtering = filteringprop_parse(&tmp); + if (tmp != NULL) { + prefs_filtering = + g_slist_append(prefs_filtering, + filtering); + } + else { + /* debug */ + g_warning(_("syntax error : %s\n"), buf); + } + } + } + + fclose(fp); +} + +/* +struct _FilteringAction { + int type; + gchar * dest_folder; + gchar * address; + gchar * newsgroups; +} + + MATCHING_ACTION_MOVE, + MATCHING_ACTION_COPY, + MATCHING_ACTION_DELETE, + MATCHING_ACTION_MARK, + MATCHING_ACTION_MARK_AS_READ, + MATCHING_ACTION_FORWARD, + MATCHING_ACTION_FORWARD_AS_ATTACHEMENT, + MATCHING_ACTION_FORWARD_NEWS, + MATCHING_ACTION_FORWARD_NEWS_AS_ATTACHEMENT, +*/ + +gchar * filteringaction_to_string(FilteringAction * action) +{ + gchar * command_str; + gint i; + gchar * account_id_str; + + command_str = NULL; + command_str = get_matchparser_tab_str(action->type); + + if (command_str == NULL) + return NULL; + + switch(action->type) { + case MATCHING_ACTION_MOVE: + case MATCHING_ACTION_COPY: + return g_strconcat(command_str, " ", action->dest_folder, + NULL); + + case MATCHING_ACTION_DELETE: + case MATCHING_ACTION_MARK: + case MATCHING_ACTION_UNMARK: + case MATCHING_ACTION_MARK_AS_READ: + case MATCHING_ACTION_MARK_AS_UNREAD: + return g_strdup(command_str); + break; + + case MATCHING_ACTION_FORWARD: + case MATCHING_ACTION_FORWARD_AS_ATTACHEMENT: + account_id_str = itos(action->account_id); + return g_strconcat(command_str, " ", account_id_str, + " \"", action->address, "\"", NULL); + + case MATCHING_ACTION_FORWARD_NEWS: + case MATCHING_ACTION_FORWARD_NEWS_AS_ATTACHEMENT: + account_id_str = itos(action->account_id); + return g_strconcat(command_str, " ", account_id_str, + " \"", action->newsgroups, "\"", NULL); + + default: + return NULL; + } +} + +gchar * filteringprop_to_string(FilteringProp * prop) +{ + gchar * list_str; + gchar * action_str; + gchar * filtering_str; + + action_str = filteringaction_to_string(prop->action); + + if (action_str == NULL) + return NULL; + + list_str = matcherlist_to_string(prop->matchers); + + if (list_str == NULL) { + g_free(action_str); + return NULL; + } + + filtering_str = g_strconcat(list_str, " ", action_str, NULL); + g_free(list_str); + g_free(action_str); + + return filtering_str; +} + +void prefs_filtering_write_config(void) +{ + gchar *rcpath; + PrefFile *pfile; + GSList *cur; + FilteringProp * prop; + + debug_print(_("Writing filtering configuration...\n")); + + rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTERING_RC, NULL); + + if ((pfile = prefs_write_open(rcpath)) == NULL) { + g_warning(_("failed to write configuration to file\n")); + g_free(rcpath); + return; + } + + for (cur = prefs_filtering; cur != NULL; cur = cur->next) { + gchar *filtering_str; + + prop = (FilteringProp *) cur->data; + filtering_str = filteringprop_to_string(prop); + if (fputs(filtering_str, pfile->fp) == EOF || + fputc('\n', pfile->fp) == EOF) { + FILE_OP_ERROR(rcpath, "fputs || fputc"); + prefs_write_close_revert(pfile); + g_free(rcpath); + g_free(filtering_str); + return; + } + g_free(filtering_str); + } + + g_free(rcpath); + + if (prefs_write_close(pfile) < 0) { + g_warning(_("failed to write configuration to file\n")); + return; + } +} diff --git a/src/filtering.h b/src/filtering.h new file mode 100644 index 000000000..aaaf77f85 --- /dev/null +++ b/src/filtering.h @@ -0,0 +1,52 @@ +#ifndef FILTER_NEW_H + +#define FILTER_NEW_H + +#include +#include "matcher.h" +#include "procmsg.h" + +struct _FilteringAction { + gint type; + gchar * dest_folder; + gint account_id; + gchar * address; + gchar * newsgroups; +}; + +typedef struct _FilteringAction FilteringAction; + +struct _FilteringProp { + MatcherList * matchers; + FilteringAction * action; +}; + +typedef struct _FilteringProp FilteringProp; + +extern GSList * prefs_filtering; + + +FilteringAction * filteringaction_new(int type, gchar * dest_folder, + int account_id, gchar * address, + gchar * newsgroups); +void filteringaction_free(FilteringAction * action); +FilteringAction * filteringaction_parse(gchar ** str); + +FilteringProp * filteringprop_new(MatcherList * matchers, + FilteringAction * action); +void filteringprop_free(FilteringProp * prop); + +FilteringProp * filteringprop_parse(gchar ** str); + + +void filter_msginfo(GSList * filtering_list, MsgInfo * info, + GHashTable *folder_table); +void filter_message(GSList * filtering_list, FolderItem * item, + gint msgnum, GHashTable *folder_table); + +gchar * filteringaction_to_string(FilteringAction * action); +void prefs_filtering_write_config(void); +void prefs_filtering_read_config(void); +gchar * filteringprop_to_string(FilteringProp * prop); + +#endif diff --git a/src/inc.c b/src/inc.c index 6f3764ef6..6588b60f9 100644 --- a/src/inc.c +++ b/src/inc.c @@ -60,6 +60,7 @@ #include "filter.h" #include "automaton.h" #include "folder.h" +#include "filtering.h" #include "pixmaps/continue.xpm" #include "pixmaps/complete.xpm" @@ -771,6 +772,7 @@ gint inc_drop_message(const gchar *file, Pop3State *state) FolderItem *inbox; FolderItem *dropfolder; gint val; + gint msgnum; if (state->ac_prefs->inbox) { inbox = folder_find_item_from_path(state->ac_prefs->inbox); @@ -783,16 +785,24 @@ gint inc_drop_message(const gchar *file, Pop3State *state) return -1; } - if (state->ac_prefs->filter_on_recv) { - dropfolder = - filter_get_dest_folder(prefs_common.fltlist, file); - if (!dropfolder) dropfolder = inbox; - else if (!strcmp(dropfolder->path, FILTER_NOT_RECEIVE)) { - g_warning(_("a message won't be received\n")); - return 1; - } - } else + + if (prefs_filtering == NULL) { + /* old filtering */ + if (state->ac_prefs->filter_on_recv) { + dropfolder = + filter_get_dest_folder(prefs_common.fltlist, file); + if (!dropfolder) dropfolder = inbox; + else if (!strcmp(dropfolder->path, FILTER_NOT_RECEIVE)) { + g_warning(_("a message won't be received\n")); + return 1; + } + } else + dropfolder = inbox; + } + else { + /* new filtering */ dropfolder = inbox; + } val = GPOINTER_TO_INT(g_hash_table_lookup (state->folder_table, dropfolder)); @@ -802,12 +812,21 @@ gint inc_drop_message(const gchar *file, Pop3State *state) GINT_TO_POINTER(1)); } - if (folder_item_add_msg(dropfolder, file) < 0) { + if ((msgnum = folder_item_add_msg(dropfolder, file)) < 0) { unlink(file); return -1; } unlink(file); + + if (prefs_filtering != NULL) { + /* new filtering */ + if (state->ac_prefs->filter_on_recv) { + filter_message(prefs_filtering, dropfolder, msgnum, + state->folder_table); + } + } + return 0; } diff --git a/src/main.c b/src/main.c index 8c91b73b6..f4168faa4 100644 --- a/src/main.c +++ b/src/main.c @@ -231,6 +231,7 @@ int main(int argc, char *argv[]) prefs_display_header_read_config(); prefs_display_header_write_config(); prefs_scoring_read_config(); + prefs_filtering_read_config(); gtkut_widget_init(); diff --git a/src/matcher.c b/src/matcher.c index 89985b186..2743fdc3b 100644 --- a/src/matcher.c +++ b/src/matcher.c @@ -14,7 +14,7 @@ struct _MatchParser { typedef struct _MatchParser MatchParser; -MatchParser matchparser_tab[] = { +static MatchParser matchparser_tab[] = { /* msginfo flags */ {MATCHING_ALL, "all"}, {MATCHING_UNREAD, "unread"}, @@ -76,13 +76,29 @@ MatchParser matchparser_tab[] = { {MATCHING_ACTION_COPY, "copy"}, {MATCHING_ACTION_DELETE, "delete"}, {MATCHING_ACTION_MARK, "mark"}, + {MATCHING_ACTION_UNMARK, "unmark"}, {MATCHING_ACTION_MARK_AS_READ, "mark_as_read"}, + {MATCHING_ACTION_MARK_AS_UNREAD, "mark_as_unread"}, {MATCHING_ACTION_FORWARD, "forward"}, {MATCHING_ACTION_FORWARD_AS_ATTACHEMENT, "forward_as_attachement"}, {MATCHING_ACTION_FORWARD_NEWS, "forward_news"}, {MATCHING_ACTION_FORWARD_NEWS_AS_ATTACHEMENT, "forward_news_as_attachement"} }; +gchar * get_matchparser_tab_str(gint id) +{ + gint i; + + for(i = 0 ; i < (int) (sizeof(matchparser_tab) / sizeof(MatchParser)) ; + i++) { + if (matchparser_tab[i].id == id) + return matchparser_tab[i].str; + } + return NULL; +} + + + /* syntax for matcher @@ -724,9 +740,15 @@ static gboolean matcherprop_criteria_headers(MatcherProp * matcher) */ static gboolean matcherlist_match_one_header(MatcherList * matchers, - gchar * buf, gboolean result) + gchar * buf) { GSList * l; + gboolean result; + + if (matchers->bool_and) + result = TRUE; + else + result = FALSE; for(l = matchers->matchers ; l != NULL ; l = g_slist_next(l)) { MatcherProp * matcher = (MatcherProp *) l->data; @@ -751,22 +773,15 @@ static gboolean matcherlist_match_one_header(MatcherList * matchers, returns TRUE if one of the headers matchs the MatcherList criteria */ -static gboolean matcherlist_match_headers(MatcherList * matchers, FILE * fp, - gboolean result) +static gboolean matcherlist_match_headers(MatcherList * matchers, FILE * fp) { gchar buf[BUFFSIZE]; - while (procheader_get_one_field(buf, sizeof(buf), fp, NULL) != -1) { - if (matcherlist_match_one_header(matchers, buf, result)) { - if (!matchers->bool_and) - return TRUE; - } - else { - if (matchers->bool_and) - return FALSE; - } - } - return result; + while (procheader_get_one_field(buf, sizeof(buf), fp, NULL) != -1) + if (matcherlist_match_one_header(matchers, buf)) + return TRUE; + + return FALSE; } /* @@ -810,10 +825,15 @@ static gboolean matcherprop_match_line(MatcherProp * matcher, gchar * line) returns TRUE if the string matchs the MatcherList criteria */ -static gboolean matcherlist_match_line(MatcherList * matchers, gchar * line, - gboolean result) +static gboolean matcherlist_match_line(MatcherList * matchers, gchar * line) { GSList * l; + gboolean result; + + if (matchers->bool_and) + result = TRUE; + else + result = FALSE; for(l = matchers->matchers ; l != NULL ; l = g_slist_next(l)) { MatcherProp * matcher = (MatcherProp *) l->data; @@ -837,22 +857,15 @@ static gboolean matcherlist_match_line(MatcherList * matchers, gchar * line, returns TRUE if one line of the body matchs the MatcherList criteria */ -static gboolean matcherlist_match_body(MatcherList * matchers, FILE * fp, - gboolean result) +static gboolean matcherlist_match_body(MatcherList * matchers, FILE * fp) { gchar buf[BUFFSIZE]; - while (fgets(buf, sizeof(buf), fp) != NULL) { - if (matcherlist_match_line(matchers, buf, result)) { - if (!matchers->bool_and) - return TRUE; - } - else { - if (matchers->bool_and) - return FALSE; - } - } - return result; + while (fgets(buf, sizeof(buf), fp) != NULL) + if (matcherlist_match_line(matchers, buf)) + return TRUE; + + return FALSE; } gboolean matcherlist_match_file(MatcherList * matchers, MsgInfo * info, @@ -889,11 +902,11 @@ gboolean matcherlist_match_file(MatcherList * matchers, MsgInfo * info, g_free(file); return result; } - + /* read the headers */ if (read_headers) { - if (matcherlist_match_headers(matchers, fp, result)) { + if (matcherlist_match_headers(matchers, fp)) { if (!matchers->bool_and) result = TRUE; } @@ -905,10 +918,10 @@ gboolean matcherlist_match_file(MatcherList * matchers, MsgInfo * info, else { matcherlist_skip_headers(fp); } - + /* read the body */ if (read_body) { - if (matcherlist_match_body(matchers, fp, result)) { + if (matcherlist_match_body(matchers, fp)) { if (!matchers->bool_and) result = TRUE; } @@ -953,16 +966,51 @@ gboolean matcherlist_match(MatcherList * matchers, MsgInfo * info) for(l = matchers->matchers ; l != NULL ; l = g_slist_next(l)) { MatcherProp * matcher = (MatcherProp *) l->data; - if (matcherprop_match(matcher, info)) { - if (!matchers->bool_and) { - result = TRUE; - break; + switch(matcher->criteria) { + case MATCHING_ALL: + case MATCHING_UNREAD: + case MATCHING_NOT_UNREAD: + case MATCHING_NEW: + case MATCHING_NOT_NEW: + case MATCHING_MARKED: + case MATCHING_NOT_MARKED: + case MATCHING_DELETED: + case MATCHING_NOT_DELETED: + case MATCHING_REPLIED: + case MATCHING_NOT_REPLIED: + case MATCHING_FORWARDED: + case MATCHING_NOT_FORWARDED: + case MATCHING_SUBJECT: + case MATCHING_NOT_SUBJECT: + case MATCHING_FROM: + case MATCHING_NOT_FROM: + case MATCHING_TO: + case MATCHING_NOT_TO: + case MATCHING_CC: + case MATCHING_NOT_CC: + case MATCHING_TO_OR_CC: + case MATCHING_NOT_TO_AND_NOT_CC: + case MATCHING_AGE_GREATER: + case MATCHING_AGE_LOWER: + case MATCHING_NEWSGROUPS: + case MATCHING_NOT_NEWSGROUPS: + case MATCHING_INREPLYTO: + case MATCHING_NOT_INREPLYTO: + case MATCHING_REFERENCES: + case MATCHING_NOT_REFERENCES: + case MATCHING_SCORE_GREATER: + case MATCHING_SCORE_LOWER: + if (matcherprop_match(matcher, info)) { + if (!matchers->bool_and) { + result = TRUE; + break; + } } - } - else { - if (matchers->bool_and) { - result = FALSE; - break; + else { + if (matchers->bool_and) { + result = FALSE; + break; + } } } } diff --git a/src/matcher.h b/src/matcher.h index c153e8e1f..d3a4f8843 100644 --- a/src/matcher.h +++ b/src/matcher.h @@ -64,6 +64,8 @@ enum { MATCHING_ACTION_DELETE, MATCHING_ACTION_MARK, MATCHING_ACTION_MARK_AS_READ, + MATCHING_ACTION_UNMARK, + MATCHING_ACTION_MARK_AS_UNREAD, MATCHING_ACTION_FORWARD, MATCHING_ACTION_FORWARD_AS_ATTACHEMENT, MATCHING_ACTION_FORWARD_NEWS, @@ -94,6 +96,7 @@ struct _MatcherList { typedef struct _MatcherList MatcherList; +gchar * get_matchparser_tab_str(gint id); MatcherProp * matcherprop_new(gint criteria, gchar * header, gint matchtype, gchar * expr, int age); diff --git a/src/mbox.c b/src/mbox.c index 073ca4963..a5de8eff8 100644 --- a/src/mbox.c +++ b/src/mbox.c @@ -41,6 +41,7 @@ #include "prefs_account.h" #include "account.h" #include "utils.h" +#include "filtering.h" #define MSGBUFSIZE 8192 @@ -103,6 +104,7 @@ gint proc_mbox(FolderItem *dest, const gchar *mbox, GHashTable *folder_table) gint empty_line; gint val; gboolean is_next_msg = FALSE; + gint msgnum; if ((tmp_fp = fopen(tmp_file, "w")) == NULL) { FILE_OP_ERROR(tmp_file, "fopen"); @@ -198,26 +200,41 @@ gint proc_mbox(FolderItem *dest, const gchar *mbox, GHashTable *folder_table) } if (folder_table) { - dropfolder = filter_get_dest_folder - (prefs_common.fltlist, tmp_file); - if (!dropfolder || - !strcmp(dropfolder->path, FILTER_NOT_RECEIVE)) + if (prefs_filtering == NULL) { + /* old filtering */ + dropfolder = filter_get_dest_folder + (prefs_common.fltlist, tmp_file); + if (!dropfolder || + !strcmp(dropfolder->path, FILTER_NOT_RECEIVE)) + dropfolder = dest; + val = GPOINTER_TO_INT(g_hash_table_lookup + (folder_table, dropfolder)); + if (val == 0) { + folder_item_scan(dropfolder); + g_hash_table_insert(folder_table, dropfolder, + GINT_TO_POINTER(1)); + } + } + else { + /* new filtering */ dropfolder = dest; - val = GPOINTER_TO_INT(g_hash_table_lookup - (folder_table, dropfolder)); - if (val == 0) { - folder_item_scan(dropfolder); - g_hash_table_insert(folder_table, dropfolder, - GINT_TO_POINTER(1)); } } else dropfolder = dest; - if (folder_item_add_msg(dropfolder, tmp_file) < 0) { + if (msgnum =folder_item_add_msg(dropfolder, tmp_file) < 0) { fclose(mbox_fp); unlink(tmp_file); return -1; } + + if (prefs_filtering != NULL) { + /* new filtering */ + if (folder_table) { + filter_message(prefs_filtering, dropfolder, + msgnum, folder_table); + } + } msgs++; } while (from_line[0] != '\0'); diff --git a/src/mh.c b/src/mh.c index 8f136bce7..bed1489d1 100644 --- a/src/mh.c +++ b/src/mh.c @@ -166,6 +166,11 @@ gint mh_move_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo) g_return_val_if_fail(dest != NULL, -1); g_return_val_if_fail(msginfo != NULL, -1); + if (!msginfo->folder) { + g_warning(_("the folder of the message is not defined\n")); + return -1; + } + if (msginfo->folder == dest) { g_warning(_("the src folder is identical to the dest.\n")); return -1; @@ -331,6 +336,11 @@ gint mh_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo) g_return_val_if_fail(dest != NULL, -1); g_return_val_if_fail(msginfo != NULL, -1); + if (!msginfo->folder) { + g_warning(_("the folder of the message is not defined\n")); + return -1; + } + if (msginfo->folder == dest) { g_warning(_("the src folder is identical to the dest.\n")); return -1; diff --git a/src/summaryview.c b/src/summaryview.c index ba93d404e..a8125f194 100644 --- a/src/summaryview.c +++ b/src/summaryview.c @@ -628,7 +628,8 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item, return FALSE; } else #endif - summary_write_cache(summaryview); + if (!is_refresh) + summary_write_cache(summaryview); gtk_clist_freeze(GTK_CLIST(ctree)); @@ -1456,8 +1457,8 @@ static void summary_set_ctree_from_list(SummaryView *summaryview, gchar * s; parentinfo->threadscore = cur_msginfo->threadscore; - s = itos(parentinfo->threadscore); #if 0 + s = itos(parentinfo->threadscore); gtk_ctree_node_set_text(ctree, cur_parent, S_COL_SCORE, s); #endif }