Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package kitinerary for openSUSE:Factory checked in at 2026-03-07 20:02:12 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/kitinerary (Old) and /work/SRC/openSUSE:Factory/.kitinerary.new.8177 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kitinerary" Sat Mar 7 20:02:12 2026 rev:95 rq:1337006 version:25.12.3 Changes: -------- --- /work/SRC/openSUSE:Factory/kitinerary/kitinerary.changes 2026-02-06 19:04:35.301567606 +0100 +++ /work/SRC/openSUSE:Factory/.kitinerary.new.8177/kitinerary.changes 2026-03-07 20:03:18.703452305 +0100 @@ -1,0 +2,16 @@ +Tue Mar 3 09:56:52 UTC 2026 - Christophe Marin <[email protected]> + +- Update to 25.12.3 + * New bugfix release + * For more details please see: + * https://kde.org/announcements/gear/25.12.3/ +- Changes since 25.12.2: + * Improve booking.com extractor + * Improve street address substring matching + * Add new FRS extractor for ferries from algeciras + * Add basic extractor for getyourguide + * hostelworld: Add support for new email format + * Extract terminal information from FCM emails + * Add Swedisch language FCM sample + +------------------------------------------------------------------- Old: ---- kitinerary-25.12.2.tar.xz kitinerary-25.12.2.tar.xz.sig New: ---- kitinerary-25.12.3.tar.xz kitinerary-25.12.3.tar.xz.sig ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kitinerary.spec ++++++ --- /var/tmp/diff_new_pack.sfoiZE/_old 2026-03-07 20:03:19.551487316 +0100 +++ /var/tmp/diff_new_pack.sfoiZE/_new 2026-03-07 20:03:19.555487481 +0100 @@ -18,11 +18,11 @@ %define kf6_version 6.19.0 %define qt6_version 6.9.0 -%define kpim6_version 6.6.2 +%define kpim6_version 6.6.3 %bcond_without released Name: kitinerary -Version: 25.12.2 +Version: 25.12.3 Release: 0 Summary: Data model and extraction system for travel reservations License: LGPL-2.1-or-later ++++++ kitinerary-25.12.2.tar.xz -> kitinerary-25.12.3.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-25.12.2/CMakeLists.txt new/kitinerary-25.12.3/CMakeLists.txt --- old/kitinerary-25.12.2/CMakeLists.txt 2026-02-02 17:53:57.000000000 +0100 +++ new/kitinerary-25.12.3/CMakeLists.txt 2026-03-02 18:03:50.000000000 +0100 @@ -7,10 +7,10 @@ # KDE Application Version, managed by release script set (RELEASE_SERVICE_VERSION_MAJOR "25") set (RELEASE_SERVICE_VERSION_MINOR "12") -set (RELEASE_SERVICE_VERSION_MICRO "2") +set (RELEASE_SERVICE_VERSION_MICRO "3") set (RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}") -set(PIM_VERSION "6.6.2") +set(PIM_VERSION "6.6.3") project(KItinerary VERSION ${PIM_VERSION}) set(QT_REQUIRED_VERSION "6.7.0") @@ -50,8 +50,8 @@ find_package(SharedMimeInfo 1.3 REQUIRED) endif() -set(KMIME_VERSION "6.6.2") -set(PIM_PKPASS "6.6.2") +set(KMIME_VERSION "6.6.3") +set(PIM_PKPASS "6.6.3") 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-25.12.2/autotests/extractordata/fcm/fcmtravel_2.txt.json new/kitinerary-25.12.3/autotests/extractordata/fcm/fcmtravel_2.txt.json --- old/kitinerary-25.12.2/autotests/extractordata/fcm/fcmtravel_2.txt.json 2026-02-02 17:53:57.000000000 +0100 +++ new/kitinerary-25.12.3/autotests/extractordata/fcm/fcmtravel_2.txt.json 2026-03-02 18:03:50.000000000 +0100 @@ -139,6 +139,7 @@ "iataCode": "SFO", "name": "San Francisco International" }, + "arrivalTerminal": "I", "arrivalTime": { "@type": "QDateTime", "@value": "2016-10-17T15:55:00-07:00", @@ -197,6 +198,7 @@ "iataCode": "SFO", "name": "San Francisco International" }, + "arrivalTerminal": "I", "arrivalTime": { "@type": "QDateTime", "@value": "2016-10-17T15:55:00-07:00", @@ -255,6 +257,7 @@ "iataCode": "ORD", "name": "O Hare International" }, + "arrivalTerminal": "3", "arrivalTime": { "@type": "QDateTime", "@value": "2016-10-22T14:00:00-05:00", @@ -313,6 +316,7 @@ "iataCode": "ORD", "name": "O Hare International" }, + "arrivalTerminal": "3", "arrivalTime": { "@type": "QDateTime", "@value": "2016-10-22T14:00:00-05:00", @@ -391,6 +395,7 @@ "name": "O Hare International" }, "departureDay": "2016-10-22", + "departureTerminal": "3", "departureTime": { "@type": "QDateTime", "@value": "2016-10-22T15:25:00-05:00", @@ -449,6 +454,7 @@ "name": "O Hare International" }, "departureDay": "2016-10-22", + "departureTerminal": "3", "departureTime": { "@type": "QDateTime", "@value": "2016-10-22T15:25:00-05:00", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-25.12.2/autotests/extractordata/fcm/fcmtravel_3.txt new/kitinerary-25.12.3/autotests/extractordata/fcm/fcmtravel_3.txt --- old/kitinerary-25.12.2/autotests/extractordata/fcm/fcmtravel_3.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/kitinerary-25.12.3/autotests/extractordata/fcm/fcmtravel_3.txt 2026-03-02 18:03:50.000000000 +0100 @@ -0,0 +1,81 @@ +Tack för att du bokat din resa hos Travellink! + + + +Din bokningsreferens: ABC123 + +Bokad av: Booking Agent +Företag: The Company AB +Adress: Street 30 + 12345 City + +Resenär: Katie Dragon + + + + +===================================================================================== +FLYG Flygbolagets bokningsreferens: ABCD0 - Iberia +===================================================================================== + + Bokningsstatus: Bekräftad +UTRESA Berlin - Las Palmas +Flyg: IB3549, Iberia +Datum: fre 3 jul 2009 +Avgång: 07:35 Tegel(TXL), Berlin, Tyskland +Ankomst: 10:35 Barajas(MAD), Madrid, Spanien + Terminal 4 +Klass: Ekonomiklass + + Bokningsstatus: Bekräftad +Flyg: IB804, Iberia +Datum: fre 3 jul 2009 +Avgång: 12:15 Barajas(MAD), Madrid, Spanien + Terminal 4 +Ankomst: 14:00 Las Palmas(LPA), Las Palmas, Spanien +Klass: Ekonomiklass +Restid: + + Bokningsstatus: Bekräftad +HEMRESA Las Palmas - Berlin +Flyg: IB807, Iberia +Datum: lör 11 jul 2009 +Avgång: 11:10 Las Palmas(LPA), Las Palmas, Spanien +Ankomst: 14:45 Barajas(MAD), Madrid, Spanien + Terminal 4S +Klass: Ekonomiklass + + Bokningsstatus: Bekräftad +Flyg: IB3548, Iberia +Datum: lör 11 jul 2009 +Avgång: 15:50 Barajas(MAD), Madrid, Spanien + Terminal 4 +Ankomst: 18:40 Tegel(TXL), Berlin, Tyskland +Klass: Ekonomiklass +Restid: + Avgångs- och ankomsttider anges i lokal tid + +------------------------------------------------------------------------------------- +Biljett(er) +------------------------------------------------------------------------------------- +Elektronisk biljett +Bokningsreferens - som e-ticket. OBS! Ta alltid med bokningsbekräftelse och giltigt foto ID till flygplatsen. +Avbokning utan avgift, kan göras via travellink.se senast kl. 10.00 fredag den 24 apr 2009. + + + + + + + + + + +------------------------------------------------------------------------------------- +Betalning +------------------------------------------------------------------------------------- +Kreditkort: American Express 3757 xxxx xxxx 013 +Pris*: 4 321 SEK +Biljettleverans: 0 SEK +Administrativ avgift: 0 SEK +Totalpris: 4 321 SEK diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-25.12.2/autotests/extractordata/fcm/fcmtravel_3.txt.json new/kitinerary-25.12.3/autotests/extractordata/fcm/fcmtravel_3.txt.json --- old/kitinerary-25.12.2/autotests/extractordata/fcm/fcmtravel_3.txt.json 1970-01-01 01:00:00.000000000 +0100 +++ new/kitinerary-25.12.3/autotests/extractordata/fcm/fcmtravel_3.txt.json 2026-03-02 18:03:50.000000000 +0100 @@ -0,0 +1,246 @@ +[ + { + "@context": "http://schema.org", + "@type": "FlightReservation", + "priceCurrency": "SEK", + "reservationFor": { + "@type": "Flight", + "airline": { + "@type": "Airline", + "iataCode": "IB", + "name": "Iberia" + }, + "arrivalAirport": { + "@type": "Airport", + "address": { + "@type": "PostalAddress", + "addressCountry": "ES" + }, + "geo": { + "@type": "GeoCoordinates", + "latitude": 40.467899322509766, + "longitude": -3.5717599391937256 + }, + "iataCode": "MAD", + "name": "Barajas" + }, + "arrivalTerminal": "4", + "arrivalTime": { + "@type": "QDateTime", + "@value": "2009-07-03T10:35:00+02:00", + "timezone": "Europe/Madrid" + }, + "departureAirport": { + "@type": "Airport", + "address": { + "@type": "PostalAddress", + "addressCountry": "DE" + }, + "geo": { + "@type": "GeoCoordinates", + "latitude": 52.55379867553711, + "longitude": 13.29319953918457 + }, + "iataCode": "TXL", + "name": "Tegel" + }, + "departureDay": "2009-07-03", + "departureTime": { + "@type": "QDateTime", + "@value": "2009-07-03T07:35:00+02:00", + "timezone": "Europe/Berlin" + }, + "flightNumber": "3549" + }, + "reservationNumber": "ABC123", + "reservationStatus": "http://schema.org/ReservationConfirmed", + "totalPrice": 4321, + "underName": { + "@type": "Person", + "name": "Katie Dragon" + } + }, + { + "@context": "http://schema.org", + "@type": "FlightReservation", + "priceCurrency": "SEK", + "reservationFor": { + "@type": "Flight", + "airline": { + "@type": "Airline", + "iataCode": "IB", + "name": "Iberia" + }, + "arrivalAirport": { + "@type": "Airport", + "address": { + "@type": "PostalAddress", + "addressCountry": "ES" + }, + "geo": { + "@type": "GeoCoordinates", + "latitude": 27.938400268554688, + "longitude": -15.388999938964844 + }, + "iataCode": "LPA", + "name": "Las Palmas" + }, + "arrivalTime": { + "@type": "QDateTime", + "@value": "2009-07-03T14:00:00+01:00", + "timezone": "Atlantic/Canary" + }, + "departureAirport": { + "@type": "Airport", + "address": { + "@type": "PostalAddress", + "addressCountry": "ES" + }, + "geo": { + "@type": "GeoCoordinates", + "latitude": 40.467899322509766, + "longitude": -3.5717599391937256 + }, + "iataCode": "MAD", + "name": "Barajas" + }, + "departureDay": "2009-07-03", + "departureTerminal": "4", + "departureTime": { + "@type": "QDateTime", + "@value": "2009-07-03T12:15:00+02:00", + "timezone": "Europe/Madrid" + }, + "flightNumber": "804" + }, + "reservationNumber": "ABC123", + "reservationStatus": "http://schema.org/ReservationConfirmed", + "totalPrice": 4321, + "underName": { + "@type": "Person", + "name": "Katie Dragon" + } + }, + { + "@context": "http://schema.org", + "@type": "FlightReservation", + "priceCurrency": "SEK", + "reservationFor": { + "@type": "Flight", + "airline": { + "@type": "Airline", + "iataCode": "IB", + "name": "Iberia" + }, + "arrivalAirport": { + "@type": "Airport", + "address": { + "@type": "PostalAddress", + "addressCountry": "ES" + }, + "geo": { + "@type": "GeoCoordinates", + "latitude": 40.467899322509766, + "longitude": -3.5717599391937256 + }, + "iataCode": "MAD", + "name": "Barajas" + }, + "arrivalTerminal": "4S", + "arrivalTime": { + "@type": "QDateTime", + "@value": "2009-07-11T14:45:00+02:00", + "timezone": "Europe/Madrid" + }, + "departureAirport": { + "@type": "Airport", + "address": { + "@type": "PostalAddress", + "addressCountry": "ES" + }, + "geo": { + "@type": "GeoCoordinates", + "latitude": 27.938400268554688, + "longitude": -15.388999938964844 + }, + "iataCode": "LPA", + "name": "Las Palmas" + }, + "departureDay": "2009-07-11", + "departureTime": { + "@type": "QDateTime", + "@value": "2009-07-11T11:10:00+01:00", + "timezone": "Atlantic/Canary" + }, + "flightNumber": "807" + }, + "reservationNumber": "ABC123", + "reservationStatus": "http://schema.org/ReservationConfirmed", + "totalPrice": 4321, + "underName": { + "@type": "Person", + "name": "Katie Dragon" + } + }, + { + "@context": "http://schema.org", + "@type": "FlightReservation", + "priceCurrency": "SEK", + "reservationFor": { + "@type": "Flight", + "airline": { + "@type": "Airline", + "iataCode": "IB", + "name": "Iberia" + }, + "arrivalAirport": { + "@type": "Airport", + "address": { + "@type": "PostalAddress", + "addressCountry": "DE" + }, + "geo": { + "@type": "GeoCoordinates", + "latitude": 52.55379867553711, + "longitude": 13.29319953918457 + }, + "iataCode": "TXL", + "name": "Tegel" + }, + "arrivalTime": { + "@type": "QDateTime", + "@value": "2009-07-11T18:40:00+02:00", + "timezone": "Europe/Berlin" + }, + "departureAirport": { + "@type": "Airport", + "address": { + "@type": "PostalAddress", + "addressCountry": "ES" + }, + "geo": { + "@type": "GeoCoordinates", + "latitude": 40.467899322509766, + "longitude": -3.5717599391937256 + }, + "iataCode": "MAD", + "name": "Barajas" + }, + "departureDay": "2009-07-11", + "departureTerminal": "4", + "departureTime": { + "@type": "QDateTime", + "@value": "2009-07-11T15:50:00+02:00", + "timezone": "Europe/Madrid" + }, + "flightNumber": "3548" + }, + "reservationNumber": "ABC123", + "reservationStatus": "http://schema.org/ReservationConfirmed", + "totalPrice": 4321, + "underName": { + "@type": "Person", + "name": "Katie Dragon" + } + } +] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-25.12.2/po/cs/kitinerary6.po new/kitinerary-25.12.3/po/cs/kitinerary6.po --- old/kitinerary-25.12.2/po/cs/kitinerary6.po 2026-02-02 17:53:57.000000000 +0100 +++ new/kitinerary-25.12.3/po/cs/kitinerary6.po 2026-03-02 18:03:50.000000000 +0100 @@ -1,18 +1,19 @@ # SPDX-FileCopyrightText: 2017, 2018, 2019, 2020, 2021, 2022, 2024 Vit Pelcak <[email protected]> +# SPDX-FileCopyrightText: 2026 Libor Filípek <[email protected]> msgid "" msgstr "" "Project-Id-Version: desktop files\n" "Report-Msgid-Bugs-To: https://bugs.kde.org\n" "POT-Creation-Date: 2025-11-17 14:41+0000\n" -"PO-Revision-Date: 2024-06-25 10:53+0200\n" -"Last-Translator: Vit Pelcak <[email protected]>\n" -"Language-Team: Czech <[email protected]>\n" +"PO-Revision-Date: 2026-02-02 17:03+0100\n" +"Last-Translator: Libor Filípek <[email protected]>\n" +"Language-Team: \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Lokalize 24.05.1\n" +"X-Generator: Lokalize 25.12.1\n" #: calendarhandler.cpp:171 #, kde-format @@ -49,7 +50,7 @@ #: calendarhandler.cpp:240 #, kde-format msgid "Boarding group: %1" -msgstr "" +msgstr "Skupina pro nástup: %1" #: calendarhandler.cpp:243 calendarhandler.cpp:275 calendarhandler.cpp:303 #, kde-format @@ -61,7 +62,7 @@ #: calendarhandler.cpp:477 calendarhandler.cpp:509 #, kde-format msgid "Booking reference: %1" -msgstr "" +msgstr "Číslo rezervace: %1" #: calendarhandler.cpp:258 #, kde-format @@ -178,3 +179,6 @@ "Under name: %2\n" "Pickup location: %3" msgstr "" +"Číslo rezervace: %1\n" +"Jméno: %2\n" +"Místo vyzvednutí: %3" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-25.12.2/src/cli/org.kde.kitinerary-extractor.appdata.xml new/kitinerary-25.12.3/src/cli/org.kde.kitinerary-extractor.appdata.xml --- old/kitinerary-25.12.2/src/cli/org.kde.kitinerary-extractor.appdata.xml 2026-02-02 17:53:57.000000000 +0100 +++ new/kitinerary-25.12.3/src/cli/org.kde.kitinerary-extractor.appdata.xml 2026-03-02 18:03:50.000000000 +0100 @@ -86,6 +86,7 @@ <p xml:lang="ar">مستخرج مسار الرحلة بسطر الأوامر.</p> <p xml:lang="ca">Extractor de les dades d'itineraris mitjançant la línia d'ordres, per a la integració en aplicacions de tercers.</p> <p xml:lang="ca-valencia">Extractor de les dades d'itineraris mitjançant la línia d'ordres, per a la integració en aplicacions de tercers.</p> + <p xml:lang="cs">Extraktor v příkazovém řádku pro data itineráře a pro integraci do aplikací třetích stran.</p> <p xml:lang="da">Kommandolinjeværktøj til at udtrække rejseplan-data, til integration med tredjepartsprogrammer.</p> <p xml:lang="de">Reisedaten-Extraktor für die Befehlszeile zur Integration in Drittanwendungen.</p> <p xml:lang="en-GB">Command line extractor for itinerary data, for integrating into 3rd party applications.</p> @@ -131,6 +132,7 @@ </categories> <launchable type="desktop-id">org.kde.kitinerary-extractor.desktop</launchable> <releases> + <release version="6.6.3" date="2026-03-05"/> <release version="6.6.2" date="2026-02-05"/> <release version="6.6.1" date="2026-01-08"/> <release version="6.6.0" date="2025-12-11"/> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-25.12.2/src/lib/locationutil.cpp new/kitinerary-25.12.3/src/lib/locationutil.cpp --- old/kitinerary-25.12.2/src/lib/locationutil.cpp 2026-02-02 17:53:57.000000000 +0100 +++ new/kitinerary-25.12.3/src/lib/locationutil.cpp 2026-03-02 18:03:50.000000000 +0100 @@ -402,7 +402,12 @@ if (!lhsAddr.postalCode().isEmpty() && !rhsAddr.postalCode().isEmpty() && lhsAddr.postalCode() != rhsAddr.postalCode()) { return false; } - return (lhsAddr.streetAddress().startsWith(rhsAddr.streetAddress(), Qt::CaseInsensitive) || rhsAddr.streetAddress().startsWith(lhsAddr.streetAddress(), Qt::CaseInsensitive)) && lhsAddr.addressLocality() == rhsAddr.addressLocality(); + return lhsAddr.addressLocality() == rhsAddr.addressLocality() && ( + lhsAddr.streetAddress().startsWith(rhsAddr.streetAddress(), Qt::CaseInsensitive) || + rhsAddr.streetAddress().startsWith(lhsAddr.streetAddress(), Qt::CaseInsensitive) || + lhsAddr.streetAddress().endsWith(rhsAddr.streetAddress(), Qt::CaseInsensitive) || + rhsAddr.streetAddress().endsWith(lhsAddr.streetAddress(), Qt::CaseInsensitive) + ); } break; case CityLevel: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-25.12.2/src/lib/rsp/rsp6decoder.cpp new/kitinerary-25.12.3/src/lib/rsp/rsp6decoder.cpp --- old/kitinerary-25.12.2/src/lib/rsp/rsp6decoder.cpp 2026-02-02 17:53:57.000000000 +0100 +++ new/kitinerary-25.12.3/src/lib/rsp/rsp6decoder.cpp 2026-03-02 18:03:50.000000000 +0100 @@ -19,7 +19,7 @@ using namespace KItinerary; -static QByteArray decodeBase45Backward(const char *begin, const char *end) +static QByteArray decodeBase26Backward(const char *begin, const char *end) { openssl::bn_ptr bn(BN_new()); BN_zero(bn.get()); @@ -85,7 +85,7 @@ } // remove base26 transport encoding - const auto decoded = decodeBase45Backward(data.begin() + 15, data.end()); + const auto decoded = decodeBase26Backward(data.begin() + 15, data.end()); // decrypt payload, try all keys for the current issuer until we find one that works QByteArray decrypted; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-25.12.2/src/lib/scripts/booking.js new/kitinerary-25.12.3/src/lib/scripts/booking.js --- old/kitinerary-25.12.2/src/lib/scripts/booking.js 2026-02-02 17:53:57.000000000 +0100 +++ new/kitinerary-25.12.3/src/lib/scripts/booking.js 2026-03-02 18:03:50.000000000 +0100 @@ -25,7 +25,7 @@ regExMap['de'] = { bookingRef: /(?:Buchungsnummer|Bestätigungsnummer): ([0-9]*)\s+/, - hotelInformation: /(?:Lage )?(\S[^\n]*(?:,[^\n,]*?\n?[^\n,]*?){2,3})[\n\s]?-?\s+(?:Reiseroute.*\n)?\s*(?:Telefon:? (\+[0-9 \-]+)|Kontakt.*|E-Mail an.*)\n/, + hotelInformation: /(?:Lage )?(\S[^\n]*(?:,[^\n,]*?\n?[^\n,]*?){1,3})[\n\s]?-?\s+(?:Reiseroute.*\n)?\s*(?:Telefon:? (\+[0-9 \-]+)|Kontakt.*|E-Mail an.*)\n/, hotelName: [/Die Unterkunft (.*)\s+erwartet Sie/, /\n\n\s*([^\s\[].*\S)\n\n\s*\[\S/], arrivalDate: /Anreise +([A-Z][a-z]+, [0-9]{1,2}\. \S+ [0-9]{4}) \((?:ab )?([0-9]{1,2}:[0-9]{2}).*\)/, departureDate: /Abreise +([A-Z][a-z]+, [0-9]{1,2}\. \S+ [0-9]{4}) \(.*?([0-9]{1,2}:[0-9]{2})\)/, @@ -85,13 +85,25 @@ continue; res.reservationNumber = bookingRef[1]; - let hotelName = undefined; - for (const nameRx of regExMap[locale]['hotelName']) { - hotelName = text.match(nameRx); - if (hotelName) - break; + // try subject first, before looking for the name in the body + let mime = node.parent; + while (mime && mime.mimeType !== "message/rfc822") + mime = mime.parent; + if (mime) { + const name = mime.content.subject.match(/(?:confirmed at|bestätigt:) (.*)/); + if (name) + res.reservationFor.name = name[1]; + } + + if (!res.reservationFor.name) { + let hotelName = undefined; + for (const nameRx of regExMap[locale]['hotelName']) { + hotelName = text.match(nameRx); + if (hotelName) + break; + } + res.reservationFor.name = hotelName[1]; } - res.reservationFor.name = hotelName[1]; const hotel = text.match(regExMap[locale]['hotelInformation']); const addr = hotel[1].split(/, */); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-25.12.2/src/lib/scripts/extractors.qrc new/kitinerary-25.12.3/src/lib/scripts/extractors.qrc --- old/kitinerary-25.12.2/src/lib/scripts/extractors.qrc 2026-02-02 17:53:57.000000000 +0100 +++ new/kitinerary-25.12.3/src/lib/scripts/extractors.qrc 2026-03-02 18:03:50.000000000 +0100 @@ -169,6 +169,8 @@ <file>flibco.js</file> <file>flixbus.json</file> <file>flixbus.js</file> + <file>frs.json</file> + <file>frs.js</file> <file>gastronovi.json</file> <file>gastronovi.js</file> <file>generic.js</file> @@ -176,6 +178,8 @@ <file>georgian-railway.js</file> <file>gepard-express.json</file> <file>gepard-express.js</file> + <file>getyourguide.json</file> + <file>getyourguide.js</file> <file>ghotel.json</file> <file>ghotel.js</file> <file>globalticket.json</file> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-25.12.2/src/lib/scripts/fcmtravel.js new/kitinerary-25.12.3/src/lib/scripts/fcmtravel.js --- old/kitinerary-25.12.2/src/lib/scripts/fcmtravel.js 2026-02-02 17:53:57.000000000 +0100 +++ new/kitinerary-25.12.3/src/lib/scripts/fcmtravel.js 2026-03-02 18:03:50.000000000 +0100 @@ -30,16 +30,17 @@ const depDate = text.substr(pos + index).match(/(?:Date|Datum): *\S{3} (.*)\n/); if (depDate) index += depDate.index + depDate[0].length; - const depLine = text.substr(pos + index).match(/(?:Departure|Avgång): *([0-9]+:[0-9]+) *(.*) *\(([A-Z]{3})\)/); + const depLine = text.substr(pos + index).match(/(?:Departure|Avgång): *([0-9]+:[0-9]+) *(.*) *\(([A-Z]{3})\).*\n(?:\s+Terminal\s(.*)\n)?/); if (!depLine) break; index += depLine.index + depLine[0].length; res.reservationFor.departureTime = JsonLd.toDateTime(depDate[1] + " " + depLine[1], "d MMM yyyy hh:mm", ['en', 'sv']); res.reservationFor.departureAirport.name = depLine[2]; res.reservationFor.departureAirport.iataCode = depLine[3]; + res.reservationFor.departureTerminal = depLine[4]; let arrDate = text.substr(pos + index).match(/(?:Date|Datum): *[A-Z][a-z]{2} (.*)\n/); - const arrLine = text.substr(pos + index).match(/(?:Arrival|Ankomst): *([0-9]+:[0-9]+) *(.*) *\(([A-Z]{3})\)/); + const arrLine = text.substr(pos + index).match(/(?:Arrival|Ankomst): *([0-9]+:[0-9]+) *(.*) *\(([A-Z]{3})\).*\n(?:\s+Terminal\s(.*)\n)?/); if (!arrLine) break; if (!arrDate || arrDate.index > arrLine.index) // arrival date is sometimes optional @@ -48,6 +49,7 @@ res.reservationFor.arrivalTime = JsonLd.toDateTime(arrDate[1] + " " + arrLine[1], "d MMM yyyy hh:mm", ['en', 'sv']); res.reservationFor.arrivalAirport.name = arrLine[2]; res.reservationFor.arrivalAirport.iataCode = arrLine[3]; + res.reservationFor.arrivalTerminal = arrLine[4]; reservations.push(res); if (index == 0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-25.12.2/src/lib/scripts/frs.js new/kitinerary-25.12.3/src/lib/scripts/frs.js --- old/kitinerary-25.12.2/src/lib/scripts/frs.js 1970-01-01 01:00:00.000000000 +0100 +++ new/kitinerary-25.12.3/src/lib/scripts/frs.js 2026-03-02 18:03:50.000000000 +0100 @@ -0,0 +1,77 @@ +// SPDX-FileCopyrightText: 2026 Carl Schwan <[email protected]> +// SPDX-License-Identifier: LGPL-2.0-or-later + +function extractPdf(pdf, node, barcode) { + const content = pdf.text; + const lines = content.split('\n'); + const reservations = []; + let departureStation; + let departureTime; + let arrivalStation; + let bookingNumber; + + for (let i = 0, count= lines.length; i < count; i++) { + const line = lines[i].trim(); + if (line.startsWith('BOOKING NUMBER')) { + bookingNumber = lines[i+1]; + } + if (line.startsWith('DEPARTURE')) { + const match = line.match('-(.*) >> (.*)'); + departureStation = match[1].trim(); + arrivalStation = match[2].trim(); + departureTime = JsonLd.toDateTime(lines[i + 1].trim().split(' ')[0], ["dd.MM.yyyy hh:mm"], ["en"]); + break; + } + } + + let barcodeText = null; + + const images = node.findChildNodes({ mimeType: "internal/qimage", scope: "Descendants" }); + + for (let image of images) { + if (image.childNodes && image.childNodes.length === 1 && image.childNodes[0].mimeType === "text/plain") { + const barcode = image.childNodes[0].content; + if (barcode) { barcodeText = "qrCode:" + barcode; + break; + } + } + } + + // hardcode because FRS only operates 3 ports + const ports = { + 'Algeciras': [36.131294, -5.438265, 'Puerto de Algeciras', 11201, 'Algeciras'], + 'Tangier Med': [35.876633, -5.5118833, 'Port Tanger Med', null, 'Tanger'], + 'Ceuta': [35.894489, -5.320913, 'Ferry Ceuta Algeciras', 51002, 'Ceuta'], // guess + }; + + for (let i = 0, count = lines.length; i < count; i++) { + const line = lines[i].trim(); + if (line.startsWith('Passenger')) { + i++; + while (lines[i].trim().length > 0) { + const res = JsonLd.newBoatReservation(); + res.reservationNumber = bookingNumber; + res.reservedTicket.ticketToken = barcodeText; + const info = lines[i].split(' ').filter(text => text.trim().length > 0); + res.underName.name = info[0]; + res.reservationFor.departureTime = departureTime; + res.reservationFor.departureBoatTerminal.name = ports[departureStation][2]; + res.reservationFor.departureBoatTerminal.geo.latitude = ports[departureStation][0]; + res.reservationFor.departureBoatTerminal.geo.longitude = ports[departureStation][1]; + res.reservationFor.departureBoatTerminal.address.postalCode = ports[departureStation][3]; + res.reservationFor.departureBoatTerminal.address.addressLocality = ports[departureStation][4]; + + res.reservationFor.arrivalBoatTerminal.name = ports[arrivalStation][2]; + res.reservationFor.arrivalBoatTerminal.geo.latitude = ports[arrivalStation][0]; + res.reservationFor.arrivalBoatTerminal.geo.longitude = ports[arrivalStation][1]; + res.reservationFor.arrivalBoatTerminal.address.postalCode = ports[arrivalStation][3]; + res.reservationFor.arrivalBoatTerminal.address.addressLocality = ports[arrivalStation][4]; + + ExtractorEngine.extractPrice(info[5].replace(' ', ''), res); + i += 4; + reservations.push(res); + } + } + } + return reservations; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-25.12.2/src/lib/scripts/frs.json new/kitinerary-25.12.3/src/lib/scripts/frs.json --- old/kitinerary-25.12.2/src/lib/scripts/frs.json 1970-01-01 01:00:00.000000000 +0100 +++ new/kitinerary-25.12.3/src/lib/scripts/frs.json 2026-03-02 18:03:50.000000000 +0100 @@ -0,0 +1,13 @@ +{ + "filter": [ + { + "field": "From", + "match": "@frs.es", + "mimeType": "message/rfc822", + "scope": "Ancestors" + } + ], + "function": "extractPdf", + "mimeType": "application/pdf", + "script": "frs.js" +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-25.12.2/src/lib/scripts/getyourguide.js new/kitinerary-25.12.3/src/lib/scripts/getyourguide.js --- old/kitinerary-25.12.2/src/lib/scripts/getyourguide.js 1970-01-01 01:00:00.000000000 +0100 +++ new/kitinerary-25.12.3/src/lib/scripts/getyourguide.js 2026-03-02 18:03:50.000000000 +0100 @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: 2026 Carl Schwan <[email protected]> +// SPDX-License-Identifier: LGPL-2.0-or-later + +function extractPdf(pdf, node) { + let reservations = []; + let i = 0; + for (let page of pdf.pages) { + const content = page.text; + const lines = content.split('\n'); + + const bookingNumber = content.match('Booking reference: (.*)'); + if (!bookingNumber) { + break; + } + + let res = JsonLd.newEventReservation(); + res.reservationNumber = bookingNumber[1]; + res.reservationFor.name = lines[2] + ' ' + lines[3]; + for (let i = 0, count = lines.length; i < count; i++) { + const line = lines[i].trim(); + if (line.startsWith('')) { + let match = line.match(", (.*) at ([0-9]{1,2}:[0-9]{2} ?(AM|PM)?)"); + res.reservationFor.startDate = JsonLd.toDateTime(match[1] + ' ' + match[2], ["MMMM dd, yyyy hh:mm AP", "MMMM dd, yyyy h:mm AP"], ['en']); + } + } + + const images = node.findChildNodes({ mimeType: "internal/qimage", scope: "Descendants" }); + const image = images[i * 2 + 1]; + if (image.childNodes && image.childNodes.length === 1 && image.childNodes[0].mimeType === "text/plain") { + const barcode = image.childNodes[0].content; + if (barcode) { + res.reservedTicket.ticketToken = "qrCode:" + barcode; + } + } + reservations.push(res); + i++; + } + return reservations; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-25.12.2/src/lib/scripts/getyourguide.json new/kitinerary-25.12.3/src/lib/scripts/getyourguide.json --- old/kitinerary-25.12.2/src/lib/scripts/getyourguide.json 1970-01-01 01:00:00.000000000 +0100 +++ new/kitinerary-25.12.3/src/lib/scripts/getyourguide.json 2026-03-02 18:03:50.000000000 +0100 @@ -0,0 +1,14 @@ +{ + "filter": [ + { + "field": "title", + "match": "^Prepaid Voucher", + "mimeType": "application/pdf", + "scope": "Current" + } + ], + "function": "extractPdf", + "mimeType": "application/pdf", + "script": "getyourguide.js" +} + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-25.12.2/src/lib/scripts/hostelworld.js new/kitinerary-25.12.3/src/lib/scripts/hostelworld.js --- old/kitinerary-25.12.2/src/lib/scripts/hostelworld.js 2026-02-02 17:53:57.000000000 +0100 +++ new/kitinerary-25.12.3/src/lib/scripts/hostelworld.js 2026-03-02 18:03:50.000000000 +0100 @@ -25,3 +25,58 @@ return res; } + +function parseReservationMailV2(content) { + let res = JsonLd.newLodgingReservation(); + + const lines = content.split('\n'); + let dateStart; + let dateEnd; + for (let i = 0, count = lines.length; i < count; i++) { + const line = lines[i]; + + if (line.startsWith('Booking Reference')) { + res.reservationNumber = lines[i + 1]; + + const name = lines[i + 2].split(','); + res.reservationFor.name = name[0] + + const address = lines[i + 3].split(','); + res.reservationFor.address.streetAddress = address[0]; + res.reservationFor.address.addressLocality = address[address.length - 2]; + res.reservationFor.address.addressCountry = address[address.length - 1]; + + const dates = lines[i + 4].split(',')[0].split(' - '); + + dateStart = dates[0] + dateEnd = dates[1] + } + + if (line.startsWith('Total')) { + const match = line.match("Total ([A-Z]{3}) (.*)"); + if (match) { + res.totalPrice = match[2]; + res.priceCurrency = match[1]; + } + } + + if (line.startsWith('Check-In:')) { + const match = line.match("From ([0-9]{2}:[0-9]{2})"); + if (match) { + dateStart += ' ' + match[1]; + } + } + + if (line.startsWith('Check-Out:')) { + const match = line.match("Before ([0-9]{2}:[0-9]{2})"); + if (match) { + dateEnd += ' ' + match[1]; + } + } + } + + res.checkinTime = JsonLd.toDateTime(dateStart, ["d MMM yyyy hh:mm", "d MMM yyyy"], ["en","de"]); + res.checkoutTime = JsonLd.toDateTime(dateEnd, ["d MMM yyyy hh:mm", "d MMM yyyy"], ["en","de"]); + + return res; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kitinerary-25.12.2/src/lib/scripts/hostelworld.json new/kitinerary-25.12.3/src/lib/scripts/hostelworld.json --- old/kitinerary-25.12.2/src/lib/scripts/hostelworld.json 2026-02-02 17:53:57.000000000 +0100 +++ new/kitinerary-25.12.3/src/lib/scripts/hostelworld.json 2026-03-02 18:03:50.000000000 +0100 @@ -1,13 +1,28 @@ -{ - "filter": [ - { - "field": "From", - "match": "@hostelworld.com", - "mimeType": "message/rfc822", - "scope": "Ancestors" - } - ], - "function": "parseReservationMail", - "mimeType": "text/plain", - "script": "hostelworld.js" -} +[ + { + "filter": [ + { + "field": "From", + "match": "@hostelworld.com", + "mimeType": "message/rfc822", + "scope": "Ancestors" + } + ], + "function": "parseReservationMail", + "mimeType": "text/plain", + "script": "hostelworld.js" + }, + { + "filter": [ + { + "field": "From", + "match": "@info.hostelworld.com", + "mimeType": "message/rfc822", + "scope": "Ancestors" + } + ], + "function": "parseReservationMailV2", + "mimeType": "text/plain", + "script": "hostelworld.js" + } +]
