7#include "filterimporterthunderbird.h"
8#include "filter/mailfilter.h"
9#include "mailcommon_debug.h"
10#include <MailImporter/FilterIcedove>
11#include <MailImporter/FilterSeaMonkey>
12#include <MailImporter/FilterThunderbird>
19FilterImporterThunderbird::FilterImporterThunderbird(
QFile *file,
bool interactive)
20 : FilterImporterAbstract(interactive)
26FilterImporterThunderbird::FilterImporterThunderbird(
QString string,
bool interactive)
27 : FilterImporterAbstract(interactive)
33FilterImporterThunderbird::~FilterImporterThunderbird() =
default;
35void FilterImporterThunderbird::readStream(
QTextStream &stream)
37 MailFilter *
filter =
nullptr;
38 while (!stream.
atEnd()) {
40 qCDebug(MAILCOMMON_LOG) <<
" line :" << line <<
" filter " <<
filter;
41 filter = parseLine(stream, line, filter);
47QString FilterImporterThunderbird::defaultSeaMonkeyFiltersSettingsPath()
49 return MailImporter::FilterSeaMonkey::defaultSettingsPath();
52QString FilterImporterThunderbird::defaultIcedoveFiltersSettingsPath()
54 return MailImporter::FilterIcedove::defaultSettingsPath();
57QString FilterImporterThunderbird::defaultThunderbirdFiltersSettingsPath()
59 return MailImporter::FilterThunderbird::defaultSettingsPath();
62MailCommon::MailFilter *FilterImporterThunderbird::parseLine(QTextStream &stream, QString line, MailCommon::MailFilter *filter)
64 if (line.
startsWith(QLatin1StringView(
"name="))) {
67 line = cleanArgument(line, QStringLiteral(
"name="));
68 filter->pattern()->setName(line);
69 filter->setToolbarName(line);
70 }
else if (line.
startsWith(QLatin1StringView(
"action="))) {
71 line = cleanArgument(line, QStringLiteral(
"action="));
73 QString actionName = extractActions(line, filter, value);
74 if (!stream.
atEnd()) {
76 if (line.
startsWith(QLatin1StringView(
"actionValue="))) {
77 value = cleanArgument(line, QStringLiteral(
"actionValue="));
79 if (actionName == QLatin1StringView(
"Change priority")) {
81 lstValue << QStringLiteral(
"X-Priority");
82 if (value == QLatin1StringView(
"Highest")) {
83 value = QStringLiteral(
"1 (Highest)");
84 }
else if (value == QLatin1StringView(
"High")) {
85 value = QStringLiteral(
"2 (High)");
86 }
else if (value == QLatin1StringView(
"Normal")) {
87 value = QStringLiteral(
"3 (Normal)");
88 }
else if (value == QLatin1StringView(
"Low")) {
89 value = QStringLiteral(
"4 (Low)");
90 }
else if (value == QLatin1StringView(
"Lowest")) {
91 value = QStringLiteral(
"5 (Lowest)");
94 value = lstValue.
join(QLatin1Char(
'\t'));
95 actionName = QStringLiteral(
"add header");
96 }
else if (actionName == QLatin1StringView(
"copy") || actionName == QLatin1StringView(
"transfer")) {
106 createFilterAction(filter, actionName, value);
108 createFilterAction(filter, actionName, value);
109 filter = parseLine(stream, line, filter);
112 createFilterAction(filter, actionName, value);
114 }
else if (line.
startsWith(QLatin1StringView(
"enabled="))) {
115 line = cleanArgument(line, QStringLiteral(
"enabled="));
116 if (line == QLatin1StringView(
"no")) {
117 filter->setEnabled(
false);
119 }
else if (line.
startsWith(QLatin1StringView(
"condition="))) {
120 line = cleanArgument(line, QStringLiteral(
"condition="));
121 extractConditions(line, filter);
122 }
else if (line.
startsWith(QLatin1StringView(
"type="))) {
123 line = cleanArgument(line, QStringLiteral(
"type="));
124 extractType(line, filter);
125 }
else if (line.
startsWith(QLatin1StringView(
"version="))) {
126 line = cleanArgument(line, QStringLiteral(
"version="));
127 if (line.
toInt() != 9) {
128 qCDebug(MAILCOMMON_LOG) <<
" thunderbird filter version different of 9 need to look at if it changed";
130 }
else if (line.
startsWith(QLatin1StringView(
"logging="))) {
131 line = cleanArgument(line, QStringLiteral(
"logging="));
132 if (line == QLatin1StringView(
"no")) {
134 }
else if (line == QLatin1StringView(
"yes")) {
137 qCDebug(MAILCOMMON_LOG) <<
" Logging option not implemented " << line;
140 qCDebug(MAILCOMMON_LOG) <<
"unknown tag : " << line;
145void FilterImporterThunderbird::extractConditions(
const QString &line, MailCommon::MailFilter *filter)
147 if (line.
startsWith(QLatin1StringView(
"AND"))) {
148 filter->pattern()->setOp(SearchPattern::OpAnd);
149 const QStringList conditionsList = line.
split(QStringLiteral(
"AND "));
150 const int numberOfCond(conditionsList.
count());
151 for (
int i = 0; i < numberOfCond; ++i) {
152 if (!conditionsList.
at(i).trimmed().isEmpty()) {
153 splitConditions(conditionsList.
at(i), filter);
156 }
else if (line.
startsWith(QLatin1StringView(
"OR"))) {
157 filter->pattern()->setOp(SearchPattern::OpOr);
158 const QStringList conditionsList = line.
split(QStringLiteral(
"OR "));
159 const int numberOfCond(conditionsList.
count());
160 for (
int i = 0; i < numberOfCond; ++i) {
161 if (!conditionsList.
at(i).trimmed().isEmpty()) {
162 splitConditions(conditionsList.
at(i), filter);
165 }
else if (line.
startsWith(QLatin1StringView(
"ALL"))) {
166 filter->pattern()->setOp(SearchPattern::OpAll);
168 qCDebug(MAILCOMMON_LOG) <<
" missing extract condition" << line;
172bool FilterImporterThunderbird::splitConditions(
const QString &cond, MailCommon::MailFilter *filter)
202 str.
remove(QLatin1Char(
'('));
205 const QStringList listOfCond = str.
split(QLatin1Char(
','));
206 if (listOfCond.
count() < 3) {
207 qCDebug(MAILCOMMON_LOG) <<
"We have a pb in cond:" << cond;
210 const QString field = listOfCond.
at(0);
211 const QString function = listOfCond.
at(1);
212 const QString contents = listOfCond.
at(2);
214 QByteArray fieldName;
215 if (field == QLatin1StringView(
"subject")) {
216 fieldName =
"subject";
217 }
else if (field == QLatin1StringView(
"from")) {
219 }
else if (field == QLatin1StringView(
"body")) {
220 fieldName =
"<body>";
221 }
else if (field == QLatin1StringView(
"date")) {
222 fieldName =
"<date>";
223 }
else if (field == QLatin1StringView(
"priority")) {
225 }
else if (field == QLatin1StringView(
"status")) {
226 fieldName =
"<status>";
227 }
else if (field == QLatin1StringView(
"to")) {
229 }
else if (field == QLatin1StringView(
"cc")) {
231 }
else if (field == QLatin1StringView(
"to or cc")) {
232 fieldName =
"<recipients>";
233 }
else if (field == QLatin1StringView(
"all addresses")) {
234 fieldName =
"<recipients>";
235 }
else if (field == QLatin1StringView(
"age in days")) {
236 fieldName =
"<age in days>";
237 }
else if (field == QLatin1StringView(
"label")) {
239 }
else if (field == QLatin1StringView(
"tag")) {
241 }
else if (field == QLatin1StringView(
"size")) {
242 fieldName =
"<size>";
243 }
else if (field == QLatin1StringView(
"from in ab")) {
245 }
else if (field == QLatin1StringView(
"junk status")) {
247 }
else if (field == QLatin1StringView(
"junk percent")) {
249 }
else if (field == QLatin1StringView(
"junk score origin")) {
251 }
else if (field == QLatin1StringView(
"has attachment status")) {
256 qCDebug(MAILCOMMON_LOG) <<
" Field not implemented: " << field;
280 if (function == QLatin1StringView(
"contains")) {
281 functionName = SearchRule::FuncContains;
282 }
else if (function == QLatin1StringView(
"doesn't contain")) {
283 functionName = SearchRule::FuncContainsNot;
284 }
else if (function == QLatin1StringView(
"is")) {
285 functionName = SearchRule::FuncEquals;
286 }
else if (function == QLatin1StringView(
"isn't")) {
287 functionName = SearchRule::FuncNotEqual;
288 }
else if (function == QLatin1StringView(
"is empty")) {
290 }
else if (function == QLatin1StringView(
"isn't empty")) {
292 }
else if (function == QLatin1StringView(
"is before")) {
293 functionName = SearchRule::FuncIsLess;
294 }
else if (function == QLatin1StringView(
"is after")) {
295 functionName = SearchRule::FuncIsGreater;
296 }
else if (function == QLatin1StringView(
"is higher than")) {
297 functionName = SearchRule::FuncIsGreater;
298 }
else if (function == QLatin1StringView(
"is lower than")) {
299 functionName = SearchRule::FuncIsLess;
300 }
else if (function == QLatin1StringView(
"begins with")) {
301 functionName = SearchRule::FuncStartWith;
302 }
else if (function == QLatin1StringView(
"ends with")) {
303 functionName = SearchRule::FuncEndWith;
304 }
else if (function == QLatin1StringView(
"is in ab")) {
305 functionName = SearchRule::FuncIsInAddressbook;
306 }
else if (function == QLatin1StringView(
"isn't in ab")) {
307 functionName = SearchRule::FuncIsNotInAddressbook;
308 }
else if (function == QLatin1StringView(
"is greater than")) {
309 functionName = SearchRule::FuncIsGreater;
310 }
else if (function == QLatin1StringView(
"is less than")) {
311 functionName = SearchRule::FuncIsLess;
312 }
else if (function == QLatin1StringView(
"matches")) {
313 functionName = SearchRule::FuncEquals;
314 }
else if (function == QLatin1StringView(
"doesn't match")) {
315 functionName = SearchRule::FuncNotEqual;
318 if (functionName == SearchRule::FuncNone) {
319 qCDebug(MAILCOMMON_LOG) <<
" functionName not implemented: " << function;
321 QString contentsName;
322 if (fieldName ==
"<status>") {
323 if (contents == QLatin1StringView(
"read")) {
324 contentsName = QStringLiteral(
"Read");
325 }
else if (contents == QLatin1StringView(
"unread")) {
326 contentsName = QStringLiteral(
"Unread");
327 }
else if (contents == QLatin1StringView(
"new")) {
328 contentsName = QStringLiteral(
"New");
329 }
else if (contents == QLatin1StringView(
"forwarded")) {
330 contentsName = QStringLiteral(
"Forwarded");
332 qCDebug(MAILCOMMON_LOG) <<
" contents for status not implemented " << contents;
334 }
else if (fieldName ==
"<size>") {
335 int value = contents.
toInt();
336 value = value * 1024;
338 }
else if (fieldName ==
"<date>") {
340 const QDate date = locale.toDate(contents, QStringLiteral(
"dd-MMM-yyyy"));
343 contentsName = contents;
347 filter->pattern()->append(rule);
353QString FilterImporterThunderbird::extractActions(
const QString &line, MailCommon::MailFilter *filter, QString &value)
378 if (line == QLatin1StringView(
"Move to folder")) {
379 actionName = QStringLiteral(
"transfer");
380 }
else if (line == QLatin1StringView(
"Forward")) {
381 actionName = QStringLiteral(
"forward");
382 }
else if (line == QLatin1StringView(
"Mark read")) {
383 actionName = QStringLiteral(
"set status");
384 value = QStringLiteral(
"R");
385 }
else if (line == QLatin1StringView(
"Mark unread")) {
386 actionName = QStringLiteral(
"set status");
387 value = QStringLiteral(
"U");
388 }
else if (line == QLatin1StringView(
"Copy to folder")) {
389 actionName = QStringLiteral(
"copy");
390 }
else if (line == QLatin1StringView(
"AddTag")) {
391 actionName = QStringLiteral(
"add tag");
392 }
else if (line == QLatin1StringView(
"Delete")) {
393 actionName = QStringLiteral(
"delete");
394 }
else if (line == QLatin1StringView(
"Change priority")) {
395 actionName = QStringLiteral(
"Change priority");
396 }
else if (line == QLatin1StringView(
"Ignore thread")) {
397 }
else if (line == QLatin1StringView(
"Ignore subthread")) {
398 }
else if (line == QLatin1StringView(
"Watch thread")) {
399 }
else if (line == QLatin1StringView(
"Mark flagged")) {
400 }
else if (line == QLatin1StringView(
"Label")) {
401 }
else if (line == QLatin1StringView(
"Reply")) {
402 actionName = QStringLiteral(
"set Reply-To");
403 }
else if (line == QLatin1StringView(
"Stop execution")) {
404 filter->setStopProcessingHere(
true);
406 }
else if (line == QLatin1StringView(
"Delete from Pop3 server")) {
407 }
else if (line == QLatin1StringView(
"JunkScore")) {
408 }
else if (line == QLatin1StringView(
"Fetch body from Pop3Server")) {
409 }
else if (line == QLatin1StringView(
"Custom")) {
412 qCDebug(MAILCOMMON_LOG) << QStringLiteral(
" missing convert method: %1").arg(line);
417void FilterImporterThunderbird::extractType(
const QString &line, MailCommon::MailFilter *filter)
419 const int value = line.
toInt();
421 filter->setApplyOnInbound(
true);
422 filter->setApplyOnExplicit(
false);
424 }
else if (value == 16) {
425 filter->setApplyOnInbound(
false);
426 filter->setApplyOnExplicit(
true);
428 }
else if (value == 17) {
429 filter->setApplyOnInbound(
true);
430 filter->setApplyOnExplicit(
true);
432 }
else if (value == 32) {
433 filter->setApplyOnExplicit(
false);
434 filter->setApplyOnOutbound(
true);
435 filter->setApplyOnInbound(
false);
437 }
else if (value == 48) {
438 filter->setApplyOnExplicit(
true);
439 filter->setApplyOnOutbound(
true);
440 filter->setApplyOnInbound(
false);
443 qCDebug(MAILCOMMON_LOG) <<
" type value is not valid :" << value;
447QString FilterImporterThunderbird::cleanArgument(
const QString &line,
const QString &removeStr)
451 str.
remove(QStringLiteral(
"\""));
std::shared_ptr< SearchRule > Ptr
Defines a pointer to a search rule.
Function
Describes operators for comparison of field and contents.
static SearchRule::Ptr createInstance(const QByteArray &field=QByteArray(), Function function=FuncContains, const QString &contents=QString())
Creates a new search rule of a certain type by instantiating the appropriate subclass depending on th...
QString path(const QString &relativePath)
bool isEmpty() const const
QString toString(QStringView format, QCalendar cal) const const
const_reference at(qsizetype i) const const
qsizetype count() const const
bool isEmpty() const const
qsizetype length() const const
QString number(double n, char format, int precision)
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
int toInt(bool *ok, int base) const const
QString trimmed() const const
QString join(QChar separator) const const
QFuture< void > filter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&filterFunction)
QString readLine(qint64 maxlen)
QUrl fromLocalFile(const QString &localFile)
bool isValid() const const
QString path(ComponentFormattingOptions options) const const