summaryrefslogtreecommitdiffstats
path: root/examples/maildirresource/maildirresource.cpp
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-11-28 19:33:01 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2016-11-28 19:33:01 +0100
commit938554f267193b652478fc12343819fa45d76034 (patch)
tree1c027f97f3209571740377f1d4b7e6721d8de777 /examples/maildirresource/maildirresource.cpp
parent885f185f55249a2e97e9c7c238f89a5d0d99d1df (diff)
downloadsink-938554f267193b652478fc12343819fa45d76034.tar.gz
sink-938554f267193b652478fc12343819fa45d76034.zip
Moved inspection commands to a separate inspector.
Diffstat (limited to 'examples/maildirresource/maildirresource.cpp')
-rw-r--r--examples/maildirresource/maildirresource.cpp185
1 files changed, 98 insertions, 87 deletions
diff --git a/examples/maildirresource/maildirresource.cpp b/examples/maildirresource/maildirresource.cpp
index ee84bde..2b19789 100644
--- a/examples/maildirresource/maildirresource.cpp
+++ b/examples/maildirresource/maildirresource.cpp
@@ -27,6 +27,7 @@
27#include "libmaildir/maildir.h" 27#include "libmaildir/maildir.h"
28#include "inspection.h" 28#include "inspection.h"
29#include "synchronizer.h" 29#include "synchronizer.h"
30#include "inspector.h"
30 31
31#include "facadefactory.h" 32#include "facadefactory.h"
32#include "adaptorfactoryregistry.h" 33#include "adaptorfactoryregistry.h"
@@ -425,6 +426,102 @@ public:
425 QString mMaildirPath; 426 QString mMaildirPath;
426}; 427};
427 428
429class MaildirInspector : public Sink::Inspector {
430public:
431 MaildirInspector(const Sink::ResourceContext &resourceContext)
432 : Sink::Inspector(resourceContext)
433 {
434
435 }
436protected:
437
438 KAsync::Job<void> inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE {
439 auto synchronizationStore = QSharedPointer<Sink::Storage::DataStore>::create(Sink::storageLocation(), mResourceContext.instanceId() + ".synchronization", Sink::Storage::DataStore::ReadOnly);
440 auto synchronizationTransaction = synchronizationStore->createTransaction(Sink::Storage::DataStore::ReadOnly);
441
442 auto mainStore = QSharedPointer<Sink::Storage::DataStore>::create(Sink::storageLocation(), mResourceContext.instanceId(), Sink::Storage::DataStore::ReadOnly);
443 auto transaction = mainStore->createTransaction(Sink::Storage::DataStore::ReadOnly);
444
445 Sink::Storage::EntityStore entityStore(mResourceContext);
446 auto syncStore = QSharedPointer<RemoteIdMap>::create(synchronizationTransaction);
447
448 SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << property << expectedValue;
449
450 if (domainType == ENTITY_TYPE_MAIL) {
451 auto mail = entityStore.readLatest<Sink::ApplicationDomain::Mail>(entityId);
452 const auto filePath = getFilePathFromMimeMessagePath(mail.getMimeMessagePath());
453
454 if (inspectionType == Sink::ResourceControl::Inspection::PropertyInspectionType) {
455 if (property == "unread") {
456 const auto flags = KPIM::Maildir::readEntryFlags(filePath.split('/').last());
457 if (expectedValue.toBool() && (flags & KPIM::Maildir::Seen)) {
458 return KAsync::error<void>(1, "Expected unread but couldn't find it.");
459 }
460 if (!expectedValue.toBool() && !(flags & KPIM::Maildir::Seen)) {
461 return KAsync::error<void>(1, "Expected read but couldn't find it.");
462 }
463 return KAsync::null<void>();
464 }
465 if (property == "subject") {
466 KMime::Message *msg = new KMime::Message;
467 msg->setHead(KMime::CRLFtoLF(KPIM::Maildir::readEntryHeadersFromFile(filePath)));
468 msg->parse();
469
470 if (msg->subject(true)->asUnicodeString() != expectedValue.toString()) {
471 return KAsync::error<void>(1, "Subject not as expected: " + msg->subject(true)->asUnicodeString());
472 }
473 return KAsync::null<void>();
474 }
475 }
476 if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) {
477 if (QFileInfo(filePath).exists() != expectedValue.toBool()) {
478 return KAsync::error<void>(1, "Wrong file existence: " + filePath);
479 }
480 }
481 }
482 if (domainType == ENTITY_TYPE_FOLDER) {
483 const auto remoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, entityId);
484 auto folder = entityStore.readLatest<Sink::ApplicationDomain::Folder>(entityId);
485
486 if (inspectionType == Sink::ResourceControl::Inspection::CacheIntegrityInspectionType) {
487 SinkTrace() << "Inspecting cache integrity" << remoteId;
488 if (!QDir(remoteId).exists()) {
489 return KAsync::error<void>(1, "The directory is not existing: " + remoteId);
490 }
491
492 int expectedCount = 0;
493 Index index("mail.index.folder", transaction);
494 index.lookup(entityId, [&](const QByteArray &sinkId) {
495 expectedCount++;
496 },
497 [&](const Index::Error &error) {
498 SinkWarning() << "Error in index: " << error.message << property;
499 });
500
501 QDir dir(remoteId + "/cur");
502 const QFileInfoList list = dir.entryInfoList(QDir::Files);
503 if (list.size() != expectedCount) {
504 for (const auto &fileInfo : list) {
505 SinkWarning() << "Found in cache: " << fileInfo.fileName();
506 }
507 return KAsync::error<void>(1, QString("Wrong number of files; found %1 instead of %2.").arg(list.size()).arg(expectedCount));
508 }
509 }
510 if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) {
511 if (!remoteId.endsWith(folder.getName().toUtf8())) {
512 return KAsync::error<void>(1, "Wrong folder name: " + remoteId);
513 }
514 //TODO we shouldn't use the remoteId here to figure out the path, it could be gone/changed already
515 if (QDir(remoteId).exists() != expectedValue.toBool()) {
516 return KAsync::error<void>(1, "Wrong folder existence: " + remoteId);
517 }
518 }
519
520 }
521 return KAsync::null<void>();
522 }
523};
524
428 525
429MaildirResource::MaildirResource(const Sink::ResourceContext &resourceContext) 526MaildirResource::MaildirResource(const Sink::ResourceContext &resourceContext)
430 : Sink::GenericResource(resourceContext) 527 : Sink::GenericResource(resourceContext)
@@ -439,6 +536,7 @@ MaildirResource::MaildirResource(const Sink::ResourceContext &resourceContext)
439 auto synchronizer = QSharedPointer<MaildirSynchronizer>::create(resourceContext); 536 auto synchronizer = QSharedPointer<MaildirSynchronizer>::create(resourceContext);
440 synchronizer->mMaildirPath = mMaildirPath; 537 synchronizer->mMaildirPath = mMaildirPath;
441 setupSynchronizer(synchronizer); 538 setupSynchronizer(synchronizer);
539 setupInspector(QSharedPointer<MaildirInspector>::create(resourceContext));
442 540
443 setupPreprocessors(ENTITY_TYPE_MAIL, QVector<Sink::Preprocessor*>() << new SpecialPurposeProcessor(resourceContext.resourceType, resourceContext.instanceId()) << new MaildirMimeMessageMover(resourceContext.instanceId(), mMaildirPath) << new MaildirMailPropertyExtractor); 541 setupPreprocessors(ENTITY_TYPE_MAIL, QVector<Sink::Preprocessor*>() << new SpecialPurposeProcessor(resourceContext.resourceType, resourceContext.instanceId()) << new MaildirMimeMessageMover(resourceContext.instanceId(), mMaildirPath) << new MaildirMailPropertyExtractor);
444 setupPreprocessors(ENTITY_TYPE_FOLDER, QVector<Sink::Preprocessor*>() << new FolderPreprocessor(mMaildirPath)); 542 setupPreprocessors(ENTITY_TYPE_FOLDER, QVector<Sink::Preprocessor*>() << new FolderPreprocessor(mMaildirPath));
@@ -458,93 +556,6 @@ MaildirResource::MaildirResource(const Sink::ResourceContext &resourceContext)
458 synchronizer->commit(); 556 synchronizer->commit();
459} 557}
460 558
461KAsync::Job<void> MaildirResource::inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue)
462{
463 auto synchronizationStore = QSharedPointer<Sink::Storage::DataStore>::create(Sink::storageLocation(), mResourceContext.instanceId() + ".synchronization", Sink::Storage::DataStore::ReadOnly);
464 auto synchronizationTransaction = synchronizationStore->createTransaction(Sink::Storage::DataStore::ReadOnly);
465
466 auto mainStore = QSharedPointer<Sink::Storage::DataStore>::create(Sink::storageLocation(), mResourceContext.instanceId(), Sink::Storage::DataStore::ReadOnly);
467 auto transaction = mainStore->createTransaction(Sink::Storage::DataStore::ReadOnly);
468
469 Sink::Storage::EntityStore entityStore(mResourceContext);
470 auto syncStore = QSharedPointer<RemoteIdMap>::create(synchronizationTransaction);
471
472 SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << property << expectedValue;
473
474 if (domainType == ENTITY_TYPE_MAIL) {
475 auto mail = entityStore.readLatest<Sink::ApplicationDomain::Mail>(entityId);
476 const auto filePath = getFilePathFromMimeMessagePath(mail.getMimeMessagePath());
477
478 if (inspectionType == Sink::ResourceControl::Inspection::PropertyInspectionType) {
479 if (property == "unread") {
480 const auto flags = KPIM::Maildir::readEntryFlags(filePath.split('/').last());
481 if (expectedValue.toBool() && (flags & KPIM::Maildir::Seen)) {
482 return KAsync::error<void>(1, "Expected unread but couldn't find it.");
483 }
484 if (!expectedValue.toBool() && !(flags & KPIM::Maildir::Seen)) {
485 return KAsync::error<void>(1, "Expected read but couldn't find it.");
486 }
487 return KAsync::null<void>();
488 }
489 if (property == "subject") {
490 KMime::Message *msg = new KMime::Message;
491 msg->setHead(KMime::CRLFtoLF(KPIM::Maildir::readEntryHeadersFromFile(filePath)));
492 msg->parse();
493
494 if (msg->subject(true)->asUnicodeString() != expectedValue.toString()) {
495 return KAsync::error<void>(1, "Subject not as expected: " + msg->subject(true)->asUnicodeString());
496 }
497 return KAsync::null<void>();
498 }
499 }
500 if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) {
501 if (QFileInfo(filePath).exists() != expectedValue.toBool()) {
502 return KAsync::error<void>(1, "Wrong file existence: " + filePath);
503 }
504 }
505 }
506 if (domainType == ENTITY_TYPE_FOLDER) {
507 const auto remoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, entityId);
508 auto folder = entityStore.readLatest<Sink::ApplicationDomain::Folder>(entityId);
509
510 if (inspectionType == Sink::ResourceControl::Inspection::CacheIntegrityInspectionType) {
511 SinkTrace() << "Inspecting cache integrity" << remoteId;
512 if (!QDir(remoteId).exists()) {
513 return KAsync::error<void>(1, "The directory is not existing: " + remoteId);
514 }
515
516 int expectedCount = 0;
517 Index index("mail.index.folder", transaction);
518 index.lookup(entityId, [&](const QByteArray &sinkId) {
519 expectedCount++;
520 },
521 [&](const Index::Error &error) {
522 SinkWarning() << "Error in index: " << error.message << property;
523 });
524
525 QDir dir(remoteId + "/cur");
526 const QFileInfoList list = dir.entryInfoList(QDir::Files);
527 if (list.size() != expectedCount) {
528 for (const auto &fileInfo : list) {
529 SinkWarning() << "Found in cache: " << fileInfo.fileName();
530 }
531 return KAsync::error<void>(1, QString("Wrong number of files; found %1 instead of %2.").arg(list.size()).arg(expectedCount));
532 }
533 }
534 if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) {
535 if (!remoteId.endsWith(folder.getName().toUtf8())) {
536 return KAsync::error<void>(1, "Wrong folder name: " + remoteId);
537 }
538 //TODO we shouldn't use the remoteId here to figure out the path, it could be gone/changed already
539 if (QDir(remoteId).exists() != expectedValue.toBool()) {
540 return KAsync::error<void>(1, "Wrong folder existence: " + remoteId);
541 }
542 }
543
544 }
545 return KAsync::null<void>();
546}
547
548 559
549MaildirResourceFactory::MaildirResourceFactory(QObject *parent) 560MaildirResourceFactory::MaildirResourceFactory(QObject *parent)
550 : Sink::ResourceFactory(parent) 561 : Sink::ResourceFactory(parent)