File indexing completed on 2024-12-29 04:50:01

0001 /*
0002     SPDX-FileCopyrightText: 2023 Volker Krause <vkrause@kde.org>
0003     SPDX-License-Identifier: LGPL-2.0-or-later
0004 */
0005 
0006 #include "extractorengine.h"
0007 #include "logging.h"
0008 
0009 #include "text/pricefinder_p.h"
0010 
0011 #include <KItinerary/ExtractorDocumentNodeFactory>
0012 
0013 #include <QJSValue>
0014 #include <QJSValueIterator>
0015 #include <QScopeGuard>
0016 
0017 using namespace KItinerary;
0018 
0019 static constexpr inline auto RecursionDepthLimit = 10;
0020 
0021 JsApi::ExtractorEngine::ExtractorEngine(QObject *parent)
0022     : QObject(parent)
0023 {
0024 }
0025 
0026 JsApi::ExtractorEngine::~ExtractorEngine() = default;
0027 
0028 void JsApi::ExtractorEngine::setEngine(KItinerary::ExtractorEngine *engine)
0029 {
0030     m_engine = engine;
0031 }
0032 
0033 void JsApi::ExtractorEngine::setCurrentNode(const ExtractorDocumentNode& node)
0034 {
0035     m_currentNode = node;
0036 }
0037 
0038 void JsApi::ExtractorEngine::clear()
0039 {
0040     m_currentNode = {};
0041 }
0042 
0043 ExtractorDocumentNode JsApi::ExtractorEngine::extract(const QByteArray &data)
0044 {
0045     if (m_recursionDepth > RecursionDepthLimit) {
0046         qCWarning(Log) << "Recursion depth limit reached, aborting";
0047         return {};
0048     }
0049 
0050     const auto preHints = m_engine->hints();
0051     const auto prevNode = m_currentNode;
0052 
0053     m_engine->setHints(preHints | KItinerary::ExtractorEngine::ExtractFullPageRasterImages);
0054     auto node = m_engine->documentNodeFactory()->createNode(data);
0055     m_currentNode.appendChild(node);
0056 
0057     ++m_recursionDepth;
0058     m_engine->processNode(node);
0059     --m_recursionDepth;
0060 
0061     m_engine->setHints(preHints);
0062     m_currentNode = prevNode;
0063 
0064     return node;
0065 }
0066 
0067 ExtractorDocumentNode JsApi::ExtractorEngine::extract(const QVariant &content, const QString &mimeType)
0068 {
0069     if (m_recursionDepth > RecursionDepthLimit) {
0070         qCWarning(Log) << "Recursion depth limit reached, aborting";
0071         return {};
0072     }
0073 
0074     const auto preHints = m_engine->hints();
0075     const auto prevNode = m_currentNode;
0076 
0077     m_engine->setHints(preHints | KItinerary::ExtractorEngine::ExtractFullPageRasterImages);
0078     auto node = m_engine->documentNodeFactory()->createNode(content, mimeType);
0079     m_currentNode.appendChild(node);
0080 
0081     ++m_recursionDepth;
0082     m_engine->processNode(node);
0083     --m_recursionDepth;
0084 
0085     m_engine->setHints(preHints);
0086     m_currentNode = prevNode;
0087 
0088     return node;
0089 }
0090 
0091 static void applyPrice(const PriceFinder::Result &price, QJSValue obj)
0092 {
0093     if (!obj.isObject()) {
0094         return;
0095     }
0096     obj.setProperty(QStringLiteral("totalPrice"), price.value);
0097     obj.setProperty(QStringLiteral("priceCurrency"), price.currency);
0098 }
0099 
0100 void JsApi::ExtractorEngine::extractPrice(const QString &text, QJSValue result) const
0101 {
0102     PriceFinder finder;
0103     const auto price = finder.findHighest(text);
0104     if (!price.hasResult()) {
0105         return;
0106     }
0107 
0108     if (result.isArray()) {
0109         QJSValueIterator it(result);
0110         while (it.hasNext()) {
0111             it.next();
0112             applyPrice(price, it.value());
0113         }
0114     } else {
0115         applyPrice(price, result);
0116     }
0117 }
0118 
0119 #include "moc_extractorengine.cpp"