Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit e6fbb7e2 authored by Volker Krause's avatar Volker Krause

Give extractor scripts access to the email sent date

This way we can determine the year a booking is for if the year isn't
actually mentioned inside the booking confirmation or ticket, as it's
the case with SNCF for example.
parent b1bd4ee0
[
{
"@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"
}
}
}
]
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
......@@ -72,6 +72,7 @@ private Q_SLOTS:
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 = engine.extract();
......@@ -122,6 +123,7 @@ private Q_SLOTS:
ExtractorEngine engine;
engine.setText(preproc.text());
engine.setSenderDate(QDateTime(QDate(2017, 12, 29), QTime(18, 46, 2)));
engine.setExtractor(&extractor);
const auto data = engine.extract();
......
......@@ -72,7 +72,20 @@ QDateTime JsApi::toDateTime(const QString &dtStr, const QString &format, const Q
return dt;
}
ExtractorEngine::ExtractorEngine() = default;
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)
......@@ -80,14 +93,14 @@ void ExtractorEngine::setExtractor(const Extractor *extractor)
m_extractor = extractor;
}
const QString &ExtractorEngine::text() const
void ExtractorEngine::setText(const QString &text)
{
return m_text;
m_text = text;
}
void ExtractorEngine::setText(const QString &text)
void ExtractorEngine::setSenderDate(const QDateTime &dt)
{
m_text = text;
m_context->m_senderDate = dt;
}
QJsonArray ExtractorEngine::extract()
......@@ -114,6 +127,7 @@ void ExtractorEngine::executeScript()
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()
......
......@@ -27,6 +27,9 @@
#include <vector>
class ContextObject;
class QDateTime;
/** Code for executing an extractor rule set on a specific email part. */
class ExtractorEngine
{
......@@ -35,8 +38,9 @@ public:
~ExtractorEngine();
void setExtractor(const Extractor *extractor);
const QString &text() const;
void setText(const QString &text);
/** The date the email containing the processed text was sent. */
void setSenderDate(const QDateTime &dt);
QJsonArray extract();
......@@ -44,6 +48,7 @@ private:
void executeScript();
const Extractor *m_extractor = nullptr;
ContextObject *m_context = nullptr;
QString m_text;
QJsonArray m_result;
};
......
......@@ -10,6 +10,8 @@
<file>eurowings.js</file>
<file>fcmtravel.json</file>
<file>fcmtravel.js</file>
<file>sncf.json</file>
<file>sncf.js</file>
<file>swiss.json</file>
<file>swiss.js</file>
</qresource>
......
......@@ -17,6 +17,14 @@
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})/);
......@@ -38,8 +46,7 @@ function main(text) {
index += depLine.index + depLine[0].length;
res.reservationFor.departureStation = JsonLd.newObject("TrainStation");
res.reservationFor.departureStation.name = depLine[1];
// TODO determine the year (which is nowhere in the ticket!)
res.reservationFor.departureTime = JsonLd.toDateTime(depLine[2] + '/' + 1970 + ' ' + depLine[3], "dd/MM/yyyy hh'h'mm", "fr");
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)
......@@ -47,8 +54,7 @@ function main(text) {
index += arrLine.index + arrLine[0].length;
res.reservationFor.arrivalStation = JsonLd.newObject("TrainStation");
res.reservationFor.arrivalStation.name = arrLine[1];
// TODO year, see above
res.reservationFor.arrivalTime = JsonLd.toDateTime(arrLine[2] + '/' + 1970 + ' ' + arrLine[3], "dd/MM/yyyy hh'h'mm", "fr");
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
......
......@@ -104,6 +104,7 @@ MimeTreeParser::MessagePart::Ptr SemanticProcessor::process(MimeTreeParser::Inte
for (auto extractor : extractors) {
ExtractorEngine engine;
engine.setExtractor(extractor);
engine.setSenderDate(static_cast<KMime::Message*>(part.content()->topLevel())->date()->dateTime());
engine.setText(preproc.text());
const auto data = engine.extract();
qCDebug(SEMANTIC_LOG).noquote() << QJsonDocument(data).toJson();
......
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