-/*
- * Copyright (C) 2007 Thomas Georgiou <TAGeorgiou@gmail.com> and Jeff Cooper <weirdsox11@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License version 2 as
- * published by the Free Software Foundation
- *
- * 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 Library General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
+/* This file is part of the KDE project
+ Copyright (C) 2022 Ivailo Monev <xakepa10@gmail.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2, as published by the Free Software Foundation.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
#include "dictengine.h"
-#include <iostream>
#include <KDebug>
#include <KLocale>
-
-#include <Plasma/DataContainer>
+#include <KIO/NetAccess>
+#include <QJsonDocument>
DictEngine::DictEngine(QObject* parent, const QVariantList& args)
: Plasma::DataEngine(parent, args)
- , m_tcpSocket(0)
{
- Q_UNUSED(args)
- m_serverName = "dict.org"; //In case we need to switch it later
- m_dictName = "wn"; //Default, good dictionary
}
DictEngine::~DictEngine()
{
}
-void DictEngine::setDict(const QString &dict)
-{
- m_dictName = dict;
-}
-
-void DictEngine::setServer(const QString &server)
+bool DictEngine::sourceRequestEvent(const QString &query)
{
- m_serverName = server;
-}
+ // qDebug() << Q_FUNC_INFO << query;
-static QString wnToHtml(const QString &word, QByteArray &text)
-{
- Q_UNUSED(word)
- QList<QByteArray> splitText = text.split('\n');
- QString def;
- def += "<dl>\n";
- QRegExp linkRx("\\{(.*)\\}");
- linkRx.setMinimal(true);
-
- bool isFirst=true;
- while (!splitText.empty()) {
- //150 n definitions retrieved - definitions follow
- //151 word database name - text follows
- //250 ok (optional timing information here)
- //552 No match
- QString currentLine = splitText.takeFirst();
- if (currentLine.startsWith(QLatin1String("151"))) {
- isFirst = true;
- continue;
- }
-
- if (currentLine.startsWith('.')) {
- def += "</dd>";
- continue;
- }
-
- if (!(currentLine.startsWith(QLatin1String("150"))
- || currentLine.startsWith(QLatin1String("151"))
- || currentLine.startsWith(QLatin1String("250"))
- || currentLine.startsWith(QLatin1String("552")))) {
- currentLine.replace(linkRx,"<a href=\"\\1\">\\1</a>");
-
- if (isFirst) {
- def += "<dt><b>" + currentLine + "</b></dt>\n<dd>";
- isFirst = false;
- continue;
- } else {
- if (currentLine.contains(QRegExp("([1-9]{1,2}:)"))) {
- def += "\n<br>\n";
- }
- currentLine.replace(QRegExp("^([\\s\\S]*[1-9]{1,2}:)"), "<b>\\1</b>");
- def += currentLine;
- continue;
- }
- }
+ setData(query, QString("text"), QString());
+ setData(QString("list-dictionaries"), QString("dictionaries"), QString());
+ const QStringList splitquery = query.split(QLatin1Char(':'));
+ QString queryword = query;
+ if (splitquery.size() == 2) {
+ queryword = splitquery.at(1);
}
- def += "</dl>";
- return def;
-}
-
-void DictEngine::getDefinition()
-{
- m_tcpSocket->readAll();
- QByteArray ret;
-
- m_tcpSocket->write(QByteArray("DEFINE "));
- m_tcpSocket->write(m_dictName.toAscii());
- m_tcpSocket->write(QByteArray(" \""));
- m_tcpSocket->write(m_currentWord.toUtf8());
- m_tcpSocket->write(QByteArray("\"\n"));
- m_tcpSocket->flush();
-
- while (!ret.contains("250") && !ret.contains("552") && !ret.contains("550")) {
- m_tcpSocket->waitForReadyRead();
- ret += m_tcpSocket->readAll();
+ if (queryword.isEmpty()) {
+ return false;
+ } else if (queryword.contains(' ')) {
+ setError(query, QLatin1String("Only words can be queried"));
+ return true;
}
- connect(m_tcpSocket, SIGNAL(disconnected()), this, SLOT(socketClosed()));
- m_tcpSocket->disconnectFromHost();
- // setData(m_currentWord, m_dictName, ret);
- // qWarning()<<ret;
- setData(m_currentWord, "text", wnToHtml(m_currentWord,ret));
-}
-
-void DictEngine::getDicts()
-{
- QMap<QString, QString> theHash;
- m_tcpSocket->readAll();
- QByteArray ret;
-
- m_tcpSocket->write(QByteArray("SHOW DB\n"));;
- m_tcpSocket->flush();
-
- m_tcpSocket->waitForReadyRead();
- while (!ret.contains("250")) {
- m_tcpSocket->waitForReadyRead();
- ret += m_tcpSocket->readAll();
+ m_data.clear();
+ const KUrl queryurl = QString::fromLatin1("https://api.dictionaryapi.dev/api/v2/entries/en/") + queryword;
+ KIO::TransferJob *kiojob = KIO::get(queryurl, KIO::Reload, KIO::HideProgressInfo);
+ connect(kiojob, SIGNAL(data(KIO::Job*,QByteArray)), this, SLOT(slotKIOData(KIO::Job*,QByteArray)));
+ const bool kioresult = KIO::NetAccess::synchronousRun(kiojob, nullptr);
+ if (!kioresult) {
+ kWarning() << "KIO job failed";
+ setError(query, QLatin1String("Cannot get meaning"));
+ return true;
}
- QList<QByteArray> retLines = ret.split('\n');
- QString tmp1, tmp2;
-
- while (!retLines.empty()) {
- QString curr(retLines.takeFirst());
-
- if (curr.startsWith(QLatin1String("554"))) {
- //TODO: What happens if no DB available?
- //TODO: Eventually there will be functionality to change the server...
- break;
- }
-
- // ignore status code and empty lines
- if (curr.startsWith(QLatin1String("250")) || curr.startsWith(QLatin1String("110"))
- || curr.isEmpty()) {
- continue;
- }
-
- if (!curr.startsWith('-') && !curr.startsWith('.')) {
- curr = curr.trimmed();
- tmp1 = curr.section(' ', 0, 0);
- tmp2 = curr.section(' ', 1);
- // theHash.insert(tmp1, tmp2);
- //kDebug() << tmp1 + " " + tmp2;
- setData("list-dictionaries", tmp1, tmp2);
- }
+ const QJsonDocument jsondocument = QJsonDocument::fromJson(m_data);
+ if (jsondocument.isNull()) {
+ kWarning() << jsondocument.errorString();
+ setError(query, QLatin1String("Cannot parse JSON"));
+ return true;
}
- m_tcpSocket->disconnectFromHost();
-// setData("list-dictionaries", "dictionaries", QByteArray(theHash);
+ const QVariantList rootlist = jsondocument.toVariant().toList();
+ if (rootlist.isEmpty()) {
+ setError(query, QLatin1String("Unexpected JSON data"));
+ return true;
+ }
+ const QVariantList meaningslist = rootlist.first().toMap().value("meanings").toList();
+ if (meaningslist.isEmpty()) {
+ setError(query, QLatin1String("Unexpected meanings data"));
+ return true;
+ }
+ // qDebug() << Q_FUNC_INFO << "meanings" << meaningslist;
+ const QVariantList definitionslist = meaningslist.first().toMap().value("definitions").toList();
+ if (definitionslist.isEmpty()) {
+ setError(query, QLatin1String("Unexpected definitions data"));
+ return true;
+ }
+ // qDebug() << Q_FUNC_INFO << "definitions" << definitionslist;
+ QString meaning = "<p>\n<dl><b>Definition:</b> ";
+ meaning.append(definitionslist.first().toMap().value("definition").toString());
+ meaning.append("\n</dl>");
+ meaning.append("<dl>\n<b>Example:</b> ");
+ meaning.append(definitionslist.first().toMap().value("example").toString());
+ meaning.append("\n</dl>\n</p>\n");
+ // qDebug() << Q_FUNC_INFO << "meaning" << meaning;
+
+ setData(query, QString("text"), meaning);
+ setData(QString("list-dictionaries"), QString("dictionaries"), QString("en"));
+ return true;
}
-
-
-void DictEngine::socketClosed()
+void DictEngine::slotKIOData(KIO::Job *kiojob, const QByteArray &kiodata)
{
- m_tcpSocket->deleteLater();
- m_tcpSocket = 0;
+ Q_UNUSED(kiojob);
+ m_data.append(kiodata);
}
-bool DictEngine::sourceRequestEvent(const QString &query)
+void DictEngine::setError(const QString &query, const QString &message)
{
- // FIXME: this is COMPLETELY broken .. it can only look up one query at a time!
- // a DataContainer subclass that does the look up should probably be made
- if (m_currentQuery == query) {
- return false;
- }
-
- if (m_tcpSocket) {
- m_tcpSocket->abort(); //stop if lookup is in progress and new query is requested
- m_tcpSocket->deleteLater();
- m_tcpSocket = 0;
- }
-
- QStringList queryParts = query.split(':', QString::SkipEmptyParts);
- if (queryParts.isEmpty()) {
- return false;
- }
-
- m_currentWord = queryParts.last();
- m_currentQuery = query;
-
- //asked for a dictionary?
- if (queryParts.count() > 1) {
- setDict(queryParts[queryParts.count()-2]);
- //default to wordnet
- } else {
- setDict("wn");
- }
-
- //asked for a server?
- if (queryParts.count() > 2) {
- setServer(queryParts[queryParts.count()-3]);
- //default to wordnet
- } else {
- setServer("dict.org");
- }
-
- if (m_currentWord.simplified().isEmpty()) {
- setData(m_currentWord, m_dictName, QString());
- } else {
- setData(m_currentWord, m_dictName, QString());
- m_tcpSocket = new QSslSocket(this);
- m_tcpSocket->abort();
- connect(m_tcpSocket, SIGNAL(disconnected()), this, SLOT(socketClosed()));
-
- if (m_currentWord == "list-dictionaries") {
- connect(m_tcpSocket, SIGNAL(readyRead()), this, SLOT(getDicts()));
- } else {
- connect(m_tcpSocket, SIGNAL(readyRead()), this, SLOT(getDefinition()));
- }
-
- m_tcpSocket->connectToHost(m_serverName, 2628);
- }
-
- return true;
+ setData(query, QString("text"), QString::fromLatin1("<p>\n<dl><b>%1</b>\n</dl>").arg(message));
+ setData(QString("list-dictionaries"), QString("dictionaries"), QString("en"));
}
#include "moc_dictengine.cpp"
-/*
- * Copyright (C) 2007 Thomas Georgiou <TAGeorgiou@gmail.com> and Jeff Cooper <weirdsox11@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License version 2 as
- * published by the Free Software Foundation
- *
- * 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 Library General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
+/* This file is part of the KDE project
+ Copyright (C) 2022 Ivailo Monev <xakepa10@gmail.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2, as published by the Free Software Foundation.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
#ifndef DICTENGINE_H
#define DICTENGINE_H
+
#include <Plasma/DataEngine>
-#include <QMap>
-#include <QSslSocket>
+#include <KIO/Job>
/**
* This class evaluates the basic expressions given in the interface.
protected:
bool sourceRequestEvent(const QString &word);
- private slots:
- void getDefinition();
- void socketClosed();
- void getDicts();
+ private Q_SLOTS:
+ void slotKIOData(KIO::Job *kiojob, const QByteArray &kiodata);
private:
- void setDict(const QString &dict);
- void setServer(const QString &server);
-
- QHash<QString, QString> m_dictNameToDictCode;
- QSslSocket *m_tcpSocket;
- QString m_currentWord;
- QString m_currentQuery;
- QString m_dictName;
- QString m_serverName;
+ void setError(const QString &query, const QString &message);
+ QByteArray m_data;
};
K_EXPORT_PLASMA_DATAENGINE(dict, DictEngine)