summaryrefslogtreecommitdiff
path: root/src/opensearch
diff options
context:
space:
mode:
Diffstat (limited to 'src/opensearch')
-rw-r--r--src/opensearch/opensearchengine.cpp6
-rw-r--r--src/opensearch/opensearchmanager.cpp166
-rw-r--r--src/opensearch/opensearchmanager.h20
-rw-r--r--src/opensearch/suggestionparser.cpp25
4 files changed, 175 insertions, 42 deletions
diff --git a/src/opensearch/opensearchengine.cpp b/src/opensearch/opensearchengine.cpp
index 9d5e866f..37685fb5 100644
--- a/src/opensearch/opensearchengine.cpp
+++ b/src/opensearch/opensearchengine.cpp
@@ -57,12 +57,18 @@ QString OpenSearchEngine::parseTemplate(const QString &searchTerm, const QString
QString language = QLocale().name();
// Simple conversion to RFC 3066.
language = language.replace(QL1C('_'), QL1C('-'));
+ QString country = language;
+ country = (country.replace(0, country.indexOf("-")+1, "")).toLower();
+ const int firstDashPosition = country.indexOf(QL1C('-'));
+ if (firstDashPosition >= 0)
+ country = country.mid(firstDashPosition+1);
QString result = searchTemplate;
result.replace(QL1S("{count}"), QL1S("20"));
result.replace(QL1S("{startIndex}"), QL1S("0"));
result.replace(QL1S("{startPage}"), QL1S("0"));
result.replace(QL1S("{language}"), language);
+ result.replace(QL1S("{country}"), country.toLower());
result.replace(QL1S("{inputEncoding}"), QL1S("UTF-8"));
result.replace(QL1S("{outputEncoding}"), QL1S("UTF-8"));
result.replace(QL1S("{searchTerms}"), searchTerm);
diff --git a/src/opensearch/opensearchmanager.cpp b/src/opensearch/opensearchmanager.cpp
index e5afc144..4ee1de33 100644
--- a/src/opensearch/opensearchmanager.cpp
+++ b/src/opensearch/opensearchmanager.cpp
@@ -34,6 +34,7 @@
#include "opensearchengine.h"
#include "opensearchreader.h"
#include "opensearchwriter.h"
+#include "application.h"
// KDE Includes
#include <KDebug>
@@ -41,10 +42,17 @@
#include <KStandardDirs>
#include <KUrl>
#include <kio/scheduler.h>
+#include <KService>
+#include <KStandardDirs>
+#include <KDE/KMessageBox>
+#include <KUriFilterData>
+#include <KConfigGroup>
// Qt Includes
#include <QtCore/QFile>
-
+#include <QtCore/QFileInfo>
+#include <QDBusMessage>
+#include <QDBusConnection>
OpenSearchManager::OpenSearchManager(QObject *parent)
: QObject(parent)
@@ -52,13 +60,15 @@ OpenSearchManager::OpenSearchManager(QObject *parent)
, m_currentJob(0)
{
m_state = IDLE;
+ loadEngines();
}
OpenSearchManager::~OpenSearchManager()
{
- qDeleteAll(m_enginesMap.values());
- m_enginesMap.clear();
+ qDeleteAll(m_engineCache.values());
+ m_engineCache.clear();
+ m_engines.clear();
}
@@ -66,10 +76,10 @@ void OpenSearchManager::setSearchProvider(const QString &searchProvider)
{
m_activeEngine = 0;
- if (!m_enginesMap.contains(searchProvider))
+ if (!m_engineCache.contains(searchProvider))
{
- const QString fileName = KGlobal::dirs()->findResource("data", "rekonq/opensearch/" + searchProvider + ".xml");
- kDebug() << searchProvider << " file name path: " << fileName;
+ const QString fileName = KGlobal::dirs()->findResource("data", "rekonq/opensearch/" + trimmedEngineName(searchProvider) + ".xml");
+ kDebug() << searchProvider << " trimmed name: " << trimmedEngineName(searchProvider) << " file name path: " << fileName;
if (fileName.isEmpty())
{
kDebug() << "OpenSearch file name empty";
@@ -88,7 +98,7 @@ void OpenSearchManager::setSearchProvider(const QString &searchProvider)
if (engine)
{
- m_enginesMap.insert(searchProvider, engine);
+ m_engineCache.insert(searchProvider, engine);
}
else
{
@@ -96,7 +106,7 @@ void OpenSearchManager::setSearchProvider(const QString &searchProvider)
}
}
- m_activeEngine = m_enginesMap.value(searchProvider);
+ m_activeEngine = m_engineCache.value(searchProvider);
}
@@ -106,22 +116,24 @@ bool OpenSearchManager::isSuggestionAvailable()
}
-void OpenSearchManager::addOpenSearchEngine(const KUrl &url, const QString &title)
+void OpenSearchManager::addOpenSearchEngine(const KUrl &url, const QString &title, const QString &shortcut)
{
Q_UNUSED(title);
+ m_shortcut = shortcut;
+
if (m_state != IDLE)
{
idleJob();
}
m_currentJob = KIO::get(url, KIO::NoReload, KIO::HideProgressInfo);
+ m_jobUrl = url;
m_state = REQ_DESCRIPTION;
connect(m_currentJob, SIGNAL(data(KIO::Job *, const QByteArray &)), this, SLOT(dataReceived(KIO::Job *, const QByteArray &)));
connect(m_currentJob, SIGNAL(result(KJob *)), this, SLOT(jobFinished(KJob *)));
}
-
void OpenSearchManager::requestSuggestion(const QString &searchText)
{
if (!m_activeEngine)
@@ -135,7 +147,7 @@ void OpenSearchManager::requestSuggestion(const QString &searchText)
// if we want in any case lets it finish its previous job we can just return here.
idleJob();
}
-
+
_typedText = searchText;
KUrl url = m_activeEngine->suggestionsUrl(searchText);
@@ -163,7 +175,7 @@ void OpenSearchManager::jobFinished(KJob *job)
m_state = IDLE;
return; // just silently return
}
-
+
if (m_state == REQ_SUGGESTION)
{
const ResponseList suggestionsList = m_activeEngine->parseSuggestion(m_jobData);
@@ -184,40 +196,144 @@ void OpenSearchManager::jobFinished(KJob *job)
OpenSearchEngine *engine = reader.read(m_jobData);
if (engine)
{
- m_enginesMap.insert(engine->name(), engine);
- QString path = KGlobal::dirs()->findResource("data", "rekonq/opensearch/");
- QString fileName = trimmedEngineName(engine->name());
- QFile file(path + fileName + ".xml");
- OpenSearchWriter writer;
- writer.write(&file, engine);
+ m_engineCache.insert(engine->name(), engine);
+ m_engines.insert(m_jobUrl, trimmedEngineName(engine->name()));
+ saveEngines();
+
+ QString path;
+ if (engine->providesSuggestions()) //save opensearch description only if it provides suggestions
+ {
+ OpenSearchWriter writer;
+ path = KGlobal::dirs()->findResource("data", "rekonq/opensearch/");
+ QFile file(path + trimmedEngineName(engine->name()) + ".xml");
+ writer.write(&file, engine);
+ }
QString searchUrl = OpenSearchEngine::parseTemplate("\\{@}", engine->searchUrlTemplate());
m_currentJob = NULL;
- emit openSearchEngineAdded(engine->name(), searchUrl, fileName);
+
+ path = KGlobal::mainComponent().dirs()->saveLocation("services", "searchproviders/");
+ KConfig _service(path + trimmedEngineName(engine->name()) + ".desktop", KConfig::SimpleConfig);
+ KConfigGroup service(&_service, "Desktop Entry");
+ service.writeEntry("Type", "Service");
+ service.writeEntry("ServiceTypes", "SearchProvider");
+ service.writeEntry("Name", engine->name());
+ service.writeEntry("Query", searchUrl);
+ service.writeEntry("Keys", m_shortcut);
+ // TODO charset
+ service.writeEntry("Charset", "" /* provider->charset() */);
+ // we might be overwriting a hidden entry
+ service.writeEntry("Hidden", false);
+ service.sync();
+
+ // Update filters in running applications...
+ QDBusMessage msg = QDBusMessage::createSignal("/", "org.kde.KUriFilterPlugin", "configure");
+ QDBusConnection::sessionBus().send(msg);
+
+ emit openSearchEngineAdded(engine->name(), searchUrl, m_shortcut);
}
else
{
kFatal() << "Error while adding new open search engine";
}
-
+
idleJob();
}
}
+void OpenSearchManager::loadEngines()
+{
+ QFile file(KStandardDirs::locate("appdata", "opensearch/db_opensearch.json"));
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
+ {
+ kDebug() << "opensearch db cannot be read";
+ return;
+ }
+
+ QString fileContent = QString::fromUtf8(file.readAll());
+ QScriptEngine reader;
+ if (!reader.canEvaluate(fileContent))
+ {
+ kDebug() << "opensearch db cannot be read";
+ return;
+ }
+
+ QScriptValue responseParts = reader.evaluate(fileContent);
+ QVariantList list;
+ qScriptValueToSequence(responseParts, list);
+ QStringList l;
+ Q_FOREACH(const QVariant &e, list)
+ {
+ l=e.toStringList();
+ m_engines.insert(KUrl(l.first()),l.last());
+ }
+ file.close();
+}
+
+
+void OpenSearchManager::saveEngines()
+{
+ QFile file(KStandardDirs::locate("appdata", "opensearch/db_opensearch.json"));
+ if (!file.open(QIODevice::WriteOnly))
+ {
+ kDebug() << "opensearch db cannot be writen";
+ return;
+ }
+ QTextStream out(&file);
+ out << "[";
+ int i=0;
+ QList<KUrl> urls = m_engines.keys();
+ Q_FOREACH(const KUrl &url, urls)
+ {
+ out << "[\"" << url.url() << "\",\"" << m_engines.value(url) << "\"]";
+ i++;
+ if (i != urls.size())
+ {
+ out << ",\n";
+ }
+ }
+ out << "]\n";
+ file.close();
+}
+
+
+void OpenSearchManager::removeDeletedEngines()
+{
+ KService::Ptr service;
+ Q_FOREACH(const KUrl &url, m_engines.keys())
+ {
+ service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(m_engines.value(url)));
+ if (!service)
+ {
+ QString path = KStandardDirs::locate("appdata", "opensearch/" + trimmedEngineName(m_engines.value(url)) + ".xml");
+ QFile::remove(path + trimmedEngineName(m_engines.value(url)) + ".xml");
+ m_engines.remove(url);
+ }
+ }
+ saveEngines();
+}
+
+
+bool OpenSearchManager::engineExists(const KUrl &url)
+{
+ return m_engines.contains(url);
+}
+
+
QString OpenSearchManager::trimmedEngineName(const QString &engineName) const
{
QString trimmed;
QString::ConstIterator constIter = engineName.constBegin();
- while (constIter != engineName.constEnd())
+ while (constIter != engineName.constEnd())
{
- if (constIter->isSpace())
+ if (constIter->isSpace())
{
- trimmed.append('-');
+ trimmed.append('_');
}
- else
+ else
{
- if (*constIter != '.')
+ if (*constIter != '.')
{
trimmed.append(constIter->toLower());
}
diff --git a/src/opensearch/opensearchmanager.h b/src/opensearch/opensearchmanager.h
index 4f42b4a8..df8e5367 100644
--- a/src/opensearch/opensearchmanager.h
+++ b/src/opensearch/opensearchmanager.h
@@ -39,6 +39,7 @@
// Qt Includes
#include <QtCore/QObject>
+#include <QFile>
// Forward Declarations
class OpenSearchEngine;
@@ -59,7 +60,7 @@ class OpenSearchManager : public QObject
REQ_DESCRIPTION,
IDLE
};
-
+
public:
/**
* Constructor
@@ -76,7 +77,7 @@ public:
*/
bool isSuggestionAvailable();
- void addOpenSearchEngine(const KUrl &url, const QString &title);
+ bool engineExists(const KUrl &url);
public Q_SLOTS:
/**
@@ -85,6 +86,8 @@ public Q_SLOTS:
* @param searchText the text to be queried to the suggestion service
*/
void requestSuggestion(const QString &searchText);
+ void addOpenSearchEngine(const KUrl &url, const QString &title, const QString &shortcut);
+ void removeDeletedEngines();
private Q_SLOTS:
void dataReceived(KIO::Job *job, const QByteArray &data);
@@ -96,18 +99,23 @@ Q_SIGNALS:
private:
QString trimmedEngineName(const QString &engineName) const;
-
+ void loadEngines();
+ void saveEngines();
void idleJob();
-
+
// QString substitutueSearchText(const QString &searchText, const QString &requestURL) const;
QByteArray m_jobData;
- QMap<QString, OpenSearchEngine*> m_enginesMap;
+ QMap<QString, OpenSearchEngine*> m_engineCache;
+ QMap<KUrl, QString> m_engines;
+
OpenSearchEngine *m_activeEngine;
STATE m_state;
-
+
KIO::TransferJob *m_currentJob;
+ KUrl m_jobUrl;
QString _typedText;
+ QString m_shortcut;
};
#endif // OPENSEARCHMANAGER_H
diff --git a/src/opensearch/suggestionparser.cpp b/src/opensearch/suggestionparser.cpp
index 4ed13e16..b2ecd009 100644
--- a/src/opensearch/suggestionparser.cpp
+++ b/src/opensearch/suggestionparser.cpp
@@ -35,7 +35,7 @@
ResponseList SuggestionParser::parse(const QByteArray &)
{
- return ResponseList();
+ return ResponseList();
}
@@ -47,7 +47,7 @@ SuggestionParser::~SuggestionParser()
ResponseList XMLParser::parse(const QByteArray &resp)
{
ResponseList rlist;
-
+
m_reader.clear();
m_reader.addData(resp);
@@ -73,16 +73,19 @@ ResponseList XMLParser::parse(const QByteArray &resp)
{
if(m_reader.isStartElement())
{
+
if (m_reader.name() == QL1S("Text"))
title = m_reader.readElementText();
if (m_reader.name() == QL1S("Url"))
url = m_reader.readElementText();
+
if (m_reader.name() == QL1S("Image"))
{
image = m_reader.attributes().value("source").toString();
image_width = m_reader.attributes().value("width").toString().toInt();
image_height = m_reader.attributes().value("height").toString().toInt();
}
+
if (m_reader.name() == QL1S("Description"))
description = m_reader.readElementText();
}
@@ -94,7 +97,7 @@ ResponseList XMLParser::parse(const QByteArray &resp)
m_reader.readNext();
}
-
+
return rlist;
}
@@ -103,23 +106,23 @@ ResponseList JSONParser::parse(const QByteArray &resp)
{
QString response = QString::fromLocal8Bit(resp);
response = response.trimmed();
-
- if (response.isEmpty())
+
+ if (response.isEmpty())
{
kDebug() << "RESPONSE IS EMPTY";
return ResponseList();
}
-
- if (!response.startsWith(QL1C('['))
+
+ if (!response.startsWith(QL1C('['))
|| !response.endsWith(QL1C(']'))
- )
+ )
{
kDebug() << "RESPONSE is NOT well FORMED";
return ResponseList();
}
// Evaluate the JSON response using QtScript.
- if (!m_reader.canEvaluate(response))
+ if (!m_reader.canEvaluate(response))
{
kDebug() << "m_reader cannot evaluate the response";
return ResponseList();
@@ -127,7 +130,7 @@ ResponseList JSONParser::parse(const QByteArray &resp)
QScriptValue responseParts = m_reader.evaluate(response);
- if (!responseParts.property(1).isArray())
+ if (!responseParts.property(1).isArray())
{
kDebug() << "RESPONSE is not an array";
return ResponseList();
@@ -141,6 +144,6 @@ ResponseList JSONParser::parse(const QByteArray &resp)
{
rlist << Response(s);
}
-
+
return rlist;
}