summaryrefslogtreecommitdiffstats
path: root/examples/imapresource
diff options
context:
space:
mode:
Diffstat (limited to 'examples/imapresource')
-rw-r--r--examples/imapresource/CMakeLists.txt2
-rw-r--r--examples/imapresource/domainadaptor.cpp35
-rw-r--r--examples/imapresource/domainadaptor.h38
-rw-r--r--examples/imapresource/facade.cpp44
-rw-r--r--examples/imapresource/facade.h36
-rw-r--r--examples/imapresource/imapresource.cpp139
-rw-r--r--examples/imapresource/imapserverproxy.cpp14
-rw-r--r--examples/imapresource/imapserverproxy.h6
8 files changed, 117 insertions, 197 deletions
diff --git a/examples/imapresource/CMakeLists.txt b/examples/imapresource/CMakeLists.txt
index 15a720d..46a8b08 100644
--- a/examples/imapresource/CMakeLists.txt
+++ b/examples/imapresource/CMakeLists.txt
@@ -8,7 +8,7 @@ find_package(KIMAP2 0.0.1 REQUIRED)
8 8
9include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) 9include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
10 10
11add_library(${PROJECT_NAME} SHARED facade.cpp imapresource.cpp domainadaptor.cpp imapserverproxy.cpp) 11add_library(${PROJECT_NAME} SHARED imapresource.cpp imapserverproxy.cpp)
12qt5_use_modules(${PROJECT_NAME} Core Network) 12qt5_use_modules(${PROJECT_NAME} Core Network)
13target_link_libraries(${PROJECT_NAME} sink KF5::Mime KIMAP2) 13target_link_libraries(${PROJECT_NAME} sink KF5::Mime KIMAP2)
14 14
diff --git a/examples/imapresource/domainadaptor.cpp b/examples/imapresource/domainadaptor.cpp
deleted file mode 100644
index 4e74ad2..0000000
--- a/examples/imapresource/domainadaptor.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
1/*
2 * Copyright (C) 2015 Christian Mollekopf <chrigi_1@fastmail.fm>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#include "domainadaptor.h"
21
22using namespace flatbuffers;
23
24ImapMailAdaptorFactory::ImapMailAdaptorFactory()
25 : DomainTypeAdaptorFactory()
26{
27
28}
29
30ImapFolderAdaptorFactory::ImapFolderAdaptorFactory()
31 : DomainTypeAdaptorFactory()
32{
33
34}
35
diff --git a/examples/imapresource/domainadaptor.h b/examples/imapresource/domainadaptor.h
deleted file mode 100644
index 06a513c..0000000
--- a/examples/imapresource/domainadaptor.h
+++ /dev/null
@@ -1,38 +0,0 @@
1/*
2 * Copyright (C) 2015 Christian Mollekopf <chrigi_1@fastmail.fm>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19#pragma once
20
21#include <common/domainadaptor.h>
22#include "mail_generated.h"
23#include "folder_generated.h"
24#include "dummy_generated.h"
25
26class ImapMailAdaptorFactory : public DomainTypeAdaptorFactory<Sink::ApplicationDomain::Mail, Sink::ApplicationDomain::Buffer::Dummy, Sink::ApplicationDomain::Buffer::DummyBuilder>
27{
28public:
29 ImapMailAdaptorFactory();
30 virtual ~ImapMailAdaptorFactory() {};
31};
32
33class ImapFolderAdaptorFactory : public DomainTypeAdaptorFactory<Sink::ApplicationDomain::Folder, Sink::ApplicationDomain::Buffer::Dummy, Sink::ApplicationDomain::Buffer::DummyBuilder>
34{
35public:
36 ImapFolderAdaptorFactory();
37 virtual ~ImapFolderAdaptorFactory() {};
38};
diff --git a/examples/imapresource/facade.cpp b/examples/imapresource/facade.cpp
deleted file mode 100644
index 2829bb1..0000000
--- a/examples/imapresource/facade.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
1/*
2 * Copyright (C) 2014 Christian Mollekopf <chrigi_1@fastmail.fm>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#include "facade.h"
21
22#include <QDir>
23#include <QFileInfo>
24
25#include "domainadaptor.h"
26#include "queryrunner.h"
27
28ImapResourceMailFacade::ImapResourceMailFacade(const Sink::ResourceContext &context)
29 : Sink::GenericFacade<Sink::ApplicationDomain::Mail>(context)
30{
31}
32
33ImapResourceMailFacade::~ImapResourceMailFacade()
34{
35}
36
37ImapResourceFolderFacade::ImapResourceFolderFacade(const Sink::ResourceContext &context)
38 : Sink::GenericFacade<Sink::ApplicationDomain::Folder>(context)
39{
40}
41
42ImapResourceFolderFacade::~ImapResourceFolderFacade()
43{
44}
diff --git a/examples/imapresource/facade.h b/examples/imapresource/facade.h
deleted file mode 100644
index 1d24856..0000000
--- a/examples/imapresource/facade.h
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2 * Copyright (C) 2014 Christian Mollekopf <chrigi_1@fastmail.fm>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#pragma once
21
22#include "common/facade.h"
23
24class ImapResourceMailFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Mail>
25{
26public:
27 ImapResourceMailFacade(const Sink::ResourceContext &context);
28 virtual ~ImapResourceMailFacade();
29};
30
31class ImapResourceFolderFacade : public Sink::GenericFacade<Sink::ApplicationDomain::Folder>
32{
33public:
34 ImapResourceFolderFacade(const Sink::ResourceContext &context);
35 virtual ~ImapResourceFolderFacade();
36};
diff --git a/examples/imapresource/imapresource.cpp b/examples/imapresource/imapresource.cpp
index 09f57d5..0579dae 100644
--- a/examples/imapresource/imapresource.cpp
+++ b/examples/imapresource/imapresource.cpp
@@ -100,7 +100,7 @@ public:
100 QByteArray createFolder(const Imap::Folder &f) 100 QByteArray createFolder(const Imap::Folder &f)
101 { 101 {
102 const auto parentFolderRid = parentRid(f); 102 const auto parentFolderRid = parentRid(f);
103 SinkTrace() << "Creating folder: " << f.name() << parentFolderRid; 103 SinkTraceCtx(mLogCtx) << "Creating folder: " << f.name() << parentFolderRid;
104 104
105 const auto remoteId = folderRid(f); 105 const auto remoteId = folderRid(f);
106 Sink::ApplicationDomain::Folder folder; 106 Sink::ApplicationDomain::Folder folder;
@@ -123,7 +123,7 @@ public:
123 123
124 void synchronizeFolders(const QVector<Folder> &folderList) 124 void synchronizeFolders(const QVector<Folder> &folderList)
125 { 125 {
126 SinkTrace() << "Found folders " << folderList.size(); 126 SinkTraceCtx(mLogCtx) << "Found folders " << folderList.size();
127 127
128 scanForRemovals(ENTITY_TYPE_FOLDER, 128 scanForRemovals(ENTITY_TYPE_FOLDER,
129 [&folderList](const QByteArray &remoteId) -> bool { 129 [&folderList](const QByteArray &remoteId) -> bool {
@@ -164,14 +164,14 @@ public:
164 { 164 {
165 auto time = QSharedPointer<QTime>::create(); 165 auto time = QSharedPointer<QTime>::create();
166 time->start(); 166 time->start();
167 SinkTrace() << "Importing new mail." << folderRid; 167 SinkTraceCtx(mLogCtx) << "Importing new mail." << folderRid;
168 168
169 const auto folderLocalId = syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, folderRid); 169 const auto folderLocalId = syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, folderRid);
170 170
171 const auto remoteId = assembleMailRid(folderLocalId, message.uid); 171 const auto remoteId = assembleMailRid(folderLocalId, message.uid);
172 172
173 Q_ASSERT(message.msg); 173 Q_ASSERT(message.msg);
174 SinkTrace() << "Found a mail " << remoteId << message.msg->subject(true)->asUnicodeString() << message.flags; 174 SinkTraceCtx(mLogCtx) << "Found a mail " << remoteId << message.msg->subject(true)->asUnicodeString() << message.flags;
175 175
176 auto mail = Sink::ApplicationDomain::Mail::create(mResourceInstanceIdentifier); 176 auto mail = Sink::ApplicationDomain::Mail::create(mResourceInstanceIdentifier);
177 mail.setFolder(folderLocalId); 177 mail.setFolder(folderLocalId);
@@ -181,7 +181,7 @@ public:
181 181
182 createOrModify(ENTITY_TYPE_MAIL, remoteId, mail); 182 createOrModify(ENTITY_TYPE_MAIL, remoteId, mail);
183 // const auto elapsed = time->elapsed(); 183 // const auto elapsed = time->elapsed();
184 // SinkTrace() << "Synchronized " << count << " mails in " << folderRid << Sink::Log::TraceTime(elapsed) << " " << elapsed/qMax(count, 1) << " [ms/mail]"; 184 // SinkTraceCtx(mLogCtx) << "Synchronized " << count << " mails in " << folderRid << Sink::Log::TraceTime(elapsed) << " " << elapsed/qMax(count, 1) << " [ms/mail]";
185 } 185 }
186 186
187 void synchronizeRemovals(const QByteArray &folderRid, const QSet<qint64> &messages) 187 void synchronizeRemovals(const QByteArray &folderRid, const QSet<qint64> &messages)
@@ -194,7 +194,7 @@ public:
194 return; 194 return;
195 } 195 }
196 196
197 SinkTrace() << "Finding removed mail: " << folderLocalId << " remoteId: " << folderRid; 197 SinkTraceCtx(mLogCtx) << "Finding removed mail: " << folderLocalId << " remoteId: " << folderRid;
198 198
199 int count = 0; 199 int count = 0;
200 200
@@ -370,7 +370,7 @@ public:
370 370
371 Sink::QueryBase applyMailDefaults(const Sink::QueryBase &query) 371 Sink::QueryBase applyMailDefaults(const Sink::QueryBase &query)
372 { 372 {
373 auto defaultDateFilter = QDate::currentDate().addDays(-14); 373 auto defaultDateFilter = QDate::currentDate().addDays(0 - mDaysToSync);
374 auto queryWithDefaults = query; 374 auto queryWithDefaults = query;
375 if (!queryWithDefaults.hasFilter<ApplicationDomain::Mail::Date>()) { 375 if (!queryWithDefaults.hasFilter<ApplicationDomain::Mail::Date>()) {
376 queryWithDefaults.filter(ApplicationDomain::Mail::Date::name, QVariant::fromValue(defaultDateFilter)); 376 queryWithDefaults.filter(ApplicationDomain::Mail::Date::name, QVariant::fromValue(defaultDateFilter));
@@ -382,7 +382,11 @@ public:
382 { 382 {
383 QList<Synchronizer::SyncRequest> list; 383 QList<Synchronizer::SyncRequest> list;
384 if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Mail>()) { 384 if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Mail>()) {
385 list << Synchronizer::SyncRequest{applyMailDefaults(query)}; 385 auto request = Synchronizer::SyncRequest{applyMailDefaults(query)};
386 if (query.hasFilter(ApplicationDomain::Mail::Folder::name)) {
387 request.applicableEntities << query.getFilter(ApplicationDomain::Mail::Folder::name).value.toByteArray();
388 }
389 list << request;
386 } else if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Folder>()) { 390 } else if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Folder>()) {
387 list << Synchronizer::SyncRequest{query}; 391 list << Synchronizer::SyncRequest{query};
388 } else { 392 } else {
@@ -393,15 +397,57 @@ public:
393 return list; 397 return list;
394 } 398 }
395 399
400 QByteArray getFolderFromLocalId(const QByteArray &id)
401 {
402 auto mailRemoteId = syncStore().resolveLocalId(ApplicationDomain::getTypeName<ApplicationDomain::Mail>(), id);
403 if (mailRemoteId.isEmpty()) {
404 return {};
405 }
406 return folderIdFromMailRid(mailRemoteId);
407 }
408
409 void mergeIntoQueue(const Synchronizer::SyncRequest &request, QList<Synchronizer::SyncRequest> &queue) Q_DECL_OVERRIDE
410 {
411 auto isIndividualMailSync = [](const Synchronizer::SyncRequest &request) {
412 if (request.requestType == SyncRequest::Synchronization) {
413 const auto query = request.query;
414 if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Mail>()) {
415 return !query.ids().isEmpty();
416 }
417 }
418 return false;
419
420 };
421
422 if (isIndividualMailSync(request)) {
423 auto newId = request.query.ids().first();
424 auto requestFolder = getFolderFromLocalId(newId);
425 if (requestFolder.isEmpty()) {
426 SinkWarningCtx(mLogCtx) << "Failed to find folder for local id. Ignoring request: " << request.query;
427 return;
428 }
429 for (auto &r : queue) {
430 if (isIndividualMailSync(r)) {
431 auto queueFolder = getFolderFromLocalId(r.query.ids().first());
432 if (requestFolder == queueFolder) {
433 //Merge
434 r.query.filter(newId);
435 SinkTrace() << "Merging request " << request.query;
436 SinkTrace() << " to " << r.query;
437 return;
438 }
439 }
440 }
441 }
442 queue << request;
443 }
444
396 KAsync::Job<void> login(QSharedPointer<ImapServerProxy> imap) 445 KAsync::Job<void> login(QSharedPointer<ImapServerProxy> imap)
397 { 446 {
398 SinkTrace() << "Connecting to:" << mServer << mPort; 447 SinkTrace() << "Connecting to:" << mServer << mPort;
399 SinkTrace() << "as:" << mUser; 448 SinkTrace() << "as:" << mUser;
400 return imap->login(mUser, mPassword) 449 return imap->login(mUser, mPassword)
401 .addToContext(imap) 450 .addToContext(imap);
402 .onError([](const KAsync::Error &error) {
403 SinkWarning() << "Login failed.";
404 });
405 } 451 }
406 452
407 KAsync::Job<QVector<Folder>> getFolderList(QSharedPointer<ImapServerProxy> imap, const Sink::QueryBase &query) 453 KAsync::Job<QVector<Folder>> getFolderList(QSharedPointer<ImapServerProxy> imap, const Sink::QueryBase &query)
@@ -431,6 +477,19 @@ public:
431 } 477 }
432 } 478 }
433 479
480 KAsync::Error getError(const KAsync::Error &error)
481 {
482 if (error) {
483 if (error.errorCode == Imap::CouldNotConnectError) {
484 return {ApplicationDomain::ConnectionError, error.errorMessage};
485 } else if (error.errorCode == Imap::SslHandshakeError) {
486 return {ApplicationDomain::LoginError, error.errorMessage};
487 }
488 return {ApplicationDomain::UnknownError, error.errorMessage};
489 }
490 return {};
491 }
492
434 KAsync::Job<void> synchronizeWithSource(const Sink::QueryBase &query) Q_DECL_OVERRIDE 493 KAsync::Job<void> synchronizeWithSource(const Sink::QueryBase &query) Q_DECL_OVERRIDE
435 { 494 {
436 auto imap = QSharedPointer<ImapServerProxy>::create(mServer, mPort, &mSessionCache); 495 auto imap = QSharedPointer<ImapServerProxy>::create(mServer, mPort, &mSessionCache);
@@ -446,11 +505,8 @@ public:
446 }); 505 });
447 }) 506 })
448 .then([=] (const KAsync::Error &error) { 507 .then([=] (const KAsync::Error &error) {
449 if (error) {
450 SinkWarning() << "Error during folder sync: " << error.errorMessage;
451 }
452 return imap->logout() 508 return imap->logout()
453 .then(KAsync::error(error)); 509 .then(KAsync::error(getError(error)));
454 }); 510 });
455 } else if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Mail>()) { 511 } else if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Mail>()) {
456 //TODO 512 //TODO
@@ -487,7 +543,7 @@ public:
487 synchronizeMails(folderRemoteId, m); 543 synchronizeMails(folderRemoteId, m);
488 }, 544 },
489 [=](int progress, int total) { 545 [=](int progress, int total) {
490 SinkLogCtx(mLogCtx) << "Progress: " << progress << " out of " << total; 546 reportProgress(progress, total);
491 //commit every 100 messages 547 //commit every 100 messages
492 if ((progress % 100) == 0) { 548 if ((progress % 100) == 0) {
493 commit(); 549 commit();
@@ -503,6 +559,8 @@ public:
503 return KAsync::value(folders) 559 return KAsync::value(folders)
504 .serialEach<void>([=](const Folder &folder) { 560 .serialEach<void>([=](const Folder &folder) {
505 SinkLog() << "Syncing folder " << folder.path(); 561 SinkLog() << "Syncing folder " << folder.path();
562 //Emit notification that the folder is being synced.
563 //The synchronizer can't do that because it has no concept of the folder filter on a mail sync scope meaning that the folder is being synchronized.
506 QDate dateFilter; 564 QDate dateFilter;
507 auto filter = query.getFilter<ApplicationDomain::Mail::Date>(); 565 auto filter = query.getFilter<ApplicationDomain::Mail::Date>();
508 if (filter.value.canConvert<QDate>()) { 566 if (filter.value.canConvert<QDate>()) {
@@ -510,7 +568,7 @@ public:
510 SinkLog() << " with date-range " << dateFilter; 568 SinkLog() << " with date-range " << dateFilter;
511 } 569 }
512 return synchronizeFolder(imap, folder, dateFilter, syncHeaders) 570 return synchronizeFolder(imap, folder, dateFilter, syncHeaders)
513 .onError([folder](const KAsync::Error &error) { 571 .onError([=](const KAsync::Error &error) {
514 SinkWarning() << "Failed to sync folder: " << folder.path() << "Error: " << error.errorMessage; 572 SinkWarning() << "Failed to sync folder: " << folder.path() << "Error: " << error.errorMessage;
515 }); 573 });
516 }); 574 });
@@ -518,11 +576,8 @@ public:
518 } 576 }
519 }) 577 })
520 .then([=] (const KAsync::Error &error) { 578 .then([=] (const KAsync::Error &error) {
521 if (error) {
522 SinkWarning() << "Error during sync: " << error.errorMessage;
523 }
524 return imap->logout() 579 return imap->logout()
525 .then(KAsync::error(error)); 580 .then(KAsync::error(getError(error)));
526 }); 581 });
527 } 582 }
528 return KAsync::error<void>("Nothing to do"); 583 return KAsync::error<void>("Nothing to do");
@@ -616,11 +671,11 @@ public:
616 if (!folder.getParent().isEmpty()) { 671 if (!folder.getParent().isEmpty()) {
617 parentFolder = syncStore().resolveLocalId(ENTITY_TYPE_FOLDER, folder.getParent()); 672 parentFolder = syncStore().resolveLocalId(ENTITY_TYPE_FOLDER, folder.getParent());
618 } 673 }
619 SinkTrace() << "Creating a new folder: " << parentFolder << folder.getName(); 674 SinkTraceCtx(mLogCtx) << "Creating a new folder: " << parentFolder << folder.getName();
620 auto rid = QSharedPointer<QByteArray>::create(); 675 auto rid = QSharedPointer<QByteArray>::create();
621 auto createFolder = login.then(imap->createSubfolder(parentFolder, folder.getName())) 676 auto createFolder = login.then(imap->createSubfolder(parentFolder, folder.getName()))
622 .then([imap, rid](const QString &createdFolder) { 677 .then([this, imap, rid](const QString &createdFolder) {
623 SinkTrace() << "Finished creating a new folder: " << createdFolder; 678 SinkTraceCtx(mLogCtx) << "Finished creating a new folder: " << createdFolder;
624 *rid = createdFolder.toUtf8(); 679 *rid = createdFolder.toUtf8();
625 }); 680 });
626 if (folder.getSpecialPurpose().isEmpty()) { 681 if (folder.getSpecialPurpose().isEmpty()) {
@@ -636,19 +691,19 @@ public:
636 specialPurposeFolders->insert(SpecialPurpose::getSpecialPurposeType(folder.name()), folder.path()); 691 specialPurposeFolders->insert(SpecialPurpose::getSpecialPurposeType(folder.name()), folder.path());
637 }; 692 };
638 })) 693 }))
639 .then([specialPurposeFolders, folder, imap, parentFolder, rid]() -> KAsync::Job<void> { 694 .then([this, specialPurposeFolders, folder, imap, parentFolder, rid]() -> KAsync::Job<void> {
640 for (const auto &purpose : folder.getSpecialPurpose()) { 695 for (const auto &purpose : folder.getSpecialPurpose()) {
641 if (specialPurposeFolders->contains(purpose)) { 696 if (specialPurposeFolders->contains(purpose)) {
642 auto f = specialPurposeFolders->value(purpose); 697 auto f = specialPurposeFolders->value(purpose);
643 SinkTrace() << "Merging specialpurpose folder with: " << f << " with purpose: " << purpose; 698 SinkTraceCtx(mLogCtx) << "Merging specialpurpose folder with: " << f << " with purpose: " << purpose;
644 *rid = f.toUtf8(); 699 *rid = f.toUtf8();
645 return KAsync::null<void>(); 700 return KAsync::null<void>();
646 } 701 }
647 } 702 }
648 SinkTrace() << "No match found for merging, creating a new folder"; 703 SinkTraceCtx(mLogCtx) << "No match found for merging, creating a new folder";
649 return imap->createSubfolder(parentFolder, folder.getName()) 704 return imap->createSubfolder(parentFolder, folder.getName())
650 .then([imap, rid](const QString &createdFolder) { 705 .then([this, imap, rid](const QString &createdFolder) {
651 SinkTrace() << "Finished creating a new folder: " << createdFolder; 706 SinkTraceCtx(mLogCtx) << "Finished creating a new folder: " << createdFolder;
652 *rid = createdFolder.toUtf8(); 707 *rid = createdFolder.toUtf8();
653 }); 708 });
654 709
@@ -659,18 +714,18 @@ public:
659 return mergeJob; 714 return mergeJob;
660 } 715 }
661 } else if (operation == Sink::Operation_Removal) { 716 } else if (operation == Sink::Operation_Removal) {
662 SinkTrace() << "Removing a folder: " << oldRemoteId; 717 SinkTraceCtx(mLogCtx) << "Removing a folder: " << oldRemoteId;
663 return login.then(imap->remove(oldRemoteId)) 718 return login.then(imap->remove(oldRemoteId))
664 .then([oldRemoteId, imap] { 719 .then([this, oldRemoteId, imap] {
665 SinkTrace() << "Finished removing a folder: " << oldRemoteId; 720 SinkTraceCtx(mLogCtx) << "Finished removing a folder: " << oldRemoteId;
666 return QByteArray(); 721 return QByteArray();
667 }); 722 });
668 } else if (operation == Sink::Operation_Modification) { 723 } else if (operation == Sink::Operation_Modification) {
669 SinkTrace() << "Renaming a folder: " << oldRemoteId << folder.getName(); 724 SinkTraceCtx(mLogCtx) << "Renaming a folder: " << oldRemoteId << folder.getName();
670 auto rid = QSharedPointer<QByteArray>::create(); 725 auto rid = QSharedPointer<QByteArray>::create();
671 return login.then(imap->renameSubfolder(oldRemoteId, folder.getName())) 726 return login.then(imap->renameSubfolder(oldRemoteId, folder.getName()))
672 .then([imap, rid](const QString &createdFolder) { 727 .then([this, imap, rid](const QString &createdFolder) {
673 SinkTrace() << "Finished renaming a folder: " << createdFolder; 728 SinkTraceCtx(mLogCtx) << "Finished renaming a folder: " << createdFolder;
674 *rid = createdFolder.toUtf8(); 729 *rid = createdFolder.toUtf8();
675 }) 730 })
676 .then([rid] { 731 .then([rid] {
@@ -685,6 +740,7 @@ public:
685 int mPort; 740 int mPort;
686 QString mUser; 741 QString mUser;
687 QString mPassword; 742 QString mPassword;
743 int mDaysToSync = 0;
688 QByteArray mResourceInstanceIdentifier; 744 QByteArray mResourceInstanceIdentifier;
689 Imap::SessionCache mSessionCache; 745 Imap::SessionCache mSessionCache;
690}; 746};
@@ -864,6 +920,7 @@ ImapResource::ImapResource(const ResourceContext &resourceContext)
864 synchronizer->mPort = port; 920 synchronizer->mPort = port;
865 synchronizer->mUser = user; 921 synchronizer->mUser = user;
866 synchronizer->mPassword = password; 922 synchronizer->mPassword = password;
923 synchronizer->mDaysToSync = 14;
867 setupSynchronizer(synchronizer); 924 setupSynchronizer(synchronizer);
868 925
869 auto inspector = QSharedPointer<ImapInspector>::create(resourceContext); 926 auto inspector = QSharedPointer<ImapInspector>::create(resourceContext);
@@ -873,7 +930,7 @@ ImapResource::ImapResource(const ResourceContext &resourceContext)
873 inspector->mPassword = password; 930 inspector->mPassword = password;
874 setupInspector(inspector); 931 setupInspector(inspector);
875 932
876 setupPreprocessors(ENTITY_TYPE_MAIL, QVector<Sink::Preprocessor*>() << new SpecialPurposeProcessor(resourceContext.resourceType, resourceContext.instanceId()) << new MailPropertyExtractor); 933 setupPreprocessors(ENTITY_TYPE_MAIL, QVector<Sink::Preprocessor*>() << new SpecialPurposeProcessor << new MailPropertyExtractor);
877 setupPreprocessors(ENTITY_TYPE_FOLDER, QVector<Sink::Preprocessor*>()); 934 setupPreprocessors(ENTITY_TYPE_FOLDER, QVector<Sink::Preprocessor*>());
878} 935}
879 936
@@ -898,14 +955,14 @@ Sink::Resource *ImapResourceFactory::createResource(const ResourceContext &conte
898 955
899void ImapResourceFactory::registerFacades(const QByteArray &name, Sink::FacadeFactory &factory) 956void ImapResourceFactory::registerFacades(const QByteArray &name, Sink::FacadeFactory &factory)
900{ 957{
901 factory.registerFacade<Sink::ApplicationDomain::Mail, ImapResourceMailFacade>(name); 958 factory.registerFacade<ApplicationDomain::Mail, DefaultFacade<ApplicationDomain::Mail>>(name);
902 factory.registerFacade<Sink::ApplicationDomain::Folder, ImapResourceFolderFacade>(name); 959 factory.registerFacade<ApplicationDomain::Folder, DefaultFacade<ApplicationDomain::Folder>>(name);
903} 960}
904 961
905void ImapResourceFactory::registerAdaptorFactories(const QByteArray &name, Sink::AdaptorFactoryRegistry &registry) 962void ImapResourceFactory::registerAdaptorFactories(const QByteArray &name, Sink::AdaptorFactoryRegistry &registry)
906{ 963{
907 registry.registerFactory<Sink::ApplicationDomain::Mail, ImapMailAdaptorFactory>(name); 964 registry.registerFactory<ApplicationDomain::Mail, DefaultAdaptorFactory<ApplicationDomain::Mail>>(name);
908 registry.registerFactory<Sink::ApplicationDomain::Folder, ImapFolderAdaptorFactory>(name); 965 registry.registerFactory<ApplicationDomain::Folder, DefaultAdaptorFactory<ApplicationDomain::Folder>>(name);
909} 966}
910 967
911void ImapResourceFactory::removeDataFromDisk(const QByteArray &instanceIdentifier) 968void ImapResourceFactory::removeDataFromDisk(const QByteArray &instanceIdentifier)
diff --git a/examples/imapresource/imapserverproxy.cpp b/examples/imapresource/imapserverproxy.cpp
index dabdd8e..0cc43b8 100644
--- a/examples/imapresource/imapserverproxy.cpp
+++ b/examples/imapresource/imapserverproxy.cpp
@@ -69,7 +69,7 @@ static KAsync::Job<T> runJob(KJob *job, const std::function<T(KJob*)> &f)
69 QObject::connect(job, &KJob::result, [&future, f](KJob *job) { 69 QObject::connect(job, &KJob::result, [&future, f](KJob *job) {
70 SinkTrace() << "Job done: " << job->metaObject()->className(); 70 SinkTrace() << "Job done: " << job->metaObject()->className();
71 if (job->error()) { 71 if (job->error()) {
72 SinkWarning() << "Job failed: " << job->errorString(); 72 SinkWarning() << "Job failed: " << job->errorString() << job->metaObject()->className();
73 future.setError(job->error(), job->errorString()); 73 future.setError(job->error(), job->errorString());
74 } else { 74 } else {
75 future.setValue(f(job)); 75 future.setValue(f(job));
@@ -87,7 +87,7 @@ static KAsync::Job<void> runJob(KJob *job)
87 QObject::connect(job, &KJob::result, [&future](KJob *job) { 87 QObject::connect(job, &KJob::result, [&future](KJob *job) {
88 SinkTrace() << "Job done: " << job->metaObject()->className(); 88 SinkTrace() << "Job done: " << job->metaObject()->className();
89 if (job->error()) { 89 if (job->error()) {
90 SinkWarning() << "Job failed: " << job->errorString(); 90 SinkWarning() << "Job failed: " << job->errorString() << job->metaObject()->className();
91 future.setError(job->error(), job->errorString()); 91 future.setError(job->error(), job->errorString());
92 } else { 92 } else {
93 future.setFinished(); 93 future.setFinished();
@@ -159,6 +159,16 @@ KAsync::Job<void> ImapServerProxy::login(const QString &username, const QString
159 // SinkTrace() << "Found personal namespaces: " << mNamespaces.personal; 159 // SinkTrace() << "Found personal namespaces: " << mNamespaces.personal;
160 // SinkTrace() << "Found shared namespaces: " << mNamespaces.shared; 160 // SinkTrace() << "Found shared namespaces: " << mNamespaces.shared;
161 // SinkTrace() << "Found user namespaces: " << mNamespaces.user; 161 // SinkTrace() << "Found user namespaces: " << mNamespaces.user;
162 }).then([=] (const KAsync::Error &error) {
163 if (error) {
164 if (error.errorCode == KIMAP2::LoginJob::ErrorCode::ERR_COULD_NOT_CONNECT) {
165 return KAsync::error(CouldNotConnectError, "Failed to connect: " + error.errorMessage);
166 } else if (error.errorCode == KIMAP2::LoginJob::ErrorCode::ERR_SSL_HANDSHAKE_FAILED) {
167 return KAsync::error(SslHandshakeError, "Ssl handshake failed: " + error.errorMessage);
168 }
169 return KAsync::error(error);
170 }
171 return KAsync::null();
162 }); 172 });
163} 173}
164 174
diff --git a/examples/imapresource/imapserverproxy.h b/examples/imapresource/imapserverproxy.h
index 6eb47ee..872f032 100644
--- a/examples/imapresource/imapserverproxy.h
+++ b/examples/imapresource/imapserverproxy.h
@@ -29,6 +29,12 @@
29 29
30namespace Imap { 30namespace Imap {
31 31
32enum ErrorCode {
33 NoError,
34 CouldNotConnectError,
35 SslHandshakeError
36};
37
32namespace Flags 38namespace Flags
33{ 39{
34 /// The flag for a message being seen (i.e. opened by user). 40 /// The flag for a message being seen (i.e. opened by user).