From 71d0162843556c365444ae7b5da761d0795f349e Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Mon, 24 Jul 2017 04:58:29 +0200 Subject: Progress reporting for the DAV resource, and commit after 5 items. Otherwise seemingly nothing will happen in the UI, and then suddenly all items will appear. --- examples/davresource/davresource.cpp | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'examples') diff --git a/examples/davresource/davresource.cpp b/examples/davresource/davresource.cpp index 465220f..4e94046 100644 --- a/examples/davresource/davresource.cpp +++ b/examples/davresource/davresource.cpp @@ -93,7 +93,7 @@ public: QVector ridList; for(const auto &f : addressbookList) { const auto &rid = getRid(f); - SinkTrace() << "Found addressbook:" << rid; + SinkLog() << "Found addressbook:" << rid << f.displayName(); ridList.append(rid); createAddressbook(f.displayName(), rid, ""); } @@ -138,19 +138,21 @@ public: if (error) { SinkWarningCtx(mLogCtx) << "Failed to synchronize addressbooks." << collectionsFetchJob->errorString(); } else { - synchronizeAddressbooks(collectionsFetchJob ->collections()); + synchronizeAddressbooks(collectionsFetchJob->collections()); } }); return job; } else if (query.type() == ApplicationDomain::getTypeName()) { SinkLogCtx(mLogCtx) << "Synchronizing contacts."; auto ridList = QSharedPointer::create(); + auto total = QSharedPointer::create(0); + auto progress = QSharedPointer::create(0); auto collectionsFetchJob = new KDAV2::DavCollectionsFetchJob(mResourceUrl); auto job = runJob(collectionsFetchJob).then([this, collectionsFetchJob] { synchronizeAddressbooks(collectionsFetchJob ->collections()); return collectionsFetchJob->collections(); }) - .serialEach([this, ridList](const KDAV2::DavCollection &collection) { + .serialEach([=](const KDAV2::DavCollection &collection) { auto collId = getRid(collection); const auto addressbookLocalId = syncStore().resolveRemoteId(ENTITY_TYPE_ADDRESSBOOK, collId); auto ctag = collection.CTag().toLatin1(); @@ -158,10 +160,11 @@ public: SinkTraceCtx(mLogCtx) << "Syncing " << collId; auto cache = std::shared_ptr(new KDAV2::EtagCache()); auto davItemsListJob = new KDAV2::DavItemsListJob(collection.url(), cache); - const QByteArray bufferType = ENTITY_TYPE_CONTACT; QHash mergeCriteria; - auto colljob = runJob(davItemsListJob).then([davItemsListJob] { - return KAsync::value(davItemsListJob->items()); + auto colljob = runJob(davItemsListJob).then([=] { + const auto items = davItemsListJob->items(); + *total = items.size(); + return KAsync::value(items); }) .serialEach([=] (const KDAV2::DavItem &item) { QByteArray rid = getRid(item); @@ -175,13 +178,19 @@ public: Sink::ApplicationDomain::Contact contact; contact.setVcard(item.data()); contact.setAddressbook(addressbookLocalId); - createOrModify(bufferType, rid, contact, mergeCriteria); + createOrModify(ENTITY_TYPE_CONTACT, rid, contact, mergeCriteria); return item; }) - .then([this, ridList] (const KDAV2::DavItem &item) { + .then([=] (const KDAV2::DavItem &item) { const auto rid = getRid(item); syncStore().writeValue(rid + "_etag", item.etag().toLatin1()); ridList->append(rid); + *progress += 1; + reportProgress(*progress, *total, QByteArrayList{} << addressbookLocalId); + //commit every 5 contacts (so contacts start appearing in the UI) + if ((*progress % 5) == 0) { + commit(); + } return rid; }); return itemjob; @@ -190,7 +199,7 @@ public: return KAsync::value(rid); } }) - .then([this, collId, ctag] () { + .then([=] () { syncStore().writeValue(collId + "_ctag", ctag); }); return colljob; -- cgit v1.2.3 From 9e6952baf64b51fa7ddb6ac91d4ce79ebfd2b2df Mon Sep 17 00:00:00 2001 From: Heiko Becker Date: Sat, 13 May 2017 00:11:45 +0200 Subject: Use imported targets instead of qt5_use_modules From Qt's documentation: "This macro is obsolete. Use target_link_libraries with IMPORTED targets instead." It's only recommended with cmake >=2.8.9 & < 2.8.12. Sink already requires cmake 3.0. One advantage of using the imported targets is, that cmake complains if a target isn't found before it's used, like Qt5Concurrent missing from the find_package_call here. Reviewers: #sink, cmollekopf Reviewed By: #sink, cmollekopf Subscribers: #sink Tags: #sink Differential Revision: https://phabricator.kde.org/D6361 --- examples/davresource/CMakeLists.txt | 3 +-- examples/dummyresource/CMakeLists.txt | 3 +-- examples/imapresource/CMakeLists.txt | 3 +-- examples/maildirresource/CMakeLists.txt | 3 +-- examples/mailtransportresource/CMakeLists.txt | 18 ++++++++++++++---- 5 files changed, 18 insertions(+), 12 deletions(-) (limited to 'examples') diff --git a/examples/davresource/CMakeLists.txt b/examples/davresource/CMakeLists.txt index 7091edc..2351ecd 100644 --- a/examples/davresource/CMakeLists.txt +++ b/examples/davresource/CMakeLists.txt @@ -6,7 +6,6 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) find_package(KPimKDAV2 REQUIRED) add_library(${PROJECT_NAME} SHARED davresource.cpp) -qt5_use_modules(${PROJECT_NAME} Core Network) -target_link_libraries(${PROJECT_NAME} sink KPim::KDAV2) +target_link_libraries(${PROJECT_NAME} sink Qt5::Core Qt5::Network KPim::KDAV2) install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${SINK_RESOURCE_PLUGINS_PATH}) diff --git a/examples/dummyresource/CMakeLists.txt b/examples/dummyresource/CMakeLists.txt index 2bbaa47..62e96f1 100644 --- a/examples/dummyresource/CMakeLists.txt +++ b/examples/dummyresource/CMakeLists.txt @@ -6,7 +6,6 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) add_library(${PROJECT_NAME} SHARED resourcefactory.cpp domainadaptor.cpp dummystore.cpp) generate_flatbuffers(${PROJECT_NAME} dummycalendar) -qt5_use_modules(${PROJECT_NAME} Core Network) -target_link_libraries(${PROJECT_NAME} sink) +target_link_libraries(${PROJECT_NAME} sink Qt5::Core Qt5::Network) install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${SINK_RESOURCE_PLUGINS_PATH}) diff --git a/examples/imapresource/CMakeLists.txt b/examples/imapresource/CMakeLists.txt index 5d2d38b..f5f51f8 100644 --- a/examples/imapresource/CMakeLists.txt +++ b/examples/imapresource/CMakeLists.txt @@ -9,8 +9,7 @@ find_package(KIMAP2 0.2 REQUIRED) include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) add_library(${PROJECT_NAME} SHARED imapresource.cpp imapserverproxy.cpp) -qt5_use_modules(${PROJECT_NAME} Core Network) -target_link_libraries(${PROJECT_NAME} sink KF5::Mime KIMAP2) +target_link_libraries(${PROJECT_NAME} sink Qt5::Core Qt5::Network KF5::Mime KIMAP2) install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${SINK_RESOURCE_PLUGINS_PATH}) diff --git a/examples/maildirresource/CMakeLists.txt b/examples/maildirresource/CMakeLists.txt index a8f0359..690817e 100644 --- a/examples/maildirresource/CMakeLists.txt +++ b/examples/maildirresource/CMakeLists.txt @@ -6,8 +6,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) find_package(KF5 COMPONENTS REQUIRED Mime) add_library(${PROJECT_NAME} SHARED facade.cpp maildirresource.cpp libmaildir/maildir.cpp libmaildir/keycache.cpp) -qt5_use_modules(${PROJECT_NAME} Core Network) -target_link_libraries(${PROJECT_NAME} sink KF5::Mime) +target_link_libraries(${PROJECT_NAME} sink Qt5::Core Qt5::Network KF5::Mime) install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${SINK_RESOURCE_PLUGINS_PATH}) diff --git a/examples/mailtransportresource/CMakeLists.txt b/examples/mailtransportresource/CMakeLists.txt index 03b89db..1c34676 100644 --- a/examples/mailtransportresource/CMakeLists.txt +++ b/examples/mailtransportresource/CMakeLists.txt @@ -10,13 +10,23 @@ include_directories(${CURL_INCLUDE_DIRS}) add_library(${PROJECT_NAME} SHARED mailtransportresource.cpp mailtransport.cpp) -qt5_use_modules(${PROJECT_NAME} Core Network) -target_link_libraries(${PROJECT_NAME} sink KF5::Mime ${CURL_LIBRARIES}) +target_link_libraries(${PROJECT_NAME} + sink + Qt5::Core + Qt5::Network + KF5::Mime + ${CURL_LIBRARIES} +) install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${SINK_RESOURCE_PLUGINS_PATH}) add_executable(sink_smtp_test smtptest.cpp mailtransport.cpp) -qt5_use_modules(sink_smtp_test Core Network) -target_link_libraries(sink_smtp_test sink KF5::Mime ${CURL_LIBRARIES}) +target_link_libraries(sink_smtp_test + sink + Qt5::Core + Qt5::Network + KF5::Mime + ${CURL_LIBRARIES} +) install(TARGETS sink_smtp_test ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) add_subdirectory(tests) -- cgit v1.2.3 From 2f38db2da3ccd93d21fa8326bfdc6bd8b115ef70 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Fri, 11 Aug 2017 20:08:49 -0600 Subject: Replaying a change without remoteid is not going to work. --- examples/imapresource/imapresource.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'examples') diff --git a/examples/imapresource/imapresource.cpp b/examples/imapresource/imapresource.cpp index 81c808b..96055b4 100644 --- a/examples/imapresource/imapresource.cpp +++ b/examples/imapresource/imapresource.cpp @@ -619,6 +619,11 @@ public: KAsync::Job replay(const ApplicationDomain::Mail &mail, Sink::Operation operation, const QByteArray &oldRemoteId, const QList &changedProperties) Q_DECL_OVERRIDE { + if (operation != Sink::Operation_Creation) { + if(oldRemoteId.isEmpty()) { + return KAsync::error("Tried to replay modification without old remoteId."); + } + } auto imap = QSharedPointer::create(mServer, mPort, &mSessionCache); auto login = imap->login(mUser, mPassword); KAsync::Job job = KAsync::null(); -- cgit v1.2.3 From d87c789f311b7727d2db687e3891319e98ad6535 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Mon, 14 Aug 2017 09:03:24 -0600 Subject: Skip over revisions that we can't replay. --- examples/imapresource/imapresource.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/imapresource/imapresource.cpp b/examples/imapresource/imapresource.cpp index 96055b4..0c0c134 100644 --- a/examples/imapresource/imapresource.cpp +++ b/examples/imapresource/imapresource.cpp @@ -621,7 +621,11 @@ public: { if (operation != Sink::Operation_Creation) { if(oldRemoteId.isEmpty()) { - return KAsync::error("Tried to replay modification without old remoteId."); + // return KAsync::error("Tried to replay modification without old remoteId."); + qWarning() << "Tried to replay modification without old remoteId."; + // Since we can't recover from the situation we just skip over the revision. + // FIXME figure out how we can ever end up in this situation + return KAsync::null(); } } auto imap = QSharedPointer::create(mServer, mPort, &mSessionCache); -- cgit v1.2.3 From 8e14799f43ea51a6d9f195c56ca4f0c0439d4039 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Wed, 23 Aug 2017 21:07:32 -0600 Subject: The davresource has the contact.storage capability --- examples/davresource/davresource.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'examples') diff --git a/examples/davresource/davresource.cpp b/examples/davresource/davresource.cpp index 4e94046..22c502f 100644 --- a/examples/davresource/davresource.cpp +++ b/examples/davresource/davresource.cpp @@ -260,6 +260,7 @@ DavResourceFactory::DavResourceFactory(QObject *parent) : Sink::ResourceFactory(parent, {Sink::ApplicationDomain::ResourceCapabilities::Contact::contact, Sink::ApplicationDomain::ResourceCapabilities::Contact::addressbook, + Sink::ApplicationDomain::ResourceCapabilities::Contact::storage } ) { -- cgit v1.2.3 From 1ba34f8b16cd06a74ff96dfae803ce4b0521652b Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Mon, 28 Aug 2017 17:19:51 -0600 Subject: Detect connection lost so we can go to offline state kimap should really have better error codes... --- examples/imapresource/imapresource.cpp | 2 ++ examples/imapresource/imapserverproxy.cpp | 32 ++++++++++++++++--------------- examples/imapresource/imapserverproxy.h | 4 +++- 3 files changed, 22 insertions(+), 16 deletions(-) (limited to 'examples') diff --git a/examples/imapresource/imapresource.cpp b/examples/imapresource/imapresource.cpp index 0c0c134..3ae7fd7 100644 --- a/examples/imapresource/imapresource.cpp +++ b/examples/imapresource/imapresource.cpp @@ -511,6 +511,8 @@ public: return {ApplicationDomain::LoginError, error.errorMessage}; case Imap::HostNotFoundError: return {ApplicationDomain::NoServerError, error.errorMessage}; + case Imap::ConnectionLost: + return {ApplicationDomain::ConnectionLostError, error.errorMessage}; default: return {ApplicationDomain::UnknownError, error.errorMessage}; } diff --git a/examples/imapresource/imapserverproxy.cpp b/examples/imapresource/imapserverproxy.cpp index 538105c..a0f0970 100644 --- a/examples/imapresource/imapserverproxy.cpp +++ b/examples/imapresource/imapserverproxy.cpp @@ -80,6 +80,21 @@ static KAsync::Job runJob(KJob *job, const std::function &f) }); } +static int translateImapError(int error) +{ + switch (error) { + case KJob::UserDefinedError: + return Imap::ConnectionLost; + case KIMAP2::LoginJob::ErrorCode::ERR_HOST_NOT_FOUND: + return Imap::HostNotFoundError; + case KIMAP2::LoginJob::ErrorCode::ERR_COULD_NOT_CONNECT: + return Imap::CouldNotConnectError; + case KIMAP2::LoginJob::ErrorCode::ERR_SSL_HANDSHAKE_FAILED: + return Imap::SslHandshakeError; + } + return Imap::UnknownError; +} + static KAsync::Job runJob(KJob *job) { return KAsync::start([job](KAsync::Future &future) { @@ -87,7 +102,8 @@ static KAsync::Job runJob(KJob *job) SinkTrace() << "Job done: " << job->metaObject()->className(); if (job->error()) { SinkWarning() << "Job failed: " << job->errorString() << job->metaObject()->className(); - future.setError(job->error(), job->errorString()); + auto proxyError = translateImapError(job->error()); + future.setError(proxyError, job->errorString()); } else { future.setFinished(); } @@ -166,20 +182,6 @@ KAsync::Job ImapServerProxy::login(const QString &username, const QString // SinkTrace() << "Found personal namespaces: " << mNamespaces.personal; // SinkTrace() << "Found shared namespaces: " << mNamespaces.shared; // SinkTrace() << "Found user namespaces: " << mNamespaces.user; - }).then([=] (const KAsync::Error &error) { - if (error) { - switch (error.errorCode) { - case KIMAP2::LoginJob::ErrorCode::ERR_HOST_NOT_FOUND: - return KAsync::error(HostNotFoundError, "Host not found: " + error.errorMessage); - case KIMAP2::LoginJob::ErrorCode::ERR_COULD_NOT_CONNECT: - return KAsync::error(CouldNotConnectError, "Failed to connect: " + error.errorMessage); - case KIMAP2::LoginJob::ErrorCode::ERR_SSL_HANDSHAKE_FAILED: - return KAsync::error(SslHandshakeError, "Ssl handshake failed: " + error.errorMessage); - default: - return KAsync::error(error); - } - } - return KAsync::null(); }); } diff --git a/examples/imapresource/imapserverproxy.h b/examples/imapresource/imapserverproxy.h index 82f4f58..f9b854b 100644 --- a/examples/imapresource/imapserverproxy.h +++ b/examples/imapresource/imapserverproxy.h @@ -33,7 +33,9 @@ enum ErrorCode { NoError, HostNotFoundError, CouldNotConnectError, - SslHandshakeError + SslHandshakeError, + ConnectionLost, + UnknownError }; namespace Flags -- cgit v1.2.3 From be19bfef2d04943aa17b3f719f50f34f647c4eeb Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Mon, 28 Aug 2017 21:21:44 -0600 Subject: Translate the error in both runJob overloads. --- examples/imapresource/imapserverproxy.cpp | 33 ++++++++++++++++--------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'examples') diff --git a/examples/imapresource/imapserverproxy.cpp b/examples/imapresource/imapserverproxy.cpp index a0f0970..5c2e07c 100644 --- a/examples/imapresource/imapserverproxy.cpp +++ b/examples/imapresource/imapserverproxy.cpp @@ -61,6 +61,21 @@ const char* Imap::Capabilities::Namespace = "NAMESPACE"; const char* Imap::Capabilities::Uidplus = "UIDPLUS"; const char* Imap::Capabilities::Condstore = "CONDSTORE"; +static int translateImapError(int error) +{ + switch (error) { + case KJob::UserDefinedError: + return Imap::ConnectionLost; + case KIMAP2::LoginJob::ErrorCode::ERR_HOST_NOT_FOUND: + return Imap::HostNotFoundError; + case KIMAP2::LoginJob::ErrorCode::ERR_COULD_NOT_CONNECT: + return Imap::CouldNotConnectError; + case KIMAP2::LoginJob::ErrorCode::ERR_SSL_HANDSHAKE_FAILED: + return Imap::SslHandshakeError; + } + return Imap::UnknownError; +} + template static KAsync::Job runJob(KJob *job, const std::function &f) { @@ -69,7 +84,8 @@ static KAsync::Job runJob(KJob *job, const std::function &f) SinkTrace() << "Job done: " << job->metaObject()->className(); if (job->error()) { SinkWarning() << "Job failed: " << job->errorString() << job->metaObject()->className(); - future.setError(job->error(), job->errorString()); + auto proxyError = translateImapError(job->error()); + future.setError(proxyError, job->errorString()); } else { future.setValue(f(job)); future.setFinished(); @@ -80,21 +96,6 @@ static KAsync::Job runJob(KJob *job, const std::function &f) }); } -static int translateImapError(int error) -{ - switch (error) { - case KJob::UserDefinedError: - return Imap::ConnectionLost; - case KIMAP2::LoginJob::ErrorCode::ERR_HOST_NOT_FOUND: - return Imap::HostNotFoundError; - case KIMAP2::LoginJob::ErrorCode::ERR_COULD_NOT_CONNECT: - return Imap::CouldNotConnectError; - case KIMAP2::LoginJob::ErrorCode::ERR_SSL_HANDSHAKE_FAILED: - return Imap::SslHandshakeError; - } - return Imap::UnknownError; -} - static KAsync::Job runJob(KJob *job) { return KAsync::start([job](KAsync::Future &future) { -- cgit v1.2.3