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"