7e7cdde08d592d15e005d64c972eb8da8f5031d7
[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 "intl.h"
7 #include "utils.h"
8 #include "defs.h"
9 #include "procheader.h"
10 #include "matcher.h"
11 #include "scoring.h"
12
13 #define PREFSBUFSIZE            1024
14
15 GSList * prefs_scoring = NULL;
16
17 ScoringProp * scoringprop_parse(gchar ** str)
18 {
19         gchar * tmp;
20         gchar * save;
21         gint key;
22         ScoringProp * scoring;
23         gint score;
24         MatcherList * matchers;
25
26         tmp = * str;
27
28         matchers = matcherlist_parse(&tmp);
29         if (tmp == NULL) {
30                 * str = NULL;
31                 return NULL;
32         }
33
34         key = matcher_parse_keyword(&tmp);
35
36         if (tmp == NULL) {
37                 matcherlist_free(matchers);
38                 * str = NULL;
39                 return NULL;
40         }
41
42         if (key != SCORING_SCORE) {
43                 matcherlist_free(matchers);
44                 * str = NULL;
45                 return NULL;
46         }
47
48         score = matcher_parse_number(&tmp);
49
50         if (tmp == NULL) {
51                 matcherlist_free(matchers);
52                 * str = NULL;
53                 return NULL;
54         }
55
56         scoring = scoringprop_new(matchers, score);
57
58         * str = tmp;
59         return scoring;
60 }
61
62
63 ScoringProp * scoringprop_new(MatcherList * matchers, int score)
64 {
65         ScoringProp * scoring;
66
67         scoring = g_new0(ScoringProp, 1);
68         scoring->matchers = matchers;
69         scoring->score = score;
70
71         return scoring;
72 }
73
74 void scoringprop_free(ScoringProp * prop)
75 {
76         matcherlist_free(prop->matchers);
77         g_free(prop);
78 }
79
80 gint scoringprop_score_message(ScoringProp * scoring, MsgInfo * info)
81 {
82         if (matcherlist_match(scoring->matchers, info))
83                 return scoring->score;
84         else
85                 return 0;
86 }
87
88 gint score_message(GSList * scoring_list, MsgInfo * info)
89 {
90         gint score = 0;
91         gint add_score;
92         GSList * l;
93
94         for(l = scoring_list ; l != NULL ; l = g_slist_next(l)) {
95                 ScoringProp * scoring = (ScoringProp *) l->data;
96                 
97                 add_score = (scoringprop_score_message(scoring, info));
98                 if (add_score == MAX_SCORE || add_score == MIN_SCORE) {
99                         score = add_score;
100                         break;
101                 }
102                 score += add_score;
103         }
104         return score;
105 }
106
107 #ifdef 0
108 static void scoringprop_print(ScoringProp * prop)
109 {
110         GSList * l;
111
112         if (prop == NULL) {
113                 printf("no scoring\n");
114                 return;
115         }
116
117         printf("----- scoring ------\n");
118         for(l = prop->matchers ; l != NULL ; l = g_slist_next(l)) {
119                 matcherprop_print((MatcherProp *) l->data);
120         }
121         printf("cond: %s\n", prop->bool_and ? "and" : "or");
122         printf("score: %i\n", prop->score);
123 }
124 #endif
125
126 /*
127   syntax for scoring config
128
129   file ~/.sylpheed/scoringrc
130
131   header "x-mailing" match "toto" score -10
132   subject match "regexp" & to regexp "regexp" score 50
133   subject match "regexp" | to regexpcase "regexp" | age_sup 5 score 30
134
135   if score is = MIN_SCORE (-999), no more match is done in the list
136   if score is = MAX_SCORE (-999), no more match is done in the list
137  */
138
139 void prefs_scoring_read_config(void)
140 {
141         gchar *rcpath;
142         FILE *fp;
143         gchar buf[PREFSBUFSIZE];
144
145         debug_print(_("Reading headers configuration...\n"));
146
147         rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, SCORING_RC, NULL);
148         if ((fp = fopen(rcpath, "r")) == NULL) {
149                 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
150                 g_free(rcpath);
151                 prefs_scoring = NULL;
152                 return;
153         }
154         g_free(rcpath);
155
156         /* remove all scoring */
157         while (prefs_scoring != NULL) {
158                 ScoringProp * scoring = (ScoringProp *) prefs_scoring->data;
159                 scoringprop_free(scoring);
160                 prefs_scoring = g_slist_remove(prefs_scoring, scoring);
161         }
162
163         while (fgets(buf, sizeof(buf), fp) != NULL) {
164                 ScoringProp * scoring;
165                 gchar * tmp;
166
167                 g_strchomp(buf);
168
169                 if ((*buf != '#') && (*buf != '\0')) {
170                         tmp = buf;
171                         scoring = scoringprop_parse(&tmp);
172                         if (tmp != NULL) {
173                                 prefs_scoring = g_slist_append(prefs_scoring,
174                                                                scoring);
175                         }
176                         else {
177                                 // debug
178                                 g_warning(_("syntax error : %s\n"), buf);
179                         }
180                 }
181         }
182
183         fclose(fp);
184 }