Commit 62936314 authored by Volker Krause's avatar Volker Krause
Browse files

Support previous/next departure queries for EFA as well

parent 52dd085d
Pipeline #75698 passed with stage
in 20 seconds
......@@ -8,7 +8,7 @@
</pa>
<pa>
<n>sessionID</n>
<v>0</v>
<v>123456789</v>
</pa>
</pas>
<dps>
......
<?xml version="1.0" encoding="UTF-8"?>
<itdRequest language="de" lengthUnit="METER" sessionID="0" virtDir="vgnExt">
<itdRequest language="de" lengthUnit="METER" sessionID="123456789" virtDir="vgnExt">
<itdDepartureMonitorRequest requestID="0">
<itdOdv type="any" usage="dm" anyObjFilter="0">
<itdOdvPlace state="identified" method="itp">
......
......@@ -138,6 +138,10 @@ private Q_SLOTS:
}
QVERIFY(!jsonRes.empty());
QCOMPARE(jsonRes, ref);
QVERIFY(!parser.requestContext().isEmpty());
QCOMPARE(parser.requestContext().sessionId, QLatin1String("123456789"));
QCOMPARE(parser.requestContext().requestId, QLatin1String("0"));
}
void testParseCompactDepartures_data()
......@@ -168,6 +172,10 @@ private Q_SLOTS:
}
QVERIFY(!jsonRes.empty());
QCOMPARE(jsonRes, ref);
QVERIFY(!parser.requestContext().isEmpty());
QCOMPARE(parser.requestContext().sessionId, QLatin1String("123456789"));
QCOMPARE(parser.requestContext().requestId, QLatin1String("0"));
}
void testParseTrips_data()
......@@ -205,9 +213,9 @@ private Q_SLOTS:
QVERIFY(!jsonRes.empty());
QCOMPARE(jsonRes, ref);
QVERIFY(!parser.journeyQueryContext().isEmpty());
QCOMPARE(parser.journeyQueryContext().sessionId, QLatin1String("123456789"));
QCOMPARE(parser.journeyQueryContext().requestId, QLatin1String("0"));
QVERIFY(!parser.requestContext().isEmpty());
QCOMPARE(parser.requestContext().sessionId, QLatin1String("123456789"));
QCOMPARE(parser.requestContext().requestId, QLatin1String("0"));
}
void testParseCompactTrips_data()
......@@ -239,9 +247,9 @@ private Q_SLOTS:
QVERIFY(!jsonRes.empty());
QCOMPARE(jsonRes, ref);
QVERIFY(!parser.journeyQueryContext().isEmpty());
QCOMPARE(parser.journeyQueryContext().sessionId, QLatin1String("123456789"));
QCOMPARE(parser.journeyQueryContext().requestId, QLatin1String("0"));
QVERIFY(!parser.requestContext().isEmpty());
QCOMPARE(parser.requestContext().sessionId, QLatin1String("123456789"));
QCOMPARE(parser.requestContext().requestId, QLatin1String("0"));
}
};
......
......@@ -34,7 +34,7 @@ EfaBackend::~EfaBackend() = default;
AbstractBackend::Capabilities EfaBackend::capabilities() const
{
return (m_endpoint.startsWith(QLatin1String("https")) ? Secure : NoCapability)
| CanQueryNextJourney | CanQueryPreviousJourney;
| CanQueryNextJourney | CanQueryPreviousJourney | CanQueryNextDeparture | CanQueryPreviousDeparture;
}
bool EfaBackend::needsLocationQuery(const Location &loc, AbstractBackend::QueryType type) const
......@@ -108,23 +108,40 @@ bool EfaBackend::queryStopover(const StopoverRequest &request, StopoverReply *re
dt = dt.toTimeZone(timeZone());
}
const auto ctx = requestContextData(request).value<EfaRequestContext>();
auto query = commonQuery();
if (stopId.isEmpty()) {
query.addQueryItem(QStringLiteral("type_dm"), QStringLiteral("coord"));
query.addQueryItem(QStringLiteral("name_dm"), QString::number(request.stop().longitude()) + QLatin1Char(':') + QString::number(request.stop().latitude()) + QLatin1String(":WGS84[DD.ddddd]"));
if (ctx.isEmpty()) {
if (stopId.isEmpty()) {
query.addQueryItem(QStringLiteral("type_dm"), QStringLiteral("coord"));
query.addQueryItem(QStringLiteral("name_dm"), QString::number(request.stop().longitude()) + QLatin1Char(':') + QString::number(request.stop().latitude()) + QLatin1String(":WGS84[DD.ddddd]"));
} else {
query.addQueryItem(QStringLiteral("type_dm"), QStringLiteral("stop"));
query.addQueryItem(QStringLiteral("name_dm"), stopId);
}
query.addQueryItem(QStringLiteral("itdDate"), dt.date().toString(QStringLiteral("yyyyMMdd")));
query.addQueryItem(QStringLiteral("itdTime"), dt.time().toString(QStringLiteral("hhmm")));
query.addQueryItem(QStringLiteral("useRealtime"), QStringLiteral("1"));
query.addQueryItem(QStringLiteral("limit"), QString::number(request.maximumResults()));
// not exactly sure what these do, but without this the result is missing departure times
query.addQueryItem(QStringLiteral("mode"), QStringLiteral("direct"));
query.addQueryItem(QStringLiteral("ptOptionsActive"), QStringLiteral("1"));
query.addQueryItem(QStringLiteral("merge_dep"), QStringLiteral("1"));
// enable support for previous/next queries
query.addQueryItem(QStringLiteral("stateless"), QStringLiteral("1"));
query.addQueryItem(QStringLiteral("sessionID"), QStringLiteral("0"));
query.addQueryItem(QStringLiteral("requestID"), QStringLiteral("0"));
} else {
query.addQueryItem(QStringLiteral("type_dm"), QStringLiteral("stop"));
query.addQueryItem(QStringLiteral("name_dm"), stopId);
query.addQueryItem(QStringLiteral("stateless"), QStringLiteral("1"));
query.addQueryItem(QStringLiteral("sessionID"), ctx.sessionId);
query.addQueryItem(QStringLiteral("requestID"), ctx.requestId);
if (requestContext(request).type == RequestContext::Next) {
query.addQueryItem(QStringLiteral("command"), QStringLiteral("dmNext"));
} else {
query.addQueryItem(QStringLiteral("command"), QStringLiteral("dmPrev"));
}
}
query.addQueryItem(QStringLiteral("itdDate"), dt.date().toString(QStringLiteral("yyyyMMdd")));
query.addQueryItem(QStringLiteral("itdTime"), dt.time().toString(QStringLiteral("hhmm")));
query.addQueryItem(QStringLiteral("useRealtime"), QStringLiteral("1"));
query.addQueryItem(QStringLiteral("limit"), QString::number(request.maximumResults()));
// not exactly sure what these do, but without this the result is missing departure times
query.addQueryItem(QStringLiteral("mode"), QStringLiteral("direct"));
query.addQueryItem(QStringLiteral("ptOptionsActive"), QStringLiteral("1"));
query.addQueryItem(QStringLiteral("merge_dep"), QStringLiteral("1"));
url.setQuery(query);
......@@ -146,6 +163,8 @@ bool EfaBackend::queryStopover(const StopoverRequest &request, StopoverReply *re
if (p->error() != Reply::NoError) {
addError(reply, p->error(), p->errorMessage());
} else {
setNextRequestContext(reply, QVariant::fromValue(p->requestContext()));
setPreviousRequestContext(reply, QVariant::fromValue(p->requestContext()));
addResult(reply, this, std::move(res));
}
});
......@@ -168,7 +187,7 @@ bool EfaBackend::queryJourney(const JourneyRequest &request, JourneyReply *reply
QUrl url(m_endpoint);
url.setPath(url.path() + (m_tripRequestCommand.isEmpty() ? QLatin1String("XML_TRIP_REQUEST2") : m_tripRequestCommand));
const auto ctx = requestContextData(request).value<EfaJourneyQueryContext>();
const auto ctx = requestContextData(request).value<EfaRequestContext>();
auto query = commonQuery();
if (ctx.isEmpty()) {
query.addQueryItem(QStringLiteral("locationServerActive"), QStringLiteral("1"));
......@@ -238,8 +257,8 @@ bool EfaBackend::queryJourney(const JourneyRequest &request, JourneyReply *reply
if (p->error() != Reply::NoError) {
addError(reply, p->error(), p->errorMessage());
} else {
setNextRequestContext(reply, QVariant::fromValue(p->journeyQueryContext()));
setPreviousRequestContext(reply, QVariant::fromValue(p->journeyQueryContext()));
setNextRequestContext(reply, QVariant::fromValue(p->requestContext()));
setPreviousRequestContext(reply, QVariant::fromValue(p->requestContext()));
addResult(reply, this, std::move(res));
}
});
......
......@@ -196,7 +196,11 @@ std::vector<Stopover> EfaCompactParser::parseDmResponse(const QByteArray &data)
QXmlStreamReader xsr(data);
ScopedXmlStreamReader reader(xsr);
while (reader.readNextElement()) {
if (reader.name() == QLatin1String("dp")) {
if (reader.name() == QLatin1String("pas")) {
const auto pas = parseKeyValueList(reader.subReader(), QLatin1String("pa"), QLatin1String("n"), QLatin1String("v"));
m_requestContext.sessionId = pas.value(QLatin1String("sessionID"));
m_requestContext.requestId = pas.value(QLatin1String("requestID"));
} else if (reader.name() == QLatin1String("dp")) {
res.push_back(parseCompactDp(reader.subReader()));
}
}
......@@ -410,8 +414,8 @@ std::vector<Journey> EfaCompactParser::parseTripResponse(const QByteArray &data)
while (reader.readNextElement()) {
if (reader.name() == QLatin1String("pas")) {
const auto pas = parseKeyValueList(reader.subReader(), QLatin1String("pa"), QLatin1String("n"), QLatin1String("v"));
m_journeyContext.sessionId = pas.value(QLatin1String("sessionID"));
m_journeyContext.requestId = pas.value(QLatin1String("requestID"));
m_requestContext.sessionId = pas.value(QLatin1String("sessionID"));
m_requestContext.requestId = pas.value(QLatin1String("requestID"));
} else if (reader.name() == QLatin1String("tp")) {
res.push_back(parseCompactTp(reader.subReader()));
}
......
......@@ -12,7 +12,7 @@
using namespace KPublicTransport;
bool EfaJourneyQueryContext::isEmpty() const
bool EfaRequestContext::isEmpty() const
{
return sessionId.isEmpty() || requestId.isEmpty() || sessionId == QLatin1String("0");
}
......@@ -95,9 +95,9 @@ bool EfaParser::isDummyStopId(QStringView id)
return id == QLatin1String("99999997") || id == QLatin1String("99999998");
}
EfaJourneyQueryContext EfaParser::journeyQueryContext() const
EfaRequestContext EfaParser::requestContext() const
{
return m_journeyContext;
return m_requestContext;
}
QHash<QString, QString> EfaParser::parseKeyValueList(ScopedXmlStreamReader &&reader, QLatin1String elemName, QLatin1String keyName, QLatin1String valueName)
......
......@@ -32,7 +32,7 @@ class Stopover;
/** Journey query context for previous/next queries.
* @internal only exported for unit tests
*/
class KPUBLICTRANSPORT_EXPORT EfaJourneyQueryContext
class KPUBLICTRANSPORT_EXPORT EfaRequestContext
{
public:
QString sessionId;
......@@ -58,7 +58,7 @@ public:
virtual std::vector<Stopover> parseDmResponse(const QByteArray &data) = 0;
virtual std::vector<Journey> parseTripResponse(const QByteArray &data) = 0;
EfaJourneyQueryContext journeyQueryContext() const;
EfaRequestContext requestContext() const;
protected:
/** convert "means of transport" type id to Line::Mode
......@@ -81,11 +81,11 @@ protected:
QString m_locationIdentifierType;
QString m_errorMsg;
Reply::Error m_error = Reply::NoError;
EfaJourneyQueryContext m_journeyContext;
EfaRequestContext m_requestContext;
};
}
Q_DECLARE_METATYPE(KPublicTransport::EfaJourneyQueryContext)
Q_DECLARE_METATYPE(KPublicTransport::EfaRequestContext)
#endif // KPUBLICTRANSPORT_EFAPARSER_H
......@@ -182,7 +182,11 @@ std::vector<Stopover> EfaXmlParser::parseDmResponse(const QByteArray &data)
QXmlStreamReader xsr(data);
ScopedXmlStreamReader reader(xsr);
while (reader.readNextElement()) {
if (reader.name() == QLatin1String("itdOdvAssignedStop") && reader.attributes().hasAttribute(QLatin1String("stopID"))) {
if (reader.name() == QLatin1String("itdRequest")) {
m_requestContext.sessionId = reader.attributes().value(QLatin1String("sessionID")).toString();
} else if (reader.name() == QLatin1String("itdDepartureMonitorRequest")) {
m_requestContext.requestId = reader.attributes().value(QLatin1String("requestID")).toString();
} else if (reader.name() == QLatin1String("itdOdvAssignedStop") && reader.attributes().hasAttribute(QLatin1String("stopID"))) {
const auto loc = parseItdOdvAssignedStop(reader);
m_locations[loc.identifier(m_locationIdentifierType)] = loc;
} else if (reader.name() == QLatin1String("itdDeparture")) {
......@@ -426,9 +430,9 @@ std::vector<Journey> EfaXmlParser::parseTripResponse(const QByteArray &data)
ScopedXmlStreamReader reader(xsr);
while (reader.readNextElement()) {
if (reader.name() == QLatin1String("itdRequest")) {
m_journeyContext.sessionId = reader.attributes().value(QLatin1String("sessionID")).toString();
m_requestContext.sessionId = reader.attributes().value(QLatin1String("sessionID")).toString();
} else if (reader.name() == QLatin1String("itdTripRequest")) {
m_journeyContext.requestId = reader.attributes().value(QLatin1String("requestID")).toString();
m_requestContext.requestId = reader.attributes().value(QLatin1String("requestID")).toString();
} else if (reader.name() == QLatin1String("itdRoute")) {
res.push_back(parseTripRoute(reader.subReader()));
}
......
Supports Markdown
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