Commit 705c677f authored by Volker Krause's avatar Volker Krause

Add generic airport terminal extractor

parent 49558353
......@@ -16,6 +16,7 @@ ecm_add_test(pdfdocumenttest.cpp LINK_LIBRARIES Qt5::Test KPim::Itinerary Qt5::G
ecm_add_test(htmldocumenttest.cpp LINK_LIBRARIES Qt5::Test KPim::Itinerary)
ecm_add_test(barcodedecodertest.cpp LINK_LIBRARIES Qt5::Test KPim::Itinerary Qt5::Gui)
ecm_add_test(pkpassextractortest.cpp LINK_LIBRARIES Qt5::Test KPim::Itinerary KPim::PkPass)
ecm_add_test(extractorutiltest.cpp LINK_LIBRARIES Qt5::Test KPim::Itinerary)
ecm_add_test(postprocessortest.cpp LINK_LIBRARIES Qt5::Test KPim::Itinerary)
if (TARGET KF5::CalendarCore)
ecm_add_test(calendarhandlertest.cpp LINK_LIBRARIES Qt5::Test KPim::Itinerary)
......
......@@ -74,8 +74,9 @@
"longitude": -83.35330200195312
},
"iataCode": "DTW",
"name": "DETROIT, MI (METROPOLITAN WAYNE CO), TERMINAL EM"
"name": "DETROIT, MI (METROPOLITAN WAYNE CO)"
},
"arrivalTerminal": "EM",
"arrivalTime": {
"@type": "QDateTime",
"@value": "2016-06-07T17:40:00-04:00",
......@@ -127,8 +128,9 @@
"longitude": 2.5477800369262695
},
"iataCode": "CDG",
"name": "PARIS, FR (CHARLES DE GAULLE), TERMINAL 2E"
"name": "PARIS, FR (CHARLES DE GAULLE)"
},
"arrivalTerminal": "2E",
"arrivalTime": {
"@type": "QDateTime",
"@value": "2016-06-10T11:30:00+02:00",
......@@ -146,9 +148,10 @@
"longitude": -83.35330200195312
},
"iataCode": "DTW",
"name": "DETROIT, MI (METROPOLITAN WAYNE CO), TERMINAL EM"
"name": "DETROIT, MI (METROPOLITAN WAYNE CO)"
},
"departureDay": "2016-06-09",
"departureTerminal": "EM",
"departureTime": {
"@type": "QDateTime",
"@value": "2016-06-09T21:40:00-04:00",
......@@ -199,9 +202,10 @@
"longitude": 2.5477800369262695
},
"iataCode": "CDG",
"name": "PARIS, FR (CHARLES DE GAULLE), TERMINAL 2F"
"name": "PARIS, FR (CHARLES DE GAULLE)"
},
"departureDay": "2016-06-10",
"departureTerminal": "2F",
"departureTime": {
"@type": "QDateTime",
"@value": "2016-06-10T13:00:00+02:00",
......
/*
Copyright (C) 2019 Volker Krause <vkrause@kde.org>
This program 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 program 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 General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <extractorutil.h>
#include <KItinerary/Flight>
#include <KItinerary/Place>
#include <QDebug>
#include <QTest>
using namespace KItinerary;
#define s(x) QStringLiteral(x)
class ExtractorUtilTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void testTerminalExtraction_data()
{
QTest::addColumn<QString>("input");
QTest::addColumn<QString>("airportName");
QTest::addColumn<QString>("terminalName");
QTest::newRow("empty") << QString() << QString() << QString();
QTest::newRow("CDG 1") << s("PARIS, FR (CHARLES DE GAULLE), TERMINAL 2E") << s("PARIS, FR (CHARLES DE GAULLE)") << s("2E");
QTest::newRow("CDG 2") << s("Paris Charles de Gaulle (Terminal 2D)") << s("Paris Charles de Gaulle") << s("2D");
QTest::newRow("LHR") << s("London/Heathrow-Terminal 2") << s("London/Heathrow") << s("2");
QTest::newRow("MAD") << s("MADRID, ES (BARAJAS), TERMINAL 4S") << s("MADRID, ES (BARAJAS)") << s("4S");
QTest::newRow("DTW") << s("DETROIT, MI (METROPOLITAN WAYNE CO), TERMINAL EM") << s("DETROIT, MI (METROPOLITAN WAYNE CO)") << s("EM");
QTest::newRow("MRS") << s("MARSEILLE FR - PROVENCE - TERMINAL 1A") << s("MARSEILLE FR - PROVENCE") << s("1A");
QTest::newRow("MUC") << s("München (Terminal 1)") << s("München") << s("1");
QTest::newRow("GTW EN") << s("London Gatwick (North Terminal)") << s("London Gatwick") << s("North");
QTest::newRow("GTW DE") << s("London Gatwick (Terminal Nord)") << s("London Gatwick") << s("Nord");
QTest::newRow("TXL") << s("Berlin Tegel (Terminal C)") << s("Berlin Tegel") << s("C");
}
void testTerminalExtraction()
{
QFETCH(QString, input);
QFETCH(QString, airportName);
QFETCH(QString, terminalName);
Airport a;
a.setName(input);
Flight f;
f.setDepartureAirport(a);
f.setArrivalAirport(a);
const auto out = ExtractorUtil::extractTerminals(f);
QCOMPARE(out.departureAirport().name(), airportName);
QCOMPARE(out.departureTerminal(), terminalName);
QCOMPARE(out.arrivalAirport().name(), airportName);
QCOMPARE(out.arrivalTerminal(), terminalName);
const auto out2 = ExtractorUtil::extractTerminals(out);
QCOMPARE(out, out2);
}
};
QTEST_GUILESS_MAIN(ExtractorUtilTest)
#include "extractorutiltest.moc"
......@@ -36,6 +36,7 @@ set(kitinerary_lib_srcs
extractorfilter.cpp
extractorpostprocessor.cpp
extractorrepository.cpp
extractorutil.cpp
genericpdfextractor.cpp
htmldocument.cpp
iatabcbpparser.cpp
......
......@@ -20,6 +20,7 @@
#include "config-kitinerary.h"
#include "extractorpostprocessor.h"
#include "extractorutil.h"
#include "iatabcbpparser.h"
#include "jsonlddocument.h"
#include "logging.h"
......@@ -211,6 +212,7 @@ Flight ExtractorPostprocessorPrivate::processFlight(Flight flight) const
flight.setBoardingTime(processFlightTime(flight.boardingTime(), flight, flight.departureAirport()));
flight.setDepartureTime(processFlightTime(flight.departureTime(), flight, flight.departureAirport()));
flight.setArrivalTime(processFlightTime(flight.arrivalTime(), flight, flight.arrivalAirport()));
flight = ExtractorUtil::extractTerminals(flight);
return flight;
}
......
......@@ -54,16 +54,11 @@ function parseHtmlBooking(doc) {
res.reservationFor = JsonLd.newObject("Flight");
var airports = row.recursiveContent.match(localeMap[locale]['airportRegExp']);
var airportName = airports[1].match(/^(.*?)( \(Terminal (.*)\))?( \((.*) Terminal\))?$/);
console.log(airportName);
res.reservationFor.departureAirport = JsonLd.newObject("Airport");
res.reservationFor.departureAirport.name = airportName[1];
res.reservationFor.departureTerminal = airportName[3] ? airportName[3] : airportName[5];
res.reservationFor.departureAirport.name = airports[1];
res.reservationFor.arrivalAirport = JsonLd.newObject("Airport");
airportName = airports[2].match(/^(.*?)( \(Terminal (.*)\))?( \((.*) Terminal\))?$/);
res.reservationFor.arrivalAirport.name = airportName[1];
res.reservationFor.arrivalTerminal = airportName[3] ? airportName[3] : airportName[5];
res.reservationFor.arrivalAirport.name = airports[2];
row = row.nextSibling;
var flightNum = row.recursiveContent.match(/([A-Z0-9]{2,3}) ?(\d{1,4})/);
......
/*
Copyright (C) 2019 Volker Krause <vkrause@kde.org>
This program 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 program 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 General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "extractorutil.h"
#include <KItinerary/Flight>
#include <QDebug>
#include <QRegularExpression>
using namespace KItinerary;
static QString trimAirportName(const QStringRef &in)
{
QString out = in.toString();
while (!out.isEmpty()) {
const auto c = out.at(out.size() - 1);
if (c.isSpace() || c == QLatin1Char('-') || c == QLatin1Char(',')) {
out.chop(1);
} else {
break;
}
}
return out;
}
static std::tuple<QString, QString> splitAirportName(const QString &name)
{
static QRegularExpression patterns[] = {
QRegularExpression(QStringLiteral("^(.*) \\(terminal (.*)\\)$"), QRegularExpression::CaseInsensitiveOption),
QRegularExpression(QStringLiteral("^(.*) \\((.*) terminal\\)$"), QRegularExpression::CaseInsensitiveOption),
QRegularExpression(QStringLiteral("^(.*)[ -]terminal (.*)$"), QRegularExpression::CaseInsensitiveOption),
};
for (const auto &re : patterns) {
const auto match = re.match(name);
if (match.hasMatch()) {
return std::make_tuple(trimAirportName(match.capturedRef(1)), match.captured(2));
break;
}
}
return std::make_tuple(name, QString());
}
Flight ExtractorUtil::extractTerminals(const Flight &flight)
{
Flight result(flight);
if (flight.departureTerminal().isEmpty()) {
auto a = flight.departureAirport();
QString name, terminal;
std::tie(name, terminal) = splitAirportName(a.name());
a.setName(name);
result.setDepartureAirport(a);
result.setDepartureTerminal(terminal);
}
if (flight.arrivalTerminal().isEmpty()) {
auto a = flight.arrivalAirport();
QString name, terminal;
std::tie(name, terminal) = splitAirportName(a.name());
a.setName(name);
result.setArrivalAirport(a);
result.setArrivalTerminal(terminal);
}
return result;
}
/*
Copyright (C) 2019 Volker Krause <vkrause@kde.org>
This program 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 program 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 General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef KITINERARY_EXTRACTORUTIL_H
#define KITINERARY_EXTRACTORUTIL_H
#include "kitinerary_export.h"
namespace KItinerary {
class Flight;
/** Data extraction utility functions. */
namespace ExtractorUtil
{
/** Move terminal indications from airport names to the correct fields.
* @internal Only exported for unit tests.
*/
KITINERARY_EXPORT Flight extractTerminals(const Flight &flight);
}
}
#endif // KITINERARY_EXTRACTORUTIL_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment