Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit 6f485546 authored by Daniel Vrátil's avatar Daniel Vrátil 🤖

Semantic formatter: add extractor for Czech Railways tickets

Differential Revision: https://phabricator.kde.org/D11396
parent 562845ce
! 1154
JÍZDENKA
eTiket Osob: 1
Z/DE/VON @ DO/A/NACH TŘÍDA/
CL./KL.
01/01 00:00 Lysá n.Labem @ Praha Masarykovo n. 02/01 06:00 2
* * * @ * * * *
Přes: Čelákovice Km: 35
IN 25 jednosměrná
Cena 4 Kč
Doklad je nepřenosný a platí vždy pouze ve spojení s osobním průkazem cestujícího, jehož jméno je uvedeno na jízdence.
Jízdu je nutno nastoupit v 1. den platnosti
Daňový doklad (informace o ceně)
Summary / Rechnung
Položka Tar. cena Body Cena DPH
Jízdenka 1 43 Kč 4 Kč 15%
Uplatněné věrnostní body -200
Celkem 4 Kč
Datum vystavení/datum platby: 1.1.2017 16:44 Platba: KARTOU/CC
Prodejce: České dráhy, a.s. 30002 Číslo obj.: 13580 282 00
Praha 1, Nábřeží L.Svobody 1222, PSČ 110 15 DIČ: CZ70994226
Jízdní řád
Timetable / Fahrplan
Stanice Odj. / Příj. x w Místo / Seat / Sitzplatz
Lysá n.Labem 01.01. 16:55 Os 9424 Údaje pro kontrolu
Praha Masarykovo n. 01.01. 17:33 Angaben für Kontrolle
Doklad číslo / Beleg Nr.:
Jízdenku lze použít po stejné trase i pro jiné vlakové spojení v tentýž den platnosti. *2606-208
Rezervace místa platí pouze pro uvedené vlaky. Jméno / Name:
VRÁTIL Daniel
Kód transakce:
VM5MZ3
Kód nepřehýbejte! / Do not fold the barcode!
Barcode nicht knicken!
Reklama
Šťastnou cestu vlakem přejí České dráhy, Váš osobní dopravce. Strana 1/1
[
{
"@type": "TrainReservation",
"reservationFor": {
"@type": "TrainTrip",
"arrivalStation": {
"@type": "TrainStation",
"name": "Brno hl.n."
},
"arrivalTime": "2017-12-31T16:20:00",
"departureStation": {
"@type": "TrainStation",
"name": "Praha hl.n."
},
"departureTime": "2017-12-31T13:51:00",
"trainNumber": "EC 173"
},
"reservedTicket": {
"@type": "Ticket",
"ticketedSeat": {
"@type": "Seat",
"seatNumber": "71",
"seatSection": "262"
}
}
},
{
"@type": "TrainReservation",
"reservationFor": {
"@type": "TrainTrip",
"arrivalStation": {
"@type": "TrainStation",
"name": "Praha hl.n."
},
"arrivalTime": "2018-01-01T13:07:00",
"departureStation": {
"@type": "TrainStation",
"name": "Brno hl.n."
},
"departureTime": "2018-01-01T10:38:00",
"trainNumber": "rj 72"
},
"reservedTicket": {
"@type": "Ticket",
"ticketedSeat": {
"@type": "Seat",
"seatNumber": "51",
"seatSection": "27"
}
}
}
]
! 1154
JÍZDENKA A MÍSTENKA
eTiket Osob: 1
Z/DE/VON @ DO/A/NACH TŘÍDA/
CL./KL.
31/12 13:51 Praha hl.n. @ Brno hl.n. * * 1
* * Brno hl.n. @ Praha hl.n. 01/01 24:00 1
Přes: PhaLb,Kolín,Pard.Hl,Ústí/Or,ČTřeb Km: 255
Rezervace (místo)
IN 25 zpáteční
Cena 662 Kč
Doklad je nepřenosný a platí vždy pouze ve spojení s osobním průkazem cestujícího, jehož jméno je uvedeno na jízdence.
Jízdu je nutno nastoupit v 1. den platnosti, nejdříve však v 13:51 hod.
Daňový doklad (informace o ceně)
Summary / Rechnung
Položka Tar. cena Body Cena DPH
Jízdenka 1 662 Kč 66 662 Kč 15%
Rezervace 2 0 Kč 0 Kč
Celkem 662 Kč
Datum vystavení/datum platby: 30.12.2017 20:27 Platba: KARTOU/CC
Prodejce: České dráhy, a.s. 30002 Číslo obj.: 20361 103 00
Praha 1, Nábřeží L.Svobody 1222, PSČ 110 15 DIČ: CZ70994226
Jízdní řád a rezervace pro cestu TAM
Timetable and Reservations – Outward Journey / Fahrplan und Reservierung Hinfahrt
Stanice Odj. / Příj. x w Místo / Seat / Sitzplatz Údaje pro kontrolu
Praha hl.n. 31.12. 13:51 EC 173 262 71 Angaben für Kontrolle
Brno hl.n. 31.12. 16:20 Doklad číslo / Beleg Nr.:
*8576-222
Jméno / Name:
Jízdní řád a rezervace pro cestu ZPĚT
Timetable and Reservations – Return Journey / Fahrplan und Reservierung Rückfahrt VRÁTIL Daniel
Stanice Odj. / Příj. x w Místo / Seat / Sitzplatz
Brno hl.n. 01.01. 10:38 rj 72 27 51 Kód transakce:
Praha hl.n. 01.01. 13:07
GIG2L1
Jízdenku lze použít po stejné trase i pro pozdější vlakové spojení v době její platnosti.
Rezervace místa platí pouze pro uvedené vlaky. Kód nepřehýbejte! / Do not fold the barcode!
Barcode nicht knicken!
Reklama
Šťastnou cestu vlakem přejí České dráhy, Váš osobní dopravce. Strana 1/1
[
{
"@type": "TrainReservation",
"reservationFor": {
"@type": "TrainTrip",
"arrivalStation": {
"@type": "TrainStation",
"name": "Praha hl.n."
},
"arrivalTime": "2017-07-09T17:06:00",
"departureStation": {
"@type": "TrainStation",
"name": "Brno dolní nádraží"
},
"departureTime": "2017-07-09T14:34:00",
"trainNumber": "RJ 76"
},
"reservationNumber": "FXI305",
"reservedTicket": {
"@type": "Ticket",
"ticketedSeat": {
"@type": "Seat",
"seatNumber": "91",
"seatSection": "26"
}
}
}
]
! 1154
JÍZDENKA A MÍSTENKA
eTiket Osob: 1
Z/DE/VON @ DO/A/NACH TŘÍDA/
CL./KL.
09/07 00:00 Brno hl.n./dolní n. @ Praha hl.n. 10/07 24:00 1
* * * @ * * * *
Přes: ČTřeb,Ústí/Or,Pard.Hl,Kolín Km: 255
Rezervace (místo)
IN 25 jednosměrná
Cena 341 Kč
Doklad je nepřenosný a platí vždy pouze ve spojení s osobním průkazem cestujícího, jehož jméno je uvedeno na jízdence.
Jízdu je nutno nastoupit v 1. den platnosti
Daňový doklad (informace o ceně)
Summary / Rechnung
Položka Tar. cena Body Cena DPH
Jízdenka 1 341 Kč 34 341 Kč 15%
Rezervace 1 0 Kč 0 Kč
Celkem 341 Kč
Datum vystavení/datum platby: 9.7.2017 14:14 Platba: KARTOU/CC
Prodejce: České dráhy, a.s. 30002 Číslo obj.: 16502 055 00
Praha 1, Nábřeží L.Svobody 1222, PSČ 110 15 DIČ: CZ70994226
Jízdní řád a rezervace
Timetable and Reservations / Fahrplan und Reservierung
Stanice Odj. / Příj. x w Místo / Seat / Sitzplatz
Brno dolní nádraží 09.07. 14:34 RJ 76 26 91 Údaje pro kontrolu
Praha hl.n. 09.07. 17:06 Angaben für Kontrolle
Doklad číslo / Beleg Nr.:
Jízdenku lze použít po stejné trase i pro jiné vlakové spojení v tentýž den platnosti. *9740-315
Rezervace místa platí pouze pro uvedené vlaky. Jméno / Name:
VRÁTIL Daniel
Kód transakce:
FXI305
Kód nepřehýbejte! / Do not fold the barcode!
Barcode nicht knicken!
Reklama
Šťastnou cestu vlakem přejí České dráhy, Váš osobní dopravce. Strana 1/1
[
{
"@type": "TrainReservation",
"reservationFor": {
"@type": "TrainTrip",
"arrivalStation": {
"@type": "TrainStation",
"name": "Hradec Králové hl.n."
},
"arrivalTime": "2017-08-09T10:51:00",
"departureStation": {
"@type": "TrainStation",
"name": "Praha hl.n."
},
"departureTime": "2017-08-09T09:07:00",
"trainNumber": "R 945"
},
"reservationNumber": "Z39230",
"reservedTicket": {
"@type": "Ticket",
"ticketedSeat": {
"@type": "Seat",
"seatNumber": "115",
"seatSection": "372"
}
}
},
{
"@type": "TrainReservation",
"reservationFor": {
"@type": "TrainTrip",
"arrivalStation": {
"@type": "TrainStation",
"name": "Jaroměř"
},
"arrivalTime": "2017-08-09T11:16:00",
"departureStation": {
"@type": "TrainStation",
"name": "Hradec Králové hl.n."
},
"departureTime": "2017-08-09T11:02:00",
"trainNumber": "Sp 1786"
},
"reservationNumber": "Z39230"
}
]
! 1154
JÍZDENKA A MÍSTENKA
eTiket Osob: 1
Z/DE/VON @ DO/A/NACH TŘÍDA/
CL./KL.
09/08 00:00 Praha hl.n. @ Jaroměř 10/08 24:00 2
* * * @ * * * *
Přes: Lysá/L,NymbH,Chlum/Ci,HradKrHl Km: 133
Rezervace (místo)
IN 25 jednosměrná
Cena 141 Kč
Doklad je nepřenosný a platí vždy pouze ve spojení s osobním průkazem cestujícího, jehož jméno je uvedeno na jízdence.
Jízdu je nutno nastoupit v 1. den platnosti
Daňový doklad (informace o ceně)
Summary / Rechnung
Položka Tar. cena Body Cena DPH
Jízdenka 1 141 Kč 14 141 Kč 15%
Rezervace 1 0 Kč 0 Kč
Celkem 141 Kč
Datum vystavení/datum platby: 7.8.2017 13:18 Platba: KARTOU/CC
Prodejce: České dráhy, a.s. 30000 Číslo obj.: 16996 165 00
Praha 1, Nábřeží L.Svobody 1222, PSČ 110 15 DIČ: CZ70994226
Jízdní řád a rezervace
Timetable and Reservations / Fahrplan und Reservierung
Stanice Odj. / Příj. x w Místo / Seat / Sitzplatz
Praha hl.n. 09.08. 09:07 R 945 372 115 Údaje pro kontrolu
Hradec Králové hl.n. 09.08. 10:51 Angaben für Kontrolle
Doklad číslo / Beleg Nr.:
Hradec Králové hl.n. 09.08. 11:02 Sp 1786 *1011-383
Jaroměř 09.08. 11:16 Jméno / Name:
VRÁTIL Daniel
Jízdenku lze použít po stejné trase i pro jiné vlakové spojení v tentýž den platnosti.
Rezervace místa platí pouze pro uvedené vlaky.
Kód transakce:
Z39230
Kód nepřehýbejte! / Do not fold the barcode!
Barcode nicht knicken!
Reklama
Šťastnou cestu vlakem přejí České dráhy, Váš osobní dopravce. Strana 1/1
/*
Copyright (c) 2017 Volker Krause <vkrause@kde.org>
Copyright (c) 2018 Daniel Vrátil <dvratil@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
function isHeaderOrFooter(line) {
return line.search(/(Jízdní řád( a rezervace)?|Jízdenku lze použít po stejné trase|Jízdní doklad zakoupený u obchodníka)/) >= 0;
}
function createSeat(res)
{
if (!res.reservedTicket)
res.reservedTicket = JsonLd.newObject("Ticket");
if (!res.reservedTicket.ticketedSeat)
res.reservedTicket.ticketedSeat = JsonLd.newObject("Seat");
}
function parseSeat(res, text) {
var coach = text.match(/(\s+)(\d+)/);
var idx = 0;
if (coach) {
createSeat(res);
res.reservedTicket.ticketedSeat.seatSection = coach[2];
idx = coach.index + coach[1].length + coach[2].length;
}
var seat = text.substr(idx).match(/\s+(\d+)/);
if (seat) {
createSeat(res);
res.reservedTicket.ticketedSeat.seatNumber = seat[1];
}
}
// There's no validity year anywhere in the ticket, so we take the purchase date and
// if the trip month and day are after the purchase month and day we assume the
// the ticket will become valid the same year it was purchased, otherwise we assume
// the ticket is for next year.
// This fails when you buy the ticket more than a year ahead of the trip, but I doubt
// you can even do that with Czech Railways...
function detectYear(tripDate, purchaseDate)
{
var tripDay = tripDate[1];
var tripMonth = tripDate[2];
var purchaseDay = purchaseDate[1];
var purchaseMonth = purchaseDate[2];
var purchaseYear = purchaseDate[3];
if ((purchaseMonth < tripMonth) ||
(purchaseMonth == tripMonth) && (purchaseDay <= tripDay)) {
return purchaseYear;
} else {
return parseInt(purchaseYear) + 1;
}
}
function parseDeparture(res, line, purchaseDate) {
res.reservationFor.departureStation = JsonLd.newObject("TrainStation");
var station = line.match(/^(.+?) /);
if (!station)
return;
var idx = station.index + station[0].length;
res.reservationFor.departureStation.name = station[1];
var dt = line.substr(idx).match(/([0-9]{2})\.([0-9]{2})\. ([0-9]{2}:[0-9]{2})/);
if (dt) {
idx += dt.index + dt[0].length;
res.reservationFor.departureTime = JsonLd.toDateTime(dt[1] + ' ' + dt[2] + ' ' + detectYear(dt, purchaseDate) + ' ' + dt[3], "dd MM yyyy hh:mm", "cs");
}
var trainId = line.substr(idx).match(/([a-zA-Z]+ [0-9a-zA-Z]+)/);
if (trainId) {
idx += trainId.index + trainId[0].length
res.reservationFor.trainNumber = trainId[1];
}
parseSeat(res, line.substr(idx));
}
function parseArrival(res, line, purchaseDate) {
res.reservationFor.arrivalStation = JsonLd.newObject("TrainStation");
var station = line.match(/^(.+?) /);
if (!station)
return;
var idx = station.index + station[0].length;
res.reservationFor.arrivalStation.name = station[1];
var dt = line.substr(idx).match(/([0-9]{2})\.([0-9]{2})\. ([0-9]{2}:[0-9]{2})/);
if (dt) {
idx += dt.index + dt[0].length;
res.reservationFor.arrivalTime = JsonLd.toDateTime(dt[1] + ' ' + dt[2] + ' ' + detectYear(dt, purchaseDate) + ' ' + dt[3], "dd MM yyyy hh:mm", "cs");
}
}
function parseLegs(text, purchaseDate) {
var reservations = new Array();
var lines = text.split('\n');
var depIdx = 1, arrIdx = 2;
while (depIdx < lines.length) {
// stop when reaching the footer or the next itinerary header
if (isHeaderOrFooter(lines[depIdx]))
return reservations;
var res = JsonLd.newObject("TrainReservation");
res.reservationFor = JsonLd.newObject("TrainTrip");
arrIdx = depIdx + 1;
parseDeparture(res, lines[depIdx], purchaseDate);
parseArrival(res, lines[arrIdx], purchaseDate);
depIdx = arrIdx + 1;
// Find the next leg
while (lines[depIdx].startsWith(" ")) {
depIdx += 1;
}
reservations.push(res);
}
return reservations;
}
function main(text) {
console.log(text);
var reservations = new Array();
var pos = 0;
var purchaseDate = text.match(/[d|D]atum platby|UZP: ([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{4})/)
while (true) {
// find itinerary headers
var header = text.substr(pos).match(/Timetable( and Reservations)?/);
if (!header)
break;
var idx = header.index + header[0].length;
var timetableHeader = text.substr(pos + idx).match(/(Místo \/ Seat \/ Sitzplatz)/)
idx = idx + timetableHeader.index + timetableHeader[0].length;
reservations = reservations.concat(parseLegs(text.substr(pos + idx), purchaseDate));
if (idx == 0)
break;
pos += idx + 1;
}
var bookingRef = text.match(/Kód transakce:\s*([A-Z0-9]{6})\n/);
for (var i = 0; bookingRef && i < reservations.length; ++i)
reservations[i].reservationNumber = bookingRef[1];
return reservations;
}
{
"filter": [
{ "header": "From", "match": "info@cd.cz" },
{ "header": "From", "match": "eshop@cd.cz" }
],
"script": "czechrailways.js"
}
......@@ -4,6 +4,8 @@
<file>amadeus.js</file>
<file>brusselsairlines.json</file>
<file>brusselsairlines.js</file>
<file>czechrailways.json</file>
<file>czechrailways.js</file>
<file>deutschebahn.json</file>
<file>deutschebahn.js</file>
<file>eurowings.json</file>
......
Markdown is supported
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