diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-26 16:22:49 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-26 16:22:49 +0200 |
| commit | 496e174e65c06563aff426bdbbeeba006102e89d (patch) | |
| tree | c43c434598fbfca36055a1cd7487fecb1dffce5f /src/notmuchworker.cpp | |
| parent | 409faeadf013952420963fa1b740d44526d8a95e (diff) | |
| download | qtmaildir-496e174e65c06563aff426bdbbeeba006102e89d.tar.gz qtmaildir-496e174e65c06563aff426bdbbeeba006102e89d.zip | |
feat: propose business senders from newly synced mail
Diffstat (limited to 'src/notmuchworker.cpp')
| -rw-r--r-- | src/notmuchworker.cpp | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/notmuchworker.cpp b/src/notmuchworker.cpp index 28834df..3de79e1 100644 --- a/src/notmuchworker.cpp +++ b/src/notmuchworker.cpp @@ -321,10 +321,19 @@ QString folderOfMessageFile(const QString &root, const QString &filePath) static const int kSortOrderMetaType = qRegisterMetaType<NotmuchWorker::SortOrder>("NotmuchWorker::SortOrder"); +/// The same registration for the sender-count map. The QHash crosses the +/// queued senderCountsReady connection from the worker thread to the UI, and +/// an unregistered type is dropped there with a warning, exactly like +/// SortOrder above. Registered with the name invokeMethod/moc resolve, so a +/// caller that never builds a worker still gets the type. +static const int kSenderCountsMetaType = + qRegisterMetaType<QHash<QString, int>>("QHash<QString,int>"); + NotmuchWorker::NotmuchWorker(const QString ¬muchConfigPath, QObject *parent) : QObject(parent), m_configPath(notmuchConfigPath) { Q_UNUSED(kSortOrderMetaType); + Q_UNUSED(kSenderCountsMetaType); } NotmuchWorker::~NotmuchWorker() @@ -1381,6 +1390,46 @@ void NotmuchWorker::requestMessageCounts(const QStringList &queries, emit messageCountsReady(counts, generation); } +void NotmuchWorker::countSenders(const QString &query) +{ + if (!openReadOnly()) { + // Answered anyway, with an empty map, so the sync path that asked is + // not left waiting on a signal it can never receive. + emit senderCountsReady({}); + return; + } + + QHash<QString, int> counts; + NmQuery nmQuery(notmuch_query_create(m_db, query.toUtf8().constData())); + if (!nmQuery) { + emit senderCountsReady(counts); + return; + } + + notmuch_messages_t *raw = nullptr; + if (notmuch_query_search_messages(nmQuery.get(), &raw) + != NOTMUCH_STATUS_SUCCESS) { + emit senderCountsReady(counts); + return; + } + + NmMessages messages(raw); + for (; notmuch_messages_valid(messages.get()); + notmuch_messages_move_to_next(messages.get())) { + notmuch_message_t *message = notmuch_messages_get(messages.get()); + if (!message) + continue; + // The BARE address, lower-cased, because that is the key + // BusinessSenders matches on: a display name would defeat the + // bulk-sender guess and a mixed-case key would duplicate one sender. + const QString sender = senderAddressOf(message); + if (!sender.isEmpty()) + counts[sender.toLower()] += 1; + } + + emit senderCountsReady(counts); +} + void NotmuchWorker::requestMailRoot() { if (!openReadOnly()) { |
