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/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 +++++++++++++++++++++++++ 7 files changed, 272 insertions(+), 59 deletions(-) create mode 100644 src/opensearch/suggestionparser.cpp create mode 100644 src/opensearch/suggestionparser.h (limited to 'src/opensearch') 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 -- cgit v1.2.1