File indexing completed on 2024-05-12 05:22:29

0001 /*
0002  * This file is part of LibKGAPI library
0003  *
0004  * SPDX-FileCopyrightText: 2023 Claudio Cambra <claudio.cambra@kde.org>
0005  *
0006  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007  */
0008 
0009 #include "personphotoupdatejob.h"
0010 #include "peopleservice.h"
0011 #include "person.h"
0012 #include "utils.h"
0013 
0014 #include <QNetworkRequest>
0015 #include <QNetworkReply>
0016 #include <QUrlQuery>
0017 #include <QJsonDocument>
0018 #include <QJsonObject>
0019 #include <QJsonArray>
0020 
0021 namespace KGAPI2::People
0022 {
0023 
0024 class Q_DECL_HIDDEN PersonPhotoUpdateJob::Private
0025 {
0026 public:
0027     explicit Private(PersonPhotoUpdateJob *parent);
0028     void processPersonPhoto();
0029 
0030     QString personResourceName;
0031     QByteArray photoRawData;
0032 
0033 private:
0034     PersonPhotoUpdateJob * const q;
0035 };
0036 
0037 PersonPhotoUpdateJob::Private::Private(PersonPhotoUpdateJob *parent)
0038     : q(parent)
0039 {
0040 }
0041 
0042 void PersonPhotoUpdateJob::Private::processPersonPhoto()
0043 {
0044     const auto modifyUrl = PeopleService::updateContactPhotoUrl(personResourceName);
0045     QNetworkRequest request(modifyUrl);
0046     request.setRawHeader("Host", "people.googleapis.com");
0047 
0048     const QJsonObject rootObject {
0049         {QStringLiteral("photoBytes"), QString::fromUtf8(photoRawData.toBase64())},
0050         {QStringLiteral("personFields"), PeopleService::allPersonFields()}
0051     };
0052     const QJsonDocument jsonDoc(rootObject);
0053     const auto rawData = jsonDoc.toJson();
0054 
0055     q->enqueueRequest(request, rawData, QStringLiteral("application/json"));
0056 }
0057 
0058 PersonPhotoUpdateJob::PersonPhotoUpdateJob(const QString &personResourceName, const QByteArray &photoRawData, const AccountPtr &account, QObject* parent)
0059     : ModifyJob(account, parent)
0060     , d(std::make_unique<Private>(this))
0061 {
0062     d->personResourceName = personResourceName;
0063     d->photoRawData = photoRawData;
0064 }
0065 
0066 PersonPhotoUpdateJob::~PersonPhotoUpdateJob() = default;
0067 
0068 void PersonPhotoUpdateJob::start()
0069 {
0070     d->processPersonPhoto();
0071 }
0072 
0073 void PersonPhotoUpdateJob::dispatchRequest(QNetworkAccessManager *accessManager,
0074                                       const QNetworkRequest &request,
0075                                       const QByteArray &data,
0076                                       const QString &contentType)
0077 {
0078     QNetworkRequest r = request;
0079     if (!r.hasRawHeader("Content-Type")) {
0080         r.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
0081     }
0082 
0083     if (!r.hasRawHeader("If-Match")) {
0084         r.setRawHeader("If-Match", "*");
0085     }
0086 
0087     accessManager->sendCustomRequest(r, "PATCH", data);
0088 }
0089 
0090 ObjectsList PersonPhotoUpdateJob::handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData)
0091 {
0092     const auto contentTypeString = reply->header(QNetworkRequest::ContentTypeHeader).toString();
0093     const auto contentType = Utils::stringToContentType(contentTypeString);
0094 
0095     if (contentType != KGAPI2::JSON) {
0096         setError(KGAPI2::InvalidResponse);
0097         setErrorString(tr("Invalid response content type"));
0098         emitFinished();
0099         return {};
0100     }
0101 
0102     ObjectsList items;
0103     const auto json = QJsonDocument::fromJson(rawData);
0104     if (json.isObject()) {
0105         const auto jsonObject = json.object();
0106         const auto personJson = jsonObject.value(QStringLiteral("person")).toObject();
0107         const auto person = Person::fromJSON(personJson);
0108         items << person;
0109     }
0110 
0111     emitFinished();
0112     return items;
0113 }
0114 
0115 }
0116 
0117 #include "moc_personphotoupdatejob.cpp"