Commit 0520bb30 authored by Volker Krause's avatar Volker Krause
Browse files

Unify UIC 918.3 outbound station extraction

This also adds ERA FCB support.
parent 4b601aff
......@@ -44,6 +44,7 @@ target_sources(KPimItinerary PRIVATE
engine/scriptextractor.cpp
era/fcbticket.cpp
era/fcbutil.cpp
era/ssbticketbase.cpp
era/ssbticketreader.cpp
era/ssbv1ticket.cpp
......
/*
SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "fcbutil.h"
using namespace KItinerary;
QString FcbUtil::stringifyUicStationIdentifier(int num, const QByteArray &ia5)
{
if (num >= 10'00000 && num <= 99'99999) {
return QLatin1String("uic:") + QString::number(num);
}
if (ia5.size() == 7) {
return QLatin1String("uic:") + QString::fromLatin1(ia5);
}
return {};
}
QString FcbUtil::stringifyStationIdentifier(bool numIsSet, int num, const QByteArray ia5)
{
if (numIsSet) {
return QString::number(num);
}
return QString::fromLatin1(ia5);
}
/*
SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef KITINERARY_FCBUTIL_H
#define KITINERARY_FCBUTIL_H
#include "fcbticket.h"
#include "logging.h"
#include <QString>
namespace KItinerary {
/** Higher-level decoding utilities for ERA FCB ticket data. */
class FcbUtil
{
public:
/** Departure station identifier for a travel document,
* in the format needed for output with our JSON-LD format.
*/
template <typename T>
static QString fromStationIdentifier(const T &doc)
{
switch (doc.stationCodeTable) {
case Fcb::stationUIC:
case Fcb::stationUICReservation:
return stringifyUicStationIdentifier(doc.fromStationNum, doc.fromStationIA5);
default:
qCWarning(Log) << "Unhandled station code table:" << doc.stationCodeTable;
}
return stringifyStationIdentifier(doc.fromStationNumIsSet(), doc.fromStationNum, doc.fromStationIA5);
}
/** Arrival station identifier for a travel document,
* in the format needed for output with our JSON-LD format.
*/
template <typename T>
static QString toStationIdentifier(const T &doc)
{
switch (doc.stationCodeTable) {
case Fcb::stationUIC:
case Fcb::stationUICReservation:
return stringifyUicStationIdentifier(doc.toStationNum, doc.toStationIA5);
default:
qCWarning(Log) << "Unhandled station code table:" << doc.stationCodeTable;
}
return stringifyStationIdentifier(doc.toStationNumIsSet(), doc.toStationNum, doc.toStationIA5);
}
private:
static QString stringifyUicStationIdentifier(int num, const QByteArray &ia5);
static QString stringifyStationIdentifier(bool numIsSet, int num, const QByteArray ia5);
};
}
#endif // KITINERARY_FCBUTIL_H
......@@ -78,8 +78,8 @@ static bool isValidTrip(const QJsonObject &trip)
}
return trip.contains(QLatin1String("departureDay"))
&& trip.value(QLatin1String("departureStation")).isObject()
&& trip.value(QLatin1String("arrivalStation")).isObject();
&& !trip.value(QLatin1String("departureStation")).toObject().value(QLatin1String("name")).toString().isEmpty()
&& !trip.value(QLatin1String("arrivalStation")).toObject().value(QLatin1String("name")).toString().isEmpty();
}
void Uic9183DocumentProcessor::preExtract(ExtractorDocumentNode &node, [[maybe_unused]] const ExtractorEngine *engine) const
......@@ -111,8 +111,8 @@ void Uic9183DocumentProcessor::preExtract(ExtractorDocumentNode &node, [[maybe_u
case Rct2Ticket::Transport:
case Rct2Ticket::Upgrade:
{
trip.insert(QStringLiteral("departureStation"), makeStation(rct2.outboundDepartureStation()));
trip.insert(QStringLiteral("arrivalStation"), makeStation(rct2.outboundArrivalStation()));
trip.insert(QStringLiteral("departureStation"), JsonLdDocument::toJson(p.outboundDepartureStation()));
trip.insert(QStringLiteral("arrivalStation"), JsonLdDocument::toJson(p.outboundArrivalStation()));
if (rct2.outboundDepartureTime().isValid()) {
trip.insert(QStringLiteral("departureDay"), JsonLdDocument::toJsonValue(rct2.outboundDepartureTime().date()));
......
......@@ -14,6 +14,7 @@
#include "vendor0080block.h"
#include "era/fcbticket.h"
#include "era/fcbutil.h"
#include <QDateTime>
#include <QDebug>
......@@ -403,6 +404,12 @@ TrainStation Uic9183Parser::outboundDepartureStation() const
{
TrainStation station;
// RTC2 ticket layout
if (const auto rtc2 = rct2Ticket(); rtc2.isValid()) {
station.setName(rtc2.outboundDepartureStation());
}
// DB vendor block
if (const auto b = findBlock<Vendor0080BLBlock>(); b.isValid()) {
if (const auto sblock = b.findSubBlock("015"); !sblock.isNull()) {
station.setName(sblock.toString());
......@@ -415,6 +422,20 @@ TrainStation Uic9183Parser::outboundDepartureStation() const
}
}
// ERA FCB
if (const auto fcb = findBlock<Fcb::UicRailTicketData>(); fcb.isValid() && !fcb.transportDocument.isEmpty()) {
const auto doc = fcb.transportDocument.at(0);
if (doc.ticket.userType() == qMetaTypeId<Fcb::ReservationData>()) {
const auto irt = doc.ticket.value<Fcb::ReservationData>();
station.setName(irt.fromStationNameUTF8);
station.setIdentifier(FcbUtil::fromStationIdentifier(irt));
} else if (doc.ticket.userType() == qMetaTypeId<Fcb::OpenTicketData>()) {
const auto nrt = doc.ticket.value<Fcb::OpenTicketData>();
station.setName(nrt.fromStationNameUTF8);
station.setIdentifier(FcbUtil::fromStationIdentifier(nrt));
}
}
return station;
}
......@@ -422,6 +443,11 @@ TrainStation Uic9183Parser::outboundArrivalStation() const
{
TrainStation station;
// RTC2 ticket layout
if (const auto rtc2 = rct2Ticket(); rtc2.isValid()) {
station.setName(rtc2.outboundArrivalStation());
}
if (const auto b = findBlock<Vendor0080BLBlock>(); b.isValid()) {
if (const auto sblock = b.findSubBlock("016"); !sblock.isNull()) {
station.setName(sblock.toString());
......@@ -434,6 +460,20 @@ TrainStation Uic9183Parser::outboundArrivalStation() const
}
}
// ERA FCB
if (const auto fcb = findBlock<Fcb::UicRailTicketData>(); fcb.isValid() && !fcb.transportDocument.isEmpty()) {
const auto doc = fcb.transportDocument.at(0);
if (doc.ticket.userType() == qMetaTypeId<Fcb::ReservationData>()) {
const auto irt = doc.ticket.value<Fcb::ReservationData>();
station.setName(irt.toStationNameUTF8);
station.setIdentifier(FcbUtil::toStationIdentifier(irt));
} else if (doc.ticket.userType() == qMetaTypeId<Fcb::OpenTicketData>()) {
const auto nrt = doc.ticket.value<Fcb::OpenTicketData>();
station.setName(nrt.toStationNameUTF8);
station.setIdentifier(FcbUtil::toStationIdentifier(nrt));
}
}
return station;
}
......
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