File indexing completed on 2024-11-17 04:44:57
0001 /* 0002 SPDX-FileCopyrightText: 2020 Krzysztof Nowicki <krissn@op.pl> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "ewsfetchitempayloadjob.h" 0008 0009 #include <KLocalizedString> 0010 0011 #include "ewsitemhandler.h" 0012 0013 #include "ewsresource_debug.h" 0014 0015 using namespace Akonadi; 0016 0017 constexpr unsigned ChunkSize = 10; 0018 0019 EwsFetchItemPayloadJob::EwsFetchItemPayloadJob(EwsClient &client, QObject *parent, const Akonadi::Item::List &items) 0020 : EwsJob(parent) 0021 , mItems(items) 0022 , mClient(client) 0023 , mChunkedJob(ChunkSize) 0024 { 0025 } 0026 0027 void EwsFetchItemPayloadJob::start() 0028 { 0029 EwsId::List ids; 0030 ids.reserve(mItems.count()); 0031 for (const Item &item : std::as_const(mItems)) { 0032 ids << EwsId(item.remoteId(), item.remoteRevision()); 0033 } 0034 0035 mChunkedJob.setItems(ids); 0036 mChunkedJob.start( 0037 [this](const EwsId::List::const_iterator &firstId, const EwsId::List::const_iterator &lastId) { 0038 auto req = new EwsGetItemRequest(mClient, this); 0039 EwsId::List ids; 0040 for (auto it = firstId; it != lastId; ++it) { 0041 ids.append(*it); 0042 } 0043 req->setItemIds(ids); 0044 EwsItemShape shape(EwsShapeIdOnly); 0045 shape << EwsPropertyField(QStringLiteral("item:MimeContent")); 0046 req->setItemShape(shape); 0047 return req; 0048 }, 0049 [](EwsGetItemRequest *req) { 0050 return req->responses(); 0051 }, 0052 [this](unsigned int progress) { 0053 Q_EMIT reportPercent(progress); 0054 }, 0055 [this](bool success, const QString &error) { 0056 itemFetchFinished(success, error); 0057 }); 0058 } 0059 0060 void EwsFetchItemPayloadJob::itemFetchFinished(bool success, const QString & /*error*/) 0061 { 0062 if (!success) { 0063 setErrorText(i18nc("@info:status", "Failed to process items retrieval request")); 0064 emitResult(); 0065 return; 0066 } 0067 0068 const EwsGetItemRequest::Response &resp = mChunkedJob.responses()[0]; 0069 if (!resp.isSuccess()) { 0070 qCWarningNC(EWSRES_AGENTIF_LOG) << QStringLiteral("retrieveItems: Item fetch failed."); 0071 setErrorText(i18nc("@info:status", "Failed to retrieve items")); 0072 emitResult(); 0073 return; 0074 } 0075 0076 if (mItems.size() != mChunkedJob.responses().size()) { 0077 qCWarningNC(EWSRES_AGENTIF_LOG) << QStringLiteral("retrieveItems: incorrect number of responses."); 0078 setErrorText(i18nc("@info:status", "Failed to retrieve items - incorrect number of responses")); 0079 emitResult(); 0080 return; 0081 } 0082 0083 /* In general EWS guarantees that the order of response items will match the order of request items. 0084 * It is therefore safe to iterate these in parallel. */ 0085 auto it = mItems.begin(); 0086 for (const auto &resp : mChunkedJob.responses()) { 0087 const EwsItem &ewsItem = resp.item(); 0088 auto id = ewsItem[EwsItemFieldItemId].value<EwsId>(); 0089 if (it->remoteId() != id.id()) { 0090 qCWarningNC(EWSRES_AGENTIF_LOG) << QStringLiteral("retrieveItems: Akonadi item not found for item %1.").arg(id.id()); 0091 setErrorText(i18nc("@info:status", "Failed to retrieve items - Akonadi item not found for item %1", id.id())); 0092 emitResult(); 0093 return; 0094 } 0095 EwsItemType type = ewsItem.internalType(); 0096 if (type == EwsItemTypeUnknown) { 0097 qCWarningNC(EWSRES_AGENTIF_LOG) << QStringLiteral("retrieveItems: Unknown item type for item %1!").arg(id.id()); 0098 setErrorText(i18nc("@info:status", "Failed to retrieve items - Unknown item type for item %1", id.id())); 0099 emitResult(); 0100 return; 0101 } 0102 if (!EwsItemHandler::itemHandler(type)->setItemPayload(*it, ewsItem)) { 0103 qCWarningNC(EWSRES_AGENTIF_LOG) << "retrieveItems: Failed to fetch item payload"; 0104 setErrorText(i18nc("@info:status", "Failed to fetch item payload")); 0105 emitResult(); 0106 return; 0107 } 0108 ++it; 0109 } 0110 0111 emitResult(); 0112 } 0113 0114 #include "moc_ewsfetchitempayloadjob.cpp"