From 9a9bb39f7641a818434cafa0dae0c8aa47124c0b Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Thu, 21 Jul 2016 21:28:23 +0200 Subject: Incremental fetch of mails --- common/remoteidmap.cpp | 17 +++++++++++++++++ common/remoteidmap.h | 3 +++ examples/imapresource/imapresource.cpp | 14 ++++++++++++-- examples/imapresource/imapserverproxy.cpp | 11 +++++------ examples/imapresource/imapserverproxy.h | 2 +- 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/common/remoteidmap.cpp b/common/remoteidmap.cpp index 20a054d..2c3e5c7 100644 --- a/common/remoteidmap.cpp +++ b/common/remoteidmap.cpp @@ -75,3 +75,20 @@ QByteArray RemoteIdMap::resolveLocalId(const QByteArray &bufferType, const QByte return remoteId; } +QByteArray RemoteIdMap::readValue(const QByteArray &key) +{ + QByteArray value; + mTransaction.openDatabase("values").scan(key, [&value](const QByteArray &, const QByteArray &v) { + value = v; + return false; + }, [](const Sink::Storage::Error &) { + //Ignore errors because we may not find the value + }); + return value; +} + +void RemoteIdMap::writeValue(const QByteArray &key, const QByteArray &value) +{ + mTransaction.openDatabase("values").write(key, value); +} + diff --git a/common/remoteidmap.h b/common/remoteidmap.h index 12891dc..bf08621 100644 --- a/common/remoteidmap.h +++ b/common/remoteidmap.h @@ -54,6 +54,9 @@ public: */ QByteArray resolveLocalId(const QByteArray &bufferType, const QByteArray &localId); + QByteArray readValue(const QByteArray &key); + void writeValue(const QByteArray &key, const QByteArray &value); + private: Sink::Storage::Transaction &mTransaction; }; diff --git a/examples/imapresource/imapresource.cpp b/examples/imapresource/imapresource.cpp index 3ad80f9..e199ea1 100644 --- a/examples/imapresource/imapresource.cpp +++ b/examples/imapresource/imapresource.cpp @@ -233,13 +233,23 @@ public: return KAsync::null(); }) .then>([this, folder, imap]() { - auto uidNext = 0; - return imap->fetchMessages(folder, uidNext, [this, folder](const QVector &messages) { + SinkTrace() << "About to fetch mail"; + const auto uidNext = syncStore().readValue(folder.normalizedPath().toUtf8() + "uidnext").toLongLong(); + auto maxUid = QSharedPointer::create(0); + return imap->fetchMessages(folder, uidNext, [this, folder, maxUid](const QVector &messages) { SinkTrace() << "Got mail"; + for (const auto &m : messages) { + if (*maxUid < m.uid) { + *maxUid = m.uid; + } + } synchronizeMails(folder.normalizedPath(), messages); }, [](int progress, int total) { SinkTrace() << "Progress: " << progress << " out of " << total; + }) + .then([this, maxUid, folder]() { + syncStore().writeValue(folder.normalizedPath().toUtf8() + "uidnext", QByteArray::number(*maxUid)); }); }); diff --git a/examples/imapresource/imapserverproxy.cpp b/examples/imapresource/imapserverproxy.cpp index 5fffb36..a3d8d16 100644 --- a/examples/imapresource/imapserverproxy.cpp +++ b/examples/imapresource/imapserverproxy.cpp @@ -338,15 +338,14 @@ QStringList ImapServerProxy::getCapabilities() const return mCapabilities; } -KAsync::Job> ImapServerProxy::fetchHeaders(const QString &mailbox) +KAsync::Job> ImapServerProxy::fetchHeaders(const QString &mailbox, const qint64 minUid) { auto list = QSharedPointer>::create(); KIMAP::FetchJob::FetchScope scope; - scope.parts.clear(); scope.mode = KIMAP::FetchJob::FetchScope::Flags; //Fetch headers of all messages - return fetch(KIMAP::ImapSet(1, 0), scope, + return fetch(KIMAP::ImapSet(minUid, 0), scope, [list](const QString &mailbox, const QMap &uids, const QMap &sizes, @@ -459,18 +458,18 @@ QString ImapServerProxy::mailboxFromFolder(const Folder &folder) const KAsync::Job ImapServerProxy::fetchMessages(const Folder &folder, qint64 uidNext, std::function &)> callback, std::function progress) { - Q_UNUSED(uidNext); auto time = QSharedPointer::create(); time->start(); Q_ASSERT(!mPersonalNamespaceSeparator.isNull()); return select(mailboxFromFolder(folder)).then, SelectResult>([this, callback, folder, time, progress, uidNext](const SelectResult &selectResult) -> KAsync::Job { - if (selectResult.uidNext == uidNext) { + SinkLog() << "UIDNEXT " << selectResult.uidNext << uidNext; + if (selectResult.uidNext == (uidNext + 1)) { SinkTrace() << "Uidnext didn't change, nothing to do."; return KAsync::null(); } - return fetchHeaders(mailboxFromFolder(folder)).then, QList>([this, callback, time, progress](const QList &uidsToFetch){ + return fetchHeaders(mailboxFromFolder(folder), (uidNext + 1)).then, QList>([this, callback, time, progress](const QList &uidsToFetch){ SinkTrace() << "Fetched headers"; SinkTrace() << " Total: " << uidsToFetch.size(); SinkTrace() << " Uids to fetch: " << uidsToFetch; diff --git a/examples/imapresource/imapserverproxy.h b/examples/imapresource/imapserverproxy.h index 9baa52c..deebc3b 100644 --- a/examples/imapresource/imapserverproxy.h +++ b/examples/imapresource/imapserverproxy.h @@ -125,7 +125,7 @@ public: QStringList getCapabilities() const; //Composed calls that do login etc. - KAsync::Job> fetchHeaders(const QString &mailbox); + KAsync::Job> fetchHeaders(const QString &mailbox, qint64 minUid = 1); KAsync::Job remove(const QString &mailbox, const KIMAP::ImapSet &set); KAsync::Job remove(const QString &mailbox, const QByteArray &imapSet); KAsync::Job move(const QString &mailbox, const KIMAP::ImapSet &set, const QString &newMailbox); -- cgit v1.2.3