Commit 74b5c013 authored by Volker Krause's avatar Volker Krause
Browse files

Validate IFOPT ids in the IVV ASS parser before using them

There seem to be invalid values in the IFOPT field for rental vehicles
(which makes sense, there are no IFOPT ids for those), so put those into
a backend specific identifier instead.
parent e79574ef
......@@ -76,7 +76,7 @@
},
{
"identifier": {
"ifopt": "v:kvb-rad:21596"
"vrs": "v:kvb-rad:21596"
},
"latitude": 50.9398193359375,
"longitude": 6.957879066467285,
......@@ -88,7 +88,7 @@
},
{
"identifier": {
"ifopt": "v:kvb-rad:210004"
"vrs": "v:kvb-rad:210004"
},
"latitude": 50.93911361694336,
"longitude": 6.958240032196045,
......
......@@ -4,6 +4,7 @@
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "ifopt/ifoptutil.cpp"
#include "backends/ivvassparser.cpp"
#include <KPublicTransport/Journey>
......@@ -51,7 +52,7 @@ private Q_SLOTS:
QFETCH(QString, inFileName);
QFETCH(QString, outFileName);
IvvAssParser p(QTimeZone("Europe/Berlin"));
IvvAssParser p(QTimeZone("Europe/Berlin"), s("vrs"));
const auto result = p.parseLocations(readFile(inFileName));
QVERIFY(!result.empty());
QVERIFY(p.errorMessage.isEmpty());
......@@ -79,7 +80,7 @@ private Q_SLOTS:
QFETCH(QString, inFileName);
QFETCH(QString, outFileName);
IvvAssParser p(QTimeZone("Europe/Berlin"));
IvvAssParser p(QTimeZone("Europe/Berlin"), s("vrs"));
const auto result = p.parseStopovers(readFile(inFileName));
QVERIFY(!result.empty());
QVERIFY(p.errorMessage.isEmpty());
......@@ -113,7 +114,7 @@ private Q_SLOTS:
QFETCH(QString, inFileName);
QFETCH(QString, outFileName);
IvvAssParser p(QTimeZone("Europe/Berlin"));
IvvAssParser p(QTimeZone("Europe/Berlin"), s("vrs"));
const auto result = p.parseJourneys(readFile(inFileName));
QVERIFY(!result.empty());
QVERIFY(p.errorMessage.isEmpty());
......@@ -129,17 +130,17 @@ private Q_SLOTS:
void testParseError()
{
{
IvvAssParser p(QTimeZone("Europe/Berlin"));
IvvAssParser p(QTimeZone("Europe/Berlin"), s("vrs"));
const auto res = p.parseLocations(R"({"error":"Ung\u00fcltige Zeit"})");
QVERIFY(!p.errorMessage.isEmpty());
}
{
IvvAssParser p(QTimeZone("Europe/Berlin"));
IvvAssParser p(QTimeZone("Europe/Berlin"), s("vrs"));
const auto res = p.parseStopovers(R"({"error":"Fehlerhaftes Ziel"})");
QVERIFY(!p.errorMessage.isEmpty());
}
{
IvvAssParser p(QTimeZone("Europe/Berlin"));
IvvAssParser p(QTimeZone("Europe/Berlin"), s("vrs"));
const auto res = p.parseJourneys(R"({"error":"Fehlerhafter Start"})");
QVERIFY(!p.errorMessage.isEmpty());
}
......
......@@ -73,7 +73,7 @@ bool IvvAssBackend::queryLocation(const LocationRequest &req, LocationReply *rep
return;
}
IvvAssParser p(timeZone());
IvvAssParser p(timeZone(), backendId());
auto result = p.parseLocations(data);
if (p.errorMessage.isEmpty()) {
Cache::addLocationCacheEntry(backendId(), reply->request().cacheKey(), result, {});
......@@ -121,7 +121,7 @@ bool IvvAssBackend::queryStopover(const StopoverRequest &req, StopoverReply *rep
return;
}
IvvAssParser p(timeZone());
IvvAssParser p(timeZone(), backendId());
auto result = p.parseStopovers(data);
if (p.errorMessage.isEmpty()) {
addResult(reply, this, std::move(result));
......@@ -185,7 +185,7 @@ bool IvvAssBackend::queryJourney(const JourneyRequest &req, JourneyReply *reply,
return;
}
IvvAssParser p(timeZone());
IvvAssParser p(timeZone(), backendId());
auto result = p.parseJourneys(data);
if (p.errorMessage.isEmpty()) {
addResult(reply, this, std::move(result));
......
......@@ -5,10 +5,10 @@
*/
#include "ivvassparser.h"
#include "ifopt/ifoptutil.h"
#include <KPublicTransport/Equipment>
#include <KPublicTransport/Journey>
#include <KPublicTransport/Location>
#include <KPublicTransport/Stopover>
#include <QByteArray>
......@@ -22,18 +22,13 @@
using namespace KPublicTransport;
IvvAssParser::IvvAssParser(const QTimeZone &tz)
IvvAssParser::IvvAssParser(const QTimeZone &tz, const QString &locationIdentifier)
: m_timezone(tz)
, m_locationIdentifier(locationIdentifier)
{
}
struct LocationData
{
Location loc;
QString platform;
};
static LocationData parseLocation(const QJsonObject &stopObj)
IvvAssParser::LocationData IvvAssParser::parseLocation(const QJsonObject &stopObj) const
{
LocationData r;
r.loc.setLatitude(stopObj.value(QLatin1String("lat")).toDouble(NAN));
......@@ -57,7 +52,12 @@ static LocationData parseLocation(const QJsonObject &stopObj)
return r;
}
r.loc.setIdentifier(QStringLiteral("ifopt"), stopObj.value(QLatin1String("ifopt")).toString());
const auto id = stopObj.value(QLatin1String("ifopt")).toString();
if (IfoptUtil::isValid(id)) {
r.loc.setIdentifier(QStringLiteral("ifopt"), id);
} else {
r.loc.setIdentifier(m_locationIdentifier, id);
}
// location is a platform: split out platform name
if (stopObj.value(QLatin1String("subtype")).toString() == QLatin1String("Post")) {
......
......@@ -7,6 +7,8 @@
#ifndef KPUBLICTRANSPORT_IVVASSPARSER_H
#define KPUBLICTRANSPORT_IVVASSPARSER_H
#include <KPublicTransport/Location>
#include <QDateTime>
#include <QString>
#include <QTimeZone>
......@@ -18,7 +20,6 @@ class QJsonObject;
namespace KPublicTransport {
class Location;
class Journey;
class Stopover;
......@@ -26,7 +27,7 @@ class Stopover;
class IvvAssParser
{
public:
explicit IvvAssParser(const QTimeZone &tz);
explicit IvvAssParser(const QTimeZone &tz, const QString &locationIdentifier);
std::vector<Location> parseLocations(const QByteArray &data);
std::vector<Stopover> parseStopovers(const QByteArray &data);
......@@ -43,7 +44,15 @@ private:
};
EventTime parseTime(const QJsonObject &obj, const char *baseKey, const char *scheduledKey) const;
struct LocationData
{
Location loc;
QString platform;
};
LocationData parseLocation(const QJsonObject &stopObj) const;
QTimeZone m_timezone;
QString m_locationIdentifier;
};
}
......
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