File indexing completed on 2024-11-24 04:44:18

0001 /*
0002     SPDX-FileCopyrightText: 2014 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
0003     SPDX-FileContributor: Kevin Krammer <kevin.krammer@kdab.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "tagchangehelper.h"
0009 #include "kolabhelpers.h"
0010 #include "kolabrelationresourcetask.h"
0011 #include "kolabresource_debug.h"
0012 #include "updatemessagejob.h"
0013 
0014 #include "imapflags.h"
0015 #include "uidnextattribute.h"
0016 
0017 #include "pimkolab/kolabformat/kolabobject.h"
0018 
0019 #include "replacemessagejob.h"
0020 #include <Akonadi/TagModifyJob>
0021 #include <KIMAP/SearchJob>
0022 #include <KIMAP/Session>
0023 
0024 KMime::Message::Ptr TagConverter::createMessage(const Akonadi::Tag &tag, const Akonadi::Item::List &items, const QString &username)
0025 {
0026     QStringList itemRemoteIds;
0027     itemRemoteIds.reserve(items.count());
0028     for (const Akonadi::Item &item : items) {
0029         const QString memberUrl = KolabHelpers::createMemberUrl(item, username);
0030         if (!memberUrl.isEmpty()) {
0031             itemRemoteIds << memberUrl;
0032         }
0033     }
0034 
0035     // save message to the server.
0036     const QLatin1StringView productId("Akonadi-Kolab-Resource");
0037     const KMime::Message::Ptr message = Kolab::KolabObjectWriter::writeTag(tag, itemRemoteIds, Kolab::KolabV3, productId);
0038     return message;
0039 }
0040 
0041 struct TagMerger : public Merger {
0042     ~TagMerger() override = default;
0043 
0044     [[nodiscard]] KMime::Message::Ptr merge(const KMime::Message::Ptr &newMessage, const QList<KMime::Message::Ptr> &conflictingMessages) const override
0045     {
0046         qCDebug(KOLABRESOURCE_LOG) << "Got " << conflictingMessages.size() << " conflicting relation configuration objects. Overwriting with local version.";
0047         return newMessage;
0048     }
0049 };
0050 
0051 TagChangeHelper::TagChangeHelper(KolabRelationResourceTask *parent)
0052     : QObject(parent)
0053     , mTask(parent)
0054 {
0055 }
0056 
0057 void TagChangeHelper::start(const Akonadi::Tag &tag, const KMime::Message::Ptr &message, KIMAP::Session *session)
0058 {
0059     Q_ASSERT(tag.isValid());
0060     const QString mailBox = mTask->mailBoxForCollection(mTask->relationCollection());
0061     const qint64 oldUid = tag.remoteId().toLongLong();
0062     qCDebug(KOLABRESOURCE_LOG) << mailBox << oldUid;
0063 
0064     const qint64 uidNext = -1;
0065 
0066     auto append = new UpdateMessageJob(message, session, tag.gid(), QSharedPointer<TagMerger>(new TagMerger), mailBox, uidNext, oldUid, this);
0067     connect(append, &KJob::result, this, &TagChangeHelper::onReplaceDone);
0068     append->setProperty("tag", QVariant::fromValue(tag));
0069     append->start();
0070 }
0071 
0072 void TagChangeHelper::recordNewUid(qint64 newUid, const Akonadi::Tag &tag)
0073 {
0074     Q_ASSERT(newUid > 0);
0075     Q_ASSERT(tag.isValid());
0076 
0077     const QByteArray remoteId = QByteArray::number(newUid);
0078     qCDebug(KOLABRESOURCE_LOG) << "Setting remote ID to " << remoteId << " on tag with local id: " << tag.id();
0079     // Make sure we only update the id and send nothing else
0080     Akonadi::Tag updateTag;
0081     updateTag.setId(tag.id());
0082     updateTag.setRemoteId(remoteId);
0083     auto modJob = new Akonadi::TagModifyJob(updateTag);
0084     connect(modJob, &KJob::result, this, &TagChangeHelper::onModifyDone);
0085 }
0086 
0087 void TagChangeHelper::onReplaceDone(KJob *job)
0088 {
0089     if (job->error()) {
0090         qCWarning(KOLABRESOURCE_LOG) << "Replace failed: " << job->errorString();
0091     }
0092     auto replaceJob = static_cast<UpdateMessageJob *>(job);
0093     const qint64 newUid = replaceJob->newUid();
0094     const auto tag = job->property("tag").value<Akonadi::Tag>();
0095     if (newUid > 0) {
0096         recordNewUid(newUid, tag);
0097     } else {
0098         Q_EMIT cancelTask(job->errorString());
0099     }
0100 }
0101 
0102 void TagChangeHelper::onModifyDone(KJob *job)
0103 {
0104     if (job->error()) {
0105         qCWarning(KOLABRESOURCE_LOG) << "Modify failed: " << job->errorString();
0106         Q_EMIT cancelTask(job->errorString());
0107         return;
0108     }
0109     Q_EMIT changeCommitted();
0110 }
0111 
0112 #include "moc_tagchangehelper.cpp"