Commit 4afc8e11 authored by Volker Krause's avatar Volker Krause
Browse files

Factor out result validation into its own files

Also, make it accept reservable types next to reservations as top-level
objects too. This is needed for PBI.
parent 86f1ca67
......@@ -56,6 +56,7 @@ set(kitinerary_lib_srcs
extractorpostprocessor.cpp
extractorrepository.cpp
extractorutil.cpp
extractorvalidator.cpp
file.cpp
flightpostprocessor.cpp
genericpdfextractor.cpp
......
......@@ -20,6 +20,7 @@
#include "config-kitinerary.h"
#include "extractorpostprocessor.h"
#include "extractorpostprocessor_p.h"
#include "extractorvalidator_p.h"
#include "flightpostprocessor_p.h"
#include "extractorutil.h"
......@@ -101,7 +102,7 @@ QVector<QVariant> ExtractorPostprocessor::result() const
{
if (!d->m_resultFinalized) {
for (auto it = d->m_data.begin(); it != d->m_data.end();) {
if (d->filterReservation(*it)) {
if (ExtractorValidator::isValidElement(*it)) {
++it;
} else {
//qCDebug(Log).noquote() << "Discarding element:" << QJsonDocument(JsonLdDocument::toJson({*it})).toJson();
......@@ -524,86 +525,3 @@ QDateTime ExtractorPostprocessorPrivate::processTimeForLocation(QDateTime dt, co
}
return dt;
}
bool ExtractorPostprocessorPrivate::filterReservation(const QVariant &res) const
{
if (JsonLd::isA<FlightReservation>(res)) {
return filterFlight(res.value<FlightReservation>().reservationFor().value<Flight>());
}
if (JsonLd::isA<TrainReservation>(res)) {
return filterTrainTrip(res.value<TrainReservation>().reservationFor().value<TrainTrip>());
}
if (JsonLd::isA<BusReservation>(res)) {
return filterBusTrip(res.value<BusReservation>().reservationFor().value<BusTrip>());
}
if (JsonLd::isA<LodgingReservation>(res)) {
return filterLodgingReservation(res.value<LodgingReservation>());
}
if (JsonLd::isA<EventReservation>(res)) {
return filterEventReservation(res.value<EventReservation>());
}
if (JsonLd::isA<FoodEstablishmentReservation>(res)) {
return filterFoodReservation(res.value<FoodEstablishmentReservation>());
}
// types without specific filters yet
if (JsonLd::isA<TouristAttractionVisit>(res) ||
JsonLd::isA<RentalCarReservation>(res) ||
JsonLd::isA<TaxiReservation>(res)) {
return true;
}
// unknown top-level type
return false;
}
bool ExtractorPostprocessorPrivate::filterLodgingReservation(const LodgingReservation &res) const
{
return res.checkinTime().isValid() && res.checkoutTime().isValid();
}
bool ExtractorPostprocessorPrivate::filterFlight(const Flight &flight) const
{
// this will be valid if either boarding time, departure time or departure day is set
const auto validDate = flight.departureDay().isValid();
return filterAirport(flight.departureAirport())
&& filterAirport(flight.arrivalAirport())
&& validDate;
}
bool ExtractorPostprocessorPrivate::filterAirport(const Airport &airport) const
{
return !airport.iataCode().isEmpty() || !airport.name().isEmpty();
}
bool ExtractorPostprocessorPrivate::filterTrainTrip(const TrainTrip &trip) const
{
return filterTrainOrBusStation(trip.departureStation())
&& filterTrainOrBusStation(trip.arrivalStation())
&& trip.departureDay().isValid();
}
bool ExtractorPostprocessorPrivate::filterBusTrip(const BusTrip &trip) const
{
return filterTrainOrBusStation(trip.departureBusStop())
&& filterTrainOrBusStation(trip.arrivalBusStop())
&& trip.departureTime().isValid() && trip.arrivalTime().isValid();
}
template <typename T>
bool ExtractorPostprocessorPrivate::filterTrainOrBusStation(const T &station) const
{
return !station.name().isEmpty();
}
bool ExtractorPostprocessorPrivate::filterEventReservation(const EventReservation &res) const
{
const auto event = res.reservationFor().value<Event>();
return !event.name().isEmpty() && event.startDate().isValid();
}
bool ExtractorPostprocessorPrivate::filterFoodReservation(const FoodEstablishmentReservation &res) const
{
return res.startTime().isValid();
}
......@@ -77,16 +77,6 @@ public:
QVariantList processActions(QVariantList actions) const;
template <typename T> QDateTime processTimeForLocation(QDateTime dt, const T &place) const;
bool filterReservation(const QVariant &res) const;
bool filterLodgingReservation(const LodgingReservation &res) const;
bool filterFlight(const Flight &flight) const;
bool filterAirport(const Airport &airport) const;
bool filterTrainTrip(const TrainTrip &trip) const;
bool filterBusTrip(const BusTrip &trip) const;
template <typename T> bool filterTrainOrBusStation(const T &station) const;
bool filterEventReservation(const EventReservation &res) const;
bool filterFoodReservation(const FoodEstablishmentReservation &res) const;
QVector<QVariant> m_data;
QDateTime m_contextDate;
bool m_resultFinalized = false;
......
/*
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 "extractorvalidator_p.h"
#include <KItinerary/BusTrip>
#include <KItinerary/Event>
#include <KItinerary/Flight>
#include <KItinerary/Place>
#include <KItinerary/RentalCar>
#include <KItinerary/Reservation>
#include <KItinerary/Taxi>
#include <KItinerary/TrainTrip>
#include <KItinerary/Visit>
#include <QDateTime>
using namespace KItinerary;
static bool filterLodgingReservation(const LodgingReservation &res)
{
return res.checkinTime().isValid() && res.checkoutTime().isValid();
}
static bool filterAirport(const Airport &airport)
{
return !airport.iataCode().isEmpty() || !airport.name().isEmpty();
}
static bool filterFlight(const Flight &flight)
{
// this will be valid if either boarding time, departure time or departure day is set
const auto validDate = flight.departureDay().isValid();
return filterAirport(flight.departureAirport())
&& filterAirport(flight.arrivalAirport())
&& validDate;
}
template <typename T>
static bool filterTrainOrBusStation(const T &station)
{
return !station.name().isEmpty();
}
static bool filterTrainTrip(const TrainTrip &trip)
{
return filterTrainOrBusStation(trip.departureStation())
&& filterTrainOrBusStation(trip.arrivalStation())
&& trip.departureDay().isValid();
}
static bool filterBusTrip(const BusTrip &trip)
{
return filterTrainOrBusStation(trip.departureBusStop())
&& filterTrainOrBusStation(trip.arrivalBusStop())
&& trip.departureTime().isValid() && trip.arrivalTime().isValid();
}
static bool filterEvent(const Event &event)
{
return !event.name().isEmpty() && event.startDate().isValid();
}
static bool filterFoodReservation(const FoodEstablishmentReservation &res)
{
return res.startTime().isValid();
}
bool ExtractorValidator::isValidElement(const QVariant &elem)
{
// reservation types
if (JsonLd::isA<LodgingReservation>(elem)) {
return filterLodgingReservation(elem.value<LodgingReservation>());
}
if (JsonLd::isA<FoodEstablishmentReservation>(elem)) {
return filterFoodReservation(elem.value<FoodEstablishmentReservation>());
}
if (JsonLd::canConvert<Reservation>(elem)) {
const auto res = JsonLd::convert<Reservation>(elem);
return isValidElement(res.reservationFor());
}
// reservationFor types
if (JsonLd::isA<Flight>(elem)) {
return filterFlight(elem.value<Flight>());
}
if (JsonLd::isA<TrainTrip>(elem)) {
return filterTrainTrip(elem.value<TrainTrip>());
}
if (JsonLd::isA<BusTrip>(elem)) {
return filterBusTrip(elem.value<BusTrip>());
}
if (JsonLd::isA<Event>(elem)) {
return filterEvent(elem.value<Event>());
}
// types without specific filters yet
if (JsonLd::isA<TouristAttractionVisit>(elem) ||
JsonLd::isA<RentalCar>(elem) ||
JsonLd::isA<Taxi>(elem)
) {
return true;
}
// unknown top-level type
return false;
}
/*
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 EXTRACTORVALIDATOR_H
#define EXTRACTORVALIDATOR_H
class QVariant;
/**
* Validates extractor results.
* Used to discard incomplete or otherwise invalid data.
*/
namespace ExtractorValidator
{
/** Checks if the given element is valid.
* This will accept both Reservation object and things
* that can be reserved as top-level objects.
*/
bool isValidElement(const QVariant &elem);
}
#endif // EXTRACTORVALIDATOR_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