File indexing completed on 2024-12-29 04:51:00
0001 /* 0002 SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "eradocumentprocessor.h" 0008 #include "logging.h" 0009 0010 #include "era/elbticket.h" 0011 #include "era/ssbticketreader.h" 0012 #include "era/ssbv1ticket.h" 0013 #include "era/ssbv2ticket.h" 0014 #include "era/ssbv3ticket.h" 0015 0016 #include <KItinerary/ExtractorResult> 0017 0018 #include <KItinerary/Reservation> 0019 #include <KItinerary/Ticket> 0020 #include <KItinerary/TrainTrip> 0021 0022 using namespace KItinerary; 0023 0024 bool ElbDocumentProcessor::canHandleData(const QByteArray &encodedData, [[maybe_unused]] QStringView fileName) const 0025 { 0026 return ELBTicket::maybeELBTicket(encodedData); 0027 } 0028 0029 ExtractorDocumentNode ElbDocumentProcessor::createNodeFromData(const QByteArray &encodedData) const 0030 { 0031 ExtractorDocumentNode node; 0032 if (const auto ticket = ELBTicket::parse(encodedData)) { 0033 node.setContent(*ticket); 0034 } 0035 return node; 0036 } 0037 0038 bool SsbDocumentProcessor::canHandleData(const QByteArray &encodedData, [[maybe_unused]] QStringView fileName) const 0039 { 0040 return SSBv3Ticket::maybeSSB(encodedData) || SSBv2Ticket::maybeSSB(encodedData) || SSBv1Ticket::maybeSSB(encodedData); 0041 } 0042 0043 ExtractorDocumentNode SsbDocumentProcessor::createNodeFromData(const QByteArray &encodedData) const 0044 { 0045 ExtractorDocumentNode node; 0046 node.setContent(SSBTicketReader::read(encodedData)); 0047 return node; 0048 } 0049 0050 TrainStation makeStation(int idType, const QString &alphaId, int numericId) 0051 { 0052 TrainStation station; 0053 if (idType == 0 && numericId > 10'00000 && numericId < 99'99999) { 0054 station.setIdentifier(QLatin1StringView("uic:") + 0055 QString::number(numericId)); 0056 station.setName(QString::number(numericId)); 0057 } else if (idType == 1 && alphaId.size() == 5 && std::all_of(alphaId.begin(), alphaId.end(), [](QChar c) { return c.isUpper(); })) { 0058 // TODO is the identifier type defined in that case?? 0059 station.setName(alphaId); 0060 } 0061 return station; 0062 } 0063 0064 void SsbDocumentProcessor::preExtract(ExtractorDocumentNode &node, [[maybe_unused]] const ExtractorEngine *engine) const 0065 { 0066 if (node.isA<SSBv3Ticket>()) { 0067 const auto ssb = node.content<SSBv3Ticket>(); 0068 0069 Seat seat; 0070 seat.setSeatingType(QString::number(ssb.classOfTravel())); 0071 Ticket ticket; 0072 ticket.setTicketToken(QLatin1StringView("aztecbin:") + 0073 QString::fromLatin1(ssb.rawData().toBase64())); 0074 0075 Organization issuer; 0076 issuer.setIdentifier( 0077 QLatin1StringView("uic:") + 0078 QString::number(ssb.issuerCode())); // left pad with 0 to 4 digets? 0079 TrainTrip trip; 0080 trip.setProvider(issuer); 0081 0082 TrainReservation res; 0083 res.setReservationNumber(ssb.tcn()); 0084 ticket.setTicketNumber(ssb.tcn()); 0085 0086 switch (ssb.ticketTypeCode()) { 0087 case SSBv3Ticket::IRT_RES_BOA: 0088 trip.setDepartureDay(ssb.type1DepartureDay(node.contextDateTime())); 0089 trip.setTrainNumber(ssb.type1TrainNumber()); 0090 seat.setSeatSection(QString::number(ssb.type1CoachNumber())); 0091 seat.setSeatNumber(ssb.type1SeatNumber()); 0092 trip.setDepartureStation(makeStation(ssb.type1StationCodeNumericOrAlpha(), ssb.type1DepartureStationAlpha(), ssb.type1DepartureStationNum())); 0093 trip.setDepartureStation(makeStation(ssb.type1StationCodeNumericOrAlpha(), ssb.type1ArrivalStationAlpha(), ssb.type1ArrivalStationNum())); 0094 break; 0095 case SSBv3Ticket::NRT: 0096 trip.setDepartureStation(makeStation(ssb.type2StationCodeNumericOrAlpha(), ssb.type2DepartureStationAlpha(), ssb.type2DepartureStationNum())); 0097 trip.setArrivalStation(makeStation(ssb.type2StationCodeNumericOrAlpha(), ssb.type2ArrivalStationAlpha(), ssb.type2ArrivalStationNum())); 0098 ticket.setValidFrom(ssb.type2ValidFrom(node.contextDateTime()).startOfDay()); 0099 ticket.setValidUntil({ssb.type2ValidUntil(node.contextDateTime()), {23, 59, 59}}); 0100 trip.setDepartureDay(ssb.type2ValidFrom(node.contextDateTime())); 0101 break; 0102 case SSBv3Ticket::GRT: 0103 case SSBv3Ticket::RPT: 0104 qCWarning(Log) << "Unsupported SSB v3 ticket type:" << ssb.ticketTypeCode(); 0105 return; 0106 } 0107 0108 res.setReservationFor(trip); 0109 ticket.setTicketedSeat(seat); 0110 res.setReservedTicket(ticket); 0111 node.addResult(QList<QVariant>{QVariant::fromValue(res)}); 0112 } 0113 }