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('#'));

Reply via email to