diff options
Diffstat (limited to 'examples')
-rw-r--r-- | examples/imapresource/imapresource.cpp | 121 | ||||
-rw-r--r-- | examples/imapresource/imapserverproxy.h | 16 | ||||
-rw-r--r-- | examples/maildirresource/maildirresource.cpp | 54 |
3 files changed, 149 insertions, 42 deletions
diff --git a/examples/imapresource/imapresource.cpp b/examples/imapresource/imapresource.cpp index d5a59b9..302d681 100644 --- a/examples/imapresource/imapresource.cpp +++ b/examples/imapresource/imapresource.cpp | |||
@@ -272,41 +272,102 @@ public: | |||
272 | 272 | ||
273 | } | 273 | } |
274 | 274 | ||
275 | KAsync::Job<void> synchronizeWithSource(const Sink::QueryBase &query) Q_DECL_OVERRIDE | 275 | QList<Synchronizer::SyncRequest> getSyncRequests(const Sink::QueryBase &query) Q_DECL_OVERRIDE |
276 | { | 276 | { |
277 | SinkLog() << " Synchronizing"; | 277 | QList<Synchronizer::SyncRequest> list; |
278 | return KAsync::start<void>([this]() { | 278 | if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Mail>()) { |
279 | SinkTrace() << "Connecting to:" << mServer << mPort; | 279 | list << Synchronizer::SyncRequest{query}; |
280 | SinkTrace() << "as:" << mUser; | 280 | } else if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Folder>()) { |
281 | auto imap = QSharedPointer<ImapServerProxy>::create(mServer, mPort); | 281 | list << Synchronizer::SyncRequest{query}; |
282 | } else { | ||
283 | list << Synchronizer::SyncRequest{Sink::QueryBase(ApplicationDomain::getTypeName<ApplicationDomain::Folder>())}; | ||
284 | list << Synchronizer::SyncRequest{Sink::QueryBase(ApplicationDomain::getTypeName<ApplicationDomain::Mail>())}; | ||
285 | } | ||
286 | return list; | ||
287 | } | ||
282 | 288 | ||
283 | return imap->login(mUser, mPassword) | 289 | KAsync::Job<void> login(QSharedPointer<ImapServerProxy> imap) |
284 | .addToContext(imap) | 290 | { |
285 | .onError([](const KAsync::Error &error) { | 291 | SinkTrace() << "Connecting to:" << mServer << mPort; |
286 | SinkWarning() << "Login failed."; | 292 | SinkTrace() << "as:" << mUser; |
287 | }) | 293 | return imap->login(mUser, mPassword) |
288 | .then<QVector<Folder>>([this, imap]() { | 294 | .addToContext(imap) |
289 | auto folderList = QSharedPointer<QVector<Folder>>::create(); | 295 | .onError([](const KAsync::Error &error) { |
290 | SinkLog() << "Login was successful"; | 296 | SinkWarning() << "Login failed."; |
291 | return imap->fetchFolders([folderList](const Folder &folder) { | 297 | }); |
292 | *folderList << folder; | 298 | } |
293 | }) | 299 | |
294 | .onError([](const KAsync::Error &error) { | 300 | KAsync::Job<void> synchronizeWithSource(const Sink::QueryBase &query) Q_DECL_OVERRIDE |
295 | SinkWarning() << "Folder list sync failed."; | 301 | { |
302 | if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Folder>()) { | ||
303 | return KAsync::start<void>([this]() { | ||
304 | auto imap = QSharedPointer<ImapServerProxy>::create(mServer, mPort); | ||
305 | auto job = login(imap); | ||
306 | job = job.then<QVector<Folder>>([this, imap]() { | ||
307 | auto folderList = QSharedPointer<QVector<Folder>>::create(); | ||
308 | return imap->fetchFolders([folderList](const Folder &folder) { | ||
309 | *folderList << folder; | ||
310 | }) | ||
311 | .onError([](const KAsync::Error &error) { | ||
312 | SinkWarning() << "Folder list sync failed."; | ||
313 | }) | ||
314 | .syncThen<QVector<Folder>>([this, folderList]() { | ||
315 | synchronizeFolders(*folderList); | ||
316 | commit(); | ||
317 | return *folderList; | ||
318 | }); | ||
319 | }); | ||
320 | return job; | ||
321 | }); | ||
322 | } else if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Mail>()) { | ||
323 | //TODO | ||
324 | //if we have a folder filter: | ||
325 | //* execute the folder query and resolve the results to the remote identifier | ||
326 | //* query only those folders | ||
327 | //if we have a date filter: | ||
328 | //* apply the date filter to the fetch | ||
329 | //if we have no folder filter: | ||
330 | //* fetch list of folders from server directly and sync (because we have no guarantee that the folder sync was already processed by the pipeline). | ||
331 | return KAsync::start<void>([this, query]() { | ||
332 | auto imap = QSharedPointer<ImapServerProxy>::create(mServer, mPort); | ||
333 | auto job = login(imap); | ||
334 | job = job.then<QVector<Folder>>([this, imap, query]() { | ||
335 | SinkLog() << "Login was successful"; | ||
336 | //FIXME If we were able to to flush in between we could just query the local store for the folder list. | ||
337 | // | ||
338 | if (query.hasFilter<ApplicationDomain::Mail::Folder>()) { | ||
339 | QVector<Folder> folders; | ||
340 | auto folderFilter = query.getFilter<ApplicationDomain::Mail::Folder>(); | ||
341 | auto localIds = resolveFilter(folderFilter); | ||
342 | auto folderRemoteIds = syncStore().resolveLocalIds(ApplicationDomain::getTypeName<ApplicationDomain::Folder>(), localIds); | ||
343 | for (const auto &r : folderRemoteIds) { | ||
344 | folders << Folder{r}; | ||
345 | } | ||
346 | return KAsync::value(folders); | ||
347 | } else { | ||
348 | auto folderList = QSharedPointer<QVector<Folder>>::create(); | ||
349 | return imap->fetchFolders([folderList](const Folder &folder) { | ||
350 | *folderList << folder; | ||
351 | }) | ||
352 | .onError([](const KAsync::Error &error) { | ||
353 | SinkWarning() << "Folder list sync failed."; | ||
354 | }) | ||
355 | .syncThen<QVector<Folder>>([this, folderList]() { | ||
356 | return *folderList; | ||
357 | }); | ||
358 | } | ||
296 | }) | 359 | }) |
297 | .syncThen<QVector<Folder>>([this, folderList]() { | 360 | .serialEach<void>([this, imap](const Folder &folder) { |
298 | synchronizeFolders(*folderList); | 361 | if (folder.noselect) { |
299 | commit(); | 362 | return KAsync::null<void>(); |
300 | return *folderList; | 363 | } |
364 | return synchronizeFolder(imap, folder); | ||
301 | }); | 365 | }); |
302 | }) | 366 | |
303 | .serialEach<void>([this, imap](const Folder &folder) { | 367 | return job; |
304 | if (folder.noselect) { | ||
305 | return KAsync::null<void>(); | ||
306 | } | ||
307 | return synchronizeFolder(imap, folder); | ||
308 | }); | 368 | }); |
309 | }); | 369 | } |
370 | return KAsync::error<void>("Nothing to do"); | ||
310 | } | 371 | } |
311 | 372 | ||
312 | public: | 373 | public: |
diff --git a/examples/imapresource/imapserverproxy.h b/examples/imapresource/imapserverproxy.h index 8b39f23..6e6626e 100644 --- a/examples/imapresource/imapserverproxy.h +++ b/examples/imapresource/imapserverproxy.h | |||
@@ -58,6 +58,20 @@ struct Message { | |||
58 | }; | 58 | }; |
59 | 59 | ||
60 | struct Folder { | 60 | struct Folder { |
61 | Folder() = default; | ||
62 | Folder(QList<QString> pathParts_, const QString &path_, const QChar &separator_, bool noselect_) | ||
63 | : pathParts(pathParts_), | ||
64 | path(path_), | ||
65 | separator(separator_), | ||
66 | noselect(noselect_) | ||
67 | { | ||
68 | } | ||
69 | |||
70 | Folder(const QString &path_) | ||
71 | : path(path_) | ||
72 | { | ||
73 | } | ||
74 | |||
61 | QString normalizedPath() const | 75 | QString normalizedPath() const |
62 | { | 76 | { |
63 | return pathParts.join('/'); | 77 | return pathParts.join('/'); |
@@ -73,7 +87,7 @@ struct Folder { | |||
73 | QList<QString> pathParts; | 87 | QList<QString> pathParts; |
74 | QString path; | 88 | QString path; |
75 | QChar separator; | 89 | QChar separator; |
76 | bool noselect; | 90 | bool noselect = false; |
77 | }; | 91 | }; |
78 | 92 | ||
79 | struct SelectResult { | 93 | struct SelectResult { |
diff --git a/examples/maildirresource/maildirresource.cpp b/examples/maildirresource/maildirresource.cpp index 820ec2f..fc77315 100644 --- a/examples/maildirresource/maildirresource.cpp +++ b/examples/maildirresource/maildirresource.cpp | |||
@@ -330,25 +330,57 @@ public: | |||
330 | SinkLog() << "Synchronized " << count << " mails in " << listingPath << Sink::Log::TraceTime(elapsed) << " " << elapsed/qMax(count, 1) << " [ms/mail]"; | 330 | SinkLog() << "Synchronized " << count << " mails in " << listingPath << Sink::Log::TraceTime(elapsed) << " " << elapsed/qMax(count, 1) << " [ms/mail]"; |
331 | } | 331 | } |
332 | 332 | ||
333 | QList<Synchronizer::SyncRequest> getSyncRequests(const Sink::QueryBase &query) Q_DECL_OVERRIDE | ||
334 | { | ||
335 | QList<Synchronizer::SyncRequest> list; | ||
336 | if (!query.type().isEmpty()) { | ||
337 | //We want to synchronize something specific | ||
338 | list << Synchronizer::SyncRequest{query}; | ||
339 | } else { | ||
340 | //We want to synchronize everything | ||
341 | list << Synchronizer::SyncRequest{Sink::QueryBase(ApplicationDomain::getTypeName<ApplicationDomain::Folder>())}; | ||
342 | //FIXME we can't process the second synchronization before the pipeline of the first one is processed, otherwise we can't execute a query on the local data. | ||
343 | /* list << Synchronizer::SyncRequest{Flush}; */ | ||
344 | list << Synchronizer::SyncRequest{Sink::QueryBase(ApplicationDomain::getTypeName<ApplicationDomain::Mail>())}; | ||
345 | } | ||
346 | return list; | ||
347 | } | ||
348 | |||
333 | KAsync::Job<void> synchronizeWithSource(const Sink::QueryBase &query) Q_DECL_OVERRIDE | 349 | KAsync::Job<void> synchronizeWithSource(const Sink::QueryBase &query) Q_DECL_OVERRIDE |
334 | { | 350 | { |
335 | SinkLog() << " Synchronizing"; | 351 | auto job = KAsync::start<void>([this] { |
336 | return KAsync::start<void>([this]() { | ||
337 | KPIM::Maildir maildir(mMaildirPath, true); | 352 | KPIM::Maildir maildir(mMaildirPath, true); |
338 | if (!maildir.isValid(false)) { | 353 | if (!maildir.isValid(false)) { |
339 | return KAsync::error<void>(1, "Maildir path doesn't point to a valid maildir: " + mMaildirPath); | 354 | return KAsync::error<void>(1, "Maildir path doesn't point to a valid maildir: " + mMaildirPath); |
340 | } | 355 | } |
341 | synchronizeFolders(); | ||
342 | //The next sync needs the folders available | ||
343 | commit(); | ||
344 | for (const auto &folder : listAvailableFolders()) { | ||
345 | synchronizeMails(folder); | ||
346 | //Don't let the transaction grow too much | ||
347 | commit(); | ||
348 | } | ||
349 | SinkLog() << "Done Synchronizing"; | ||
350 | return KAsync::null<void>(); | 356 | return KAsync::null<void>(); |
351 | }); | 357 | }); |
358 | |||
359 | if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Folder>()) { | ||
360 | job = job.syncThen<void>([this] { | ||
361 | synchronizeFolders(); | ||
362 | }); | ||
363 | } else if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Mail>()) { | ||
364 | job = job.syncThen<void>([this, query] { | ||
365 | QStringList folders; | ||
366 | if (query.hasFilter<ApplicationDomain::Mail::Folder>()) { | ||
367 | auto folderFilter = query.getFilter<ApplicationDomain::Mail::Folder>(); | ||
368 | auto localIds = resolveFilter(folderFilter); | ||
369 | auto folderRemoteIds = syncStore().resolveLocalIds(ApplicationDomain::getTypeName<ApplicationDomain::Folder>(), localIds); | ||
370 | for (const auto &r : folderRemoteIds) { | ||
371 | folders << r; | ||
372 | } | ||
373 | } else { | ||
374 | folders = listAvailableFolders(); | ||
375 | } | ||
376 | for (const auto &folder : folders) { | ||
377 | synchronizeMails(folder); | ||
378 | //Don't let the transaction grow too much | ||
379 | commit(); | ||
380 | } | ||
381 | }); | ||
382 | } | ||
383 | return job; | ||
352 | } | 384 | } |
353 | 385 | ||
354 | public: | 386 | public: |