Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package kitinerary for openSUSE:Factory 
checked in at 2021-09-04 22:33:08
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kitinerary (Old)
 and      /work/SRC/openSUSE:Factory/.kitinerary.new.1899 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "kitinerary"

Sat Sep  4 22:33:08 2021 rev:39 rq:915917 version:21.08.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/kitinerary/kitinerary.changes    2021-08-16 
10:07:34.015383551 +0200
+++ /work/SRC/openSUSE:Factory/.kitinerary.new.1899/kitinerary.changes  
2021-09-04 22:34:55.648117517 +0200
@@ -1,0 +2,19 @@
+Wed Sep  1 12:38:31 UTC 2021 - Christophe Giboudeaux <[email protected]>
+
+- Update to 21.08.1
+  * New bugfix release
+  * For more details please see:
+  * https://kde.org/announcements/gear/21.08.1
+- Changes since 21.08.0:
+  * Add Airdo confirmation mail extractor script
+  * Extract SNCF Ouigo confirmation emails (kde#441361)
+  * Extract Ryanair PDF boarding passes
+  * Actually add the MAV extractor
+  * Add basic MAV (Hungarian state railway) domestic ticket extractor
+  * Add an alternative way of decoding RCT2 reservation data
+  * Reproduce whitespaces a bit more correctly when layouting U_TLAY text
+  * Let RCT2 type detection ignore whitespaces and support Hungarian IRTs
+  * Add a watchdog timer to interrupt long running extractor scripts
+  * Add Regionado pkpass extractor script
+
+-------------------------------------------------------------------

Old:
----
  kitinerary-21.08.0.tar.xz
  kitinerary-21.08.0.tar.xz.sig

New:
----
  kitinerary-21.08.1.tar.xz
  kitinerary-21.08.1.tar.xz.sig

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ kitinerary.spec ++++++
--- /var/tmp/diff_new_pack.anHXVg/_old  2021-09-04 22:34:57.420119866 +0200
+++ /var/tmp/diff_new_pack.anHXVg/_new  2021-09-04 22:34:57.424119871 +0200
@@ -18,7 +18,7 @@
 
 %bcond_without lang
 Name:           kitinerary
-Version:        21.08.0
+Version:        21.08.1
 Release:        0
 Summary:        Data model and extraction system for travel reservations
 License:        LGPL-2.1-or-later


++++++ kitinerary-21.08.0.tar.xz -> kitinerary-21.08.1.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitinerary-21.08.0/CMakeLists.txt 
new/kitinerary-21.08.1/CMakeLists.txt
--- old/kitinerary-21.08.0/CMakeLists.txt       2021-08-05 00:09:33.000000000 
+0200
+++ new/kitinerary-21.08.1/CMakeLists.txt       2021-08-30 18:21:55.000000000 
+0200
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 
 cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
-set(PIM_VERSION "5.18.0")
+set(PIM_VERSION "5.18.1")
 project(KItinerary VERSION ${PIM_VERSION})
 
 set(CMAKE_CXX_STANDARD 17)
@@ -37,8 +37,8 @@
     find_package(SharedMimeInfo 1.3 REQUIRED)
 endif()
 
-set(KMIME_VERSION "5.18.0")
-set(PIM_PKPASS "5.18.0")
+set(KMIME_VERSION "5.18.1")
+set(PIM_PKPASS "5.18.1")
 
 find_package(KF5Mime ${KMIME_VERSION} CONFIG REQUIRED)
 find_package(KF5CalendarCore ${KF5_MIN_VERSION} CONFIG)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitinerary-21.08.0/autotests/buggy.js 
new/kitinerary-21.08.1/autotests/buggy.js
--- old/kitinerary-21.08.0/autotests/buggy.js   1970-01-01 01:00:00.000000000 
+0100
+++ new/kitinerary-21.08.1/autotests/buggy.js   2021-08-30 18:21:55.000000000 
+0200
@@ -0,0 +1,10 @@
+/*
+    SPDX-FileCopyrightText: 2021 Volker Krause <[email protected]>
+
+    SPDX-License-Identifier: LGPL-2.0-or-later
+*/
+
+function infiniteLoop()
+{
+    while (true) {}
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kitinerary-21.08.0/autotests/extractorscriptenginetest.cpp 
new/kitinerary-21.08.1/autotests/extractorscriptenginetest.cpp
--- old/kitinerary-21.08.0/autotests/extractorscriptenginetest.cpp      
2021-08-05 00:09:33.000000000 +0200
+++ new/kitinerary-21.08.1/autotests/extractorscriptenginetest.cpp      
2021-08-30 18:21:55.000000000 +0200
@@ -70,7 +70,6 @@
 
     void testArguments()
     {
-
         QFETCH(QString, inputFile);
         QFETCH(QString, refFile);
 
@@ -96,6 +95,22 @@
         }
         QCOMPARE(result, refResult);
     }
+
+    void testInfiniteLoop()
+    {
+        QFile in(s(SOURCE_DIR "/scriptenginedata/plain-text.txt"));
+        QVERIFY(in.open(QFile::ReadOnly));
+
+        ExtractorEngine engine;
+        auto root = engine.documentNodeFactory()->createNode(in.readAll());
+        QVERIFY(!root.isNull());
+        expandRecursive(root, &engine);
+
+        ScriptExtractor extractor;
+        extractor.setScriptFileName(s(":/buggy.js"));
+        extractor.setScriptFunction(s("infiniteLoop"));
+        const auto result = extractor.extract(root, &engine).jsonLdResult();
+    }
 };
 
 QTEST_GUILESS_MAIN(ExtractorScriptEngineTest)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kitinerary-21.08.0/autotests/extractorscriptenginetest.qrc 
new/kitinerary-21.08.1/autotests/extractorscriptenginetest.qrc
--- old/kitinerary-21.08.0/autotests/extractorscriptenginetest.qrc      
2021-08-05 00:09:33.000000000 +0200
+++ new/kitinerary-21.08.1/autotests/extractorscriptenginetest.qrc      
2021-08-30 18:21:55.000000000 +0200
@@ -4,6 +4,7 @@
 -->
 <RCC>
     <qresource prefix="/">
+        <file>buggy.js</file>
         <file>reflector.js</file>
     </qresource>
 </RCC>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitinerary-21.08.0/autotests/rct2/valid/irt-mav.json 
new/kitinerary-21.08.1/autotests/rct2/valid/irt-mav.json
--- old/kitinerary-21.08.0/autotests/rct2/valid/irt-mav.json    1970-01-01 
01:00:00.000000000 +0100
+++ new/kitinerary-21.08.1/autotests/rct2/valid/irt-mav.json    2021-08-30 
18:21:55.000000000 +0200
@@ -0,0 +1,16 @@
+[
+    {
+        "@context": "http://schema.org";,
+        "@type": "Rct2Ticket",
+        "coachNumber": "23",
+        "outboundArrivalStation": "MUENCHEN HBF",
+        "outboundArrivalTime": "2018-08-19T14:32:00",
+        "outboundClass": "2",
+        "outboundDepartureStation": "BUDAPEST-KELETI",
+        "outboundDepartureTime": "2018-08-19T07:40:00",
+        "passengerName": "J??hn ?? Doe",
+        "seatNumber": "101, 102",
+        "trainNumber": "RJX 42",
+        "type": "http://schema.org/TransportReservation";
+    }
+]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitinerary-21.08.0/autotests/rct2/valid/irt-mav.rct2 
new/kitinerary-21.08.1/autotests/rct2/valid/irt-mav.rct2
--- old/kitinerary-21.08.0/autotests/rct2/valid/irt-mav.rct2    1970-01-01 
01:00:00.000000000 +0100
+++ new/kitinerary-21.08.1/autotests/rct2/valid/irt-mav.rct2    2021-08-30 
18:21:55.000000000 +0200
@@ -0,0 +1 @@
+U_TLAY010831RCT200410001011400015M??V-START 
Zrt.0018011800018MENETJEGY+HELYJEGY0052011000012J??hn ?? 
Doe0118012300023FAHRSCHEIN+RESERVIERUNG0152010200002020155011400016??L??HELY/SITZPL0201010800008CIV
 
1155060101050000519.08060701050000507:400613011500015BUDAPEST-KELETI0634011200012MUENCHEN
 
HBF065201050000519.08065801050000514:32066801010000120703010100001*0709010100001*0713010100001*0734010100001*0754010100001*0760010100001*0768010100001*0801010300003ZUG0805010200002420811010300003RJX0815010500005WAGEN0821010200002230825010500005PLATZ0831010800008101,
 1021201011500015START Europa 
DE1237010800008CARRIERS1301010200002011304011900020FELN??TT/ERWACHSENER1401010200002011404011900020FELN??TT/ERWACHSENER13370114000141155
 1181 
10801352010200003??R1358010300003HUF1362010900009*12345.001452010500005PREIS1458010300003EUR1462010900009***123.00
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitinerary-21.08.0/po/fi/kitinerary.po 
new/kitinerary-21.08.1/po/fi/kitinerary.po
--- old/kitinerary-21.08.0/po/fi/kitinerary.po  2021-08-06 02:25:14.000000000 
+0200
+++ new/kitinerary-21.08.1/po/fi/kitinerary.po  2021-08-31 02:39:27.000000000 
+0200
@@ -1,10 +1,10 @@
-# Tommi Nieminen <[email protected]>, 2017, 2018, 2019, 2020.
+# Tommi Nieminen <[email protected]>, 2017, 2018, 2019, 2020, 2021.
 msgid ""
 msgstr ""
 "Project-Id-Version: desktop files\n"
 "Report-Msgid-Bugs-To: https://bugs.kde.org\n";
 "POT-Creation-Date: 2021-05-24 00:17+0000\n"
-"PO-Revision-Date: 2020-07-29 13:51+0300\n"
+"PO-Revision-Date: 2021-08-18 19:08+0300\n"
 "Last-Translator: Tommi Nieminen <[email protected]>\n"
 "Language-Team: Finnish <[email protected]>\n"
 "Language: fi\n"
@@ -41,8 +41,7 @@
 msgstr "Koneeseennousuaika: %1"
 
 #: calendarhandler.cpp:250
-#, fuzzy, kde-format
-#| msgid "Departure gate: %1"
+#, kde-format
 msgctxt "flight departure gate"
 msgid "Departure gate: %1"
 msgstr "L??ht??portti: %1"
@@ -130,10 +129,9 @@
 msgstr "Ravintolavaraus: %1"
 
 #: calendarhandler.cpp:464
-#, fuzzy, kde-format
-#| msgid "Number Of People: %1"
+#, kde-format
 msgid "Number of people: %1"
-msgstr "Henkil??iden m????r??: %1"
+msgstr "Henkil??m????r??: %1"
 
 #: calendarhandler.cpp:471 calendarhandler.cpp:503
 #, kde-format
@@ -141,8 +139,7 @@
 msgstr "Nimell??: %1"
 
 #: calendarhandler.cpp:481
-#, fuzzy, kde-format
-#| msgid "Rental Car reservation: %1"
+#, kde-format
 msgid "Rental car reservation: %1"
 msgstr "Autonvuokrausvaraus: %1"
 
@@ -152,6 +149,8 @@
 "Pickup location: %1\n"
 "%2\n"
 msgstr ""
+"Noutopaikka: %1\n"
+"%2\n"
 
 #: calendarhandler.cpp:496
 #, kde-format
@@ -159,13 +158,11 @@
 "Dropoff location: %1\n"
 "%2\n"
 msgstr ""
+"J??tt??paikka: %1\n"
+"%2\n"
 
 #: calendarhandler.cpp:525
-#, fuzzy, kde-format
-#| msgid ""
-#| "Reservation reference: %1\n"
-#| "Under name: %2\n"
-#| "PickUp location: %3"
+#, kde-format
 msgid ""
 "Reservation reference: %1\n"
 "Under name: %2\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitinerary-21.08.0/po/zh_CN/kitinerary.po 
new/kitinerary-21.08.1/po/zh_CN/kitinerary.po
--- old/kitinerary-21.08.0/po/zh_CN/kitinerary.po       2021-08-06 
02:25:14.000000000 +0200
+++ new/kitinerary-21.08.1/po/zh_CN/kitinerary.po       2021-08-31 
02:39:27.000000000 +0200
@@ -8,7 +8,7 @@
 "Project-Id-Version: kdeorg\n"
 "Report-Msgid-Bugs-To: https://bugs.kde.org\n";
 "POT-Creation-Date: 2021-05-24 00:17+0000\n"
-"PO-Revision-Date: 2021-07-26 13:49\n"
+"PO-Revision-Date: 2021-08-30 11:45\n"
 "Last-Translator: \n"
 "Language-Team: Chinese Simplified\n"
 "Language: zh_CN\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kitinerary-21.08.0/src/cli/org.kde.kitinerary-extractor.appdata.xml 
new/kitinerary-21.08.1/src/cli/org.kde.kitinerary-extractor.appdata.xml
--- old/kitinerary-21.08.0/src/cli/org.kde.kitinerary-extractor.appdata.xml     
2021-08-05 00:09:33.000000000 +0200
+++ new/kitinerary-21.08.1/src/cli/org.kde.kitinerary-extractor.appdata.xml     
2021-08-30 18:21:55.000000000 +0200
@@ -101,9 +101,9 @@
     <binary>kitinerary-extractor</binary>
   </provides>
   <releases>
+    <release version="5.18.1" date="2021-09-02"/>
     <release version="5.18.0" date="2021-08-12"/>
     <release version="5.17.3" date="2021-07-08"/>
     <release version="5.17.2" date="2021-06-10"/>
-    <release version="5.17.1" date="2021-05-13"/>
   </releases>
 </component>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kitinerary-21.08.0/src/lib/engine/extractorscriptengine.cpp 
new/kitinerary-21.08.1/src/lib/engine/extractorscriptengine.cpp
--- old/kitinerary-21.08.0/src/lib/engine/extractorscriptengine.cpp     
2021-08-05 00:09:33.000000000 +0200
+++ new/kitinerary-21.08.1/src/lib/engine/extractorscriptengine.cpp     
2021-08-30 18:21:55.000000000 +0200
@@ -18,20 +18,33 @@
 #include <QJSEngine>
 #include <QJSValueIterator>
 #include <QScopeGuard>
+#include <QThread>
+#include <QTimer>
 
 using namespace KItinerary;
 
 namespace KItinerary {
 class ExtractorScriptEnginePrivate {
 public:
+    ~ExtractorScriptEnginePrivate();
     bool loadScript(const QString &fileName);
 
     JsApi::Barcode *m_barcodeApi = nullptr;
     JsApi::JsonLd *m_jsonLdApi = nullptr;
     QJSEngine m_engine;
+
+    QThread m_watchdogThread;
+    QTimer *m_watchdogTimer = nullptr;
 };
 }
 
+ExtractorScriptEnginePrivate::~ExtractorScriptEnginePrivate()
+{
+    m_watchdogTimer->deleteLater();
+    m_watchdogThread.quit();
+    m_watchdogThread.wait();
+}
+
 ExtractorScriptEngine::ExtractorScriptEngine() = default;
 ExtractorScriptEngine::~ExtractorScriptEngine() = default;
 
@@ -47,6 +60,13 @@
     d->m_engine.globalObject().setProperty(QStringLiteral("JsonLd"), 
d->m_engine.newQObject(d->m_jsonLdApi));
     d->m_barcodeApi = new JsApi::Barcode;
     d->m_engine.globalObject().setProperty(QStringLiteral("Barcode"), 
d->m_engine.newQObject(d->m_barcodeApi));
+
+    d->m_watchdogThread.start();
+    d->m_watchdogTimer = new QTimer;
+    d->m_watchdogTimer->setInterval(std::chrono::seconds(1));
+    d->m_watchdogTimer->setSingleShot(true);
+    d->m_watchdogTimer->moveToThread(&d->m_watchdogThread);
+    QObject::connect(d->m_watchdogTimer, &QTimer::timeout, &d->m_engine, 
[this]() { d->m_engine.setInterrupted(true); }, Qt::DirectConnection);
 }
 
 void ExtractorScriptEngine::setBarcodeDecoder(BarcodeDecoder *barcodeDecoder)
@@ -55,10 +75,20 @@
     d->m_barcodeApi->setDecoder(barcodeDecoder);
 }
 
-static void printScriptError(const QJSValue &result)
+// produce the same output as the JS engine error result fileName property 
would have
+static QString fileNameToUrl(const QString &fileName)
 {
+    if (fileName.startsWith(QLatin1Char(':'))) {
+        return QLatin1String("qrc:/") + QStringView(fileName).mid(1);
+    }
+    return QUrl::fromLocalFile(fileName).toString();
+}
+
+static void printScriptError(const QJSValue &result, const QString 
&fileNameFallback)
+{
+    const auto fileName = result.property(QStringLiteral("fileName"));
     // don't change the formatting without adjusting KItinerary Workbench too!
-    qCWarning(Log).noquote().nospace() << "JS ERROR: [" << 
result.property(QStringLiteral("fileName")).toString()
+    qCWarning(Log).noquote().nospace() << "JS ERROR: [" << 
(fileName.isString() ? fileName.toString() : fileNameToUrl(fileNameFallback))
         << "]:" << result.property(QStringLiteral("lineNumber")).toInt() << ": 
" << result.toString();
 }
 
@@ -78,7 +108,7 @@
 
     auto result = m_engine.evaluate(QString::fromUtf8(f.readAll()), 
f.fileName());
     if (result.isError()) {
-        printScriptError(result);
+        printScriptError(result, fileName);
         return false;
     }
 
@@ -89,6 +119,13 @@
 {
     const_cast<ExtractorScriptEngine*>(this)->ensureInitialized();
 
+    // watchdog setup
+    QMetaObject::invokeMethod(d->m_watchdogTimer, qOverload<>(&QTimer::start));
+    const auto watchdogStop = qScopeGuard([this]() {
+        QMetaObject::invokeMethod(d->m_watchdogTimer, 
qOverload<>(&QTimer::stop));
+    });
+    d->m_engine.setInterrupted(false);
+
     if (!d->loadScript(extractor->scriptFileName())) {
         return {};
     }
@@ -117,7 +154,7 @@
 
     const auto result = mainFunc.call(args);
     if (result.isError()) {
-        printScriptError(result);
+        printScriptError(result, extractor->scriptFileName());
         return {};
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitinerary-21.08.0/src/lib/scripts/airdo.js 
new/kitinerary-21.08.1/src/lib/scripts/airdo.js
--- old/kitinerary-21.08.0/src/lib/scripts/airdo.js     1970-01-01 
01:00:00.000000000 +0100
+++ new/kitinerary-21.08.1/src/lib/scripts/airdo.js     2021-08-30 
18:21:55.000000000 +0200
@@ -0,0 +1,44 @@
+/*
+   SPDX-FileCopyrightText: 2021 Volker Krause <[email protected]>
+   SPDX-License-Identifier: LGPL-2.0-or-later
+*/
+
+function parseConfirmation(text, node) {
+    var flightRes = new Array();
+    var idx = 0;
+    while (true) {
+        const flight = text.substr(idx).match(/\[\d+\]\n(\d{1,2} \w+)\(.*\) 
([A-Z0-9]+) (\d+)\n(.*) - (.*)\n.*?(\d{1,2}:\d{2})-(\d{1,2}:\d{2})/);
+        if (!flight) {
+            break;
+        }
+        idx += flight.index + flight[0].length;
+
+        var f = JsonLd.newFlightReservation();
+        f.reservationFor.departureAirport.name = flight[4];
+        f.reservationFor.arrivalAirport.name = flight[5];
+        f.reservationFor.departureTime = JsonLd.toDateTime(flight[1] + 
flight[6], "d MMMMhh:mm", "en");
+        f.reservationFor.arrivalTime = JsonLd.toDateTime(flight[1] + 
flight[7], "d MMMMhh:mm", "en");
+        f.reservationFor.airline.iataCode = flight[2];
+        f.reservationFor.flightNumber = flight[3];
+        flightRes.push(f);
+    }
+
+    const seats = text.match(/\[Seat Number\]([\s\S]+?)\n\[/);
+    if (!seats) {
+        return flightRes;
+    }
+    var reservations = new Array();
+    for (seat of seats[1].split(/\n/)) {
+        const passenger = seat.match(/(.*) (\d+[A-Z])[\n\[]/);
+        if (!passenger) {
+            continue;
+        }
+        for (flight of flightRes) {
+            var res = JsonLd.clone(flight);
+            res.underName.name = passenger[1];
+            res.airplaneSeat = passenger[2];
+            reservations.push(res);
+        }
+    }
+    return reservations;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitinerary-21.08.0/src/lib/scripts/airdo.json 
new/kitinerary-21.08.1/src/lib/scripts/airdo.json
--- old/kitinerary-21.08.0/src/lib/scripts/airdo.json   1970-01-01 
01:00:00.000000000 +0100
+++ new/kitinerary-21.08.1/src/lib/scripts/airdo.json   2021-08-30 
18:21:55.000000000 +0200
@@ -0,0 +1,13 @@
+{
+    "filter": [
+        {
+            "field": "From",
+            "match": "@airdo.co.jp",
+            "mimeType": "message/rfc822",
+            "scope": "Parent"
+        }
+    ],
+    "function": "parseConfirmation",
+    "mimeType": "text/plain",
+    "script": "airdo.js"
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitinerary-21.08.0/src/lib/scripts/extractors.qrc 
new/kitinerary-21.08.1/src/lib/scripts/extractors.qrc
--- old/kitinerary-21.08.0/src/lib/scripts/extractors.qrc       2021-08-05 
00:09:33.000000000 +0200
+++ new/kitinerary-21.08.1/src/lib/scripts/extractors.qrc       2021-08-30 
18:21:55.000000000 +0200
@@ -16,6 +16,8 @@
         <file>airbaltic.js</file>
         <file>aircoach-ie.json</file>
         <file>aircoach-ie.js</file>
+        <file>airdo.json</file>
+        <file>airdo.js</file>
         <file>amadeus.json</file>
         <file>amadeus.js</file>
         <file>americanairlines.json</file>
@@ -78,6 +80,8 @@
         <file>korail.js</file>
         <file>lufthansa.json</file>
         <file>lufthansa-pkpass.js</file>
+        <file>mav.json</file>
+        <file>mav.js</file>
         <file>nationalexpress.json</file>
         <file>nationalexpress.js</file>
         <file>nh-hotels.json</file>
@@ -90,8 +94,12 @@
         <file>oebb.js</file>
         <file>regiojet.json</file>
         <file>regiojet.js</file>
+        <file>regiondo.json</file>
+        <file>regiondo.js</file>
         <file>renfe.json</file>
         <file>renfe.js</file>
+        <file>ryanair.json</file>
+        <file>ryanair.js</file>
         <file>sas.json</file>
         <file>sas-boardingpass.js</file>
         <file>sas-receipt.js</file>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitinerary-21.08.0/src/lib/scripts/mav.js 
new/kitinerary-21.08.1/src/lib/scripts/mav.js
--- old/kitinerary-21.08.0/src/lib/scripts/mav.js       1970-01-01 
01:00:00.000000000 +0100
+++ new/kitinerary-21.08.1/src/lib/scripts/mav.js       2021-08-30 
18:21:55.000000000 +0200
@@ -0,0 +1,27 @@
+/*
+   SPDX-FileCopyrightText: 2021 Volker Krause <[email protected]>
+   SPDX-License-Identifier: LGPL-2.0-or-later
+*/
+
+function parseTicket(pdf, node, triggerNode) {
+    var reservations = new Array();
+    const text = pdf.pages[triggerNode.location].text;
+    var idx = 0;
+    while (true) {
+        var trip = text.substr(idx).match(/(\d{4}\.\d{2}\.\d{2})\. 
*(\d{2}:\d{2}) *(.*) *-> *(.*) *(\d{2}:\d{2}) *(.*) *(\d)\./);
+        if (!trip) {
+            break;
+        }
+        idx += trip.index + trip[0].length
+        var res = JsonLd.newTrainReservation();
+        res.reservationFor.departureStation.name = trip[3];
+        res.reservationFor.arrivalStation.name = trip[4];
+        res.reservationFor.departureTime = JsonLd.toDateTime(trip[1] + 
trip[2], "yyyy.MM.ddhh:mm", "hu");
+        res.reservationFor.arrivalTime = JsonLd.toDateTime(trip[1] + trip[5], 
"yyyy.MM.ddhh:mm", "hu");
+        res.reservationFor.trainNumber = trip[6];
+        res.reservedTicket.ticketedSeat.seatingType = trip[7];
+        res.reservedTicket.ticketToken = "pdf417bin:" + 
Barcode.toBase64(triggerNode.content);
+        reservations.push(res);
+    }
+    return reservations;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitinerary-21.08.0/src/lib/scripts/mav.json 
new/kitinerary-21.08.1/src/lib/scripts/mav.json
--- old/kitinerary-21.08.0/src/lib/scripts/mav.json     1970-01-01 
01:00:00.000000000 +0100
+++ new/kitinerary-21.08.1/src/lib/scripts/mav.json     2021-08-30 
18:21:55.000000000 +0200
@@ -0,0 +1,12 @@
+{
+    "filter": [
+        {
+            "match": "^\\x04\\x03\\x1f\\x8b",
+            "mimeType": "application/octet-stream",
+            "scope": "Descendants"
+        }
+    ],
+    "function": "parseTicket",
+    "mimeType": "application/pdf",
+    "script": "mav.js"
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitinerary-21.08.0/src/lib/scripts/regiondo.js 
new/kitinerary-21.08.1/src/lib/scripts/regiondo.js
--- old/kitinerary-21.08.0/src/lib/scripts/regiondo.js  1970-01-01 
01:00:00.000000000 +0100
+++ new/kitinerary-21.08.1/src/lib/scripts/regiondo.js  2021-08-30 
18:21:55.000000000 +0200
@@ -0,0 +1,25 @@
+/*
+   SPDX-FileCopyrightText: 2021 Volker Krause <[email protected]>
+   SPDX-License-Identifier: LGPL-2.0-or-later
+*/
+
+function parsePass(pass, node) {
+    var res = node.result[0];
+    res.reservationFor.startDate = pass.field["when"].value;
+    res.underName = JsonLd.newObject("Person");
+    res.underName.name = pass.field["buyer"].value;
+
+    var addr = pass.field["venue"].value.match(/(.*), (.*)/);
+    res.reservationFor.location.name = null;
+    res.reservationFor.location.address = JsonLd.newObject("PostalAddress");
+    res.reservationFor.location.address.addressCountry = addr[2];
+    if (addr[2] == "Deutschland") {
+        var addr2 = addr[1].match(/(.*) (\d{5} .*) ([A-Z]{2})/);
+        res.reservationFor.location.address.streetAddress = addr2[1];
+        res.reservationFor.location.address.addressLocality = addr2[2];
+        res.reservationFor.location.address.addressRegion = addr2[3];
+    } else {
+        res.reservationFor.location.address.streetAddress = addr[1];
+    }
+    return res;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitinerary-21.08.0/src/lib/scripts/regiondo.json 
new/kitinerary-21.08.1/src/lib/scripts/regiondo.json
--- old/kitinerary-21.08.0/src/lib/scripts/regiondo.json        1970-01-01 
01:00:00.000000000 +0100
+++ new/kitinerary-21.08.1/src/lib/scripts/regiondo.json        2021-08-30 
18:21:55.000000000 +0200
@@ -0,0 +1,13 @@
+{
+    "filter": [
+        {
+            "field": "passTypeIdentifier",
+            "match": "pass.de.regiondo.pass",
+            "mimeType": "application/vnd.apple.pkpass",
+            "scope": "Current"
+        }
+    ],
+    "function": "parsePass",
+    "mimeType": "application/vnd.apple.pkpass",
+    "script": "regiondo.js"
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitinerary-21.08.0/src/lib/scripts/ryanair.js 
new/kitinerary-21.08.1/src/lib/scripts/ryanair.js
--- old/kitinerary-21.08.0/src/lib/scripts/ryanair.js   1970-01-01 
01:00:00.000000000 +0100
+++ new/kitinerary-21.08.1/src/lib/scripts/ryanair.js   2021-08-30 
18:21:55.000000000 +0200
@@ -0,0 +1,20 @@
+/*
+   SPDX-FileCopyrightText: 2021 Volker Krause <[email protected]>
+   SPDX-License-Identifier: LGPL-2.0-or-later
+*/
+
+function parseBoardingPass(pdf, node, triggerNode) {
+    console.log(pdf);
+    var res = triggerNode.result[0];
+    const page = pdf.pages[triggerNode.location];
+    const timesText = page.textInRect(0.5, 0.5, 1, 1);
+    console.log(timesText);
+    const times = 
timesText.match(/\n(\d\d:\d\d)[\s\S]*?\n(\d\d:\d\d)[\s\S]*?\n(\d\d:\d\d)[\s\S]*?\n(\d\d:\d\d)[\s\S]*?\d\d:\d\d\./);
+    res.reservationFor.boardingTime = JsonLd.toDateTime(times[2], "hh:mm", 
"en");
+    res.reservationFor.departureTime = JsonLd.toDateTime(times[3], "hh:mm", 
"en");
+    res.reservationFor.arrivalTime = JsonLd.toDateTime(times[4], "hh:mm", 
"en");
+
+    res.reservationFor.departureAirport.name = page.textInRect(0.5, 0.3, 0.75, 
0.375);
+    res.reservationFor.arrivalAirport.name = page.textInRect(0.75, 0.3, 1, 
0.375);
+    return res;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitinerary-21.08.0/src/lib/scripts/ryanair.json 
new/kitinerary-21.08.1/src/lib/scripts/ryanair.json
--- old/kitinerary-21.08.0/src/lib/scripts/ryanair.json 1970-01-01 
01:00:00.000000000 +0100
+++ new/kitinerary-21.08.1/src/lib/scripts/ryanair.json 2021-08-30 
18:21:55.000000000 +0200
@@ -0,0 +1,13 @@
+{
+    "filter": [
+        {
+            "field": "operatingCarrierDesignator",
+            "match": "FR",
+            "mimeType": "internal/iata-bcbp",
+            "scope": "Descendants"
+        }
+    ],
+    "function": "parseBoardingPass",
+    "mimeType": "application/pdf",
+    "script": "ryanair.js"
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitinerary-21.08.0/src/lib/scripts/sncf.js 
new/kitinerary-21.08.1/src/lib/scripts/sncf.js
--- old/kitinerary-21.08.0/src/lib/scripts/sncf.js      2021-08-05 
00:09:33.000000000 +0200
+++ new/kitinerary-21.08.1/src/lib/scripts/sncf.js      2021-08-30 
18:21:55.000000000 +0200
@@ -266,16 +266,16 @@
     return reservations;
 }
 
-function parseOuigoEmail(html)
+function parseOuiEmail(html)
 {
     if (html.eval('//*[@data-select="travel-summary-reference"]').length > 0) {
-        return parseOuigoSummary(html);
+        return parseOuiSummary(html);
     } else {
-        return parseOuigoConfirmation(html);
+        return parseOuiConfirmation(html);
     }
 }
 
-function parseOuigoSummaryTime(htmlElem)
+function parseOuiSummaryTime(htmlElem)
 {
     var timeStr = htmlElem[0].recursiveContent;
     var time = timeStr.match(/(\d+ [^ ]+ \d+) +[^ ]+ (\d+:\d+)/);
@@ -286,7 +286,7 @@
     return JsonLd.toDateTime(time[1] + time[2].replace('h', ':'), "d 
MMMMhh:mm", "fr");
 }
 
-function parseOuigoSummary(html)
+function parseOuiSummary(html)
 {
     // TODO extract passenger names
     var res = JsonLd.newTrainReservation();
@@ -296,7 +296,7 @@
     res.reservationFor.arrivalStation.name = destinations[0].content;
     res.reservationNumber = 
html.eval('//*[@data-select="travel-summary-reference"]')[0].content;
 
-    res.reservationFor.departureTime = 
parseOuigoSummaryTime(html.eval('//*[@data-select="travel-departureDate"]'));
+    res.reservationFor.departureTime = 
parseOuiSummaryTime(html.eval('//*[@data-select="travel-departureDate"]'));
 
     var trainNum = 
html.eval('//*[@data-select="passenger-detail-outwardFares"]//*[@class="passenger-detail__equipment"]');
     if (trainNum.length == 2 || trainNum[1].content == trainNum[3].content) {
@@ -313,7 +313,7 @@
     var retour = JsonLd.newTrainReservation();
     retour.reservationFor.departureStation.name = origins[1] ? 
origins[1].content : res.reservationFor.arrivalStation.name;
     retour.reservationFor.arrivalStation.name = destinations[1] ? 
destinations[1].content : res.reservationFor.departureStation.name;
-    retour.reservationFor.departureTime = parseOuigoSummaryTime(retourTime);
+    retour.reservationFor.departureTime = parseOuiSummaryTime(retourTime);
     trainNum = 
html.eval('//*[@data-select="passenger-detail-inwardFares"]//*[@class="passenger-detail__equipment"]');
     if (trainNum.length == 2 || trainNum[1].content == trainNum[3].content) {
         retour.reservationFor.trainNumber = trainNum[0].content + " " + 
trainNum[1].content;
@@ -322,7 +322,7 @@
     return [res, retour];
 }
 
-function parseOuigoConfirmation(html)
+function parseOuiConfirmation(html)
 {
     var reservations = new Array();
 
@@ -433,3 +433,35 @@
     }
     return reservations;
 }
+
+function parseOuigoConfirmation(html) {
+    var reservations = new Array();
+    const refNum = html.eval('//strong')[1].content;
+    const tabs = html.eval('//table//table//table[@class = "rsz_320"]');
+    for (const tab of tabs) {
+        const text = tab.recursiveContent;
+        if (!text.match(/TRAJET/)) {
+            continue;
+        }
+
+        var idx = 0;
+        while (true) {
+            const date = text.substr(idx).match(/\w+ (\d{1,2} \w+ \d{4})/);
+            if (!date) {
+                break;
+            }
+            const leg = 
text.substr(idx).match(/(\d{2}h\d{2})\s+(.*?)\n\s+(\d{2}h\d{2})\s+(.*?)\n\s+TRAIN
 N?? *(.*)\n/);
+            var res = JsonLd.newTrainReservation();
+            res.reservationNumber = refNum;
+            res.reservationFor.departureTime = JsonLd.toDateTime(date[1] + 
leg[1], "d MMMM yyyyhh'h'mm", "fr");
+            res.reservationFor.departureStation.name = leg[2];
+            res.reservationFor.arrivalStation.name = leg[4];
+            res.reservationFor.arrivalTime = JsonLd.toDateTime(date[1] + 
leg[3],  "d MMMM yyyyhh'h'mm", "fr");
+            res.reservationFor.trainNumber = leg[5];
+            reservations.push(res);
+
+            idx += leg[0].length + leg.index;
+        }
+    }
+    return reservations;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitinerary-21.08.0/src/lib/scripts/sncf.json 
new/kitinerary-21.08.1/src/lib/scripts/sncf.json
--- old/kitinerary-21.08.0/src/lib/scripts/sncf.json    2021-08-05 
00:09:33.000000000 +0200
+++ new/kitinerary-21.08.1/src/lib/scripts/sncf.json    2021-08-30 
18:21:55.000000000 +0200
@@ -63,7 +63,7 @@
                 "scope": "Ancestors"
             }
         ],
-        "function": "parseOuigoEmail",
+        "function": "parseOuiEmail",
         "mimeType": "text/html",
         "script": "sncf.js"
     },
@@ -98,5 +98,18 @@
         "function": "parseTerConfirmation",
         "mimeType": "text/html",
         "script": "sncf.js"
+    },
+    {
+        "filter": [
+            {
+                "field": "From",
+                "match": "[email protected]",
+                "mimeType": "message/rfc822",
+                "scope": "Ancestors"
+            }
+        ],
+        "function": "parseOuigoConfirmation",
+        "mimeType": "text/html",
+        "script": "sncf.js"
     }
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitinerary-21.08.0/src/lib/uic9183/rct2ticket.cpp 
new/kitinerary-21.08.1/src/lib/uic9183/rct2ticket.cpp
--- old/kitinerary-21.08.0/src/lib/uic9183/rct2ticket.cpp       2021-08-05 
00:09:33.000000000 +0200
+++ new/kitinerary-21.08.1/src/lib/uic9183/rct2ticket.cpp       2021-08-30 
18:21:55.000000000 +0200
@@ -10,6 +10,7 @@
 
 #include <QDateTime>
 #include <QDebug>
+#include <QRegularExpression>
 
 #include <cstring>
 
@@ -22,6 +23,7 @@
 public:
     QDate firstDayOfValidity() const;
     QDateTime parseTime(const QString &dateStr, const QString &timeStr) const;
+    QString reservationPatternCapture(QStringView name) const;
 
     Uic9183TicketLayout layout;
     QDateTime contextDt;
@@ -67,6 +69,24 @@
     return QDateTime({year, d.month(), d.day()}, t);
 }
 
+static constexpr const char* res_patterns[] = {
+    "ZUG +(?P<train_number>\\d+) +(?P<train_category>[A-Z][A-Z0-9]+) +WAGEN 
+(?P<coach>\\d+) +PLATZ +(?P<seat>\\d[\\d, ]+)"
+};
+
+QString Rct2TicketPrivate::reservationPatternCapture(QStringView name) const
+{
+    const auto text = layout.text(8, 0, 72, 1);
+    for (const auto *pattern : res_patterns) {
+        QRegularExpression re{QLatin1String(pattern), 
QRegularExpression::CaseInsensitiveOption};
+        Q_ASSERT(re.isValid());
+        const auto match = re.match(text);
+        if (match.hasMatch()) {
+            return match.captured(name);
+        }
+    }
+    return {};
+}
+
 
 // 6x "U_TLAY"
 // 2x version (always "01")
@@ -104,12 +124,13 @@
     return d->firstDayOfValidity();
 }
 
-static const struct {
+static constexpr const struct {
     const char *name; // case folded
     Rct2Ticket::Type type;
 } rct2_ticket_type_map[] = {
-    { "ticket + reservation", Rct2Ticket::TransportReservation },
-    { "fahrschein + reservierung", Rct2Ticket::TransportReservation },
+    { "ticket+reservation", Rct2Ticket::TransportReservation },
+    { "fahrschein+reservierung", Rct2Ticket::TransportReservation },
+    { "menetjegy+helyjegy", Rct2Ticket::TransportReservation },
     { "upgrade", Rct2Ticket::Upgrade },
     { "aufpreis", Rct2Ticket::Upgrade },
     { "ticket", Rct2Ticket::Transport },
@@ -125,8 +146,8 @@
     // in theory: columns 15 - 18 blank, columns 19 - 51 ticket type (1-based 
indices!)
     // however, some providers overrun and also use the blank columns, so 
consider those too
     // if they are really empty, we trim them anyway.
-    const auto typeName1 = d->layout.text(0, 14, 38, 
1).trimmed().toCaseFolded();
-    const auto typeName2 = d->layout.text(1, 14, 38, 
1).trimmed().toCaseFolded(); // used for alternative language type name
+    const auto typeName1 = d->layout.text(0, 14, 38, 
1).trimmed().remove(QLatin1Char(' ')).toCaseFolded();
+    const auto typeName2 = d->layout.text(1, 14, 38, 
1).trimmed().remove(QLatin1Char(' ')).toCaseFolded(); // used for alternative 
language type name
 
     // prefer exact matches
     for (auto it = std::begin(rct2_ticket_type_map); it != 
std::end(rct2_ticket_type_map); ++it) {
@@ -150,12 +171,12 @@
 
 QDateTime Rct2Ticket::outboundDepartureTime() const
 {
-    return d->parseTime(d->layout.text(6, 1, 5, 1), d->layout.text(6, 7, 5, 
1));
+    return d->parseTime(d->layout.text(6, 1, 5, 1).trimmed(), 
d->layout.text(6, 7, 5, 1).trimmed());
 }
 
 QDateTime Rct2Ticket::outboundArrivalTime() const
 {
-    return d->parseTime(d->layout.text(6, 52, 5, 1), d->layout.text(6, 58, 5, 
1));
+    return d->parseTime(d->layout.text(6, 52, 5, 1).trimmed(), 
d->layout.text(6, 58, 5, 1).trimmed());
 }
 
 QString Rct2Ticket::outboundDepartureStation() const
@@ -185,8 +206,13 @@
 {
     const auto t = type();
     if (t == Reservation || t == TransportReservation || t == Upgrade) {
+        auto num = d->reservationPatternCapture(u"train_number");
+        if (!num.isEmpty()) {
+            return d->reservationPatternCapture(u"train_category") + 
QLatin1Char(' ') + num;
+        }
+
         const auto cat = d->layout.text(8, 13, 3, 1).trimmed();
-        auto num = d->layout.text(8, 7, 5, 1).trimmed();
+        num = d->layout.text(8, 7, 5, 1).trimmed();
 
         // check for train number bleeding into our left neighbour field 
(happens e.g. on ??BB IRT/RES tickets)
         if (num.isEmpty() || num.at(0).isDigit()) {
@@ -213,7 +239,8 @@
 {
     const auto t = type();
     if (t == Reservation || t == TransportReservation) {
-        return d->layout.text(8, 26, 3, 1).trimmed();
+        const auto coach = d->reservationPatternCapture(u"coach");
+        return coach.isEmpty() ? d->layout.text(8, 26, 3, 1).trimmed() : coach;
     }
     return {};
 }
@@ -222,6 +249,11 @@
 {
     const auto t = type();
     if (t == Reservation || t == TransportReservation) {
+        const auto seat = d->reservationPatternCapture(u"seat");
+        if (!seat.isEmpty()) {
+            return seat;
+        }
+
         const auto row8 = d->layout.text(8, 48, 23, 1).trimmed();
         if (!row8.isEmpty()) {
             return row8;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kitinerary-21.08.0/src/lib/uic9183/uic9183ticketlayout.cpp 
new/kitinerary-21.08.1/src/lib/uic9183/uic9183ticketlayout.cpp
--- old/kitinerary-21.08.0/src/lib/uic9183/uic9183ticketlayout.cpp      
2021-08-05 00:09:33.000000000 +0200
+++ new/kitinerary-21.08.1/src/lib/uic9183/uic9183ticketlayout.cpp      
2021-08-30 18:21:55.000000000 +0200
@@ -178,7 +178,8 @@
             if (offset >= 0) {
                 s[f.row() + i - row] += lines.at(i).mid(offset).left(width);
             } else {
-                s[f.row() + i - row] += lines.at(i); // TODO left padding by 
offset, truncate by width + offset
+                s[f.row() + i - row] += QString(-offset, QLatin1Char(' '));
+                s[f.row() + i - row] += lines.at(i); // TODO truncate by width 
+ offset
             }
         }
     }

Reply via email to