KItinerary

eradocumentprocessor.cpp
1/*
2 SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "eradocumentprocessor.h"
8#include "logging.h"
9
10#include "era/elbticket.h"
11#include "era/ssbticketreader.h"
12#include "era/ssbv1ticket.h"
13#include "era/ssbv2ticket.h"
14#include "era/ssbv3ticket.h"
15
16#include <KItinerary/ExtractorResult>
17
18#include <KItinerary/Reservation>
19#include <KItinerary/Ticket>
20#include <KItinerary/TrainTrip>
21
22using namespace KItinerary;
23
24bool ElbDocumentProcessor::canHandleData(const QByteArray &encodedData, [[maybe_unused]] QStringView fileName) const
25{
26 return ELBTicket::maybeELBTicket(encodedData);
27}
28
30{
32 if (const auto ticket = ELBTicket::parse(encodedData)) {
33 node.setContent(*ticket);
34 }
35 return node;
36}
37
38bool SsbDocumentProcessor::canHandleData(const QByteArray &encodedData, [[maybe_unused]] QStringView fileName) const
39{
40 return SSBTicketReader::maybeSSB(encodedData);
41}
42
44{
46 node.setContent(SSBTicketReader::read(encodedData));
47 return node;
48}
49
50TrainStation makeStation(int idType, const QString &alphaId, int numericId)
51{
52 TrainStation station;
53 if (idType == 0 && numericId > 10'00000 && numericId < 99'99999) {
54 station.setIdentifier(QLatin1StringView("uic:") +
55 QString::number(numericId));
56 station.setName(QString::number(numericId));
57 } else if (idType == 1 && alphaId.size() == 5 && std::all_of(alphaId.begin(), alphaId.end(), [](QChar c) { return c.isUpper(); })) {
58 // TODO is the identifier type defined in that case??
59 station.setName(alphaId);
60 }
61 return station;
62}
63
64void SsbDocumentProcessor::preExtract(ExtractorDocumentNode &node, [[maybe_unused]] const ExtractorEngine *engine) const
65{
66 if (node.isA<SSBv3Ticket>()) {
67 const auto ssb = node.content<SSBv3Ticket>();
68
69 Seat seat;
70 seat.setSeatingType(QString::number(ssb.classOfTravel()));
71 Ticket ticket;
72 ticket.setTicketToken(QLatin1StringView("aztecbin:") +
73 QString::fromLatin1(ssb.rawData().toBase64()));
74
75 Organization issuer;
76 issuer.setIdentifier(
77 QLatin1StringView("uic:") +
78 QString::number(ssb.issuerCode())); // left pad with 0 to 4 digets?
79 TrainTrip trip;
80 trip.setProvider(issuer);
81
83 res.setReservationNumber(ssb.tcn());
84 ticket.setTicketNumber(ssb.tcn());
85
86 switch (ssb.ticketTypeCode()) {
87 case SSBv3Ticket::IRT_RES_BOA:
88 trip.setDepartureDay(ssb.type1DepartureDay(node.contextDateTime()));
89 trip.setTrainNumber(ssb.type1TrainNumber());
90 seat.setSeatSection(QString::number(ssb.type1CoachNumber()));
91 seat.setSeatNumber(ssb.type1SeatNumber());
92 trip.setDepartureStation(makeStation(ssb.type1StationCodeNumericOrAlpha(), ssb.type1DepartureStationAlpha(), ssb.type1DepartureStationNum()));
93 trip.setDepartureStation(makeStation(ssb.type1StationCodeNumericOrAlpha(), ssb.type1ArrivalStationAlpha(), ssb.type1ArrivalStationNum()));
94 break;
95 case SSBv3Ticket::NRT:
96 trip.setDepartureStation(makeStation(ssb.type2StationCodeNumericOrAlpha(), ssb.type2DepartureStationAlpha(), ssb.type2DepartureStationNum()));
97 trip.setArrivalStation(makeStation(ssb.type2StationCodeNumericOrAlpha(), ssb.type2ArrivalStationAlpha(), ssb.type2ArrivalStationNum()));
98 ticket.setValidFrom(ssb.type2ValidFrom(node.contextDateTime()).startOfDay());
99 ticket.setValidUntil({ssb.type2ValidUntil(node.contextDateTime()), {23, 59, 59}});
100 trip.setDepartureDay(ssb.type2ValidFrom(node.contextDateTime()));
101 break;
102 case SSBv3Ticket::GRT:
103 case SSBv3Ticket::RPT:
104 qCWarning(Log) << "Unsupported SSB v3 ticket type:" << ssb.ticketTypeCode();
105 return;
106 }
107
108 res.setReservationFor(trip);
109 ticket.setTicketedSeat(seat);
110 res.setReservedTicket(ticket);
112 }
113}
ExtractorDocumentNode createNodeFromData(const QByteArray &encodedData) const override
Create a document node from raw data.
bool canHandleData(const QByteArray &encodedData, QStringView fileName) const override
Fast check whether the given encoded data can possibly be processed by this instance.
A node in the extracted document object tree.
bool isA() const
Checks if the content of this node is of type T.
QJSValue content
The decoded content of this node.
void addResult(ExtractorResult &&result)
Add additional results from an extraction step.
QDateTime contextDateTime
The best known context date/time at this point in the document tree.
void setContent(const QVariant &content)
Set decoded content.
Semantic data extraction engine.
ERA SSB ticket barcode (version 3).
Definition ssbv3ticket.h:20
A reserved seat.
Definition ticket.h:23
void preExtract(ExtractorDocumentNode &node, const ExtractorEngine *engine) const override
Called before extractors are applied to node.
ExtractorDocumentNode createNodeFromData(const QByteArray &encodedData) const override
Create a document node from raw data.
bool canHandleData(const QByteArray &encodedData, QStringView fileName) const override
Fast check whether the given encoded data can possibly be processed by this instance.
A booked ticket.
Definition ticket.h:41
A train reservation.
Train station.
Definition place.h:126
A train trip.
Definition traintrip.h:24
QVariant read(const QByteArray &data, int versionOverride=0)
Attempt to read an SSB ticket.
bool maybeSSB(const QByteArray &data)
Returns whether data could be an ERA SSB ticket.
Classes for reservation/travel data models, data extraction and data augmentation.
Definition berelement.h:17
iterator begin()
iterator end()
QString fromLatin1(QByteArrayView str)
QString number(double n, char format, int precision)
qsizetype size() const const
QVariant fromValue(T &&value)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:09:59 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.