diff --git a/resources/kolab/updatemessagejob.cpp b/resources/kolab/updatemessagejob.cpp index f845c1441..1926e3e37 100644 --- a/resources/kolab/updatemessagejob.cpp +++ b/resources/kolab/updatemessagejob.cpp @@ -1,236 +1,239 @@ /* Copyright (c) 2014 Christian Mollekopf This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "updatemessagejob.h" #include #include #include #include #include #include #include #include #include #include "imapflags.h" //Check if the expected uid message is still there => no modification, replace message. //otherwise search for uptodate message by subject containing UID, merge contents, and replace message UpdateMessageJob::UpdateMessageJob(const KMime::Message::Ptr &msg, KIMAP::Session *session, const QByteArray &kolabUid, QSharedPointer merger, const QString &mailbox, qint64 uidNext, qint64 oldUid, QObject *parent) : KJob(parent), mSession(session), mMessage(msg), mMailbox(mailbox), mUidNext(uidNext), mOldUid(oldUid), mNewUid(-1), mMessageId(msg->messageID()->asUnicodeString().toUtf8()), mKolabUid(kolabUid), mMerger(merger) { mOldUids.add(oldUid); } void UpdateMessageJob::start() +{ + if (mSession->selectedMailBox() != mMailbox) { + KIMAP::SelectJob *select = new KIMAP::SelectJob(mSession); + select->setMailBox(mMailbox); + connect(select, SIGNAL(result(KJob*)), this, SLOT(onSelectDone(KJob*))); + select->start(); + } else { + fetchHeaders(); + } +} + +void UpdateMessageJob::onSelectDone(KJob *job) +{ + if (job->error()) { + kWarning() << job->errorString(); + setError(KJob::UserDefinedError); + emitResult(); + } else { + fetchHeaders(); + } +} + +void UpdateMessageJob::fetchHeaders() { KIMAP::FetchJob * fetchJob = new KIMAP::FetchJob(mSession); fetchJob->setSequenceSet(KIMAP::ImapSet(mOldUid)); fetchJob->setUidBased(true); KIMAP::FetchJob::FetchScope scope; scope.parts.clear(); scope.mode = KIMAP::FetchJob::FetchScope::Headers; fetchJob->setScope(scope); connect(fetchJob, SIGNAL(headersReceived(QString, QMap, QMap, QMap, QMap, QMap)), this, SLOT(onHeadersReceived(QString, QMap, QMap, QMap, QMap, QMap))); connect(fetchJob, SIGNAL(result(KJob*)), this, SLOT(onHeadersFetchDone(KJob*))); fetchJob->start(); - - } void UpdateMessageJob::onHeadersReceived(QString, QMap uids, QMap, QMap, QMap flags, QMap) { //Filter deleted messages foreach (qint64 number, uids.keys()) { //krazy:exclude=foreach // const KMime::Message::Ptr msg = messages[number]; if (!flags[number].contains(ImapFlags::Deleted)) { mFoundUids << uids[number]; } } } void UpdateMessageJob::onHeadersFetchDone(KJob *job) { if (job->error()) { kWarning() << "Failed to fetch message: " << job->errorString(); } if (mFoundUids.size() >= 1) { kDebug() << "Fast-forward update, replacing message."; appendMessage(); - } else { - if (mSession->selectedMailBox() != mMailbox) { - KIMAP::SelectJob *select = new KIMAP::SelectJob(mSession); - select->setMailBox(mMailbox); - connect(select, SIGNAL(result(KJob*)), this, SLOT(onSelectDone(KJob*))); - select->start(); - } else { - searchForLatestVersion(); - } - } -} - -void UpdateMessageJob::onSelectDone(KJob *job) -{ - if (job->error()) { - kWarning() << job->errorString(); - setError(KJob::UserDefinedError); - emitResult(); } else { searchForLatestVersion(); } } void UpdateMessageJob::searchForLatestVersion() { KIMAP::SearchJob *search = new KIMAP::SearchJob(mSession); search->setUidBased(true); search->setSearchLogic(KIMAP::SearchJob::And); search->addSearchCriteria(KIMAP::SearchJob::Header, "Subject " + mKolabUid); connect(search, SIGNAL(result(KJob*)), this, SLOT(onSearchDone(KJob*))); search->start(); } void UpdateMessageJob::onSearchDone(KJob *job) { if (job->error()) { kWarning() << job->errorString(); setError(KJob::UserDefinedError); emitResult(); return; } KIMAP::SearchJob *search = static_cast(job); if (search->results().count() >= 1) { mOldUids = KIMAP::ImapSet(); foreach (qint64 id, search->results()) { mOldUids.add(id); } KIMAP::FetchJob * fetchJob = new KIMAP::FetchJob(mSession); fetchJob->setSequenceSet(mOldUids); fetchJob->setUidBased(true); KIMAP::FetchJob::FetchScope scope; scope.parts.clear(); scope.mode = KIMAP::FetchJob::FetchScope::Full; fetchJob->setScope(scope); connect(fetchJob, SIGNAL(headersReceived(QString, QMap, QMap, QMap, QMap, QMap)), this, SLOT(onConflictingMessagesReceived(QString, QMap, QMap, QMap, QMap, QMap))); connect(fetchJob, SIGNAL(result(KJob*)), this, SLOT(onConflictingMessageFetchDone(KJob*))); fetchJob->start(); } else { kWarning() << "failed to find latest version of object"; appendMessage(); } } void UpdateMessageJob::onConflictingMessagesReceived(QString, QMap uids, QMap, QMap, QMap flags, QMap messages) { foreach (qint64 number, uids.keys()) { //krazy:exclude=foreach if (!flags[number].contains(ImapFlags::Deleted)) { mMessagesToMerge << messages[number]; } } } void UpdateMessageJob::onConflictingMessageFetchDone(KJob *job) { if (job->error()) { kWarning() << "Failed to retrieve messages to merge: " << job->errorString(); } mMessage = mMerger->merge(mMessage, mMessagesToMerge); appendMessage(); } void UpdateMessageJob::appendMessage() { const qint64 uidNext = -1; ReplaceMessageJob *replace = new ReplaceMessageJob(mMessage, mSession, mMailbox, uidNext, mOldUids, this); connect(replace, SIGNAL(result(KJob*)), this, SLOT(onReplaceDone(KJob*))); replace->start(); } void UpdateMessageJob::onReplaceDone(KJob *job) { if (job->error()) { kWarning() << job->errorString(); setError(KJob::UserDefinedError); emitResult(); return; } ReplaceMessageJob *replaceJob = static_cast(job); mNewUid = replaceJob->newUid(); emitResult(); } qint64 UpdateMessageJob::newUid() const { return mNewUid; } diff --git a/resources/kolab/updatemessagejob.h b/resources/kolab/updatemessagejob.h index 9567959b6..b7f2498e9 100644 --- a/resources/kolab/updatemessagejob.h +++ b/resources/kolab/updatemessagejob.h @@ -1,85 +1,86 @@ /* Copyright (c) 2014 Christian Mollekopf This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef UPDATEMESSAGEJOB_H #define UPDATEMESSAGEJOB_H #include #include #include #include struct Merger { virtual ~Merger() {} virtual KMime::Message::Ptr merge(KMime::Message::Ptr newMessage, QList conflictingMessages) const = 0; }; /** * This job appends a message, marks the old one as deleted, and returns the uid of the appended message. */ class UpdateMessageJob : public KJob { Q_OBJECT public: UpdateMessageJob(const KMime::Message::Ptr &msg, KIMAP::Session *session, const QByteArray &kolabUid, QSharedPointer merger, const QString &mailbox, qint64 uidNext = -1, qint64 oldUid = -1, QObject *parent = 0); qint64 newUid() const; void start(); private: + void fetchHeaders(); void searchForLatestVersion(); void appendMessage(); private Q_SLOTS: void onHeadersReceived(QString, QMap uids, QMap, QMap, QMap, QMap); void onHeadersFetchDone(KJob *job); void onSelectDone(KJob *job); void onSearchDone(KJob *job); void onConflictingMessagesReceived(QString, QMap uids, QMap, QMap, QMap, QMap); void onConflictingMessageFetchDone(KJob *job); void onReplaceDone(KJob *job); private: KIMAP::Session *mSession; KMime::Message::Ptr mMessage; const QString mMailbox; qint64 mUidNext; qint64 mOldUid; KIMAP::ImapSet mOldUids; qint64 mNewUid; const QByteArray mMessageId; const QByteArray mKolabUid; QList mFoundUids; QList mMessagesToMerge; QSharedPointer mMerger; }; #endif