Differential D11396 Diff 29708 plugins/messageviewer/bodypartformatter/semantic/extractors/czechrailways.js
Changeset View
Changeset View
Standalone View
Standalone View
plugins/messageviewer/bodypartformatter/semantic/extractors/czechrailways.js
- This file was added.
1 | /* | ||||
---|---|---|---|---|---|
2 | Copyright (c) 2017 Volker Krause <vkrause@kde.org> | ||||
3 | Copyright (c) 2018 Daniel Vrátil <dvratil@kde.org> | ||||
4 | | ||||
5 | This library is free software; you can redistribute it and/or modify it | ||||
6 | under the terms of the GNU Library General Public License as published by | ||||
7 | the Free Software Foundation; either version 2 of the License, or (at your | ||||
8 | option) any later version. | ||||
9 | | ||||
10 | This library is distributed in the hope that it will be useful, but WITHOUT | ||||
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||||
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public | ||||
13 | License for more details. | ||||
14 | | ||||
15 | You should have received a copy of the GNU Library General Public License | ||||
16 | along with this library; see the file COPYING.LIB. If not, write to the | ||||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
18 | 02110-1301, USA. | ||||
19 | */ | ||||
20 | | ||||
21 | function isHeaderOrFooter(line) { | ||||
22 | return line.search(/(Jízdní řád( a rezervace)?|Jízdenku lze použít po stejné trase|Jízdní doklad zakoupený u obchodníka)/) >= 0; | ||||
23 | } | ||||
24 | | ||||
25 | function createSeat(res) | ||||
26 | { | ||||
27 | if (!res.reservedTicket) | ||||
28 | res.reservedTicket = JsonLd.newObject("Ticket"); | ||||
29 | if (!res.reservedTicket.ticketedSeat) | ||||
30 | res.reservedTicket.ticketedSeat = JsonLd.newObject("Seat"); | ||||
31 | } | ||||
32 | | ||||
33 | function parseSeat(res, text) { | ||||
34 | var coach = text.match(/(\s+)(\d+)/); | ||||
35 | var idx = 0; | ||||
36 | if (coach) { | ||||
37 | createSeat(res); | ||||
38 | res.reservedTicket.ticketedSeat.seatSection = coach[2]; | ||||
39 | idx = coach.index + coach[1].length + coach[2].length; | ||||
40 | } | ||||
41 | var seat = text.substr(idx).match(/\s+(\d+)/); | ||||
42 | if (seat) { | ||||
43 | createSeat(res); | ||||
44 | res.reservedTicket.ticketedSeat.seatNumber = seat[1]; | ||||
45 | } | ||||
46 | } | ||||
47 | | ||||
48 | // There's no validity year anywhere in the ticket, so we take the purchase date and | ||||
49 | // if the trip month and day are after the purchase month and day we assume the | ||||
50 | // the ticket will become valid the same year it was purchased, otherwise we assume | ||||
51 | // the ticket is for next year. | ||||
52 | // This fails when you buy the ticket more than a year ahead of the trip, but I doubt | ||||
53 | // you can even do that with Czech Railways... | ||||
54 | function detectYear(tripDate, purchaseDate) | ||||
55 | { | ||||
56 | var tripDay = tripDate[1]; | ||||
57 | var tripMonth = tripDate[2]; | ||||
58 | var purchaseDay = purchaseDate[1]; | ||||
59 | var purchaseMonth = purchaseDate[2]; | ||||
60 | var purchaseYear = purchaseDate[3]; | ||||
61 | | ||||
62 | if ((purchaseMonth < tripMonth) || | ||||
63 | (purchaseMonth == tripMonth) && (purchaseDay <= tripDay)) { | ||||
64 | return purchaseYear; | ||||
65 | } else { | ||||
66 | return parseInt(purchaseYear) + 1; | ||||
67 | } | ||||
68 | } | ||||
69 | | ||||
70 | function parseDeparture(res, line, purchaseDate) { | ||||
71 | res.reservationFor.departureStation = JsonLd.newObject("TrainStation"); | ||||
72 | var station = line.match(/^(.+?) /); | ||||
73 | if (!station) | ||||
74 | return; | ||||
75 | var idx = station.index + station[0].length; | ||||
76 | res.reservationFor.departureStation.name = station[1]; | ||||
77 | var dt = line.substr(idx).match(/([0-9]{2})\.([0-9]{2})\. ([0-9]{2}:[0-9]{2})/); | ||||
78 | if (dt) { | ||||
79 | idx += dt.index + dt[0].length; | ||||
80 | res.reservationFor.departureTime = JsonLd.toDateTime(dt[1] + ' ' + dt[2] + ' ' + detectYear(dt, purchaseDate) + ' ' + dt[3], "dd MM yyyy hh:mm", "cs"); | ||||
81 | } | ||||
82 | var trainId = line.substr(idx).match(/([a-zA-Z]+ [0-9a-zA-Z]+)/); | ||||
83 | if (trainId) { | ||||
84 | idx += trainId.index + trainId[0].length | ||||
85 | res.reservationFor.trainNumber = trainId[1]; | ||||
86 | } | ||||
87 | parseSeat(res, line.substr(idx)); | ||||
88 | } | ||||
89 | | ||||
90 | function parseArrival(res, line, purchaseDate) { | ||||
91 | res.reservationFor.arrivalStation = JsonLd.newObject("TrainStation"); | ||||
92 | var station = line.match(/^(.+?) /); | ||||
93 | if (!station) | ||||
94 | return; | ||||
95 | var idx = station.index + station[0].length; | ||||
96 | res.reservationFor.arrivalStation.name = station[1]; | ||||
97 | var dt = line.substr(idx).match(/([0-9]{2})\.([0-9]{2})\. ([0-9]{2}:[0-9]{2})/); | ||||
98 | if (dt) { | ||||
99 | idx += dt.index + dt[0].length; | ||||
100 | res.reservationFor.arrivalTime = JsonLd.toDateTime(dt[1] + ' ' + dt[2] + ' ' + detectYear(dt, purchaseDate) + ' ' + dt[3], "dd MM yyyy hh:mm", "cs"); | ||||
101 | } | ||||
102 | } | ||||
103 | | ||||
104 | function parseLegs(text, purchaseDate) { | ||||
105 | var reservations = new Array(); | ||||
106 | var lines = text.split('\n'); | ||||
107 | var depIdx = 1, arrIdx = 2; | ||||
108 | while (depIdx < lines.length) { | ||||
109 | // stop when reaching the footer or the next itinerary header | ||||
110 | if (isHeaderOrFooter(lines[depIdx])) | ||||
111 | return reservations; | ||||
112 | | ||||
113 | var res = JsonLd.newObject("TrainReservation"); | ||||
114 | res.reservationFor = JsonLd.newObject("TrainTrip"); | ||||
115 | | ||||
116 | arrIdx = depIdx + 1; | ||||
117 | parseDeparture(res, lines[depIdx], purchaseDate); | ||||
118 | parseArrival(res, lines[arrIdx], purchaseDate); | ||||
119 | depIdx = arrIdx + 1; | ||||
120 | // Find the next leg | ||||
121 | while (lines[depIdx].startsWith(" ")) { | ||||
122 | depIdx += 1; | ||||
123 | } | ||||
124 | | ||||
125 | reservations.push(res); | ||||
126 | } | ||||
127 | | ||||
128 | return reservations; | ||||
129 | } | ||||
130 | | ||||
131 | function main(text) { | ||||
132 | console.log(text); | ||||
133 | var reservations = new Array(); | ||||
134 | var pos = 0; | ||||
135 | | ||||
136 | var purchaseDate = text.match(/[d|D]atum platby|UZP: ([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{4})/) | ||||
137 | | ||||
138 | while (true) { | ||||
139 | // find itinerary headers | ||||
140 | var header = text.substr(pos).match(/Timetable( and Reservations)?/); | ||||
141 | if (!header) | ||||
142 | break; | ||||
143 | var idx = header.index + header[0].length; | ||||
144 | var timetableHeader = text.substr(pos + idx).match(/(Místo \/ Seat \/ Sitzplatz)/) | ||||
145 | idx = idx + timetableHeader.index + timetableHeader[0].length; | ||||
146 | reservations = reservations.concat(parseLegs(text.substr(pos + idx), purchaseDate)); | ||||
147 | if (idx == 0) | ||||
148 | break; | ||||
149 | pos += idx + 1; | ||||
150 | } | ||||
151 | | ||||
152 | var bookingRef = text.match(/Kód transakce:\s*([A-Z0-9]{6})\n/); | ||||
153 | for (var i = 0; bookingRef && i < reservations.length; ++i) | ||||
154 | reservations[i].reservationNumber = bookingRef[1]; | ||||
155 | return reservations; | ||||
156 | } |