File indexing completed on 2024-05-12 04:42:55

0001 /*
0002     SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
0003     SPDX-License-Identifier: LGPL-2.0-or-later
0004 */
0005 
0006 #include "restonboardbackend_p.h"
0007 #include "logging.h"
0008 #include "positiondata_p.h"
0009 
0010 #include "../../lib/json/jsonp_p.h"
0011 
0012 #include <KPublicTransport/Journey>
0013 
0014 #include <QFile>
0015 #include <QFileInfo>
0016 #include <QJsonArray>
0017 #include <QJsonDocument>
0018 #include <QJsonObject>
0019 #include <QNetworkAccessManager>
0020 #include <QNetworkReply>
0021 
0022 using namespace KPublicTransport;
0023 
0024 RestOnboardBackend::RestOnboardBackend(QObject *parent)
0025     : AbstractOnboardBackend(parent)
0026 {
0027 }
0028 
0029 RestOnboardBackend::~RestOnboardBackend() = default;
0030 
0031 static QString fakeResponseFile(QLatin1String key)
0032 {
0033     QFile configFile(qEnvironmentVariable("KPUBLICTRANSPORT_ONBOARD_FAKE_CONFIG"));
0034     if (!configFile.open(QFile::ReadOnly)) {
0035         qCWarning(Log) << configFile.errorString() << configFile.fileName();
0036         return {};
0037     }
0038 
0039     const auto path = QJsonDocument::fromJson(configFile.readAll()).object().value(key).toString();
0040     if (QFileInfo(path).isAbsolute()) {
0041         return path;
0042     }
0043 
0044     return QFileInfo(configFile.fileName()).absolutePath() + QLatin1Char('/') + path;
0045 }
0046 
0047 static QJsonObject fakeResponse(QLatin1String key)
0048 {
0049     QFile f(fakeResponseFile(key));
0050     if (!f.open(QFile::ReadOnly)) {
0051         qCWarning(Log) << f.errorString() << f.fileName();
0052         return {};
0053     }
0054 
0055     const auto doc = QJsonDocument::fromJson(JsonP::decode(f.readAll()));
0056     return doc.object();
0057 }
0058 
0059 void RestOnboardBackend::requestPosition(QNetworkAccessManager *nam)
0060 {
0061     if (Q_UNLIKELY(qEnvironmentVariableIsSet("KPUBLICTRANSPORT_ONBOARD_FAKE_CONFIG"))) {
0062         Q_EMIT positionReceived(parsePositionData(fakeResponse(QLatin1String("positionResponse"))));
0063         return;
0064     }
0065 
0066     if (!supportsPosition()) {
0067         return;
0068     }
0069 
0070     auto reply = nam->get(createPositionRequest());
0071     connect(reply, &QNetworkReply::finished, this, [this, reply]() {
0072         reply->deleteLater();
0073         if (reply->error() != QNetworkReply::NoError) {
0074             qCWarning(Log) << reply->url() << reply->errorString();
0075             Q_EMIT positionReceived({});
0076             return;
0077         }
0078 
0079         const auto doc = QJsonDocument::fromJson(JsonP::decode(reply->readAll()));
0080         if (doc.isArray()) {
0081             Q_EMIT positionReceived(parsePositionData(doc.array()));
0082         } else {
0083             Q_EMIT positionReceived(parsePositionData(doc.object()));
0084         }
0085     });
0086 }
0087 
0088 void RestOnboardBackend::requestJourney(QNetworkAccessManager *nam)
0089 {
0090     if (Q_UNLIKELY(qEnvironmentVariableIsSet("KPUBLICTRANSPORT_ONBOARD_FAKE_CONFIG"))) {
0091         Q_EMIT journeyReceived(parseJourneyData(fakeResponse(QLatin1String("journeyResponse"))));
0092         return;
0093     }
0094 
0095     if (!supportsJourney()) {
0096         return;
0097     }
0098 
0099     auto reply = nam->get(createJourneyRequest());
0100     connect(reply, &QNetworkReply::finished, this, [this, reply]() {
0101         reply->deleteLater();
0102         if (reply->error() != QNetworkReply::NoError) {
0103             qCWarning(Log) << reply->url() << reply->errorString();
0104             Q_EMIT journeyReceived({});
0105             return;
0106         }
0107 
0108         const auto doc = QJsonDocument::fromJson(reply->readAll());
0109         if (doc.isArray()) {
0110             Q_EMIT journeyReceived(parseJourneyData(doc.array()));
0111         } else {
0112             Q_EMIT journeyReceived(parseJourneyData(doc.object()));
0113         }
0114     });
0115 }