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

0001 /*
0002     SPDX-FileCopyrightText: 2019 Harald Sitter <sitter@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "apijob.h"
0008 
0009 #include <QMetaMethod>
0010 #include <QNetworkAccessManager>
0011 #include <QNetworkReply>
0012 #include <QTimer>
0013 
0014 #include "bugzilla_debug.h"
0015 #include "exceptions.h"
0016 
0017 namespace Bugzilla
0018 {
0019 QJsonDocument APIJob::document() const
0020 {
0021     ProtocolException::maybeThrow(this);
0022     Q_ASSERT(error() == KJob::NoError);
0023 
0024     auto document = QJsonDocument::fromJson(data());
0025     APIException::maybeThrow(document);
0026     return document;
0027 }
0028 
0029 QJsonObject APIJob::object() const
0030 {
0031     return document().object();
0032 }
0033 
0034 void APIJob::setAutoStart(bool start)
0035 {
0036     m_autostart = start;
0037 }
0038 
0039 void APIJob::connectNotify(const QMetaMethod &signal)
0040 {
0041     if (m_autostart && signal == QMetaMethod::fromSignal(&KJob::finished)) {
0042         qCDebug(BUGZILLA_LOG) << "auto starting";
0043         start();
0044     }
0045     KJob::connectNotify(signal);
0046 }
0047 
0048 NetworkAPIJob::NetworkAPIJob(const QUrl &url, const std::function<QNetworkReply *(QNetworkAccessManager &, QNetworkRequest &)> &starter, QObject *parent)
0049     : APIJob(parent)
0050 {
0051     m_manager.setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
0052     QNetworkRequest request(url);
0053     request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"_qba);
0054     request.setRawHeader("Accept"_qba, "application/json"_qba);
0055     request.setHeader(QNetworkRequest::UserAgentHeader, "DrKonqi"_qba);
0056 
0057     auto reply = starter(m_manager, request);
0058 
0059     connect(reply, &QIODevice::readyRead, this, [this, reply] {
0060         m_data += reply->readAll();
0061     });
0062 
0063     connect(reply, &QNetworkReply::finished, this, [this, reply] {
0064         reply->deleteLater();
0065 
0066         // Set errors, they are read by document() when the consumer reads
0067         // the data and possibly raised as exception.
0068         setError(reply->error());
0069         setErrorText(reply->errorString());
0070 
0071         // Force a delay on all API actions if configured. This allows
0072         // simulation of slow connections.
0073         static int delay = qEnvironmentVariableIntValue("DRKONQI_HTTP_DELAY_MS");
0074         if (delay > 0) {
0075             QTimer::singleShot(delay, this, [this] {
0076                 emitResult();
0077             });
0078             return;
0079         }
0080 
0081         emitResult();
0082     });
0083 
0084     connect(reply, &QNetworkReply::errorOccurred, this, [this, reply] {
0085         setError(reply->error());
0086         setErrorText(reply->errorString());
0087     });
0088 }
0089 
0090 } // namespace Bugzilla
0091 
0092 #include "moc_apijob.cpp"