Commit bc5af1df authored by Krzysztof Nowicki's avatar Krzysztof Nowicki Committed by Laurent Montel
Browse files

Factor out item payload retrieval to a separate job



This is a preparatory change to introduce chunked mode in this job.

It also improves code readability by removing lines from the already
overloaded ewsresource.cpp file.
Signed-off-by: Krzysztof Nowicki's avatarKrzysztof Nowicki <krissn@op.pl>
parent c4d7a747
......@@ -50,6 +50,7 @@ set(ewsresource_SRCS
ewsfetchfoldersincrjob.cpp
ewsfetchfoldersjob.cpp
ewsfetchitemdetailjob.cpp
ewsfetchitempayloadjob.cpp
ewsfetchitemsjob.cpp
ewsitemhandler.cpp
ewsmodifyitemflagsjob.cpp
......
/*
SPDX-FileCopyrightText: 2020 Krzysztof Nowicki <krissn@op.pl>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "ewsfetchitempayloadjob.h"
#include <KLocalizedString>
#include "ewsgetitemrequest.h"
#include "ewsitemhandler.h"
#include "ewsresource_debug.h"
using namespace Akonadi;
EwsFetchItemPayloadJob::EwsFetchItemPayloadJob(EwsClient &client, QObject *parent, const Akonadi::Item::List &items)
: EwsJob(parent)
, mItems(items)
, mClient(client)
{
}
void EwsFetchItemPayloadJob::start()
{
auto req = new EwsGetItemRequest(mClient, this);
EwsId::List ids;
ids.reserve(mItems.count());
for (const Item &item : std::as_const(mItems)) {
ids << EwsId(item.remoteId(), item.remoteRevision());
}
req->setItemIds(ids);
EwsItemShape shape(EwsShapeIdOnly);
shape << EwsPropertyField(QStringLiteral("item:MimeContent"));
req->setItemShape(shape);
connect(req, &EwsGetItemRequest::result, this, &EwsFetchItemPayloadJob::itemFetchFinished);
req->start();
}
void EwsFetchItemPayloadJob::itemFetchFinished(KJob *job)
{
if (!success) {
setErrorText(i18nc("@info:status", "Failed to process items retrieval request"));
emitResult();
return;
}
auto req = qobject_cast<EwsGetItemRequest *>(job);
if (!req) {
qCWarning(EWSRES_LOG) << QStringLiteral("Invalid EwsGetItemRequest job object");
setErrorText(i18nc("@info:status", "Failed to retrieve items - internal error"));
emitResult();
return;
}
QHash<QString, Item> itemHash;
itemHash.reserve(mItems.count());
for (const Item &item : mItems) {
itemHash.insert(item.remoteId(), item);
}
const EwsGetItemRequest::Response &resp = req->responses()[0];
if (!resp.isSuccess()) {
qCWarningNC(EWSRES_AGENTIF_LOG) << QStringLiteral("retrieveItems: Item fetch failed.");
setErrorText(i18nc("@info:status", "Failed to retrieve items"));
emitResult();
return;
}
if (mItems.size() != req->responses().size()) {
qCWarningNC(EWSRES_AGENTIF_LOG) << QStringLiteral("retrieveItems: incorrect number of responses.");
setErrorText(i18nc("@info:status", "Failed to retrieve items - incorrect number of responses"));
emitResult();
return;
}
Q_FOREACH (const EwsGetItemRequest::Response &resp, req->responses()) {
const EwsItem &ewsItem = resp.item();
auto id = ewsItem[EwsItemFieldItemId].value<EwsId>();
auto it = itemHash.find(id.id());
if (it == itemHash.end()) {
qCWarningNC(EWSRES_AGENTIF_LOG) << QStringLiteral("retrieveItems: Akonadi item not found for item %1.").arg(id.id());
setErrorText(i18nc("@info:status", "Failed to retrieve items - Akonadi item not found for item %1", id.id()));
emitResult();
return;
}
EwsItemType type = ewsItem.internalType();
if (type == EwsItemTypeUnknown) {
qCWarningNC(EWSRES_AGENTIF_LOG) << QStringLiteral("retrieveItems: Unknown item type for item %1!").arg(id.id());
setErrorText(i18nc("@info:status", "Failed to retrieve items - Unknown item type for item %1", id.id()));
emitResult();
return;
}
if (!EwsItemHandler::itemHandler(type)->setItemPayload(*it, ewsItem)) {
qCWarningNC(EWSRES_AGENTIF_LOG) << "retrieveItems: Failed to fetch item payload";
setErrorText(i18nc("@info:status", "Failed to fetch item payload"));
emitResult();
return;
}
}
mResultItems = itemHash.values().toVector();
emitResult();
}
/*
SPDX-FileCopyrightText: 2020 Krzysztof Nowicki <krissn@op.pl>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#pragma once
#include <AkonadiCore/Item>
#include "ewsclient.h"
#include "ewsjob.h"
#include "ewstypes.h"
class EwsFetchItemPayloadJob : public EwsJob
{
Q_OBJECT
public:
EwsFetchItemPayloadJob(EwsClient &client, QObject *parent, const Akonadi::Item::List &items);
~EwsFetchItemPayloadJob() override = default;
Akonadi::Item::List items() const
{
return mResultItems;
}
void start() override;
Q_SIGNALS:
void status(int status, const QString &message = QString());
void percent(int progress);
private:
void itemFetchFinished(KJob *job);
Akonadi::Item::List mItems;
Akonadi::Item::List mResultItems;
EwsClient &mClient;
};
/*
SPDX-FileCopyrightText: 2015-2019 Krzysztof Nowicki <krissn@op.pl>
SPDX-FileCopyrightText: 2015-2020 Krzysztof Nowicki <krissn@op.pl>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
......@@ -31,6 +31,7 @@
#include "ewsdeleteitemrequest.h"
#include "ewsfetchfoldersincrjob.h"
#include "ewsfetchfoldersjob.h"
#include "ewsfetchitempayloadjob.h"
#include "ewsfetchitemsjob.h"
#include "ewsgetfolderrequest.h"
#include "ewsgetitemrequest.h"
......@@ -330,82 +331,34 @@ bool EwsResource::retrieveItems(const Item::List &items, const QSet<QByteArray>
{
qCDebugNC(EWSRES_AGENTIF_LOG) << "retrieveItems: start " << items << parts;
auto req = new EwsGetItemRequest(mEwsClient, this);
EwsId::List ids;
ids.reserve(items.count());
for (const Item &item : items) {
ids << EwsId(item.remoteId(), item.remoteRevision());
}
req->setItemIds(ids);
EwsItemShape shape(EwsShapeIdOnly);
shape << EwsPropertyField(QStringLiteral("item:MimeContent"));
req->setItemShape(shape);
req->setProperty("items", QVariant::fromValue<Item::List>(items));
connect(req, &EwsGetItemRequest::result, this, &EwsResource::getItemsRequestFinished);
req->start();
Q_EMIT status(Running, i18nc("@info:status", "Retrieving items"));
auto job = new EwsFetchItemPayloadJob(mEwsClient, this, items);
connect(job, &EwsGetItemRequest::result, this, &EwsResource::getItemsRequestFinished);
connectStatusSignals(job);
job->start();
return true;
}
void EwsResource::getItemsRequestFinished(KJob *job)
{
if (job->error()) {
qWarning() << "ERROR" << job->errorString();
cancelTask(i18nc("@info:status", "Failed to process items retrieval request"));
return;
}
auto req = qobject_cast<EwsGetItemRequest *>(job);
if (!req) {
qCWarning(EWSRES_LOG) << QStringLiteral("Invalid EwsGetItemRequest job object");
cancelTask(i18nc("@info:status", "Failed to retrieve items - internal error"));
return;
}
const auto items = req->property("items").value<Item::List>();
QHash<QString, Item> itemHash;
itemHash.reserve(items.count());
for (const Item &item : items) {
itemHash.insert(item.remoteId(), item);
}
emitReadyStatus();
const EwsGetItemRequest::Response &resp = req->responses()[0];
if (!resp.isSuccess()) {
qCWarningNC(EWSRES_AGENTIF_LOG) << QStringLiteral("retrieveItems: Item fetch failed.");
cancelTask(i18nc("@info:status", "Failed to retrieve items"));
if (job->error()) {
cancelTask(job->errorText());
return;
}
if (items.size() != req->responses().size()) {
qCWarningNC(EWSRES_AGENTIF_LOG) << QStringLiteral("retrieveItems: incorrect number of responses.");
cancelTask(i18nc("@info:status", "Failed to retrieve items - incorrect number of responses"));
EwsFetchItemPayloadJob *fetchJob = qobject_cast<EwsFetchItemPayloadJob *>(job);
if (!fetchJob) {
qCWarning(EWSRES_LOG) << QStringLiteral("Invalid EwsFetchItemPayloadJob job object");
cancelTask(i18nc("@info:status", "Failed to retrieve items - internal error"));
return;
}
Q_FOREACH (const EwsGetItemRequest::Response &resp, req->responses()) {
const EwsItem &ewsItem = resp.item();
auto id = ewsItem[EwsItemFieldItemId].value<EwsId>();
auto it = itemHash.find(id.id());
if (it == itemHash.end()) {
qCWarningNC(EWSRES_AGENTIF_LOG) << QStringLiteral("retrieveItems: Akonadi item not found for item %1.").arg(id.id());
cancelTask(i18nc("@info:status", "Failed to retrieve items - Akonadi item not found for item %1", id.id()));
return;
}
EwsItemType type = ewsItem.internalType();
if (type == EwsItemTypeUnknown) {
qCWarningNC(EWSRES_AGENTIF_LOG) << QStringLiteral("retrieveItems: Unknown item type for item %1!").arg(id.id());
cancelTask(i18nc("@info:status", "Failed to retrieve items - Unknown item type for item %1", id.id()));
return;
}
if (!EwsItemHandler::itemHandler(type)->setItemPayload(*it, ewsItem)) {
qCWarningNC(EWSRES_AGENTIF_LOG) << "retrieveItems: Failed to fetch item payload";
cancelTask(i18nc("@info:status", "Failed to fetch item payload"));
return;
}
}
qCDebugNC(EWSRES_AGENTIF_LOG) << "retrieveItems: done";
itemsRetrieved(itemHash.values().toVector());
itemsRetrieved(fetchJob->items());
}
void EwsResource::reloadConfig()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment