diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,6 +91,7 @@ set(IMPORTWIZARD_LIB_VERSION "5.7.80") set(MAILIMPORTER_LIB_VERSION "5.7.80") set(KPIMPKPASS_LIB_VERSION "5.8.40") +set(KPIMITINERARY_LIB_VERSION "5.8.40") find_package(KF5CalendarUtils ${CALENDAR_UTILS_VERSION} CONFIG REQUIRED) find_package(KF5WebEngineViewer ${MESSAGELIB_LIB_VERSION} CONFIG REQUIRED) @@ -122,6 +123,7 @@ find_package(KPimImportWizard ${IMPORTWIZARD_LIB_VERSION} CONFIG) find_package(KF5MailImporterAkonadi ${MAILIMPORTER_LIB_VERSION} CONFIG REQUIRED) find_package(KPimPkPass ${KPIMPKPASS_LIB_VERSION} CONFIG REQUIRED) +find_package(KPimItinerary ${KPIMITINERARY_LIB_VERSION} CONFIG REQUIRED) add_definitions(-DQT_NO_CAST_FROM_ASCII) add_definitions(-DQT_NO_CAST_TO_ASCII) add_definitions(-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT) @@ -136,8 +138,6 @@ # Extra package find_package(Gpgmepp 1.8.0 CONFIG) set_package_properties(Gpgmepp PROPERTIES DESCRIPTION "GpgME library" URL "http://www.gnupg.org" TYPE REQUIRED) -find_package(Poppler COMPONENTS Qt5) -set_package_properties("Poppler" PROPERTIES TYPE OPTIONAL PURPOSE "Support for PDF booking confirmations in the semantic extraction plugin.") if(KDEPIMADDONS_BUILD_EXAMPLES) add_subdirectory(examples) diff --git a/plugins/messageviewer/bodypartformatter/autotests/CMakeLists.txt b/plugins/messageviewer/bodypartformatter/autotests/CMakeLists.txt --- a/plugins/messageviewer/bodypartformatter/autotests/CMakeLists.txt +++ b/plugins/messageviewer/bodypartformatter/autotests/CMakeLists.txt @@ -46,30 +46,3 @@ endmacro () add_diff_bodyformatter_class_unittest(diffhighlightertest.cpp "../highlighter/highlighter.cpp") - -ecm_add_test( - airportdbtest.cpp - NAME_PREFIX "messageviewerplugins-" - LINK_LIBRARIES Qt5::Test semantic_extractor -) -add_definitions(-DSOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}") -ecm_add_test( - structureddataextractortest.cpp - NAME_PREFIX "messageviewerplugins-" - LINK_LIBRARIES Qt5::Test semantic_extractor -) -ecm_add_test( - unstructureddataextractortest.cpp - NAME_PREFIX "messageviewerplugins-" - LINK_LIBRARIES Qt5::Test semantic_extractor -) -ecm_add_test( - postprocessortest.cpp - NAME_PREFIX "messageviewerplugins-" - LINK_LIBRARIES Qt5::Test semantic_extractor -) -ecm_add_test( - calendarhandlertest.cpp - NAME_PREFIX "messageviewerplugins-" - LINK_LIBRARIES Qt5::Test semantic_extractor -) diff --git a/plugins/messageviewer/bodypartformatter/autotests/airportdbtest.cpp b/plugins/messageviewer/bodypartformatter/autotests/airportdbtest.cpp deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/airportdbtest.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "airportdb/airportdb.h" - -#include -#include -#include -#include - -#include - -class AirportDbTest : public QObject -{ - Q_OBJECT -private Q_SLOTS: - void iataCodeTest() - { - const auto txl = AirportDb::IataCode{"TXL"}; - QVERIFY(txl.isValid()); - const auto invalid = AirportDb::IataCode{}; - QVERIFY(!invalid.isValid()); - QVERIFY(txl != invalid); - QVERIFY(!(txl == invalid)); - QVERIFY(txl == txl); - QCOMPARE(invalid.toString(), QString()); - - const auto cdg = AirportDb::IataCode{"CDG"}; - QVERIFY(cdg.isValid()); - QVERIFY(cdg != txl); - QVERIFY(!(cdg == txl)); - QVERIFY(cdg < txl); - QVERIFY(!(txl < cdg)); - - QVERIFY(AirportDb::IataCode{"ABC"} < AirportDb::IataCode{"CBA"}); - QVERIFY(!(AirportDb::IataCode{"CBA"} < AirportDb::IataCode{"ABC"})); - } - - void coordinateLookupTest() - { - auto coord = AirportDb::coordinateForAirport(AirportDb::IataCode{"TXL"}); - QVERIFY(coord.isValid()); - QCOMPARE((int)coord.longitude, 13); - QCOMPARE((int)coord.latitude, 52); - - coord = AirportDb::coordinateForAirport(AirportDb::IataCode{"XXX"}); - QVERIFY(!coord.isValid()); - QVERIFY(std::isnan(coord.latitude)); - QVERIFY(std::isnan(coord.longitude)); - - // test coordinate parsing corner cases - coord = AirportDb::coordinateForAirport(AirportDb::IataCode{"LCY"}); - QCOMPARE((int)coord.longitude, 0); - QVERIFY(coord.longitude > 0.0f); - coord = AirportDb::coordinateForAirport(AirportDb::IataCode{"LHR"}); - QCOMPARE((int)coord.longitude, 0); - QVERIFY(coord.longitude < 0.0f); - - // Köln-Bonn is a hybrid civilian/military airport, so that should be included - coord = AirportDb::coordinateForAirport(AirportDb::IataCode{"CGN"}); - QVERIFY(coord.isValid()); - // Frankfurt-Hahn is a former military airport, should be included - coord = AirportDb::coordinateForAirport(AirportDb::IataCode{"HHN"}); - QVERIFY(coord.isValid()); - // Ramstein is a military airport that should not be included - coord = AirportDb::coordinateForAirport(AirportDb::IataCode{"RMS"}); - QVERIFY(!coord.isValid()); - - // IATA codes that changed airports in various ways - QVERIFY(AirportDb::coordinateForAirport(AirportDb::IataCode{"DEN"}).isValid()); - QVERIFY(AirportDb::coordinateForAirport(AirportDb::IataCode{"MUC"}).isValid()); - QVERIFY(AirportDb::coordinateForAirport(AirportDb::IataCode{"GOT"}).isValid()); - QVERIFY(AirportDb::coordinateForAirport(AirportDb::IataCode{"OSL"}).isValid()); - - // IATA codes of no longer active airports - QVERIFY(!AirportDb::coordinateForAirport(AirportDb::IataCode{"THF"}).isValid()); - - // IATA codes of civilian airports that match the primitive military filter - QVERIFY(AirportDb::coordinateForAirport(AirportDb::IataCode{"RAF"}).isValid()); - QVERIFY(AirportDb::coordinateForAirport(AirportDb::IataCode{"CFB"}).isValid()); - QVERIFY(AirportDb::coordinateForAirport(AirportDb::IataCode{"PAF"}).isValid()); - - // one airport with 3 IATA codes - coord = AirportDb::coordinateForAirport(AirportDb::IataCode{"BSL"}); - QVERIFY(coord.isValid()); - QCOMPARE(AirportDb::coordinateForAirport(AirportDb::IataCode{"BSL"}), AirportDb::coordinateForAirport(AirportDb::IataCode{"MLH"})); - QCOMPARE(AirportDb::coordinateForAirport(AirportDb::IataCode{"BSL"}), AirportDb::coordinateForAirport(AirportDb::IataCode{"EAP"})); - } - - void timezoneLookupTest() - { - auto tz = AirportDb::timezoneForAirport(AirportDb::IataCode{"TXL"}); - QVERIFY(tz.isValid()); - QCOMPARE(tz.id(), QByteArray("Europe/Berlin")); - - tz = AirportDb::timezoneForAirport(AirportDb::IataCode{"XXX"}); - QVERIFY(!tz.isValid()); - - // tiny, make sure our lookup resolution is big enough for that - tz = AirportDb::timezoneForAirport(AirportDb::IataCode{"LUX"}); - QCOMPARE(tz.id(), QByteArray("Europe/Luxembourg")); - } - - void iataLookupTest() - { - // via unique fragment lookup - QCOMPARE(AirportDb::iataCodeFromName(QStringLiteral("Flughafen Berlin-Tegel")), AirportDb::IataCode{"TXL"}); - QCOMPARE(AirportDb::iataCodeFromName(QStringLiteral("TEGEL")), AirportDb::IataCode{"TXL"}); - QCOMPARE(AirportDb::iataCodeFromName(QStringLiteral("Paris Charles de Gaulle")), AirportDb::IataCode{"CDG"}); - QCOMPARE(AirportDb::iataCodeFromName(QStringLiteral("Zürich")), AirportDb::IataCode{"ZRH"}); - QCOMPARE(AirportDb::iataCodeFromName(QStringLiteral("AMSTERDAM, NL (SCHIPHOL AIRPORT)")), AirportDb::IataCode{"AMS"}); - QCOMPARE(AirportDb::iataCodeFromName(QStringLiteral("London Heathrow")), AirportDb::IataCode{"LHR"}); - - // via non-unique fragment lookup - QCOMPARE(AirportDb::iataCodeFromName(QStringLiteral("John F. Kennedy International Airport")), AirportDb::IataCode{"JFK"}); - QCOMPARE(AirportDb::iataCodeFromName(QStringLiteral("San Francisco International")), AirportDb::IataCode{"SFO"}); - QCOMPARE(AirportDb::iataCodeFromName(QStringLiteral("Düsseldorf International")), AirportDb::IataCode{"DUS"}); - QCOMPARE(AirportDb::iataCodeFromName(QStringLiteral("London City")), AirportDb::IataCode{"LCY"}); - QCOMPARE(AirportDb::iataCodeFromName(QStringLiteral("DETROIT, MI (METROPOLITAN WAYNE CO)")), AirportDb::IataCode{"DTW"}); - - // not unique - QVERIFY(!AirportDb::iataCodeFromName(QStringLiteral("Flughafen Berlin")).isValid()); - QVERIFY(!AirportDb::iataCodeFromName(QStringLiteral("Charles de Gaulle Orly")).isValid()); - QVERIFY(!AirportDb::iataCodeFromName(QStringLiteral("Brussels Airport, BE")).isValid()); - QVERIFY(!AirportDb::iataCodeFromName(QStringLiteral("Frankfurt")).isValid()); - } -}; - -QTEST_APPLESS_MAIN(AirportDbTest) - -#include "airportdbtest.moc" diff --git a/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/flight-augment.post.json b/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/flight-augment.post.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/flight-augment.post.json +++ /dev/null @@ -1,36 +0,0 @@ -[{ - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "UA", - "name": "United" - }, - "arrivalAirport": { - "@type": "Airport", - "geo": { - "@type": "GeoCoordinates", - "longitude": -77.45580291748047, - "latitude": 38.944400787353516 - }, - "iataCode": "IAD", - "name": "Washington Dulles International Airport" - }, - "arrivalTime": "2027-03-05T06:30:00-05:00", - "departureAirport": { - "@type": "Airport", - "geo": { - "@type": "GeoCoordinates", - "longitude": -122.30899810791016, - "latitude": 47.44889831542969 - }, - "iataCode": "SEA", - "name": "Seattle-Tacoma International Airport" - }, - "departureTime": "2027-03-04T20:15:00-08:00", - "flightNumber": "110" - }, - "reservationNumber": "RXJ34P" -}] diff --git a/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/flight-augment.pre.json b/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/flight-augment.pre.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/flight-augment.pre.json +++ /dev/null @@ -1,24 +0,0 @@ -[{ - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationNumber": "RXJ34P", - "reservationFor": { - "@type": "Flight", - "flightNumber": "110", - "airline": { - "@type": "Airline", - "name": "United", - "iataCode": "UA" - }, - "departureAirport": { - "@type": "Airport", - "name": "Seattle-Tacoma International Airport" - }, - "departureTime": "2027-03-04T20:15:00", - "arrivalAirport": { - "@type": "Airport", - "name": "Washington Dulles International Airport" - }, - "arrivalTime": "2027-03-05T06:30:00" - } -}] diff --git a/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/flight-filter.post.json b/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/flight-filter.post.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/flight-filter.post.json +++ /dev/null @@ -1,2 +0,0 @@ -[ -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/flight-filter.pre.json b/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/flight-filter.pre.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/flight-filter.pre.json +++ /dev/null @@ -1,73 +0,0 @@ -[{ - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationNumber": "RXJ34P", - "reservationFor": { - "@type": "Flight", - "flightNumber": "110", - "airline": { - "@type": "Airline", - "name": "United", - "iataCode": "UA" - }, - "departureAirport": { - "@type": "Airport", - "name": "San Francisco Airport", - "iataCode": "SFO" - }, - "departureTime": "2027-03-04T20:15:00-08:00", - "arrivalTime": "2027-03-05T06:30:00-05:00" - } -}, { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationNumber": "XXX123" -}, { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationNumber": "RXJ34P", - "reservationFor": { - "@type": "Flight", - "flightNumber": "110", - "airline": { - "@type": "Airline", - "name": "United", - "iataCode": "UA" - }, - "departureAirport": { - "@type": "Airport", - "name": "San Francisco Airport", - "iataCode": "SFO" - }, - "arrivalAirport": { - "@type": "Airport", - "name": "John F. Kennedy International Airport" - }, - "arrivalTime": "2027-03-05T06:30:00-05:00" - } -}, { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationNumber": "RXJ34P", - "reservationFor": { - "@type": "Flight", - "flightNumber": "110", - "airline": { - "@type": "Airline", - "name": "United", - "iataCode": "UA" - }, - "departureAirport": { - "@type": "Airport", - "name": "San Francisco Airport", - "iataCode": "SFO" - }, - "departureTime": "2027-03-04T20:15:00-08:00", - "arrivalAirport": { - "@type": "Airport", - "name": "John F. Kennedy International Airport" - } - } -} -] - diff --git a/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/hotel-filter.post.json b/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/hotel-filter.post.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/hotel-filter.post.json +++ /dev/null @@ -1,2 +0,0 @@ -[ -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/hotel-filter.pre.json b/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/hotel-filter.pre.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/hotel-filter.pre.json +++ /dev/null @@ -1,41 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "LodgingReservation", - "checkoutDate": "2017-09-20T12:00:00+03:00", - "reservationFor": { - "@type": "LodgingBusiness", - "address": { - "@type": "PostalAddress", - "addressCountry": "Finland", - "addressLocality": "Espoo", - "addressRegion": "", - "postalCode": "02600", - "streetAddress": "Leppävaarankatu 1" - }, - "name": "Glo Hotel Sello" - }, - "reservationNumber": "1234567890", - "reservationStatus": "http://schema.org/Confirmed" - }, - { - "@context": "http://schema.org", - "@type": "LodgingReservation", - "checkinDate": "2017-09-19T15:00:00+03:00", - "reservationFor": { - "@type": "LodgingBusiness", - "address": { - "@type": "PostalAddress", - "addressCountry": "Finland", - "addressLocality": "Espoo", - "addressRegion": "", - "postalCode": "02600", - "streetAddress": "Leppävaarankatu 1" - }, - "name": "Glo Hotel Sello" - }, - "reservationNumber": "1234567890", - "reservationStatus": "http://schema.org/Confirmed" - } -] - diff --git a/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/train-unsorted.post.json b/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/train-unsorted.post.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/train-unsorted.post.json +++ /dev/null @@ -1,82 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalStation": { - "@type": "TrainStation", - "geo": { - "@type": "GeoCoordinates", - "latitude": 43.83229064941406, - "longitude": 4.365845203399658 - }, - "name": "Nîmes Gare" - }, - "arrivalTime": "2017-09-24T20:33:00+02:00", - "departureStation": { - "@type": "TrainStation", - "geo": { - "@type": "GeoCoordinates", - "latitude": 45.76055908203125, - "longitude": 4.8593549728393555 - }, - "name": "Lyon Part-Dieu" - }, - "departureTime": "2017-09-24T19:09:00+02:00", - "trainName": "TGV", - "trainNumber": "5119" - }, - "reservationNumber": "XXX007", - "reservedTicket": { - "@type": "Ticket", - "ticketToken": "aztecCode:somerandomdata DOE JOHN111110 00000", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "71", - "seatSection": "13" - } - }, - "url": "https://www.trainline.fr/tickets" - }, - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalStation": { - "@type": "TrainStation", - "geo": { - "@type": "GeoCoordinates", - "latitude": 45.76055908203125, - "longitude": 4.8593549728393555 - }, - "name": "Lyon Part-Dieu" - }, - "arrivalTime": "2017-09-29T19:52:00+02:00", - "departureStation": { - "@type": "TrainStation", - "geo": { - "@type": "GeoCoordinates", - "latitude": 43.83229064941406, - "longitude": 4.365845203399658 - }, - "name": "Nîmes Gare" - }, - "departureTime": "2017-09-29T18:26:00+02:00", - "trainName": "TGV", - "trainNumber": "5186" - }, - "reservationNumber": "XXX007", - "reservedTicket": { - "@type": "Ticket", - "ticketToken": "aztecCode:somerandomdata DOE JOHN111110 00000", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "62", - "seatSection": "17" - } - }, - "url": "https://www.trainline.fr/tickets" - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/train-unsorted.pre.json b/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/train-unsorted.pre.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/postprocessordata/train-unsorted.pre.json +++ /dev/null @@ -1,128 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "bookingAgent": { - "@type": "Organization", - "email": "someone@trainline.fr", - "name": "Trainline" - }, - "bookingTime": "2017-09-19T13:42:00+02:00", - "cancelReservationUrl": "https://www.trainline.fr/tickets", - "modifiedTime": "2017-09-21T09:19:38+02:00", - "modifyReservationUrl": "https://www.trainline.fr/tickets", - "reservationFor": { - "@type": "TrainTrip", - "arrivalStation": { - "@type": "TrainStation", - "geo": { - "@type": "GeoCoordinates", - "latitude": 45.760559, - "longitude": 4.859355 - }, - "name": "Lyon Part-Dieu" - }, - "arrivalTime": "2017-09-29T19:52:00+02:00", - "departureStation": { - "@type": "TrainStation", - "geo": { - "@type": "GeoCoordinates", - "latitude": 43.832291, - "longitude": 4.365845 - }, - "name": "Nîmes Gare" - }, - "departureTime": "2017-09-29T18:26:00+02:00", - "trainCompany": { - "@type": "Organization", - "name": "SNCF" - }, - "trainName": "TGV", - "trainNumber": "5186" - }, - "reservationNumber": "XXX007", - "reservationStatus": "http://schema.org/ReservationConfirmed", - "reservedTicket": { - "@type": "Ticket", - "ticketToken": "aztecCode:somerandomdata DOE JOHN111110 00000", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "62", - "seatSection": "17", - "seatingType": "Economy" - }, - "underName": { - "@type": "Person", - "name": "John Doe" - } - }, - "underName": { - "@type": "Person", - "name": "John Doe" - }, - "url": "https://www.trainline.fr/tickets" - }, - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "bookingAgent": { - "@type": "Organization", - "email": "somebody@trainline.fr", - "name": "Trainline" - }, - "bookingTime": "2017-09-19T13:42:00+02:00", - "cancelReservationUrl": "https://www.trainline.fr/tickets", - "modifiedTime": "2017-09-21T09:19:38+02:00", - "modifyReservationUrl": "https://www.trainline.fr/tickets", - "reservationFor": { - "@type": "TrainTrip", - "arrivalStation": { - "@type": "TrainStation", - "geo": { - "@type": "GeoCoordinates", - "latitude": 43.832291, - "longitude": 4.365845 - }, - "name": "Nîmes Gare" - }, - "arrivalTime": "2017-09-24T20:33:00+02:00", - "departureStation": { - "@type": "TrainStation", - "geo": { - "@type": "GeoCoordinates", - "latitude": 45.760559, - "longitude": 4.859355 - }, - "name": "Lyon Part-Dieu" - }, - "departureTime": "2017-09-24T19:09:00+02:00", - "trainCompany": { - "@type": "Organization", - "name": "SNCF" - }, - "trainName": "TGV", - "trainNumber": "5119" - }, - "reservationNumber": "XXX007", - "reservationStatus": "http://schema.org/ReservationConfirmed", - "reservedTicket": { - "@type": "Ticket", - "ticketToken": "aztecCode:somerandomdata DOE JOHN111110 00000", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "71", - "seatSection": "13", - "seatingType": "First" - }, - "underName": { - "@type": "Person", - "name": "John Doe" - } - }, - "underName": { - "@type": "Person", - "name": "John Doe" - }, - "url": "https://www.trainline.fr/tickets" - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/postprocessortest.cpp b/plugins/messageviewer/bodypartformatter/autotests/postprocessortest.cpp deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/postprocessortest.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "extractorpostprocessor.h" -#include "jsonlddocument.h" - -#include -#include -#include -#include -#include -#include -#include - -class PostprocessorTest : public QObject -{ - Q_OBJECT -private Q_SLOTS: - void testPostProc_data() - { - QTest::addColumn("preFile"); - QTest::addColumn("postFile"); - - QDir dir(QStringLiteral(SOURCE_DIR "/postprocessordata")); - const auto lst = dir.entryList(QStringList(QStringLiteral("*.pre.json")), QDir::Files | QDir::Readable | QDir::NoSymLinks); - for (const auto &file : lst) { - const auto refFile = dir.path() + QLatin1Char('/') + file.left(file.size() - 8) + QStringLiteral("post.json"); - if (!QFile::exists(refFile)) { - qDebug() << "reference file" << refFile << "does not exist, skipping test file" << file; - continue; - } - QTest::newRow(file.toLatin1()) << QString(dir.path() + QLatin1Char('/') + file) << refFile; - } - } - - void testPostProc() - { - QFETCH(QString, preFile); - QFETCH(QString, postFile); - - QFile f(preFile); - QVERIFY(f.open(QFile::ReadOnly)); - const auto inArray = QJsonDocument::fromJson(f.readAll()).array(); - QVERIFY(!inArray.isEmpty()); - const auto preData = JsonLdDocument::fromJson(inArray); - QCOMPARE(inArray.size(), preData.size()); - - ExtractorPostprocessor postproc; - postproc.process(preData); - const auto outArray = JsonLdDocument::toJson(postproc.result()); - QCOMPARE(outArray.size(), postproc.result().size()); - - QFile ref(postFile); - QVERIFY(ref.open(QFile::ReadOnly)); - const auto refArray = QJsonDocument::fromJson(ref.readAll()).array(); - - if (outArray != refArray) { - qDebug().noquote() << QJsonDocument(outArray).toJson(); - } - QCOMPARE(refArray.size(), postproc.result().size()); - QCOMPARE(outArray, refArray); - } -}; - -QTEST_APPLESS_MAIN(PostprocessorTest) - -#include "postprocessortest.moc" diff --git a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-flight-reservation-json-ld.html b/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-flight-reservation-json-ld.html deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-flight-reservation-json-ld.html +++ /dev/null @@ -1,34 +0,0 @@ - - diff --git a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-flight-reservation-json-ld.json b/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-flight-reservation-json-ld.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-flight-reservation-json-ld.json +++ /dev/null @@ -1,31 +0,0 @@ -[{ - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationNumber": "RXJ34P", - "reservationStatus": "http://schema.org/Confirmed", - "underName": { - "@type": "Person", - "name": "Eva Green" - }, - "reservationFor": { - "@type": "Flight", - "flightNumber": "110", - "airline": { - "@type": "Airline", - "name": "United", - "iataCode": "UA" - }, - "departureAirport": { - "@type": "Airport", - "name": "San Francisco Airport", - "iataCode": "SFO" - }, - "departureTime": "2027-03-04T20:15:00-08:00", - "arrivalAirport": { - "@type": "Airport", - "name": "John F. Kennedy International Airport", - "iataCode": "JFK" - }, - "arrivalTime": "2027-03-05T06:30:00-05:00" - } -}] diff --git a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-flight-reservation-microdata.html b/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-flight-reservation-microdata.html deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-flight-reservation-microdata.html +++ /dev/null @@ -1,25 +0,0 @@ - -
- - -
- -
-
- -
- - -
-
- - -
- -
- - -
- -
-
diff --git a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-flight-reservation-microdata.json b/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-flight-reservation-microdata.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-flight-reservation-microdata.json +++ /dev/null @@ -1,32 +0,0 @@ -[{ - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationNumber": "RXJ34P", - "reservationStatus": "http://schema.org/Confirmed", - "underName": { - "@type": "Person", - "name": "Eva Green" - }, - "reservationFor": { - "@type": "Flight", - "flightNumber": "110", - "airline": { - "@type": "Airline", - "name": "United", - "iataCode": "UA" - }, - "departureAirport": { - "@type": "Airport", - "name": "San Francisco Airport", - "iataCode": "SFO" - }, - "departureTime": "2027-03-04T20:15:00-08:00", - "arrivalAirport": { - "@type": "Airport", - "name": "John F. Kennedy International Airport", - "iataCode": "JFK" - }, - "arrivalTime": "2027-03-05T06:30:00-05:00" - } -}] - diff --git a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-json-ld.html b/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-json-ld.html deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-json-ld.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - -

- Dear John, thanks for booking your Google I/O ticket with us. -

-

- BOOKING DETAILS
- Reservation number: IO12345
- Order for: John Smith
- Event: Google I/O 2013
- Start time: May 15th 2013 8:00am PST
- Venue: Moscone Center, 800 Howard St., San Francisco, CA 94103
-

- - diff --git a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-json-ld.json b/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-json-ld.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-json-ld.json +++ /dev/null @@ -1,26 +0,0 @@ -[{ - "@context": "http://schema.org", - "@type": "EventReservation", - "reservationNumber": "IO12345", - "underName": { - "@type": "Person", - "name": "John Smith" - }, - "reservationFor": { - "@type": "Event", - "name": "Google I/O 2013", - "startDate": "2013-05-15T08:30:00-08:00", - "location": { - "@type": "Place", - "name": "Moscone Center", - "address": { - "@type": "PostalAddress", - "streetAddress": "800 Howard St.", - "addressLocality": "San Francisco", - "addressRegion": "CA", - "postalCode": "94103", - "addressCountry": "US" - } - } - } -}] diff --git a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-microdata-inline.html b/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-microdata-inline.html deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-microdata-inline.html +++ /dev/null @@ -1,29 +0,0 @@ - - - -

- Dear John, thanks for booking your Google I/O ticket with us. -

-

- BOOKING DETAILS
- Reservation number: IO12345
- Order for: - John Smith -
-

- Event: Google I/O 2013
-
- Venue: - Moscone Center - - 800 Howard St., - San Francisco, - CA, - 94103, - US - - -
-

- - diff --git a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-microdata-inline.json b/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-microdata-inline.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-microdata-inline.json +++ /dev/null @@ -1,27 +0,0 @@ -[{ - "@context": "http://schema.org", - "@type": "EventReservation", - "reservationNumber": "IO12345", - "underName": { - "@type": "Person", - "name": "John Smith" - }, - "reservationFor": { - "@type": "Event", - "name": "Google I/O 2013", - "startDate": "2013-05-15T08:30:00-08:00", - "location": { - "@type": "Place", - "name": "Moscone Center", - "address": { - "@type": "PostalAddress", - "streetAddress": "800 Howard St.", - "addressLocality": "San Francisco", - "addressRegion": "CA", - "postalCode": "94103", - "addressCountry": "US" - } - } - } -}] - diff --git a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-microdata.html b/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-microdata.html deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-microdata.html +++ /dev/null @@ -1,36 +0,0 @@ - - - -
- -
- -
-
- -
-
-

- Dear John, thanks for booking your Google I/O ticket with us. -

-

- BOOKING DETAILS
- Reservation number: IO12345
- Order for: John Smith
- Event: Google I/O 2013
- Start time: May 15th 2013 8:00am PST
- Venue: Moscone Center, 800 Howard St., San Francisco, CA 94103
-

- - diff --git a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-microdata.json b/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-microdata.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/structureddata/google-microdata.json +++ /dev/null @@ -1,26 +0,0 @@ -[{ - "@context": "http://schema.org", - "@type": "EventReservation", - "reservationNumber": "IO12345", - "underName": { - "@type": "Person", - "name": "John Smith" - }, - "reservationFor": { - "@type": "Event", - "name": "Google I/O 2013", - "startDate": "2013-05-15T08:30:00-08:00", - "location": { - "@type": "Place", - "name": "Moscone Center", - "address": { - "@type": "PostalAddress", - "streetAddress": "800 Howard St.", - "addressLocality": "San Francisco", - "addressRegion": "CA", - "postalCode": "94103", - "addressCountry": "US" - } - } - } -}] diff --git a/plugins/messageviewer/bodypartformatter/autotests/structureddata/hotel-json-ld-fallback.html b/plugins/messageviewer/bodypartformatter/autotests/structureddata/hotel-json-ld-fallback.html deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/structureddata/hotel-json-ld-fallback.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - Reservation Confirmation - - - -

random content
can be invalid - - diff --git a/plugins/messageviewer/bodypartformatter/autotests/structureddata/hotel-json-ld-fallback.json b/plugins/messageviewer/bodypartformatter/autotests/structureddata/hotel-json-ld-fallback.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/structureddata/hotel-json-ld-fallback.json +++ /dev/null @@ -1,25 +0,0 @@ -[{ - "@context": "http://schema.org", - "@type": "LodgingReservation", - "checkinDate": "2017-06-15T14:00:00+0:00", - "checkoutDate": "2017-06-18T11:00:00+0:00", - "reservationFor": { - "@type": "LodgingBusiness", - "address": { - "@type": "PostalAddress", - "addressCountry": "GB", - "addressLocality": "London", - "addressRegion": "LONDON", - "postalCode": "123 ABC", - "streetAddress": "10 Downing Street" - }, - "name": "Parser & Breaking Hotels", - "telephone": "+44-123-4-567-890" - }, - "reservationNumber": "KDEKDEKDE", - "reservationStatus": "http://schema.org/Confirmed", - "underName": { - "@type": "Person", - "name": "Volker Krause" - } -}] diff --git a/plugins/messageviewer/bodypartformatter/autotests/structureddata/lh-invalid-microdata.html b/plugins/messageviewer/bodypartformatter/autotests/structureddata/lh-invalid-microdata.html deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/structureddata/lh-invalid-microdata.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - -

- -
- -
-
- -
- - -
-
- - -
- -
- - -
- -
-
- -
-
-
- -
- -
-
- -
- - -
-
- - -
- -
- - -
- -
-
- -
-
-
- -
- -
-
- -
- - -
-
- - -
- -
- - -
- -
-
- -
-
-
- -
- -
-
- -
- - -
-
- - -
- -
- - -
- -
-
- -
-
- - - -lots of actual content
can be invalid to parse - - diff --git a/plugins/messageviewer/bodypartformatter/autotests/structureddata/lh-invalid-microdata.json b/plugins/messageviewer/bodypartformatter/autotests/structureddata/lh-invalid-microdata.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/structureddata/lh-invalid-microdata.json +++ /dev/null @@ -1,136 +0,0 @@ -[{ - "@context": "http://schema.org", - "@type": "FlightReservation", - "airplaneSeatClass": { - "@type": "AirplaneSeatClass", - "name": "ECONOMY" - }, - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "LH", - "name": "LUFTHANSA" - }, - "arrivalAirport": { - "@type": "Airport", - "iataCode": "MUC", - "name": "MUNICH DE MUNICH INTERNATIONAL" - }, - "arrivalTime": "2017-04-07T09:35:00+02:00", - "departureAirport": { - "@type": "Airport", - "iataCode": "TXL", - "name": "BERLIN DE TEGEL" - }, - "departureTime": "2017-04-07T08:30:00+02:00", - "flightNumber": "2029" - }, - "reservationNumber": "KDEKDE", - "underName": { - "@type": "Person", - "name": "VOLKER KRAUSE" - } -}, -{ - "@context": "http://schema.org", - "@type": "FlightReservation", - "airplaneSeatClass": { - "@type": "AirplaneSeatClass", - "name": "ECONOMY" - }, - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "LH", - "name": "LUFTHANSA" - }, - "arrivalAirport": { - "@type": "Airport", - "iataCode": "TLS", - "name": "TOULOUSE FR BLAGNAC" - }, - "arrivalTime": "2017-04-07T13:00:00+02:00", - "departureAirport": { - "@type": "Airport", - "iataCode": "MUC", - "name": "MUNICH DE MUNICH INTERNATIONAL" - }, - "departureTime": "2017-04-07T11:10:00+02:00", - "flightNumber": "2218" - }, - "reservationNumber": "KDEKDE", - "underName": { - "@type": "Person", - "name": "VOLKER KRAUSE" - } -}, -{ - "@context": "http://schema.org", - "@type": "FlightReservation", - "airplaneSeatClass": { - "@type": "AirplaneSeatClass", - "name": "ECONOMY" - }, - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "LH", - "name": "LUFTHANSA" - }, - "arrivalAirport": { - "@type": "Airport", - "iataCode": "MUC", - "name": "MUNICH DE MUNICH INTERNATIONAL" - }, - "arrivalTime": "2017-04-09T19:55:00+02:00", - "departureAirport": { - "@type": "Airport", - "iataCode": "TLS", - "name": "TOULOUSE FR BLAGNAC" - }, - "departureTime": "2017-04-09T18:15:00+02:00", - "flightNumber": "2221" - }, - "reservationNumber": "KDEKDE", - "underName": { - "@type": "Person", - "name": "VOLKER KRAUSE" - } -}, -{ - "@context": "http://schema.org", - "@type": "FlightReservation", - "airplaneSeatClass": { - "@type": "AirplaneSeatClass", - "name": "ECONOMY" - }, - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "LH", - "name": "LUFTHANSA" - }, - "arrivalAirport": { - "@type": "Airport", - "iataCode": "TXL", - "name": "BERLIN DE TEGEL" - }, - "arrivalTime": "2017-04-09T22:35:00+02:00", - "departureAirport": { - "@type": "Airport", - "iataCode": "MUC", - "name": "MUNICH DE MUNICH INTERNATIONAL" - }, - "departureTime": "2017-04-09T21:30:00+02:00", - "flightNumber": "2054" - }, - "reservationNumber": "KDEKDE", - "underName": { - "@type": "Person", - "name": "VOLKER KRAUSE" - } -}] diff --git a/plugins/messageviewer/bodypartformatter/autotests/structureddataextractortest.cpp b/plugins/messageviewer/bodypartformatter/autotests/structureddataextractortest.cpp deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/structureddataextractortest.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "structureddataextractor.h" - -#include -#include -#include -#include -#include -#include - -class StructuredDataExtractorTest : public QObject -{ - Q_OBJECT -private Q_SLOTS: - void testExtract_data() - { - QTest::addColumn("inputFile"); - QTest::addColumn("jsonFile"); - - QDir dir(QStringLiteral(SOURCE_DIR "/structureddata")); - const auto lst = dir.entryList(QStringList(QStringLiteral("*.html")), QDir::Files | QDir::Readable | QDir::NoSymLinks); - for (const auto &file : lst) { - const auto refFile = dir.path() + QLatin1Char('/') + file.left(file.size() - 5) + QStringLiteral(".json"); - if (!QFile::exists(refFile)) { - qDebug() << "reference file" << refFile << "does not exist, skipping test file" << file; - continue; - } - QTest::newRow(file.toLatin1()) << QString(dir.path() + QLatin1Char('/') + file) << refFile; - } - } - - void testExtract() - { - QFETCH(QString, inputFile); - QFETCH(QString, jsonFile); - - StructuredDataExtractor extractor; - QFile f(inputFile); - QVERIFY(f.open(QFile::ReadOnly)); - extractor.parse(QString::fromUtf8(f.readAll())); - - QFile ref(jsonFile); - QVERIFY(ref.open(QFile::ReadOnly)); - const auto doc = QJsonDocument::fromJson(ref.readAll()); - QVERIFY(doc.isArray()); - - if (extractor.data() != doc.array()) { - qDebug().noquote() << QJsonDocument(extractor.data()).toJson(); - } - QCOMPARE(extractor.data(), doc.array()); - } -}; - -QTEST_APPLESS_MAIN(StructuredDataExtractorTest) - -#include "structureddataextractortest.moc" diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/amadeus_1.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/amadeus_1.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/amadeus_1.json +++ /dev/null @@ -1,98 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "DL", - "name": "DELTA AIR LINES" - }, - "arrivalAirport": { - "@type": "Airport", - "name": "AMSTERDAM, NL (SCHIPHOL AIRPORT)" - }, - "arrivalTime": "2016-06-07T13:30:00", - "departureAirport": { - "@type": "Airport", - "name": "BERLIN, DE (TEGEL)" - }, - "departureTime": "2016-06-07T12:10:00", - "flightNumber": "9520" - }, - "reservationNumber": "123456" - }, - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "DL", - "name": "DELTA AIR LINES" - }, - "arrivalAirport": { - "@type": "Airport", - "name": "DETROIT, MI (METROPOLITAN WAYNE CO), TERMINAL EM" - }, - "arrivalTime": "2016-06-07T17:40:00", - "departureAirport": { - "@type": "Airport", - "name": "AMSTERDAM, NL (SCHIPHOL AIRPORT)" - }, - "departureTime": "2016-06-07T15:00:00", - "flightNumber": "139" - }, - "reservationNumber": "123456" - }, - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "DL", - "name": "DELTA AIR LINES" - }, - "arrivalAirport": { - "@type": "Airport", - "name": "PARIS, FR (CHARLES DE GAULLE), TERMINAL 2E" - }, - "arrivalTime": "2016-06-10T11:30:00", - "departureAirport": { - "@type": "Airport", - "name": "DETROIT, MI (METROPOLITAN WAYNE CO), TERMINAL EM" - }, - "departureTime": "2016-06-09T21:40:00", - "flightNumber": "8573" - }, - "reservationNumber": "123456" - }, - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "DL", - "name": "DELTA AIR LINES" - }, - "arrivalAirport": { - "@type": "Airport", - "name": "BERLIN, DE (TEGEL)" - }, - "arrivalTime": "2016-06-10T14:40:00", - "departureAirport": { - "@type": "Airport", - "name": "PARIS, FR (CHARLES DE GAULLE), TERMINAL 2F" - }, - "departureTime": "2016-06-10T13:00:00", - "flightNumber": "8680" - }, - "reservationNumber": "123456" - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/amadeus_1.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/amadeus_1.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/amadeus_1.txt +++ /dev/null @@ -1,66 +0,0 @@ -/TIT IMPORTANT MESSAGE PLEASE READ INFO AT THE BOTTOM - -TRAVEL AGENCY BOOKING REF: 123456 -SOME PLACE, SOMEWHERE. 9 DATE: 27 MAY 2016 -S-171 54 SOME CITY -COUNTRY DOE/JOHN MR - - -FLIGHT DL 9520 - DELTA AIR LINES TUE 07 JUNE 2016 ------------------------------------------------------------------------------ -DEPARTURE: BERLIN, DE (TEGEL) 07 JUN 12:10 -ARRIVAL: AMSTERDAM, NL (SCHIPHOL AIRPORT) 07 JUN 13:30 - FLIGHT BOOKING REF: DL/123456 - RESERVATION CONFIRMED, ECONOMY (M) DURATION: 01:20 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BAGGAGE ALLOWANCE: 1PC - MEAL: SNACK -NON STOP BERLIN TO AMSTERDAM - OPERATED BY: KLM ROYAL DUTCH AIRLINES, KL 1824 - EQUIPMENT: BOEING 737-900 - -FLIGHT DL 139 - DELTA AIR LINES TUE 07 JUNE 2016 ------------------------------------------------------------------------------ -DEPARTURE: AMSTERDAM, NL (SCHIPHOL AIRPORT) 07 JUN 15:00 -ARRIVAL: DETROIT, MI (METROPOLITAN WAYNE CO), TERMINAL EM - 07 JUN 17:40 - E.H. MCNAMARA TERMINAL - FLIGHT BOOKING REF: DL/123456 - RESERVATION CONFIRMED, ECONOMY (M) DURATION: 08:40 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BAGGAGE ALLOWANCE: 1PC - MEAL: DINNER -NON STOP AMSTERDAM TO DETROIT, MI - OPERATED BY: DELTA AIR LINES, DL - EQUIPMENT: AIRBUS INDUSTRIE A330-200 - -FLIGHT DL 8573 - DELTA AIR LINES THU 09 JUNE 2016 ------------------------------------------------------------------------------ -DEPARTURE: DETROIT, MI (METROPOLITAN WAYNE CO), TERMINAL EM - 09 JUN 21:40 - E.H. MCNAMARA TERMINAL -ARRIVAL: PARIS, FR (CHARLES DE GAULLE), TERMINAL 2E - 10 JUN 11:30 - AEROGARE 2 TERMINAL E - FLIGHT BOOKING REF: DL/123456 - RESERVATION CONFIRMED, ECONOMY (M) DURATION: 07:50 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BAGGAGE ALLOWANCE: 1PC - MEAL: BREAKFAST -NON STOP DETROIT, MI TO PARIS - OPERATED BY: AIR FRANCE, AF 377 - EQUIPMENT: AIRBUS INDUSTRIE A340-300 - -FLIGHT DL 8680 - DELTA AIR LINES FRI 10 JUNE 2016 ------------------------------------------------------------------------------ -DEPARTURE: PARIS, FR (CHARLES DE GAULLE), TERMINAL 2F - 10 JUN 13:00 - AEROGARE 2 TERMINAL F -ARRIVAL: BERLIN, DE (TEGEL) 10 JUN 14:40 - FLIGHT BOOKING REF: DL/123456 - RESERVATION CONFIRMED, ECONOMY (M) DURATION: 01:40 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BAGGAGE ALLOWANCE: 1PC -NON STOP PARIS TO BERLIN - OPERATED BY: AIR FRANCE, AF 1534 - EQUIPMENT: AIRBUS INDUSTRIE A321 - -FLIGHT(S) CALCULATED AVERAGE CO2 EMISSIONS IS 978.44 KG/PERSON -SOURCE: ICAO CARBON EMISSIONS CALCULATOR -http://www.icao.int/environmental-protection/CarbonOffset/Pages/default.aspx diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/brusselsairlines_1.html b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/brusselsairlines_1.html deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/brusselsairlines_1.html +++ /dev/null @@ -1,139 +0,0 @@ - - - - Your reservation - A00000000 - - - - - - - - - - - -
- -
- - - - - - -
HeaderBooking confirmationBrussels Airlines Logo
-
-

Your booking details

-
 
- - - - - -
- - - - - -
Booking reference:XXX007
-
- - - - - - - - - - - - - -
Main contact:Mr John Doe
E-mail:my@email.eu
Mobile:49-0987654321
-
- -
 
-
- -
-
 
- -

Passengers

-
 
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Mr John DoeFlightTXL-BRU, BRU-TXL
Frequent flyerMiles & More 12345678123490
Ticket number082-1234567890
Seats*,*
- -
 
-

Flight details

-
 
-
Departure
- - - - - - - - - - - - -
Berlin, Tegel Airport, DE
Fri, 03 Feb 2017, 18:25
Brussels Airport, BE
Fri, 03 Feb 2017, 19:45
SN 2588
Brussels Airlines
- Check&Go - (Q)
Non stop -
Airbus A320-100/200
-
 
-
Return
- - - - - - - - - - - - -
Brussels Airport, BE
Sun, 05 Feb 2017, 20:40
Berlin, Tegel Airport, DE
Sun, 05 Feb 2017, 22:00
SN 2591
Brussels Airlines
- Check&Go - (E)
Non stop -
Airbus A319
- - - diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/brusselsairlines_1.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/brusselsairlines_1.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/brusselsairlines_1.json +++ /dev/null @@ -1,50 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "SN", - "name": "Brussels Airlines" - }, - "arrivalAirport": { - "@type": "Airport", - "name": "Brussels Airport, BE" - }, - "arrivalTime": "2017-02-03T19:45:00", - "departureAirport": { - "@type": "Airport", - "name": "Berlin, Tegel Airport, DE" - }, - "departureTime": "2017-02-03T18:25:00", - "flightNumber": "2588" - }, - "reservationNumber": "XXX007" - }, - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "SN", - "name": "Brussels Airlines" - }, - "arrivalAirport": { - "@type": "Airport", - "name": "Berlin, Tegel Airport, DE" - }, - "arrivalTime": "2017-02-05T22:00:00", - "departureAirport": { - "@type": "Airport", - "name": "Brussels Airport, BE" - }, - "departureTime": "2017-02-05T20:40:00", - "flightNumber": "2591" - }, - "reservationNumber": "XXX007" - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_one-leg-no-seat-single.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_one-leg-no-seat-single.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_one-leg-no-seat-single.json +++ /dev/null @@ -1,21 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalStation": { - "@type": "TrainStation", - "name": "Praha Masarykovo n." - }, - "arrivalTime": "2017-01-01T17:33:00", - "departureStation": { - "@type": "TrainStation", - "name": "Lysá n.Labem" - }, - "departureTime": "2017-01-01T16:55:00", - "trainNumber": "Os 9424" - }, - "reservationNumber": "VM5MZ3" - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_one-leg-no-seat-single.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_one-leg-no-seat-single.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_one-leg-no-seat-single.txt +++ /dev/null @@ -1,36 +0,0 @@ -! 1154 - JÍZDENKA - eTiket Osob: 1 - Z/DE/VON @ DO/A/NACH TŘÍDA/ - CL./KL. - 01/01 00:00 Lysá n.Labem @ Praha Masarykovo n. 02/01 06:00 2 - * * * @ * * * * - Přes: Čelákovice Km: 35 - IN 25 jednosměrná - Cena 4 Kč -Doklad je nepřenosný a platí vždy pouze ve spojení s osobním průkazem cestujícího, jehož jméno je uvedeno na jízdence. -Jízdu je nutno nastoupit v 1. den platnosti -Daňový doklad (informace o ceně) -Summary / Rechnung -Položka Tar. cena Body Cena DPH -Jízdenka 1 43 Kč 4 Kč 15% -Uplatněné věrnostní body -200 -Celkem 4 Kč -Datum vystavení/datum platby: 1.1.2017 16:44 Platba: KARTOU/CC -Prodejce: České dráhy, a.s. 30002 Číslo obj.: 13580 282 00 -Praha 1, Nábřeží L.Svobody 1222, PSČ 110 15 DIČ: CZ70994226 -Jízdní řád -Timetable / Fahrplan -Stanice Odj. / Příj. x w Místo / Seat / Sitzplatz -Lysá n.Labem 01.01. 16:55 Os 9424 Údaje pro kontrolu -Praha Masarykovo n. 01.01. 17:33 Angaben für Kontrolle - Doklad číslo / Beleg Nr.: -Jízdenku lze použít po stejné trase i pro jiné vlakové spojení v tentýž den platnosti. *2606-208 -Rezervace místa platí pouze pro uvedené vlaky. Jméno / Name: - VRÁTIL Daniel - Kód transakce: - VM5MZ3 - Kód nepřehýbejte! / Do not fold the barcode! - Barcode nicht knicken! -Reklama -Šťastnou cestu vlakem přejí České dráhy, Váš osobní dopravce. Strana 1/1 diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_one-leg-return.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_one-leg-return.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_one-leg-return.json +++ /dev/null @@ -1,54 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalStation": { - "@type": "TrainStation", - "name": "Brno hl.n." - }, - "arrivalTime": "2017-12-31T16:20:00", - "departureStation": { - "@type": "TrainStation", - "name": "Praha hl.n." - }, - "departureTime": "2017-12-31T13:51:00", - "trainNumber": "EC 173" - }, - "reservedTicket": { - "@type": "Ticket", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "71", - "seatSection": "262" - } - } - }, - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalStation": { - "@type": "TrainStation", - "name": "Praha hl.n." - }, - "arrivalTime": "2018-01-01T13:07:00", - "departureStation": { - "@type": "TrainStation", - "name": "Brno hl.n." - }, - "departureTime": "2018-01-01T10:38:00", - "trainNumber": "rj 72" - }, - "reservedTicket": { - "@type": "Ticket", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "51", - "seatSection": "27" - } - } - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_one-leg-return.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_one-leg-return.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_one-leg-return.txt +++ /dev/null @@ -1,41 +0,0 @@ -! 1154 - JÍZDENKA A MÍSTENKA - eTiket Osob: 1 - Z/DE/VON @ DO/A/NACH TŘÍDA/ - CL./KL. - 31/12 13:51 Praha hl.n. @ Brno hl.n. * * 1 - * * Brno hl.n. @ Praha hl.n. 01/01 24:00 1 - Přes: PhaLb,Kolín,Pard.Hl,Ústí/Or,ČTřeb Km: 255 - Rezervace (místo) - IN 25 zpáteční - Cena 662 Kč -Doklad je nepřenosný a platí vždy pouze ve spojení s osobním průkazem cestujícího, jehož jméno je uvedeno na jízdence. -Jízdu je nutno nastoupit v 1. den platnosti, nejdříve však v 13:51 hod. -Daňový doklad (informace o ceně) -Summary / Rechnung -Položka Tar. cena Body Cena DPH -Jízdenka 1 662 Kč 66 662 Kč 15% -Rezervace 2 0 Kč 0 Kč -Celkem 662 Kč -Datum vystavení/datum platby: 30.12.2017 20:27 Platba: KARTOU/CC -Prodejce: České dráhy, a.s. 30002 Číslo obj.: 20361 103 00 -Praha 1, Nábřeží L.Svobody 1222, PSČ 110 15 DIČ: CZ70994226 -Jízdní řád a rezervace pro cestu TAM -Timetable and Reservations – Outward Journey / Fahrplan und Reservierung Hinfahrt -Stanice Odj. / Příj. x w Místo / Seat / Sitzplatz Údaje pro kontrolu -Praha hl.n. 31.12. 13:51 EC 173 262 71 Angaben für Kontrolle -Brno hl.n. 31.12. 16:20 Doklad číslo / Beleg Nr.: - *8576-222 - Jméno / Name: -Jízdní řád a rezervace pro cestu ZPĚT -Timetable and Reservations – Return Journey / Fahrplan und Reservierung Rückfahrt VRÁTIL Daniel -Stanice Odj. / Příj. x w Místo / Seat / Sitzplatz -Brno hl.n. 01.01. 10:38 rj 72 27 51 Kód transakce: -Praha hl.n. 01.01. 13:07 - GIG2L1 -Jízdenku lze použít po stejné trase i pro pozdější vlakové spojení v době její platnosti. -Rezervace místa platí pouze pro uvedené vlaky. Kód nepřehýbejte! / Do not fold the barcode! - Barcode nicht knicken! -Reklama -Šťastnou cestu vlakem přejí České dráhy, Váš osobní dopravce. Strana 1/1 - diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_one-leg-single.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_one-leg-single.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_one-leg-single.json +++ /dev/null @@ -1,29 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalStation": { - "@type": "TrainStation", - "name": "Praha hl.n." - }, - "arrivalTime": "2017-07-09T17:06:00", - "departureStation": { - "@type": "TrainStation", - "name": "Brno dolní nádraží" - }, - "departureTime": "2017-07-09T14:34:00", - "trainNumber": "RJ 76" - }, - "reservationNumber": "FXI305", - "reservedTicket": { - "@type": "Ticket", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "91", - "seatSection": "26" - } - } - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_one-leg-single.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_one-leg-single.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_one-leg-single.txt +++ /dev/null @@ -1,37 +0,0 @@ -! 1154 - JÍZDENKA A MÍSTENKA - eTiket Osob: 1 - Z/DE/VON @ DO/A/NACH TŘÍDA/ - CL./KL. - 09/07 00:00 Brno hl.n./dolní n. @ Praha hl.n. 10/07 24:00 1 - * * * @ * * * * - Přes: ČTřeb,Ústí/Or,Pard.Hl,Kolín Km: 255 - Rezervace (místo) - IN 25 jednosměrná - Cena 341 Kč -Doklad je nepřenosný a platí vždy pouze ve spojení s osobním průkazem cestujícího, jehož jméno je uvedeno na jízdence. -Jízdu je nutno nastoupit v 1. den platnosti -Daňový doklad (informace o ceně) -Summary / Rechnung -Položka Tar. cena Body Cena DPH -Jízdenka 1 341 Kč 34 341 Kč 15% -Rezervace 1 0 Kč 0 Kč -Celkem 341 Kč -Datum vystavení/datum platby: 9.7.2017 14:14 Platba: KARTOU/CC -Prodejce: České dráhy, a.s. 30002 Číslo obj.: 16502 055 00 -Praha 1, Nábřeží L.Svobody 1222, PSČ 110 15 DIČ: CZ70994226 -Jízdní řád a rezervace -Timetable and Reservations / Fahrplan und Reservierung -Stanice Odj. / Příj. x w Místo / Seat / Sitzplatz -Brno dolní nádraží 09.07. 14:34 RJ 76 26 91 Údaje pro kontrolu -Praha hl.n. 09.07. 17:06 Angaben für Kontrolle - Doklad číslo / Beleg Nr.: -Jízdenku lze použít po stejné trase i pro jiné vlakové spojení v tentýž den platnosti. *9740-315 -Rezervace místa platí pouze pro uvedené vlaky. Jméno / Name: - VRÁTIL Daniel - Kód transakce: - FXI305 - Kód nepřehýbejte! / Do not fold the barcode! - Barcode nicht knicken! -Reklama -Šťastnou cestu vlakem přejí České dráhy, Váš osobní dopravce. Strana 1/1 diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_two-leg-single.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_two-leg-single.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_two-leg-single.json +++ /dev/null @@ -1,48 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalStation": { - "@type": "TrainStation", - "name": "Hradec Králové hl.n." - }, - "arrivalTime": "2017-08-09T10:51:00", - "departureStation": { - "@type": "TrainStation", - "name": "Praha hl.n." - }, - "departureTime": "2017-08-09T09:07:00", - "trainNumber": "R 945" - }, - "reservationNumber": "Z39230", - "reservedTicket": { - "@type": "Ticket", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "115", - "seatSection": "372" - } - } - }, - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalStation": { - "@type": "TrainStation", - "name": "Jaroměř" - }, - "arrivalTime": "2017-08-09T11:16:00", - "departureStation": { - "@type": "TrainStation", - "name": "Hradec Králové hl.n." - }, - "departureTime": "2017-08-09T11:02:00", - "trainNumber": "Sp 1786" - }, - "reservationNumber": "Z39230" - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_two-leg-single.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_two-leg-single.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/czechrailways_two-leg-single.txt +++ /dev/null @@ -1,39 +0,0 @@ -! 1154 - JÍZDENKA A MÍSTENKA - eTiket Osob: 1 - Z/DE/VON @ DO/A/NACH TŘÍDA/ - CL./KL. - 09/08 00:00 Praha hl.n. @ Jaroměř 10/08 24:00 2 - * * * @ * * * * - Přes: Lysá/L,NymbH,Chlum/Ci,HradKrHl Km: 133 - Rezervace (místo) - IN 25 jednosměrná - Cena 141 Kč -Doklad je nepřenosný a platí vždy pouze ve spojení s osobním průkazem cestujícího, jehož jméno je uvedeno na jízdence. -Jízdu je nutno nastoupit v 1. den platnosti -Daňový doklad (informace o ceně) -Summary / Rechnung -Položka Tar. cena Body Cena DPH -Jízdenka 1 141 Kč 14 141 Kč 15% -Rezervace 1 0 Kč 0 Kč -Celkem 141 Kč -Datum vystavení/datum platby: 7.8.2017 13:18 Platba: KARTOU/CC -Prodejce: České dráhy, a.s. 30000 Číslo obj.: 16996 165 00 -Praha 1, Nábřeží L.Svobody 1222, PSČ 110 15 DIČ: CZ70994226 -Jízdní řád a rezervace -Timetable and Reservations / Fahrplan und Reservierung -Stanice Odj. / Příj. x w Místo / Seat / Sitzplatz -Praha hl.n. 09.08. 09:07 R 945 372 115 Údaje pro kontrolu -Hradec Králové hl.n. 09.08. 10:51 Angaben für Kontrolle - Doklad číslo / Beleg Nr.: -Hradec Králové hl.n. 09.08. 11:02 Sp 1786 *1011-383 -Jaroměř 09.08. 11:16 Jméno / Name: - VRÁTIL Daniel -Jízdenku lze použít po stejné trase i pro jiné vlakové spojení v tentýž den platnosti. -Rezervace místa platí pouze pro uvedené vlaky. - Kód transakce: - Z39230 - Kód nepřehýbejte! / Do not fold the barcode! - Barcode nicht knicken! -Reklama -Šťastnou cestu vlakem přejí České dráhy, Váš osobní dopravce. Strana 1/1 diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_one-leg-return-international.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_one-leg-return-international.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_one-leg-return-international.json +++ /dev/null @@ -1,58 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalStation": { - "@type": "TrainStation", - "name": "Brno hl.n." - }, - "arrivalTime": "2027-11-15T14:19:00", - "departurePlatform": "2", - "departureStation": { - "@type": "TrainStation", - "name": "Berlin Hbf (tief)" - }, - "departureTime": "2027-11-15T06:46:00", - "trainNumber": "EC 171" - }, - "reservationNumber": "XXX007", - "reservedTicket": { - "@type": "Ticket", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "105", - "seatSection": "258" - } - } - }, - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalPlatform": "6", - "arrivalStation": { - "@type": "TrainStation", - "name": "Berlin Hbf (tief)" - }, - "arrivalTime": "2027-11-17T21:15:00", - "departureStation": { - "@type": "TrainStation", - "name": "Brno hl.n." - }, - "departureTime": "2027-11-17T13:39:00", - "trainNumber": "EC 170" - }, - "reservationNumber": "XXX007", - "reservedTicket": { - "@type": "Ticket", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "62", - "seatSection": "256" - } - } - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_one-leg-return-international.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_one-leg-return-international.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_one-leg-return-international.txt +++ /dev/null @@ -1,56 +0,0 @@ - Online-Ticket Bitte auf A4 ausdrucken - IC/EC Fahrkarte UMTAUSCH/ERSTATTUNG KOSTEN- - CIV 1080 Normalpreis PFLICHTIG AB 1.GELTUNGSTAG 1 Erwachsener - Gültigkeit: ab 15.11.2027 - 14.12.2027 - VON ->NACH -IC/EC Berlin ->Brno 2 -IC/EC Brno ->Berlin - VIA: <1080>BGS*(BKH/BWK)*BSFL*ZS*DOKI*ELW*DD*BSU*Schöna(Gr)<1154>Usti - nad Labem*Praha*(Havlickuv Brod/C.Trebova) - Normalpreis - 1 BC 50 1 RAILPLUS - Zahlungspositionen und Preis Hinfahrt: - Positionen Preis Mwst D: 19% Zertifikat: ABCD 1234 QVZ - IC/EC Fahrkarte 1 999,20€ 99,00€ 9,18€ Gültig ab: 15.11.2027 - Reservierungen 2 9,00€ - Summe 999,20€ 99,00€ 9,18€ - Kreditkartenzahlung - Zangenabdruck - Betrag 999,20€ VU-Nr 4556123419 Transaktions-Nr 123456 - Datum 13.11.2027 Gen-Nr 012343 Rückfahrt: - Zertifikat: ABCD 1234 C5P - Ihre Kreditkarte wurde mit dem oben genannten Betrag belastet. Die Buchung Ihres - Online-Tickets erfolgte am 13.11.2027. DB Fernverkehr AG/DB Regio AG, Gültig ab: 15.11.2027 - Stephensonstr. 1, 60326 Frankfurt, Steuernummer: 045 231 28552. - Ihre Reiseverbindung und Reservierung Hinfahrt am 15.11.2027 Zangenabdruck - Halt Datum Zeit Gleis Fahrt/Reservierung Herr John Doe - Berlin Hbf (tief) 15.11. ab 06:46 2 EC 171, 1 Sitzplatz, Wg. 258, ID-Karte: BahnCard 1234 - Brno hl.n. 15.11. an 14:19 Pl. 105, 1 Fenster, Abteil, Auftragsnummer: XXX007 - Nichtraucher - Ihre Reiseverbindung und Reservierung Rückfahrt am 17.11.2027 - Halt Datum Zeit Gleis Fahrt/Reservierung - Brno hl.n. 17.11. ab 13:39 EC 170, 1 Sitzplatz, Wg. 256, - Berlin Hbf (tief) 17.11. an 21:15 6 Pl. 62, 1 Fenster, Großraum, - Nichtraucher - Barcode bitte nicht knicken! - XXX007 Seite 1 / 2 -Hinweise: -- Die Fahrkarte muss ausgedruckt vorliegen und gilt nur zusammen mit der beim Kauf angegebenen - eigenen gültigen Identifizierungskarte -- Bei Normalpreisen auch in anderen Zügen als in der Reiseverbindung angegeben innerhalb der - Geltungsdauer gültig (ggf. Aufpreis für anderen Weg erforderlich) -- Erstattung oder Rücknahme über www.bahn.de, in DB Reisezentren oder die in Ihrer - Auftragsbestätigung angegebene Serviceadresse. Keine Erstattung oder Rücknahme in Reisebüros -- Das Online-Ticket gilt nur für den unter "Fahrkarte" angegebenen Reiseabschnitt. Die Übersicht "Ihre - Reiseverbindung" enthält ggf. Reiseinformationen zu Teilstrecken (z.B. mit dem Bus), für die ein - weiteres Ticket erforderlich ist. -- Wenn Ihr Ticket die City-Option beinhaltet, gilt diese nur am Ankunftstag der Hinfahrt bzw. am - Abfahrtstag der Rückfahrt (Reisetage wie unter "Ihre Reiseverbindung" angegeben). Die Hinfahrt - muss durch Zangenabdruck entwertet sein. -- Es gelten die nationalen und internationalen Beförderungsbedingungen der jeweiligen Beförderer - bzw. innerhalb von Verkehrsverbünden und Tarifgemeinschaften deren Beförderungsbedingungen. - Den jeweiligen Beförderer finden Sie unter: www.DieBefoerderer.de bzw. www.bahn.de/agb . -Mehr Information gibt es unter www.bahn.de/onlineticket. Informieren Sie sich unter www.bahn.de/ -reiseplan zeitnah über Ihre Verbindung. Wir danken Ihnen für Ihre Buchung und wünschen Ihnen -eine angenehme Reise! -XXX007 Seite 2 / 2 diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_one-leg-return-no-seat.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_one-leg-return-no-seat.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_one-leg-return-no-seat.json +++ /dev/null @@ -1,44 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalPlatform": "12", - "arrivalStation": { - "@type": "TrainStation", - "name": "Osnabrück Hbf" - }, - "arrivalTime": "2027-02-10T11:51:00", - "departurePlatform": "13", - "departureStation": { - "@type": "TrainStation", - "name": "Berlin Hbf" - }, - "departureTime": "2027-02-10T08:37:00", - "trainNumber": "IC 148" - }, - "reservationNumber": "XXX007" - }, - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalPlatform": "11", - "arrivalStation": { - "@type": "TrainStation", - "name": "Berlin Hbf" - }, - "arrivalTime": "2027-02-12T19:19:00", - "departurePlatform": "11", - "departureStation": { - "@type": "TrainStation", - "name": "Osnabrück Hbf" - }, - "departureTime": "2027-02-12T16:08:00", - "trainNumber": "IC 147" - }, - "reservationNumber": "XXX007" - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_one-leg-return-no-seat.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_one-leg-return-no-seat.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_one-leg-return-no-seat.txt +++ /dev/null @@ -1,58 +0,0 @@ - Online-Ticket - Bitte auf A4 ausdrucken - Barcode bitte nicht knicken! -IC/EC Fahrkarte - Gültigkeit: 10.02.2027 - 09.03.2027 Hinfahrt bis 11.02.2027 -Rückfahrt an 2 aufeinander folgenden Tagen innerhalb der Gültigkeit -Normalpreis (Hin- und Rückfahrt) -Klasse: 2 -Erw: 1, mit 1 BC50 -Hinfahrt: Berlin Osnabrück+City, mit IC/EC -Rückfahrt: Osnabrück+City Berlin, mit IC/EC -Über: VIA: BGS*(MD*EILS/SDL)*H*(HF*BI/BUEN) -15 EUR ENTGELT FÜR UMTAUSCH/ERSTATTUNG AB 1. GELTUNGSTAG -Zahlungspositionen und Preis - Hinfahrt: -Positionen Preis Mwst D: 19% Zertifikat: 1234 ABCD UPY -IC/EC Fahrkarte 1 99,00€ 99,00€ 99,34€ Gültig ab: 10.02.2027 -Summe 99,00€ 99,00€ 99,34€ -Kreditkartenzahlung - Zangenabdruck -Betrag 99,00€ VU-Nr 1234123419 Transaktions-Nr 123123 Rückfahrt: -Datum 08.02.2027 Gen-Nr 010123 Zertifikat: 1234 ABCD 5Q9 -Ihre Kreditkarte wurde mit dem oben genannten Betrag belastet. Die Buchung Ihres Gültig ab: 10.02.2027 -Online-Tickets erfolgte am 08.02.2027. DB Fernverkehr AG/DB Regio AG, -Stephensonstr. 1, 60326 Frankfurt, Steuernummer: 045 231 28552. Zangenabdruck - Herr John Doe - ID-Karte: BahnCard 1234 - Auftragsnummer: XXX007 -Ihre Reiseverbindung und Reservierung Hinfahrt am 10.02.2027 -Halt Datum Zeit Gleis Fahrt Reservierung -Berlin Hbf 10.02. ab 08:37 13 IC 148 -Osnabrück Hbf 10.02. an 11:51 12 -Ihre Reiseverbindung und Reservierung Rückfahrt am 12.02.2027 -Halt Datum Zeit Gleis Fahrt Reservierung -Osnabrück Hbf 12.02. ab 16:08 11 IC 147 -Berlin Hbf 12.02. an 19:19 11 -Hinweise: -- Die Fahrkarte muss ausgedruckt vorliegen und gilt nur zusammen mit der beim Kauf angegebenen eigenen gültigen Identifizierungskarte -- Bei Normalpreisen auch in anderen Zügen als in der Reiseverbindung angegeben innerhalb der Geltungsdauer gültig (ggf. Aufpreis für anderen - Weg erforderlich) -- Erstattung oder Rücknahme über www.bahn.de, in DB ReiseZentren oder die in Ihrer Auftragsbestätigung angegebene Serviceadresse. Keine - Erstattung oder Rücknahme in Reisebüros -- Das Online-Ticket gilt nur für den unter "Fahrkarte" angegebenen Reiseabschnitt. Die Übersicht "Ihre Reiseverbindung" enthält ggf. - Reiseinformationen zu Teilstrecken (z.B. mit dem Bus), für die ein weiteres Ticket erforderlich ist -- Wenn Ihr Ticket die City-Option beinhaltet, gilt diese nur am Ankunftstag der Hinfahrt bzw. am Abfahrtstag der Rückfahrt (Reisetage wie unter - "Ihre Reiseverbindung" angegeben) -- Für Fahrten im City-Gebiet mit City-Ticket oder City mobil muss die Echtheit des Online-Tickets durch den Zangenabdruck des Zugbegleiters - bestätigt werden -- Es gelten die Beförderungsbedingungen der DB AG bzw. besondere Regelungen für bestimmte Strecken und Angebote (z.B. innerhalb von - Verkehrsverbünden, Tarifgemeinschaften, Ländertarife). -Mehr Information gibt es unter www.bahn.de/onlineticket. Wir danken Ihnen für Ihre Buchung und wünschen Ihnen eine angenehme Reise! - Aktuelle - Infos aufs - Handy! - Fahrpläne, Pünktlichkeit, - Ticketbuchung und mehr! - m.bahn.de -XXX007 Seite 1 / 1 diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_one-leg-single-international.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_one-leg-single-international.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_one-leg-single-international.json +++ /dev/null @@ -1,30 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalPlatform": "6", - "arrivalStation": { - "@type": "TrainStation", - "name": "Berlin Hbf (tief)" - }, - "arrivalTime": "2027-09-12T21:15:00", - "departureStation": { - "@type": "TrainStation", - "name": "Brno hl.n." - }, - "departureTime": "2027-09-12T13:39:00", - "trainNumber": "EC 170" - }, - "reservationNumber": "XXX007", - "reservedTicket": { - "@type": "Ticket", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "71", - "seatSection": "256" - } - } - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_one-leg-single-international.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_one-leg-single-international.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_one-leg-single-international.txt +++ /dev/null @@ -1,52 +0,0 @@ - Online-Ticket Bitte auf A4 ausdrucken - IC/EC Fahrkarte UMT./ERSTATT. KOSTENPFLICHTIG; - CIV 1080 Europa-Spezial BIS 1 TAG VOR 1.GELTUNGSTAG 1 Erwachsener - DB: GILT NUR FÜR EINGETRAGENE ZÜGE UND REISETAGE(ZUGBINDUNG) - Gültigkeit: ab 12.09.2027 - 26.09.2027 NV (S/RB/RE/IRE) - XX - VON ->NACH XX -IC/EC Brno ->Berlin 05 T:05 2 - VIA: <1154>(C.Trebova/Havlickuv Brod)*Praha*Usti nad Labem*Schöna(Gr) - <1080>(12.09.2027)SchönaG EC170 - Europa-Spezial - Europa-Spez.Tschech. - ------- . - Zahlungspositionen und Preis Hinfahrt: - Positionen Preis Mwst D: 19% Mwst D: 7% Zertifikat: ABCD 1234 V6Q - IC/EC Fahrkarte 1 99,00€ 99,00€ 9,83€ Gültig ab: 12.09.2027 - Reservierung 1 9,00€ - Summe 99,00€ 99,00€ 9,83€ - Kreditkartenzahlung - Zangenabdruck - Betrag 99,00€ VU-Nr 1234123419 Transaktions-Nr 123123 - Datum 29.08.2027 Gen-Nr 051509 Herr John Doe - Ihre Kreditkarte wurde mit dem oben genannten Betrag belastet. Die Buchung Ihres ID-Karte: BahnCard 1234 - Online-Tickets erfolgte am 29.08.2027. DB Fernverkehr AG/DB Regio AG, Auftragsnummer: XXX007 - Stephensonstr. 1, 60326 Frankfurt, Steuernummer: 29/550/00001. - Ihre Reiseverbindung und Reservierung Hinfahrt am 12.09.2027 - Halt Datum Zeit Gleis Produkte/Reservierung - Brno hl.n. 12.09. ab 13:39 EC 170, 2 Sitzplätze, Wg. 256, - Berlin Hbf (tief) 12.09. an 21:15 6 Pl. 71 73, 1 Fenster, 1 Gang, - Großraum, Nichtraucher - Wichtige Nutzungshinweise: - - Beauftragen Sie niemals Unbekannte mit der Buchung eines personalisierten Online-Tickets zu - vermeintlich besonders günstigen Preisen. Tickets werden nur zu dem aufgedruckten Originalpreis - ausgegeben. Mit der Nutzung eines solchen Online-Tickets erkennen Sie die Gültigkeit des durch - den Buchenden für Sie abgeschlossenen Beförderungsvertrags zu dem aufgedruckten Preis an - - Die Fahrkarte muss ausgedruckt vorliegen und gilt nur zusammen mit der beim Kauf angegebenen - eigenen gültigen Identifizierungskarte - - Bei Normalpreisen auch in anderen Zügen als in der Reiseverbindung angegeben innerhalb der - Geltungsdauer gültig (ggf. Aufpreis für anderen Weg erforderlich) - - Erstattung oder Rücknahme über www.bahn.de, in DB Reisezentren oder die in Ihrer - Auftragsbestätigung angegebene Serviceadresse. Keine Erstattung oder Rücknahme in Reisebüros - - Das Online-Ticket gilt nur für den unter "Fahrkarte" angegebenen Reiseabschnitt. Die Übersicht "Ihre - Reiseverbindung" enthält ggf. Reiseinformationen zu Teilstrecken (z.B. mit dem Bus), für die ein - weiteres Ticket erforderlich ist. - - Es gelten die nationalen und internationalen Beförderungsbedingungen der jeweiligen Beförderer - bzw. innerhalb von Verkehrsverbünden und Tarifgemeinschaften deren Beförderungsbedingungen. - Den jeweiligen Beförderer finden Sie unter: www.DieBefoerderer.de bzw. www.bahn.de/agb . - Bitte informieren Sie sich kurz vor Ihrer Reise über mögliche Änderungen Ihrer Reisedaten unter - www.bahn.de/reiseplan oder mobil über die App DB Navigator. Achten Sie auch auf Informationen Barcode bitte nicht knicken! - und Ansagen im Zug und am Bahnhof. Wir danken Ihnen für Ihre Buchung und wünschen Ihnen - eine angenehme Reise! - XXX007 Seite 1 / 1 diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_two-leg-return.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_two-leg-return.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_two-leg-return.json +++ /dev/null @@ -1,101 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalPlatform": "6 D-G", - "arrivalStation": { - "@type": "TrainStation", - "name": "Köln Hbf" - }, - "arrivalTime": "2027-11-03T12:09:00", - "departurePlatform": "4A-D", - "departureStation": { - "@type": "TrainStation", - "name": "Berlin Hbf (tief)" - }, - "departureTime": "2027-11-03T07:49:00", - "trainNumber": "ICE 954" - }, - "reservationNumber": "XXX007", - "reservedTicket": { - "@type": "Ticket", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "61", - "seatSection": "34" - } - } - }, - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalPlatform": "3", - "arrivalStation": { - "@type": "TrainStation", - "name": "Somewhere(Specific)" - }, - "arrivalTime": "2027-11-03T12:45:00", - "departurePlatform": "10 A-B", - "departureStation": { - "@type": "TrainStation", - "name": "Köln Hbf" - }, - "departureTime": "2027-11-03T12:17:00", - "trainNumber": "S0" - }, - "reservationNumber": "XXX007" - }, - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalPlatform": "14", - "arrivalStation": { - "@type": "TrainStation", - "name": "Düsseldorf Hbf" - }, - "arrivalTime": "2027-11-04T14:28:00", - "departurePlatform": "3", - "departureStation": { - "@type": "TrainStation", - "name": "Somewhere(Specific)" - }, - "departureTime": "2027-11-04T14:06:00", - "trainNumber": "S0" - }, - "reservationNumber": "XXX007" - }, - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalStation": { - "@type": "TrainStation", - "name": "Berlin Hbf (tief)" - }, - "arrivalTime": "2027-11-04T19:27:00", - "departurePlatform": "19", - "departureStation": { - "@type": "TrainStation", - "name": "Düsseldorf Hbf" - }, - "departureTime": "2027-11-04T14:52:00", - "trainNumber": "ICE 641" - }, - "reservationNumber": "XXX007", - "reservedTicket": { - "@type": "Ticket", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "85", - "seatSection": "22" - } - } - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_two-leg-return.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_two-leg-return.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_two-leg-return.txt +++ /dev/null @@ -1,54 +0,0 @@ - Online-Ticket - Barcode bitte nicht knicken! -ICE Fahrkarte - Fahrtantritt Hinfahrt: 03.11.2027 - Fahrtantritt Rückfahrt: 04.11.2027 -City-Rückfahrt am 04.11.17 -Flexpreis (Hin- und Rückfahrt) -Klasse: 2 -Erw: 1, mit 1 BC50 -Hinfahrt: Berlin+City Somewhere(Specific), mit ICE -Rückfahrt: Somewhere(Specific) Berlin+City, mit ICE -Über: VIA: H: H*(BI/OS)*K R: D*(OS/BI)*H -Umtausch/Erstattung kostenlos bis 1 Tag vor Reiseantritt (Hinfahrt). - Hinfahrt: -Zahlungspositionen und Preis Gültig ab: 03.11.2027 -Positionen Preis MwSt (D) 19% MwSt D: 7% -ICE Fahrkarte 1 999,99€ 999,00€ 99,84€ Zangenabdruck -Reservierungen 2 9,00€ 9,00€ 9,44€ Rückfahrt: -Summe 999,00€ 999,00€ 99,28€ Gültig ab: 04.11.2027 -Lastschriftzahlung -Betrag 999,99€ Bank Big Money Bank - Zangenabdruck -Datum 02.11.2027 IBAN DExxxxxxxxxxxxxxxxxxxx - Herr John Doe -Der oben genannte Betrag wird von Ihrem Konto eingezogen. Die Buchung Ihres -Online-Tickets erfolgte am 02.11.2027 13:59 Uhr. DB Fernverkehr AG/DB Regio AG, Auftragsnummer: XXX007 -Stephensonstr. 1, 60326 Frankfurt, Steuernummer: 29/001/60002. -Ihre Reiseverbindung und Reservierung Hinfahrt am 03.11.2027 -Halt Datum Zeit Gleis Produkte Reservierung -Berlin Hbf (tief) 03.11. ab 07:49 4A-D ICE 954 1 Sitzplatz, Wg. 34, Pl. 61, 1 Fenster, Großraum, -Köln Hbf 03.11. an 12:09 6 D-G Nichtraucher, Res.Nr. 1234 1013 0000 76 -Köln Hbf 03.11. ab 12:17 10 A-B S0 -Somewhere(Specific) 03.11. an 12:45 3 -Ihre Reiseverbindung und Reservierung Rückfahrt am 04.11.2027 -Halt Datum Zeit Gleis Produkte Reservierung -Somewhere(Specific) 04.11. ab 14:06 3 S0 -Düsseldorf Hbf 04.11. an 14:28 14 -Düsseldorf Hbf 04.11. ab 14:52 19 ICE 641 1 Sitzplatz, Wg. 22, Pl. 85, 1 Fenster, Großraum, -Berlin Hbf (tief) 04.11. an 19:27 Nichtraucher, - Ruhebereich, Res.Nr. 1234 1014 0000 04 -Wichtige Nutzungshinweise: -- Ihre Fahrkarte gilt nur zusammen mit einem amtlichen Lichtbildausweis (z.B. Personalausweis) oder Ihrer BahnCard. -- Mit Ihrer Fahrkarte zum Flexpreis können Sie jeden Zug der gewählten Verbindung nutzen: mit einer IC/EC-Fahrkarte alle IC- und EC-Züge, mit - einer ICE-Fahrkarte auch alle anderen Züge. -- Das Online-Ticket gilt nur für den unter "Fahrkarte" angegebenen Reiseabschnitt. Die Übersicht "Ihre Reiseverbindung" enthält gegebenenfalls - Reiseinformationen zu Teilstrecken (z.B. Bus oder Straßenbahn), für die eine weitere Fahrkarte erforderlich sein kann. -- Wenn Ihr Ticket den Zusatz "+City" oder "City mobil" zeigt, gilt dieser nur am Tag der Hinfahrt bzw. am Tag der Rückfahrt. -- Es gelten die nationalen und internationalen Beförderungsbedingungen der DB AG. Innerhalb von Verkehrsverbünden und Tarifgemeinschaften - gelten deren Bedingungen. Alle Bedingungen finden Sie unter: www.bahn.de/agb und www.diebefoerderer.de. -Ihre Reisedaten können sich kurzfristig durch Bauarbeiten oder andere erforderliche Fahrplananpassungen ändern. -Bitte informieren Sie sich kurz vor Ihrer Reise über mögliche Änderungen Ihrer Reisedaten unter www.bahn.de/reiseplan oder mobil über die -App DB Navigator. Achten Sie auch auf Informationen und Ansagen im Zug und am Bahnhof. Wir danken Ihnen für Ihre Buchung und wünschen -Ihnen eine angenehme Reise!. -XXX007 Seite 1 / 1 diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_two-leg-single.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_two-leg-single.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_two-leg-single.json +++ /dev/null @@ -1,52 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalPlatform": "14", - "arrivalStation": { - "@type": "TrainStation", - "name": "Düsseldorf Hbf" - }, - "arrivalTime": "2026-12-28T15:28:00", - "departurePlatform": "3", - "departureStation": { - "@type": "TrainStation", - "name": "Somewhere(Specific)" - }, - "departureTime": "2026-12-28T15:06:00", - "trainNumber": "S0" - }, - "reservationNumber": "XXX007" - }, - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalPlatform": "6D-G", - "arrivalStation": { - "@type": "TrainStation", - "name": "Berlin Hbf (tief)" - }, - "arrivalTime": "2026-12-28T20:09:00", - "departurePlatform": "19", - "departureStation": { - "@type": "TrainStation", - "name": "Düsseldorf Hbf" - }, - "departureTime": "2026-12-28T15:52:00", - "trainNumber": "ICE 943" - }, - "reservationNumber": "XXX007", - "reservedTicket": { - "@type": "Ticket", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "66", - "seatSection": "24" - } - } - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_two-leg-single.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_two-leg-single.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/deutschebahn_two-leg-single.txt +++ /dev/null @@ -1,60 +0,0 @@ - Online-Ticket - Bitte auf A4 ausdrucken - Barcode bitte nicht knicken! -ICE Fahrkarte - Fahrtantritt am 28.12.2026 -Flexpreis (Einfache Fahrt) -Klasse: 2 -Erw: 1, mit 1 BC50 -Hinfahrt: Somewhere(Specific) Berlin+City, mit ICE -Über: VIA: D*(OS/BI)*H -Zahlungspositionen und Preis -Positionen Preis MwSt (D) 19% MwSt D: 7% -ICE Fahrkarte 1 99,00€ 99,00€ 9,10€ -Reservierung 1 9,50€ 9,50€ 9,72€ - Hinfahrt: -Summe 99,50€ 99,50€ 9,82€ - Gültig ab: 28.12.2026 -Lastschriftzahlung -Betrag 99,50€ Bank Big Money Bank -Datum 27.12.2026 IBAN DExxxxxxxxxxxxxxxxxxxx Zangenabdruck -Der oben genannte Betrag wird von Ihrem Konto eingezogen. Die Buchung Ihres Herr John Doe -Online-Tickets erfolgte am 27.12.2026 10:03 Uhr. DB Fernverkehr AG/DB Regio AG, Auftragsnummer: XXX007 -Stephensonstr. 1, 60326 Frankfurt, Steuernummer: 29/001/60002. -Ihre Reiseverbindung und Reservierung Hinfahrt am 28.12.2026 -Halt Datum Zeit Gleis Produkte Reservierung -Somewhere(Specific) 28.12. ab 15:06 3 S0 -Düsseldorf Hbf 28.12. an 15:28 14 -Düsseldorf Hbf 28.12. ab 15:52 19 ICE 943 1 Sitzplatz, Wg. 24, Pl. 66, 1 Fenster, Großraum, -Berlin Hbf (tief) 28.12. an 20:09 6D-G Nichtraucher, Res.Nr. 8051 1002 8138 40 -Wichtige Nutzungshinweise: -- Beauftragen Sie niemals Unbekannte mit der Buchung eines personalisierten Online-Tickets zu vermeintlich besonders günstigen Preisen. - Tickets werden nur zu dem aufgedruckten Originalpreis ausgegeben. Mit der Nutzung eines solchen Online-Tickets erkennen Sie die Gültigkeit - des durch den Buchenden für Sie abgeschlossenen Beförderungsvertrags zu dem aufgedruckten Preis an -- Die Fahrkarte muss ausgedruckt vorliegen und gilt nur zusammen mit einem Personalausweis, Reisepass, elektronischen Aufenthaltstitel, BüMA - oder der BahnCard des Fahrkarteninhabers. -- Bei Tickets mit BahnCard-Rabatt müssen Sie eine gültige BahnCard vorlegen können -- Bei Flexpreisen auch in anderen Zügen als in der Reiseverbindung angegeben innerhalb der Geltungsdauer gültig (ggf. Aufpreis für anderen - Weg erforderlich). Der Fahrtantritt bei Flexpreisen Inland muss am angegebenen Fahrtantritt erfolgen. Soll der Tag des Fahrtantritts geändert - werden, so ist ein Umtausch erforderlich -- Erstattung oder Rücknahme über www.bahn.de, in DB Reisezentren oder die in Ihrer Auftragsbestätigung angegebene Serviceadresse. Keine - Erstattung oder Rücknahme in Reisebüros -- Das Online-Ticket gilt nur für den unter "Fahrkarte" angegebenen Reiseabschnitt. Die Übersicht "Ihre Reiseverbindung" enthält ggf. - Reiseinformationen zu Teilstrecken (z.B. mit dem Bus), für die ein weiteres Ticket erforderlich ist -- Wenn Ihr Ticket den Zusatz "+City" oder "City mobil" beinhaltet, gilt dieser nur am Tag der Hinfahrt bzw. am Tag der Rückfahrt (Reisetage wie - unter "Ihre Reiseverbindung" angegeben) -- Es gelten die nationalen und internationalen Beförderungsbedingungen der jeweiligen Beförderer bzw. innerhalb von Verkehrsverbünden und - Tarifgemeinschaften deren Beförderungsbedingungen. Den jeweiligen Beförderer finden Sie unter: www.DieBefoerderer.de bzw. www.bahn.de/ - agb . -Ihre Reisedaten können sich kurzfristig durch Bauarbeiten oder andere erforderliche Fahrplananpassungen ändern -Bitte informieren Sie sich kurz vor Ihrer Reise über mögliche Änderungen Ihrer Reisedaten unter www.bahn.de/reiseplan oder mobil über die -App DB Navigator. Achten Sie auch auf Informationen und Ansagen im Zug und am Bahnhof. Wir danken Ihnen für Ihre Buchung und wünschen -Ihnen eine angenehme Reise! - Aktuelle - Infos aufs - Handy! - Fahrpläne, Pünktlichkeit, - Alternativen zur Fahrt - und mehr! - m.bahn.de -XXX007 Seite 1 / 1 diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/eurowings_1.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/eurowings_1.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/eurowings_1.json +++ /dev/null @@ -1,50 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "4U", - "name": "Germanwings" - }, - "arrivalAirport": { - "@type": "Airport", - "name": "London Heathrow" - }, - "arrivalTime": "2017-06-15T13:50:00", - "departureAirport": { - "@type": "Airport", - "name": "Berlin-Tegel" - }, - "departureTime": "2017-06-15T12:55:00", - "flightNumber": "8462" - }, - "reservationNumber": "ABC123" - }, - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "4U", - "name": "Germanwings" - }, - "arrivalAirport": { - "@type": "Airport", - "name": "Berlin-Tegel" - }, - "arrivalTime": "2017-06-18T22:00:00", - "departureAirport": { - "@type": "Airport", - "name": "London Heathrow" - }, - "departureTime": "2017-06-18T19:10:00", - "flightNumber": "8465" - }, - "reservationNumber": "ABC123" - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/eurowings_1.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/eurowings_1.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/eurowings_1.txt +++ /dev/null @@ -1,57 +0,0 @@ - Eurowings - -PASSENGER RECEIPT - Confirmation of Booking - -MR John Doe 23.04.2017 | 11:10:45 Uhr - - -Street 5 -12345 City -Country - - -Dear MR John Doe, - -many thanks for booking your flight with us. -We wish you a pleasant flight. - -====================================================================== -YOUR BOOKING -====================================================================== - - Individual reservation code: ** ABC123 ** - (please state at check-in) - - Date of booking: 23.04.2017 11:09 - Date of change: 23.04.2017 11:09 - ----------------------------------------------------------------------- - ** FLIGHT DATA (TIMES ARE LOCAL TIMES) ** ----------------------------------------------------------------------- - - Flight: 15.06.2017 | 4U 8462 (X) - * operated by Germanwings - - Departure: 12:55 Berlin-Tegel - Arrival: 13:50 London Heathrow - - Flight: 18.06.2017 | 4U 8465 (K) - * operated by Germanwings - - Departure: 19:10 London Heathrow - Arrival: 22:00 Berlin-Tegel - ----------------------------------------------------------------------- - ** PASSENGER ** ----------------------------------------------------------------------- - - 1. Passenger: MR John Doe - Frequent Flyer Number: 123401234567890 - - -====================================================================== -FREE INFORMATION SERVICE -====================================================================== - - Stay up to date on your flight status. Sign up with your mobile[...] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/fcmtravel_1.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/fcmtravel_1.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/fcmtravel_1.json +++ /dev/null @@ -1,54 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "BT", - "name": "Air Baltic" - }, - "arrivalAirport": { - "@type": "Airport", - "iataCode": "RIX", - "name": "Riga" - }, - "arrivalTime": "2017-11-05T11:35:00", - "departureAirport": { - "@type": "Airport", - "iataCode": "TXL", - "name": "Tegel" - }, - "departureTime": "2017-11-05T08:55:00", - "flightNumber": "212" - }, - "reservationNumber": "ABCDEF" - }, - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "BT", - "name": "Air Baltic" - }, - "arrivalAirport": { - "@type": "Airport", - "iataCode": "TXL", - "name": "Tegel" - }, - "arrivalTime": "2017-11-10T08:20:00", - "departureAirport": { - "@type": "Airport", - "iataCode": "RIX", - "name": "Riga" - }, - "departureTime": "2017-11-10T07:35:00", - "flightNumber": "211" - }, - "reservationNumber": "ABCDEF" - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/fcmtravel_1.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/fcmtravel_1.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/fcmtravel_1.txt +++ /dev/null @@ -1,54 +0,0 @@ -===================================================================================== -Thank you for booking with Travellink Corporate -===================================================================================== - -Booking reference: ABCDEF - - - - - -Reserved by: Travel Agent -Company: My Company -Address: Street 30 - 12345 City - -Traveller: John Doe - - -===================================================================================== -FLIGHT Airline booking reference: ABCDEF - BT -===================================================================================== - - Status: Confirmed -OUTBOUND Berlin - Riga -Flight: BT212, Air Baltic -Operated by: Air Baltic -Date: Sun 5 Nov 2017 -Departure: 08:55 Tegel(TXL), Berlin, Germany -Date: Sun 5 Nov 2017 -Arrival: 11:35 Riga(RIX), Riga, Latvia -Cabin class: Economy -Duration: - - Status: Confirmed -HOMEBOUND Riga - Berlin -Flight: BT211, Air Baltic -Operated by: Air Baltic -Date: Fri 10 Nov 2017 -Departure: 07:35 Riga(RIX), Riga, Latvia -Date: Fri 10 Nov 2017 -Arrival: 08:20 Tegel(TXL), Berlin, Germany -Cabin class: Economy -Duration: - Departure and arrival times displayed are always in local time. - Please note! Verify your flight departure terminal before you leave for the airport. - - - - -------------------------------------------------------------------------------------- -Booking information -------------------------------------------------------------------------------------- - -Check-in: Use Booking reference and your surname (Passport/National ID) for check-in at the airport counter or at the airlines website. diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/fcmtravel_2.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/fcmtravel_2.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/fcmtravel_2.json +++ /dev/null @@ -1,106 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "AB", - "name": "Air Berlin" - }, - "arrivalAirport": { - "@type": "Airport", - "iataCode": "DUS", - "name": "International Airport" - }, - "arrivalTime": "2016-10-17T12:00:00", - "departureAirport": { - "@type": "Airport", - "iataCode": "TXL", - "name": "Tegel" - }, - "departureTime": "2016-10-17T10:50:00", - "flightNumber": "6439" - }, - "reservationNumber": "XXX007" - }, - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "AB", - "name": "Air Berlin" - }, - "arrivalAirport": { - "@type": "Airport", - "iataCode": "SFO", - "name": "San Francisco International" - }, - "arrivalTime": "2016-10-17T15:55:00", - "departureAirport": { - "@type": "Airport", - "iataCode": "DUS", - "name": "International Airport" - }, - "departureTime": "2016-10-17T13:20:00", - "flightNumber": "7392" - }, - "reservationNumber": "XXX007" - }, - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "AA", - "name": "American Airlines" - }, - "arrivalAirport": { - "@type": "Airport", - "iataCode": "ORD", - "name": "O Hare International" - }, - "arrivalTime": "2016-10-22T14:00:00", - "departureAirport": { - "@type": "Airport", - "iataCode": "PDX", - "name": "Portland International" - }, - "departureTime": "2016-10-22T08:00:00", - "flightNumber": "086" - }, - "reservationNumber": "XXX007" - }, - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "AB", - "name": "Air Berlin" - }, - "arrivalAirport": { - "@type": "Airport", - "iataCode": "TXL", - "name": "Tegel" - }, - "arrivalTime": "2016-10-23T07:00:00", - "departureAirport": { - "@type": "Airport", - "iataCode": "ORD", - "name": "O Hare International" - }, - "departureTime": "2016-10-22T15:25:00", - "flightNumber": "7421" - }, - "reservationNumber": "XXX007" - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/fcmtravel_2.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/fcmtravel_2.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/fcmtravel_2.txt +++ /dev/null @@ -1,72 +0,0 @@ -===================================================================================== -Thank you for booking with Travellink Corporate -===================================================================================== - - -Travellink booking reference: XXX007 - - - - - -Reserved by: Booking Agent -Company: My Company -Address: Street 30 - 12345 City - -Traveller: John Doe -Traveller: Jane Doe - -===================================================================================== - -===================================================================================== - - Status: Confirmed -OUTBOUND Berlin - San Francisco -Flight: AB6439, Air Berlin -Date: Mon 17 Oct 2016 -Departure: 10:50 Tegel(TXL), Berlin, Germany -Date: Mon 17 Oct 2016 -Arrival: 12:00 International Airport(DUS), Duesseldorf, Germany -Cabin class: Economy - - Status: Confirmed -Flight: AB7392, Air Berlin -Date: Mon 17 Oct 2016 -Departure: 13:20 International Airport(DUS), Duesseldorf, Germany -Date: Mon 17 Oct 2016 -Arrival: 15:55 San Francisco International(SFO), San Francisco, United States Of America - Terminal I -Cabin class: Economy -Duration: 14h 05min - - Status: Confirmed -HOMEBOUND Portland - Berlin -Flight: AA086, American Airlines -Date: Sat 22 Oct 2016 -Departure: 08:00 Portland International(PDX), Portland, United States Of America -Date: Sat 22 Oct 2016 -Arrival: 14:00 O Hare International(ORD), Chicago, United States Of America - Terminal 3 -Cabin class: Economy - - Status: Confirmed -Flight: AB7421, Air Berlin -Date: Sat 22 Oct 2016 -Departure: 15:25 O Hare International(ORD), Chicago, United States Of America - Terminal 3 -Date: Sun 23 Oct 2016 -Arrival: 07:00 Tegel(TXL), Berlin, Germany -Cabin class: Economy -Duration: 14h 00min - Departure and arrival times displayed are always in local time. - Please note! Verify your flight departure terminal before you leave for the airport. - - - - -------------------------------------------------------------------------------------- -Booking information -------------------------------------------------------------------------------------- - -Check-in: Use Booking reference and your surname (Passport/National ID) for check-in at the airport counter or at the airlines website. diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/iberia_1.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/iberia_1.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/iberia_1.json +++ /dev/null @@ -1,105 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "IB", - "name": "Iberia Express" - }, - "arrivalAirport": { - "@type": "Airport", - "iataCode": "MAD", - "name": "Madrid" - }, - "arrivalTime": "2018-07-20T15:35:00", - "departureAirport": { - "@type": "Airport", - "iataCode": "TXL", - "name": "Berlin" - }, - "departureTime": "2018-07-20T12:25:00", - "flightNumber": "3677" - }, - "reservationNumber": "XXX007" - }, - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "IB", - "name": "Iberia Regional Air Nostrum" - }, - "arrivalAirport": { - "@type": "Airport", - "iataCode": "LEI", - "name": "Almeria" - }, - "arrivalTime": "2018-07-20T19:00:00", - "departureAirport": { - "@type": "Airport", - "iataCode": "MAD", - "name": "Madrid" - }, - "departureTime": "2018-07-20T17:50:00", - "flightNumber": "8588" - }, - "reservationNumber": "XXX007" - }, - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "IB", - "name": "Iberia Regional Air Nostrum" - }, - "arrivalAirport": { - "@type": "Airport", - "iataCode": "MAD", - "name": "Madrid" - }, - "arrivalTime": "2018-07-28T08:25:00", - "departureAirport": { - "@type": "Airport", - "iataCode": "LEI", - "name": "Almeria" - }, - "departureTime": "2018-07-28T07:15:00", - "flightNumber": "8603" - }, - "reservationNumber": "XXX007" - }, - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "IB" - }, - "arrivalAirport": { - "@type": "Airport", - "iataCode": "TXL", - "name": "Berlin" - }, - "arrivalTime": "2018-07-28T15:00:00", - "departureAirport": { - "@type": "Airport", - "iataCode": "MAD", - "name": "Madrid" - }, - "departureTime": "2018-07-28T12:00:00", - "flightNumber": "3186" - }, - "reservationNumber": "XXX007" - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/iberia_1.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/iberia_1.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/iberia_1.txt +++ /dev/null @@ -1,45 +0,0 @@ - Strichcode0752371401064KRAU - Ihres Flugscheins in den - Check-In Automaten einführen. - Insert the barcode into the check-in - machines. -Ihr E-Ticket und Reiseroutel -Your electronic ticket and itinerary. -Check-in erforderlich / Need to check in. -Passagierdaten /Passenger data -Name (Nicht übertragbar) /Name (not transferable) -DOE, JOHN -Ausweisdokument /Identity document Buchungsnummer /Booking code - XXX007 -Ticketnummer /Number -075-1234567890 -Flugdaten /Flight data -Ausgangspunkt/Zielort Flug Abflug Ankunft Nicht gültig Klasse - Tarif Freigepäck Flugstatus -Origin/Destination Flight Departure Arrival Not Valid Class - Fare Baggage Status - Von /From IB3677 20-Jul 20-Jul Vor dem /Before F 1PC / Bestätigt - Berlin (TXL) 12:25 15:35 20-Jul FNNN0C Confirmed - Nach /To Terminal 4 Nach /After - Madrid (MAD) 20-Jul - Durchgeführt von /Operated by - : Iberia Express - Von /From IB8588 20-Jul 20-Jul Vor dem /Before F 1 Stück- Bestätigt - Madrid (MAD) 17:50 19:00 20-Jul FNNN0C System /Pieces Confirmed - Nach /To Terminal 4 Nach /After - Almeria (LEI) 20-Jul - Durchgeführt von /Operated by - : Iberia Regional Air Nostrum - Von /From IB8603 28-Jul 28-Jul Vor dem /Before H 1 Stück- Bestätigt - Almeria (LEI) 07:15 08:25 28-Jul HDNN0C System /Pieces Confirmed - Nach /To Terminal 4 Nach /After - Madrid (MAD) 28-Jul - Durchgeführt von /Operated by - : Iberia Regional Air Nostrum - Von /From IB3186 28-Jul 28-Jul Vor dem /Before H 1 Stück- Bestätigt - Madrid (MAD) 12:00 15:00 28-Jul HDNN0C System /Pieces Confirmed - Nach /To Terminal 4S Nach /After - Berlin (TXL) 28-Jul -Einzelheiten zur Ticketausstellung /Ticket issue data -Ticketnummer /Number Ausstellungsdatum /Issue date Ausgestelltvon /Issued by -075-1234567890 05-Juni-2017 IBERIA LAE SA Operadora Unipersonal -Büronummer /Iss. Off. Code Steuernummer /Fiscal No. Ausstellungsort /Place of issue -12345678 A12345678 Spanien diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_bus_cs-one-leg-return.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_bus_cs-one-leg-return.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_bus_cs-one-leg-return.json +++ /dev/null @@ -1,58 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "BusReservation", - "modifyReservationUrl": "https://jizdenky.studentagency.cz/OnlineTicket?pam1=9876543210&pam2=0123456789", - "reservationFor": { - "@type": "BusTrip", - "arrivalStation": { - "@type": "BusStation", - "name": "Wien, Lassallestr./Praterstern" - }, - "arrivalTime": "2012-08-11T11:20:00", - "busName": "Praha → Vídeň", - "busNumber": "SA", - "departureStation": { - "@type": "BusStation", - "name": "Brno, AN u hotelu Grand" - }, - "departureTime": "2012-08-11T09:30:00" - }, - "reservationNumber": "0123456789", - "reservedTicket": { - "@type": "Ticket", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "51, 52, 55, 56" - } - } - }, - { - "@context": "http://schema.org", - "@type": "BusReservation", - "modifyReservationUrl": "https://jizdenky.studentagency.cz/OnlineTicket?pam1=9876543210&pam2=0123456789", - "reservationFor": { - "@type": "BusTrip", - "arrivalStation": { - "@type": "BusStation", - "name": "Brno, AN u hotelu Grand" - }, - "arrivalTime": "2012-08-12T00:30:00", - "busName": "Vídeň → Praha", - "busNumber": "SA", - "departureStation": { - "@type": "BusStation", - "name": "Wien, Lassallestr./Praterstern" - }, - "departureTime": "2012-08-11T22:40:00" - }, - "reservationNumber": "0123456789", - "reservedTicket": { - "@type": "Ticket", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "35, 36, 39, 40" - } - } - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_bus_cs-one-leg-return.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_bus_cs-one-leg-return.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_bus_cs-one-leg-return.txt +++ /dev/null @@ -1,44 +0,0 @@ -Elektronická jízdenka č. 0123456789 - -Počet cestujících (použité tarify): 4 (Dospělý, Dospělý, ISIC, ISIC) - - -Cesta tam -Datum Zastávka/Přestup Příjezd Odjezd Nást. Spoj Vůz/sedadla -So 11.8.12 Brno, AN u hotelu Grand 9:30 Praha → Vídeň (SA) 51, 52, 55, 56 - Wien, Lassallestr./Praterstern 11:20 - -Cesta zpět -Datum Zastávka/Přestup Příjezd Odjezd Nást. Spoj Vůz/sedadla -So 11.8.12 Wien, Lassallestr./Praterstern 22:40 Vídeň → Praha (SA) 35, 36, 39, 40 -Ne 12.8.12 Brno, AN u hotelu Grand 0:30 - -Cena: 1 443 CZK -Stornovací podmínky: více než 5 hodin: 0 %, méně než 5 hodin: nelze stornovat -Podmínky přerezervace: více než 5 hodin: 0 CZK, méně než 5 hodin: nelze přerezervovat - -Akce: Flexi (http://jizdenky.studentagency.cz/cs/ceniky/ceniky-podstranky/flexi-jizdenka.html) - -Důležité informace: -Zavazadla - bezplatně přepravujeme pro 1 cestujícího: -1 příruční zavazadlo (max. rozměry 15 x 25 x 35 cm) -a 1 zavazadlo v zavazadlovém prostoru do 30 kg a rozměrů 30 x 60 x 80 cm. -Poplatek za každé další zavazadlo/poplatek za nadrozměrné zavazadlo/poplatek za přepravu kola je 100 Kč/ 4 EUR. - -Dopravci: -SA - STUDENT AGENCY, s.r.o., IČO: 25317075, internet: www.studentagency.cz, telefon: +420 542 42 42 42 - - -Vaši jízdenku můžete spravovat zde https://jizdenky.studentagency.cz/OnlineTicket?pam1=9876543210&pam2=0123456789 (k přihlášení potřebujete číslo jízdenky) - - - -S pozdravem -STUDENT AGENCY Express -STUDENT AGENCY s.r.o. -www.studentagency.cz -tel: +420 841 101 101, +420 542 42 42 42, pro letenky +420 800 100 300 - --------------------------------------------------------------------------------- -STUDENT AGENCY express je online rezervační systém autobusové dopravy společnosti STUDENT AGENCY (http://www.studentagency.cz). -Pokud nechcete automaticky dostávat emaily o změnách v rezervacích, proveďte změnu v sekci nastavení. diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_bus_cs-one-leg-single.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_bus_cs-one-leg-single.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_bus_cs-one-leg-single.json +++ /dev/null @@ -1,30 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "BusReservation", - "modifyReservationUrl": "http://jizdenky.studentagency.cz/OnlineTicket?pam1=0987654321&pam2=0123456789", - "reservationFor": { - "@type": "BusTrip", - "arrivalStation": { - "@type": "BusStation", - "name": "Wien, SchwechatAirport Bbf." - }, - "arrivalTime": "2012-06-29T05:35:00", - "busName": "Praha → Vídeň", - "busNumber": "SA", - "departureStation": { - "@type": "BusStation", - "name": "Brno, AN u hotelu Grand" - }, - "departureTime": "2012-06-29T03:20:00" - }, - "reservationNumber": "0123456789", - "reservedTicket": { - "@type": "Ticket", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "43" - } - } - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_bus_cs-one-leg-single.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_bus_cs-one-leg-single.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_bus_cs-one-leg-single.txt +++ /dev/null @@ -1,39 +0,0 @@ -Elektronická jízdenka č. 0123456789 - -Počet cestujících (použité tarify): 1 (ISIC) - - -Cesta -Datum Zastávka/Přestup Příjezd Odjezd Nást. Spoj Vůz/sedadla -Pá 29.6.12 Brno, AN u hotelu Grand 3:20 Praha → Vídeň (SA) 43 - Wien, SchwechatAirport Bbf. 5:35 - -Cena: 272 CZK -Stornovací podmínky: více než 5 hodin: 0 %, méně než 5 hodin: nelze stornovat -Podmínky přerezervace: více než 5 hodin: 0 CZK, méně než 5 hodin: nelze přerezervovat - -Akce: Flexi (http://jizdenky.studentagency.cz/cs/ceniky/ceniky-podstranky/flexi-jizdenka.html) - -Důležité informace: -Zavazadla - bezplatně přepravujeme pro 1 cestujícího: -1 příruční zavazadlo (max. rozměry 15 x 25 x 35 cm) -a 1 zavazadlo v zavazadlovém prostoru do 30 kg a rozměrů 30 x 60 x 80 cm. -Poplatek za každé další zavazadlo/poplatek za nadrozměrné zavazadlo/poplatek za přepravu kola je 100 Kč/ 4 EUR. - -Dopravci: -SA - STUDENT AGENCY, s.r.o., IČO: 25317075, internet: www.studentagency.cz, telefon: +420 542 42 42 42 - - -Vaši jízdenku můžete spravovat zde http://jizdenky.studentagency.cz/OnlineTicket?pam1=0987654321&pam2=0123456789 (k přihlášení potřebujete číslo jízdenky) - - - -S pozdravem -STUDENT AGENCY Express -STUDENT AGENCY s.r.o. -www.studentagency.cz -tel: +420 841 101 101, +420 542 42 42 42, pro letenky +420 800 100 300 - --------------------------------------------------------------------------------- -STUDENT AGENCY express je online rezervační systém autobusové dopravy společnosti STUDENT AGENCY (http://www.studentagency.cz). -Pokud nechcete automaticky dostávat emaily o změnách v rezervacích, proveďte změnu v sekci nastavení. diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_bus_en-one-leg-single.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_bus_en-one-leg-single.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_bus_en-one-leg-single.json +++ /dev/null @@ -1,31 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "BusReservation", - "modifyReservationUrl": "https://jizdenky.studentagency.cz/OnlineTicket?pam1=0987654321&pam2=0123456789", - "reservationFor": { - "@type": "BusTrip", - "arrivalStation": { - "@type": "BusStation", - "name": "Brno, AN u hotelu Grand" - }, - "arrivalTime": "2015-08-01T00:30:00", - "busName": "Vienna → Prague", - "busNumber": "SA", - "departurePlatform": "2", - "departureStation": { - "@type": "BusStation", - "name": "Wien, Schwechat Airport Bbf." - }, - "departureTime": "2015-07-31T22:10:00" - }, - "reservationNumber": "0123456789", - "reservedTicket": { - "@type": "Ticket", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "48" - } - } - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_bus_en-one-leg-single.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_bus_en-one-leg-single.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_bus_en-one-leg-single.txt +++ /dev/null @@ -1,44 +0,0 @@ -Electronic ticket 0123456789 - -Number of passengers (used tarifs): 1 (Adult) -Passengers: Daniel Vratil - - -Route -Date Station/Transfer Arrival Departure Platf. Connection Coach/Seats -Fri 31/07/15 Wien, Schwechat Airport Bbf. 22:10 2 Vienna → Prague (SA) 48 -Sat 01/08/15 Brno, AN u hotelu Grand 00:30 - - - -Price: 340 CZK -Cancellation terms: more than 1 hour: 0 %, less than 1 hour: not possible -Rebook terms: more than 1 hour: by cancellation for 0 CZK, less than 1 hour: not possible - -Action: Flexi (https://bustickets.studentagency.eu/en/special-offers/special-offers-details/akce-praha-drazdany-berlin-nejlevnejsi-cena-2015.html) - - -Important information: -Dear passengers! Please have your valid travel document (ID card or passport) ready for inspection when boarding the bus. Residence permits, travel document copies, etc. are not a valid travel document! Clients without valid travel documents will not be transported. -Luggage – luggage transported for one passenger free of charge: -1 piece of hand luggage (maximum size 15 x 25 x 35 cm) -and 1 piece of luggage in the luggage compartment not exceeding 30 kg or the size of 30 x 60 x 80 cm. -The fee for each extra piece of luggage/fee for luggage exceeding the maximum size/fee the transport of a bicycle is 100 CZK/ 4 € while paying by a coach or 50 CZK /2 € for payment in advance in the reservation system. - -Operators: -SA - STUDENT AGENCY k.s., ID: 25317075, internet: www.studentagency.cz, phone: +420 841 101 101 - - -You can manage your ticket here https://jizdenky.studentagency.cz/OnlineTicket?pam1=0987654321&pam2=0123456789 (you will need the ticket number to log in) - -To board the bus, you only need to give the ticket number unless otherwise stated in the conditions. - - - - -Yours sincerely -STUDENT AGENCY/ REGIOJET -www.studentagency.cz, www.regiojet.cz -phone: +420 841 101 101, +420 542 42 42 42 --------------------------------------------------------------------------------- -Thank you for using online bus/train ticket reservation system utilized by STUDENT AGENCY and REGIOJET (http://www.studentagency.cz; http://www.regiojet.cz). diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_train_cs-one-leg-single.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_train_cs-one-leg-single.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_train_cs-one-leg-single.json +++ /dev/null @@ -1,31 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "modifyReservationUrl": "https://jizdenky.regiojet.cz/OnlineTicket?pam1=0987654321&pam2=0123456789", - "reservationFor": { - "@type": "TrainTrip", - "arrivalStation": { - "@type": "TrainStation", - "name": "Praha, hl.n." - }, - "arrivalTime": "2017-07-02T14:12:00", - "departureStation": { - "@type": "TrainStation", - "name": "Olomouc, hl.n." - }, - "departureTime": "2017-07-02T11:56:00", - "trainName": "Návsí (Jablunkov) → Praha", - "trainNumber": "RJ, RJ 1010" - }, - "reservationNumber": "0123456789", - "reservedTicket": { - "@type": "Ticket", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "48", - "seatSection": "1" - } - } - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_train_cs-one-leg-single.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_train_cs-one-leg-single.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/regiojet_train_cs-one-leg-single.txt +++ /dev/null @@ -1,43 +0,0 @@ -Elektronická jízdenka č. 0123456789 - -Počet cestujících (použité tarify): 1 (Dospělý) - - -Cesta -Datum Zastávka/Přestup Příjezd Odjezd Nást. Spoj Vůz/sedadla -Ne 2.7.17 Olomouc, hl.n. 11:56 Návsí (Jablunkov) → Praha (RJ, RJ 1010) 1/48 - Praha, hl.n. 14:12 - - - -Cena: 239 CZK -Stornovací podmínky: více než 15 minut: 0 %, méně než 15 minut: nelze stornovat -Podmínky přerezervace: více než 15 minut: stornem za 0 CZK, méně než 15 minut: nelze přerezervovat - - -Tarif: LOW COST - bez servisu - -Důležité informace: -Vybrali jste si sedadlo ve třídě LOW COST – bez servisu. Sedadla jsou vybavana loketními opěrkami a jsou nepolohovatelná, proto jsou vhodná pro cestování na krátkých trasách. K dispozici je balená voda Rajec, denní tisk a časopisy na představcích. Užijte si ničím nerušenou jízdu s možností sledování více než 50 filmů, poslechem hudby a hraním her ve vlastním zařízení. - -Dopravci: -RJ - REGIOJET a.s., IČO: 28333187, DIČ: CZ28333187, internet: www.regiojet.cz, telefon: +420841101101 - - -Vaši jízdenku můžete spravovat zde https://jizdenky.regiojet.cz/OnlineTicket?pam1=0987654321&pam2=0123456789 (k přihlášení potřebujete číslo jízdenky) - -K odbavení u spoje postačuje sdělit číslo jízdenky, není-li v podmínkách uvedeno jinak. - - - - - - -S pozdravem -REGIOJET -www.regiojet.cz -tel: +420 841 101 101, +420 542 42 42 42 --------------------------------------------------------------------------------- -Děkujeme, že používáte online rezervační systém autobusové a vlakové dopravy společnosti REGIOJET (http://www.regiojet.cz). -Online rezervační systém spravuje STUDENT AGENCY k.s., Česká republika -Pokud nechcete automaticky dostávat emaily, proveďte změnu v sekci nastavení. diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/sncf_one-leg-single-tgv.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/sncf_one-leg-single-tgv.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/sncf_one-leg-single-tgv.json +++ /dev/null @@ -1,29 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "TrainReservation", - "reservationFor": { - "@type": "TrainTrip", - "arrivalStation": { - "@type": "TrainStation", - "name": "MONTPELLIER ST-RO" - }, - "arrivalTime": "2018-07-15T19:58:00", - "departureStation": { - "@type": "TrainStation", - "name": "TOULOUSE MATABIAU" - }, - "departureTime": "2018-07-15T17:50:00", - "trainNumber": "6857" - }, - "reservationNumber": "XXX007", - "reservedTicket": { - "@type": "Ticket", - "ticketedSeat": { - "@type": "Seat", - "seatNumber": "31", - "seatSection": "13" - } - } - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/sncf_one-leg-single-tgv.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/sncf_one-leg-single-tgv.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/sncf_one-leg-single-tgv.txt +++ /dev/null @@ -1,16 +0,0 @@ -VOTRE CONFIRMATION E-BILLET - TOULOUSE MATABIAU / MONTPELLIER ST-RO 35.00 EUR - CK -Nom : DOE DOSSIER VOYAGE : XXX007 -Prénom : JOHN Référence client : 0011223344556677889 -Voyageur : ADULTE N° e-billet : 123456789 - Départ / Arrivée Date / Heure TGV TGV LOISIR REDUIT-ECH/REMB PAYANT JOUR DU - DEPART - PR11 - ABC123 - TRAIN N°6857 - TOULOUSE MATABIAU 15/07 à 17h50 VOITURE 13 - PLACE 31 - 1e CLASSE / PLACE ASSISE - MONTPELLIER ST-RO 15/07 à 19h58 ISOLEE SOLO - E-Billet valable uniquement sur ce train -Présence à quai obligatoire 2 mn avant départ. -Pour connaître l'empreinte CO2 de votre voyage et accéder au détail de la méthode de calcul, rendez-vous sur SNCF.com diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/swiss_one-leg-return.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/swiss_one-leg-return.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/swiss_one-leg-return.json +++ /dev/null @@ -1,52 +0,0 @@ -[ - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "LX" - }, - "arrivalAirport": { - "@type": "Airport", - "iataCode": "ZRH", - "name": "Zürich" - }, - "arrivalTime": "2017-09-10T08:15:00", - "departureAirport": { - "@type": "Airport", - "iataCode": "TXL", - "name": "Berlin" - }, - "departureTime": "2017-09-10T06:45:00", - "flightNumber": "963" - }, - "reservationNumber": "XXX007" - }, - { - "@context": "http://schema.org", - "@type": "FlightReservation", - "reservationFor": { - "@type": "Flight", - "airline": { - "@type": "Airline", - "iataCode": "LX" - }, - "arrivalAirport": { - "@type": "Airport", - "iataCode": "TXL", - "name": "Berlin" - }, - "arrivalTime": "2017-09-15T22:15:00", - "departureAirport": { - "@type": "Airport", - "iataCode": "ZRH", - "name": "Zürich" - }, - "departureTime": "2017-09-15T20:50:00", - "flightNumber": "962" - }, - "reservationNumber": "XXX007" - } -] diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/swiss_one-leg-return.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/swiss_one-leg-return.txt deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/swiss_one-leg-return.txt +++ /dev/null @@ -1,7 +0,0 @@ -// technically this is HTML, but it contains soooo much style sheet noise I didn't want to check that in, so this is preprocssed content already - Vielen Dank, Ihre Buchung ist bestätigt. - Vielen Dank, Ihre Buchung ist bestätigt. Buchungsreferenz: XXX007 Sehr geehrter Herr Doe - -Danke, dass Sie mit uns fliegen. Ihre Buchungsdetails finden Sie untenstehend. Eine gute Reise und bis bald. Mit Ihrer Buchungsreferenz können Sie jederzeit Ihre Buchungen bearbeiten . Wenn Sie ein elektronisches e-Ticket wünschen, können Sie es unter Elektronische Dokumente bestellen Fluginformationen Hinflug Berlin (TXL) - Zürich (ZRH) So 10.09.2017 06:45 TXL 08:15 ZRH Reisedauer 1h 30m LX 963 Classic - K Durchgeführt von SWISS Rückflug Zürich (ZRH) - Berlin (TXL) Fr 15.09.2017 20:50 ZRH 22:15 TXL Reisedauer 1h 25m LX 962 Classic - T Durchgeführt von SWISS Bitte beachten Sie • Je nach gewähltem Tarif ist nur die Mitnahme von Handgepäck im Ticket inbegriffen. Überprüfen Sie die Konditionen Ihres Tarifs. • Nach geltendem EU-Recht haben Sie das Recht den Namen und die Adresse einer zusätzlichen Kontaktperson bei SWISS anzugeben. Gepäckinformationen Berlin (TXL) - Zürich (ZRH) So 10.09.2017 1 Erwachsener Freigepäck (inkl.) 1 Gepäckstück à 23kg Total 1 Gepäckstück à 23kg Zürich (ZRH) - Berlin (TXL) Fr 15.09.2017 1 Erwachsener Freigepäck (inkl.) 1 Gepäckstück à 23kg Total 1 Gepäckstück à 23kg Gepäckregeln Aufgegebenes Gepäck Übergepäck Gepäckgebühren auf Codeshare und Interline Partner Gewählte Leistungen Name E-Ticket Services Preis in EUR John Doe 1234567850627 Flugtarif 42,00 Internationaler Zuschlag 42,00 Flughafentaxen 42,40 SWISS Service Fee 0,00 OPC 2,50 Sitzreservation 0,00 999,90 Gesamtpreis EUR 999,90 - Quicklinks Buchung verwalten Reisevorbereitung An Bord Zürich entdecken Mietwagen Profitieren Sie jetzt von einer grossen Auswahl an Mietwagen. Mit SWISS zu günstigen Preisen buchen. Jetzt buchen Hotel Angebote Finden Sie mit SWISS das perfekte Hotel zu günstigen Preisen. Jetzt buchen Aktivitäten Die besten Angebote für Aktivitäten an Ihrem Reiseziel. Jetzt buchen Rechtliches | Beförderungsbestimmungen | Kontakt - diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddataextractortest.cpp b/plugins/messageviewer/bodypartformatter/autotests/unstructureddataextractortest.cpp deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/unstructureddataextractortest.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "extractor.h" -#include "extractorengine.h" -#include "extractorpreprocessor.h" -#include "jsonlddocument.h" - -#include -#include -#include -#include -#include -#include - -class UnstructuredDataExtractorTest : public QObject -{ - Q_OBJECT -private Q_SLOTS: - void initTestCase() - { - Q_INIT_RESOURCE(extractors); - // use some exotic locale to ensure the date/time parsing doesn't just work by luck - QLocale::setDefault(QLocale(QStringLiteral("fr_FR"))); - } - - void testExtractText_data() - { - QTest::addColumn("inputFile"); - QTest::addColumn("extractorName"); - QTest::addColumn("jsonFile"); - - QDir dir(QStringLiteral(SOURCE_DIR "/unstructureddata")); - const auto lst = dir.entryList(QStringList(QStringLiteral("*.txt")), QDir::Files | QDir::Readable | QDir::NoSymLinks); - for (const auto &file : lst) { - const auto refFile = dir.path() + QLatin1Char('/') + file.left(file.size() - 4) + QStringLiteral(".json"); - if (!QFile::exists(refFile)) { - qDebug() << "reference file" << refFile << "does not exist, skipping test file" << file; - continue; - } - const auto idx = file.indexOf(QLatin1Char('_')); - QTest::newRow(file.toLatin1()) << QString(dir.path() + QLatin1Char('/') + file) << file.left(idx) << refFile; - } - } - - void testExtractText() - { - QFETCH(QString, inputFile); - QFETCH(QString, extractorName); - QFETCH(QString, jsonFile); - - QFile f(inputFile); - QVERIFY(f.open(QFile::ReadOnly)); - - Extractor extractor; - QVERIFY(extractor.load(QLatin1String(":/org.kde.pim/messageviewer/semantic/extractors/") + extractorName + QLatin1String(".json"))); - - ExtractorEngine engine; - engine.setText(QString::fromUtf8(f.readAll())); - engine.setSenderDate(QDateTime(QDate(2017, 12, 29), QTime(18, 46, 2))); - engine.setExtractor(&extractor); - const auto data = JsonLdDocument::toJson(JsonLdDocument::fromJson(engine.extract())); - - QFile ref(jsonFile); - QVERIFY(ref.open(QFile::ReadOnly)); - const auto doc = QJsonDocument::fromJson(ref.readAll()); - QVERIFY(doc.isArray()); - - if (data != doc.array()) { - qDebug().noquote() << QJsonDocument(data).toJson(); - } - QCOMPARE(data, doc.array()); - } - - void testExtractHtml_data() - { - QTest::addColumn("inputFile"); - QTest::addColumn("extractorName"); - QTest::addColumn("jsonFile"); - - QDir dir(QStringLiteral(SOURCE_DIR "/unstructureddata")); - const auto lst = dir.entryList(QStringList(QStringLiteral("*.html")), QDir::Files | QDir::Readable | QDir::NoSymLinks); - for (const auto &file : lst) { - const auto refFile = dir.path() + QLatin1Char('/') + file.left(file.size() - 5) + QStringLiteral(".json"); - if (!QFile::exists(refFile)) { - qDebug() << "reference file" << refFile << "does not exist, skipping test file" << file; - continue; - } - const auto idx = file.indexOf(QLatin1Char('_')); - QTest::newRow(file.toLatin1()) << QString(dir.path() + QLatin1Char('/') + file) << file.left(idx) << refFile; - } - } - - void testExtractHtml() - { - QFETCH(QString, inputFile); - QFETCH(QString, extractorName); - QFETCH(QString, jsonFile); - - QFile f(inputFile); - QVERIFY(f.open(QFile::ReadOnly)); - - Extractor extractor; - QVERIFY(extractor.load(QLatin1String(":/org.kde.pim/messageviewer/semantic/extractors/") + extractorName + QLatin1String(".json"))); - - ExtractorPreprocessor preproc; - preproc.preprocessHtml(QString::fromUtf8(f.readAll())); - - ExtractorEngine engine; - engine.setText(preproc.text()); - engine.setSenderDate(QDateTime(QDate(2017, 12, 29), QTime(18, 46, 2))); - engine.setExtractor(&extractor); - const auto data = JsonLdDocument::toJson(JsonLdDocument::fromJson(engine.extract())); - - QFile ref(jsonFile); - QVERIFY(ref.open(QFile::ReadOnly)); - const auto doc = QJsonDocument::fromJson(ref.readAll()); - QVERIFY(doc.isArray()); - - if (data != doc.array()) { - qDebug().noquote() << QJsonDocument(data).toJson(); - } - QCOMPARE(data, doc.array()); - } -}; - -QTEST_MAIN(UnstructuredDataExtractorTest) - -#include "unstructureddataextractortest.moc" diff --git a/plugins/messageviewer/bodypartformatter/semantic/CMakeLists.txt b/plugins/messageviewer/bodypartformatter/semantic/CMakeLists.txt --- a/plugins/messageviewer/bodypartformatter/semantic/CMakeLists.txt +++ b/plugins/messageviewer/bodypartformatter/semantic/CMakeLists.txt @@ -1,52 +1,22 @@ -add_subdirectory(airportdb) - -if(TARGET Poppler::Qt5) - set(HAVE_POPPLER ON) -endif() -configure_file(config-semantic.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-semantic.h) - -# static lib for use by unit test -set(semantic_lib_srcs - airportdb/airportdb.cpp - calendarhandler.cpp - datatypes.cpp - extractor.cpp - extractorengine.cpp - extractorfilter.cpp - extractorpreprocessor.cpp - extractorpostprocessor.cpp - extractorrepository.cpp - jsonlddocument.cpp - structureddataextractor.cpp -) -qt5_add_resources(semantic_lib_srcs extractors/extractors.qrc) -ecm_qt_declare_logging_category(semantic_lib_srcs HEADER semantic_debug.h IDENTIFIER SEMANTIC_LOG CATEGORY_NAME org.kde.pim.messageviewer.semantic) -add_library(semantic_extractor STATIC ${semantic_lib_srcs}) -set_target_properties(semantic_extractor PROPERTIES POSITION_INDEPENDENT_CODE ON) -target_link_libraries(semantic_extractor PUBLIC Qt5::Core KF5::Mime KF5::CalendarCore PRIVATE Qt5::Qml KF5::I18n) -if (HAVE_POPPLER) - target_link_libraries(semantic_extractor PRIVATE Poppler::Qt5) -endif() - - set(semantic_plugin_srcs semantic_plugin.cpp semanticmemento.cpp semanticprocessor.cpp semanticrenderer.cpp semanticurlhandler.cpp ) +ecm_qt_declare_logging_category(semantic_plugin_srcs HEADER semantic_debug.h IDENTIFIER SEMANTIC_LOG CATEGORY_NAME org.kde.pim.messageviewer.semantic) qt5_add_resources(semantic_plugin_srcs templates.qrc) add_library(messageviewer_bodypartformatter_semantic MODULE ${semantic_plugin_srcs}) target_compile_definitions(messageviewer_bodypartformatter_semantic PRIVATE -DTRANSLATION_DOMAIN=\"messageviewer_semantic_plugin\") target_link_libraries(messageviewer_bodypartformatter_semantic - semantic_extractor KF5::MessageViewer KF5::CalendarSupport KF5::I18n Grantlee5::Templates Qt5::DBus KF5::Prison + KPim::Itinerary ) install(TARGETS messageviewer_bodypartformatter_semantic DESTINATION ${KDE_INSTALL_PLUGINDIR}/messageviewer/bodypartformatter) diff --git a/plugins/messageviewer/bodypartformatter/semantic/calendarhandler.h b/plugins/messageviewer/bodypartformatter/semantic/calendarhandler.h deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/calendarhandler.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#ifndef CALENDARHANDLER_H -#define CALENDARHANDLER_H - -#include -#include - -class QVariant; - -/** Methods for converting between ical events and JSON-LD booking data. */ -class CalendarHandler -{ -public: - /** Returns the start time associated with the given reservation. */ - static QDateTime startDateTime(const QVariant &reservation); - - /** Attempts to find an event in @p calendar for @p reservation. */ - static KCalCore::Event::Ptr findEvent(const KCalCore::Calendar::Ptr &calendar, const QVariant &reservation); - - /** Fills @p event with details of @p reservation. - * Can be used on new events or to update existing ones. - */ - static void fillEvent(const QVariant &reservation, const KCalCore::Event::Ptr &event); - -private: - static void fillFlightReservation(const QVariant &reservation, const KCalCore::Event::Ptr &event); - static void fillTripReservation(const QVariant &reservation, const KCalCore::Event::Ptr &event); - static void fillTrainReservation(const QVariant &reservation, const KCalCore::Event::Ptr &event); - static void fillBusReservation(const QVariant &reservation, const KCalCore::Event::Ptr &event); - static void fillLodgingReservation(const QVariant &reservation, const KCalCore::Event::Ptr &event); - static void fillGeoPosition(const QVariant &place, const KCalCore::Event::Ptr &event); -}; - -#endif // CALENDARHANDLER_H diff --git a/plugins/messageviewer/bodypartformatter/semantic/calendarhandler.cpp b/plugins/messageviewer/bodypartformatter/semantic/calendarhandler.cpp deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/calendarhandler.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "calendarhandler.h" -#include "datatypes.h" -#include "jsonlddocument.h" -#include "semantic_debug.h" - -#include - -#include - -using namespace KCalCore; - -QDateTime CalendarHandler::startDateTime(const QVariant &reservation) -{ - if (reservation.userType() == qMetaTypeId() - || reservation.userType() == qMetaTypeId() - || reservation.userType() == qMetaTypeId()) { - const auto trip = JsonLdDocument::readProperty(reservation, "reservationFor"); - return JsonLdDocument::readProperty(trip, "departureTime").toDateTime(); - } else if (reservation.userType() == qMetaTypeId()) { - return JsonLdDocument::readProperty(reservation, "checkinDate").toDateTime(); - } - return {}; -} - -Event::Ptr CalendarHandler::findEvent(const Calendar::Ptr &calendar, const QVariant &reservation) -{ - const auto bookingRef = JsonLdDocument::readProperty(reservation, "reservationNumber").toString(); - if (bookingRef.isEmpty()) { - return {}; - } - - auto dt = startDateTime(reservation); - if (reservation.userType() == qMetaTypeId()) { - dt = QDateTime(dt.date(), QTime()); - } - - const auto events = calendar->events(dt); - for (const auto &event : events) { - if (event->dtStart() == dt && event->uid().startsWith(bookingRef)) { - return event; - } - } - return {}; -} - -void CalendarHandler::fillEvent(const QVariant &reservation, const KCalCore::Event::Ptr &event) -{ - const int typeId = reservation.userType(); - if (typeId == qMetaTypeId()) { - fillFlightReservation(reservation, event); - } else if (typeId == qMetaTypeId()) { - fillLodgingReservation(reservation, event); - } else if (typeId == qMetaTypeId()) { - fillTrainReservation(reservation, event); - } else if (typeId == qMetaTypeId()) { - fillBusReservation(reservation, event); - } - - const auto bookingRef = JsonLdDocument::readProperty(reservation, "reservationNumber").toString(); - if (!event->uid().startsWith(bookingRef)) { - event->setUid(bookingRef + QLatin1Char('-') + event->uid()); - } -} - -void CalendarHandler::fillFlightReservation(const QVariant &reservation, const KCalCore::Event::Ptr &event) -{ - const auto flight = JsonLdDocument::readProperty(reservation, "reservationFor"); - const auto airline = JsonLdDocument::readProperty(flight, "airline"); - const auto depPort = JsonLdDocument::readProperty(flight, "departureAirport"); - const auto arrPort = JsonLdDocument::readProperty(flight, "arrivalAirport"); - if (flight.isNull() || airline.isNull() || depPort.isNull() || arrPort.isNull()) { - qCDebug(SEMANTIC_LOG) << "got invalid flight reservation"; - return; - } - - const auto flightNumber = JsonLdDocument::readProperty(airline, "iataCode").toString() - + QLatin1Char(' ') - + JsonLdDocument::readProperty(flight, "flightNumber").toString(); - - event->setSummary(i18n("Flight %1 from %2 to %3", flightNumber, - JsonLdDocument::readProperty(depPort, "iataCode").toString(), - JsonLdDocument::readProperty(arrPort, "iataCode").toString() - )); - event->setLocation(JsonLdDocument::readProperty(depPort, "name").toString()); - fillGeoPosition(depPort, event); - event->setDtStart(JsonLdDocument::readProperty(flight, "departureTime").toDateTime()); - event->setDtEnd(JsonLdDocument::readProperty(flight, "arrivalTime").toDateTime()); - event->setAllDay(false); - - const auto boardingTime = JsonLdDocument::readProperty(flight, "boardingTime").toDateTime(); - const auto departureGate = JsonLdDocument::readProperty(flight, "departureGate").toString(); - if (boardingTime.isValid()) { - Alarm::Ptr alarm(new Alarm(event.data())); - alarm->setStartOffset(Duration(event->dtStart(), boardingTime)); - if (departureGate.isEmpty()) { - alarm->setDisplayAlarm(i18n("Boarding for flight %1", flightNumber)); - } else { - alarm->setDisplayAlarm(i18n("Boarding for flight %1 at gate %2", flightNumber, departureGate)); - } - alarm->setEnabled(true); - event->addAlarm(alarm); - } - - QStringList desc; - if (boardingTime.isValid()) { - desc.push_back(i18n("Boarding time: %1", QLocale().toString(boardingTime.time(), QLocale::ShortFormat))); - } - if (!departureGate.isEmpty()) { - desc.push_back(i18n("Departure gate: %1", departureGate)); - } - auto s = JsonLdDocument::readProperty(reservation, "boardingGroup").toString(); - if (!s.isEmpty()) { - desc.push_back(i18n("Boarding group: %1", s)); - } - s = JsonLdDocument::readProperty(reservation, "airplaneSeat").toString(); - if (!s.isEmpty()) { - desc.push_back(i18n("Seat: %1", s)); - } - s = JsonLdDocument::readProperty(reservation, "reservationNumber").toString(); - if (!s.isEmpty()) { - desc.push_back(i18n("Booking reference: %1", s)); - } - event->setDescription(desc.join(QLatin1Char('\n'))); -} - -void CalendarHandler::fillTripReservation(const QVariant &reservation, const KCalCore::Event::Ptr &event) -{ - const auto trip = JsonLdDocument::readProperty(reservation, "reservationFor"); - const auto depStation = JsonLdDocument::readProperty(trip, "departureStation"); - const auto arrStation = JsonLdDocument::readProperty(trip, "arrivalStation"); - - event->setLocation(JsonLdDocument::readProperty(depStation, "name").toString()); - fillGeoPosition(depStation, event); - event->setDtStart(JsonLdDocument::readProperty(trip, "departureTime").toDateTime()); - event->setDtEnd(JsonLdDocument::readProperty(trip, "arrivalTime").toDateTime()); - event->setAllDay(false); - - QStringList desc; - auto s = JsonLdDocument::readProperty(trip, "departurePlatform").toString(); - if (!s.isEmpty()) { - desc.push_back(i18n("Departure platform: %1", s)); - } - const auto ticket = JsonLdDocument::readProperty(reservation, "reservedTicket"); - const auto seat = JsonLdDocument::readProperty(ticket, "ticketedSeat"); - s = JsonLdDocument::readProperty(seat, "seatSection").toString(); - if (!s.isEmpty()) { - desc.push_back(i18n("Coach: %1", s)); - } - s = JsonLdDocument::readProperty(seat, "seatNumber").toString(); - if (!s.isEmpty()) { - desc.push_back(i18n("Seat: %1", s)); - } - s = JsonLdDocument::readProperty(trip, "arrivalPlatform").toString(); - if (!s.isEmpty()) { - desc.push_back(i18n("Arrival platform: %1", s)); - } - s = JsonLdDocument::readProperty(reservation, "reservationNumber").toString(); - if (!s.isEmpty()) { - desc.push_back(i18n("Booking reference: %1", s)); - } - event->setDescription(desc.join(QLatin1Char('\n'))); -} - -void CalendarHandler::fillTrainReservation(const QVariant &reservation, const KCalCore::Event::Ptr &event) -{ - const auto trip = JsonLdDocument::readProperty(reservation, "reservationFor"); - const auto depStation = JsonLdDocument::readProperty(trip, "departureStation"); - const auto arrStation = JsonLdDocument::readProperty(trip, "arrivalStation"); - if (trip.isNull() || depStation.isNull() || arrStation.isNull()) { - return; - } - - event->setSummary(i18n("Train %1 from %2 to %3", - JsonLdDocument::readProperty(trip, "trainNumber").toString(), - JsonLdDocument::readProperty(depStation, "name").toString(), - JsonLdDocument::readProperty(arrStation, "name").toString() - )); - fillTripReservation(reservation, event); -} - -void CalendarHandler::fillBusReservation(const QVariant &reservation, const KCalCore::Event::Ptr &event) -{ - const auto trip = JsonLdDocument::readProperty(reservation, "reservationFor"); - const auto depStation = JsonLdDocument::readProperty(trip, "departureStation"); - const auto arrStation = JsonLdDocument::readProperty(trip, "arrivalStation"); - if (trip.isNull() || depStation.isNull() || arrStation.isNull()) { - return; - } - - event->setSummary(i18n("Bus %1 from %2 to %3", - JsonLdDocument::readProperty(trip, "busNumber").toString(), - JsonLdDocument::readProperty(depStation, "name").toString(), - JsonLdDocument::readProperty(arrStation, "name").toString() - )); - fillTripReservation(reservation, event); -} - -void CalendarHandler::fillLodgingReservation(const QVariant &reservation, const KCalCore::Event::Ptr &event) -{ - const auto lodgingBusiness = JsonLdDocument::readProperty(reservation, "reservationFor"); - const auto address = JsonLdDocument::readProperty(lodgingBusiness, "address"); - if (lodgingBusiness.isNull() || address.isNull()) { - return; - } - - event->setSummary(i18n("Hotel reservation: %1", - JsonLdDocument::readProperty(lodgingBusiness, "name").toString() - )); - event->setLocation(i18n("%1, %2 %3, %4", - JsonLdDocument::readProperty(address, "streetAddress").toString(), - JsonLdDocument::readProperty(address, "postalCode").toString(), - JsonLdDocument::readProperty(address, "addressLocality").toString(), - JsonLdDocument::readProperty(address, "addressCountry").toString() - )); - fillGeoPosition(lodgingBusiness, event); - - const auto checkinDt = JsonLdDocument::readProperty(reservation, "checkinDate").toDateTime(); - const auto checkoutDt = JsonLdDocument::readProperty(reservation, "checkoutDate").toDateTime(); - event->setDtStart(QDateTime(checkinDt.date(), QTime())); - event->setDtEnd(QDateTime(checkoutDt.date(), QTime())); - event->setAllDay(true); - event->setDescription(i18n("Check-in: %1\nCheck-out: %2\nBooking reference: %3", - QLocale().toString(checkinDt.time(), QLocale::ShortFormat), - QLocale().toString(checkoutDt.time(), QLocale::ShortFormat), - JsonLdDocument::readProperty(reservation, "reservationNumber").toString() - )); - event->setTransparency(Event::Transparent); -} - -void CalendarHandler::fillGeoPosition(const QVariant &place, const KCalCore::Event::Ptr &event) -{ - const auto geo = JsonLdDocument::readProperty(place, "geo"); - if (geo.isNull()) { - return; - } - - event->setHasGeo(true); - event->setGeoLatitude(JsonLdDocument::readProperty(geo, "latitude").toFloat()); - event->setGeoLongitude(JsonLdDocument::readProperty(geo, "longitude").toFloat()); -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/config-semantic.h.cmake b/plugins/messageviewer/bodypartformatter/semantic/config-semantic.h.cmake deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/config-semantic.h.cmake +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#ifndef CONFIG_SEMANTIC_H -#define CONFIG_SEMANTIC_H - -#cmakedefine HAVE_POPPLER - -#endif diff --git a/plugins/messageviewer/bodypartformatter/semantic/datatypes.h b/plugins/messageviewer/bodypartformatter/semantic/datatypes.h deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/datatypes.h +++ /dev/null @@ -1,260 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#ifndef DATATYPES_H -#define DATATYPES_H - -#include -#include -#include -#include - -#define SEMANTIC_GADGET \ - Q_GADGET \ - Q_PROPERTY(QString className READ className STORED false CONSTANT) \ - inline QString className() const { return QString::fromUtf8(staticMetaObject.className()); } - -#define SEMANTIC_PROPERTY(Type, Name) \ - Q_PROPERTY(Type Name MEMBER m_##Name) \ - Type m_##Name; - -/** @file - * The classes in here could possibly be auto-generated from the ontology defined by http://schema.org... - */ - -class GeoCoordinates -{ - SEMANTIC_GADGET - SEMANTIC_PROPERTY(float, latitude) - SEMANTIC_PROPERTY(float, longitude) -public: - GeoCoordinates(); - bool isValid() const; -}; - -class PostalAddress -{ - SEMANTIC_GADGET - SEMANTIC_PROPERTY(QString, streetAddress) - SEMANTIC_PROPERTY(QString, addressLocality) - SEMANTIC_PROPERTY(QString, postalCode) - SEMANTIC_PROPERTY(QString, addressCountry) -}; - -class Place -{ - Q_GADGET - SEMANTIC_PROPERTY(QVariant, address) - SEMANTIC_PROPERTY(QVariant, geo) -public: - bool operator!=(const Place &other) const; -}; - -class Airport : protected Place -{ - SEMANTIC_GADGET - SEMANTIC_PROPERTY(QString, name) - SEMANTIC_PROPERTY(QString, iataCode) -public: - bool operator!=(const Airport &other) const; -}; - -class Airline { - SEMANTIC_GADGET - SEMANTIC_PROPERTY(QString, name) - SEMANTIC_PROPERTY(QString, iataCode) -public: - bool operator!=(const Airline &other) const; -}; - -class TrainStation : protected Place -{ - SEMANTIC_GADGET - SEMANTIC_PROPERTY(QString, name) -public: - bool operator!=(const TrainStation &other) const; -}; - -class BusStation : protected Place -{ - SEMANTIC_GADGET - SEMANTIC_PROPERTY(QString, name) -public: - bool operator!=(const BusStation &other) const; -}; - -/** - * @see https://schema.org/Flight - * @see https://developers.google.com/gmail/markup/reference/flight-reservation - */ -class Flight -{ - SEMANTIC_GADGET - SEMANTIC_PROPERTY(QString, flightNumber) - SEMANTIC_PROPERTY(Airline, airline) - SEMANTIC_PROPERTY(Airport, departureAirport) - SEMANTIC_PROPERTY(QDateTime, departureTime) - SEMANTIC_PROPERTY(Airport, arrivalAirport) - SEMANTIC_PROPERTY(QDateTime, arrivalTime) - - // Google extension for boarding pass data - SEMANTIC_PROPERTY(QDateTime, boardingTime) - SEMANTIC_PROPERTY(QString, departureGate) - - Q_PROPERTY(QString departureTimeLocalized READ departureTimeLocalized STORED false CONSTANT) - Q_PROPERTY(QString arrivalTimeLocalized READ arrivalTimeLocalized STORED false CONSTANT) - Q_PROPERTY(QString boardingTimeLocalized READ boardingTimeLocalized STORED false CONSTANT) -private: - QString departureTimeLocalized() const; - QString arrivalTimeLocalized() const; - QString boardingTimeLocalized() const; -}; - -class LodgingBusiness: protected Place -{ - SEMANTIC_GADGET - SEMANTIC_PROPERTY(QString, name) -}; - -class TrainTrip -{ - SEMANTIC_GADGET - SEMANTIC_PROPERTY(QString, arrivalPlatform) - SEMANTIC_PROPERTY(TrainStation, arrivalStation) - SEMANTIC_PROPERTY(QDateTime, arrivalTime) - SEMANTIC_PROPERTY(QString, departurePlatform) - SEMANTIC_PROPERTY(TrainStation, departureStation) - SEMANTIC_PROPERTY(QDateTime, departureTime) - SEMANTIC_PROPERTY(QString, trainName) - SEMANTIC_PROPERTY(QString, trainNumber) - - Q_PROPERTY(QString departureTimeLocalized READ departureTimeLocalized STORED false CONSTANT) - Q_PROPERTY(QString arrivalTimeLocalized READ arrivalTimeLocalized STORED false CONSTANT) - -private: - QString departureTimeLocalized() const; - QString arrivalTimeLocalized() const; -}; - -class BusTrip -{ - SEMANTIC_GADGET - SEMANTIC_PROPERTY(QString, arrivalPlatform) - SEMANTIC_PROPERTY(BusStation, arrivalStation) - SEMANTIC_PROPERTY(QDateTime, arrivalTime) - SEMANTIC_PROPERTY(QString, departurePlatform) - SEMANTIC_PROPERTY(BusStation, departureStation) - SEMANTIC_PROPERTY(QDateTime, departureTime) - SEMANTIC_PROPERTY(QString, busName) - SEMANTIC_PROPERTY(QString, busNumber) - - Q_PROPERTY(QString departureTimeLocalized READ departureTimeLocalized STORED false CONSTANT) - Q_PROPERTY(QString arrivalTimeLocalized READ arrivalTimeLocalized STORED false CONSTANT) - -private: - QString departureTimeLocalized() const; - QString arrivalTimeLocalized() const; -}; - -class Seat -{ - SEMANTIC_GADGET - SEMANTIC_PROPERTY(QString, seatNumber) - SEMANTIC_PROPERTY(QString, seatRow) - SEMANTIC_PROPERTY(QString, seatSection) -}; - -class Ticket -{ - SEMANTIC_GADGET - SEMANTIC_PROPERTY(QVariant, ticketedSeat) - SEMANTIC_PROPERTY(QString, ticketToken) -}; - -class Reservation -{ - Q_GADGET - SEMANTIC_PROPERTY(QString, reservationNumber) - SEMANTIC_PROPERTY(QVariant, reservationFor) - SEMANTIC_PROPERTY(QVariant, reservedTicket) - - // Google extension - SEMANTIC_PROPERTY(QUrl, cancelReservationUrl) - SEMANTIC_PROPERTY(QUrl, modifyReservationUrl) - SEMANTIC_PROPERTY(QString, ticketToken) - SEMANTIC_PROPERTY(QUrl, url) -}; - -class LodgingReservation : protected Reservation -{ - SEMANTIC_GADGET - SEMANTIC_PROPERTY(QDateTime, checkinDate) - SEMANTIC_PROPERTY(QDateTime, checkoutDate) - - Q_PROPERTY(QString checkinDateLocalized READ checkinDateLocalized STORED false CONSTANT) - Q_PROPERTY(QString checkoutDateLocalized READ checkoutDateLocalized STORED false CONSTANT) -private: - QString checkinDateLocalized() const; - QString checkoutDateLocalized() const; -}; - -/** - * @see https://schema.org/FlightReservation - * @see https://developers.google.com/gmail/markup/reference/flight-reservation - */ -class FlightReservation : protected Reservation -{ - SEMANTIC_GADGET - - // Google extensions - SEMANTIC_PROPERTY(QString, airplaneSeat) - SEMANTIC_PROPERTY(QString, boardingGroup) - SEMANTIC_PROPERTY(QUrl, ticketDownloadUrl) -}; - -class TrainReservation : protected Reservation -{ - SEMANTIC_GADGET -}; - -class BusReservation : protected Reservation -{ - SEMANTIC_GADGET -}; - -Q_DECLARE_METATYPE(GeoCoordinates) -Q_DECLARE_METATYPE(Airport) -Q_DECLARE_METATYPE(Airline) -Q_DECLARE_METATYPE(Flight) -Q_DECLARE_METATYPE(FlightReservation) -Q_DECLARE_METATYPE(LodgingBusiness) -Q_DECLARE_METATYPE(LodgingReservation) -Q_DECLARE_METATYPE(PostalAddress) -Q_DECLARE_METATYPE(Seat) -Q_DECLARE_METATYPE(Ticket) -Q_DECLARE_METATYPE(TrainStation) -Q_DECLARE_METATYPE(TrainTrip) -Q_DECLARE_METATYPE(TrainReservation) -Q_DECLARE_METATYPE(BusStation) -Q_DECLARE_METATYPE(BusTrip) -Q_DECLARE_METATYPE(BusReservation) - -#undef SEMANTIC_GADGET - -#endif // DATATYPES_H diff --git a/plugins/messageviewer/bodypartformatter/semantic/datatypes.cpp b/plugins/messageviewer/bodypartformatter/semantic/datatypes.cpp deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/datatypes.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "datatypes.h" - -#include -#include - -#include - -GeoCoordinates::GeoCoordinates() - : m_latitude(NAN) - , m_longitude(NAN) -{ -} - -bool GeoCoordinates::isValid() const -{ - return !std::isnan(m_latitude) && !std::isnan(m_longitude); -} - -bool Place::operator!=(const Place &other) const -{ - return m_geo != other.m_geo || m_address != other.m_address; -} - -bool Airport::operator!=(const Airport &other) const -{ - return m_iataCode != other.m_iataCode || m_name != other.m_name || Place::operator!=(other); -} - -bool Airline::operator!=(const Airline &other) const -{ - return m_iataCode != other.m_iataCode || m_name != other.m_name; -} - -bool TrainStation::operator!=(const TrainStation &other) const -{ - return m_name != other.m_name; -} - -bool BusStation::operator!=(const BusStation &other) const -{ - return m_name != other.m_name; -} - -static QString localizedDateTime(const QDateTime &dt) -{ - auto s = QLocale().toString(dt, QLocale::ShortFormat); - if (dt.timeSpec() == Qt::TimeZone || dt.timeSpec() == Qt::OffsetFromUTC) { - s += QLatin1Char(' ') + dt.timeZone().abbreviation(dt); - } - return s; -} - -QString Flight::departureTimeLocalized() const -{ - return localizedDateTime(m_departureTime); -} - -QString Flight::arrivalTimeLocalized() const -{ - return localizedDateTime(m_arrivalTime); -} - -QString Flight::boardingTimeLocalized() const -{ - auto s = QLocale().toString(m_boardingTime.time(), QLocale::ShortFormat); - if (m_boardingTime.timeSpec() == Qt::TimeZone || m_boardingTime.timeSpec() == Qt::OffsetFromUTC) { - s += QLatin1Char(' ') + m_boardingTime.timeZone().abbreviation(m_boardingTime); - } - return s; -} - -QString LodgingReservation::checkinDateLocalized() const -{ - return QLocale().toString(m_checkinDate.date(), QLocale::ShortFormat); -} - -QString LodgingReservation::checkoutDateLocalized() const -{ - return QLocale().toString(m_checkoutDate.date(), QLocale::ShortFormat); -} - -QString TrainTrip::departureTimeLocalized() const -{ - return QLocale().toString(m_departureTime, QLocale::ShortFormat); -} - -QString TrainTrip::arrivalTimeLocalized() const -{ - return QLocale().toString(m_arrivalTime, QLocale::ShortFormat); -} - -QString BusTrip::departureTimeLocalized() const -{ - return QLocale().toString(m_departureTime, QLocale::ShortFormat); -} - -QString BusTrip::arrivalTimeLocalized() const -{ - return QLocale().toString(m_arrivalTime, QLocale::ShortFormat); -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractor.h b/plugins/messageviewer/bodypartformatter/semantic/extractor.h deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractor.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#ifndef EXTRACTOR_H -#define EXTRACTOR_H - -#include "extractorfilter.h" - -#include - -class ExtractorRule; -class QString; - -/** A single unstructured data extraction rule set. */ -class Extractor -{ -public: - Extractor(); - Extractor(const Extractor &) = delete; - Extractor(Extractor &&); - ~Extractor(); - - bool load(const QString &fileName); - - QString scriptFileName() const; - const std::vector &filters() const; - -private: - QString m_scriptName; - std::vector m_filters; -}; - -#endif // EXTRACTOR_H diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractor.cpp b/plugins/messageviewer/bodypartformatter/semantic/extractor.cpp deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractor.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "extractor.h" -#include "semantic_debug.h" - -#include -#include -#include -#include -#include -#include - -#include - -Extractor::Extractor() = default; -Extractor::Extractor(Extractor &&) = default; -Extractor::~Extractor() = default; - -bool Extractor::load(const QString &fileName) -{ - QFile file(fileName); - if (!file.open(QFile::ReadOnly)) { - return false; - } - - QJsonParseError error; - const auto doc = QJsonDocument::fromJson(file.readAll(), &error); - if (doc.isNull()) { - qCWarning(SEMANTIC_LOG) << "Extractor loading error:" << fileName << error.errorString(); - return false; - } - - const auto obj = doc.object(); - for (const auto &filterValue : obj.value(QLatin1String("filter")).toArray()) { - ExtractorFilter f; - if (!f.load(filterValue.toObject())) { - return false; - } - m_filters.push_back(std::move(f)); - } - - const auto scriptName = obj.value(QLatin1String("script")).toString(); - QFileInfo fi(fileName); - m_scriptName = fi.absolutePath() + QLatin1Char('/') + scriptName; - return !m_filters.empty() && !m_scriptName.isEmpty() && QFile::exists(m_scriptName); -} - -QString Extractor::scriptFileName() const -{ - return m_scriptName; -} - -const std::vector &Extractor::filters() const -{ - return m_filters; -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractorengine.h b/plugins/messageviewer/bodypartformatter/semantic/extractorengine.h deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractorengine.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#ifndef EXTRACTORENGINE_H -#define EXTRACTORENGINE_H - -#include "extractor.h" - -#include -#include - -#include - -class ContextObject; -class QDateTime; - -/** Code for executing an extractor rule set on a specific email part. */ -class ExtractorEngine -{ -public: - ExtractorEngine(); - ~ExtractorEngine(); - - void setExtractor(const Extractor *extractor); - void setText(const QString &text); - /** The date the email containing the processed text was sent. */ - void setSenderDate(const QDateTime &dt); - - QJsonArray extract(); - -private: - void executeScript(); - - const Extractor *m_extractor = nullptr; - ContextObject *m_context = nullptr; - QString m_text; - QJsonArray m_result; -}; - -#endif // EXTRACTORENGINE_H diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractorengine.cpp b/plugins/messageviewer/bodypartformatter/semantic/extractorengine.cpp deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractorengine.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "extractorengine.h" -#include "semantic_debug.h" - -#include -#include -#include -#include - -class JsApi : public QObject -{ - Q_OBJECT -public: - explicit JsApi(QJSEngine *engine) - : QObject(engine) - , m_engine(engine) - { - } - - Q_INVOKABLE QJSValue newObject(const QString &typeName) const; - Q_INVOKABLE QDateTime toDateTime(const QString &dtStr, const QString &format, const QString &localeName) const; - -private: - QJSEngine *m_engine; -}; - -QJSValue JsApi::newObject(const QString &typeName) const -{ - auto v = m_engine->newObject(); - v.setProperty(QStringLiteral("@type"), typeName); - return v; -} - -QDateTime JsApi::toDateTime(const QString &dtStr, const QString &format, const QString &localeName) const -{ - QLocale locale(localeName); - const auto dt = locale.toDateTime(dtStr, format); - if (dt.isValid()) { - return dt; - } - - // try harder for the "MMM" month format - // QLocale expects the exact string in QLocale::shortMonthName(), while we often encounter a three - // letter month identifier. For en_US that's the same, for Swedish it isn't though for example. So - // let's try to fix up the month identifiers to the full short name. - if (format.contains(QLatin1String("MMM"))) { - auto dtStrFixed = dtStr; - for (int i = 0; i < 12; ++i) { - const auto monthName = locale.monthName(i, QLocale::ShortFormat); - dtStrFixed = dtStrFixed.replace(monthName.left(3), monthName); - } - return locale.toDateTime(dtStrFixed, format); - } - return dt; -} - -class ContextObject : public QObject -{ - Q_OBJECT - Q_PROPERTY(QDateTime senderDate MEMBER m_senderDate) - -public: - QDateTime m_senderDate; -}; - -ExtractorEngine::ExtractorEngine() - : m_context(new ContextObject) // will be deleted by QJSEngine taking ownership -{ -} - -ExtractorEngine::~ExtractorEngine() = default; - -void ExtractorEngine::setExtractor(const Extractor *extractor) -{ - m_extractor = extractor; -} - -void ExtractorEngine::setText(const QString &text) -{ - m_text = text; -} - -void ExtractorEngine::setSenderDate(const QDateTime &dt) -{ - m_context->m_senderDate = dt; -} - -QJsonArray ExtractorEngine::extract() -{ - if (!m_extractor || m_text.isEmpty()) { - return {}; - } - - executeScript(); - return m_result; -} - -void ExtractorEngine::executeScript() -{ - Q_ASSERT(m_extractor); - - QFile f(m_extractor->scriptFileName()); - if (!f.open(QFile::ReadOnly)) { - qCWarning(SEMANTIC_LOG) << "Failed to open extractor script" << f.fileName() << f.errorString(); - return; - } - - QJSEngine engine; - engine.installExtensions(QJSEngine::ConsoleExtension); - auto jsApi = new JsApi(&engine); - engine.globalObject().setProperty(QStringLiteral("JsonLd"), engine.newQObject(jsApi)); - engine.globalObject().setProperty(QStringLiteral("Context"), engine.newQObject(m_context)); - auto result = engine.evaluate(QString::fromUtf8(f.readAll()), f.fileName()); - if (result.isError()) { - qCWarning(SEMANTIC_LOG) << "Script parsing error in" << result.property(QLatin1String("fileName")).toString() - << ':' << result.property(QLatin1String("lineNumber")).toInt() << result.toString(); - return; - } - - auto mainFunc = engine.globalObject().property(QLatin1String("main")); - if (!mainFunc.isCallable()) { - qCWarning(SEMANTIC_LOG) << "Script has no main() function!"; - return; - } - result = mainFunc.call({m_text}); - if (result.isError()) { - qCWarning(SEMANTIC_LOG) << "Script execution error in" << result.property(QLatin1String("fileName")).toString() - << ':' << result.property(QLatin1String("lineNumber")).toInt() << result.toString(); - return; - } - - m_result = QJsonArray::fromVariantList(result.toVariant().toList()); -} - -#include "extractorengine.moc" diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractorfilter.h b/plugins/messageviewer/bodypartformatter/semantic/extractorfilter.h deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractorfilter.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#ifndef EXTRACTORFILTER_H -#define EXTRACTORFILTER_H - -#include -#include - -class QJsonObject; - -/** Determines whether an extractor is applicable to a given email. */ -class ExtractorFilter -{ -public: - ExtractorFilter(); - ~ExtractorFilter(); - - const char *headerName() const; - bool matches(const QString &headerData) const; - bool load(const QJsonObject &obj); - -private: - QByteArray m_headerName; - QRegularExpression m_exp; -}; - -#endif // EXTRACTORFILTER_H diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractorfilter.cpp b/plugins/messageviewer/bodypartformatter/semantic/extractorfilter.cpp deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractorfilter.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "extractorfilter.h" - -#include - -ExtractorFilter::ExtractorFilter() = default; -ExtractorFilter::~ExtractorFilter() = default; - -const char *ExtractorFilter::headerName() const -{ - return m_headerName.constData(); -} - -bool ExtractorFilter::matches(const QString &headerData) const -{ - return m_exp.match(headerData).hasMatch(); -} - -bool ExtractorFilter::load(const QJsonObject &obj) -{ - m_headerName = obj.value(QLatin1String("header")).toString().toUtf8(); - m_exp.setPattern(obj.value(QLatin1String("match")).toString()); - return !m_headerName.isEmpty() && m_exp.isValid(); -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractorpostprocessor.h b/plugins/messageviewer/bodypartformatter/semantic/extractorpostprocessor.h deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractorpostprocessor.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#ifndef EXTRACTORPOSTPROCESSOR_H -#define EXTRACTORPOSTPROCESSOR_H - -#include -#include - -/** Post-process extracted data to filter out garbage and augment data from other sources. */ -class ExtractorPostprocessor -{ -public: - void process(const QVector &data); - QVector result() const; - -private: - QVariant processProperty(QVariant obj, const char *name, QVariant (ExtractorPostprocessor::*processor)(QVariant) const) const; - - QVariant processFlightReservation(QVariant res) const; - QVariant processFlight(QVariant flight) const; - QVariant processAirport(QVariant airport) const; - QVariant processAirline(QVariant airline) const; - void processFlightTime(QVariant &flight, const char *timePropName, const char *airportPropName) const; - QVariant processReservation(QVariant res) const; - - bool filterReservation(const QVariant &res) const; - bool filterLodgingReservation(const QVariant &res) const; - bool filterFlight(const QVariant &flight) const; - bool filterAirport(const QVariant &airport) const; - bool filterTrainOrBusTrip(const QVariant &trip) const; - bool filterTrainOrBusStation(const QVariant &station) const; - - QVector m_data; -}; - -#endif // EXTRACTORPOSTPROCESSOR_H diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractorpostprocessor.cpp b/plugins/messageviewer/bodypartformatter/semantic/extractorpostprocessor.cpp deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractorpostprocessor.cpp +++ /dev/null @@ -1,242 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "extractorpostprocessor.h" -#include "calendarhandler.h" -#include "datatypes.h" -#include "jsonlddocument.h" -#include "airportdb/airportdb.h" - -#include -#include - -#include - -void ExtractorPostprocessor::process(const QVector &data) -{ - m_data.reserve(data.size()); - for (auto d : data) { - if (d.userType() == qMetaTypeId()) { - d = processFlightReservation(d); - } else if (d.userType() == qMetaTypeId()) { - d = processReservation(d); - } else if (d.userType() == qMetaTypeId()) { - d = processReservation(d); - } else if (d.userType() == qMetaTypeId()) { - d = processReservation(d); - } - - if (filterReservation(d)) { - m_data.push_back(d); - } - } - - std::stable_sort(m_data.begin(), m_data.end(), [](const QVariant &lhs, const QVariant &rhs) { - return CalendarHandler::startDateTime(lhs) < CalendarHandler::startDateTime(rhs); - }); -} - -QVector ExtractorPostprocessor::result() const -{ - return m_data; -} - -QVariant ExtractorPostprocessor::processProperty(QVariant obj, const char *name, QVariant (ExtractorPostprocessor::*processor)(QVariant) const) const -{ - auto value = JsonLdDocument::readProperty(obj, name); - value = (this->*processor)(value); - JsonLdDocument::writeProperty(obj, name, value); - return obj; -} - -QVariant ExtractorPostprocessor::processFlightReservation(QVariant res) const -{ - res = processReservation(res); - res = processProperty(res, "reservationFor", &ExtractorPostprocessor::processFlight); - return res; -} - -QVariant ExtractorPostprocessor::processFlight(QVariant flight) const -{ - flight = processProperty(flight, "departureAirport", &ExtractorPostprocessor::processAirport); - flight = processProperty(flight, "arrivalAirport", &ExtractorPostprocessor::processAirport); - flight = processProperty(flight, "airline", &ExtractorPostprocessor::processAirline); - - processFlightTime(flight, "boardingTime", "departureAirport"); - processFlightTime(flight, "departureTime", "departureAirport"); - processFlightTime(flight, "arrivalTime", "arrivalAirport"); - - return flight; -} - -QVariant ExtractorPostprocessor::processAirport(QVariant airport) const -{ - // clean up name - const auto name = JsonLdDocument::readProperty(airport, "name").toString(); - JsonLdDocument::writeProperty(airport, "name", name.trimmed()); - - // complete missing IATA codes - auto iataCode = JsonLdDocument::readProperty(airport, "iataCode").toString(); - if (iataCode.isEmpty()) { - iataCode = AirportDb::iataCodeFromName(name).toString(); - if (!iataCode.isEmpty()) { - JsonLdDocument::writeProperty(airport, "iataCode", iataCode); - } - } - - // complete missing geo coordinates - auto geo = JsonLdDocument::readProperty(airport, "geo"); - if (!geo.value().isValid()) { - const auto coord = AirportDb::coordinateForAirport(AirportDb::IataCode{iataCode}); - if (coord.isValid()) { - geo = QVariant::fromValue(GeoCoordinates()); - JsonLdDocument::writeProperty(geo, "latitude", coord.latitude); - JsonLdDocument::writeProperty(geo, "longitude", coord.longitude); - JsonLdDocument::writeProperty(airport, "geo", geo); - } - } - - return airport; -} - -QVariant ExtractorPostprocessor::processAirline(QVariant airline) const -{ - const auto name = JsonLdDocument::readProperty(airline, "name").toString(); - JsonLdDocument::writeProperty(airline, "name", name.trimmed()); - return airline; -} - -void ExtractorPostprocessor::processFlightTime(QVariant &flight, const char *timePropName, const char *airportPropName) const -{ - const auto airport = JsonLdDocument::readProperty(flight, airportPropName); - const auto iataCode = JsonLdDocument::readProperty(airport, "iataCode").toString(); - if (iataCode.isEmpty()) { - return; - } - - auto dt = JsonLdDocument::readProperty(flight, timePropName).toDateTime(); - if (!dt.isValid() || dt.timeSpec() == Qt::TimeZone) { - return; - } - - const auto tz = AirportDb::timezoneForAirport(AirportDb::IataCode{iataCode}); - if (!tz.isValid()) { - return; - } - - // prefer our timezone over externally provided UTC offset, if they match - if (dt.timeSpec() == Qt::OffsetFromUTC && tz.offsetFromUtc(dt) != dt.offsetFromUtc()) { - return; - } - - dt.setTimeSpec(Qt::TimeZone); - dt.setTimeZone(tz); - // if we updated from UTC offset to timezone spec here, QDateTime will compare equal - // and the auto-generated property code will not actually update the property - // so, clear the property first to force an update - JsonLdDocument::writeProperty(flight, timePropName, QDateTime()); - JsonLdDocument::writeProperty(flight, timePropName, dt); -} - -QVariant ExtractorPostprocessor::processReservation(QVariant res) const -{ - const auto viewUrl = JsonLdDocument::readProperty(res, "url").toUrl(); - const auto modUrl = JsonLdDocument::readProperty(res, "modifyReservationUrl").toUrl(); - const auto cancelUrl = JsonLdDocument::readProperty(res, "cancelReservationUrl").toUrl(); - // remove duplicated urls - if (modUrl.isValid() && viewUrl == modUrl) { - JsonLdDocument::removeProperty(res, "modifyReservationUrl"); - } - if (cancelUrl.isValid() && viewUrl == cancelUrl) { - JsonLdDocument::removeProperty(res, "cancelReservationUrl"); - } - - // move ticketToken to Ticket (Google vs. schema.org difference) - const auto token = JsonLdDocument::readProperty(res, "ticketToken").toString(); - if (!token.isEmpty()) { - auto ticket = JsonLdDocument::readProperty(res, "reservedTicket"); - if (ticket.isNull()) { - ticket = QVariant::fromValue(Ticket{}); - } - if (JsonLdDocument::readProperty(ticket, "ticketToken").toString().isEmpty()) { - JsonLdDocument::writeProperty(ticket, "ticketToken", token); - JsonLdDocument::writeProperty(res, "reservedTicket", ticket); - } - } - - return res; -} - -bool ExtractorPostprocessor::filterReservation(const QVariant &res) const -{ - const auto resFor = JsonLdDocument::readProperty(res, "reservationFor"); - if (resFor.isNull()) { - return false; - } - - if (resFor.userType() == qMetaTypeId()) { - return filterFlight(resFor); - } else if (resFor.userType() == qMetaTypeId()) { - return filterTrainOrBusTrip(resFor); - } else if (resFor.userType() == qMetaTypeId()) { - return filterTrainOrBusTrip(resFor); - } - - if (res.userType() == qMetaTypeId()) { - return filterLodgingReservation(res); - } - return true; -} - -bool ExtractorPostprocessor::filterLodgingReservation(const QVariant &res) const -{ - const auto checkinDate = JsonLdDocument::readProperty(res, "checkinDate").toDateTime(); - const auto checkoutDate = JsonLdDocument::readProperty(res, "checkoutDate").toDateTime(); - return checkinDate.isValid() && checkoutDate.isValid(); -} - -bool ExtractorPostprocessor::filterFlight(const QVariant &flight) const -{ - const auto depDt = JsonLdDocument::readProperty(flight, "departureTime").toDateTime(); - const auto arrDt = JsonLdDocument::readProperty(flight, "arrivalTime").toDateTime(); - return filterAirport(JsonLdDocument::readProperty(flight, "departureAirport")) - && filterAirport(JsonLdDocument::readProperty(flight, "arrivalAirport")) - && depDt.isValid() && arrDt.isValid(); -} - -bool ExtractorPostprocessor::filterAirport(const QVariant &airport) const -{ - const auto iataCode = JsonLdDocument::readProperty(airport, "iataCode").toString(); - const auto name = JsonLdDocument::readProperty(airport, "name").toString(); - return !iataCode.isEmpty() || !name.isEmpty(); -} - -bool ExtractorPostprocessor::filterTrainOrBusTrip(const QVariant &trip) const -{ - const auto depDt = JsonLdDocument::readProperty(trip, "departureTime").toDateTime(); - const auto arrDt = JsonLdDocument::readProperty(trip, "arrivalTime").toDateTime(); - return filterTrainOrBusStation(JsonLdDocument::readProperty(trip, "departureStation")) - && filterTrainOrBusStation(JsonLdDocument::readProperty(trip, "arrivalStation")) - && depDt.isValid() && arrDt.isValid(); -} - -bool ExtractorPostprocessor::filterTrainOrBusStation(const QVariant &station) const -{ - return !JsonLdDocument::readProperty(station, "name").toString().isEmpty(); -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractorpreprocessor.h b/plugins/messageviewer/bodypartformatter/semantic/extractorpreprocessor.h deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractorpreprocessor.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#ifndef EXTRACTORPREPROCESSOR_H -#define EXTRACTORPREPROCESSOR_H - -#include - -/** Preprocessing of HTML and PDF attachments. */ -class ExtractorPreprocessor -{ -public: - void preprocessPlainText(const QString &input); - void preprocessHtml(const QString &input); - void preprocessPdf(const QByteArray &input); - - QString text() const; - -private: - void replaceEntityAndAppend(const QStringRef &source); - QString m_buffer; -}; - -#endif // EXTRACTORPREPROCESSOR_H diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractorpreprocessor.cpp b/plugins/messageviewer/bodypartformatter/semantic/extractorpreprocessor.cpp deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractorpreprocessor.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "config-semantic.h" - -#include "extractorpreprocessor.h" -#include "semantic_debug.h" - -#ifdef HAVE_POPPLER -#include -#endif - -#include - -void ExtractorPreprocessor::preprocessPlainText(const QString &input) -{ - m_buffer = input; -} - -void ExtractorPreprocessor::preprocessHtml(const QString &input) -{ - m_buffer.reserve(input.size()); - int begin = 0; - int end = input.indexOf(QLatin1Char('<'), begin); - while (begin < input.size() && end < input.size() && end >= 0 && begin >= 0) { - if (end > begin) { - replaceEntityAndAppend(input.midRef(begin, end - begin)); - } - begin = input.indexOf(QLatin1Char('>'), end); - if (begin < 0) { - break; - } - - // replace elements with something suitable for field separation - const auto elementName = input.mid(end + 1, begin - end - 1); - if (elementName.startsWith(QLatin1String("br"), Qt::CaseInsensitive)) { - m_buffer.append(QLatin1Char('\n')); - } else { - m_buffer.append(QLatin1Char(' ')); - } - - ++begin; - end = input.indexOf(QLatin1Char('<'), begin); - } - if (begin >= 0 && end < 0) { - replaceEntityAndAppend(input.midRef(begin)); - } - //qCDebug(SEMANTIC_LOG) << "Preprocessed HTML content: " << m_buffer; -} - -void ExtractorPreprocessor::preprocessPdf(const QByteArray &input) -{ -#ifdef HAVE_POPPLER - std::unique_ptr doc(Poppler::Document::loadFromData(input)); - if (!doc || doc->isLocked()) { - return; - } - - for (int i = 0, total = doc->numPages(); i < total; ++i) { - std::unique_ptr page(doc->page(i)); - m_buffer += page->text({}, Poppler::Page::PhysicalLayout); - } -#else - Q_UNUSED(input); -#endif -} - -QString ExtractorPreprocessor::text() const -{ - return m_buffer; -} - -void ExtractorPreprocessor::replaceEntityAndAppend(const QStringRef &source) -{ - int begin = 0; - int end = source.indexOf(QLatin1Char('&'), begin); - while (begin < source.size() && end < source.size() && end >= 0 && begin >= 0) { - if (end > begin) { - m_buffer.append(source.mid(begin, end - begin)); - } - begin = source.indexOf(QLatin1Char(';'), end); - if (begin < 0) { - break; - } - const auto entityName = source.mid(end + 1, begin - end - 1); - if (entityName == QLatin1String("nbsp")) { - m_buffer.append(QLatin1Char(' ')); - } else { - // keep unknown entities - m_buffer.append(source.mid(end, begin - end + 1)); - } - ++begin; - end = source.indexOf(QLatin1Char('&'), begin); - } - if (begin >= 0 && end < 0) { - m_buffer.append(source.mid(begin)); - } -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractorrepository.h b/plugins/messageviewer/bodypartformatter/semantic/extractorrepository.h deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractorrepository.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#ifndef EXTRACTORREPOSITORY_H -#define EXTRACTORREPOSITORY_H - -#include - -namespace KMime { -class Content; -} - -class Extractor; - -/** Collection of all unstructured data extractor rule sets. */ -class ExtractorRepository -{ -public: - ExtractorRepository(); - ~ExtractorRepository(); - ExtractorRepository(const ExtractorRepository &) = delete; - - /** Finds matching extractors for the given message part. */ - std::vector extractorsForMessage(KMime::Content *part) const; - -private: - void loadExtractors(); - - std::vector m_extractors; -}; - -#endif // EXTRACTORREPOSITORY_H diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractorrepository.cpp b/plugins/messageviewer/bodypartformatter/semantic/extractorrepository.cpp deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractorrepository.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "extractorrepository.h" -#include "extractor.h" -#include "semantic_debug.h" - -#include - -#include -#include - -ExtractorRepository::ExtractorRepository() -{ - loadExtractors(); -} - -ExtractorRepository::~ExtractorRepository() = default; - -std::vector ExtractorRepository::extractorsForMessage(KMime::Content *part) const -{ - std::vector v; - if (!part) { - return v; - } - - for (auto it = m_extractors.begin(), end = m_extractors.end(); it != end; ++it) { - for (const auto &filter : (*it).filters()) { - auto header = part->headerByType(filter.headerName()); - if (!header && part->topLevel()) { - header = part->topLevel()->headerByType(filter.headerName()); - } - if (!header) { - continue; - } - const auto headerData = header->asUnicodeString(); - if (filter.matches(headerData)) { - v.push_back(&(*it)); - break; - } - } - } - - return v; -} - -void ExtractorRepository::loadExtractors() -{ - auto searchDirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); - searchDirs += QStringLiteral(":/org.kde.pim"); - - for (const auto &dir : qAsConst(searchDirs)) { - QDirIterator it(dir + QStringLiteral("/messageviewer/semantic/extractors"), {QStringLiteral("*.json")}, QDir::Files); - while (it.hasNext()) { - Extractor e; - if (e.load(it.next())) { - m_extractors.push_back(std::move(e)); - } - } - } -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/amadeus.js b/plugins/messageviewer/bodypartformatter/semantic/extractors/amadeus.js deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/amadeus.js +++ /dev/null @@ -1,63 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -function main(text) { - var reservations = new Array(); - var bookingRef = text.match(/BOOKING REF: ([A-Z0-9]{6})/); - - var pos = 0; - while (true) { - var flightHeader = text.substr(pos).match(/FLIGHT *([A-Z0-9]{2}) ([0-9]{3,4}) - ([A-Za-z0-9 ]*?) .*([0-9]{4})\n/); - if (!flightHeader) - break; - var idx = flightHeader.index + flightHeader[0].length; - - var res = JsonLd.newObject("FlightReservation"); - res.reservationNumber = bookingRef[1]; - res.reservationFor = JsonLd.newObject("Flight"); - res.reservationFor.airline = JsonLd.newObject("Airline"); - res.reservationFor.airline.iataCode = flightHeader[1]; - res.reservationFor.airline.name = flightHeader[3]; - res.reservationFor.flightNumber = flightHeader[2]; - - // TODO support line continuation for DEPARTURE/ARRIVAL - var depLine = text.substr(pos + idx).match(/DEPARTURE: +(.*?) [ -] *([0-9]{2} [A-Z]{3}) ([0-9]{2}:[0-9]{2})/); - if (!depLine) - break; - idx = depLine.index + depLine[0].length; - res.reservationFor.departureAirport = JsonLd.newObject("Airport"); - res.reservationFor.departureAirport.name = depLine[1]; - res.reservationFor.departureTime = JsonLd.toDateTime(depLine[2] + ' ' + flightHeader[4] + ' ' + depLine[3], "dd MMM yyyy hh:mm", "en"); - - var arrLine = text.substr(pos + idx).match(/ARRIVAL: +(.*?) [ -] *([0-9]{2} [A-Z]{3}) ([0-9]{2}:[0-9]{2})/); - if (!arrLine) - break; - idx = arrLine.index + arrLine[0].length; - res.reservationFor.arrivalAirport = JsonLd.newObject("Airport"); - res.reservationFor.arrivalAirport.name = arrLine[1]; - res.reservationFor.arrivalTime = JsonLd.toDateTime(arrLine[2] + ' ' + flightHeader[4] + ' ' + arrLine[3], "dd MMM yyyy hh:mm", "en"); - - reservations.push(res); - if (idx == 0) - break; - pos += idx; - } - - return reservations; -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/amadeus.json b/plugins/messageviewer/bodypartformatter/semantic/extractors/amadeus.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/amadeus.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "filter": [ - { "header": "From", "match": "@amadeus.com" } - ], - "script": "amadeus.js" -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/brusselsairlines.js b/plugins/messageviewer/bodypartformatter/semantic/extractors/brusselsairlines.js deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/brusselsairlines.js +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -function main(text) { - var reservations = new Array(); - var bookingRef = text.match(/Booking reference:\s+([A-Z0-9]{6})/); - - var pos = 0; - while (true) { - var header = text.substr(pos).match(/Departure|Return/); - if (!header) - break; - var idx = header.index + header[0].length; - - var res = JsonLd.newObject("FlightReservation"); - res.reservationNumber = bookingRef[1]; - res.reservationFor = JsonLd.newObject("Flight"); - - var depAirport = text.substr(pos + idx).match(/([A-Z][\S ]*)\n/); - if (!depAirport) - break; - idx += depAirport.index + depAirport[0].length; - res.reservationFor.departureAirport = JsonLd.newObject("Airport"); - res.reservationFor.departureAirport.name = depAirport[1].trim(); - - var depTime = text.substr(pos + idx).match(/([0-9]{2} [A-Za-z]{3} [0-9]{4}),\s*([0-9]{2}:[0-9]{2})/); - if (!depTime) - break; - idx += depTime.index + depTime[0].length; - res.reservationFor.departureTime = JsonLd.toDateTime(depTime[1] + ' ' + depTime[2], "dd MMM yyyy hh:mm", "en"); - - var arrAirport = text.substr(pos + idx).match(/([A-Z][\S ]*)\n/); - if (!arrAirport) - break; - idx += arrAirport.index + arrAirport[0].length; - res.reservationFor.arrivalAirport = JsonLd.newObject("Airport"); - res.reservationFor.arrivalAirport.name = arrAirport[1].trim(); - - var arrTime = text.substr(pos + idx).match(/([0-9]{2} [A-Za-z]{3} [0-9]{4}),\s*([0-9]{2}:[0-9]{2})/); - if (!arrTime) - break; - idx += arrTime.index + arrTime[0].length; - res.reservationFor.arrivalTime = JsonLd.toDateTime(arrTime[1] + ' ' + arrTime[2], "dd MMM yyyy hh:mm", "en"); - - var airline = text.substr(pos + idx).match(/([A-Z0-9]{2}) ([0-9]{3,4})\s*([A-Z][A-Za-z0-9 ]*)\n/); - if (!airline) - break; - idx += airline.index + airline[0].length; - res.reservationFor.airline = JsonLd.newObject("Airline"); - res.reservationFor.airline.iataCode = airline[1]; - res.reservationFor.airline.name = airline[3]; - res.reservationFor.flightNumber = airline[2]; - - reservations.push(res); - if (idx == 0) - break; - pos += idx; - } - - return reservations; -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/brusselsairlines.json b/plugins/messageviewer/bodypartformatter/semantic/extractors/brusselsairlines.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/brusselsairlines.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "filter": [ - { "header": "From", "match": "@brusselsairlines.com" } - ], - "script": "brusselsairlines.js" -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/czechrailways.js b/plugins/messageviewer/bodypartformatter/semantic/extractors/czechrailways.js deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/czechrailways.js +++ /dev/null @@ -1,155 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - Copyright (c) 2018 Daniel Vrátil - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -function isHeaderOrFooter(line) { - return line.search(/(Jízdní řád( a rezervace)?|Jízdenku lze použít po stejné trase|Jízdní doklad zakoupený u obchodníka)/) >= 0; -} - -function createSeat(res) -{ - if (!res.reservedTicket) - res.reservedTicket = JsonLd.newObject("Ticket"); - if (!res.reservedTicket.ticketedSeat) - res.reservedTicket.ticketedSeat = JsonLd.newObject("Seat"); -} - -function parseSeat(res, text) { - var coach = text.match(/(\s+)(\d+)/); - var idx = 0; - if (coach) { - createSeat(res); - res.reservedTicket.ticketedSeat.seatSection = coach[2]; - idx = coach.index + coach[1].length + coach[2].length; - } - var seat = text.substr(idx).match(/\s+(\d+)/); - if (seat) { - createSeat(res); - res.reservedTicket.ticketedSeat.seatNumber = seat[1]; - } -} - -// There's no validity year anywhere in the ticket, so we take the purchase date and -// if the trip month and day are after the purchase month and day we assume the -// the ticket will become valid the same year it was purchased, otherwise we assume -// the ticket is for next year. -// This fails when you buy the ticket more than a year ahead of the trip, but I doubt -// you can even do that with Czech Railways... -function detectYear(tripDate, purchaseDate) -{ - var tripDay = parseInt(tripDate[1]); - var tripMonth = parseInt(tripDate[2]); - var purchaseDay = parseInt(purchaseDate[2]); - var purchaseMonth = parseInt(purchaseDate[3]); - var purchaseYear = parseInt(purchaseDate[4]); - - if ((purchaseMonth < tripMonth) || - (purchaseMonth == tripMonth) && (purchaseDay <= tripDay)) { - return purchaseYear; - } else { - return purchaseYear + 1; - } -} - -function parseDeparture(res, line, purchaseDate) { - res.reservationFor.departureStation = JsonLd.newObject("TrainStation"); - var station = line.match(/^(.+?) /); - if (!station) - return; - var idx = station.index + station[0].length; - res.reservationFor.departureStation.name = station[1]; - var dt = line.substr(idx).match(/([0-9]{2})\.([0-9]{2})\. ([0-9]{2}:[0-9]{2})/); - if (dt) { - idx += dt.index + dt[0].length; - res.reservationFor.departureTime = JsonLd.toDateTime(dt[1] + ' ' + dt[2] + ' ' + detectYear(dt, purchaseDate) + ' ' + dt[3], "dd MM yyyy hh:mm", "cs"); - } - var trainId = line.substr(idx).match(/([a-zA-Z]+ [0-9a-zA-Z]+)/); - if (trainId) { - idx += trainId.index + trainId[0].length - res.reservationFor.trainNumber = trainId[1]; - } - parseSeat(res, line.substr(idx)); -} - -function parseArrival(res, line, purchaseDate) { - res.reservationFor.arrivalStation = JsonLd.newObject("TrainStation"); - var station = line.match(/^(.+?) /); - if (!station) - return; - var idx = station.index + station[0].length; - res.reservationFor.arrivalStation.name = station[1]; - var dt = line.substr(idx).match(/([0-9]{2})\.([0-9]{2})\. ([0-9]{2}:[0-9]{2})/); - if (dt) { - idx += dt.index + dt[0].length; - res.reservationFor.arrivalTime = JsonLd.toDateTime(dt[1] + ' ' + dt[2] + ' ' + detectYear(dt, purchaseDate) + ' ' + dt[3], "dd MM yyyy hh:mm", "cs"); - } -} - -function parseLegs(text, purchaseDate) { - var reservations = new Array(); - var lines = text.split('\n'); - var depIdx = 1, arrIdx = 2; - while (depIdx < lines.length) { - // stop when reaching the footer or the next itinerary header - if (isHeaderOrFooter(lines[depIdx])) - return reservations; - - var res = JsonLd.newObject("TrainReservation"); - res.reservationFor = JsonLd.newObject("TrainTrip"); - - arrIdx = depIdx + 1; - parseDeparture(res, lines[depIdx], purchaseDate); - parseArrival(res, lines[arrIdx], purchaseDate); - depIdx = arrIdx + 1; - // Find the next leg - while (lines[depIdx].startsWith(" ")) { - depIdx += 1; - } - - reservations.push(res); - } - - return reservations; -} - -function main(text) { - var reservations = new Array(); - var pos = 0; - - var purchaseDate = text.match(/([d|D]atum platby|UZP): ([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{4})/) - - while (true) { - // find itinerary headers - var header = text.substr(pos).match(/Timetable( and Reservations)?/); - if (!header) - break; - var idx = header.index + header[0].length; - var timetableHeader = text.substr(pos + idx).match(/(Místo \/ Seat \/ Sitzplatz)/) - idx = idx + timetableHeader.index + timetableHeader[0].length; - reservations = reservations.concat(parseLegs(text.substr(pos + idx), purchaseDate)); - if (idx == 0) - break; - pos += idx + 1; - } - - var bookingRef = text.match(/Kód transakce:\s*([A-Z0-9]{6})\n/); - for (var i = 0; bookingRef && i < reservations.length; ++i) - reservations[i].reservationNumber = bookingRef[1]; - return reservations; -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/czechrailways.json b/plugins/messageviewer/bodypartformatter/semantic/extractors/czechrailways.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/czechrailways.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "filter": [ - { "header": "From", "match": "info@cd.cz" }, - { "header": "From", "match": "eshop@cd.cz" } - ], - "script": "czechrailways.js" -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/deutschebahn.js b/plugins/messageviewer/bodypartformatter/semantic/extractors/deutschebahn.js deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/deutschebahn.js +++ /dev/null @@ -1,154 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -function isHeaderOrFooter(line) { - return line.search(/(Ihre Reiseverbindung|Wichtige Nutzungshinweise|Hinweise:|Seite \d \/ \d)/) >= 0; -} - -function createSeat(res) -{ - if (!res.reservedTicket) - res.reservedTicket = JsonLd.newObject("Ticket"); - if (!res.reservedTicket.ticketedSeat) - res.reservedTicket.ticketedSeat = JsonLd.newObject("Seat"); -} - -function parseSeat(res, text) { - var coach = text.match(/Wg. (\d+)/); - if (coach) { - createSeat(res); - res.reservedTicket.ticketedSeat.seatSection = coach[1]; - } - var seat = text.match(/Pl. (\d+)/); - if (seat) { - createSeat(res); - res.reservedTicket.ticketedSeat.seatNumber = seat[1]; - } -} - -function parseDeparture(res, line, year, compact) { - res.reservationFor.departureStation = JsonLd.newObject("TrainStation"); - var station = line.match(/^(.+?) /); - if (!station) - return; - var idx = station.index + station[0].length; - res.reservationFor.departureStation.name = station[1]; - var dt = line.substr(idx).match(/([0-9]{2})\.([0-9]{2})\. +ab ([0-9]{2}:[0-9]{2})/); - if (dt) { - idx += dt.index + dt[0].length; - res.reservationFor.departureTime = JsonLd.toDateTime(dt[1] + ' ' + dt[2] + ' ' + year + ' ' + dt[3], "dd MM yyyy hh:mm", "de"); - } - var platform = line.substr(idx).match(/^ {1,3}(.*?)(?=( | IC|$))/); - if (platform) { - idx += platform.index + platform[0].length; - res.reservationFor.departurePlatform = platform[1]; - } - var trainId = line.substr(idx).match(compact ? / +([^,]*?)(?=(,|$))/ : / +(.*?)(?=( |$))/); - if (trainId) { - idx += trainId.index + trainId[0].length - res.reservationFor.trainNumber = trainId[1]; - } - parseSeat(res, line.substr(idx)); -} - -function parseArrival(res, line, year) { - res.reservationFor.arrivalStation = JsonLd.newObject("TrainStation"); - var station = line.match(/^(.+?) /); - if (!station) - return; - var idx = station.index + station[0].length; - res.reservationFor.arrivalStation.name = station[1]; - var dt = line.substr(idx).match(/([0-9]{2})\.([0-9]{2})\. +an ([0-9]{2}:[0-9]{2})/); - if (dt) { - idx += dt.index + dt[0].length; - res.reservationFor.arrivalTime = JsonLd.toDateTime(dt[1] + ' ' + dt[2] + ' ' + year + ' ' + dt[3], "dd MM yyyy hh:mm", "de"); - } - var platform = line.substr(idx).match(/^ {1,3}(.*?)(?=( | IC|$))/); - if (platform) { - idx += platform.index + platform[0].length; - res.reservationFor.arrivalPlatform = platform[1]; - } - parseSeat(res, line.substr(idx)); -} - -function parseLegs(text, year, compact) { - var reservations = new Array(); - var lines = text.split('\n'); - for (var i = 0; compact && i < lines.length; ++i) - lines[i] = lines[i].substr(6); - - var depIdx = 0, arrIdx = 1; - while (depIdx < lines.length) { - var res = JsonLd.newObject("TrainReservation"); - res.reservationFor = JsonLd.newObject("TrainTrip"); - - // stop when reaching the footer or the next itinerary header - if (isHeaderOrFooter(lines[depIdx])) - return reservations; - - arrIdx = depIdx + 1; - while (arrIdx < lines.length && lines[arrIdx].startsWith(' ')) // line continuations for departure, we still need to handle that correctly - ++arrIdx; - parseDeparture(res, lines[depIdx], year, compact); - parseArrival(res, lines[arrIdx], year); - depIdx = arrIdx + 1; - while (depIdx < lines.length && lines[depIdx].startsWith(' ') && !isHeaderOrFooter(lines[depIdx])) // line continuations for arrival, dito - ++depIdx; - reservations.push(res); - } - - return reservations; -} - -function main(text) { - var reservations = new Array(); - var pos = 0; - while (true) { - // find itinerary headers - var header = text.substr(pos).match(/Ihre Reiseverbindung[\S ]+(Hin|Rück)fahrt am [0-9]{2}.[0-9]{2}.([0-9]{4}).*\n/); - if (!header) - break; - var idx = header.index + header[0].length; - var year = header[2]; - - // determine ticket type - var domesticHeader = text.substr(pos + idx).match(/ Reservierung\n/); - var intlHeader = text.substr(pos + idx).match(/(Produkte\/Reservierung|Fahrt\/Reservierung).*\n/); - if (domesticHeader) { - idx += domesticHeader.index + domesticHeader[0].length; - reservations = reservations.concat(parseLegs(text.substr(pos + idx), year, false)); - } else if (intlHeader) { - idx += intlHeader.index + intlHeader[0].length; - reservations = reservations.concat(parseLegs(text.substr(pos + idx), year, true)); - } else { - break; - } - - if (idx == 0) - break; - pos += idx; - } - - // international tickets have the booking reference somewhere on the side, so we don't really know - // where it is relative to the itinerary - var bookingRef = text.match(/Auftragsnummer:\s*([A-Z0-9]{6})\n/); - for (var i = 0; i < reservations.length; ++i) - reservations[i].reservationNumber = bookingRef[1]; - return reservations; -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/deutschebahn.json b/plugins/messageviewer/bodypartformatter/semantic/extractors/deutschebahn.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/deutschebahn.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "filter": [ - { "header": "From", "match": "buchungsbestaetigung@bahn.de" } - ], - "script": "deutschebahn.js" -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/eurowings.js b/plugins/messageviewer/bodypartformatter/semantic/extractors/eurowings.js deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/eurowings.js +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -function main(text) { - var reservations = new Array(); - var bookingRef = text.match(/Individual reservation code:\s*\*\* ([A-Z0-9]{6})/); - - var pos = 0; - while (true) { - var flightLine = text.substr(pos).match(/Flight: ([0-9]{2}\.[0-9]{2}\.[0-9]{4})\s*\|\s*([A-Z0-9]{2}) ([0-9]{3,4}).*\n/); - if (!flightLine) - break; - var idx = flightLine.index + flightLine[0].length; - - var res = JsonLd.newObject("FlightReservation"); - res.reservationNumber = bookingRef[1]; - res.reservationFor = JsonLd.newObject("Flight"); - res.reservationFor.flightNumber = flightLine[3]; - - res.reservationFor.airline = JsonLd.newObject("Airline"); - res.reservationFor.airline.iataCode = flightLine[2]; - - var opByLine = text.substr(pos + idx).match(/^\s*\* operated by (.*)\n/); - if (opByLine) { - idx += opByLine.index + opByLine[0].length; - res.reservationFor.airline.name = opByLine[1]; - } - - var depLine = text.substr(pos + idx).match(/Departure:\s*([0-9]{2}:[0-9]{2})\s+(.*)\n/); - if (!depLine) - break; - idx += depLine.index + depLine[0].length; - res.reservationFor.departureTime = JsonLd.toDateTime(flightLine[1] + ' ' + depLine[1], "dd.MM.yyyy hh:mm", "en"); - res.reservationFor.departureAirport = JsonLd.newObject("Airport"); - res.reservationFor.departureAirport.name = depLine[2]; - - var arrLine = text.substr(pos + idx).match(/Arrival:\s*([0-9]{2}:[0-9]{2})\s+(.*)\n/); - if (!arrLine) - break; - idx += arrLine.index + arrLine[0].length; - res.reservationFor.arrivalTime = JsonLd.toDateTime(flightLine[1] + ' ' + arrLine[1], "dd.MM.yyyy hh:mm", "en"); - res.reservationFor.arrivalAirport = JsonLd.newObject("Airport"); - res.reservationFor.arrivalAirport.name = arrLine[2]; - - reservations.push(res); - if (idx == 0) - break; - pos += idx; - } - - return reservations; -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/eurowings.json b/plugins/messageviewer/bodypartformatter/semantic/extractors/eurowings.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/eurowings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "filter": [ - { "header": "From", "match": "@booking.eurowings.com" } - ], - "script": "eurowings.js" -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/extractors.qrc b/plugins/messageviewer/bodypartformatter/semantic/extractors/extractors.qrc deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/extractors.qrc +++ /dev/null @@ -1,26 +0,0 @@ - - - amadeus.json - amadeus.js - brusselsairlines.json - brusselsairlines.js - czechrailways.json - czechrailways.js - deutschebahn.json - deutschebahn.js - eurowings.json - eurowings.js - fcmtravel.json - fcmtravel.js - iberia.json - iberia.js - klm.json - klm.js - regiojet.json - regiojet.js - sncf.json - sncf.js - swiss.json - swiss.js - - diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/fcmtravel.js b/plugins/messageviewer/bodypartformatter/semantic/extractors/fcmtravel.js deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/fcmtravel.js +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -var regExMap = new Array(); -regExMap['en_US'] = new Array(); -regExMap['en_US']['bookingRef'] = /[Bb]ooking reference: ([A-Z0-9]{6})/; -regExMap['en_US']['flightLine'] = /Flight:\s+([A-Z0-9]{2}) *([0-9]{2,4}), ([A-Za-z0-9 ]*)\n/; -regExMap['en_US']['date'] = /Date: *[A-Z][a-z]{2} (.*)\n/; -regExMap['en_US']['departure'] = /Departure: *([0-9]+:[0-9]+) *(.*) *\(([A-Z]{3})\)/; -regExMap['en_US']['arrival'] = /Arrival: *([0-9]+:[0-9]+) *(.*) *\(([A-Z]{3})\)/; -regExMap['sv_SE'] = new Array(); -regExMap['sv_SE']['bookingRef'] = /[Bb]okningsreferens: ([A-Z0-9]{6})/; -regExMap['sv_SE']['flightLine'] = /Flyg:\s+([A-Z0-9]{2}) *([0-9]{2,4}), ([A-Za-z0-9 ]*)\n/; -regExMap['sv_SE']['date'] = /Datum: *.{3} (.*)\n/; -regExMap['sv_SE']['departure'] = /Avgång: *([0-9]+:[0-9]+) *(.*) *\(([A-Z]{3})\)/; -regExMap['sv_SE']['arrival'] = /Ankomst: *([0-9]+:[0-9]+) *(.*) *\(([A-Z]{3})\)/; - -function main(text) { - var reservations = new Array(); - - for (var locale in regExMap) { - var bookingRef = text.match(regExMap[locale]['bookingRef']); - if (!bookingRef) - continue; - - var pos = 0; - while (true) { - var flightLine = text.substr(pos).match(regExMap[locale]['flightLine']); - if (!flightLine) - break; - var index = flightLine.index + flightLine[0].length; - - var res = JsonLd.newObject("FlightReservation"); - res.reservationNumber = bookingRef[1]; - res.reservationFor = JsonLd.newObject("Flight"); - res.reservationFor.flightNumber = flightLine[2]; - res.reservationFor.airline = JsonLd.newObject("Airline"); - res.reservationFor.airline.iataCode = flightLine[1]; - res.reservationFor.airline.name = flightLine[3]; - - var depDate = text.substr(pos + index).match(regExMap[locale]['date']); - if (depDate) - index += depDate.index + depDate[0].length; - var depLine = text.substr(pos + index).match(regExMap[locale]['departure']); - if (!depLine) - break; - index += depLine.index + depLine[0].length; - res.reservationFor.departureTime = JsonLd.toDateTime(depDate[1] + " " + depLine[1], "d MMM yyyy hh:mm", locale); - res.reservationFor.departureAirport = JsonLd.newObject("Airport"); - res.reservationFor.departureAirport.name = depLine[2]; - res.reservationFor.departureAirport.iataCode = depLine[3]; - - var arrDate = text.substr(pos + index).match(regExMap[locale]['date']); - if (arrDate) - index += arrDate.index + arrDate[0].length; - var arrLine = text.substr(pos + index).match(regExMap[locale]['arrival']); - if (!arrLine) - break; - index += arrLine.index + arrLine[0].length; - res.reservationFor.arrivalTime = JsonLd.toDateTime(arrDate[1] + " " + arrLine[1], "d MMM yyyy hh:mm", locale); - res.reservationFor.arrivalAirport = JsonLd.newObject("Airport"); - res.reservationFor.arrivalAirport.name = arrLine[2]; - res.reservationFor.arrivalAirport.iataCode = arrLine[3]; - - reservations.push(res); - if (index == 0) - break; - pos += index; - } - - if (reservations.length > 0) - break; - } - - return reservations; -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/fcmtravel.json b/plugins/messageviewer/bodypartformatter/semantic/extractors/fcmtravel.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/fcmtravel.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "filter": [ - { "header": "From", "match": "@fcmtravel\." }, - { "header": "From", "match": "@travellink\." } - ], - "script": "fcmtravel.js" -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/iberia.js b/plugins/messageviewer/bodypartformatter/semantic/extractors/iberia.js deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/iberia.js +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -function parseDate(dateStr, timeStr) { - // the text does not contain the year at all, so guess that from Context.senderDate - var date = JsonLd.toDateTime(dateStr + '-' + Context.senderDate.getFullYear() + ' ' + timeStr, "dd-MMM-yyyy hh:mm", "en"); - if (date < Context.senderDate) - date.setFullYear(Context.senderDate.getFullYear() + 1); - return date; -} - -function main(text) { - var reservations = new Array(); - - var bookingRef = text.match(/Booking code\n.*([0-9A-z]{6})\n/); - if (!bookingRef) - return reservations; - - var pos = bookingRef.index + bookingRef[0].length; - while (true) { - var firstLine = text.substr(pos).match(/From +([A-Z]{2})(\d{2,4}) +(\d{1,2}-\w{3}) +(\d{1,2}-\w{3}).*\n/); - if (!firstLine) - break; - var index = firstLine.index + firstLine[0].length; - - var res = JsonLd.newObject("FlightReservation"); - res.reservationNumber = bookingRef[1]; - res.reservationFor = JsonLd.newObject("Flight"); - res.reservationFor.flightNumber = firstLine[2]; - res.reservationFor.airline = JsonLd.newObject("Airline"); - res.reservationFor.airline.iataCode = firstLine[1]; - - var secondLine = text.substr(pos + index).match(/^ (\w+) \(([A-Z]{3})\) +(\d{2}:\d{2}) + (\d{2}:\d{2}) .*\n/); - if (!secondLine) - break; - index += secondLine.index + secondLine[0].length; - - res.reservationFor.departureAirport = JsonLd.newObject("Airport"); - res.reservationFor.departureAirport.name = secondLine[1]; - res.reservationFor.departureAirport.iataCode = secondLine[2]; - res.reservationFor.departureTime = parseDate(firstLine[3], secondLine[3]); - res.reservationFor.arrivalTime = parseDate(firstLine[4], secondLine[4]); - - var fourthLine = text.substr(pos + index).match(/^.*\n (\w+) \(([A-Z]{3})\) .*\n/); - if (!fourthLine) - break; - index += fourthLine.index + fourthLine[0].length; - - res.reservationFor.arrivalAirport = JsonLd.newObject("Airport"); - res.reservationFor.arrivalAirport.name = fourthLine[1]; - res.reservationFor.arrivalAirport.iataCode = fourthLine[2]; - - var opByLine = text.substr(pos + index).match(/^.*Operated by\n +: (.*)\n/); - if (opByLine) { - index += opByLine.index + opByLine[0].length; - res.reservationFor.airline.name = opByLine[1]; - } - - reservations.push(res); - if (index == 0) - break; - pos += index; - } - - return reservations; -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/iberia.json b/plugins/messageviewer/bodypartformatter/semantic/extractors/iberia.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/iberia.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "filter": [ - { "header": "From", "match": "@iberia.com" } - ], - "script": "iberia.js" -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/klm.js b/plugins/messageviewer/bodypartformatter/semantic/extractors/klm.js deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/klm.js +++ /dev/null @@ -1,73 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -function main(text) { - var reservations = new Array(); - var bookingRef = text.match(/Flug - Buchungscode\s+([0-9A-z]{6})/); - console.warn(bookingRef); - if (!bookingRef) - return reservations; - - var pos = bookingRef.index + bookingRef[0].length; - while (true) { - var departure = text.substr(pos).match(/[A-Z][a-z] (\d{1,2} \w{3} \d{2})\s+(\d{2}:\d{2})\s+(.+?)\n\t+\((.+?)\)\n/); - console.warn("departure", departure); - if (!departure) - break; - var index = departure.index + departure[0].length; - - var res = JsonLd.newObject("FlightReservation"); - res.reservationNumber = bookingRef[1]; - res.reservationFor = JsonLd.newObject("Flight"); - res.reservationFor.departureTime = JsonLd.toDateTime(departure[1] + ' ' + departure[2], "d MMM yy hh:mm", "en"); - res.reservationFor.departureAirport = JsonLd.newObject("Airport"); - res.reservationFor.departureAirport.name = departure[3] + ", " + departure[4]; - - var arrival = text.substr(pos + index).match(/[A-Z][a-z] (\d{1,2} \w{3} \d{2})\s+(\d{2}:\d{2})\s+(.+?)\n\s+\((.+?)\)\n/); - console.warn("arrivla", arrival); - if (!arrival) - break; - index += arrival.index + arrival[1].length; - - res.reservationFor.arrivalTime = JsonLd.toDateTime(arrival[1] + ' ' + arrival[2], "d MMM yy hh:mm", "en"); - res.reservationFor.arrivalAirport = JsonLd.newObject("Airport"); - res.reservationFor.arrivalAirport.name = arrival[3] + ", " + arrival[4]; - - var flightNumber = text.substr(pos + index).match(/Flugnummer: ([A-Z]{2}) (\d{2,4})\n/); - console.warn("details", flightNumber); - if (!flightNumber) - break; - index += flightNumber.index + flightNumber[0].length; - res.reservationFor.flightNumber = flightNumber[2]; - res.reservationFor.airline = JsonLd.newObject("Airline"); - res.reservationFor.airline.iataCode = flightNumber[1]; - - var opBy = text.substr(pos + index).match(/Durchgeführt von: (.*?)\n/); - if (!opBy) - break; - index += opBy.index + opBy[0].length; - res.reservationFor.airline.name = opBy[1]; - - reservations.push(res); - if (index == 0) - break; - pos += index; - } - return reservations; -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/klm.json b/plugins/messageviewer/bodypartformatter/semantic/extractors/klm.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/klm.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "filter": [ - { "header": "From", "match": "noreply@klm.com" } - ], - "script": "klm.js" -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/regiojet.js b/plugins/messageviewer/bodypartformatter/semantic/extractors/regiojet.js deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/regiojet.js +++ /dev/null @@ -1,217 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - Copyright (c) 2018 Daniel Vrátil - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -var regExMap = new Array(); -regExMap["cs_CZ"] = new Array(); -regExMap["cs_CZ"]["ticketId"] = /Elektronická jízdenka č\.\s+([0-9]+)/; -regExMap["cs_CZ"]["singleTripHeader"] = /Cesta/; -regExMap["cs_CZ"]["thereTripHeader"] = /Cesta tam/; -regExMap["cs_CZ"]["returnTripHeader"] = /Cesta zpět/; -regExMap["cs_CZ"]["columns"] = [ /Datum/, /Zastávka\/Přestup/, /Příjezd/, /Odjezd/, /Nást\./, /Spoj/, /Vůz\/sedadla/ ]; -regExMap["cs_CZ"]["date"] = /([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{2})/; -regExMap["en_US"] = new Array(); -regExMap["en_US"]["ticketId"] = /Electronic ticket\s+([0-9]+)/; -regExMap["en_US"]["singleTripHeader"] = /Route/; -regExMap["en_US"]["thereTripHeader"] = /Route there/; -regExMap["en_US"]["returnTripHeader"] = /Route back/; -regExMap["en_US"]["columns"] = [ /Date/, /Station\/Transfer/, /Arrival/, /Departure/, /Platf\./, /Connection/, /Coach\/Seats/ ]; -regExMap["en_US"]["date"] = /([0-9]{2})\/([0-9]{2})\/([0-9]{2})/; - -function padDigit(s) { - while (s.length < 2) { - s = '0' + s; - } - return s; -} - -function parseDate(date, time, locale) { - var d = date.match(regExMap[locale]["date"]); - var t = time.match(/([0-9]{1,2}):([0-9]{1,2})/); - if (!d || !t) { - return null; - } - return JsonLd.toDateTime(padDigit(d[1]) + "." + padDigit(d[2]) + ".20" + d[3] + " " - + padDigit(t[1]) + ":" + padDigit(t[2]), - "dd.MM.yyyy HH:mm", locale); -} - -var Columns = Object.freeze({ - Date: 0, - Station: 1, - ArrivalTime: 2, - DepartureTime: 3, - Platform: 4, - Connection: 5, - Seat: 6, - - ColumnCount: 7 -}); - -function columnValue(line, columns, column, locale) { - var start = columns.match(regExMap[locale]["columns"][column]); - if (!start) { - return ""; - } - if (column < Columns.ColumnCount - 1) { - var end = columns.match(regExMap[locale]["columns"][column + 1]); - if (!end) { - return ""; - } - return line.substr(start.index, end.index - start.index).trim(); - } else { - return line.substr(start.index).trim(); - } -} - -function parseTrip(trip, locale) { - var text = trip.split("\n") - var columns = text[0]; - var reservations = new Array(); - var transportType = "Bus"; - for (var i = 1; i < text.length; i++) { - // Skip the destination arrival part, we already populated it as part - // of completing the previous departure line - if (i < text.length - 1 && !text[i + 1]) { - break; - } - - var connection = columnValue(text[i], columns, Columns.Connection, locale); - var number = null; - var name = null; - if (connection) { - var split = connection.lastIndexOf("(") - name = connection.substr(0, split - 1); - number = connection.substr(split + 1, connection.length - split - 2); - transportType = number.match(/RJ [0-9]+/) ? "Train" : "Bus"; - } - - var res = JsonLd.newObject(transportType + "Reservation"); - res.reservationFor = JsonLd.newObject(transportType + "Trip"); - if (transportType == "Bus") { - if (number) { - res.reservationFor.busNumber = number; - } - if (name) { - res.reservationFor.busName = name; - } - } else if (transportType == "Train") { - if (number) { - res.reservationFor.trainNumber = number; - } - if (name) { - res.reservationFor.trainName = name; - } - } - - var arrivalTime = columnValue(text[i + 1], columns, Columns.ArrivalTime, locale); - var arrivalDate = columnValue(text[i + 1], columns, Columns.Date, locale); - if (!arrivalTime) { - arrivalTime = columnValue(text[i], columns, Columns.ArrivalTime, locale); - } - if (!arrivalDate) { - arrivalDate = columnValue(text[i], columns, Columns.Date, locale); - } - if (arrivalDate && arrivalTime) { - res.reservationFor.arrivalStation = JsonLd.newObject(transportType + "Station"); - res.reservationFor.arrivalStation.name = columnValue(text[i+1], columns, Columns.Station, locale); - res.reservationFor.arrivalTime = parseDate(arrivalDate, arrivalTime, locale); - } - - var departureTime = columnValue(text[i], columns, Columns.DepartureTime, locale); - var departure = ""; - if (departureTime != "") { - departure = text[i]; - } else if (i > 0) { - departure = text[i - 1]; - departureTime = columnValue(departure, columns, Columns.DepartureTime, locale); - } - if (departure) { - res.reservationFor.departureStation = JsonLd.newObject(transportType + "Station"); - res.reservationFor.departureStation.name = columnValue(departure, columns, Columns.Station, locale); - res.reservationFor.departureTime = parseDate(columnValue(departure, columns, Columns.Date, locale), - departureTime, locale); - - var platform = columnValue(departure, columns, Columns.Platform, locale); - if (platform) { - res.reservationFor.departurePlatform = platform; - } - - // seats are always bound to departur - var seat = columnValue(departure, columns, Columns.Seat, locale); - if (seat) { - var r = seat.match(/([0-9]+)\/([0-9]+)/); - res.reservedTicket = JsonLd.newObject("Ticket"); - res.reservedTicket.ticketedSeat = JsonLd.newObject("Seat"); - if (r) { - res.reservedTicket.ticketedSeat.seatSection = r[1]; - res.reservedTicket.ticketedSeat.seatNumber = r[2]; - } else { - res.reservedTicket.ticketedSeat.seatNumber = seat; - } - } - } - reservations.push(res); - } - return reservations; -} - -function main(text) { - var reservations = new Array(); - - for (var locale in regExMap) { - var ticketId = text.match(regExMap[locale]["ticketId"]); - if (!ticketId) { - continue; - } - - var resUrl = text.match(/http(s)?:\/\/jizdenky\.(regiojet|studentagency)\.cz\/OnlineTicket\?pam1=[0-9]+\&pam2=[0-9]+/) - - var returnHeader = text.match(regExMap[locale]["returnTripHeader"]); - var isReturn = (returnHeader != null); - var routeHeader = text.match(regExMap[locale][isReturn ? "thereTripHeader" : "singleTripHeader"]); - if (!routeHeader) { - break; - } - - var trip = text.substr(routeHeader.index + routeHeader[0].length + 1); - var newRes = parseTrip(trip, locale); - if (newRes.length == 0) { - break; - } - reservations = reservations.concat(newRes); - - if (isReturn) { - trip = text.substr(returnHeader.index + returnHeader[0].length + 1); - reservations = reservations.concat(parseTrip(trip, locale)); - } - - for (var i = 0; i < reservations.length; ++i) { - reservations[i].reservationNumber = ticketId[1]; - if (resUrl) { - reservations[i].modifyReservationUrl = resUrl[0]; - } - } - - // No need to scan any further locales - break; - } - - return reservations; -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/regiojet.json b/plugins/messageviewer/bodypartformatter/semantic/extractors/regiojet.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/regiojet.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "filter": [ - { "header": "From", "match": "express@studentagency.cz" }, - { "header": "From", "match": "info@regiojet.cz" } - ], - "script": "regiojet.js" -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/sncf.js b/plugins/messageviewer/bodypartformatter/semantic/extractors/sncf.js deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/sncf.js +++ /dev/null @@ -1,81 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -function parseDate(dateStr, timeStr) { - // the text does not contain the year at all, so guess that from Context.senderDate - var date = JsonLd.toDateTime(dateStr + '/' + Context.senderDate.getFullYear() + ' ' + timeStr, "dd/MM/yyyy hh'h'mm", "fr"); - if (date < Context.senderDate) - date.setFullYear(Context.senderDate.getFullYear() + 1); - return date; -} - -function main(text) { - var reservations = new Array(); - var bookingRef = text.match(/DOSSIER VOYAGE : ([A-Z0-9]{6})/); - - var pos = 0; - while (true) { - var header = text.substr(pos).match(/ Départ \/ Arrivée.*\n/); - if (!header) - break; - var index = header.index + header[0].length; - - var res = JsonLd.newObject("TrainReservation"); - res.reservationNumber = bookingRef[1]; - res.reservationFor = JsonLd.newObject("TrainTrip"); - - var depLine = text.substr(pos + index).match(/\n ([\w -]+?) +(\d{2}\/\d{2}) à (\d{2}h\d{2})/); - if (!depLine) - break; - index += depLine.index + depLine[0].length; - res.reservationFor.departureStation = JsonLd.newObject("TrainStation"); - res.reservationFor.departureStation.name = depLine[1]; - res.reservationFor.departureTime = parseDate(depLine[2], depLine[3]); - - var arrLine = text.substr(pos + index).match(/\n ([\w -]+?) +(\d{2}\/\d{2}) à (\d{2}h\d{2})/); - if (!arrLine) - break; - index += arrLine.index + arrLine[0].length; - res.reservationFor.arrivalStation = JsonLd.newObject("TrainStation"); - res.reservationFor.arrivalStation.name = arrLine[1]; - res.reservationFor.arrivalTime = parseDate(arrLine[2], arrLine[3]); - - // parse seat, train number, etc from the text for one leg - // since the stations are vertically centered, the stuff we are looking for might be at different - // positions relative to them - var legText = text.substring(pos + header.index + header[0].length, pos + index); - var trainNumber = legText.match(/TRAIN N°(\d{3,4})/); - if (trainNumber) - res.reservationFor.trainNumber = trainNumber[1]; - var seatRes = legText.match(/VOITURE (\d+) - PLACE (\d+)/); - if (seatRes) { - res.reservedTicket = JsonLd.newObject("Ticket"); - res.reservedTicket.ticketedSeat = JsonLd.newObject("Seat"); - res.reservedTicket.ticketedSeat.seatSection = seatRes[1]; - res.reservedTicket.ticketedSeat.seatNumber = seatRes[2]; - } - - reservations.push(res); - if (index == 0) - break; - pos += index; - } - - return reservations; -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/sncf.json b/plugins/messageviewer/bodypartformatter/semantic/extractors/sncf.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/sncf.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "filter": [ - { "header": "From", "match": "e-billet@sncf.fr" } - ], - "script": "sncf.js" -} - diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/swiss.js b/plugins/messageviewer/bodypartformatter/semantic/extractors/swiss.js deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/swiss.js +++ /dev/null @@ -1,59 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -function main(text) { - var reservations = new Array(); - var bookingRef = text.match(/Buchungsreferenz: ([A-Z0-9]{6})/); - - var pos = 0; - while (true) { - var flight = text.substr(pos).match(/Hinflug|Rückflug/); - if (!flight) - break; - var index = flight.index + flight[0].length; - - var res = JsonLd.newObject("FlightReservation"); - res.reservationNumber = bookingRef[1]; - res.reservationFor = JsonLd.newObject("Flight"); - - var leg = text.substr(pos + index).match(/ +(.+?) \(([A-Z]{3})\) - (.+?) \(([A-Z]{3})\) +[A-Z][a-z] (\d{2}.\d{2}.\d{4}) +(\d{2}:\d{2}) +[A-Z]{3} +(\d{2}:\d{2}) .*? ([A-Z0-9]{2}) (\d{3,4})/); - if (!leg) - break; - index += leg.index + leg[0].length; - res.reservationFor.departureAirport = JsonLd.newObject("Airport"); - res.reservationFor.departureAirport.name = leg[1]; - res.reservationFor.departureAirport.iataCode = leg[2]; - res.reservationFor.arrivalAirport = JsonLd.newObject("Airport"); - res.reservationFor.arrivalAirport.name = leg[3]; - res.reservationFor.arrivalAirport.iataCode = leg[4]; - res.reservationFor.departureTime = JsonLd.toDateTime(leg[5] + ' ' + leg[6], "dd.MM.yyyy hh:mm", "en"); - res.reservationFor.arrivalTime = JsonLd.toDateTime(leg[5] + ' ' + leg[7], "dd.MM.yyyy hh:mm", "en"); - res.reservationFor.flightNumber = leg[9]; - res.reservationFor.airline = JsonLd.newObject("Airline"); - res.reservationFor.airline.iataCode = leg[8]; - // TODO: parse the operated by part to fill in airline name - - reservations.push(res); - if (index == 0) - break; - pos += index; - } - - return reservations; -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/swiss.json b/plugins/messageviewer/bodypartformatter/semantic/extractors/swiss.json deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/extractors/swiss.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "filter": [ - { "header": "From", "match": "noreply@swiss.com" } - ], - "script": "swiss.js" -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/jsonlddocument.h b/plugins/messageviewer/bodypartformatter/semantic/jsonlddocument.h deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/jsonlddocument.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#ifndef JSONLDDOCUMENT_H -#define JSONLDDOCUMENT_H - -#include -#include - -class QJsonArray; - -/** Serialization/deserialization code for JSON-LD data. */ -namespace JsonLdDocument { -QVector fromJson(const QJsonArray &array); -QJsonArray toJson(const QVector &data); - -/** Read property @p name on object @p obj. */ -QVariant readProperty(const QVariant &obj, const char *name); -/** Set property @p name on object @p obj to value @p value. */ -void writeProperty(QVariant &obj, const char *name, const QVariant &value); -/** Removes property @p name on object @p obj. */ -void removeProperty(QVariant &obj, const char *name); -} - -#endif // JSONLDDOCUMENT_H diff --git a/plugins/messageviewer/bodypartformatter/semantic/jsonlddocument.cpp b/plugins/messageviewer/bodypartformatter/semantic/jsonlddocument.cpp deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/jsonlddocument.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "jsonlddocument.h" -#include "datatypes.h" -#include "semantic_debug.h" - -#include -#include -#include - -static QVariant createInstance(const QJsonObject &obj); - -// Eurowings workarounds... -static const char *fallbackDateTimePattern[] = { - "yyyy-MM-dd HH:mm:ss", - "yyyy-MM-dd HH:mm", - "MM-dd-yyyy HH:mm" // yes, seriously ;( -}; -static const auto fallbackDateTimePatternCount = sizeof(fallbackDateTimePattern) / sizeof(const char *); - -static QVariant propertyValue(const QMetaProperty &prop, const QJsonValue &v) -{ - switch (prop.type()) { - case QVariant::String: - return v.toString(); - case QVariant::DateTime: - { - auto str = v.toString(); - auto dt = QDateTime::fromString(str, Qt::ISODate); - for (unsigned int i = 0; i < fallbackDateTimePatternCount && dt.isNull(); ++i) { - dt = QDateTime::fromString(str, QString::fromLatin1(fallbackDateTimePattern[i])); - } - if (dt.isNull()) { - qCDebug(SEMANTIC_LOG) << "Datetime parsing failed for" << str; - } - return dt; - } - case QVariant::Double: - return v.toDouble(); - case QVariant::Url: - return QUrl(v.toString()); - default: - break; - } - if (prop.type() == qMetaTypeId()) { - return v.toDouble(); - } - return createInstance(v.toObject()); -} - -template -static QVariant createInstance(const QJsonObject &obj) -{ - T t; - for (auto it = obj.begin(); it != obj.end(); ++it) { - if (it.key().startsWith(QLatin1Char('@'))) { - continue; - } - const auto idx = T::staticMetaObject.indexOfProperty(it.key().toLatin1()); - if (idx < 0) { - qCDebug(SEMANTIC_LOG) << "property" << it.key() << "could not be set on object of type" << T::staticMetaObject.className(); - continue; - } - const auto prop = T::staticMetaObject.property(idx); - const auto value = propertyValue(prop, it.value()); - prop.writeOnGadget(&t, value); - } - return QVariant::fromValue(t); -} - -#define MAKE_FACTORY(Class) \ - if (type == QLatin1String(#Class)) \ - return createInstance(obj) - -static QVariant createInstance(const QJsonObject &obj) -{ - const auto type = obj.value(QLatin1String("@type")).toString(); - MAKE_FACTORY(GeoCoordinates); - MAKE_FACTORY(Airline); - MAKE_FACTORY(Airport); - MAKE_FACTORY(FlightReservation); - MAKE_FACTORY(Flight); - MAKE_FACTORY(LodgingBusiness); - MAKE_FACTORY(LodgingReservation); - MAKE_FACTORY(PostalAddress); - MAKE_FACTORY(Seat); - MAKE_FACTORY(Ticket); - MAKE_FACTORY(TrainStation); - MAKE_FACTORY(TrainTrip); - MAKE_FACTORY(TrainReservation); - MAKE_FACTORY(BusStation); - MAKE_FACTORY(BusTrip); - MAKE_FACTORY(BusReservation); - return {}; -} - -#undef MAKE_FACTORY - -QVector JsonLdDocument::fromJson(const QJsonArray &array) -{ - QVector l; - l.reserve(array.size()); - for (const auto &obj : array) { - const auto v = createInstance(obj.toObject()); - if (!v.isNull()) { - l.push_back(v); - } - } - return l; -} - -static bool valueIsNull(const QVariant &v) -{ - if (v.type() == QVariant::Url) { - return !v.toUrl().isValid(); - } - return v.isNull(); -} - -static QJsonValue toJson(const QVariant &v) -{ - const auto mo = QMetaType(v.userType()).metaObject(); - if (!mo) { - // basic types - switch (v.type()) { - case QVariant::String: - return v.toString(); - case QVariant::Double: - return v.toDouble(); - case QVariant::Int: - return v.toInt(); - case QVariant::DateTime: - return v.toDateTime().toString(Qt::ISODate); - case QVariant::Url: - return v.toUrl().toString(); - default: - break; - } - if (v.userType() == qMetaTypeId()) { - return v.toFloat(); - } - qCDebug(SEMANTIC_LOG) << "unhandled value:" << v; - return {}; - } - - // composite types - QJsonObject obj; - obj.insert(QStringLiteral("@type"), QString::fromUtf8(mo->className())); - for (int i = 0; i < mo->propertyCount(); ++i) { - const auto prop = mo->property(i); - if (!prop.isStored()) { - continue; - } - const auto value = prop.readOnGadget(v.constData()); - if (!valueIsNull(value)) { - obj.insert(QString::fromUtf8(prop.name()), toJson(value)); - } - } - return obj; -} - -QJsonArray JsonLdDocument::toJson(const QVector &data) -{ - QJsonArray a; - for (const auto &d : data) { - const auto value = toJson(d); - if (!value.isObject()) { - continue; - } - auto obj = value.toObject(); - obj.insert(QStringLiteral("@context"), QStringLiteral("http://schema.org")); - a.push_back(obj); - } - return a; -} - -QVariant JsonLdDocument::readProperty(const QVariant &obj, const char *name) -{ - const auto mo = QMetaType(obj.userType()).metaObject(); - if (!mo) { - return {}; - } - - const auto idx = mo->indexOfProperty(name); - if (idx < 0) { - return {}; - } - - const auto prop = mo->property(idx); - return prop.readOnGadget(obj.constData()); -} - -void JsonLdDocument::writeProperty(QVariant &obj, const char *name, const QVariant &value) -{ - const auto mo = QMetaType(obj.userType()).metaObject(); - if (!mo) { - return; - } - - const auto idx = mo->indexOfProperty(name); - if (idx < 0) { - return; - } - - const auto prop = mo->property(idx); - prop.writeOnGadget(obj.data(), value); -} - -void JsonLdDocument::removeProperty(QVariant &obj, const char *name) -{ - writeProperty(obj, name, QVariant()); -} diff --git a/plugins/messageviewer/bodypartformatter/semantic/semantic_plugin.cpp b/plugins/messageviewer/bodypartformatter/semantic/semantic_plugin.cpp --- a/plugins/messageviewer/bodypartformatter/semantic/semantic_plugin.cpp +++ b/plugins/messageviewer/bodypartformatter/semantic/semantic_plugin.cpp @@ -24,25 +24,14 @@ #include #include -// needs to be outside of the anonymous namespace -static void initResource() -{ - Q_INIT_RESOURCE(extractors); -} - namespace { class SemanticPlugin : public QObject, public MimeTreeParser::Interface::BodyPartFormatterPlugin, public MessageViewer::MessagePartRenderPlugin { Q_OBJECT Q_INTERFACES(MimeTreeParser::Interface::BodyPartFormatterPlugin) Q_INTERFACES(MessageViewer::MessagePartRenderPlugin) Q_PLUGIN_METADATA(IID "com.kde.messageviewer.bodypartformatter" FILE "semantic_plugin.json") public: - SemanticPlugin() - { - initResource(); - } - const MimeTreeParser::Interface::BodyPartFormatter *bodyPartFormatter(int idx) const override { if (idx < 3) { diff --git a/plugins/messageviewer/bodypartformatter/semantic/semanticprocessor.h b/plugins/messageviewer/bodypartformatter/semantic/semanticprocessor.h --- a/plugins/messageviewer/bodypartformatter/semantic/semanticprocessor.h +++ b/plugins/messageviewer/bodypartformatter/semantic/semanticprocessor.h @@ -20,12 +20,12 @@ #ifndef SEMANTICPROCESSOR_H #define SEMANTICPROCESSOR_H -#include "extractorrepository.h" - #include #include #include +#include + #include /** Processor plugin for MimeTreeParser. */ @@ -38,8 +38,8 @@ MimeTreeParser::MessagePart::Ptr process(MimeTreeParser::Interface::BodyPart &part) const override; private: - std::shared_ptr m_repository; - static std::weak_ptr s_repository; + std::shared_ptr m_repository; + static std::weak_ptr s_repository; }; #endif // SEMANTICPROCESSOR_H diff --git a/plugins/messageviewer/bodypartformatter/semantic/semanticprocessor.cpp b/plugins/messageviewer/bodypartformatter/semantic/semanticprocessor.cpp --- a/plugins/messageviewer/bodypartformatter/semantic/semanticprocessor.cpp +++ b/plugins/messageviewer/bodypartformatter/semantic/semanticprocessor.cpp @@ -18,16 +18,20 @@ */ #include "semanticprocessor.h" -#include "extractorengine.h" -#include "extractorpreprocessor.h" -#include "extractorpostprocessor.h" -#include "jsonlddocument.h" -#include "structureddataextractor.h" #include "semanticmemento.h" #include "semantic_debug.h" +#include +#include +#include +#include +#include + +#include #include +using namespace KItinerary; + std::weak_ptr SemanticProcessor::s_repository; SemanticProcessor::SemanticProcessor() diff --git a/plugins/messageviewer/bodypartformatter/semantic/semanticrenderer.cpp b/plugins/messageviewer/bodypartformatter/semantic/semanticrenderer.cpp --- a/plugins/messageviewer/bodypartformatter/semantic/semanticrenderer.cpp +++ b/plugins/messageviewer/bodypartformatter/semantic/semanticrenderer.cpp @@ -18,15 +18,22 @@ */ #include "semanticrenderer.h" -#include "datatypes.h" -#include "jsonlddocument.h" #include "semanticmemento.h" #include "semantic_debug.h" #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include + #include #include @@ -36,6 +43,8 @@ #include #include +using namespace KItinerary; + // Grantlee has no Q_GADGET support yet #define GRANTLEE_MAKE_GADGET(Class) \ GRANTLEE_BEGIN_LOOKUP(Class) \ diff --git a/plugins/messageviewer/bodypartformatter/semantic/semanticurlhandler.cpp b/plugins/messageviewer/bodypartformatter/semantic/semanticurlhandler.cpp --- a/plugins/messageviewer/bodypartformatter/semantic/semanticurlhandler.cpp +++ b/plugins/messageviewer/bodypartformatter/semantic/semanticurlhandler.cpp @@ -18,17 +18,19 @@ */ #include "semanticurlhandler.h" -#include "calendarhandler.h" -#include "datatypes.h" -#include "jsonlddocument.h" #include "semanticmemento.h" #include "semantic_debug.h" #include #include #include +#include +#include +#include +#include + #include #include @@ -43,6 +45,8 @@ #include +using namespace KItinerary; + bool SemanticUrlHandler::handleClick(MessageViewer::Viewer *viewerInstance, MimeTreeParser::Interface::BodyPart *part, const QString &path) const { Q_UNUSED(viewerInstance); diff --git a/plugins/messageviewer/bodypartformatter/semantic/structureddataextractor.h b/plugins/messageviewer/bodypartformatter/semantic/structureddataextractor.h deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/structureddataextractor.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#ifndef STRUCTUREDDATAEXTRACTOR_H -#define STRUCTUREDDATAEXTRACTOR_H - -#include - -class QJsonObject; -class QString; -class QXmlStreamReader; - -/** Extract schema.org structured data from HTML text. - * @see https://developers.google.com/gmail/markup/getting-started - */ -class StructuredDataExtractor -{ -public: - void parse(const QString &text); - QJsonArray data() const - { - return m_data; - } - -private: - /** Try to parse using an actual XML parser. */ - void parseXml(const QString &text); - /** Try to find application/ld+json content with basic string search. */ - void findLdJson(const QString &text); - /** Try to fix some common HTML4 damage to make @p text consumable for parseXml(). */ - QString fixupHtml4(const QString &text) const; - /** Recursive microdata parsing. */ - QJsonObject parseMicroData(QXmlStreamReader &reader) const; - /** Element-dependent Microdata property value. */ - QString valueForItemProperty(QXmlStreamReader &reader) const; - - QJsonArray m_data; -}; - -#endif // STRUCTUREDDATAEXTRACTOR_H diff --git a/plugins/messageviewer/bodypartformatter/semantic/structureddataextractor.cpp b/plugins/messageviewer/bodypartformatter/semantic/structureddataextractor.cpp deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/structureddataextractor.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "structureddataextractor.h" -#include "semantic_debug.h" - -#include -#include -#include -#include -#include -#include - -void StructuredDataExtractor::parse(const QString &text) -{ - parseXml(text); - if (m_data.isEmpty()) { - findLdJson(text); - if (m_data.isEmpty()) { - parseXml(fixupHtml4(text)); - } - } -} - -void StructuredDataExtractor::parseXml(const QString &text) -{ - QXmlStreamReader reader(text); - while (!reader.atEnd()) { - if (reader.tokenType() == QXmlStreamReader::StartElement) { - // JSON-LD - if (reader.name() == QLatin1String("script") && reader.attributes().value(QLatin1String("type")) == QLatin1String("application/ld+json")) { - const auto jsonData = reader.readElementText(QXmlStreamReader::IncludeChildElements); - const auto jsonDoc = QJsonDocument::fromJson(jsonData.toUtf8()); - if (jsonDoc.isNull()) { - continue; - } - if (jsonDoc.isArray()) { - m_data.append(jsonDoc.array()); - } else if (jsonDoc.isObject()) { - m_data.push_back(jsonDoc.object()); - } - } - - // Microdata - const auto itemType = reader.attributes().value(QLatin1String("itemtype")).toString(); - if (itemType.startsWith(QLatin1String("http://schema.org/"))) { - auto obj = parseMicroData(reader); - if (obj.isEmpty()) { - continue; - } - obj.insert(QStringLiteral("@context"), QStringLiteral("http://schema.org")); - const QUrl typeUrl(itemType); - obj.insert(QStringLiteral("@type"), typeUrl.fileName()); - m_data.push_back(obj); - continue; - } - } - reader.readNext(); - } - - if (reader.hasError()) { - qCDebug(SEMANTIC_LOG) << reader.errorString() << reader.lineNumber() << reader.columnNumber(); - } -} - -void StructuredDataExtractor::findLdJson(const QString &text) -{ - for (int i = 0; i < text.size();) { - i = text.indexOf(QLatin1String("'), i) + 1; - if (i < 0) { - break; - } - i = text.indexOf(QLatin1String(""), begin, Qt::CaseInsensitive); - const auto jsonData = text.mid(begin, i - begin); - QJsonParseError error; - auto jsonDoc = QJsonDocument::fromJson(jsonData.toUtf8(), &error); - if (jsonDoc.isNull()) { - qCDebug(SEMANTIC_LOG).noquote() << jsonData; - qCDebug(SEMANTIC_LOG) << error.errorString() << "at offset" << error.offset; - continue; - } - if (jsonDoc.isArray()) { - for (const auto &v : jsonDoc.array()) { - m_data.push_back(v); - } - } else if (jsonDoc.isObject()) { - m_data.push_back(jsonDoc.object()); - } - } -} - -QString StructuredDataExtractor::fixupHtml4(const QString &text) const -{ - auto output(text); - - // close single-element tags - output.replace(QRegularExpression(QStringLiteral("(]*[^>/])>")), QStringLiteral("\\1/>")); - - // fix value-less attributes - output.replace(QRegularExpression(QStringLiteral("(<[^>]+ )itemscope( [^>]*>)")), QStringLiteral("\\1itemscope=\"\"\\2")); - - // TODO remove legacy entities like   - return output; -} - -QJsonObject StructuredDataExtractor::parseMicroData(QXmlStreamReader &reader) const -{ - QJsonObject obj; - reader.readNext(); - int depth = 1; - - while (!reader.atEnd()) { - if (reader.tokenType() == QXmlStreamReader::StartElement) { - ++depth; - const auto prop = reader.attributes().value(QLatin1String("itemprop")).toString(); - const auto type = reader.attributes().value(QLatin1String("itemtype")).toString(); - if (type.startsWith(QLatin1String("http://schema.org/"))) { - auto subObj = parseMicroData(reader); - const QUrl typeUrl(type); - subObj.insert(QStringLiteral("@type"), typeUrl.fileName()); - - obj.insert(prop, subObj); - continue; - } - if (!prop.isEmpty()) { - obj.insert(prop, valueForItemProperty(reader)); - continue; - } - } else if (reader.tokenType() == QXmlStreamReader::EndElement) { - --depth; - if (depth == 0) { - return obj; - } - } - reader.readNext(); - } - - if (reader.hasError()) { - qCDebug(SEMANTIC_LOG) << reader.errorString() << reader.lineNumber() << reader.columnNumber(); - } - return {}; -} - -QString StructuredDataExtractor::valueForItemProperty(QXmlStreamReader &reader) const -{ - // TODO see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/itemprop#Values - const auto elemName = reader.name(); - if (elemName == QLatin1String("span")) { - return reader.readElementText(QXmlStreamReader::IncludeChildElements); - } - - QString v; - if (elemName == QLatin1String("meta")) { - v = reader.attributes().value(QLatin1String("content")).toString(); - } else if (elemName == QLatin1String("time")) { - v = reader.attributes().value(QLatin1String("datetime")).toString(); - } else if (elemName == QLatin1String("link") || elemName == QLatin1String("a")) { - v = reader.attributes().value(QLatin1String("href")).toString(); - } else { - qCDebug(SEMANTIC_LOG) << "TODO:" << elemName; - } - - reader.readNext(); - return v; -}