File indexing completed on 2024-11-24 04:43:49
0001 /* 0002 SPDX-FileCopyrightText: 2015-2021 Krzysztof Nowicki <krissn@op.pl> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "ewsmodifymailjob.h" 0008 0009 #include <Akonadi/MessageFlags> 0010 0011 #include <KLocalizedString> 0012 0013 #include "ewsmailhandler.h" 0014 0015 #include "ewsresource_debug.h" 0016 0017 using namespace Akonadi; 0018 0019 constexpr unsigned ChunkSize = 10; 0020 0021 EwsModifyMailJob::EwsModifyMailJob(EwsClient &client, const Akonadi::Item::List &items, const QSet<QByteArray> &parts, QObject *parent) 0022 : EwsModifyItemJob(client, items, parts, parent) 0023 , mChunkedJob(ChunkSize) 0024 { 0025 } 0026 0027 EwsModifyMailJob::~EwsModifyMailJob() = default; 0028 0029 void EwsModifyMailJob::start() 0030 { 0031 bool doSubmit = false; 0032 EwsId itemId; 0033 0034 EwsUpdateItemRequest::ItemChange::List itemChanges; 0035 itemChanges.reserve(mItems.size()); 0036 for (const Item &item : std::as_const(mItems)) { 0037 itemId = EwsId(item.remoteId(), item.remoteRevision()); 0038 0039 if (mParts.contains("FLAGS")) { 0040 EwsUpdateItemRequest::ItemChange ic(itemId, EwsItemTypeMessage); 0041 QHash<EwsPropertyField, QVariant> propertyHash = EwsMailHandler::writeFlags(item.flags()); 0042 0043 for (auto it = propertyHash.cbegin(), end = propertyHash.cend(); it != end; ++it) { 0044 EwsUpdateItemRequest::Update *upd; 0045 if (it.value().isNull()) { 0046 upd = new EwsUpdateItemRequest::DeleteUpdate(it.key()); 0047 } else { 0048 upd = new EwsUpdateItemRequest::SetUpdate(it.key(), it.value()); 0049 } 0050 ic.addUpdate(upd); 0051 } 0052 0053 itemChanges.append(ic); 0054 doSubmit = true; 0055 } 0056 } 0057 0058 if (doSubmit) { 0059 mChunkedJob.setItems(itemChanges); 0060 mChunkedJob.start( 0061 [this](const EwsUpdateItemRequest::ItemChange::List::const_iterator &firstChange, 0062 const EwsUpdateItemRequest::ItemChange::List::const_iterator &lastChange) { 0063 auto req = new EwsUpdateItemRequest(mClient, this); 0064 req->addItemChanges(firstChange, lastChange); 0065 return req; 0066 }, 0067 [](EwsUpdateItemRequest *req) { 0068 return req->responses(); 0069 }, 0070 [this](unsigned int progress) { 0071 Q_EMIT reportPercent(progress); 0072 }, 0073 [this](bool success, const QString &error) { 0074 updateItemsFinished(success, error); 0075 }); 0076 } else { 0077 emitResult(); 0078 } 0079 } 0080 0081 void EwsModifyMailJob::updateItemsFinished(bool success, const QString &error) 0082 { 0083 if (!success) { 0084 setErrorText(error); 0085 emitResult(); 0086 return; 0087 } 0088 0089 Item::List::iterator it = mItems.begin(); 0090 for (const auto &resp : mChunkedJob.responses()) { 0091 if (!resp.isSuccess()) { 0092 setErrorText(i18nc("@info:status", "Item update failed: ") + resp.responseMessage()); 0093 emitResult(); 0094 return; 0095 } 0096 0097 /* In general EWS guarantees that the order of response items will match the order of request items. 0098 * It is therefore safe to iterate these in parallel. */ 0099 if (it->remoteId() == resp.itemId().id()) { 0100 it->setRemoteRevision(resp.itemId().changeKey()); 0101 ++it; 0102 } else { 0103 setErrorText(i18nc("@info:status", "Item out of order while processing update item response.")); 0104 emitResult(); 0105 return; 0106 } 0107 } 0108 emitResult(); 0109 } 0110 0111 #include "moc_ewsmodifymailjob.cpp"