diff options
Diffstat (limited to 'src/opensearch')
| -rw-r--r-- | src/opensearch/opensearchengine.cpp | 274 | ||||
| -rw-r--r-- | src/opensearch/opensearchengine.h | 110 | ||||
| -rw-r--r-- | src/opensearch/opensearchmanager.cpp | 234 | ||||
| -rw-r--r-- | src/opensearch/opensearchmanager.h | 112 | ||||
| -rw-r--r-- | src/opensearch/opensearchreader.cpp | 174 | ||||
| -rw-r--r-- | src/opensearch/opensearchreader.h | 55 | ||||
| -rw-r--r-- | src/opensearch/opensearchwriter.cpp | 134 | ||||
| -rw-r--r-- | src/opensearch/opensearchwriter.h | 56 | ||||
| -rw-r--r-- | src/opensearch/searchengine.cpp | 157 | ||||
| -rw-r--r-- | src/opensearch/searchengine.h | 59 | 
10 files changed, 1365 insertions, 0 deletions
| diff --git a/src/opensearch/opensearchengine.cpp b/src/opensearch/opensearchengine.cpp new file mode 100644 index 00000000..78e50980 --- /dev/null +++ b/src/opensearch/opensearchengine.cpp @@ -0,0 +1,274 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Jakub Wieczorek <faw217@gmail.com> +* Copyright (C) 2009 by Christian Franke <cfchris6@ts2server.com> +* Copyright (C) 2009 by Fredy Yanardi <fyanardi@gmail.com> +* Copyright (C) 2010 by Lionel Chauvin <megabigbug@yahoo.fr> +* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com> +* +* +* 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 <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +// Self Includes +#include "opensearchengine.h" + +// Qt Includes +#include <QtCore/QRegExp> +#include <QtCore/QStringList> +#include <QtScript/QScriptEngine> +#include <QtScript/QScriptValue> + + +OpenSearchEngine::OpenSearchEngine(QObject *) +    : m_scriptEngine(0) +{ +} + + +OpenSearchEngine::~OpenSearchEngine() +{ +    if (m_scriptEngine)  +    { +        delete m_scriptEngine; +    } +} + + +QString OpenSearchEngine::parseTemplate(const QString &searchTerm, const QString &searchTemplate) +{ +    QString result = searchTemplate; +    result.replace(QL1S("{count}"), QL1S("20")); +    result.replace(QL1S("{startIndex}"), QL1S("0")); +    result.replace(QL1S("{startPage}"), QL1S("0")); +    // TODO - get setting from KDE +    result.replace(QL1S("{language}"), QL1S("en-US")); +    result.replace(QL1S("{inputEncoding}"), QL1S("UTF-8")); +    result.replace(QL1S("{outputEncoding}"), QL1S("UTF-8")); +    result.replace(QL1S("{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; +} + + +KUrl OpenSearchEngine::searchUrl(const QString &searchTerm) const +{ +    if (m_searchUrlTemplate.isEmpty())  +    { +        return KUrl(); +    } + +    KUrl retVal = KUrl::fromEncoded(parseTemplate(searchTerm, m_searchUrlTemplate).toUtf8()); + +    QList<Parameter>::const_iterator i; +    for ( i = m_searchParameters.constBegin(); i != m_searchParameters.constEnd(); ++i)  +    { +        retVal.addQueryItem(i->first, parseTemplate(searchTerm, i->second)); +    } + +    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; +} + + +KUrl OpenSearchEngine::suggestionsUrl(const QString &searchTerm) const +{ +    if (m_suggestionsUrlTemplate.isEmpty())  +    { +        return KUrl(); +    } + +    KUrl retVal = KUrl::fromEncoded(parseTemplate(searchTerm, m_suggestionsUrlTemplate).toUtf8()); + +    QList<Parameter>::const_iterator i; +    for( i = m_suggestionsParameters.constBegin(); i != m_suggestionsParameters.constEnd(); ++i) +    { +        retVal.addQueryItem(i->first, parseTemplate(searchTerm, i->second)); +    } +    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) +{ +    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); + +    return suggestionsList; +} diff --git a/src/opensearch/opensearchengine.h b/src/opensearch/opensearchengine.h new file mode 100644 index 00000000..f2329624 --- /dev/null +++ b/src/opensearch/opensearchengine.h @@ -0,0 +1,110 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Jakub Wieczorek <faw217@gmail.com> +* Copyright (C) 2009 by Christian Franke <cfchris6@ts2server.com> +* Copyright (C) 2010 by Lionel Chauvin <megabigbug@yahoo.fr> +* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com> +* +* +* 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 <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +#ifndef OPENSEARCHENGINE_H +#define OPENSEARCHENGINE_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// KDE Includes +#include <KUrl> + +// Qt Includes +#include <QtCore/QPair> +#include <QtGui/QImage> + +// Forward Declarations +class QNetworkAccessManager; +class QNetworkReply; +class QScriptEngine; + + +class OpenSearchEngine +{ +public: +    typedef QPair<QString, QString> Parameter; + +    OpenSearchEngine(QObject *parent = 0); +    ~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); +    KUrl searchUrl(const QString &searchTerm) const; + +    bool providesSuggestions() const; + +    QString suggestionsUrlTemplate() const; +    void setSuggestionsUrlTemplate(const QString &suggestionsUrl); +    KUrl 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 diff --git a/src/opensearch/opensearchmanager.cpp b/src/opensearch/opensearchmanager.cpp new file mode 100644 index 00000000..8e024951 --- /dev/null +++ b/src/opensearch/opensearchmanager.cpp @@ -0,0 +1,234 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Fredy Yanardi <fyanardi@gmail.com> +* Copyright (C) 2010 by Lionel Chauvin <megabigbug@yahoo.fr> +* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com> +* +* +* 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 <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +// Self Includes +#include "opensearchmanager.h" +#include "opensearchmanager.moc" + +// Local Includes +#include "opensearchengine.h" +#include "opensearchreader.h" +#include "opensearchwriter.h" + +// KDE Includes +#include <KDebug> +#include <KGlobal> +#include <KStandardDirs> +#include <KUrl> +#include <kio/scheduler.h> + +// Qt Includes +#include <QtCore/QFile> + + +OpenSearchManager::OpenSearchManager(QObject *parent) +    : QObject(parent) +    , m_activeEngine(0) +    , m_currentJob(0) +{ +    m_state = IDLE; +} + + +OpenSearchManager::~OpenSearchManager()  +{ +    qDeleteAll(m_enginesMap.values()); +    m_enginesMap.clear(); +     +    if(m_currentJob) +        m_currentJob->kill(); +} + + +void OpenSearchManager::setSearchProvider(const QString &searchProvider) +{ +    m_activeEngine = 0; + +    if (!m_enginesMap.contains(searchProvider))  +    { +        const QString fileName = KGlobal::dirs()->findResource("data", "rekonq/opensearch/" + searchProvider + ".xml"); +        kDebug() << searchProvider <<  " file name path: " << fileName; +        if (fileName.isEmpty())  +        { +            kDebug() << "OpenSearch file name empty"; +            return; +        } +        QFile file(fileName); + +        if (!file.open(QIODevice::ReadOnly | QIODevice::Text))  +        { +            kDebug() << "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 != 0; +} + + +void OpenSearchManager::addOpenSearchEngine(const KUrl &url, const QString &title) +{ +    Q_UNUSED(title); + +    if (m_currentJob) +    { +        disconnect(m_currentJob); +        m_currentJob->kill(); +	delete m_currentJob; +    } + +    m_jobData.clear(); + +    if (m_state != IDLE)  +    { +        // TODO: cancel job +    } + +    m_state = REQ_DESCRIPTION; +    m_currentJob = KIO::get(url, KIO::NoReload, KIO::HideProgressInfo); +    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)  +        return; + +    if (m_state != IDLE)  +    { +        // TODO: cancel job +    } +    m_state = REQ_SUGGESTION; + +    _typedText = searchText; + +    KUrl url = m_activeEngine->suggestionsUrl(searchText); +    kDebug() << "Requesting for suggestions: " << url.url(); + +    if (m_currentJob) +    { +        disconnect(m_currentJob); +        m_currentJob->kill(); +    } +    m_jobData.clear(); + +    m_currentJob = KIO::get(url, KIO::NoReload, KIO::HideProgressInfo); +    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::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); +        kDebug() << "Received suggestions in "<< _typedText << " from " << m_activeEngine->name() << ": " << suggestionsList; + +        m_currentJob = NULL; +        emit suggestionReceived(_typedText, suggestionsList); +        return; +    } + +    if (m_state == REQ_DESCRIPTION)  +    { +        OpenSearchReader reader; +        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); + +            QString searchUrl = OpenSearchEngine::parseTemplate("\\{@}", engine->searchUrlTemplate()); +            m_currentJob = NULL; +            emit openSearchEngineAdded(engine->name(), searchUrl, fileName); +        } +        else  +        { +            kFatal() << "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; +} diff --git a/src/opensearch/opensearchmanager.h b/src/opensearch/opensearchmanager.h new file mode 100644 index 00000000..224ada08 --- /dev/null +++ b/src/opensearch/opensearchmanager.h @@ -0,0 +1,112 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Fredy Yanardi <fyanardi@gmail.com> +* Copyright (C) 2010 by Lionel Chauvin <megabigbug@yahoo.fr> +* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com> +* +* +* 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 <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +#ifndef OPENSEARCHMANAGER_H +#define OPENSEARCHMANAGER_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// KDE Includes +#include <kio/jobclasses.h> + +// Qt Includes +#include <QtCore/QObject> + +// Forward Declarations +class SuggestionEngine; +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 = 0); + +    virtual ~OpenSearchManager(); + +    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 KUrl &url, const QString &title); + +public slots: +    /** +     * Ask the specific suggestion engine to request for suggestion for the search text +     *  +     * @param searchText the text to be queried to the suggestion service +     */ +    void requestSuggestion(const QString &searchText); + +private slots: +    void dataReceived(KIO::Job *job, const QByteArray &data); +    void jobFinished(KJob *job); + +signals: +    void suggestionReceived(const QString &text, 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; +     +    KIO::TransferJob *m_currentJob; + +    QString _typedText; +}; + +#endif // OPENSEARCHMANAGER_H diff --git a/src/opensearch/opensearchreader.cpp b/src/opensearch/opensearchreader.cpp new file mode 100644 index 00000000..5b7ece2c --- /dev/null +++ b/src/opensearch/opensearchreader.cpp @@ -0,0 +1,174 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Jakub Wieczorek <faw217@gmail.com> +* Copyright (C) 2009 by Fredy Yanardi <fyanardi@gmail.com> +* Copyright (C) 2010 by Lionel Chauvin <megabigbug@yahoo.fr> +* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com> +* +* +* 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 <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +// Self Includes +#include "opensearchreader.h" + +// Local Includes +#include "opensearchengine.h" + +// Qt Includes +#include <QtCore/QIODevice> + + +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() +{ +    OpenSearchEngine *engine = new OpenSearchEngine(); + +    while (!isStartElement() && !atEnd()) { +        readNext(); +    } + +    if (    name() != QL1S("OpenSearchDescription") +         || namespaceUri() != QL1S("http://a9.com/-/spec/opensearch/1.1/") +       )  +    { +        raiseError(QObject::tr("The file is not an OpenSearch 1.1 file.")); +        return engine; +    } + +    while (!(isEndElement() && name() == QL1S("OpenSearchDescription")) && !atEnd())  +    { +        readNext(); + +        if (!isStartElement()) +            continue; + +        // ShortName +        if (name() == QL1S("ShortName"))  +        { +            engine->setName(readElementText()); +            continue; +        } +         +        // Description +        if (name() == QL1S("Description"))  +        { +            engine->setDescription(readElementText()); +            continue; +        } +         +        // Url +        if (name() == QL1S("Url"))  +        { +            QString type = attributes().value(QL1S("type")).toString(); +            QString url = attributes().value(QL1S("template")).toString(); + +            if (url.isEmpty()) +                continue; + +            QList<OpenSearchEngine::Parameter> parameters; + +            readNext(); + +            while (!(isEndElement() && name() == QL1S("Url")))  +            { +                if (!isStartElement() || (name() != QL1S("Param") && name() != QL1S("Parameter"))) { +                    readNext(); +                    continue; +                } + +                QString key = attributes().value(QL1S("name")).toString(); +                QString value = attributes().value(QL1S("value")).toString(); + +                if (!key.isEmpty() && !value.isEmpty())  +                { +                    parameters.append(OpenSearchEngine::Parameter(key, value)); +                } + +                while (!isEndElement())  +                { +                    readNext(); +                } +            } + +            if (type == QL1S("application/x-suggestions+json"))  +            { +                engine->setSuggestionsUrlTemplate(url); +                engine->setSuggestionsParameters(parameters); +            } +            else  +            { +                engine->setSearchUrlTemplate(url); +                engine->setSearchParameters(parameters); +            } +             +            continue; +        } +         +        // Image +        if (name() == QL1S("Image"))  +        { +             engine->setImageUrl(readElementText()); +             continue; +        } + +        // Engine check +        if (    !engine->name().isEmpty() +             && !engine->description().isEmpty() +             && !engine->suggestionsUrlTemplate().isEmpty() +             && !engine->searchUrlTemplate().isEmpty() +             && !engine->imageUrl().isEmpty() +           )  +        { +            break; +        } +    } + +    return engine; +} diff --git a/src/opensearch/opensearchreader.h b/src/opensearch/opensearchreader.h new file mode 100644 index 00000000..4e2444e0 --- /dev/null +++ b/src/opensearch/opensearchreader.h @@ -0,0 +1,55 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Jakub Wieczorek <faw217@gmail.com> +* Copyright (C) 2010 by Lionel Chauvin <megabigbug@yahoo.fr> +* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com> +* +* +* 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 <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +#ifndef OPENSEARCHREADER_H +#define OPENSEARCHREADER_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// Qt Includes +#include <QtCore/QXmlStreamReader> + +// Forward Declarations +class OpenSearchEngine; + + +class OpenSearchReader : public QXmlStreamReader +{ +public: +    OpenSearchReader(); + +    OpenSearchEngine *read(const QByteArray &data); +    OpenSearchEngine *read(QIODevice *device); + +private: +    OpenSearchEngine *read(); +}; + +#endif // OPENSEARCHREADER_H diff --git a/src/opensearch/opensearchwriter.cpp b/src/opensearch/opensearchwriter.cpp new file mode 100644 index 00000000..81ce022c --- /dev/null +++ b/src/opensearch/opensearchwriter.cpp @@ -0,0 +1,134 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Jakub Wieczorek <faw217@gmail.com> +* Copyright (C) 2010 by Lionel Chauvin <megabigbug@yahoo.fr> +* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com> +* +* +* 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 <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +// Self Includes +#include "opensearchwriter.h" + +// Local Includes +#include "opensearchengine.h" + +// KDE Includes +#include <KDebug> + +// Qt Includes +#include <QtCore/QIODevice> + + + +OpenSearchWriter::OpenSearchWriter() +    : QXmlStreamWriter() +{ +    setAutoFormatting(true); +} + + +bool OpenSearchWriter::write(QIODevice *device, OpenSearchEngine *engine) +{ +    if (!engine) +        return false; + +    if (!device->isOpen()) +        device->open(QIODevice::WriteOnly); + +    setDevice(device); +    write(engine); +    return true; +} + + +void OpenSearchWriter::write(OpenSearchEngine *engine) +{ +    writeStartDocument(); +    writeStartElement(QL1S("OpenSearchDescription")); +    writeDefaultNamespace(QL1S("http://a9.com/-/spec/opensearch/1.1/")); + +    if (!engine->name().isEmpty())  +    { +        writeTextElement(QL1S("ShortName"), engine->name()); +    } + +    if (!engine->description().isEmpty())  +    { +        writeTextElement(QL1S("Description"), engine->description()); +    } + +    if (!engine->searchUrlTemplate().isEmpty())  +    { +        writeStartElement(QL1S("Url")); +        writeAttribute(QL1S("method"), QL1S("get")); +        writeAttribute(QL1S("template"), engine->searchUrlTemplate()); + +        if (!engine->searchParameters().empty())  +        { +            writeNamespace(QL1S("http://a9.com/-/spec/opensearch/extensions/parameters/1.0/"), QL1S("p")); + +            QList<OpenSearchEngine::Parameter>::const_iterator end = engine->searchParameters().constEnd(); +            QList<OpenSearchEngine::Parameter>::const_iterator i = engine->searchParameters().constBegin(); +            for (; i != end; ++i)  +            { +                writeStartElement(QL1S("p:Parameter")); +                writeAttribute(QL1S("name"), i->first); +                writeAttribute(QL1S("value"), i->second); +                writeEndElement(); +            } +        } + +        writeEndElement(); +    } + +    if (!engine->suggestionsUrlTemplate().isEmpty())  +    { +        writeStartElement(QL1S("Url")); +        writeAttribute(QL1S("method"), QL1S("get")); +        writeAttribute(QL1S("type"), QL1S("application/x-suggestions+json")); +        writeAttribute(QL1S("template"), engine->suggestionsUrlTemplate()); + +        if (!engine->suggestionsParameters().empty())  +        { +            writeNamespace(QL1S("http://a9.com/-/spec/opensearch/extensions/parameters/1.0/"), QL1S("p")); + +            QList<OpenSearchEngine::Parameter>::const_iterator end = engine->suggestionsParameters().constEnd(); +            QList<OpenSearchEngine::Parameter>::const_iterator i = engine->suggestionsParameters().constBegin(); +            for (; i != end; ++i)  +            { +                writeStartElement(QL1S("p:Parameter")); +                writeAttribute(QL1S("name"), i->first); +                writeAttribute(QL1S("value"), i->second); +                writeEndElement(); +            } +        } + +        writeEndElement(); +    } + +    if (!engine->imageUrl().isEmpty()) +        writeTextElement(QL1S("Image"), engine->imageUrl()); + +    writeEndElement(); +    writeEndDocument(); +} diff --git a/src/opensearch/opensearchwriter.h b/src/opensearch/opensearchwriter.h new file mode 100644 index 00000000..6a2e0d11 --- /dev/null +++ b/src/opensearch/opensearchwriter.h @@ -0,0 +1,56 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Jakub Wieczorek <faw217@gmail.com> +* Copyright (C) 2010 by Lionel Chauvin <megabigbug@yahoo.fr> +* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com> +* +* +* 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 <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +#ifndef OPENSEARCHWRITER_H +#define OPENSEARCHWRITER_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// Qt Includes +#include <QtCore/QXmlStreamWriter> + +// Forward Declarations +class QIODevice; +class OpenSearchEngine; + + +class OpenSearchWriter : public QXmlStreamWriter +{ +public: +    OpenSearchWriter(); + +    bool write(QIODevice *device, OpenSearchEngine *engine); + +private: +    void write(OpenSearchEngine *engine); +}; + +#endif + diff --git a/src/opensearch/searchengine.cpp b/src/opensearch/searchengine.cpp new file mode 100644 index 00000000..89e62dee --- /dev/null +++ b/src/opensearch/searchengine.cpp @@ -0,0 +1,157 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr> +* +* +* 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 <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +//local includes +#include "searchengine.h" +#include "application.h" +#include "iconmanager.h" + +// Auto Includes +#include "rekonq.h" + +//KDE includes +#include <KConfigGroup> +#include <KServiceTypeTrader> + + +bool SearchEngine::m_loaded = false; +QString SearchEngine::m_delimiter = ""; +KService::List SearchEngine::m_favorites; +KService::Ptr SearchEngine::m_defaultEngine; + + +void SearchEngine::reload() +{ +    KConfig config("kuriikwsfilterrc"); //Shared with konqueror +    KConfigGroup cg = config.group("General"); + +    //load delimiter +    m_delimiter = cg.readEntry("KeywordDelimiter", ":"); + +    //load favorite engines +    QStringList favoriteEngines; +    favoriteEngines = cg.readEntry("FavoriteSearchEngines", favoriteEngines); +    KService::List favorites; +    KService::Ptr service; +    foreach(const QString &engine, favoriteEngines) +    { +        service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(engine)); +        if (service) +        { +            QUrl url = service->property("Query").toUrl(); +            kDebug() << "ENGINE URL: " << url; +            Application::iconManager()->downloadIconFromUrl(url); +             +            favorites << service; +        } +    } +    m_favorites = favorites; + +    //load default engine +    QString d = cg.readEntry("DefaultSearchEngine");   +    m_defaultEngine = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(d)); +    if (!m_defaultEngine) +    { +        d = QL1S("google"); +        m_defaultEngine = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(d)); +    } +     +    m_loaded = true; +} + + +QString SearchEngine::delimiter() +{ +    if (!m_loaded) +        reload(); + +    return m_delimiter; +} + + +KService::List SearchEngine::favorites() +{ +    if (!m_loaded) +        reload(); + +    return m_favorites; +} + + +KService::Ptr SearchEngine::defaultEngine() +{ +    if (!m_loaded) +        reload(); + +    return m_defaultEngine; +} + + +KService::Ptr SearchEngine::fromString(const QString &text) +{ +    KService::List providers = KServiceTypeTrader::self()->query("SearchProvider"); +    int i = 0; +    bool found = false; +    KService::Ptr service; +    while (!found && i < providers.size()) +    { +        QStringList list = providers.at(i)->property("Keys").toStringList(); +        foreach(const QString &key, list) +        { +            const QString searchPrefix = key + delimiter(); +            if (text.startsWith(searchPrefix)) +            { +                service = providers.at(i); +                found = true; +            } +        } +        i++; +    } + +    return service; +} + + +QString SearchEngine::extractQuery(const QString &text) +{ +    QString query = text; +    KService::Ptr engine = SearchEngine::fromString(text); +    if (engine) +    { +        query = query.remove(0, text.indexOf(SearchEngine::delimiter()) + 1); +    } + +    return query; +} + + +QString SearchEngine::buildQuery(KService::Ptr engine, const QString &text) +{ +    QString query = engine->property("Query").toString(); +    query = query.replace("\\{@}", KUrl::toPercentEncoding(text)); +    return query; +} diff --git a/src/opensearch/searchengine.h b/src/opensearch/searchengine.h new file mode 100644 index 00000000..d813666b --- /dev/null +++ b/src/opensearch/searchengine.h @@ -0,0 +1,59 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr> +* +* +* 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 <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + +#ifndef SEARCHENGINE_H +#define SEARCHENGINE_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// KDE Includes +#include <KService> + +//Qt Includes +#include <QString> + + +class SearchEngine +{ +public: +    static void reload(); +    static QString delimiter(); +    static KService::Ptr defaultEngine(); +    static KService::List favorites(); +    static KService::Ptr fromString(const QString &text); +    static QString buildQuery(KService::Ptr engine, const QString &text); +    static QString extractQuery(const QString &text); +     +private: +    static bool m_loaded; +    static QString m_delimiter; +    static KService::List m_favorites; +    static KService::Ptr m_defaultEngine; +}; + +#endif | 
