diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-07-21 21:28:23 +0200 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-09-15 16:14:19 +0200 |
commit | 9a9bb39f7641a818434cafa0dae0c8aa47124c0b (patch) | |
tree | 3da0b8642fb73f1fe8762291a7b3a8ed171444d6 | |
parent | 07d9eaaa97dfa63bb3ff9767c6b2e152ad8a04e0 (diff) | |
download | sink-9a9bb39f7641a818434cafa0dae0c8aa47124c0b.tar.gz sink-9a9bb39f7641a818434cafa0dae0c8aa47124c0b.zip |
Incremental fetch of mails
-rw-r--r-- | common/remoteidmap.cpp | 17 | ||||
-rw-r--r-- | common/remoteidmap.h | 3 | ||||
-rw-r--r-- | examples/imapresource/imapresource.cpp | 14 | ||||
-rw-r--r-- | examples/imapresource/imapserverproxy.cpp | 11 | ||||
-rw-r--r-- | 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 | |||
75 | return remoteId; | 75 | return remoteId; |
76 | } | 76 | } |
77 | 77 | ||
78 | QByteArray RemoteIdMap::readValue(const QByteArray &key) | ||
79 | { | ||
80 | QByteArray value; | ||
81 | mTransaction.openDatabase("values").scan(key, [&value](const QByteArray &, const QByteArray &v) { | ||
82 | value = v; | ||
83 | return false; | ||
84 | }, [](const Sink::Storage::Error &) { | ||
85 | //Ignore errors because we may not find the value | ||
86 | }); | ||
87 | return value; | ||
88 | } | ||
89 | |||
90 | void RemoteIdMap::writeValue(const QByteArray &key, const QByteArray &value) | ||
91 | { | ||
92 | mTransaction.openDatabase("values").write(key, value); | ||
93 | } | ||
94 | |||
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: | |||
54 | */ | 54 | */ |
55 | QByteArray resolveLocalId(const QByteArray &bufferType, const QByteArray &localId); | 55 | QByteArray resolveLocalId(const QByteArray &bufferType, const QByteArray &localId); |
56 | 56 | ||
57 | QByteArray readValue(const QByteArray &key); | ||
58 | void writeValue(const QByteArray &key, const QByteArray &value); | ||
59 | |||
57 | private: | 60 | private: |
58 | Sink::Storage::Transaction &mTransaction; | 61 | Sink::Storage::Transaction &mTransaction; |
59 | }; | 62 | }; |
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: | |||
233 | return KAsync::null<void>(); | 233 | return KAsync::null<void>(); |
234 | }) | 234 | }) |
235 | .then<void, KAsync::Job<void>>([this, folder, imap]() { | 235 | .then<void, KAsync::Job<void>>([this, folder, imap]() { |
236 | auto uidNext = 0; | 236 | SinkTrace() << "About to fetch mail"; |
237 | return imap->fetchMessages(folder, uidNext, [this, folder](const QVector<Message> &messages) { | 237 | const auto uidNext = syncStore().readValue(folder.normalizedPath().toUtf8() + "uidnext").toLongLong(); |
238 | auto maxUid = QSharedPointer<qint64>::create(0); | ||
239 | return imap->fetchMessages(folder, uidNext, [this, folder, maxUid](const QVector<Message> &messages) { | ||
238 | SinkTrace() << "Got mail"; | 240 | SinkTrace() << "Got mail"; |
241 | for (const auto &m : messages) { | ||
242 | if (*maxUid < m.uid) { | ||
243 | *maxUid = m.uid; | ||
244 | } | ||
245 | } | ||
239 | synchronizeMails(folder.normalizedPath(), messages); | 246 | synchronizeMails(folder.normalizedPath(), messages); |
240 | }, | 247 | }, |
241 | [](int progress, int total) { | 248 | [](int progress, int total) { |
242 | SinkTrace() << "Progress: " << progress << " out of " << total; | 249 | SinkTrace() << "Progress: " << progress << " out of " << total; |
250 | }) | ||
251 | .then<void>([this, maxUid, folder]() { | ||
252 | syncStore().writeValue(folder.normalizedPath().toUtf8() + "uidnext", QByteArray::number(*maxUid)); | ||
243 | }); | 253 | }); |
244 | }); | 254 | }); |
245 | 255 | ||
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 | |||
338 | return mCapabilities; | 338 | return mCapabilities; |
339 | } | 339 | } |
340 | 340 | ||
341 | KAsync::Job<QList<qint64>> ImapServerProxy::fetchHeaders(const QString &mailbox) | 341 | KAsync::Job<QList<qint64>> ImapServerProxy::fetchHeaders(const QString &mailbox, const qint64 minUid) |
342 | { | 342 | { |
343 | auto list = QSharedPointer<QList<qint64>>::create(); | 343 | auto list = QSharedPointer<QList<qint64>>::create(); |
344 | KIMAP::FetchJob::FetchScope scope; | 344 | KIMAP::FetchJob::FetchScope scope; |
345 | scope.parts.clear(); | ||
346 | scope.mode = KIMAP::FetchJob::FetchScope::Flags; | 345 | scope.mode = KIMAP::FetchJob::FetchScope::Flags; |
347 | 346 | ||
348 | //Fetch headers of all messages | 347 | //Fetch headers of all messages |
349 | return fetch(KIMAP::ImapSet(1, 0), scope, | 348 | return fetch(KIMAP::ImapSet(minUid, 0), scope, |
350 | [list](const QString &mailbox, | 349 | [list](const QString &mailbox, |
351 | const QMap<qint64,qint64> &uids, | 350 | const QMap<qint64,qint64> &uids, |
352 | const QMap<qint64,qint64> &sizes, | 351 | const QMap<qint64,qint64> &sizes, |
@@ -459,18 +458,18 @@ QString ImapServerProxy::mailboxFromFolder(const Folder &folder) const | |||
459 | 458 | ||
460 | KAsync::Job<void> ImapServerProxy::fetchMessages(const Folder &folder, qint64 uidNext, std::function<void(const QVector<Message> &)> callback, std::function<void(int, int)> progress) | 459 | KAsync::Job<void> ImapServerProxy::fetchMessages(const Folder &folder, qint64 uidNext, std::function<void(const QVector<Message> &)> callback, std::function<void(int, int)> progress) |
461 | { | 460 | { |
462 | Q_UNUSED(uidNext); | ||
463 | auto time = QSharedPointer<QTime>::create(); | 461 | auto time = QSharedPointer<QTime>::create(); |
464 | time->start(); | 462 | time->start(); |
465 | Q_ASSERT(!mPersonalNamespaceSeparator.isNull()); | 463 | Q_ASSERT(!mPersonalNamespaceSeparator.isNull()); |
466 | return select(mailboxFromFolder(folder)).then<void, KAsync::Job<void>, SelectResult>([this, callback, folder, time, progress, uidNext](const SelectResult &selectResult) -> KAsync::Job<void> { | 464 | return select(mailboxFromFolder(folder)).then<void, KAsync::Job<void>, SelectResult>([this, callback, folder, time, progress, uidNext](const SelectResult &selectResult) -> KAsync::Job<void> { |
467 | 465 | ||
468 | if (selectResult.uidNext == uidNext) { | 466 | SinkLog() << "UIDNEXT " << selectResult.uidNext << uidNext; |
467 | if (selectResult.uidNext == (uidNext + 1)) { | ||
469 | SinkTrace() << "Uidnext didn't change, nothing to do."; | 468 | SinkTrace() << "Uidnext didn't change, nothing to do."; |
470 | return KAsync::null<void>(); | 469 | return KAsync::null<void>(); |
471 | } | 470 | } |
472 | 471 | ||
473 | return fetchHeaders(mailboxFromFolder(folder)).then<void, KAsync::Job<void>, QList<qint64>>([this, callback, time, progress](const QList<qint64> &uidsToFetch){ | 472 | return fetchHeaders(mailboxFromFolder(folder), (uidNext + 1)).then<void, KAsync::Job<void>, QList<qint64>>([this, callback, time, progress](const QList<qint64> &uidsToFetch){ |
474 | SinkTrace() << "Fetched headers"; | 473 | SinkTrace() << "Fetched headers"; |
475 | SinkTrace() << " Total: " << uidsToFetch.size(); | 474 | SinkTrace() << " Total: " << uidsToFetch.size(); |
476 | SinkTrace() << " Uids to fetch: " << uidsToFetch; | 475 | 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: | |||
125 | QStringList getCapabilities() const; | 125 | QStringList getCapabilities() const; |
126 | 126 | ||
127 | //Composed calls that do login etc. | 127 | //Composed calls that do login etc. |
128 | KAsync::Job<QList<qint64>> fetchHeaders(const QString &mailbox); | 128 | KAsync::Job<QList<qint64>> fetchHeaders(const QString &mailbox, qint64 minUid = 1); |
129 | KAsync::Job<void> remove(const QString &mailbox, const KIMAP::ImapSet &set); | 129 | KAsync::Job<void> remove(const QString &mailbox, const KIMAP::ImapSet &set); |
130 | KAsync::Job<void> remove(const QString &mailbox, const QByteArray &imapSet); | 130 | KAsync::Job<void> remove(const QString &mailbox, const QByteArray &imapSet); |
131 | KAsync::Job<void> move(const QString &mailbox, const KIMAP::ImapSet &set, const QString &newMailbox); | 131 | KAsync::Job<void> move(const QString &mailbox, const KIMAP::ImapSet &set, const QString &newMailbox); |