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 }