From 72af78494652e97cf2caaf05a4ac1613359400f6 Mon Sep 17 00:00:00 2001 From: megabigbug Date: Mon, 4 Oct 2010 08:32:21 +0200 Subject: add an xml parser to the opensearch engine. --- src/CMakeLists.txt | 1 + src/opensearch/opensearchengine.cpp | 58 ++++----------- src/opensearch/opensearchengine.h | 10 +-- src/opensearch/opensearchmanager.cpp | 10 ++- src/opensearch/opensearchmanager.h | 4 +- src/opensearch/opensearchreader.cpp | 22 ++++-- src/opensearch/suggestionparser.cpp | 132 +++++++++++++++++++++++++++++++++++ src/opensearch/suggestionparser.h | 95 +++++++++++++++++++++++++ src/urlbar/urlresolver.cpp | 16 +++-- src/urlbar/urlresolver.h | 7 +- 10 files changed, 287 insertions(+), 68 deletions(-) create mode 100644 src/opensearch/suggestionparser.cpp create mode 100644 src/opensearch/suggestionparser.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b786bcdd..3cdad51a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -79,6 +79,7 @@ SET( rekonq_KDEINIT_SRCS opensearch/opensearchreader.cpp opensearch/opensearchmanager.cpp opensearch/opensearchengine.cpp + opensearch/suggestionparser.cpp ) diff --git a/src/opensearch/opensearchengine.cpp b/src/opensearch/opensearchengine.cpp index 9b0d7d03..88016ab0 100644 --- a/src/opensearch/opensearchengine.cpp +++ b/src/opensearch/opensearchengine.cpp @@ -30,25 +30,22 @@ // Self Includes #include "opensearchengine.h" +#include "suggestionparser.h" // Qt Includes #include -#include -#include -#include - OpenSearchEngine::OpenSearchEngine(QObject *) - : m_scriptEngine(0) + : m_parser(0) { } OpenSearchEngine::~OpenSearchEngine() { - if (m_scriptEngine) + if (m_parser) { - delete m_scriptEngine; + delete m_parser; } } @@ -187,6 +184,12 @@ void OpenSearchEngine::setSuggestionsParameters(const QList &suggesti } +void OpenSearchEngine::setSuggestionParser(SuggestionParser *parser) +{ + m_parser = parser; +} + + QString OpenSearchEngine::imageUrl() const { return m_imageUrl; @@ -235,43 +238,10 @@ bool OpenSearchEngine::operator<(const OpenSearchEngine &other) const } -QStringList OpenSearchEngine::parseSuggestion(const QByteArray &resp) +ResponseList OpenSearchEngine::parseSuggestion(const QByteArray &resp) { - QString response = QString::fromLocal8Bit(resp); - response = response.trimmed(); - - if (response.isEmpty()) - { - return QStringList(); - } - - if ( !response.startsWith(QL1C('[')) - || !response.endsWith(QL1C(']')) - ) - { - return QStringList(); - } - - 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); + if (!m_parser) + return ResponseList(); - return suggestionsList; + return m_parser->parse(resp); } diff --git a/src/opensearch/opensearchengine.h b/src/opensearch/opensearchengine.h index f2329624..d755fc95 100644 --- a/src/opensearch/opensearchengine.h +++ b/src/opensearch/opensearchengine.h @@ -33,6 +33,7 @@ // Rekonq Includes #include "rekonq_defines.h" +#include "suggestionparser.h" // KDE Includes #include @@ -41,11 +42,10 @@ #include #include + // Forward Declarations class QNetworkAccessManager; class QNetworkReply; -class QScriptEngine; - class OpenSearchEngine { @@ -77,6 +77,8 @@ public: QList suggestionsParameters() const; void setSuggestionsParameters(const QList &suggestionsParameters); + void setSuggestionParser(SuggestionParser *parser); + QString imageUrl() const; void setImageUrl(const QString &url); @@ -88,7 +90,7 @@ public: bool operator==(const OpenSearchEngine &other) const; bool operator<(const OpenSearchEngine &other) const; - QStringList parseSuggestion(const QByteArray &response); + ResponseList parseSuggestion(const QByteArray &response); static QString parseTemplate(const QString &searchTerm, const QString &searchTemplate); @@ -104,7 +106,7 @@ private: QList m_searchParameters; QList m_suggestionsParameters; - QScriptEngine *m_scriptEngine; + SuggestionParser *m_parser; }; #endif // OPENSEARCHENGINE_H diff --git a/src/opensearch/opensearchmanager.cpp b/src/opensearch/opensearchmanager.cpp index d0d47f63..ed8c5fc5 100644 --- a/src/opensearch/opensearchmanager.cpp +++ b/src/opensearch/opensearchmanager.cpp @@ -159,15 +159,19 @@ void OpenSearchManager::jobFinished(KJob *job) { if (job->error()) { - emit suggestionReceived(_typedText, QStringList()); + emit suggestionReceived(_typedText, ResponseList()); m_state = IDLE; return; // just silently return } if (m_state == REQ_SUGGESTION) { - const QStringList suggestionsList = m_activeEngine->parseSuggestion(m_jobData); - kDebug() << "Received suggestions in "<< _typedText << " from " << m_activeEngine->name() << ": " << suggestionsList; + const ResponseList suggestionsList = m_activeEngine->parseSuggestion(m_jobData); + kDebug() << "Received suggestions in "<< _typedText << " from " << m_activeEngine->name() << ": "; + foreach(Response r, suggestionsList) + { + kDebug() << r.title; + } emit suggestionReceived(_typedText, suggestionsList); idleJob(); diff --git a/src/opensearch/opensearchmanager.h b/src/opensearch/opensearchmanager.h index fd4b3820..43f11640 100644 --- a/src/opensearch/opensearchmanager.h +++ b/src/opensearch/opensearchmanager.h @@ -32,6 +32,7 @@ // Rekonq Includes #include "rekonq_defines.h" +#include "suggestionparser.h" // KDE Includes #include @@ -43,7 +44,6 @@ class SuggestionEngine; class OpenSearchEngine; - /** * This class acts as a proxy between the SearchBar plugin * and the individual suggestion engine. @@ -92,7 +92,7 @@ private slots: void jobFinished(KJob *job); signals: - void suggestionReceived(const QString &text, const QStringList &suggestion); + void suggestionReceived(const QString &text, const ResponseList &suggestion); void openSearchEngineAdded(const QString &name, const QString &searchUrl, const QString &fileName); private: diff --git a/src/opensearch/opensearchreader.cpp b/src/opensearch/opensearchreader.cpp index 5b7ece2c..7da4113f 100644 --- a/src/opensearch/opensearchreader.cpp +++ b/src/opensearch/opensearchreader.cpp @@ -32,6 +32,7 @@ // Local Includes #include "opensearchengine.h" +#include "suggestionparser.h" // Qt Includes #include @@ -137,16 +138,25 @@ OpenSearchEngine *OpenSearchReader::read() } } - if (type == QL1S("application/x-suggestions+json")) - { - engine->setSuggestionsUrlTemplate(url); - engine->setSuggestionsParameters(parameters); - } - else + if (type == QLatin1String("text/html")) { engine->setSearchUrlTemplate(url); engine->setSearchParameters(parameters); } + else + { + engine->setSuggestionsUrlTemplate(url); + engine->setSuggestionsParameters(parameters); + + if (type == QL1S("application/x-suggestions+xml")) + { + engine->setSuggestionParser(new XMLParser()); + } + else if (type == QL1S("application/x-suggestions+json")) + { + engine->setSuggestionParser(new JSONParser()); + } + } continue; } diff --git a/src/opensearch/suggestionparser.cpp b/src/opensearch/suggestionparser.cpp new file mode 100644 index 00000000..56cd2c8e --- /dev/null +++ b/src/opensearch/suggestionparser.cpp @@ -0,0 +1,132 @@ +/* ============================================================ + * + * This file is a part of the rekonq project + * + * Copyright (C) 2010 by Lionel Chauvin + * Copyright (C) 2010 by Andrea Diamantini + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * ============================================================ */ + +#define QL1C(x) QLatin1Char(x) +#define QL1S(x) QLatin1String(x) + +// Self Includes +#include "suggestionparser.h" + +// Local Includes +#include +// Qt Includes +#include +#include + +ResponseList SuggestionParser::parse(const QByteArray &resp) +{ + return ResponseList(); +} + + +SuggestionParser::~SuggestionParser() +{ +} + + +ResponseList XMLParser::parse(const QByteArray &resp) +{ + ResponseList rlist; + + m_reader.clear(); + m_reader.addData(resp); + + while (!m_reader.isStartElement() && !m_reader.atEnd()) + { + m_reader.readNext(); + } + + while (!(m_reader.isEndElement() && m_reader.name() == QL1S("SearchSuggestion")) && !m_reader.atEnd()) + { + m_reader.readNext(); + + if (!m_reader.isStartElement()) + continue; + + if (m_reader.name() == QL1S("Item")) + { + QString title; + QString url; + QString description; + + while (!m_reader.isEndElement() && !m_reader.atEnd()) + { + m_reader.readNext(); + + 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("Description")) description = m_reader.readElementText(); + } + + rlist << Response(url, title, description); + } + } + + return rlist; +} + + +ResponseList JSONParser::parse(const QByteArray &resp) +{ + QString response = QString::fromLocal8Bit(resp); + response = response.trimmed(); + + if (response.isEmpty()) + { + return ResponseList(); + } + + if (!response.startsWith(QL1C('[')) + || !response.endsWith(QL1C(']')) + ) + { + return ResponseList(); + } + + // Evaluate the JSON response using QtScript. + if (!m_reader.canEvaluate(response)) + { + return ResponseList(); + } + + QScriptValue responseParts = m_reader.evaluate(response); + + if (!responseParts.property(1).isArray()) + { + return ResponseList(); + } + + ResponseList rlist; + QStringList responsePartsList; + qScriptValueToSequence(responseParts.property(1), responsePartsList); + + foreach(QString s, responsePartsList) + { + rlist << Response(QString(), s, QString()); + } + + return rlist; +} \ No newline at end of file diff --git a/src/opensearch/suggestionparser.h b/src/opensearch/suggestionparser.h new file mode 100644 index 00000000..7de54654 --- /dev/null +++ b/src/opensearch/suggestionparser.h @@ -0,0 +1,95 @@ +/* ============================================================ + * + * This file is a part of the rekonq project + * + * Copyright (C) 2010 by Lionel Chauvin + * Copyright (C) 2010 by Andrea Diamantini + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * ============================================================ */ + +#ifndef SUGGESTIONPARSER_H +#define SUGGESTIONPARSER_H + +// Self Includes + +// Local Includes + + +// Qt Includes +#include +#include +#include + + +class Response +{ +public: + QString url; + QString title; + QString description; + + Response(const Response &item) : url(item.url), + title(item.title), + description(item.description) + {}; + + Response() : url(QString()), + title(QString()), + description(QString()) + {}; + + Response(const QString &_url, + const QString &_title = QString(), + const QString &description = QString()) : url(_url), + title(_title), + description(description) + {}; +}; + +typedef QList ResponseList; + + +class SuggestionParser +{ +public: + virtual ~SuggestionParser(); + virtual ResponseList parse(const QByteArray &resp); +}; + + +class XMLParser : public SuggestionParser +{ +protected: + QXmlStreamReader m_reader; + +public: + ResponseList parse(const QByteArray &resp); +}; + +class JSONParser : public SuggestionParser +{ +private: + QScriptEngine m_reader; + +public: + ResponseList parse(const QByteArray &resp); +}; + +#endif //SUGGESTIONPARSER_H \ No newline at end of file diff --git a/src/urlbar/urlresolver.cpp b/src/urlbar/urlresolver.cpp index 71d6e69c..a7c63969 100644 --- a/src/urlbar/urlresolver.cpp +++ b/src/urlbar/urlresolver.cpp @@ -29,11 +29,9 @@ #include "urlresolver.moc" // Local Includes -#include "application.h" #include "historymanager.h" #include "bookmarkprovider.h" #include "searchengine.h" -#include "opensearchmanager.h" // KDE Includes #include @@ -72,7 +70,7 @@ UrlResolver::UrlResolver(const QString &typedUrl) : QObject() , _typedString(typedUrl.trimmed()) { - if (!_searchEngine ) _searchEngine = SearchEngine::defaultEngine(); + if (!_searchEngine ) setSearchEngine(SearchEngine::defaultEngine()); if ( _browseRegexp.isEmpty() ) { @@ -392,25 +390,29 @@ void UrlResolver::computeSuggestions() if (Application::opensearchManager()->isSuggestionAvailable()) { connect(Application::opensearchManager(), - SIGNAL(suggestionReceived(const QString &, const QStringList &)), + SIGNAL(suggestionReceived(const QString &, const ResponseList &)), this, - SLOT(suggestionsReceived(const QString &, const QStringList &))); + SLOT(suggestionsReceived(const QString &, const ResponseList &))); Application::opensearchManager()->requestSuggestion(_typedString); } } -void UrlResolver::suggestionsReceived(const QString &text, const QStringList &suggestions) +void UrlResolver::suggestionsReceived(const QString &text, const ResponseList &suggestions) { if(text != _typedString) return; UrlSearchList sugList; - Q_FOREACH(const QString &s, suggestions) + Q_FOREACH(const Response &i, suggestions) { +<<<<<<< HEAD UrlSearchItem gItem(UrlSearchItem::Suggestion, SearchEngine::buildQuery(UrlResolver::searchEngine(), s), s); +======= + UrlSearchItem gItem(UrlSearchItem::Suggestion, i.title, i.title); +>>>>>>> add an xml parser to the opensearch engine. sugList << gItem; } emit suggestionsReady(sugList, _typedString); diff --git a/src/urlbar/urlresolver.h b/src/urlbar/urlresolver.h index f16c44f8..a94ef1de 100644 --- a/src/urlbar/urlresolver.h +++ b/src/urlbar/urlresolver.h @@ -30,6 +30,8 @@ // Rekonq Includes #include "rekonq_defines.h" +#include "application.h" +#include "opensearchmanager.h" // KDE Includes #include @@ -38,7 +40,7 @@ // Qt Includes #include #include -#include +#include "suggestionparser.h" class UrlSearchItem @@ -113,12 +115,13 @@ public: static void setSearchEngine(KService::Ptr engine) { _searchEngine = engine; + Application::opensearchManager()->setSearchProvider(engine->desktopEntryName()); }; void computeSuggestions(); private Q_SLOTS: - void suggestionsReceived(const QString &text, const QStringList &suggestions); + void suggestionsReceived(const QString &text, const ResponseList &suggestions); Q_SIGNALS: void suggestionsReady(const UrlSearchList &, const QString &); -- cgit v1.2.1