diff options
Diffstat (limited to 'examples/imapresource/imapresource.cpp')
-rw-r--r-- | examples/imapresource/imapresource.cpp | 213 |
1 files changed, 125 insertions, 88 deletions
diff --git a/examples/imapresource/imapresource.cpp b/examples/imapresource/imapresource.cpp index 2bb28e7..4122a69 100644 --- a/examples/imapresource/imapresource.cpp +++ b/examples/imapresource/imapresource.cpp | |||
@@ -320,6 +320,73 @@ public: | |||
320 | QByteArray mResourceInstanceIdentifier; | 320 | QByteArray mResourceInstanceIdentifier; |
321 | }; | 321 | }; |
322 | 322 | ||
323 | class ImapWriteback : public Sink::SourceWriteBack | ||
324 | { | ||
325 | public: | ||
326 | ImapWriteback(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier) : Sink::SourceWriteBack(resourceType, resourceInstanceIdentifier) | ||
327 | { | ||
328 | |||
329 | } | ||
330 | |||
331 | KAsync::Job<QByteArray> replay(const ApplicationDomain::Mail &mail, Sink::Operation operation, const QByteArray &oldRemoteId) | ||
332 | { | ||
333 | return KAsync::null<QByteArray>(); | ||
334 | } | ||
335 | |||
336 | QString buildPath(const ApplicationDomain::Folder &folder) | ||
337 | { | ||
338 | //Don't use entityStore in here, it can produce wrong results we're replaying an older revision than the latest one | ||
339 | QChar separator = '/'; | ||
340 | QString path; | ||
341 | auto parent = folder.getParent(); | ||
342 | if (!parent.isEmpty()) { | ||
343 | auto parentRemoteId = syncStore().resolveLocalId("folder", parent); | ||
344 | return parentRemoteId + separator.toLatin1() + folder.getName().toUtf8(); | ||
345 | } | ||
346 | return separator + folder.getName(); | ||
347 | } | ||
348 | |||
349 | KAsync::Job<QByteArray> replay(const ApplicationDomain::Folder &folder, Sink::Operation operation, const QByteArray &oldRemoteId) | ||
350 | { | ||
351 | auto imap = QSharedPointer<ImapServerProxy>::create(mServer, mPort); | ||
352 | auto login = imap->login(mUser, mPassword); | ||
353 | if (operation == Sink::Operation_Creation) { | ||
354 | auto folderPath = buildPath(folder); | ||
355 | auto imapPath = "INBOX" + folderPath.replace('/', '.'); | ||
356 | Trace() << "Creating a new folder: " << imapPath; | ||
357 | return login.then<void>(imap->create(imapPath)) | ||
358 | .then<QByteArray>([imapPath, imap]() { | ||
359 | Trace() << "Finished creating a new folder: " << imapPath; | ||
360 | return imapPath.toUtf8(); | ||
361 | }); | ||
362 | } else if (operation == Sink::Operation_Removal) { | ||
363 | Trace() << "Removing a folder: " << oldRemoteId; | ||
364 | return login.then<void>(imap->remove(oldRemoteId)) | ||
365 | .then<QByteArray>([oldRemoteId, imap]() { | ||
366 | Trace() << "Finished removing a folder: " << oldRemoteId; | ||
367 | return QByteArray(); | ||
368 | }); | ||
369 | } else if (operation == Sink::Operation_Modification) { | ||
370 | auto newFolderPath = buildPath(folder); | ||
371 | auto newImapPath = "INBOX" + newFolderPath.replace('/', '.'); | ||
372 | Trace() << "Renaming a folder: " << oldRemoteId << newImapPath; | ||
373 | return login.then<void>(imap->rename(oldRemoteId, newImapPath)) | ||
374 | .then<QByteArray>([newImapPath, imap]() { | ||
375 | Trace() << "Finished renaming a folder: " << newImapPath; | ||
376 | return newImapPath.toUtf8(); | ||
377 | }); | ||
378 | } | ||
379 | return KAsync::null<QByteArray>(); | ||
380 | } | ||
381 | |||
382 | public: | ||
383 | QString mServer; | ||
384 | int mPort; | ||
385 | QString mUser; | ||
386 | QString mPassword; | ||
387 | QByteArray mResourceInstanceIdentifier; | ||
388 | }; | ||
389 | |||
323 | ImapResource::ImapResource(const QByteArray &instanceIdentifier, const QSharedPointer<Sink::Pipeline> &pipeline) | 390 | ImapResource::ImapResource(const QByteArray &instanceIdentifier, const QSharedPointer<Sink::Pipeline> &pipeline) |
324 | : Sink::GenericResource(PLUGIN_NAME, instanceIdentifier, pipeline) | 391 | : Sink::GenericResource(PLUGIN_NAME, instanceIdentifier, pipeline) |
325 | { | 392 | { |
@@ -336,12 +403,11 @@ ImapResource::ImapResource(const QByteArray &instanceIdentifier, const QSharedPo | |||
336 | synchronizer->mPassword = mPassword; | 403 | synchronizer->mPassword = mPassword; |
337 | synchronizer->mResourceInstanceIdentifier = instanceIdentifier; | 404 | synchronizer->mResourceInstanceIdentifier = instanceIdentifier; |
338 | setupSynchronizer(synchronizer); | 405 | setupSynchronizer(synchronizer); |
339 | auto changereplay = QSharedPointer<Sink::NullChangeReplay>::create(instanceIdentifier); | 406 | auto changereplay = QSharedPointer<ImapWriteback>::create(PLUGIN_NAME, instanceIdentifier); |
340 | // auto changereplay = QSharedPointer<ImapWriteback>::create(PLUGIN_NAME, instanceIdentifier); | 407 | changereplay->mServer = mServer; |
341 | // changereplay->mServer = mServer; | 408 | changereplay->mPort = mPort; |
342 | // changereplay->mPort = mPort; | 409 | changereplay->mUser = mUser; |
343 | // changereplay->mUser = mUser; | 410 | changereplay->mPassword = mPassword; |
344 | // changereplay->mPassword = mPassword; | ||
345 | setupChangereplay(changereplay); | 411 | setupChangereplay(changereplay); |
346 | 412 | ||
347 | setupPreprocessors(ENTITY_TYPE_MAIL, QVector<Sink::Preprocessor*>() << new MailPropertyExtractor << new DefaultIndexUpdater<Sink::ApplicationDomain::Mail>); | 413 | setupPreprocessors(ENTITY_TYPE_MAIL, QVector<Sink::Preprocessor*>() << new MailPropertyExtractor << new DefaultIndexUpdater<Sink::ApplicationDomain::Mail>); |
@@ -356,7 +422,7 @@ void ImapResource::removeFromDisk(const QByteArray &instanceIdentifier) | |||
356 | 422 | ||
357 | KAsync::Job<void> ImapResource::inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) | 423 | KAsync::Job<void> ImapResource::inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) |
358 | { | 424 | { |
359 | auto synchronizationStore = QSharedPointer<Sink::Storage>::create(Sink::storageLocation(), mResourceInstanceIdentifier + ".synchronization", Sink::Storage::ReadOnly); | 425 | auto synchronizationStore = QSharedPointer<Sink::Storage>::create(Sink::storageLocation(), mResourceInstanceIdentifier + ".synchronization", Sink::Storage::ReadOnly); |
360 | auto synchronizationTransaction = synchronizationStore->createTransaction(Sink::Storage::ReadOnly); | 426 | auto synchronizationTransaction = synchronizationStore->createTransaction(Sink::Storage::ReadOnly); |
361 | 427 | ||
362 | auto mainStore = QSharedPointer<Sink::Storage>::create(Sink::storageLocation(), mResourceInstanceIdentifier, Sink::Storage::ReadOnly); | 428 | auto mainStore = QSharedPointer<Sink::Storage>::create(Sink::storageLocation(), mResourceInstanceIdentifier, Sink::Storage::ReadOnly); |
@@ -367,87 +433,58 @@ KAsync::Job<void> ImapResource::inspect(int inspectionType, const QByteArray &in | |||
367 | 433 | ||
368 | Trace() << "Inspecting " << inspectionType << domainType << entityId << property << expectedValue; | 434 | Trace() << "Inspecting " << inspectionType << domainType << entityId << property << expectedValue; |
369 | 435 | ||
370 | // if (domainType == ENTITY_TYPE_MAIL) { | 436 | if (domainType == ENTITY_TYPE_MAIL) { |
371 | // const auto mail = entityStore->read<Sink::ApplicationDomain::Mail>(entityId); | 437 | const auto mail = entityStore->read<Sink::ApplicationDomain::Mail>(entityId); |
372 | // const auto folder = entityStore->read<Sink::ApplicationDomain::Folder>(mail.getFolder()); | 438 | const auto folder = entityStore->read<Sink::ApplicationDomain::Folder>(mail.getFolder()); |
373 | // const auto folderRemoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, mail.getFolder()); | 439 | const auto folderRemoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, mail.getFolder()); |
374 | // const auto mailRemoteId = syncStore->resolveLocalId(ENTITY_TYPE_MAIL, mail.identifier()); | 440 | const auto mailRemoteId = syncStore->resolveLocalId(ENTITY_TYPE_MAIL, mail.identifier()); |
375 | // // const auto filePath = getFilePathFromMimeMessagePath(mail.getMimeMessagePath()); | 441 | if (mailRemoteId.isEmpty() || folderRemoteId.isEmpty()) { |
376 | // ImapServerProxy imap(mServer, mPort); | 442 | KAsync::error<void>(); |
377 | // imap.login(mUser, mPassword).exec().waitForFinished(); | 443 | } |
378 | // imap.select(folderRemoteId).exec().waitForFinished(); | 444 | Trace() << "Mail remote id: " << folderRemoteId << mailRemoteId << mail.identifier() << folder.identifier(); |
379 | // KIMAP::ImapSet set; | 445 | |
380 | // set.add(mailRemoteId.toLongLong()); | 446 | if (inspectionType == Sink::ResourceControl::Inspection::PropertyInspectionType) { |
381 | // KIMAP::FetchJob::FetchScope scope; | 447 | if (property == "unread") { |
382 | // scope.mode = KIMAP::FetchJob::FetchScope::Full; | 448 | return KAsync::null<void>(); |
383 | // imap.fetch(set, scope, [](const QVector<Imap::Message> &messages) { | 449 | } |
384 | // | 450 | if (property == "subject") { |
385 | // }).exec().waitForFinished(); | 451 | return KAsync::null<void>(); |
386 | // | 452 | } |
387 | // if (inspectionType == Sink::ResourceControl::Inspection::PropertyInspectionType) { | 453 | } |
388 | // if (property == "unread") { | 454 | if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { |
389 | // // const auto flags = KPIM::Maildir::readEntryFlags(filePath.split('/').last()); | 455 | } |
390 | // // if (expectedValue.toBool() && (flags & KPIM::Maildir::Seen)) { | 456 | } |
391 | // // return KAsync::error<void>(1, "Expected unread but couldn't find it."); | 457 | if (domainType == ENTITY_TYPE_FOLDER) { |
392 | // // } | 458 | const auto remoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, entityId); |
393 | // // if (!expectedValue.toBool() && !(flags & KPIM::Maildir::Seen)) { | 459 | const auto folder = entityStore->read<Sink::ApplicationDomain::Folder>(entityId); |
394 | // // return KAsync::error<void>(1, "Expected read but couldn't find it."); | 460 | |
395 | // // } | 461 | if (inspectionType == Sink::ResourceControl::Inspection::CacheIntegrityInspectionType) { |
396 | // return KAsync::null<void>(); | 462 | } |
397 | // } | 463 | if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { |
398 | // if (property == "subject") { | 464 | auto folderByPath = QSharedPointer<QSet<QString>>::create(); |
399 | // // KMime::Message *msg = new KMime::Message; | 465 | auto folderByName = QSharedPointer<QSet<QString>>::create(); |
400 | // // msg->setHead(KMime::CRLFtoLF(KPIM::Maildir::readEntryHeadersFromFile(filePath))); | 466 | |
401 | // // msg->parse(); | 467 | auto imap = QSharedPointer<ImapServerProxy>::create(mServer, mPort); |
402 | // // | 468 | auto inspectionJob = imap->login(mUser, mPassword) |
403 | // // if (msg->subject(true)->asUnicodeString() != expectedValue.toString()) { | 469 | .then<void>(imap->fetchFolders([=](const QVector<Imap::Folder> &folders) { |
404 | // // return KAsync::error<void>(1, "Subject not as expected: " + msg->subject(true)->asUnicodeString()); | 470 | for (const auto &f : folders) { |
405 | // // } | 471 | *folderByPath << f.normalizedPath(); |
406 | // return KAsync::null<void>(); | 472 | *folderByName << f.pathParts.last(); |
407 | // } | 473 | } |
408 | // } | 474 | })) |
409 | // if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { | 475 | .then<void, KAsync::Job<void>>([folderByName, folderByPath, folder, remoteId, imap]() { |
410 | // // if (QFileInfo(filePath).exists() != expectedValue.toBool()) { | 476 | if (!folderByName->contains(folder.getName())) { |
411 | // // return KAsync::error<void>(1, "Wrong file existence: " + filePath); | 477 | Warning() << "Existing folders are: " << *folderByPath; |
412 | // // } | 478 | Warning() << "We're looking for: " << folder.getName(); |
413 | // } | 479 | return KAsync::error<void>(1, "Wrong folder name: " + remoteId); |
414 | // } | 480 | } |
415 | // if (domainType == ENTITY_TYPE_FOLDER) { | 481 | return KAsync::null<void>(); |
416 | // const auto remoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, entityId); | 482 | }); |
417 | // const auto folder = entityStore->read<Sink::ApplicationDomain::Folder>(entityId); | 483 | |
418 | // | 484 | return inspectionJob; |
419 | // if (inspectionType == Sink::ResourceControl::Inspection::CacheIntegrityInspectionType) { | 485 | } |
420 | // // Warning() << "Inspecting cache integrity" << remoteId; | 486 | |
421 | // // if (!QDir(remoteId).exists()) { | 487 | } |
422 | // // return KAsync::error<void>(1, "The directory is not existing: " + remoteId); | ||
423 | // // } | ||
424 | // // | ||
425 | // // int expectedCount = 0; | ||
426 | // // Index index("mail.index.folder", transaction); | ||
427 | // // index.lookup(entityId, [&](const QByteArray &sinkId) { | ||
428 | // // expectedCount++; | ||
429 | // // }, | ||
430 | // // [&](const Index::Error &error) { | ||
431 | // // Warning() << "Error in index: " << error.message << property; | ||
432 | // // }); | ||
433 | // // | ||
434 | // // QDir dir(remoteId + "/cur"); | ||
435 | // // const QFileInfoList list = dir.entryInfoList(QDir::Files); | ||
436 | // // if (list.size() != expectedCount) { | ||
437 | // // return KAsync::error<void>(1, QString("Wrong number of files; found %1 instead of %2.").arg(list.size()).arg(expectedCount)); | ||
438 | // // } | ||
439 | // // if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { | ||
440 | // // if (!remoteId.endsWith(folder.getName().toUtf8())) { | ||
441 | // // return KAsync::error<void>(1, "Wrong folder name: " + remoteId); | ||
442 | // // } | ||
443 | // // //TODO we shouldn't use the remoteId here to figure out the path, it could be gone/changed already | ||
444 | // // if (QDir(remoteId).exists() != expectedValue.toBool()) { | ||
445 | // // return KAsync::error<void>(1, "Wrong folder existence: " + remoteId); | ||
446 | // // } | ||
447 | // // } | ||
448 | // } | ||
449 | // | ||
450 | // } | ||
451 | return KAsync::null<void>(); | 488 | return KAsync::null<void>(); |
452 | } | 489 | } |
453 | 490 | ||