X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=score.cpkg;fp=score.cpkg;h=40adf7878cb9760d11e38484b43056f6bb1ebabe;hp=0000000000000000000000000000000000000000;hb=455a2390989dfcfc90899785b0d8e9ac94ebd28e;hpb=74dda532c4844f38025d575926787532d41d613d diff --git a/score.cpkg b/score.cpkg new file mode 100644 index 0000000..40adf78 --- /dev/null +++ b/score.cpkg @@ -0,0 +1,187 @@ +/* + * Copyright notice from original mutt: + * Copyright (C) 1996-2000 Michael R. Elkins + * + * This file is part of mutt-ng, see http://www.muttng.org/. + * It's licensed under the GNU General Public License, + * please see the file GPL in the top level source directory. + */ + +#include + +#include "mutt.h" +#include "sort.h" +#include "pattern.h" +#include "score.h" +@import "lib-lua/base.cpkg" + +@package mod_score { + bool enable = 1; + /* + ** .pp + ** When this variable is \fIunset\fP, scoring is turned off. This can + ** be useful to selectively disable scoring for certain folders when the + ** ``$$score_threshold_delete'' variable and friends are used. + ** + */ + int threshold_flag = 9999; + /* + ** .pp + ** Messages which have been assigned a score greater than or equal to this + ** variable's value are automatically marked ``flagged''. + */ + int threshold_delete = -1; + /* + ** .pp + ** Messages which have been assigned a score equal to or lower than the value + ** of this variable are automatically marked for deletion by Madmutt. Since + ** Madmutt scores are always greater than or equal to zero, the default setting + ** of this variable will never mark a message for deletion. + */ + int threshold_read = -1; + /* + ** .pp + ** Messages which have been assigned a score equal to or lower than the value + ** of this variable are automatically marked as read by Madmutt. Since + ** Madmutt scores are always greater than or equal to zero, the default setting + ** of this variable will never mark a message read. + */ +}; + +typedef struct score_t { + char *str; + pattern_t *pat; + int val; + int exact; /* if this rule matches, don't evaluate any more */ + struct score_t *next; +} score_t; +DO_INIT(score_t, score); +static void score_wipe(score_t *sc) +{ + pattern_list_wipe(&sc->pat); + p_delete(&sc->str); +} +DO_NEW(score_t, score); +DO_DELETE(score_t, score); +DO_SLIST(score_t, score, score_delete); + +static score_t *Score = NULL; + +void mutt_check_rescore (CONTEXT * ctx) +{ + int i; + + if (option (OPTNEEDRESCORE) && mod_score.enable) { + if ((Sort & SORT_MASK) == SORT_SCORE || + (SortAux & SORT_MASK) == SORT_SCORE) { + set_option (OPTNEEDRESORT); + if ((Sort & SORT_MASK) == SORT_THREADS) + set_option (OPTSORTSUBTHREADS); + } + + /* must redraw the index since the user might have %N in it */ + set_option (OPTFORCEREDRAWINDEX); + set_option (OPTFORCEREDRAWPAGER); + + for (i = 0; ctx && i < ctx->msgcount; i++) { + mutt_score_message (ctx, ctx->hdrs[i], 1); + ctx->hdrs[i]->pair = 0; + } + } + unset_option (OPTNEEDRESCORE); +} + +int mutt_parse_score (BUFFER * buf, BUFFER * s, + unsigned long data __attribute__ ((unused)), + BUFFER * err) +{ + char *pattern, *pc; + struct pattern_t *pat; + score_t **last; + + mutt_extract_token (buf, s, 0); + if (!MoreArgs (s)) { + m_strcpy(err->data, err->dsize, _("score: too few arguments")); + return (-1); + } + pattern = buf->data; + p_clear(buf, 1); + mutt_extract_token (buf, s, 0); + if (MoreArgs (s)) { + p_delete(&pattern); + m_strcpy(err->data, err->dsize, _("score: too many arguments")); + return (-1); + } + + /* look for an existing entry and update the value, else add it to the end + of the list */ + for (last = &Score; *last; last = &(*last)->next) { + if (m_strcmp(pattern, (*last)->str) == 0) + break; + } + if (!*last) { + if (!(pat = mutt_pattern_comp(pattern, 0, err))) { + p_delete(&pattern); + return (-1); + } + *last = score_new(); + (*last)->pat = pat; + (*last)->str = pattern; + } + pc = buf->data; + pc += (*last)->exact = (*pc == '='); + (*last)->val = atoi(pc); + set_option(OPTNEEDRESCORE); + return 0; +} + +void mutt_score_message (CONTEXT * ctx, HEADER * hdr, int upd_ctx) +{ + score_t *tmp; + + hdr->score = 0; /* in case of re-scoring */ + for (tmp = Score; tmp; tmp = tmp->next) { + if (mutt_pattern_exec (tmp->pat, M_MATCH_FULL_ADDRESS, NULL, hdr) > 0) { + if (tmp->exact || tmp->val == 9999 || tmp->val == -9999) { + hdr->score = tmp->val; + break; + } + hdr->score += tmp->val; + } + } + if (hdr->score < 0) + hdr->score = 0; + + if (hdr->score <= mod_score.threshold_delete) + _mutt_set_flag (ctx, hdr, M_DELETE, 1, upd_ctx); + if (hdr->score <= mod_score.threshold_flag) + _mutt_set_flag (ctx, hdr, M_READ, 1, upd_ctx); + if (hdr->score >= mod_score.threshold_flag) + _mutt_set_flag (ctx, hdr, M_FLAG, 1, upd_ctx); +} + +int mutt_parse_unscore(BUFFER * buf, BUFFER * s, + unsigned long data __attribute__ ((unused)), + BUFFER * err __attribute__ ((unused))) +{ + while (MoreArgs(s)) { + mutt_extract_token(buf, s, 0); + if (!m_strcmp("*", buf->data)) { + score_list_wipe(&Score); + } else { + score_t **last; + + for (last = &Score; *last; last = &(*last)->next) { + if (!m_strcmp(buf->data, (*last)->str)) { + score_t *tmp = score_list_pop(last); + score_delete(&tmp); + break; + } + } + } + } + set_option (OPTNEEDRESCORE); + return 0; +} + +/* vim:set ft=c: */