diff options
Diffstat (limited to 'src/opensearch')
| -rw-r--r-- | src/opensearch/opensearchengine.cpp | 6 | ||||
| -rw-r--r-- | src/opensearch/opensearchmanager.cpp | 166 | ||||
| -rw-r--r-- | src/opensearch/opensearchmanager.h | 20 | ||||
| -rw-r--r-- | src/opensearch/suggestionparser.cpp | 25 | 
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;  } | 
