summaryrefslogtreecommitdiffstats
path: root/examples/imapresource/imapresource.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'examples/imapresource/imapresource.cpp')
-rw-r--r--examples/imapresource/imapresource.cpp44
1 files changed, 27 insertions, 17 deletions
diff --git a/examples/imapresource/imapresource.cpp b/examples/imapresource/imapresource.cpp
index f87c5ff..811e560 100644
--- a/examples/imapresource/imapresource.cpp
+++ b/examples/imapresource/imapresource.cpp
@@ -267,13 +267,13 @@ public:
267 }) 267 })
268 // //First we fetch flag changes for all messages. Since we don't know which messages are locally available we just get everything and only apply to what we have. 268 // //First we fetch flag changes for all messages. Since we don't know which messages are locally available we just get everything and only apply to what we have.
269 .then([=] { 269 .then([=] {
270 auto uidNext = syncStore().readValue(folderRemoteId, "uidnext").toLongLong(); 270 auto lastSeenUid = syncStore().readValue(folderRemoteId, "uidnext").toLongLong();
271 bool ok = false; 271 bool ok = false;
272 const auto changedsince = syncStore().readValue(folderRemoteId, "changedsince").toLongLong(&ok); 272 const auto changedsince = syncStore().readValue(folderRemoteId, "changedsince").toLongLong(&ok);
273 SinkLogCtx(mLogCtx) << "About to update flags" << folder.path() << "changedsince: " << changedsince; 273 SinkLogCtx(mLogCtx) << "About to update flags" << folder.path() << "changedsince: " << changedsince;
274 //If we have any mails so far we start off by updating any changed flags using changedsince 274 //If we have any mails so far we start off by updating any changed flags using changedsince
275 if (ok) { 275 if (ok) {
276 return imap->fetchFlags(folder, KIMAP2::ImapSet(1, qMax(uidNext, qint64(1))), changedsince, [=](const Message &message) { 276 return imap->fetchFlags(folder, KIMAP2::ImapSet(1, qMax(lastSeenUid, qint64(1))), changedsince, [=](const Message &message) {
277 const auto folderLocalId = syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, folderRemoteId); 277 const auto folderLocalId = syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, folderRemoteId);
278 const auto remoteId = assembleMailRid(folderLocalId, message.uid); 278 const auto remoteId = assembleMailRid(folderLocalId, message.uid);
279 279
@@ -315,12 +315,12 @@ public:
315 return job.then([=](const QVector<qint64> &uidsToFetch) { 315 return job.then([=](const QVector<qint64> &uidsToFetch) {
316 SinkTraceCtx(mLogCtx) << "Received result set " << uidsToFetch; 316 SinkTraceCtx(mLogCtx) << "Received result set " << uidsToFetch;
317 SinkTraceCtx(mLogCtx) << "About to fetch mail" << folder.path(); 317 SinkTraceCtx(mLogCtx) << "About to fetch mail" << folder.path();
318 const auto uidNext = syncStore().readValue(folderRemoteId, "uidnext").toLongLong(); 318 const auto lastSeenUid = syncStore().readValue(folderRemoteId, "uidnext").toLongLong();
319 319
320 //Make sure the uids are sorted in reverse order and drop everything below uidNext (so we don't refetch what we already have 320 //Make sure the uids are sorted in reverse order and drop everything below lastSeenUid (so we don't refetch what we already have
321 QVector<qint64> filteredAndSorted = uidsToFetch; 321 QVector<qint64> filteredAndSorted = uidsToFetch;
322 qSort(filteredAndSorted.begin(), filteredAndSorted.end(), qGreater<qint64>()); 322 qSort(filteredAndSorted.begin(), filteredAndSorted.end(), qGreater<qint64>());
323 auto lowerBound = qLowerBound(filteredAndSorted.begin(), filteredAndSorted.end(), uidNext, qGreater<qint64>()); 323 auto lowerBound = qLowerBound(filteredAndSorted.begin(), filteredAndSorted.end(), lastSeenUid, qGreater<qint64>());
324 if (lowerBound != filteredAndSorted.end()) { 324 if (lowerBound != filteredAndSorted.end()) {
325 filteredAndSorted.erase(lowerBound, filteredAndSorted.end()); 325 filteredAndSorted.erase(lowerBound, filteredAndSorted.end());
326 } 326 }
@@ -348,13 +348,14 @@ public:
348 } 348 }
349 }) 349 })
350 .then([=] { 350 .then([=] {
351 SinkLogCtx(mLogCtx) << "UIDMAX: " << *maxUid << folder.path(); 351 SinkLogCtx(mLogCtx) << "Highest found uid: " << *maxUid << folder.path();
352 if (*maxUid > 0) { 352 if (*maxUid > 0) {
353 syncStore().writeValue(folderRemoteId, "uidnext", QByteArray::number(*maxUid)); 353 syncStore().writeValue(folderRemoteId, "uidnext", QByteArray::number(*maxUid));
354 } else { 354 } else {
355 if (serverUidNext) { 355 if (serverUidNext) {
356 SinkLogCtx(mLogCtx) << "Storing the server side uidnext: " << serverUidNext << folder.path();
356 //If we don't receive a mail we should still record the updated uidnext value. 357 //If we don't receive a mail we should still record the updated uidnext value.
357 syncStore().writeValue(folderRemoteId, "uidnext", QByteArray::number(serverUidNext)); 358 syncStore().writeValue(folderRemoteId, "uidnext", QByteArray::number(serverUidNext - 1));
358 } 359 }
359 } 360 }
360 syncStore().writeValue(folderRemoteId, "fullsetLowerbound", QByteArray::number(lowerBoundUid)); 361 syncStore().writeValue(folderRemoteId, "fullsetLowerbound", QByteArray::number(lowerBoundUid));
@@ -567,17 +568,26 @@ public:
567 synchronizeFolders(*folderList); 568 synchronizeFolders(*folderList);
568 return *folderList; 569 return *folderList;
569 }) 570 })
571 //The rest is only to check for new messages.
570 .each([=](const Imap::Folder &folder) { 572 .each([=](const Imap::Folder &folder) {
571 //TODO examine instead 573 if (!folder.noselect && folder.subscribed) {
572 return imap->select(folder) 574 return imap->examine(folder)
573 .then([=](const SelectResult &result) { 575 .then([=](const SelectResult &result) {
574 const auto folderRemoteId = folderRid(folder); 576 const auto folderRemoteId = folderRid(folder);
575 auto localUidNext = syncStore().readValue(folderRemoteId, "uidnext").toLongLong(); 577 auto lastSeenUid = syncStore().readValue(folderRemoteId, "uidnext").toLongLong();
576 if (result.uidNext > localUidNext) { 578 SinkTraceCtx(mLogCtx) << "Checking for new messages." << folderRemoteId << " Last seen uid: " << lastSeenUid << " Uidnext: " << result.uidNext;
577 const auto folderLocalId = syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, folderRemoteId); 579 if (result.uidNext > (lastSeenUid + 1)) {
578 emitNotification(Notification::Info, ApplicationDomain::NewContentAvailable, {}, {}, {{folderLocalId}}); 580 const auto folderLocalId = syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, folderRemoteId);
579 } 581 emitNotification(Notification::Info, ApplicationDomain::NewContentAvailable, {}, {}, {{folderLocalId}});
580 }); 582 }
583 }).then([=] (const KAsync::Error &error) {
584 if (error) {
585 //Ignore the error because we don't want to fail the synchronization here
586 SinkWarningCtx(mLogCtx) << "Examine failed: " << error.errorMessage;
587 }
588 });
589 }
590 return KAsync::null();
581 }); 591 });
582 }) 592 })
583 .then([=] (const KAsync::Error &error) { 593 .then([=] (const KAsync::Error &error) {