cleaner messages, no popup if required
[claws.git] / src / scoring.c
1 #include <ctype.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <errno.h>
5 #include <stdio.h>
6 #include "defs.h"
7 #include "intl.h"
8 #include "utils.h"
9 #include "procheader.h"
10 #include "matcher.h"
11 #include "scoring.h"
12 #include "prefs.h"
13 #include "folder.h"
14
15 #define PREFSBUFSIZE            1024
16
17
18 GSList * global_scoring = NULL;
19
20 ScoringProp * scoringprop_new(MatcherList * matchers, int score)
21 {
22         ScoringProp * scoring;
23
24         scoring = g_new0(ScoringProp, 1);
25         scoring->matchers = matchers;
26         scoring->score = score;
27
28         return scoring;
29 }
30
31 ScoringProp * scoringprop_copy(ScoringProp *src)
32 {
33         ScoringProp * new;
34         GSList *tmp;
35         
36         new = g_new0(ScoringProp, 1);
37         new->matchers = g_new0(MatcherList, 1);
38         for (tmp = src->matchers->matchers; tmp != NULL && tmp->data != NULL;) {
39                 MatcherProp *matcher = (MatcherProp *)tmp->data;
40                 
41                 new->matchers->matchers = g_slist_append(new->matchers->matchers,
42                                                    matcherprop_copy(matcher));
43                 tmp = tmp->next;
44         }
45         new->matchers->bool_and = src->matchers->bool_and;
46         new->score = src->score;
47
48         return new;
49 }
50
51 void scoringprop_free(ScoringProp * prop)
52 {
53         matcherlist_free(prop->matchers);
54         g_free(prop);
55 }
56
57 gint scoringprop_score_message(ScoringProp * scoring, MsgInfo * info)
58 {
59         if (matcherlist_match(scoring->matchers, info))
60                 return scoring->score;
61         else
62                 return 0;
63 }
64
65 gint score_message(GSList * scoring_list, MsgInfo * info)
66 {
67         gint score = 0;
68         gint add_score;
69         GSList * l;
70
71         for(l = scoring_list ; l != NULL ; l = g_slist_next(l)) {
72                 ScoringProp * scoring = (ScoringProp *) l->data;
73                 
74                 add_score = (scoringprop_score_message(scoring, info));
75                 if (add_score == MAX_SCORE || add_score == MIN_SCORE) {
76                         score = add_score;
77                         break;
78                 }
79                 score += add_score;
80         }
81         return score;
82 }
83
84 /*
85   syntax for scoring config
86
87   file ~/.sylpheed/scoringrc
88
89   header "x-mailing" match "toto" score -10
90   subject match "regexp" & to regexp "regexp" score 50
91   subject match "regexp" | to regexpcase "regexp" | age_sup 5 score 30
92
93   if score is = MIN_SCORE (-999), no more match is done in the list
94   if score is = MAX_SCORE (-999), no more match is done in the list
95  */
96
97
98 gchar * scoringprop_to_string(ScoringProp * prop)
99 {
100         gchar * list_str;
101         gchar * score_str;
102         gchar * scoring_str;
103
104         list_str = matcherlist_to_string(prop->matchers);
105
106         if (list_str == NULL)
107                 return NULL;
108
109         score_str = itos(prop->score);
110         scoring_str = g_strconcat(list_str, " score ", score_str, NULL);
111         g_free(list_str);
112
113         return scoring_str;
114 }
115
116 void prefs_scoring_free(GSList * prefs_scoring)
117 {
118         while (prefs_scoring != NULL) {
119                 ScoringProp * scoring = (ScoringProp *) prefs_scoring->data;
120                 scoringprop_free(scoring);
121                 prefs_scoring = g_slist_remove(prefs_scoring, scoring);
122         }
123 }
124
125 static gboolean prefs_scoring_free_func(GNode *node, gpointer data)
126 {
127         FolderItem *item = node->data;
128
129         if(!item->prefs)
130                 return FALSE;
131
132         prefs_scoring_free(item->prefs->scoring);
133         item->prefs->scoring = NULL;
134
135         return FALSE;
136 }
137
138 void prefs_scoring_clear()
139 {
140         GList * cur;
141
142         for (cur = folder_get_list() ; cur != NULL ; cur = g_list_next(cur)) {
143                 Folder *folder;
144
145                 folder = (Folder *) cur->data;
146                 g_node_traverse(folder->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
147                                 prefs_scoring_free_func, NULL);
148         }
149
150         prefs_scoring_free(global_scoring);
151         global_scoring = NULL;
152 }