File indexing completed on 2024-11-24 04:16:56

0001 /*
0002   SPDX-FileCopyrightText: 2022-2024 Laurent Montel <montel@kde.org>
0003 
0004   SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "googleengineplugin.h"
0008 #include "googletranslator_debug.h"
0009 #include <KLocalizedString>
0010 #include <QJsonDocument>
0011 #include <QJsonParseError>
0012 #include <QNetworkAccessManager>
0013 #include <QNetworkReply>
0014 #include <QNetworkRequest>
0015 #include <QUrlQuery>
0016 #include <TextTranslator/TranslatorEngineAccessManager>
0017 
0018 GoogleEnginePlugin::GoogleEnginePlugin(QObject *parent)
0019     : TextTranslator::TranslatorEnginePlugin(parent)
0020 {
0021     connect(TextTranslator::TranslatorEngineAccessManager::self()->networkManager(),
0022             &QNetworkAccessManager::finished,
0023             this,
0024             &GoogleEnginePlugin::slotTranslateFinished);
0025 }
0026 
0027 GoogleEnginePlugin::~GoogleEnginePlugin() = default;
0028 
0029 void GoogleEnginePlugin::translate()
0030 {
0031     if (verifyFromAndToLanguage()) {
0032         return;
0033     }
0034 
0035     clear();
0036 
0037     QUrlQuery urlQuery;
0038     urlQuery.addQueryItem(QStringLiteral("client"), QStringLiteral("gtx"));
0039     urlQuery.addQueryItem(QStringLiteral("sl"), languageCode(from()));
0040     urlQuery.addQueryItem(QStringLiteral("tl"), languageCode(to()));
0041     urlQuery.addQueryItem(QStringLiteral("dt"), QStringLiteral("t"));
0042     urlQuery.addQueryItem(QStringLiteral("q"), inputText());
0043 
0044     QUrl url;
0045     url.setQuery(urlQuery);
0046     url.setScheme(QStringLiteral("https"));
0047     url.setHost(QStringLiteral("translate.googleapis.com"));
0048     url.setPath(QStringLiteral("/translate_a/single"));
0049     const QNetworkRequest request(url);
0050 
0051     QNetworkReply *reply = TextTranslator::TranslatorEngineAccessManager::self()->networkManager()->get(request);
0052     connect(reply, &QNetworkReply::errorOccurred, this, [this, reply](QNetworkReply::NetworkError error) {
0053         slotError(error);
0054         reply->deleteLater();
0055     });
0056 }
0057 
0058 QString GoogleEnginePlugin::languageCode(const QString &langStr)
0059 {
0060     if (langStr == QLatin1String("iw")) {
0061         return QStringLiteral("iw");
0062     }
0063     return langStr;
0064 }
0065 
0066 void GoogleEnginePlugin::slotTranslateFinished(QNetworkReply *reply)
0067 {
0068     clear();
0069     mJsonData = QString::fromUtf8(reply->readAll());
0070     reply->deleteLater();
0071     //  jsonData contains arrays like this: ["foo",,"bar"]
0072     //  but this is not valid JSON for QJSON, it expects empty strings: ["foo","","bar"]
0073     mJsonData.replace(QRegularExpression(QStringLiteral(",{3,3}")), QStringLiteral(",\"\",\"\","));
0074     mJsonData.replace(QRegularExpression(QStringLiteral(",{2,2}")), QStringLiteral(",\"\","));
0075     qCDebug(TRANSLATOR_GOOGLE_LOG) << mJsonData;
0076 
0077     QJsonParseError parsingError;
0078     const QJsonDocument jsonDoc = QJsonDocument::fromJson(mJsonData.toUtf8(), &parsingError);
0079     if (parsingError.error != QJsonParseError::NoError || jsonDoc.isNull()) {
0080         Q_EMIT translateFailed(i18n("Invalid answer."));
0081         return;
0082     }
0083     const QVariantList json = jsonDoc.toVariant().toList();
0084     if (hasDebug()) {
0085         setJsonDebug(QString::fromUtf8(jsonDoc.toJson(QJsonDocument::Indented)));
0086     }
0087     for (const QVariant &level0 : json) {
0088         const QVariantList listLevel0 = level0.toList();
0089         if (listLevel0.isEmpty()) {
0090             continue;
0091         }
0092         for (const QVariant &level1 : listLevel0) {
0093             if (level1.toList().size() <= 2) {
0094                 continue;
0095             }
0096             appendResult(level1.toList().at(0).toString());
0097         }
0098     }
0099     Q_EMIT translateDone();
0100 }