From 82ca7ebb9c24fef6f1860eeca9577d998af03c7f Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Mon, 13 Jun 2016 14:39:57 +0200 Subject: Implemented maildir mail moves and got it to pass tests again --- examples/maildirresource/facade.cpp | 1 + examples/maildirresource/libmaildir/maildir.cpp | 8 +++- examples/maildirresource/maildirresource.cpp | 61 +++++++++++++++++++------ examples/maildirresource/maildirresource.h | 2 - 4 files changed, 53 insertions(+), 19 deletions(-) (limited to 'examples') diff --git a/examples/maildirresource/facade.cpp b/examples/maildirresource/facade.cpp index a7a0348..d8fc02d 100644 --- a/examples/maildirresource/facade.cpp +++ b/examples/maildirresource/facade.cpp @@ -48,6 +48,7 @@ MaildirResourceMailFacade::MaildirResourceMailFacade(const QByteArray &instanceI value.setProperty("mimeMessage", list.at(0).filePath()); } } + value.setChangedProperties(QSet()); }; } diff --git a/examples/maildirresource/libmaildir/maildir.cpp b/examples/maildirresource/libmaildir/maildir.cpp index c55e00e..de704f2 100644 --- a/examples/maildirresource/libmaildir/maildir.cpp +++ b/examples/maildirresource/libmaildir/maildir.cpp @@ -141,6 +141,10 @@ public: QString findRealKey(const QString& key) const { + if (key.isEmpty()) { + qWarning() << "Empty key: " << key; + return key; + } // KeyCache* keyCache = KeyCache::self(); // if (keyCache->isNewKey(path, key)) { if (QFile::exists(path + QString::fromLatin1("/new/") + key)) { @@ -670,7 +674,7 @@ QString Maildir::addEntry(const QByteArray& data) do { uniqueKey = createUniqueFileName() + d->hostName; key = d->path + QLatin1String("/tmp/") + uniqueKey; - finalKey = d->path + QLatin1String("/new/") + uniqueKey; + finalKey = d->path + QLatin1String("/cur/") + uniqueKey; curKey = d->path + QLatin1String("/cur/") + uniqueKey; } while (QFile::exists(key) || QFile::exists(finalKey) || QFile::exists(curKey)); @@ -911,7 +915,7 @@ QString Maildir::moveEntryTo(const QString &key, const Maildir &destination) } QFile f(realKey); // ### is this safe regarding the maildir locking scheme? - const QString targetKey = destination.path() + QDir::separator() + QLatin1String("new") + QDir::separator() + key; + const QString targetKey = destination.path() + QDir::separator() + QLatin1String("cur") + QDir::separator() + key; if (!f.rename(targetKey)) { qDebug() << "Failed to rename" << realKey << "to" << targetKey << "! Error: " << f.errorString();; d->lastError = f.errorString(); diff --git a/examples/maildirresource/maildirresource.cpp b/examples/maildirresource/maildirresource.cpp index 9800f7f..05441b0 100644 --- a/examples/maildirresource/maildirresource.cpp +++ b/examples/maildirresource/maildirresource.cpp @@ -139,10 +139,30 @@ public: const auto path = getPath(folder, transaction); KPIM::Maildir maildir(path, false); if (!maildir.isValid(true)) { - qWarning() << "Maildir is not existing: " << path; + Warning() << "Maildir is not existing: " << path; } auto identifier = maildir.addEntryFromPath(oldPath); return path + "/" + identifier; + } else { + //Handle moves + const auto path = getPath(folder, transaction); + KPIM::Maildir maildir(path, false); + if (!maildir.isValid(true)) { + Warning() << "Maildir is not existing: " << path; + } + auto oldIdentifier = KPIM::Maildir::getKeyFromFile(oldPath); + auto pathParts = oldPath.split('/'); + pathParts.takeLast(); + auto oldDirectory = pathParts.join('/'); + if (oldDirectory == path) { + return oldPath; + } + KPIM::Maildir oldMaildir(oldDirectory, false); + if (!oldMaildir.isValid(false)) { + Warning() << "Maildir is not existing: " << path; + } + auto identifier = oldMaildir.moveEntryTo(oldIdentifier, maildir); + return path + "/" + identifier; } return oldPath; } @@ -161,21 +181,29 @@ public: void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE { - //TODO deal with moves + if (newEntity.getProperty("draft").toBool()) { + newEntity.setProperty("folder", mDraftsFolder); + } const auto mimeMessage = newEntity.getProperty("mimeMessage"); - if (mimeMessage.isValid() && mimeMessage.toString() != oldEntity.getProperty("mimeMessage").toString()) { - //Remove the olde mime message if there is a new one - const auto filePath = getFilePathFromMimeMessagePath(oldEntity.getProperty("mimeMessage").toString()); - QFile::remove(filePath); - - newEntity.setProperty("mimeMessage", moveMessage(mimeMessage.toString(), newEntity.getProperty("folder").toByteArray(), transaction)); - Trace() << "Modified message: " << filePath << oldEntity.getProperty("mimeMessage").toString(); + const auto newFolder = newEntity.getProperty("folder"); + const bool mimeMessageChanged = mimeMessage.isValid() && mimeMessage.toString() != oldEntity.getProperty("mimeMessage").toString(); + const bool folderChanged = newFolder.isValid() && newFolder.toString() != oldEntity.getProperty("mimeMessage").toString(); + if (mimeMessageChanged || folderChanged) { + Trace() << "Moving mime message: " << mimeMessageChanged << folderChanged; + auto newPath = moveMessage(mimeMessage.toString(), newEntity.getProperty("folder").toByteArray(), transaction); + if (newPath != oldEntity.getProperty("mimeMessage").toString()) { + const auto oldPath = getFilePathFromMimeMessagePath(oldEntity.getProperty("mimeMessage").toString()); + newEntity.setProperty("mimeMessage", newPath); + //Remove the olde mime message if there is a new one + QFile::remove(oldPath); + } } auto mimeMessagePath = newEntity.getProperty("mimeMessage").toString(); const auto maildirPath = getPath(newEntity.getProperty("folder").toByteArray(), transaction); KPIM::Maildir maildir(maildirPath, false); - QString identifier = KPIM::Maildir::getKeyFromFile(mimeMessagePath); + const auto file = getFilePathFromMimeMessagePath(mimeMessagePath); + QString identifier = KPIM::Maildir::getKeyFromFile(file); //get flags from KPIM::Maildir::Flags flags; @@ -247,14 +275,17 @@ public: return list; } - QByteArray createFolder(const QString &folderPath, const QByteArray &icon) + QByteArray createFolder(const QString &folderPath, const QByteArray &icon, const QByteArrayList &specialpurpose = QByteArrayList()) { auto remoteId = folderPath.toUtf8(); auto bufferType = ENTITY_TYPE_FOLDER; KPIM::Maildir md(folderPath, folderPath == mMaildirPath); Sink::ApplicationDomain::Folder folder; - folder.setProperty("name", md.name()); - folder.setProperty("icon", icon); + folder.setName(md.name()); + folder.setIcon(icon); + if (!specialpurpose.isEmpty()) { + folder.setSpecialPurpose(specialpurpose); + } if (!md.isRoot()) { folder.setProperty("parent", syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, md.parent().path().toUtf8())); @@ -478,10 +509,10 @@ MaildirResource::MaildirResource(const QByteArray &instanceIdentifier, const QSh setupPreprocessors(ENTITY_TYPE_FOLDER, QVector() << folderPreprocessor << new DefaultIndexUpdater); KPIM::Maildir dir(mMaildirPath, true); - mDraftsFolder = dir.addSubFolder("drafts"); Trace() << "Started maildir resource for maildir: " << mMaildirPath; + mDraftsFolder = dir.addSubFolder("Drafts"); - auto remoteId = synchronizer->createFolder(mDraftsFolder, "folder"); + auto remoteId = synchronizer->createFolder(mDraftsFolder, "folder", QByteArrayList() << "drafts"); auto draftsFolderLocalId = synchronizer->syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, remoteId); synchronizer->commit(); synchronizer->commitSync(); diff --git a/examples/maildirresource/maildirresource.h b/examples/maildirresource/maildirresource.h index b3bce5e..d481b22 100644 --- a/examples/maildirresource/maildirresource.h +++ b/examples/maildirresource/maildirresource.h @@ -49,8 +49,6 @@ public: KAsync::Job inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE; static void removeFromDisk(const QByteArray &instanceIdentifier); private: - // KAsync::Job replay(const Sink::ApplicationDomain::Mail &, Sink::Operation, const QByteArray &oldRemoteId) Q_DECL_OVERRIDE; - // KAsync::Job replay(const Sink::ApplicationDomain::Folder &, Sink::Operation, const QByteArray &oldRemoteId) Q_DECL_OVERRIDE; QStringList listAvailableFolders(); QString mMaildirPath; -- cgit v1.2.3