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