Branch data Line data Source code
1 : : #include "SuggestionWorker.h"
2 : :
3 : : #include "data/FolderPredictor.h"
4 : : #include "service/ImapResponseParser.h"
5 : :
6 : 4 : SuggestionWorker::SuggestionWorker(QObject *parent) : QObject(parent) {}
7 : :
8 : 2 : void SuggestionWorker::cancel() { m_cancelled.storeRelaxed(1); }
9 : :
10 : 4 : void SuggestionWorker::process(const QString &dbPath,
11 : : const QList<MailHeader> &headers,
12 : : const QString ¤tFolder,
13 : : const QString &junkFolder) {
14 : 4 : m_cancelled.storeRelaxed(0);
15 : :
16 : : // Open a separate FolderPredictor with its own DB connection
17 [ + - ]: 4 : FolderPredictor predictor;
18 [ + - - + ]: 4 : if (!predictor.open(dbPath)) {
19 [ # # ]: 0 : emit batchFinished();
20 : 0 : return;
21 : : }
22 : :
23 [ + + ]: 12 : for (const auto &h : headers) {
24 [ - + ]: 8 : if (m_cancelled.loadRelaxed())
25 : 0 : break;
26 : :
27 [ + - ]: 8 : auto topN = predictor.predictTop(h.from, h.subject, h.to, 2);
28 [ + - ]: 8 : if (topN.isEmpty())
29 : 8 : continue;
30 : :
31 [ # # ]: 0 : QString folder = topN[0].first;
32 [ # # ]: 0 : double conf = topN[0].second;
33 : :
34 : : // T-231: X-Spam override
35 [ # # # # : 0 : if (h.isSpam && !junkFolder.isEmpty()) {
# # ]
36 [ # # # # : 0 : if (conf < 0.98 || folder == junkFolder) {
# # ]
37 : 0 : folder = junkFolder;
38 : 0 : conf = qMax(conf, 0.95);
39 : : }
40 : : }
41 : :
42 : : // Don't suggest current folder or low confidence
43 [ # # # # : 0 : if (folder == currentFolder || conf < 0.4)
# # ]
44 : 0 : continue;
45 : :
46 : : // Build display text
47 : 0 : int pct = static_cast<int>(conf * 100);
48 : 0 : QString shortName = folder;
49 : 0 : int lastSep = qMax(folder.lastIndexOf(QLatin1Char('.')),
50 : 0 : folder.lastIndexOf(QLatin1Char('/')));
51 [ # # ]: 0 : if (lastSep >= 0)
52 [ # # ]: 0 : shortName = folder.mid(lastSep + 1);
53 : :
54 : : // Decode Modified UTF-7 (IMAP encoding) for proper umlaut display
55 [ # # ]: 0 : shortName = ImapResponseParser::decodeMailboxName(shortName);
56 : :
57 : 0 : QString text;
58 [ # # ]: 0 : if (h.isSpam) {
59 [ # # # # ]: 0 : text = QStringLiteral("🛡 %1 %2%").arg(shortName).arg(pct);
60 : : } else {
61 [ # # # # ]: 0 : text = QStringLiteral("→ %1 %2%").arg(shortName).arg(pct);
62 : : }
63 : :
64 [ # # ]: 0 : if (!m_cancelled.loadRelaxed())
65 [ # # ]: 0 : emit resultReady(h.uid, text, conf);
66 [ - - - + ]: 8 : }
67 : :
68 : : // FolderPredictor destructor closes DB connection cleanly here
69 [ + - ]: 4 : emit batchFinished();
70 [ + - ]: 4 : }
|