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_name;
28 QString m_mimeType;
29 QString m_fileName;
30 QString m_scriptName;
31 QString m_scriptFunction;
32 std::vector<ExtractorFilter> m_filters;
33 int m_index = -1;
34};
35}
36
37ScriptExtractor::ScriptExtractor()
38 : d(std::make_unique<ScriptExtractorPrivate>())
39{
40}
41
42ScriptExtractor::~ScriptExtractor() = default;
43
44bool ScriptExtractor::load(const QJsonObject &obj, const QString &fileName, int index)
45{
46 d->m_fileName = fileName;
47 d->m_index = index;
48
49 d->m_mimeType = obj.value(QLatin1StringView("mimeType")).toString();
50
51 const auto filterArray = obj.value(QLatin1StringView("filter")).toArray();
52 for (const auto &filterValue : filterArray) {
54 if (!f.load(filterValue.toObject())) {
55 qCDebug(Log) << "invalid filter expression:" << fileName;
56 return false;
57 }
58 d->m_filters.push_back(std::move(f));
59 }
60
61 const auto scriptName = obj.value(QLatin1StringView("script")).toString();
62 if (!scriptName.isEmpty()) {
63 QFileInfo fi(fileName);
64 d->m_scriptName = fi.path() + QLatin1Char('/') + scriptName;
65 }
66
67 if (!d->m_scriptName.isEmpty() && !QFile::exists(d->m_scriptName)) {
68 qCWarning(Log) << "Script file not found:" << d->m_scriptName;
69 return false;
70 }
71 d->m_scriptFunction = obj.value(QLatin1StringView("function"))
72 .toString(QStringLiteral("main"));
73
74 if (QFileInfo fi(d->m_fileName); d->m_index < 0) {
75 d->m_name = fi.baseName();
76 } else {
77 d->m_name = fi.baseName() + QLatin1Char(':') + QString::number(d->m_index);
78 }
79
80 return !d->m_filters.empty() && !d->m_mimeType.isEmpty();
81}
82
83QJsonObject ScriptExtractor::toJson() const
84{
85 QJsonObject obj;
86 obj.insert(QStringLiteral("mimeType"), d->m_mimeType);
87
88 QFileInfo metaFi(d->m_fileName);
89 QFileInfo scriptFi(d->m_scriptName);
90 if (metaFi.canonicalPath() == scriptFi.canonicalPath()) {
91 obj.insert(QStringLiteral("script"), scriptFi.fileName());
92 } else {
93 obj.insert(QStringLiteral("script"), d->m_scriptName);
94 }
95 obj.insert(QStringLiteral("function"), d->m_scriptFunction);
96
98 std::transform(d->m_filters.begin(), d->m_filters.end(), std::back_inserter(filters), std::mem_fn(&ExtractorFilter::toJson));
99 obj.insert(QStringLiteral("filter"), filters);
100
101 return obj;
102}
103
105{
106 return d->m_name;
107}
108
110{
111 return d->m_mimeType;
112}
113
114void ScriptExtractor::setMimeType(const QString &mimeType)
115{
116 d->m_mimeType = mimeType;
117}
118
120{
121 return d->m_scriptName;
122}
123
124void ScriptExtractor::setScriptFileName(const QString &script)
125{
126 d->m_scriptName = script;
127}
128
130{
131 return d->m_scriptFunction;
132}
133
134void ScriptExtractor::setScriptFunction(const QString &func)
135{
136 d->m_scriptFunction = func;
137}
138
139QString ScriptExtractor::fileName() const
140{
141 return d->m_fileName;
142}
143
144const std::vector<ExtractorFilter>& ScriptExtractor::filters() const
145{
146 return d->m_filters;
147}
148
149void ScriptExtractor::setFilters(std::vector<ExtractorFilter> &&filters)
150{
151 d->m_filters = std::move(filters);
152}
153
154void ScriptExtractor::setFilters(const std::vector<ExtractorFilter> &filters)
155{
156 d->m_filters = filters;
157}
158
160{
161 if (node.mimeType() != d->m_mimeType) {
162 return false;
163 }
164
165 // no filters matches always
166 if (d->m_filters.empty()) {
167 return true;
168 }
169
170 return std::any_of(d->m_filters.begin(), d->m_filters.end(), [&node](const auto &filter) {
171 return filter.matches(node);
172 });
173}
174
176{
177 std::vector<ExtractorDocumentNode> triggerNodes;
178 for (const auto &filter : d->m_filters) {
179 if (filter.scope() != ExtractorFilter::Current) {
180 filter.allMatches(node, triggerNodes);
181 }
182 }
183
184 if (triggerNodes.empty()) {
185 return engine->scriptEngine()->execute(this, node, node);
186 } else {
187 ExtractorResult result;
188 for (const auto &triggerNode : triggerNodes) {
189 result.append(engine->scriptEngine()->execute(this, node, triggerNode));
190 }
191 return result;
192 }
193}
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
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 18 2024 12:09:58 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.