Commit c3afac74 authored by Volker Krause's avatar Volker Krause
Browse files

Add an import filter for JsonLdDocument::fromJson

This allows us to migrate/translate deprecated or renamed values. Use
this for translating Google's Reservation::ticketToken to the schema.org
replacement Ticket::ticketToken.
parent 6a29c86f
......@@ -40,7 +40,6 @@
"@type": "Ticket",
"ticketToken": "aztecCode:M1KRAUSE/VOLKER EXXX007 TXLRIXBT 0212 309Y014E0063 100"
},
"ticketToken": "aztecCode:M1KRAUSE/VOLKER EXXX007 TXLRIXBT 0212 309Y014E0063 100",
"underName": {
"@type": "Person",
"name": "KRAUSE/VOLKER"
......
......@@ -40,7 +40,6 @@
"@type": "Ticket",
"ticketToken": "aztecCode:M1KRAUSE/VOLKER EXXX007 TXLMUCAB 6203 297Y019F0060 33C>5080 B2A N00 "
},
"ticketToken": "aztecCode:M1KRAUSE/VOLKER EXXX007 TXLMUCAB 6203 297Y019F0060 33C>5080 B2A N00 ",
"underName": {
"@type": "Person",
"name": "KRAUSE/VOLKER"
......
......@@ -44,7 +44,6 @@
"@type": "Ticket",
"ticketToken": "aztecCode:M1KRAUSE/VOLKER EXXX007 LHRTXL4U 8465 169Y017C0040 147>1181 7168B4U 0000000000000291040PASSPORTID2 LH 123412341234012 "
},
"ticketToken": "aztecCode:M1KRAUSE/VOLKER EXXX007 LHRTXL4U 8465 169Y017C0040 147>1181 7168B4U 0000000000000291040PASSPORTID2 LH 123412341234012 ",
"underName": {
"@type": "Person",
"name": "KRAUSE/VOLKER"
......
......@@ -43,7 +43,6 @@
"@type": "Ticket",
"ticketToken": "aztecCode:M1DOE/JOHN EXXX007 MUCTXLLH 2724 065M005A0017 35D>6180WW8064BLH 2A22012345678900 LH N*30600000K09 "
},
"ticketToken": "aztecCode:M1DOE/JOHN EXXX007 MUCTXLLH 2724 065M005A0017 35D>6180WW8064BLH 2A22012345678900 LH N*30600000K09 ",
"underName": {
"@type": "Person",
"name": "DOE/JOHN"
......
......@@ -45,7 +45,6 @@
"@type": "Ticket",
"ticketToken": "aztecCode:M1KRAUSE/VOLKER EXXX007 ZRHTXLLX 0962 258Y010E0143 15D>5180 M7258BLX 2A724xxxxxxxxxx0 LX LH 123456789012345 N*30600000K09 "
},
"ticketToken": "aztecCode:M1KRAUSE/VOLKER EXXX007 ZRHTXLLX 0962 258Y010E0143 15D>5180 M7258BLX 2A724xxxxxxxxxx0 LX LH 123456789012345 N*30600000K09 ",
"underName": {
"@type": "Person",
"name": "KRAUSE/VOLKER"
......
......@@ -43,7 +43,6 @@
"underName": {
"@type": "Person",
"name": "DESMARAIS/LUC"
},
"ticketToken": "aztecCode:M1DESMARAIS/LUC EABC123 YULFRAAC 0834 326J001A0025 100"
}
}
]
......@@ -28,6 +28,7 @@ set(kitinerary_lib_srcs
extractorrepository.cpp
iatabcbpparser.cpp
jsonlddocument.cpp
jsonldimportfilter.cpp
mergeutil.cpp
structureddataextractor.cpp
)
......
......@@ -34,10 +34,9 @@ public:
QVariant reservationFor;
QVariant reservedTicket;
QVariant underName;
QUrl url;
QUrl cancelReservationUrl;
QUrl modifyReservationUrl;
QString ticketToken;
QUrl url;
QString pkpassPassTypeIdentifier;
QString pkpassSerialNumber;
Organization provider;
......@@ -50,7 +49,6 @@ KITINERARY_MAKE_PROPERTY(Reservation, QVariant, reservedTicket, setReservedTicke
KITINERARY_MAKE_PROPERTY(Reservation, QVariant, underName, setUnderName)
KITINERARY_MAKE_PROPERTY(Reservation, QUrl, cancelReservationUrl, setCancelReservationUrl)
KITINERARY_MAKE_PROPERTY(Reservation, QUrl, modifyReservationUrl, setModifyReservationUrl)
KITINERARY_MAKE_PROPERTY(Reservation, QString, ticketToken, setTicketToken)
KITINERARY_MAKE_PROPERTY(Reservation, QUrl, url, setUrl)
KITINERARY_MAKE_PROPERTY(Reservation, QString, pkpassPassTypeIdentifier, setPkpassPassTypeIdentifier)
KITINERARY_MAKE_PROPERTY(Reservation, QString, pkpassSerialNumber, setPkpassSerialNumber)
......
......@@ -40,21 +40,18 @@ class KITINERARY_EXPORT Reservation
KITINERARY_PROPERTY(QVariant, reservedTicket, setReservedTicket)
KITINERARY_PROPERTY(QVariant, underName, setUnderName)
KITINERARY_PROPERTY(Organization, provider, setProvider)
KITINERARY_PROPERTY(QUrl, url, setUrl)
// Google extension
KITINERARY_PROPERTY(QUrl, cancelReservationUrl, setCancelReservationUrl)
KITINERARY_PROPERTY(QUrl, modifyReservationUrl, setModifyReservationUrl)
KITINERARY_PROPERTY(QString, ticketToken, setTicketToken)
KITINERARY_PROPERTY(QUrl, url, setUrl)
// KDE extensions
/** @property pkpassPassTypeIdentifier pass type identifier of an associated
* Apple Wallet boarding pass.
/** Pass type identifier of an associated Apple Wallet boarding pass.
* @see KPkPass::Pass::passTypeIdentifier
*/
KITINERARY_PROPERTY(QString, pkpassPassTypeIdentifier, setPkpassPassTypeIdentifier)
/** @property pkpassSerialNumber serial number of an associated Apple Wallet
* boarding pass.
/** Serial number of an associated Apple Wallet boarding pass.
* @see KPkPass::Pass::serialNumber
*/
KITINERARY_PROPERTY(QString, pkpassSerialNumber, setPkpassSerialNumber)
......
......@@ -265,7 +265,7 @@ void ExtractorEnginePrivate::extractPass()
}
// barcode contains the ticket token
if (!m_pass->barcodes().isEmpty() && !res.contains(QLatin1String("ticketToken"))) {
if (!m_pass->barcodes().isEmpty() && !res.contains(QLatin1String("reservedTicket"))) {
const auto barcode = m_pass->barcodes().at(0);
QString token;
switch (barcode.format()) {
......@@ -279,7 +279,10 @@ void ExtractorEnginePrivate::extractPass()
break;
}
token += barcode.message();
res.insert(QLatin1String("ticketToken"), token);
QJsonObject ticket;
ticket.insert(QLatin1String("@type"), QLatin1String("Ticket"));
ticket.insert(QLatin1String("ticketToken"), token);
res.insert(QLatin1String("reservedTicket"), ticket);
}
res.insert(QLatin1String("reservationFor"), resFor);
......
......@@ -23,12 +23,12 @@
#include "airportdb/airportdb.h"
#include "iatabcbpparser.h"
#include <datatypes/bustrip.h>
#include <datatypes/flight.h>
#include <datatypes/place.h>
#include <datatypes/reservation.h>
#include <datatypes/ticket.h>
#include <datatypes/traintrip.h>
#include <KItinerary/BusTrip>
#include <KItinerary/Flight>
#include <KItinerary/Place>
#include <KItinerary/Reservation>
#include <KItinerary/Ticket>
#include <KItinerary/TrainTrip>
#include <QDebug>
#include <QTimeZone>
......@@ -42,7 +42,7 @@ class ExtractorPostprocessorPrivate
public:
QVariant processProperty(QVariant obj, const char *name, QVariant (ExtractorPostprocessorPrivate::*processor)(QVariant) const) const;
QVariant processFlightReservation(QVariant res) const;
QVariant processFlightReservation(FlightReservation res) const;
QVariant processFlight(QVariant flight) const;
QVariant processAirport(QVariant airport) const;
QVariant processAirline(QVariant airline) const;
......@@ -74,7 +74,7 @@ void ExtractorPostprocessor::process(const QVector<QVariant> &data)
d->m_data.reserve(data.size());
for (auto elem : data) {
if (elem.userType() == qMetaTypeId<FlightReservation>()) {
elem = d->processFlightReservation(elem);
elem = d->processFlightReservation(elem.value<FlightReservation>());
} else if (elem.userType() == qMetaTypeId<TrainReservation>()) {
elem = d->processReservation(elem);
} else if (elem.userType() == qMetaTypeId<LodgingReservation>()) {
......@@ -111,10 +111,10 @@ QVariant ExtractorPostprocessorPrivate::processProperty(QVariant obj, const char
return obj;
}
QVariant ExtractorPostprocessorPrivate::processFlightReservation(QVariant res) const
QVariant ExtractorPostprocessorPrivate::processFlightReservation(FlightReservation res) const
{
// expand ticketToken for IATA BCBP data
auto bcbp = JsonLdDocument::readProperty(res, "ticketToken").toString();
auto bcbp = res.reservedTicket().value<Ticket>().ticketToken();
if (!bcbp.isEmpty()) {
if (bcbp.startsWith(QLatin1String("aztecCode:"))) {
bcbp = bcbp.mid(10);
......@@ -123,13 +123,13 @@ QVariant ExtractorPostprocessorPrivate::processFlightReservation(QVariant res) c
}
const auto bcbpData = IataBcbpParser::parse(bcbp, m_contextDate.date());
if (bcbpData.size() == 1) {
res = JsonLdDocument::apply(bcbpData.at(0), res);
res = JsonLdDocument::apply(bcbpData.at(0), QVariant::fromValue(res)).value<FlightReservation>();
}
}
res = processReservation(res);
res = processProperty(res, "reservationFor", &ExtractorPostprocessorPrivate::processFlight);
return res;
res = processReservation(QVariant::fromValue(res)).value<FlightReservation>();
res = processProperty(QVariant::fromValue(res), "reservationFor", &ExtractorPostprocessorPrivate::processFlight).value<FlightReservation>();
return QVariant::fromValue(res);
}
QVariant ExtractorPostprocessorPrivate::processFlight(QVariant flight) const
......@@ -227,19 +227,6 @@ QVariant ExtractorPostprocessorPrivate::processReservation(QVariant res) const
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;
}
......
......@@ -18,6 +18,7 @@
*/
#include "jsonlddocument.h"
#include "jsonldimportfilter.h"
#include "logging.h"
#include <datatypes/bustrip.h>
......@@ -147,7 +148,7 @@ QVector<QVariant> JsonLdDocument::fromJson(const QJsonArray &array)
QVector<QVariant> l;
l.reserve(array.size());
for (const auto &obj : array) {
const auto v = createInstance(obj.toObject());
const auto v = createInstance(JsonLdImportFilter::filterObject(obj.toObject()));
if (!v.isNull()) {
l.push_back(v);
}
......
......@@ -29,9 +29,13 @@ class QJsonArray;
namespace KItinerary {
/** Serialization/deserialization code for JSON-LD data. */
/** Serialization/deserialization code for JSON-LD data.
* @see https://www.w3.org/TR/json-ld/
*/
namespace JsonLdDocument {
/** Convert JSON-LD data into instantiated data types. */
KITINERARY_EXPORT QVector<QVariant> fromJson(const QJsonArray &array);
/** Serialize instantiated data types to JSON. */
KITINERARY_EXPORT QJsonArray toJson(const QVector<QVariant> &data);
/** Read property @p name on object @p obj. */
......
/*
Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
*/
#include "jsonldimportfilter.h"
#include <QJsonObject>
using namespace KItinerary;
static QJsonObject filterReservation(QJsonObject res)
{
// move ticketToken to Ticket (Google vs. schema.org difference)
const auto token = res.value(QLatin1String("ticketToken")).toString();
if (!token.isEmpty()) {
auto ticket = res.value(QLatin1String("reservedTicket")).toObject();
if (ticket.isEmpty()) {
ticket.insert(QLatin1String("@type"), QLatin1String("Ticket"));
}
if (!ticket.contains(QLatin1String("ticketToken"))) {
ticket.insert(QLatin1String("ticketToken"), token);
res.insert(QLatin1String("reservedTicket"), ticket);
}
}
return res;
}
QJsonObject JsonLdImportFilter::filterObject(const QJsonObject& obj)
{
if (obj.value(QLatin1String("@type")).toString().endsWith(QLatin1String("Reservation"))) {
return filterReservation(obj);
}
return obj;
}
/*
Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
*/
#ifndef KITINERARY_JSONLDIMPORTFILTER_H
#define KITINERARY_JSONLDIMPORTFILTER_H
class QJsonObject;
namespace KItinerary {
/** Filter input JSON for loading with JsonLdDocument, to deal with obsolete
* or renamed elements.
*/
namespace JsonLdImportFilter
{
QJsonObject filterObject(const QJsonObject &obj);
}
}
#endif // KITINERARY_JSONLDIMPORTFILTER_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