1 /* -*- mode: C++; c-file-style: "gnu" -*-
4 This file is part of KMail, the KDE mail client.
5 Copyright (c) 2004 Patrick Audley <paudley@blackcat.ca>
6 Copyright (c) 2004 Ingo Kloecker <kloecker@kde.org>
8 KMail is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 KMail is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 In addition, as a special exception, the copyright holders give
23 permission to link the code of this program with any edition of
24 the Qt library by Trolltech AS, Norway (or with modified versions
25 of Qt that use the same license as Qt), and distribute linked
26 combinations including the two. You must obey the GNU General
27 Public License in all respects for all of the code used other than
28 Qt. If you modify this file, you may extend this exception to
29 your version of the file, but you are not obligated to do so. If
30 you do not wish to do so, delete this exception statement from
35 #include <config-messageviewer.h>
37 #include "spamheaderanalyzer.h"
39 #include "antispamconfig.h"
41 #include <kmime/kmime_message.h>
42 #include <kmime/kmime_headers.h>
46 #include <boost/shared_ptr.hpp>
48 using namespace MessageViewer
;
51 SpamScores
SpamHeaderAnalyzer::getSpamScores( KMime::Message
*message
) {
53 const SpamAgents agents
= AntiSpamConfig::instance()->uniqueAgents();
54 SpamAgents::const_iterator
end( agents
.end() );
55 for ( SpamAgents::const_iterator it
= agents
.begin(); it
!= end
; ++it
) {
58 SpamError spamError
= noError
;
61 if ( (*it
).scoreType() == SpamAgentNone
)
64 // Do we have the needed score field for this agent?
65 KMime::Headers::Base
*header
= message
->headerByType( (*it
).header() );
69 const QString mField
= header
->asUnicodeString();
71 if ( mField
.isEmpty() )
75 bool scoreValid
= false;
77 if ( (*it
).scoreType() != SpamAgentBool
) {
78 // Can we extract the score?
79 QRegExp scorePattern
= (*it
).scorePattern();
80 if ( scorePattern
.indexIn( mField
) != -1 ) {
81 scoreString
= scorePattern
.cap( 1 );
88 spamError
= couldNotFindTheScoreField
;
89 kDebug() << "Score could not be extracted from header '"
92 bool floatValid
= false;
93 switch ( (*it
).scoreType() ) {
95 spamError
= errorExtractingAgentString
;
99 if( (*it
).scorePattern().indexIn( mField
) == -1 )
106 score
= scoreString
.toFloat( &floatValid
);
108 spamError
= couldNotConverScoreToFloat
;
109 kDebug() << "Score (" << scoreString
<< ") is no number";
115 case SpamAgentFloatLarge
:
116 score
= scoreString
.toFloat( &floatValid
);
118 spamError
= couldNotConverScoreToFloat
;
119 kDebug() << "Score (" << scoreString
<< ") is no number";
123 case SpamAgentAdjustedFloat
:
124 score
= scoreString
.toFloat( &floatValid
);
126 spamError
= couldNotConverScoreToFloat
;
127 kDebug() << "Score (" << scoreString
<< ") is no number";
131 // Find the threshold value.
132 QString thresholdString
;
133 QRegExp thresholdPattern
= (*it
).thresholdPattern();
134 if ( thresholdPattern
.indexIn( mField
) != -1 ) {
135 thresholdString
= thresholdPattern
.cap( 1 );
138 spamError
= couldNotFindTheThresholdField
;
139 kDebug() << "Threshold could not be extracted from header '"
143 float threshold
= thresholdString
.toFloat( &floatValid
);
144 if ( !floatValid
|| ( threshold
<= 0.0 ) ) {
145 spamError
= couldNotConvertThresholdToFloatOrThresholdIsNegative
;
146 kDebug() << "Threshold (" << thresholdString
<< ") is no"
147 << "number or is negative";
151 // Normalize the score. Anything below 0 means 0%, anything above
152 // threshold mean 100%. Values between 0 and threshold are mapped
153 // linearily to 0% - 100%.
156 else if ( score
> threshold
)
159 score
= score
/ threshold
* 100.0;
163 //Find the confidence
164 float confidence
= -2.0;
165 QString confidenceString
= "-2.0";
166 bool confidenceValid
= false;
167 // Do we have the needed confidence field for this agent?
168 QByteArray confidenceHeaderName
= (*it
).confidenceHeader();
170 if( !confidenceHeaderName
.isEmpty() )
172 KMime::Headers::Base
*cHeader
= message
->headerByType( confidenceHeaderName
);
175 mCField
= cHeader
->asUnicodeString();
176 if ( ! mCField
.isEmpty() ) {
177 // Can we extract the confidence?
178 QRegExp cScorePattern
= (*it
).confidencePattern();
179 if ( cScorePattern
.indexIn( mCField
) != -1 ) {
180 confidenceString
= cScorePattern
.cap( 1 );
182 confidence
= confidenceString
.toFloat( &confidenceValid
);
183 if( !confidenceValid
) {
184 spamError
= couldNotConvertConfidenceToFloat
;
185 kDebug() << "Unable to convert confidence to float:" << confidenceString
;
190 scores
.append( SpamScore( (*it
).name(), spamError
, score
, confidence
*100, mField
, mCField
) );