Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package kitinerary for openSUSE:Factory checked in at 2024-09-13 14:27:14 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/kitinerary (Old) and /work/SRC/openSUSE:Factory/.kitinerary.new.29891 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kitinerary" Fri Sep 13 14:27:14 2024 rev:76 rq:1200587 version:24.08.1 Changes: -------- --- /work/SRC/openSUSE:Factory/kitinerary/kitinerary.changes 2024-08-26 22:04:52.632601687 +0200 +++ /work/SRC/openSUSE:Factory/.kitinerary.new.29891/kitinerary.changes 2024-09-13 14:29:37.084051136 +0200 @@ -1,0 +2,21 @@ +Tue Sep 10 14:10:50 UTC 2024 - Christophe Marin <christo...@krop.fr> + +- Update to 24.08.1 + * New bugfix release + * For more details please see: + * https://kde.org/announcements/gear/24.08.1/ +- Changes since 24.08.0: + * Add United Airlines reservations parser + * sunnycars: Extract drop-off location, if available + * Handle MAV ticket barcodes without a trip block + * Fix latitude/longitude mixup + * Add extractor script for (new?) Italo PDF tickets + * Support French date/time format in BlablaBus tickets + * Fix extraction of multi-page BlablaBus PDF tickets + * Handle more Eurostar PDF layout variants + * Add extractor script for Reisnordland ferries (kde#492096) + * Unify the two DB ical extractor methods a bit + * Add Reservix extractor + * Try harder to decode names in VDV tickets + +------------------------------------------------------------------- Old: ---- kitinerary-24.08.0.tar.xz kitinerary-24.08.0.tar.xz.sig New: ---- kitinerary-24.08.1.tar.xz kitinerary-24.08.1.tar.xz.sig ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kitinerary.spec ++++++ --- /var/tmp/diff_new_pack.H4eULj/_old 2024-09-13 14:29:37.792080671 +0200 +++ /var/tmp/diff_new_pack.H4eULj/_new 2024-09-13 14:29:37.792080671 +0200 @@ -18,11 +18,11 @@ %define kf6_version 6.3.0 %define qt6_version 6.6.0 -%define kpim6_version 6.2.0 +%define kpim6_version 6.2.1 %bcond_without released Name: kitinerary -Version: 24.08.0 +Version: 24.08.1 Release: 0 Summary: Data model and extraction system for travel reservations License: LGPL-2.1-or-later ++++++ kitinerary-24.08.0.tar.xz -> kitinerary-24.08.1.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/CMakeLists.txt new/kitinerary-24.08.1/CMakeLists.txt --- old/kitinerary-24.08.0/CMakeLists.txt 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/CMakeLists.txt 2024-09-08 07:27:01.000000000 +0200 @@ -3,7 +3,7 @@ # SPDX-License-Identifier: BSD-3-Clause cmake_minimum_required(VERSION 3.16 FATAL_ERROR) -set(PIM_VERSION "6.2.0") +set(PIM_VERSION "6.2.1") project(KItinerary VERSION ${PIM_VERSION}) set(QT_REQUIRED_VERSION "6.6.0") @@ -43,8 +43,8 @@ find_package(SharedMimeInfo 1.3 REQUIRED) endif() -set(KMIME_VERSION "6.1.90") -set(PIM_PKPASS "6.1.90") +set(KMIME_VERSION "6.2.1") +set(PIM_PKPASS "6.2.1") find_package(KPim6Mime ${KMIME_VERSION} CONFIG REQUIRED) find_package(KPim6PkPass ${PIM_PKPASS} CONFIG REQUIRED) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20220726-copenhagen-amsterdam-NL.ics.json new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20220726-copenhagen-amsterdam-NL.ics.json --- old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20220726-copenhagen-amsterdam-NL.ics.json 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20220726-copenhagen-amsterdam-NL.ics.json 2024-09-08 07:27:01.000000000 +0200 @@ -21,7 +21,7 @@ "@value": "2022-07-26T13:17:00+02:00", "timezone": "Europe/Berlin" }, - "trainName": "IC 1197" + "trainNumber": "IC 1197" }, "reservationStatus": "http://schema.org/ReservationConfirmed" }, @@ -43,7 +43,7 @@ "name": "Hamburg Hbf" }, "departureTime": "2022-07-26T18:46:00", - "trainName": "IC 2307" + "trainNumber": "IC 2307" }, "reservationStatus": "http://schema.org/ReservationConfirmed" }, @@ -65,7 +65,7 @@ "name": "Bremen Hbf" }, "departureTime": "2022-07-26T19:53:00", - "trainName": "IC 2034" + "trainNumber": "IC 2034" }, "reservationStatus": "http://schema.org/ReservationConfirmed" }, @@ -79,7 +79,7 @@ "name": "Groningen CS Hoofdstation" }, "arrivalTime": "2022-07-26T22:25:00", - "busName": "Bus 647", + "busNumber": "Bus 647", "departureBusStop": { "@type": "BusStation", "name": "Leer(Ostfriesl) ZOB/Bahnhof" @@ -110,7 +110,7 @@ "name": "Groningen" }, "departureTime": "2022-07-26T22:49:00", - "trainName": "IC 786" + "trainNumber": "IC 786" }, "reservationStatus": "http://schema.org/ReservationConfirmed" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20220726-frankfurt-cologne-paris.ics.json new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20220726-frankfurt-cologne-paris.ics.json --- old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20220726-frankfurt-cologne-paris.ics.json 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20220726-frankfurt-cologne-paris.ics.json 2024-09-08 07:27:01.000000000 +0200 @@ -21,7 +21,7 @@ "@value": "2022-07-26T10:26:00+02:00", "timezone": "Europe/Berlin" }, - "trainName": "ICE 16" + "trainNumber": "ICE 16" }, "reservationStatus": "http://schema.org/ReservationConfirmed" }, @@ -46,7 +46,7 @@ "name": "Köln Hbf" }, "departureTime": "2022-07-26T12:42:00", - "trainName": "THA 9448" + "trainNumber": "THA 9448" }, "reservationStatus": "http://schema.org/ReservationConfirmed" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20220726-hamburg-dortmund-ES.ics.json new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20220726-hamburg-dortmund-ES.ics.json --- old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20220726-hamburg-dortmund-ES.ics.json 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20220726-hamburg-dortmund-ES.ics.json 2024-09-08 07:27:01.000000000 +0200 @@ -21,7 +21,7 @@ "@value": "2022-07-26T12:46:00+02:00", "timezone": "Europe/Berlin" }, - "trainName": "IC 2311" + "trainNumber": "IC 2311" }, "reservationStatus": "http://schema.org/ReservationConfirmed" }, @@ -43,7 +43,7 @@ "name": "Münster(Westf)Hbf" }, "departureTime": "2022-07-26T15:10:00", - "trainName": "RB 90027" + "trainNumber": "RB 90027" }, "reservationStatus": "http://schema.org/ReservationConfirmed" }, @@ -69,7 +69,7 @@ "name": "Hamm(Westf)Hbf" }, "departureTime": "2022-07-26T15:44:00", - "trainName": "RE 89726" + "trainNumber": "RE 89726" }, "reservationStatus": "http://schema.org/ReservationConfirmed" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20220726-praha-vienna-CZ.ics.json new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20220726-praha-vienna-CZ.ics.json --- old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20220726-praha-vienna-CZ.ics.json 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20220726-praha-vienna-CZ.ics.json 2024-09-08 07:27:01.000000000 +0200 @@ -24,7 +24,7 @@ "@value": "2022-07-26T11:56:00+02:00", "timezone": "Europe/Berlin" }, - "trainName": "RJ 79" + "trainNumber": "RJ 79" }, "reservationStatus": "http://schema.org/ReservationConfirmed" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20220726-rovereto-randa-IT.ics.json new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20220726-rovereto-randa-IT.ics.json --- old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20220726-rovereto-randa-IT.ics.json 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20220726-rovereto-randa-IT.ics.json 2024-09-08 07:27:01.000000000 +0200 @@ -19,7 +19,7 @@ "@value": "2022-07-26T13:57:00+02:00", "timezone": "Europe/Berlin" }, - "trainName": "FA 8519" + "trainNumber": "FA 8519" }, "reservationStatus": "http://schema.org/ReservationConfirmed" }, @@ -39,7 +39,7 @@ "name": "Verona Porta Nuova" }, "departureTime": "2022-07-26T15:02:00", - "trainName": "FA 9736" + "trainNumber": "FA 9736" }, "reservationStatus": "http://schema.org/ReservationConfirmed" }, @@ -60,7 +60,7 @@ "name": "Milano Centrale" }, "departureTime": "2022-07-26T17:20:00", - "trainName": "EC 36" + "trainNumber": "EC 36" }, "reservationStatus": "http://schema.org/ReservationConfirmed" }, @@ -85,7 +85,7 @@ "name": "Brig Bahnhofplatz" }, "departureTime": "2022-07-26T19:52:00", - "trainName": "RE 265" + "trainNumber": "RE 265" }, "reservationStatus": "http://schema.org/ReservationConfirmed" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20220726-stockholm-hannover-DK.ics.json new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20220726-stockholm-hannover-DK.ics.json --- old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20220726-stockholm-hannover-DK.ics.json 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20220726-stockholm-hannover-DK.ics.json 2024-09-08 07:27:01.000000000 +0200 @@ -19,7 +19,7 @@ "@value": "2022-07-26T11:21:00+02:00", "timezone": "Europe/Berlin" }, - "trainName": "X2 531" + "trainNumber": "X2 531" }, "reservationStatus": "http://schema.org/ReservationConfirmed" }, @@ -40,7 +40,7 @@ "name": "Malmö Central" }, "departureTime": "2022-07-26T16:13:00", - "trainName": "R 1077" + "trainNumber": "R 1077" }, "reservationStatus": "http://schema.org/ReservationConfirmed" }, @@ -62,7 +62,7 @@ "name": "Koebenhavn H" }, "departureTime": "2022-07-26T17:17:00", - "trainName": "IC 1199" + "trainNumber": "IC 1199" }, "reservationStatus": "http://schema.org/ReservationConfirmed" }, @@ -88,7 +88,7 @@ "name": "Hamburg Hbf" }, "departureTime": "2022-07-26T22:12:00", - "trainName": "ICE 1689" + "trainNumber": "ICE 1689" }, "reservationStatus": "http://schema.org/ReservationConfirmed" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20220726-strasbourg-munich-FR.ics.json new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20220726-strasbourg-munich-FR.ics.json --- old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20220726-strasbourg-munich-FR.ics.json 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20220726-strasbourg-munich-FR.ics.json 2024-09-08 07:27:01.000000000 +0200 @@ -20,7 +20,7 @@ "@value": "2022-07-26T12:46:00+02:00", "timezone": "Europe/Berlin" }, - "trainName": "ICE 9573" + "trainNumber": "ICE 9573" }, "reservationStatus": "http://schema.org/ReservationConfirmed" }, @@ -46,7 +46,7 @@ "name": "Stuttgart Hbf" }, "departureTime": "2022-07-26T14:14:00", - "trainName": "ICE 517" + "trainNumber": "ICE 517" }, "reservationStatus": "http://schema.org/ReservationConfirmed" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20220726-warsaw-luxembourg-PL.ics.json new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20220726-warsaw-luxembourg-PL.ics.json --- old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20220726-warsaw-luxembourg-PL.ics.json 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20220726-warsaw-luxembourg-PL.ics.json 2024-09-08 07:27:01.000000000 +0200 @@ -17,7 +17,7 @@ "name": "Nürnberg Hbf" }, "departureTime": "2022-07-26T01:41:00", - "trainName": "NJ 40490" + "trainNumber": "NJ 40490" }, "reservationStatus": "http://schema.org/ReservationConfirmed" }, @@ -39,7 +39,7 @@ "name": "Koblenz Hbf" }, "departureTime": "2022-07-26T06:03:00", - "trainName": "RE 4100" + "trainNumber": "RE 4100" }, "reservationStatus": "http://schema.org/ReservationConfirmed" }, @@ -57,7 +57,7 @@ "@value": "2022-07-27T08:31:00+02:00", "timezone": "Europe/Berlin" }, - "busName": "Bus51016", + "busNumber": "Bus51016", "departureBusStop": { "@type": "BusStation", "name": "Trier Hbf" @@ -87,7 +87,7 @@ "@value": "2022-07-26T12:15:00+02:00", "timezone": "Europe/Berlin" }, - "trainName": "EC 44" + "trainNumber": "EC 44" }, "reservationStatus": "http://schema.org/ReservationConfirmed" }, @@ -109,7 +109,7 @@ "name": "Berlin Gesundbrunnen" }, "departureTime": "2022-07-26T19:55:00", - "trainName": "ICE 1109" + "trainNumber": "ICE 1109" }, "reservationStatus": "http://schema.org/ReservationConfirmed" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20240822-berlin-paris.ics new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20240822-berlin-paris.ics --- old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20240822-berlin-paris.ics 1970-01-01 01:00:00.000000000 +0100 +++ new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20240822-berlin-paris.ics 2024-09-08 07:27:01.000000000 +0200 @@ -0,0 +1,150 @@ +BEGIN:VCALENDAR +PRODID:https://www.bahn.de +VERSION:2.0 +CALSCALE:GREGORIAN +X-LOTUS-CHARSET:UTF-8 +METHOD:PUBLISH +BEGIN:VTIMEZONE +TZID:Europe/Berlin +LAST-MODIFIED:20231222T233358Z +TZURL:https://www.tzurl.org/zoneinfo/Europe/Berlin +X-LIC-LOCATION:Europe/Berlin +X-PROLEPTIC-TZNAME:LMT +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+005328 +TZOFFSETTO:+0100 +DTSTART:18930401T000000 +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +DTSTART:19160430T230000 +RDATE:19400401T020000 +RDATE:19430329T020000 +RDATE:19460414T020000 +RDATE:19470406T030000 +RDATE:19480418T020000 +RDATE:19490410T020000 +RDATE:19800406T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19161001T010000 +RDATE:19421102T030000 +RDATE:19431004T030000 +RDATE:19441002T030000 +RDATE:19451118T030000 +RDATE:19461007T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +DTSTART:19170416T020000 +RRULE:FREQ=YEARLY;UNTIL=19180415T010000Z;BYMONTH=4;BYDAY=3MO +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19170917T030000 +RRULE:FREQ=YEARLY;UNTIL=19180916T010000Z;BYMONTH=9;BYDAY=3MO +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +DTSTART:19440403T020000 +RRULE:FREQ=YEARLY;UNTIL=19450402T010000Z;BYMONTH=4;BYDAY=1MO +END:DAYLIGHT +BEGIN:DAYLIGHT +TZNAME:CEMT +TZOFFSETFROM:+0200 +TZOFFSETTO:+0300 +DTSTART:19450524T020000 +RDATE:19470511T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZNAME:CEST +TZOFFSETFROM:+0300 +TZOFFSETTO:+0200 +DTSTART:19450924T030000 +RDATE:19470629T030000 +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+0100 +TZOFFSETTO:+0100 +DTSTART:19460101T000000 +RDATE:19800101T000000 +END:STANDARD +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19471005T030000 +RRULE:FREQ=YEARLY;UNTIL=19491002T010000Z;BYMONTH=10;BYDAY=1SU +END:STANDARD +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19800928T030000 +RRULE:FREQ=YEARLY;UNTIL=19950924T010000Z;BYMONTH=9;BYDAY=-1SU +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +DTSTART:19810329T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19961027T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +UID:c42a4883-509a-4105-927a-f5a020fb7...@bahn.de +SUMMARY:Berlin Hbf â Paris Est +CLASS:PUBLIC +LOCATION:Berlin Hbf +DESCRIPTION:Berlin Hbf â Paris Est\nDatum: 22.08.2024\nKlasse: Keine Info + rmation\n\nBerlin Hbf â Mannheim Hbf\nICE 577 (1071)\nâ ab 10:27 Berlin + Hbf â· Gleis 14\nâ an 15:53 Mannheim Hbf â· Gleis 5\n\nMannheim Hbf â Pari + s Est\nICE 9502 (3925)\nâ ab 17:40 Mannheim Hbf â· Gleis 1a\nâ an 20:52 P + aris Est â· Gleis \n\nDauer: 10h 25min\nââââ\nReisen Sie entspannt und oh + ne Ticketkontrolle. Nutzen Sie den Komfort Check-in sobald Sie Ihren Sit + zplatz erreicht haben. Einfach und schnell unter <a href="https://www.ba + hn.de/buchung/jetzt-einchecken" title="Jetzt Einchecken">https://www.bah + n.de/buchung/jetzt-einchecken</a>\nââââ\nAlle Angaben ohne Gewähr. Fahrp + lanänderungen vorbehalten. Bitte prüfen Sie kurz vor der Reise den aktue + llen Fahrplan unter: www.bahn.de +DTSTART:20240822T102700 +DTEND:20240822T205200 +DTSTAMP:20240819T142351Z +X-ALT-DESC;FMTTYPE=text/html:<html xmlns:v="urn:schemas-microsoft-com:vml + " xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas + -microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office + /2004/ 12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head></head><bo + dy lang=DE><div class=WordSection1><p class=MsoNormal>Berlin Hbf â Paris + Est<br>Datum: 22.08.2024<br>Klasse: Keine Information<br><br>Berlin Hbf + â Mannheim Hbf<br>ICE 577 (1071)<br>â ab 10:27 Berlin Hbf â· Gleis 14<br + >â an 15:53 Mannheim Hbf â· Gleis 5<br><br>Mannheim Hbf â Paris Est<br>IC + E 9502 (3925)<br>â ab 17:40 Mannheim Hbf â· Gleis 1a<br>â an 20:52 Paris + Est â· Gleis <br><br>Dauer: 10h 25min<br>ââââ<br>Reisen Sie entspannt und + ohne Ticketkontrolle. Nutzen Sie den Komfort Check-in sobald Sie Ihren + Sitzplatz erreicht haben. Einfach und schnell unter <a href="https://www + .bahn.de/buchung/jetzt-einchecken" title="Jetzt Einchecken">https://www. + bahn.de/buchung/jetzt-einchecken</a><br>ââââ<br>Alle Angaben ohne Gewähr + . Fahrplanänderungen vorbehalten. Bitte prüfen Sie kurz vor der Reise de + n aktuellen Fahrplan unter: www.bahn.de</p></div></body></html> +END:VEVENT +END:VCALENDAR diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20240822-berlin-paris.ics.json new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20240822-berlin-paris.ics.json --- old/kitinerary-24.08.0/autotests/extractordata/deutschebahn/20240822-berlin-paris.ics.json 1970-01-01 01:00:00.000000000 +0100 +++ new/kitinerary-24.08.1/autotests/extractordata/deutschebahn/20240822-berlin-paris.ics.json 2024-09-08 07:27:01.000000000 +0200 @@ -0,0 +1,46 @@ +[ + { + "@context": "http://schema.org", + "@type": "TrainReservation", + "reservationFor": { + "@type": "TrainTrip", + "arrivalPlatform": "5", + "arrivalStation": { + "@type": "TrainStation", + "name": "Mannheim Hbf" + }, + "arrivalTime": "2024-08-22T15:53:00", + "departureDay": "2024-08-22", + "departurePlatform": "14", + "departureStation": { + "@type": "TrainStation", + "name": "Berlin Hbf" + }, + "departureTime": "2024-08-22T10:27:00", + "trainNumber": "ICE 577" + }, + "reservationStatus": "http://schema.org/ReservationConfirmed" + }, + { + "@context": "http://schema.org", + "@type": "TrainReservation", + "reservationFor": { + "@type": "TrainTrip", + "arrivalPlatform": "", + "arrivalStation": { + "@type": "TrainStation", + "name": "Paris Est" + }, + "arrivalTime": "2024-08-22T20:52:00", + "departureDay": "2024-08-22", + "departurePlatform": "1a", + "departureStation": { + "@type": "TrainStation", + "name": "Mannheim Hbf" + }, + "departureTime": "2024-08-22T17:40:00", + "trainNumber": "ICE 9502" + }, + "reservationStatus": "http://schema.org/ReservationConfirmed" + } +] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/autotests/jsonlddata/place-coordinate-propagation.out.json new/kitinerary-24.08.1/autotests/jsonlddata/place-coordinate-propagation.out.json --- old/kitinerary-24.08.0/autotests/jsonlddata/place-coordinate-propagation.out.json 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/autotests/jsonlddata/place-coordinate-propagation.out.json 2024-09-08 07:27:01.000000000 +0200 @@ -12,7 +12,7 @@ "geo": { "@type": "GeoCoordinates", "latitude": 25.0440673828125, - "longitude": 25.0440673828125 + "longitude": 121.53218078613281 } }, "name": "OpenStreetMap x Wikidata Taipei #62", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/po/de/kitinerary6.po new/kitinerary-24.08.1/po/de/kitinerary6.po --- old/kitinerary-24.08.0/po/de/kitinerary6.po 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/po/de/kitinerary6.po 2024-09-08 07:27:01.000000000 +0200 @@ -3,7 +3,7 @@ # Frank Steinmetzger <dev-...@felsenfleischer.de>, 2022. msgid "" msgstr "" -"Project-Id-Version: \n" +"Project-Id-Version: kitinerary6\n" "Report-Msgid-Bugs-To: https://bugs.kde.org\n" "POT-Creation-Date: 2024-01-15 00:38+0000\n" "PO-Revision-Date: 2023-02-09 01:31+0100\n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/src/cli/org.kde.kitinerary-extractor.appdata.xml new/kitinerary-24.08.1/src/cli/org.kde.kitinerary-extractor.appdata.xml --- old/kitinerary-24.08.0/src/cli/org.kde.kitinerary-extractor.appdata.xml 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/src/cli/org.kde.kitinerary-extractor.appdata.xml 2024-09-08 07:27:01.000000000 +0200 @@ -125,6 +125,7 @@ </categories> <launchable type="desktop-id">org.kde.kitinerary-extractor.desktop</launchable> <releases> + <release version="6.2.1" date="2024-09-12"/> <release version="6.1.90" date="2024-08-22"/> <release version="6.1.2" date="2024-07-04"/> <release version="6.1.1" date="2024-06-13"/> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/src/cli/org.kde.kitinerary-extractor.desktop new/kitinerary-24.08.1/src/cli/org.kde.kitinerary-extractor.desktop --- old/kitinerary-24.08.0/src/cli/org.kde.kitinerary-extractor.desktop 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/src/cli/org.kde.kitinerary-extractor.desktop 2024-09-08 07:27:01.000000000 +0200 @@ -13,7 +13,7 @@ Name[et]=KItinerary hankija Name[eu]=KItinerary erauzlea Name[fi]=KItinerary-jäsennin -Name[fr]=Extracteur KItinerary +Name[fr]=Extracteur de KItinerary Name[gl]=Extractor de KItinerary Name[he]=×××××¥ KItinerary Name[ia]=KItinerary Extractor @@ -49,7 +49,7 @@ GenericName[et]=KItinerary käsurea hankija GenericName[eu]=KItinerary komando-lerroko erauzlea GenericName[fi]=KItineraryn komentorivijäsennin -GenericName[fr]=Extracteur KItinerary en ligne de commande +GenericName[fr]=Extracteur de KItinerary en ligne de commandes GenericName[gl]=Extractor de liña de ordes de KItinerary GenericName[he]=××××¥ KItinerary ×ש×רת ×פק××× GenericName[ia]=KItinerary extractor de commando in linea diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/src/lib/json/jsonldimportfilter.cpp new/kitinerary-24.08.1/src/lib/json/jsonldimportfilter.cpp --- old/kitinerary-24.08.0/src/lib/json/jsonldimportfilter.cpp 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/src/lib/json/jsonldimportfilter.cpp 2024-09-08 07:27:01.000000000 +0200 @@ -133,7 +133,7 @@ geo.insert("latitude"_L1, lat); } if (!geo.contains("longitude"_L1)) { - geo.insert("longitude"_L1, lat); + geo.insert("longitude"_L1, lon); } obj.insert("geo"_L1, geo); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/src/lib/scripts/blablacar-bus.js new/kitinerary-24.08.1/src/lib/scripts/blablacar-bus.js --- old/kitinerary-24.08.0/src/lib/scripts/blablacar-bus.js 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/src/lib/scripts/blablacar-bus.js 2024-09-08 07:27:01.000000000 +0200 @@ -5,6 +5,7 @@ */ function main(pdf) { + let reservations = []; for (var i = 0; i < pdf.pageCount; ++i) { var page = pdf.pages[i]; var nextBarcode = null; @@ -12,23 +13,24 @@ for (var j = 0; j < images.length && !nextBarcode; ++j) { nextBarcode = Barcode.decodeQR(images[j]); if (nextBarcode) - return decodeBarcode(pdf.text, nextBarcode); + reservations.push(decodeBarcode(page.text, nextBarcode)); } } + return reservations } function decodeBarcode(text, barcode) { var res = JsonLd.newBusReservation(); // Time and date is only in the PDF text - const times = text.match(/(\d{2}\.\d{2}\.\d{4} \d{2}:\d{2})/g); + const times = text.match(/(\d{2}\.\d{2}\.\d{4} \d{2}:\d{2}|\d{2}-\d{2}-\d{4} à \d{2}:\d{2})/g); if (times.length !== 2) { console.log("Failed to extract departure/arrival time from text: " + times); return null; } - res.reservationFor.departureTime = JsonLd.toDateTime(times[0], "dd.MM.yyyy hh:mm", "en"); - res.reservationFor.arrivalTime = JsonLd.toDateTime(times[1], "dd.MM.yyyy hh:mm", "en"); + res.reservationFor.departureTime = JsonLd.toDateTime(times[0], ["dd.MM.yyyy hh:mm", "dd-MM-yyyy à hh:mm"], "en"); + res.reservationFor.arrivalTime = JsonLd.toDateTime(times[1], ["dd.MM.yyyy hh:mm", "dd-MM-yyyy à hh:mm"], "en"); // The rest of the info can be found in the QR code, separated by | const parts = barcode.split("|"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/src/lib/scripts/deutschebahn.js new/kitinerary-24.08.1/src/lib/scripts/deutschebahn.js --- old/kitinerary-24.08.0/src/lib/scripts/deutschebahn.js 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/src/lib/scripts/deutschebahn.js 2024-09-08 07:27:01.000000000 +0200 @@ -323,7 +323,7 @@ function parseEvent(event) { let res = JsonLd.newTrainReservation(); - const names = event.summary.match(/(.*) -> (.*)/); + const names = event.summary.match(/(.*) (?:->|â) (.*)/); res.reservationFor.departureStation.name = names[1]; res.reservationFor.departureTime = JsonLd.readQDateTime(event, 'dtStart'); res.reservationFor.arrivalStation.name = names[2]; @@ -333,23 +333,26 @@ let reservations = []; let idx = 0; while (true) { - const trip = event.description.substr(idx).match(/(\d{2}:\d{2}) (.*?)(?:- (?:Gleis|platform|voie|VÃa|Spor|Kolej|binario|Peron) (.*?))?(?: \((.*\d+)\))?\n.* (\d{2}:\d{2}) (.*?)(?:\n| - (?:Gleis|platform|voie|VÃa|Spor|Kolej|binario|Peron) (.*)\n)/); + const trip = event.description.substr(idx).match(/(?:\[.*: \d .* (\S+), .* (\d+)\])?\n(?:(\S.*\S) \(.*\n)?.*(\d{2}:\d{2}) (.*?)(?:[-â·] (?:Gleis|platform|voie|VÃa|Spor|Kolej|binario|Peron) (.*?))?(?: \((.*\d+)\))?\n.* (\d{2}:\d{2}) (.*?)(?:\n| [-â·] (?:Gleis|platform|voie|VÃa|Spor|Kolej|binario|Peron) (.*)\n)/); if (!trip) { break; } idx += trip.index + trip[0].length; let res = JsonLd.newTrainReservation(); - const date = JsonLd.readQDateTime(event, 'dtStart')['@value'].substr(0, 10); - res.reservationFor.departureStation.name = trip[2]; - res.reservationFor.departureTime = JsonLd.toDateTime(date + trip[1], 'yyyy-MM-ddhh:mm', 'de'); - res.reservationFor.departurePlatform = trip[3]; - res.reservationFor.trainName = trip[4]; - res.reservationFor.arrivalStation.name = trip[6]; - res.reservationFor.arrivalTime = JsonLd.toDateTime(date + trip[5], 'yyyy-MM-ddhh:mm', 'de'); - res.reservationFor.arrivalPlatform = trip[7]; + const dtObj = JsonLd.readQDateTime(event, 'dtStart'); + const date = typeof dtObj === "string" ? dtObj.substr(0, 10) : dtObj['@value'].substr(0, 10); + res.reservationFor.departureStation.name = trip[5]; + res.reservationFor.departureTime = JsonLd.toDateTime(date + trip[4], 'yyyy-MM-ddhh:mm', 'de'); + res.reservationFor.departurePlatform = trip[6]; + res.reservationFor.trainNumber = trip[3] ? trip[3] : trip[7]; + res.reservationFor.arrivalStation.name = trip[9]; + res.reservationFor.arrivalTime = JsonLd.toDateTime(date + trip[8], 'yyyy-MM-ddhh:mm', 'de'); + res.reservationFor.arrivalPlatform = trip[10]; + res.reservedTicket.ticketedSeat.seatSection = trip[1]; + res.reservedTicket.ticketedSeat.seatNumber = trip[2]; - if (trip[4] && trip[4].match(/^Bus[ \d]/)) { + if (res.reservationFor.trainNumber.match(/^Bus[ \d]/)) { res = JsonLd.trainToBusReservation(res); } @@ -375,7 +378,7 @@ const trip = event.description.match(/.* â .*\n\[.*: \d .* (\S+), .* (\d+)\]\n(.*) \(.*\n.* ab .* â· \S+ (\S.*)\n.* an ?.* â· \S+ (\S.*)\n/); res.reservationFor.departurePlatform = trip[4]; - res.reservationFor.trainName = trip[3]; + res.reservationFor.trainNumber = trip[3]; res.reservationFor.arrivalPlatform = trip[5]; res.reservedTicket.ticketedSeat.seatSection = trip[1]; res.reservedTicket.ticketedSeat.seatNumber = trip[2]; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/src/lib/scripts/deutschebahn.json new/kitinerary-24.08.1/src/lib/scripts/deutschebahn.json --- old/kitinerary-24.08.0/src/lib/scripts/deutschebahn.json 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/src/lib/scripts/deutschebahn.json 2024-09-08 07:27:01.000000000 +0200 @@ -102,6 +102,12 @@ "match": "^\\d{14}@hafas$", "mimeType": "internal/event", "scope": "Current" + }, + { + "field": "uid", + "match": "^\\S{36}@bahn.de$", + "mimeType": "internal/event", + "scope": "Current" } ], "function": "parseEvent", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/src/lib/scripts/eurostar.js new/kitinerary-24.08.1/src/lib/scripts/eurostar.js --- old/kitinerary-24.08.0/src/lib/scripts/eurostar.js 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/src/lib/scripts/eurostar.js 2024-09-08 07:27:01.000000000 +0200 @@ -33,7 +33,7 @@ const dep = text.match(/From.*\n(?: +.*\n)?([ \S]\S.*?\S) /); res.reservationFor.departureStation.name = dep[1]; res.reservationFor.departureTime = JsonLd.toDateTime(times[1], "hh:mm", "en"); - const arr = text.match(/To.*\n(?: +.*\n)?([ \S]\S.*?\S) /); + const arr = text.match(/To.*\n(?: +.*\n)?([ \S]\S.*?\S)(?: |\n)/); res.reservationFor.arrivalStation.name = arr[1]; res.reservationFor.arrivalTime = JsonLd.toDateTime(times[2], "hh:mm", "en"); return res; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/src/lib/scripts/extractors.qrc new/kitinerary-24.08.1/src/lib/scripts/extractors.qrc --- old/kitinerary-24.08.0/src/lib/scripts/extractors.qrc 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/src/lib/scripts/extractors.qrc 2024-09-08 07:27:01.000000000 +0200 @@ -233,8 +233,12 @@ <file>regiojet.js</file> <file>regiondo.json</file> <file>regiondo.js</file> + <file>reisnordland.json</file> + <file>reisnordland.js</file> <file>renfe.json</file> <file>renfe.js</file> + <file>reservix.json</file> + <file>reservix.js</file> <file>ryanair.json</file> <file>ryanair.js</file> <file>salzbergwerk.de.json</file> @@ -297,6 +301,8 @@ <file>travelport-galileo.js</file> <file>trenitalia.json</file> <file>trenitalia.js</file> + <file>united.json</file> + <file>united.js</file> <file>viarail.json</file> <file>viarail.js</file> <file>vistara.json</file> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/src/lib/scripts/italo.js new/kitinerary-24.08.1/src/lib/scripts/italo.js --- old/kitinerary-24.08.0/src/lib/scripts/italo.js 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/src/lib/scripts/italo.js 2024-09-08 07:27:01.000000000 +0200 @@ -33,3 +33,36 @@ return reservations.length > 0 ? reservations : res; } + +function parsePdfTicket(pdf, node, barcode) { + const text = pdf.pages[barcode.location].text; + let res = JsonLd.newTrainReservation(); + res.reservedTicket.ticketToken = 'azteccode:' + barcode.content; + res.reservationNumber = text.match(/ ([A-Z0-9]{6})\n/)[1]; + const leg = text.match(/(\S.*\S) +(\S.*\S) +(\d\d \w{3} \d{4}) +(\S.*\S) +(\S.*\S)\n.*(\d\d:\d\d) +(\d\d:\d\d)/); + res.reservationFor.departureStation.name = leg[1]; + res.reservationFor.departureTime = JsonLd.toDateTime(leg[3] + ' ' + leg[6], 'dd MMM yyyy hh:mm', 'it'); + res.reservationFor.arrivalStation.name = leg[2]; + res.reservationFor.arrivalTime = JsonLd.toDateTime(leg[3] + ' ' + leg[7], 'dd MMM yyyy hh:mm', 'it'); + res.reservationFor.trainNumber = leg[4]; + res.reservedTicket.ticketedSeat.seatingType = leg[5]; + res.reservedTicket.ticketNumber = text.match(/(\d+) +CIV/)[1]; + + let idx = 0; + let reservations = []; + while (true) { + let pas = text.substr(idx).match(/(\S.*\S) +(\S.*\S) +(\d+) +(\d+)\n/); + if (!pas) { + break; + } + let r = JsonLd.clone(res); + r.underName.name = pas[1]; + r.reservedTicket.name = pas[2]; + r.reservedTicket.ticketedSeat.seatSection = pas[3]; + r.reservedTicket.ticketedSeat.seatNumber = pas[4]; + reservations.push(r); + idx += pas.index + pas[0].length; + } + + return reservations; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/src/lib/scripts/italo.json new/kitinerary-24.08.1/src/lib/scripts/italo.json --- old/kitinerary-24.08.0/src/lib/scripts/italo.json 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/src/lib/scripts/italo.json 2024-09-08 07:27:01.000000000 +0200 @@ -1,4 +1,4 @@ -{ +[{ "filter": [ { "match": "^[A-Za-z0-9/\\+=]{89}", @@ -9,4 +9,16 @@ "function": "parseTicket", "mimeType": "application/pdf", "script": "italo.js" -} +}, +{ + "filter": [ + { + "match": "^[A-Za-z0-9/\\+=]{65}", + "mimeType": "text/plain", + "scope": "Descendants" + } + ], + "function": "parsePdfTicket", + "mimeType": "application/pdf", + "script": "italo.js" +}] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/src/lib/scripts/mav.js new/kitinerary-24.08.1/src/lib/scripts/mav.js --- old/kitinerary-24.08.0/src/lib/scripts/mav.js 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/src/lib/scripts/mav.js 2024-09-08 07:27:01.000000000 +0200 @@ -19,15 +19,18 @@ // data starts at offset 20 in the header block, at which point both formats are structurally identical function parseBarcodeCommon(res, data) { const view = new DataView(data); - const tripBlockOffset = view.getUInt8(8) == 0x81 ? 87 : 23; - res.reservationFor.departureStation.identifier = parseUicStationCode(view.getUint32(tripBlockOffset - 1, false)); - res.reservationFor.departureStation.name = "" + (view.getUint32(tripBlockOffset - 1, false) & 0xffffff); - res.reservationFor.arrivalStation.identifier = parseUicStationCode(view.getUint32(tripBlockOffset + 2 , false)); - res.reservationFor.arrivalStation.name = "" + (view.getUint32(tripBlockOffset + 2, false) & 0xffffff); - res.reservedTicket.ticketedSeat.seatingType = ByteArray.decodeUtf8(data.slice(tripBlockOffset + 96, tripBlockOffset + 97)); - res.reservationFor.departureDay = parseDateTime(view.getUint32(tripBlockOffset + 98, false)); - if (view.getUInt8(8) == 0x81) { - res.underName.name = ByteArray.decodeUtf8(data.slice(19, 19 + 45)); + const ticketType = view.getUInt8(8); + const tripBlockOffset = ticketType == 0x81 ? 87 : 23; + if (ticketType & 0x01) { + res.reservationFor.departureStation.identifier = parseUicStationCode(view.getUint32(tripBlockOffset - 1, false)); + res.reservationFor.departureStation.name = "" + (view.getUint32(tripBlockOffset - 1, false) & 0xffffff); + res.reservationFor.arrivalStation.identifier = parseUicStationCode(view.getUint32(tripBlockOffset + 2 , false)); + res.reservationFor.arrivalStation.name = "" + (view.getUint32(tripBlockOffset + 2, false) & 0xffffff); + res.reservedTicket.ticketedSeat.seatingType = ByteArray.decodeUtf8(data.slice(tripBlockOffset + 96, tripBlockOffset + 97)); + res.reservationFor.departureDay = parseDateTime(view.getUint32(tripBlockOffset + 98, false)); + if (ticketType & 0x80) { + res.underName.name = ByteArray.decodeUtf8(data.slice(19, 19 + 45)); + } } for (var i = 0; i < view.getUInt8(10); ++i) { const seatBlock = data.slice(data.byteLength - ((i+1) *57)); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/src/lib/scripts/reisnordland.js new/kitinerary-24.08.1/src/lib/scripts/reisnordland.js --- old/kitinerary-24.08.0/src/lib/scripts/reisnordland.js 1970-01-01 01:00:00.000000000 +0100 +++ new/kitinerary-24.08.1/src/lib/scripts/reisnordland.js 2024-09-08 07:27:01.000000000 +0200 @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: 2024 Volker Krause <vkra...@kde.org> +// SPDX-License-Identifier: LGPL-2.0-or-later + +function extractPdfTicket(pdf, node, barcode) +{ + let res = JsonLd.newBoatReservation(); + res.reservedTicket.ticketToken = "qrcode:" + barcode.content; + const text = pdf.pages[barcode.location].text; + res.reservationNumber = text.match(/Ticket code:.*\n(\S+)\n/)[1]; + const dep = text.match(/from:(.*\S) +(\d{4}-\d{2}-\d{2} \d\d:\d\d:\d\d)\n/); + res.reservationFor.departureBoatTerminal.name = dep[1]; + res.reservationFor.departureTime = JsonLd.toDateTime(dep[2], "yyyy-MM-dd hh:mm:ss", "no"); + const arr = text.match(/to:(.*\S) +(\d{4}-\d{2}-\d{2} \d\d:\d\d:\d\d)\n/); + res.reservationFor.arrivalBoatTerminal.name = arr[1]; + res.reservationFor.arrivalTime = JsonLd.toDateTime(arr[2], "yyyy-MM-dd hh:mm:ss", "no"); + return res; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/src/lib/scripts/reisnordland.json new/kitinerary-24.08.1/src/lib/scripts/reisnordland.json --- old/kitinerary-24.08.0/src/lib/scripts/reisnordland.json 1970-01-01 01:00:00.000000000 +0100 +++ new/kitinerary-24.08.1/src/lib/scripts/reisnordland.json 2024-09-08 07:27:01.000000000 +0200 @@ -0,0 +1,12 @@ +{ + "filter": [ + { + "match": "^[A-Z0-9]{40}$", + "mimeType": "text/plain", + "scope": "Descendants" + } + ], + "function": "extractPdfTicket", + "mimeType": "application/pdf", + "script": "reisnordland.js" +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/src/lib/scripts/reservix.js new/kitinerary-24.08.1/src/lib/scripts/reservix.js --- old/kitinerary-24.08.0/src/lib/scripts/reservix.js 1970-01-01 01:00:00.000000000 +0100 +++ new/kitinerary-24.08.1/src/lib/scripts/reservix.js 2024-09-08 07:27:01.000000000 +0200 @@ -0,0 +1,25 @@ +/* + SPDX-FileCopyrightText: 2024 Kai Uwe Broulik <k...@broulik.de> + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +function parsePkPass(pass, node) { + let res = node.result[0]; + + res.reservationFor.name = pass.field.eventname.value; + res.reservationFor.startDate = JsonLd.toDateTime(pass.field.date.value, 'dd.MM.yyyy hh:mm', 'de'); + + res.reservationFor.location = JsonLd.newObject("Place"); + res.reservationFor.location.name = pass.field.location.value; + + const positionField = pass.field.position; + if (positionField && positionField.label === "Bereich / Reihe / Platz") { + const positionSegments = positionField.value.split(" / "); + res.reservedTicket.ticketedSeat = JsonLd.newObject("Seat"); + res.reservedTicket.ticketedSeat.seatSection = positionSegments[0]; + res.reservedTicket.ticketedSeat.seatRow = positionSegments[1]; + res.reservedTicket.ticketedSeat.seatNumber = positionSegments[2]; + } + + return res; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/src/lib/scripts/reservix.json new/kitinerary-24.08.1/src/lib/scripts/reservix.json --- old/kitinerary-24.08.0/src/lib/scripts/reservix.json 1970-01-01 01:00:00.000000000 +0100 +++ new/kitinerary-24.08.1/src/lib/scripts/reservix.json 2024-09-08 07:27:01.000000000 +0200 @@ -0,0 +1,13 @@ +[{ + "filter": [ + { + "field": "passTypeIdentifier", + "match": "pass.de.reservix.core", + "mimeType": "application/vnd.apple.pkpass", + "scope": "Current" + } + ], + "function": "parsePkPass", + "mimeType": "application/vnd.apple.pkpass", + "script": "reservix.js" +}] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/src/lib/scripts/sunnycars.js new/kitinerary-24.08.1/src/lib/scripts/sunnycars.js --- old/kitinerary-24.08.0/src/lib/scripts/sunnycars.js 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/src/lib/scripts/sunnycars.js 2024-09-08 07:27:01.000000000 +0200 @@ -37,9 +37,26 @@ res.pickupLocation.geo.latitude = location.latitude; res.pickupLocation.geo.longitude = location.longitude; - // TODO drop-off location. We currently do not have enough samples - // to tell whether the absence of a drop-off location indicates - // that it is identical to the pickup location. + // If dropoff-address is present, it's a one-way rental, + // otherwise assume the dropoff is identical with pickup. + // There is no geo coordinates for dropoff provided. + const dropoffAddress = pass.field["dropoff-address"]; + if (dropoffAddress) { + const dropoffAddressParts = dropoffAddress.value.split("\n"); + + if (!res.dropoffLocation.name) { + res.dropoffLocation.name = dropoffAddressParts[0]; + } + + res.dropoffLocation.address.streetAddress = dropoffAddressParts[1]; + + const dropoffTelLine = dropoffAddressParts[3]; + if (dropoffTelLine && dropoffTelLine.startsWith(telPrefix)) { + res.dropoffLocation.telephone = dropoffTelLine.substring(telPrefix.length); + } + } else { + res.dropoffLocation = res.pickupLocation; + } res.reservationFor.model = pass.field["vehicle-group-detail"].value; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/src/lib/scripts/united.js new/kitinerary-24.08.1/src/lib/scripts/united.js --- old/kitinerary-24.08.0/src/lib/scripts/united.js 1970-01-01 01:00:00.000000000 +0100 +++ new/kitinerary-24.08.1/src/lib/scripts/united.js 2024-09-08 07:27:01.000000000 +0200 @@ -0,0 +1,113 @@ +/* + SPDX-FileCopyrightText: 2024 Joshua Goins <j...@redstrate.com> + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +// Example: Tue, Sep 03, 2024 02:23 AM +const unitedDateFormat = "ddd, MMM d, yyyy hh:mm ap"; + +function collectChildren(element) { + var children = new Array(); + var child = element.firstChild; + while (!child.isNull) { + children.push(child); + child = child.nextSibling; + } + return children; +} + +function parseAirport(airport, name) { + airport.name = name; + return airport; +} + +function main(html) { + var reservations = new Array(); + console.log(html); + + var confirmationNumberElement = html.eval("//tr[td[text()='Confirmation Number:']]/following-sibling::tr[1]")[0] + if (!confirmationNumberElement) + return {}; + + // Each flight is in it's own table + var rows = html.eval("//tr/td/table[tr[td[contains(., 'Flight')]]]") + for (var i in rows) { + // Deficiency in the XPath, the first table is not relevant + if (i == 0) + continue; + + var res = JsonLd.newFlightReservation(); + res.reservationNumber = confirmationNumberElement.recursiveContent; + + // Then the table is made up of four <tr> + var tableRow = rows[i].firstChild; + for (var j = 0; j < 4; j++) { + var departureDate; + var arrivalDate; + + const children = collectChildren(tableRow); + if (j == 0) { + // Flight index, flight number and class + const flightNumber = children[0].content; + const flightClass = children[2]; + + // Example: Flight 1 of 4 UA1757 + var airline = flightNumber.match(/Flight\s([0-9])\sof\s[0-9]\s([A-Z0-9]{2})(\d{1,4})\b/); + if (!airline) + continue; + res.reservationFor.airline.iataCode = airline[2]; + // TODO: what to do about other IATA's? I need to find a previous reservation with an "operated by" tag probably. + if (airline[2] == "UA") { + res.reservationFor.airline.name = "United Airlines"; + } + res.reservationFor.flightNumber = airline[3]; + } else if (j == 1) { + // Departure and arrival dates + departureDate = children[0].content; + arrivalDate = children[2].content; + } else if (j == 2) { + // Departure and arrival times + const departureTime = children[0].content; + const arrivalTime = children[2].content; + + res.reservationFor.arrivalTime = JsonLd.toDateTime(arrivalDate + ' ' + arrivalTime, unitedDateFormat, "en"); + res.reservationFor.departureTime = JsonLd.toDateTime(departureDate + ' ' + departureTime, unitedDateFormat, "en"); + } else if (j == 3) { + // Departure and arrival airports + const departureAirport = children[0].content; + const arrivalAirport = children[2].content; + parseAirport(res.reservationFor.departureAirport, departureAirport); + parseAirport(res.reservationFor.arrivalAirport, arrivalAirport); + } + tableRow = tableRow.nextSibling; + } + + reservations.push(res); + } + + // Parse the seats, they are in a completely separate thing in the end + var travelerInformation = html.eval("//tr/td/table[tr[td[contains(., 'Traveler Details')]]]")[1] + var travelerRow = travelerInformation.firstChild; + var i = 0; + var j = 0; + while (!travelerRow.isNull) { + if (i == 1) { + // Traveler name, the name is usually garbage but it's useful to keep anyway + res.underName = travelerRow.recursiveContent; + } else if (i > 1) { + // Possibly contains seating information + // Example: JFK-IAD 29C + const seats = travelerRow.recursiveContent.match(/([A-Z]{3})-([A-Z]{3})\s([0-9]{2}[A-Z])/); + if (seats) { + // TODO: This is almost certainly always in order, but we should find the specific flight connection from the two given to us via the regex. + reservations[j].airplaneSeat = seats[3]; + j++; + } + } + travelerRow = travelerRow.nextSibling; + i++; + } + + return reservations; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/src/lib/scripts/united.json new/kitinerary-24.08.1/src/lib/scripts/united.json --- old/kitinerary-24.08.0/src/lib/scripts/united.json 1970-01-01 01:00:00.000000000 +0100 +++ new/kitinerary-24.08.1/src/lib/scripts/united.json 2024-09-08 07:27:01.000000000 +0200 @@ -0,0 +1,13 @@ +{ + "filter": [ + { + "field": "From", + "match": "@united.com", + "mimeType": "message/rfc822", + "scope": "Ancestors" + } + ], + "function": "main", + "mimeType": "text/html", + "script": "united.js" +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-24.08.0/src/lib/vdv/vdvticket.cpp new/kitinerary-24.08.1/src/lib/vdv/vdvticket.cpp --- old/kitinerary-24.08.0/src/lib/vdv/vdvticket.cpp 2024-08-16 07:00:56.000000000 +0200 +++ new/kitinerary-24.08.1/src/lib/vdv/vdvticket.cpp 2024-09-08 07:27:01.000000000 +0200 @@ -12,6 +12,7 @@ #include "../asn1/berelement.h" #include <QDebug> +#include <QStringDecoder> using namespace KItinerary; @@ -152,12 +153,17 @@ return {}; } - const auto len = strnlen(tlv->name(), tlv->nameSize(elem.contentSize())); // name field can contain null bytes + const auto len = (qsizetype)strnlen(tlv->name(), tlv->nameSize(elem.contentSize())); // name field can contain null bytes if (len == 0) { return {}; } - const auto name = QString::fromUtf8(tlv->name(), len); + QString name; + QStringDecoder utf8Decoder(QStringDecoder::Utf8); + name = utf8Decoder.decode(QByteArrayView(tlv->name(), len)); + if (utf8Decoder.hasError()) { + name = QString::fromLatin1(tlv->name(), len); + } Person p; const auto idxHash = name.indexOf(QLatin1Char('#'));