Commit 72ddfa7d authored by Alexander Lohnau's avatar Alexander Lohnau 💬
Browse files

Clean up defunct opensearch classes

We only ever used google, but here the API endpoint was removed.
In the code we silently failed without any indication what went wrong.
See also BUG: 299846.

If we were to add suggestions, we would need to reimplement it anyways.

This way we also get rid of the QtScript dependency.
parent 63be3163
Pipeline #143466 passed with stage
in 6 minutes and 42 seconds
project (searchbar)
add_definitions(-DTRANSLATION_DOMAIN=\"searchbarplugin\")
find_package(Qt5 REQUIRED Script)
add_subdirectory( icons )
add_subdirectory( opensearch )
########### next target ###############
set(searchbarplugin_PART_SRCS
searchbar.cpp
OpenSearchManager.cpp
SuggestionEngine.cpp
WebShortcutWidget.cpp
opensearch/OpenSearchEngine.cpp
opensearch/OpenSearchReader.cpp
opensearch/OpenSearchWriter.cpp)
WebShortcutWidget.cpp)
ecm_qt_declare_logging_category(searchbarplugin_PART_SRCS HEADER searchbar_debug.h IDENTIFIER SEARCHBAR_LOG CATEGORY_NAME org.kde.konqueror.searchbar)
add_library(searchbarplugin MODULE ${searchbarplugin_PART_SRCS})
kcoreaddons_desktop_to_json(searchbarplugin searchbar.desktop)
target_link_libraries(searchbarplugin KF5::I18n KF5::TextWidgets KF5::Parts Qt5::Script KF5Konq)
target_link_libraries(searchbarplugin KF5::I18n KF5::TextWidgets KF5::Parts KF5Konq)
install(TARGETS searchbarplugin DESTINATION ${KDE_INSTALL_PLUGINDIR}/konqueror/kpartplugins)
install(FILES searchbarplugin.rc DESTINATION ${KDE_INSTALL_DATADIR}/konqueror/partsrcfiles)
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2009 Fredy Yanardi <fyanardi@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "OpenSearchManager.h"
#include <QFile>
#include <QUrl>
#include <QStandardPaths>
#include "opensearch/OpenSearchEngine.h"
#include "opensearch/OpenSearchReader.h"
#include "opensearch/OpenSearchWriter.h"
#include "searchbar_debug.h"
OpenSearchManager::OpenSearchManager(QObject *parent)
: QObject(parent)
, m_activeEngine(nullptr)
{
m_state = IDLE;
}
OpenSearchManager::~OpenSearchManager()
{
qDeleteAll(m_enginesMap);
m_enginesMap.clear();
}
void OpenSearchManager::setSearchProvider(const QString &searchProvider)
{
m_activeEngine = nullptr;
if (!m_enginesMap.contains(searchProvider)) {
const QString fileName = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "konqueror/opensearch/" + searchProvider + ".xml");
if (fileName.isEmpty()) {
return;
}
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qCWarning(SEARCHBAR_LOG) << "Cannot open opensearch description file: " + fileName;
return;
}
OpenSearchReader reader;
OpenSearchEngine *engine = reader.read(&file);
if (engine) {
m_enginesMap.insert(searchProvider, engine);
} else {
return;
}
}
m_activeEngine = m_enginesMap.value(searchProvider);
}
bool OpenSearchManager::isSuggestionAvailable()
{
return m_activeEngine != nullptr;
}
void OpenSearchManager::addOpenSearchEngine(const QUrl &url, const QString &title)
{
Q_UNUSED(title);
m_jobData.clear();
if (m_state != IDLE) {
// TODO: cancel job
}
m_state = REQ_DESCRIPTION;
KIO::TransferJob *job = KIO::get(url, KIO::NoReload, KIO::HideProgressInfo);
connect(job, &KIO::TransferJob::data, this, &OpenSearchManager::dataReceived);
connect(job, &KJob::result, this, &OpenSearchManager::jobFinished);
}
void OpenSearchManager::requestSuggestion(const QString &searchText)
{
if (!m_activeEngine) {
return;
}
if (m_state != IDLE) {
// TODO: cancel job
}
m_state = REQ_SUGGESTION;
QUrl url = m_activeEngine->suggestionsUrl(searchText);
qCDebug(SEARCHBAR_LOG) << "Requesting for suggestions: " << url.url();
m_jobData.clear();
KIO::TransferJob *job = KIO::get(url, KIO::NoReload, KIO::HideProgressInfo);
connect(job, &KIO::TransferJob::data, this, &OpenSearchManager::dataReceived);
connect(job, &KJob::result, this, &OpenSearchManager::jobFinished);
}
void OpenSearchManager::dataReceived(KIO::Job *job, const QByteArray &data)
{
Q_UNUSED(job);
m_jobData.append(data);
}
void OpenSearchManager::jobFinished(KJob *job)
{
if (job->error()) {
return; // just silently return
}
if (m_state == REQ_SUGGESTION) {
const QStringList suggestionsList = m_activeEngine->parseSuggestion(m_jobData);
qCDebug(SEARCHBAR_LOG) << "Received suggestion from " << m_activeEngine->name() << ": " << suggestionsList;
emit suggestionReceived(suggestionsList);
} else if (m_state == REQ_DESCRIPTION) {
OpenSearchReader reader;
OpenSearchEngine *engine = reader.read(m_jobData);
if (engine) {
m_enginesMap.insert(engine->name(), engine);
QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("/konqueror/opensearch/"), QStandardPaths::LocateDirectory) + "/";
QString fileName = trimmedEngineName(engine->name());
QFile file(path + fileName + ".xml");
OpenSearchWriter writer;
writer.write(&file, engine);
QString searchUrl = OpenSearchEngine::parseTemplate(QStringLiteral("\\{@}"), engine->searchUrlTemplate());
emit openSearchEngineAdded(engine->name(), searchUrl, fileName);
} else {
qCCritical(SEARCHBAR_LOG) << "Error while adding new open search engine";
}
}
}
QString OpenSearchManager::trimmedEngineName(const QString &engineName) const
{
QString trimmed;
QString::ConstIterator constIter = engineName.constBegin();
while (constIter != engineName.constEnd()) {
if (constIter->isSpace()) {
trimmed.append('-');
} else if (*constIter != '.') {
trimmed.append(constIter->toLower());
}
constIter++;
}
return trimmed;
}
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2009 Fredy Yanardi <fyanardi@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef OPENSEARCHMANAGER_H
#define OPENSEARCHMANAGER_H
#include <QObject>
#include <kio/jobclasses.h>
class OpenSearchEngine;
/**
* This class acts as a proxy between the SearchBar plugin and the individual suggestion engine.
* This class has a map of all available engines, and route the suggestion request to the correct engine
*/
class OpenSearchManager : public QObject
{
Q_OBJECT
enum STATE {
REQ_SUGGESTION,
REQ_DESCRIPTION,
IDLE
};
public:
/**
* Constructor
*/
explicit OpenSearchManager(QObject *parent = nullptr);
~OpenSearchManager() override;
void setSearchProvider(const QString &searchProvider);
/**
* Check whether a search suggestion engine is available for the given search provider
* @param searchProvider the queried search provider
*/
bool isSuggestionAvailable();
void addOpenSearchEngine(const QUrl &url, const QString &title);
public slots:
/**
* Ask the specific suggestion engine to request for suggestion for the search text
* @param searchProvider the search provider that provides the suggestion service
* @param searchText the text to be queried to the suggestion service
*/
void requestSuggestion(const QString &searchProvider);
private slots:
void dataReceived(KIO::Job *job, const QByteArray &data);
void jobFinished(KJob *job);
signals:
void suggestionReceived(const QStringList &suggestion);
void openSearchEngineAdded(const QString &name, const QString &searchUrl, const QString &fileName);
private:
QString trimmedEngineName(const QString &engineName) const;
// QString substitutueSearchText(const QString &searchText, const QString &requestURL) const;
QByteArray m_jobData;
QMap<QString, OpenSearchEngine *> m_enginesMap;
OpenSearchEngine *m_activeEngine;
STATE m_state;
};
#endif // OPENSEARCHMANAGER_H
/*
SPDX-FileCopyrightText: 2009 Jakub Wieczorek <faw217@gmail.com>
SPDX-FileCopyrightText: 2009 Christian Franke <cfchris6@ts2server.com>
SPDX-FileCopyrightText: 2009 Fredy Yanardi <fyanardi@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "OpenSearchEngine.h"
#include <QRegExp>
#include <QStringList>
#include <QScriptEngine>
#include <QScriptValue>
#include <QLocale>
#include <QUrlQuery>
OpenSearchEngine::OpenSearchEngine(QObject *)
: m_scriptEngine(nullptr)
{
}
OpenSearchEngine::~OpenSearchEngine()
{
delete m_scriptEngine;
}
QString OpenSearchEngine::parseTemplate(const QString &searchTerm, const QString &searchTemplate)
{
QString result = searchTemplate;
result.replace(QLatin1String("{count}"), QLatin1String("20"));
result.replace(QLatin1String("{startIndex}"), QLatin1String("0"));
result.replace(QLatin1String("{startPage}"), QLatin1String("0"));
result.replace(QLatin1String("{language}"), QLocale::languageToString(QLocale().language()));
result.replace(QLatin1String("{inputEncoding}"), QLatin1String("UTF-8"));
result.replace(QLatin1String("{outputEncoding}"), QLatin1String("UTF-8"));
result.replace(QLatin1String("{searchTerms}"), searchTerm);
return result;
}
QString OpenSearchEngine::name() const
{
return m_name;
}
void OpenSearchEngine::setName(const QString &name)
{
m_name = name;
}
QString OpenSearchEngine::description() const
{
return m_description;
}
void OpenSearchEngine::setDescription(const QString &description)
{
m_description = description;
}
QString OpenSearchEngine::searchUrlTemplate() const
{
return m_searchUrlTemplate;
}
void OpenSearchEngine::setSearchUrlTemplate(const QString &searchUrlTemplate)
{
m_searchUrlTemplate = searchUrlTemplate;
}
QUrl OpenSearchEngine::searchUrl(const QString &searchTerm) const
{
if (m_searchUrlTemplate.isEmpty()) {
return QUrl();
}
QUrl retVal = QUrl::fromEncoded(parseTemplate(searchTerm, m_searchUrlTemplate).toUtf8());
QUrlQuery query(retVal);
QList<Parameter>::const_iterator end = m_searchParameters.constEnd();
QList<Parameter>::const_iterator i = m_searchParameters.constBegin();
for (; i != end; ++i) {
query.addQueryItem(i->first, parseTemplate(searchTerm, i->second));
}
retVal.setQuery(query);
return retVal;
}
bool OpenSearchEngine::providesSuggestions() const
{
return !m_suggestionsUrlTemplate.isEmpty();
}
QString OpenSearchEngine::suggestionsUrlTemplate() const
{
return m_suggestionsUrlTemplate;
}
void OpenSearchEngine::setSuggestionsUrlTemplate(const QString &suggestionsUrlTemplate)
{
m_suggestionsUrlTemplate = suggestionsUrlTemplate;
}
QUrl OpenSearchEngine::suggestionsUrl(const QString &searchTerm) const
{
if (m_suggestionsUrlTemplate.isEmpty()) {
return QUrl();
}
QUrl retVal = QUrl::fromEncoded(parseTemplate(searchTerm, m_suggestionsUrlTemplate).toUtf8());
QUrlQuery query(retVal);
QList<Parameter>::const_iterator end = m_suggestionsParameters.constEnd();
QList<Parameter>::const_iterator i = m_suggestionsParameters.constBegin();
for (; i != end; ++i) {
query.addQueryItem(i->first, parseTemplate(searchTerm, i->second));
}
retVal.setQuery(query);
return retVal;
}
QList<OpenSearchEngine::Parameter> OpenSearchEngine::searchParameters() const
{
return m_searchParameters;
}
void OpenSearchEngine::setSearchParameters(const QList<Parameter> &searchParameters)
{
m_searchParameters = searchParameters;
}
QList<OpenSearchEngine::Parameter> OpenSearchEngine::suggestionsParameters() const
{
return m_suggestionsParameters;
}
void OpenSearchEngine::setSuggestionsParameters(const QList<Parameter> &suggestionsParameters)
{
m_suggestionsParameters = suggestionsParameters;
}
QString OpenSearchEngine::imageUrl() const
{
return m_imageUrl;
}
void OpenSearchEngine::setImageUrl(const QString &imageUrl)
{
m_imageUrl = imageUrl;
}
QImage OpenSearchEngine::image() const
{
return m_image;
}
void OpenSearchEngine::setImage(const QImage &image)
{
m_image = image;
}
bool OpenSearchEngine::isValid() const
{
return (!m_name.isEmpty() && !m_searchUrlTemplate.isEmpty());
}
bool OpenSearchEngine::operator==(const OpenSearchEngine &other) const
{
return (m_name == other.m_name
&& m_description == other.m_description
&& m_imageUrl == other.m_imageUrl
&& m_searchUrlTemplate == other.m_searchUrlTemplate
&& m_suggestionsUrlTemplate == other.m_suggestionsUrlTemplate
&& m_searchParameters == other.m_searchParameters
&& m_suggestionsParameters == other.m_suggestionsParameters);
}
bool OpenSearchEngine::operator<(const OpenSearchEngine &other) const
{
return (m_name < other.m_name);
}
QStringList OpenSearchEngine::parseSuggestion(const QByteArray &resp)
{
const QString response = QString::fromUtf8(resp.constData(), resp.size()).trimmed();
if (response.isEmpty()) {
return QStringList();
}
if (!response.startsWith(QLatin1Char('[')) || !response.endsWith(QLatin1Char(']'))) {
return QStringList();
}
#ifdef __GNUC__
#warning "QScriptEngine is deprecated, port to QJsonDocument"
#endif
if (!m_scriptEngine) {
m_scriptEngine = new QScriptEngine();
}
// Evaluate the JSON response using QtScript.
if (!m_scriptEngine->canEvaluate(response)) {
return QStringList();
}
QScriptValue responseParts = m_scriptEngine->evaluate(response);
if (!responseParts.property(1).isArray()) {
return QStringList();
}
QStringList suggestionsList;
qScriptValueToSequence(responseParts.property(1), suggestionsList);
return suggestionsList;
}
/*
SPDX-FileCopyrightText: 2009 Jakub Wieczorek <faw217@gmail.com>
SPDX-FileCopyrightText: 2009 Christian Franke <cfchris6@ts2server.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef OPENSEARCHENGINE_H
#define OPENSEARCHENGINE_H
#include <QPair>
#include <QImage>
#include <QUrl>
class QScriptEngine;
class OpenSearchEngine
{
public:
typedef QPair<QString, QString> Parameter;
OpenSearchEngine(QObject *parent = nullptr);
~OpenSearchEngine();
QString name() const;
void setName(const QString &name);
QString description() const;
void setDescription(const QString &description);
QString searchUrlTemplate() const;
void setSearchUrlTemplate(const QString &searchUrl);
QUrl searchUrl(const QString &searchTerm) const;
bool providesSuggestions() const;
QString suggestionsUrlTemplate() const;
void setSuggestionsUrlTemplate(const QString &suggestionsUrl);
QUrl suggestionsUrl(const QString &searchTerm) const;
QList<Parameter> searchParameters() const;
void setSearchParameters(const QList<Parameter> &searchParameters);
QList<Parameter> suggestionsParameters() const;
void setSuggestionsParameters(const QList<Parameter> &suggestionsParameters);
QString imageUrl() const;
void setImageUrl(const QString &url);
QImage image() const;
void setImage(const QImage &image);
bool isValid() const;
bool operator==(const OpenSearchEngine &other) const;
bool operator<(const OpenSearchEngine &other) const;
QStringList parseSuggestion(const QByteArray &response);
static QString parseTemplate(const QString &searchTerm, const QString &searchTemplate);
private:
QString m_name;
QString m_description;
QString m_imageUrl;
QImage m_image;
QString m_searchUrlTemplate;
QString m_suggestionsUrlTemplate;
QList<Parameter> m_searchParameters;
QList<Parameter> m_suggestionsParameters;
QScriptEngine *m_scriptEngine;
};
#endif // OPENSEARCHENGINE_H
/*
SPDX-FileCopyrightText: 2009 Jakub Wieczorek <faw217@gmail.com>
SPDX-FileCopyrightText: 2009 Fredy Yanardi <fyanardi@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "OpenSearchReader.h"
#include "OpenSearchEngine.h"
#include <QIODevice>
#include <KLocalizedString>
OpenSearchReader::OpenSearchReader()
: QXmlStreamReader()
{
}
OpenSearchEngine *OpenSearchReader::read(const QByteArray &data)
{
clear();
addData(data);
return read();
}
OpenSearchEngine *OpenSearchReader::read(QIODevice *device)
{
clear();
if (!device->isOpen()) {
device->open(QIODevice::ReadOnly);
}
setDevice(device);
return read();
}
OpenSearchEngine *OpenSearchReader::read()
{