KItinerary

scriptextractor.cpp
1/*
2 SPDX-FileCopyrightText: 2017-2021 Volker Krause <vkrause@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "scriptextractor.h"
8#include "extractorscriptengine_p.h"
9#include "logging.h"
10
11#include <KItinerary/ExtractorDocumentNode>
12#include <KItinerary/ExtractorEngine>
13#include <KItinerary/ExtractorFilter>
14#include <KItinerary/ExtractorResult>
15
16#include <QFile>
17#include <QFileInfo>
18#include <QJsonArray>
19#include <QJsonObject>
20
21using namespace KItinerary;
22
23namespace KItinerary {
24class ScriptExtractorPrivate
25{
26public:
27 QString m_mimeType;
28 QString m_fileName;
29 QString m_scriptName;
30 QString m_scriptFunction;
31 std::vector<ExtractorFilter> m_filters;
32 int m_index = -1;
33};
34}
35
36ScriptExtractor::ScriptExtractor()
37 : d(std::make_unique<ScriptExtractorPrivate>())
38{
39}
40
41ScriptExtractor::~ScriptExtractor() = default;
42
43bool ScriptExtractor::load(const QJsonObject &obj, const QString &fileName, int index)
44{
45 d->m_fileName = fileName;
46 d->m_index = index;
47
48 d->m_mimeType = obj.value(QLatin1StringView("mimeType")).toString();
49
50 const auto filterArray = obj.value(QLatin1StringView("filter")).toArray();
51 for (const auto &filterValue : filterArray) {
53 if (!f.load(filterValue.toObject())) {
54 qCDebug(Log) << "invalid filter expression:" << fileName;
55 return false;
56 }
57 d->m_filters.push_back(std::move(f));
58 }
59
60 const auto scriptName = obj.value(QLatin1StringView("script")).toString();
61 if (!scriptName.isEmpty()) {
62 QFileInfo fi(fileName);
63 d->m_scriptName = fi.path() + QLatin1Char('/') + scriptName;
64 }
65
66 if (!d->m_scriptName.isEmpty() && !QFile::exists(d->m_scriptName)) {
67 qCWarning(Log) << "Script file not found:" << d->m_scriptName;
68 return false;
69 }
70 d->m_scriptFunction = obj.value(QLatin1StringView("function"))
71 .toString(QStringLiteral("main"));
72
73 return !d->m_filters.empty() && !d->m_mimeType.isEmpty();
74}
75
76QJsonObject ScriptExtractor::toJson() const
77{
78 QJsonObject obj;
79 obj.insert(QStringLiteral("mimeType"), d->m_mimeType);
80
81 QFileInfo metaFi(d->m_fileName);
82 QFileInfo scriptFi(d->m_scriptName);
83 if (metaFi.canonicalPath() == scriptFi.canonicalPath()) {
84 obj.insert(QStringLiteral("script"), scriptFi.fileName());
85 } else {
86 obj.insert(QStringLiteral("script"), d->m_scriptName);
87 }
88 obj.insert(QStringLiteral("function"), d->m_scriptFunction);
89
91 std::transform(d->m_filters.begin(), d->m_filters.end(), std::back_inserter(filters), std::mem_fn(&ExtractorFilter::toJson));
92 obj.insert(QStringLiteral("filter"), filters);
93
94 return obj;
95}
96
98{
99 QFileInfo fi(d->m_fileName);
100 if (d->m_index < 0) {
101 return fi.baseName();
102 }
103 return fi.baseName() + QLatin1Char(':') + QString::number(d->m_index);
104}
105
107{
108 return d->m_mimeType;
109}
110
111void ScriptExtractor::setMimeType(const QString &mimeType)
112{
113 d->m_mimeType = mimeType;
114}
115
117{
118 return d->m_scriptName;
119}
120
121void ScriptExtractor::setScriptFileName(const QString &script)
122{
123 d->m_scriptName = script;
124}
125
127{
128 return d->m_scriptFunction;
129}
130
131void ScriptExtractor::setScriptFunction(const QString &func)
132{
133 d->m_scriptFunction = func;
134}
135
136QString ScriptExtractor::fileName() const
137{
138 return d->m_fileName;
139}
140
141const std::vector<ExtractorFilter>& ScriptExtractor::filters() const
142{
143 return d->m_filters;
144}
145
146void ScriptExtractor::setFilters(std::vector<ExtractorFilter> &&filters)
147{
148 d->m_filters = std::move(filters);
149}
150
151void ScriptExtractor::setFilters(const std::vector<ExtractorFilter> &filters)
152{
153 d->m_filters = filters;
154}
155
157{
158 if (node.mimeType() != d->m_mimeType) {
159 return false;
160 }
161
162 // no filters matches always
163 if (d->m_filters.empty()) {
164 return true;
165 }
166
167 return std::any_of(d->m_filters.begin(), d->m_filters.end(), [&node](const auto &filter) {
168 return filter.matches(node);
169 });
170}
171
173{
174 std::vector<ExtractorDocumentNode> triggerNodes;
175 for (const auto &filter : d->m_filters) {
176 if (filter.scope() != ExtractorFilter::Current) {
177 filter.allMatches(node, triggerNodes);
178 }
179 }
180
181 if (triggerNodes.empty()) {
182 return engine->scriptEngine()->execute(this, node, node);
183 } else {
184 ExtractorResult result;
185 for (const auto &triggerNode : triggerNodes) {
186 result.append(engine->scriptEngine()->execute(this, node, triggerNode));
187 }
188 return result;
189 }
190}
A node in the extracted document object tree.
QString mimeType
The MIME type of this node.
Semantic data extraction engine.
Determines whether an extractor is applicable to a given email.
@ Current
match the node being extracted
Generic extraction result.
void append(ExtractorResult &&other)
Append another result to this one.
QString scriptFunction() const
The JS function entry point for this extractor, main if empty.
ExtractorResult extract(const ExtractorDocumentNode &node, const ExtractorEngine *engine) const override
Extract data from node.
const std::vector< ExtractorFilter > & filters() const
Returns the filters deciding whether this extractor should be applied.
QString mimeType() const
Mime type this script extractor supports.
QString name() const override
Identifier for this extractor.
QString scriptFileName() const
The JS script containing the code of the extractor.
bool canHandle(const ExtractorDocumentNode &node) const override
Fast check whether this extractor is applicable for node.
Classes for reservation/travel data models, data extraction and data augmentation.
Definition berelement.h:17
bool exists() const const
QString baseName() const const
iterator insert(QLatin1StringView key, const QJsonValue &value)
QJsonValue value(QLatin1StringView key) const const
QJsonArray toArray() const const
QString toString() const const
QString number(double n, char format, int precision)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 4 2024 16:28:48 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.