From 938554f267193b652478fc12343819fa45d76034 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Mon, 28 Nov 2016 19:33:01 +0100 Subject: Moved inspection commands to a separate inspector. --- examples/imapresource/imapresource.cpp | 306 ++++++++++++++++++--------------- examples/imapresource/imapresource.h | 7 - 2 files changed, 165 insertions(+), 148 deletions(-) (limited to 'examples/imapresource') diff --git a/examples/imapresource/imapresource.cpp b/examples/imapresource/imapresource.cpp index 2aa5a2c..40fa75f 100644 --- a/examples/imapresource/imapresource.cpp +++ b/examples/imapresource/imapresource.cpp @@ -27,6 +27,7 @@ #include "definitions.h" #include "inspection.h" #include "synchronizer.h" +#include "inspector.h" #include "remoteidmap.h" #include "query.h" @@ -553,169 +554,192 @@ public: QByteArray mResourceInstanceIdentifier; }; -ImapResource::ImapResource(const ResourceContext &resourceContext) - : Sink::GenericResource(resourceContext) -{ - auto config = ResourceConfig::getConfiguration(resourceContext.instanceId()); - mServer = config.value("server").toString(); - mPort = config.value("port").toInt(); - mUser = config.value("username").toString(); - mPassword = config.value("password").toString(); - if (mServer.startsWith("imap")) { - mServer.remove("imap://"); - mServer.remove("imaps://"); - } - if (mServer.contains(':')) { - auto list = mServer.split(':'); - mServer = list.at(0); - mPort = list.at(1).toInt(); - } - - auto synchronizer = QSharedPointer::create(resourceContext); - synchronizer->mServer = mServer; - synchronizer->mPort = mPort; - synchronizer->mUser = mUser; - synchronizer->mPassword = mPassword; - setupSynchronizer(synchronizer); - - setupPreprocessors(ENTITY_TYPE_MAIL, QVector() << new SpecialPurposeProcessor(resourceContext.resourceType, resourceContext.instanceId()) << new MimeMessageMover << new MailPropertyExtractor); - setupPreprocessors(ENTITY_TYPE_FOLDER, QVector()); -} +class ImapInspector : public Sink::Inspector { +public: + ImapInspector(const Sink::ResourceContext &resourceContext) + : Sink::Inspector(resourceContext) + { -KAsync::Job ImapResource::inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) -{ - auto synchronizationStore = QSharedPointer::create(Sink::storageLocation(), mResourceContext.instanceId() + ".synchronization", Sink::Storage::DataStore::ReadOnly); - auto synchronizationTransaction = synchronizationStore->createTransaction(Sink::Storage::DataStore::ReadOnly); + } - auto mainStore = QSharedPointer::create(Sink::storageLocation(), mResourceContext.instanceId(), Sink::Storage::DataStore::ReadOnly); - auto transaction = mainStore->createTransaction(Sink::Storage::DataStore::ReadOnly); +protected: + KAsync::Job inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE { + auto synchronizationStore = QSharedPointer::create(Sink::storageLocation(), mResourceContext.instanceId() + ".synchronization", Sink::Storage::DataStore::ReadOnly); + auto synchronizationTransaction = synchronizationStore->createTransaction(Sink::Storage::DataStore::ReadOnly); - Sink::Storage::EntityStore entityStore(mResourceContext); - auto syncStore = QSharedPointer::create(synchronizationTransaction); + auto mainStore = QSharedPointer::create(Sink::storageLocation(), mResourceContext.instanceId(), Sink::Storage::DataStore::ReadOnly); + auto transaction = mainStore->createTransaction(Sink::Storage::DataStore::ReadOnly); - SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << property << expectedValue; + Sink::Storage::EntityStore entityStore(mResourceContext); + auto syncStore = QSharedPointer::create(synchronizationTransaction); - if (domainType == ENTITY_TYPE_MAIL) { - const auto mail = entityStore.readLatest(entityId); - const auto folder = entityStore.readLatest(mail.getFolder()); - const auto folderRemoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, mail.getFolder()); - const auto mailRemoteId = syncStore->resolveLocalId(ENTITY_TYPE_MAIL, mail.identifier()); - if (mailRemoteId.isEmpty() || folderRemoteId.isEmpty()) { - SinkWarning() << "Missing remote id for folder or mail. " << mailRemoteId << folderRemoteId; - return KAsync::error(); - } - const auto uid = uidFromMailRid(mailRemoteId); - SinkTrace() << "Mail remote id: " << folderRemoteId << mailRemoteId << mail.identifier() << folder.identifier(); + SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << property << expectedValue; - KIMAP2::ImapSet set; - set.add(uid); - if (set.isEmpty()) { - return KAsync::error(1, "Couldn't determine uid of mail."); - } - KIMAP2::FetchJob::FetchScope scope; - scope.mode = KIMAP2::FetchJob::FetchScope::Full; - auto imap = QSharedPointer::create(mServer, mPort); - auto messageByUid = QSharedPointer>::create(); - SinkTrace() << "Connecting to:" << mServer << mPort; - SinkTrace() << "as:" << mUser; - auto inspectionJob = imap->login(mUser, mPassword) - .then(imap->select(folderRemoteId)) - .syncThen([](Imap::SelectResult){}) - .then(imap->fetch(set, scope, [imap, messageByUid](const Imap::Message &message) { - messageByUid->insert(message.uid, message); - })); - - if (inspectionType == Sink::ResourceControl::Inspection::PropertyInspectionType) { - if (property == "unread") { - return inspectionJob.then([=]() { - auto msg = messageByUid->value(uid); - if (expectedValue.toBool() && msg.flags.contains(Imap::Flags::Seen)) { - return KAsync::error(1, "Expected unread but couldn't find it."); - } - if (!expectedValue.toBool() && !msg.flags.contains(Imap::Flags::Seen)) { - return KAsync::error(1, "Expected read but couldn't find it."); - } - return KAsync::null(); - }); - } - if (property == "subject") { - return inspectionJob.then([=]() { - auto msg = messageByUid->value(uid); - if (msg.msg->subject(true)->asUnicodeString() != expectedValue.toString()) { - return KAsync::error(1, "Subject not as expected: " + msg.msg->subject(true)->asUnicodeString()); - } - return KAsync::null(); - }); + if (domainType == ENTITY_TYPE_MAIL) { + const auto mail = entityStore.readLatest(entityId); + const auto folder = entityStore.readLatest(mail.getFolder()); + const auto folderRemoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, mail.getFolder()); + const auto mailRemoteId = syncStore->resolveLocalId(ENTITY_TYPE_MAIL, mail.identifier()); + if (mailRemoteId.isEmpty() || folderRemoteId.isEmpty()) { + SinkWarning() << "Missing remote id for folder or mail. " << mailRemoteId << folderRemoteId; + return KAsync::error(); } - } - if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { - return inspectionJob.then([=]() { - if (!messageByUid->contains(uid)) { - SinkWarning() << "Existing messages are: " << messageByUid->keys(); - SinkWarning() << "We're looking for: " << uid; - return KAsync::error(1, "Couldn't find message: " + mailRemoteId); - } - return KAsync::null(); - }); - } - } - if (domainType == ENTITY_TYPE_FOLDER) { - const auto remoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, entityId); - const auto folder = entityStore.readLatest(entityId); - - if (inspectionType == Sink::ResourceControl::Inspection::CacheIntegrityInspectionType) { - SinkLog() << "Inspecting cache integrity" << remoteId; + const auto uid = uidFromMailRid(mailRemoteId); + SinkTrace() << "Mail remote id: " << folderRemoteId << mailRemoteId << mail.identifier() << folder.identifier(); - int expectedCount = 0; - Index index("mail.index.folder", transaction); - index.lookup(entityId, [&](const QByteArray &sinkId) { - expectedCount++; - }, - [&](const Index::Error &error) { - SinkWarning() << "Error in index: " << error.message << property; - }); - - auto set = KIMAP2::ImapSet::fromImapSequenceSet("1:*"); + KIMAP2::ImapSet set; + set.add(uid); + if (set.isEmpty()) { + return KAsync::error(1, "Couldn't determine uid of mail."); + } KIMAP2::FetchJob::FetchScope scope; - scope.mode = KIMAP2::FetchJob::FetchScope::Headers; + scope.mode = KIMAP2::FetchJob::FetchScope::Full; auto imap = QSharedPointer::create(mServer, mPort); auto messageByUid = QSharedPointer>::create(); - return imap->login(mUser, mPassword) - .then(imap->select(remoteId).syncThen([](){})) - .then(imap->fetch(set, scope, [=](const Imap::Message message) { + SinkTrace() << "Connecting to:" << mServer << mPort; + SinkTrace() << "as:" << mUser; + auto inspectionJob = imap->login(mUser, mPassword) + .then(imap->select(folderRemoteId)) + .syncThen([](Imap::SelectResult){}) + .then(imap->fetch(set, scope, [imap, messageByUid](const Imap::Message &message) { messageByUid->insert(message.uid, message); - })) - .then([imap, messageByUid, expectedCount]() { - if (messageByUid->size() != expectedCount) { - return KAsync::error(1, QString("Wrong number of messages on the server; found %1 instead of %2.").arg(messageByUid->size()).arg(expectedCount)); + })); + + if (inspectionType == Sink::ResourceControl::Inspection::PropertyInspectionType) { + if (property == "unread") { + return inspectionJob.then([=]() { + auto msg = messageByUid->value(uid); + if (expectedValue.toBool() && msg.flags.contains(Imap::Flags::Seen)) { + return KAsync::error(1, "Expected unread but couldn't find it."); + } + if (!expectedValue.toBool() && !msg.flags.contains(Imap::Flags::Seen)) { + return KAsync::error(1, "Expected read but couldn't find it."); + } + return KAsync::null(); + }); + } + if (property == "subject") { + return inspectionJob.then([=]() { + auto msg = messageByUid->value(uid); + if (msg.msg->subject(true)->asUnicodeString() != expectedValue.toString()) { + return KAsync::error(1, "Subject not as expected: " + msg.msg->subject(true)->asUnicodeString()); + } + return KAsync::null(); + }); + } + } + if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { + return inspectionJob.then([=]() { + if (!messageByUid->contains(uid)) { + SinkWarning() << "Existing messages are: " << messageByUid->keys(); + SinkWarning() << "We're looking for: " << uid; + return KAsync::error(1, "Couldn't find message: " + mailRemoteId); } return KAsync::null(); }); + } } - if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { - auto folderByPath = QSharedPointer>::create(); - auto folderByName = QSharedPointer>::create(); + if (domainType == ENTITY_TYPE_FOLDER) { + const auto remoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, entityId); + const auto folder = entityStore.readLatest(entityId); - auto imap = QSharedPointer::create(mServer, mPort); - auto inspectionJob = imap->login(mUser, mPassword) - .then(imap->fetchFolders([=](const Imap::Folder &f) { - *folderByPath << f.normalizedPath(); - *folderByName << f.name(); - })) - .then([this, folderByName, folderByPath, folder, remoteId, imap]() { - if (!folderByName->contains(folder.getName())) { - SinkWarning() << "Existing folders are: " << *folderByPath; - SinkWarning() << "We're looking for: " << folder.getName(); - return KAsync::error(1, "Wrong folder name: " + remoteId); - } - return KAsync::null(); + if (inspectionType == Sink::ResourceControl::Inspection::CacheIntegrityInspectionType) { + SinkLog() << "Inspecting cache integrity" << remoteId; + + int expectedCount = 0; + Index index("mail.index.folder", transaction); + index.lookup(entityId, [&](const QByteArray &sinkId) { + expectedCount++; + }, + [&](const Index::Error &error) { + SinkWarning() << "Error in index: " << error.message << property; }); - return inspectionJob; + auto set = KIMAP2::ImapSet::fromImapSequenceSet("1:*"); + KIMAP2::FetchJob::FetchScope scope; + scope.mode = KIMAP2::FetchJob::FetchScope::Headers; + auto imap = QSharedPointer::create(mServer, mPort); + auto messageByUid = QSharedPointer>::create(); + return imap->login(mUser, mPassword) + .then(imap->select(remoteId).syncThen([](){})) + .then(imap->fetch(set, scope, [=](const Imap::Message message) { + messageByUid->insert(message.uid, message); + })) + .then([imap, messageByUid, expectedCount]() { + if (messageByUid->size() != expectedCount) { + return KAsync::error(1, QString("Wrong number of messages on the server; found %1 instead of %2.").arg(messageByUid->size()).arg(expectedCount)); + } + return KAsync::null(); + }); + } + if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { + auto folderByPath = QSharedPointer>::create(); + auto folderByName = QSharedPointer>::create(); + + auto imap = QSharedPointer::create(mServer, mPort); + auto inspectionJob = imap->login(mUser, mPassword) + .then(imap->fetchFolders([=](const Imap::Folder &f) { + *folderByPath << f.normalizedPath(); + *folderByName << f.name(); + })) + .then([this, folderByName, folderByPath, folder, remoteId, imap]() { + if (!folderByName->contains(folder.getName())) { + SinkWarning() << "Existing folders are: " << *folderByPath; + SinkWarning() << "We're looking for: " << folder.getName(); + return KAsync::error(1, "Wrong folder name: " + remoteId); + } + return KAsync::null(); + }); + + return inspectionJob; + } + } + return KAsync::null(); + } + +public: + QString mServer; + int mPort; + QString mUser; + QString mPassword; +}; + +ImapResource::ImapResource(const ResourceContext &resourceContext) + : Sink::GenericResource(resourceContext) +{ + auto config = ResourceConfig::getConfiguration(resourceContext.instanceId()); + auto server = config.value("server").toString(); + auto port = config.value("port").toInt(); + auto user = config.value("username").toString(); + auto password = config.value("password").toString(); + if (server.startsWith("imap")) { + server.remove("imap://"); + server.remove("imaps://"); + } + if (server.contains(':')) { + auto list = server.split(':'); + server = list.at(0); + port = list.at(1).toInt(); } - return KAsync::null(); + + auto synchronizer = QSharedPointer::create(resourceContext); + synchronizer->mServer = server; + synchronizer->mPort = port; + synchronizer->mUser = user; + synchronizer->mPassword = password; + setupSynchronizer(synchronizer); + + auto inspector = QSharedPointer::create(resourceContext); + inspector->mServer = server; + inspector->mPort = port; + inspector->mUser = user; + inspector->mPassword = password; + setupInspector(inspector); + + setupPreprocessors(ENTITY_TYPE_MAIL, QVector() << new SpecialPurposeProcessor(resourceContext.resourceType, resourceContext.instanceId()) << new MimeMessageMover << new MailPropertyExtractor); + setupPreprocessors(ENTITY_TYPE_FOLDER, QVector()); } ImapResourceFactory::ImapResourceFactory(QObject *parent) diff --git a/examples/imapresource/imapresource.h b/examples/imapresource/imapresource.h index d345d64..aeb1200 100644 --- a/examples/imapresource/imapresource.h +++ b/examples/imapresource/imapresource.h @@ -40,13 +40,6 @@ class ImapResource : public Sink::GenericResource { public: ImapResource(const Sink::ResourceContext &resourceContext); - KAsync::Job inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE; - -private: - QString mServer; - int mPort; - QString mUser; - QString mPassword; }; class ImapResourceFactory : public Sink::ResourceFactory -- cgit v1.2.3