1 /*
2 SPDX-FileCopyrightText: 2015-2021 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "searchrulenumerical.h"
8
9 #include "filter/filterlog.h"
10 using MailCommon::FilterLog;
11
12 #include <KMime/KMimeMessage>
13 #include <QDateTime>
14
15 #include <QRegularExpression>
16
17 #include <algorithm>
18
19 using namespace MailCommon;
20
SearchRuleNumerical(const QByteArray & field,Function func,const QString & contents)21 SearchRuleNumerical::SearchRuleNumerical(const QByteArray &field, Function func, const QString &contents)
22 : SearchRule(field, func, contents)
23 {
24 }
25
isEmpty() const26 bool SearchRuleNumerical::isEmpty() const
27 {
28 bool ok = false;
29 contents().toLongLong(&ok);
30
31 return !ok;
32 }
33
matches(const Akonadi::Item & item) const34 bool SearchRuleNumerical::matches(const Akonadi::Item &item) const
35 {
36 if (!item.hasPayload<KMime::Message::Ptr>()) {
37 return false;
38 }
39
40 const auto msg = item.payload<KMime::Message::Ptr>();
41
42 QString msgContents;
43 qint64 numericalMsgContents = 0;
44 qint64 numericalValue = 0;
45
46 if (qstricmp(field().constData(), "<size>") == 0) {
47 numericalMsgContents = item.size();
48 numericalValue = contents().toLongLong();
49 msgContents.setNum(numericalMsgContents);
50 } else if (qstricmp(field().constData(), "<age in days>") == 0) {
51 QDateTime msgDateTime = msg->date()->dateTime();
52 numericalMsgContents = msgDateTime.daysTo(QDateTime::currentDateTime());
53 numericalValue = contents().toInt();
54 msgContents.setNum(numericalMsgContents);
55 } else {
56 return false;
57 }
58 bool rc = matchesInternal(numericalValue, numericalMsgContents, msgContents);
59 if (FilterLog::instance()->isLogging()) {
60 QString msg = (rc ? QStringLiteral("<font color=#00FF00>1 = </font>") : QStringLiteral("<font color=#FF0000>0 = </font>"));
61 msg += FilterLog::recode(asString());
62 msg += QLatin1String(" ( <i>") + QString::number(numericalMsgContents) + QLatin1String("</i> )");
63 FilterLog::instance()->add(msg, FilterLog::RuleResult);
64 }
65 return rc;
66 }
67
requiredPart() const68 SearchRule::RequiredPart SearchRuleNumerical::requiredPart() const
69 {
70 return SearchRule::Envelope;
71 }
72
matchesInternal(long numericalValue,long numericalMsgContents,const QString & msgContents) const73 bool SearchRuleNumerical::matchesInternal(long numericalValue, long numericalMsgContents, const QString &msgContents) const
74 {
75 switch (function()) {
76 case SearchRule::FuncEquals:
77 return numericalValue == numericalMsgContents;
78
79 case SearchRule::FuncNotEqual:
80 return numericalValue != numericalMsgContents;
81
82 case SearchRule::FuncContains:
83 return msgContents.contains(contents(), Qt::CaseInsensitive);
84
85 case SearchRule::FuncContainsNot:
86 return !msgContents.contains(contents(), Qt::CaseInsensitive);
87
88 case SearchRule::FuncRegExp:
89 return msgContents.contains(QRegularExpression(contents(), QRegularExpression::CaseInsensitiveOption));
90
91 case SearchRule::FuncNotRegExp:
92 return !msgContents.contains(QRegularExpression(contents(), QRegularExpression::CaseInsensitiveOption));
93
94 case FuncIsGreater:
95 return numericalMsgContents > numericalValue;
96
97 case FuncIsLessOrEqual:
98 return numericalMsgContents <= numericalValue;
99
100 case FuncIsLess:
101 return numericalMsgContents < numericalValue;
102
103 case FuncIsGreaterOrEqual:
104 return numericalMsgContents >= numericalValue;
105
106 case FuncIsInAddressbook: // since email-addresses are not numerical, I settle for false here
107 return false;
108
109 case FuncIsNotInAddressbook:
110 return false;
111
112 default:;
113 }
114
115 return false;
116 }
117
addQueryTerms(Akonadi::SearchTerm & groupTerm,bool & emptyIsNotAnError) const118 void SearchRuleNumerical::addQueryTerms(Akonadi::SearchTerm &groupTerm, bool &emptyIsNotAnError) const
119 {
120 using namespace Akonadi;
121 emptyIsNotAnError = false;
122 if (qstricmp(field().constData(), "<size>") == 0) {
123 EmailSearchTerm term(EmailSearchTerm::ByteSize, contents().toInt(), akonadiComparator());
124 term.setIsNegated(isNegated());
125 groupTerm.addSubTerm(term);
126 } else if (qstricmp(field().constData(), "<age in days>") == 0) {
127 QDate date(QDate::currentDate());
128 date = date.addDays(contents().toInt());
129 EmailSearchTerm term(EmailSearchTerm::HeaderOnlyDate, date, akonadiComparator());
130 term.setIsNegated(isNegated());
131 groupTerm.addSubTerm(term);
132 }
133 }
134
informationAboutNotValidRules() const135 QString SearchRuleNumerical::informationAboutNotValidRules() const
136 {
137 return i18n("Content is not a number.");
138 }
139