6#include "scriptedrestonboardbackend_p.h"
8#include "positiondata_p.h"
10#include "../lib/datatypes/journeyutil_p.h"
12#include <KPublicTransport/Journey>
13#include <KPublicTransport/Stopover>
19#include <QNetworkRequest>
26ScriptedRestOnboardBackend::ScriptedRestOnboardBackend(
QObject *parent)
27 : RestOnboardBackend(parent)
31ScriptedRestOnboardBackend::~ScriptedRestOnboardBackend()
33 if (m_watchdogTimer) {
34 m_watchdogTimer->deleteLater();
36 m_watchdogThread.quit();
37 m_watchdogThread.wait();
40bool ScriptedRestOnboardBackend::supportsPosition()
const
42 return m_positionEndpoint.isValid();
45bool ScriptedRestOnboardBackend::supportsJourney()
const
47 return m_journeyEndpoint.isValid();
50QNetworkRequest ScriptedRestOnboardBackend::createPositionRequest()
const
60static double strictToNumber(
const QJSValue &val)
68 return result ? n : NAN;
73PositionData ScriptedRestOnboardBackend::parsePositionData(
const QJsonValue &response)
const
79 const auto watchdogStop = qScopeGuard([
this]() {
82 m_engine->setInterrupted(
false);
84 auto func = m_engine->globalObject().property(m_positionFunction);
85 if (!func.isCallable()) {
86 qCWarning(
Log) <<
"Script entry point not found!" << m_positionFunction;
90 const auto arg = m_engine->toScriptValue(response);
91 const auto result = func.call(QJSValueList{arg});
92 if (result.isError()) {
93 printScriptError(result);
100 pos.latitude = strictToNumber(result.property(QStringLiteral(
"latitude")));
101 pos.longitude = strictToNumber(result.property(QStringLiteral(
"longitude")));
102 pos.speed = strictToNumber(result.property(QStringLiteral(
"speed")));
103 pos.heading = strictToNumber(result.property(QStringLiteral(
"heading")));
104 pos.altitude = strictToNumber(result.property(QStringLiteral(
"altitude")));
108Journey ScriptedRestOnboardBackend::parseJourneyData(
const QJsonValue &response)
const
114 const auto watchdogStop = qScopeGuard([
this]() {
117 m_engine->setInterrupted(
false);
119 auto func = m_engine->globalObject().property(m_journeyFunction);
120 if (!func.isCallable()) {
121 qCWarning(
Log) <<
"Script entry point not found!" << m_journeyFunction;
125 const auto arg = m_engine->toScriptValue(response);
126 const auto result = func.call(QJSValueList{arg});
127 if (result.isError()) {
128 printScriptError(result);
134 auto sections = jny.takeSections();
136 for (
auto §ion : sections) {
137 auto stops = section.takeIntermediateStops();
140 if (section.from().isEmpty() && !stops.empty()) {
141 const auto s = stops.front();
142 section.setDeparture(s);
143 stops.erase(stops.begin());
146 if (section.to().isEmpty() && !stops.empty()) {
147 const auto s = stops.back();
148 section.setArrival(s);
152 section.setIntermediateStops(std::move(stops));
155 jny.setSections(std::move(sections));
156 JourneyUtil::propagateTimeZones(jny);
160void ScriptedRestOnboardBackend::setupEngine()
const
168 m_watchdogThread.start();
169 m_watchdogTimer =
new QTimer;
170 m_watchdogTimer->
setInterval(std::chrono::milliseconds(500));
171 m_watchdogTimer->setSingleShot(
true);
172 m_watchdogTimer->moveToThread(&m_watchdogThread);
178 qCWarning(
Log) <<
"Failed to open extractor script" << f.fileName() << f.errorString();
182 const auto result = m_engine->evaluate(
QString::fromUtf8(f.readAll()), f.fileName());
183 if (result.isError()) {
184 printScriptError(result);
189void ScriptedRestOnboardBackend::printScriptError(
const QJSValue &error)
const
191 qCWarning(
Log) <<
"JS ERROR: " << m_scriptName <<
error.property(
QLatin1String(
"lineNumber")).toInt() <<
": " <<
error.toString();
static Journey fromJson(const QJsonObject &obj)
Deserialize an object from JSON.
char * toString(const EngineQuery &query)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
Query operations and data types for accessing realtime public transport information from online servi...
QDateTime fromString(QStringView string, QStringView format, QCalendar cal)
QJsonValue fromVariant(const QVariant &variant)
QJsonObject toObject() const const
bool isNumber() const const
bool isString() const const
double toNumber() const const
QString toString() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString fromUtf8(QByteArrayView str)
double toDouble(bool *ok) const const
void setInterval(int msec)