File indexing completed on 2024-12-29 04:51:06
0001 /* 0002 SPDX-FileCopyrightText: 2019 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 // see https://community.kde.org/KDE_PIM/KItinerary/Trenitalia_Barcode 0008 function parseSsb(ssb, node) { 0009 let res = JsonLd.newTrainReservation(); 0010 res.reservationFor.departureStation.name = "" + (ssb.departureStationNum % 10000000); 0011 res.reservationFor.departureStation.identifier = "uic:" + (ssb.departureStationNum % 10000000); 0012 if (ssb.departureStationNum != ssb.arrivalStationNum) { 0013 res.reservationFor.arrivalStation.name = "" + (ssb.arrivalStationNum % 10000000); 0014 res.reservationFor.arrivalStation.identifier = "uic:" + (ssb.arrivalStationNum % 10000000); 0015 } 0016 res.reservationFor.provider.identifier = "uic:" + ssb.issuerCode; 0017 if (ssb.customerNumber > 0) { 0018 res.programMembershipUsed.membershipNumber = ssb.customerNumber; 0019 res.programMembershipUsed.programName = "CartaFRECCIA"; 0020 } 0021 0022 if (ssb.firstDayOfValidityDay == ssb.lastDayOfValidityDay) { 0023 res.reservationFor.departureDay = ssb.firstDayOfValidity(node.contextDateTime) 0024 } 0025 0026 res.reservationFor.trainNumber = ssb.readNumber(22*8 + 2, 16); 0027 0028 const seatNum = ssb.readNumber(31*8 + 2, 7); 0029 const seatCol = ssb.readNumber(32*8 + 3, 4); 0030 if (seatNum > 0 && (seatNum != 99 || seatCol != 9)) { 0031 res.reservedTicket.ticketedSeat.seatNumber = "" + seatNum; 0032 if (seatCol > 0) { 0033 res.reservedTicket.ticketedSeat.seatNumber += seatCol.toString(16).toUpperCase(); 0034 } 0035 0036 res.reservedTicket.ticketedSeat.seatSection = ssb.readNumber(30*8 +6, 4) 0037 } 0038 0039 res.reservationNumber = ssb.readString(33*8 + 6, 6); 0040 if (res.reservationNumber === '000000') { 0041 res.reservationNumber = ssb.readNumber(58*8 + 4, 32); 0042 } 0043 0044 res.reservedTicket.ticketToken = "aztecbin:" + ByteArray.toBase64(ssb.rawData); 0045 return res; 0046 } 0047 0048 function parsePdf(pdf, node, triggerNode) { 0049 let reservations = []; 0050 const page = pdf.pages[triggerNode.location]; 0051 const text = page.text; 0052 0053 var res = JsonLd.newTrainReservation(); 0054 var pnr = text.match(/PNR: (\S+)/); 0055 if (pnr) { 0056 res.reservationNumber = pnr[1]; 0057 } 0058 0059 const leftHeaderText = page.textInRect(0.0, 0.15, 0.33, 0.25); 0060 const midHeaderText = page.textInRect(0.33, 0.15, 0.65, 0.25); 0061 const rightHeaderText = page.textInRect(0.65, 0.15, 1.0, 0.25); 0062 0063 const train = rightHeaderText.match(/(?:Train|Treno|Zug)(?:\/Train)?:[ \n](.*)\n/); 0064 res.reservationFor.trainNumber = train[1]; 0065 0066 const departure_time = leftHeaderText.match(/(\d{2}:\d{2}) - (\d{2}\/\d{2}\/\d{4})/) 0067 const arrival_time = midHeaderText.match(/(\d{2}:\d{2}) - (\d{2}\/\d{2}\/\d{4})/) 0068 res.reservationFor.departureTime = JsonLd.toDateTime(departure_time[2] + departure_time[1], "dd/MM/yyyyhh:mm", "it"); 0069 res.reservationFor.arrivalTime = JsonLd.toDateTime(arrival_time[2] + arrival_time[1], "dd/MM/yyyyhh:mm", "it"); 0070 0071 const dep = leftHeaderText.match(/(?:Stazione di Partenza|Departure station|Abfahrtsbahnhof|Gare de départ)(?:\/From)?\n+(.*)\n/); 0072 res.reservationFor.departureStation.name = dep[1]; 0073 const arr = midHeaderText.match(/(?:Stazione di Arrivo|Arrival station|Ankunft Bahnhof|Gare d'arrivée)(?:\/To)?\n+(.*)\n/); 0074 res.reservationFor.arrivalStation.name = arr[1]; 0075 0076 const barcodes = node.findChildNodes({ scope: "Descendants", mimeType: "internal/era-ssb", field: "issuerCode", match: "83" }).concat(node.findChildNodes({ scope: "Descendants", mimeType: "internal/uic9183", field: "carrierId", match: "83" })); 0077 var offset = 0; 0078 const passengerColumn = page.textInRect(0.0, 0.3, 0.27, 1.0); 0079 let seatOffset = 0; 0080 for (let j = 0; j < barcodes.length; ++j) { 0081 if (barcodes[j].location != triggerNode.location) { 0082 continue; 0083 } 0084 let personalRes = JsonLd.clone(res); 0085 var name = passengerColumn.substr(offset).match(/(?:Passenger Name|Nome Passeggero|Nom du Passager)(?:\/Passenger\n *name)?.*\n(?: .*\n)* *((?:\w+|\-\-).*?)(?: |\n)/); 0086 offset += name.index + name[0].length; 0087 if (name[1] !== "--") { 0088 personalRes.underName.name = name[1]; 0089 } else { 0090 personalRes.underName.name = "Passenger " + (j + 1); 0091 } 0092 0093 var coach = text.match(/(?:Coaches|Carrozza|Wagen|Voiture)(?:\/Coach)?: +(\S+)/); 0094 if (coach) { 0095 personalRes.reservedTicket.ticketedSeat.seatSection = coach[1]; 0096 } 0097 0098 if (barcodes[j].result[0]['@type'] == 'TrainReservation') { 0099 personalRes = JsonLd.apply(barcodes[j].result[0], personalRes); 0100 } else { 0101 personalRes.reservedTicket = JsonLd.apply(barcodes[j].result[0], personalRes.reservedTicket); 0102 } 0103 0104 // fallback seat parsing for unparsable ERA FCB tickets 0105 const seat = page.text.substr(seatOffset).match(/(\d+) +(\d+[A-F]?) +([A-Z0-9]{6})/); 0106 if (seat) { 0107 seatOffset += seat.index + seat[0].length; 0108 if (personalRes.reservedTicket.ticketedSeat.seatSection == seat[1] && !personalRes.reservedTicket.ticketedSeat.seatNumber) { 0109 personalRes.reservedTicket.ticketedSeat.seatNumber = seat[2]; 0110 } 0111 } 0112 0113 ExtractorEngine.extractPrice(text, personalRes); 0114 reservations.push(personalRes); 0115 } 0116 0117 return reservations; 0118 } 0119 0120 function parseEvent(event) 0121 { 0122 let res = JsonLd.newTrainReservation(); 0123 res.reservationFor.departureTime = JsonLd.readQDateTime(event, 'dtStart'); 0124 res.reservationFor.arrivalTime = JsonLd.readQDateTime(event, 'dtEnd'); 0125 res.reservationFor.departureStation.name = event.location; 0126 res.reservationFor.arrivalStation.name = event.description.match(event.location + "-(.*?);")[1]; 0127 res.reservationFor.trainNumber = event.description.match(/Train: (.*?),/)[1]; 0128 res.reservationNumber = event.description.match(/pnr code ([A-Z0-9]{6})\b/)[1]; 0129 const seat = event.description.match(/Coach (.*?), Position (.*?)[;\b]/); 0130 if (seat) { 0131 res.reservedTicket.ticketedSeat.seatSection = seat[1]; 0132 res.reservedTicket.ticketedSeat.seatNumber = seat[2]; 0133 } 0134 return res; 0135 }