diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2018-03-01 10:30:42 +0100 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2018-03-01 10:30:42 +0100 |
commit | 14d33366f8ed61105f0d10328a03ccb07cf8970a (patch) | |
tree | 2c6b07899ad706dc6d3ec14338b4c6f9fe207034 /examples | |
parent | d0f138ae5aaeb6291f12c49a13e3bb2e2237c792 (diff) | |
download | sink-14d33366f8ed61105f0d10328a03ccb07cf8970a.tar.gz sink-14d33366f8ed61105f0d10328a03ccb07cf8970a.zip |
Select all folders and emit notification if new mails are available
Diffstat (limited to 'examples')
-rw-r--r-- | examples/imapresource/imapresource.cpp | 24 | ||||
-rw-r--r-- | examples/imapresource/tests/imapmailsynctest.cpp | 61 |
2 files changed, 83 insertions, 2 deletions
diff --git a/examples/imapresource/imapresource.cpp b/examples/imapresource/imapresource.cpp index 5f7304d..061fdb1 100644 --- a/examples/imapresource/imapresource.cpp +++ b/examples/imapresource/imapresource.cpp | |||
@@ -287,6 +287,7 @@ public: | |||
287 | .then([=](const SelectResult &selectResult) { | 287 | .then([=](const SelectResult &selectResult) { |
288 | SinkLogCtx(mLogCtx) << "Flags updated. New changedsince value: " << selectResult.highestModSequence; | 288 | SinkLogCtx(mLogCtx) << "Flags updated. New changedsince value: " << selectResult.highestModSequence; |
289 | syncStore().writeValue(folderRemoteId, "changedsince", QByteArray::number(selectResult.highestModSequence)); | 289 | syncStore().writeValue(folderRemoteId, "changedsince", QByteArray::number(selectResult.highestModSequence)); |
290 | return selectResult.uidNext; | ||
290 | }); | 291 | }); |
291 | } else { | 292 | } else { |
292 | //We hit this path on initial sync and simply record the current changedsince value | 293 | //We hit this path on initial sync and simply record the current changedsince value |
@@ -294,13 +295,14 @@ public: | |||
294 | .then([=](const SelectResult &selectResult) { | 295 | .then([=](const SelectResult &selectResult) { |
295 | SinkLogCtx(mLogCtx) << "No flags to update. New changedsince value: " << selectResult.highestModSequence; | 296 | SinkLogCtx(mLogCtx) << "No flags to update. New changedsince value: " << selectResult.highestModSequence; |
296 | syncStore().writeValue(folderRemoteId, "changedsince", QByteArray::number(selectResult.highestModSequence)); | 297 | syncStore().writeValue(folderRemoteId, "changedsince", QByteArray::number(selectResult.highestModSequence)); |
298 | return selectResult.uidNext; | ||
297 | }); | 299 | }); |
298 | } | 300 | } |
299 | }) | 301 | }) |
300 | //Next we synchronize the full set that is given by the date limit. | 302 | //Next we synchronize the full set that is given by the date limit. |
301 | //We fetch all data for this set. | 303 | //We fetch all data for this set. |
302 | //This will also pull in any new messages in subsequent runs. | 304 | //This will also pull in any new messages in subsequent runs. |
303 | .then([=] { | 305 | .then([=] (qint64 serverUidNext){ |
304 | auto job = [&] { | 306 | auto job = [&] { |
305 | if (dateFilter.isValid()) { | 307 | if (dateFilter.isValid()) { |
306 | SinkLogCtx(mLogCtx) << "Fetching messages since: " << dateFilter; | 308 | SinkLogCtx(mLogCtx) << "Fetching messages since: " << dateFilter; |
@@ -349,6 +351,11 @@ public: | |||
349 | SinkLogCtx(mLogCtx) << "UIDMAX: " << *maxUid << folder.path(); | 351 | SinkLogCtx(mLogCtx) << "UIDMAX: " << *maxUid << folder.path(); |
350 | if (*maxUid > 0) { | 352 | if (*maxUid > 0) { |
351 | syncStore().writeValue(folderRemoteId, "uidnext", QByteArray::number(*maxUid)); | 353 | syncStore().writeValue(folderRemoteId, "uidnext", QByteArray::number(*maxUid)); |
354 | } else { | ||
355 | if (serverUidNext) { | ||
356 | //If we don't receive a mail we should still record the updated uidnext value. | ||
357 | syncStore().writeValue(folderRemoteId, "uidnext", QByteArray::number(serverUidNext)); | ||
358 | } | ||
352 | } | 359 | } |
353 | syncStore().writeValue(folderRemoteId, "fullsetLowerbound", QByteArray::number(lowerBoundUid)); | 360 | syncStore().writeValue(folderRemoteId, "fullsetLowerbound", QByteArray::number(lowerBoundUid)); |
354 | commit(); | 361 | commit(); |
@@ -555,8 +562,21 @@ public: | |||
555 | return imap->fetchFolders([folderList](const Folder &folder) { | 562 | return imap->fetchFolders([folderList](const Folder &folder) { |
556 | *folderList << folder; | 563 | *folderList << folder; |
557 | }) | 564 | }) |
558 | .then([this, folderList]() { | 565 | .then([=]() { |
559 | synchronizeFolders(*folderList); | 566 | synchronizeFolders(*folderList); |
567 | return *folderList; | ||
568 | }) | ||
569 | .each([=](const Imap::Folder &folder) { | ||
570 | //TODO examine instead | ||
571 | return imap->select(folder) | ||
572 | .then([=](const SelectResult &result) { | ||
573 | const auto folderRemoteId = folderRid(folder); | ||
574 | auto localUidNext = syncStore().readValue(folderRemoteId, "uidnext").toLongLong(); | ||
575 | if (result.uidNext > localUidNext) { | ||
576 | const auto folderLocalId = syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, folderRemoteId); | ||
577 | emitNotification(Notification::Info, ApplicationDomain::NewContentAvailable, {}, {}, {{folderLocalId}}); | ||
578 | } | ||
579 | }); | ||
560 | }); | 580 | }); |
561 | }) | 581 | }) |
562 | .then([=] (const KAsync::Error &error) { | 582 | .then([=] (const KAsync::Error &error) { |
diff --git a/examples/imapresource/tests/imapmailsynctest.cpp b/examples/imapresource/tests/imapmailsynctest.cpp index 3e975b8..e40aec8 100644 --- a/examples/imapresource/tests/imapmailsynctest.cpp +++ b/examples/imapresource/tests/imapmailsynctest.cpp | |||
@@ -26,6 +26,9 @@ | |||
26 | #include "common/test.h" | 26 | #include "common/test.h" |
27 | #include "common/domain/applicationdomaintype.h" | 27 | #include "common/domain/applicationdomaintype.h" |
28 | #include "common/secretstore.h" | 28 | #include "common/secretstore.h" |
29 | #include "common/store.h" | ||
30 | #include "common/resourcecontrol.h" | ||
31 | #include "common/notifier.h" | ||
29 | 32 | ||
30 | using namespace Sink; | 33 | using namespace Sink; |
31 | using namespace Sink::ApplicationDomain; | 34 | using namespace Sink::ApplicationDomain; |
@@ -115,6 +118,64 @@ protected: | |||
115 | VERIFYEXEC(imap.select("INBOX." + folderPath.join('.'))); | 118 | VERIFYEXEC(imap.select("INBOX." + folderPath.join('.'))); |
116 | VERIFYEXEC(imap.addFlags(KIMAP2::ImapSet::fromImapSequenceSet(messageIdentifier), QByteArrayList() << Imap::Flags::Flagged)); | 119 | VERIFYEXEC(imap.addFlags(KIMAP2::ImapSet::fromImapSequenceSet(messageIdentifier), QByteArrayList() << Imap::Flags::Flagged)); |
117 | } | 120 | } |
121 | |||
122 | static QByteArray newMessage(const QString &subject) | ||
123 | { | ||
124 | auto msg = KMime::Message::Ptr::create(); | ||
125 | msg->subject(true)->fromUnicodeString(subject, "utf8"); | ||
126 | msg->date(true)->setDateTime(QDateTime::currentDateTimeUtc()); | ||
127 | msg->assemble(); | ||
128 | return msg->encodedContent(true); | ||
129 | } | ||
130 | |||
131 | private slots: | ||
132 | void testNewMailNotification() | ||
133 | { | ||
134 | const auto syncFolders = Sink::SyncScope{ApplicationDomain::getTypeName<Folder>()}.resourceFilter(mResourceInstanceIdentifier); | ||
135 | //Fetch folders initially | ||
136 | VERIFYEXEC(Store::synchronize(syncFolders)); | ||
137 | VERIFYEXEC(ResourceControl::flushMessageQueue(mResourceInstanceIdentifier)); | ||
138 | |||
139 | auto folder = Store::readOne<Folder>(Sink::Query{}.resourceFilter(mResourceInstanceIdentifier).filter<Folder::Name>("test")); | ||
140 | Q_ASSERT(!folder.identifier().isEmpty()); | ||
141 | |||
142 | const auto syncTestMails = Sink::SyncScope{ApplicationDomain::getTypeName<Mail>()}.resourceFilter(mResourceInstanceIdentifier).filter<Mail::Folder>(QVariant::fromValue(folder.identifier())); | ||
143 | |||
144 | bool notificationReceived = false; | ||
145 | auto notifier = QSharedPointer<Sink::Notifier>::create(mResourceInstanceIdentifier); | ||
146 | notifier->registerHandler([&](const Notification ¬ification) { | ||
147 | if (notification.type == Sink::Notification::Info && notification.code == ApplicationDomain::NewContentAvailable && notification.entities.contains(folder.identifier())) { | ||
148 | notificationReceived = true; | ||
149 | } | ||
150 | }); | ||
151 | |||
152 | //Should result in a change notification for test | ||
153 | VERIFYEXEC(Store::synchronize(syncFolders)); | ||
154 | VERIFYEXEC(ResourceControl::flushMessageQueue(mResourceInstanceIdentifier)); | ||
155 | |||
156 | QTRY_VERIFY(notificationReceived); | ||
157 | |||
158 | notificationReceived = false; | ||
159 | |||
160 | //Fetch test mails to skip change notification | ||
161 | VERIFYEXEC(Store::synchronize(syncTestMails)); | ||
162 | VERIFYEXEC(ResourceControl::flushMessageQueue(mResourceInstanceIdentifier)); | ||
163 | |||
164 | //Should no longer result in change notifications for test | ||
165 | VERIFYEXEC(Store::synchronize(syncFolders)); | ||
166 | VERIFYEXEC(ResourceControl::flushMessageQueue(mResourceInstanceIdentifier)); | ||
167 | |||
168 | QVERIFY(!notificationReceived); | ||
169 | |||
170 | //Create message and retry | ||
171 | createMessage(QStringList() << "test", newMessage("This is a Subject.")); | ||
172 | |||
173 | //Should result in change notification | ||
174 | VERIFYEXEC(Store::synchronize(syncFolders)); | ||
175 | VERIFYEXEC(ResourceControl::flushMessageQueue(mResourceInstanceIdentifier)); | ||
176 | |||
177 | QTRY_VERIFY(notificationReceived); | ||
178 | } | ||
118 | }; | 179 | }; |
119 | 180 | ||
120 | QTEST_MAIN(ImapMailSyncTest) | 181 | QTEST_MAIN(ImapMailSyncTest) |