KTextAddons

googleengineplugin.cpp
1/*
2 SPDX-FileCopyrightText: 2022-2024 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "googleengineplugin.h"
8using namespace Qt::Literals::StringLiterals;
9
10#include "googletranslator_debug.h"
11#include <KLocalizedString>
12#include <QJsonDocument>
13#include <QJsonParseError>
14#include <QNetworkAccessManager>
15#include <QNetworkReply>
16#include <QNetworkRequest>
17#include <QUrlQuery>
18#include <TextTranslator/TranslatorEngineAccessManager>
19
20GoogleEnginePlugin::GoogleEnginePlugin(QObject *parent)
21 : TextTranslator::TranslatorEnginePlugin(parent)
22{
23 connect(TextTranslator::TranslatorEngineAccessManager::self()->networkManager(),
25 this,
26 &GoogleEnginePlugin::slotTranslateFinished);
27}
28
29GoogleEnginePlugin::~GoogleEnginePlugin() = default;
30
31void GoogleEnginePlugin::translate()
32{
33 if (verifyFromAndToLanguage()) {
34 return;
35 }
36
37 clear();
38
39 QUrlQuery urlQuery;
40 urlQuery.addQueryItem(QStringLiteral("client"), QStringLiteral("gtx"));
41 urlQuery.addQueryItem(QStringLiteral("sl"), languageCode(from()));
42 urlQuery.addQueryItem(QStringLiteral("tl"), languageCode(to()));
43 urlQuery.addQueryItem(QStringLiteral("dt"), QStringLiteral("t"));
44 urlQuery.addQueryItem(QStringLiteral("q"), inputText());
45
46 QUrl url;
47 url.setQuery(urlQuery);
48 url.setScheme(QStringLiteral("https"));
49 url.setHost(QStringLiteral("translate.googleapis.com"));
50 url.setPath(QStringLiteral("/translate_a/single"));
51 const QNetworkRequest request(url);
52
53 QNetworkReply *reply = TextTranslator::TranslatorEngineAccessManager::self()->networkManager()->get(request);
54 connect(reply, &QNetworkReply::errorOccurred, this, [this, reply](QNetworkReply::NetworkError error) {
55 slotError(error);
56 reply->deleteLater();
57 });
58}
59
60QString GoogleEnginePlugin::languageCode(const QString &langStr)
61{
62 if (langStr == "iw"_L1) {
63 return QStringLiteral("iw");
64 }
65 return langStr;
66}
67
68void GoogleEnginePlugin::slotTranslateFinished(QNetworkReply *reply)
69{
70 clear();
71 mJsonData = QString::fromUtf8(reply->readAll());
72 reply->deleteLater();
73 // jsonData contains arrays like this: ["foo",,"bar"]
74 // but this is not valid JSON for QJSON, it expects empty strings: ["foo","","bar"]
75 mJsonData.replace(QRegularExpression(QStringLiteral(",{3,3}")), QStringLiteral(",\"\",\"\","));
76 mJsonData.replace(QRegularExpression(QStringLiteral(",{2,2}")), QStringLiteral(",\"\","));
77 qCDebug(TRANSLATOR_GOOGLE_LOG) << mJsonData;
78
79 QJsonParseError parsingError;
80 const QJsonDocument jsonDoc = QJsonDocument::fromJson(mJsonData.toUtf8(), &parsingError);
81 if (parsingError.error != QJsonParseError::NoError || jsonDoc.isNull()) {
82 Q_EMIT translateFailed(i18n("Invalid answer."));
83 return;
84 }
85 const QVariantList json = jsonDoc.toVariant().toList();
86 if (hasDebug()) {
87 setJsonDebug(QString::fromUtf8(jsonDoc.toJson(QJsonDocument::Indented)));
88 }
89 for (const QVariant &level0 : json) {
90 const QVariantList listLevel0 = level0.toList();
91 if (listLevel0.isEmpty()) {
92 continue;
93 }
94 for (const QVariant &level1 : listLevel0) {
95 if (level1.toList().size() <= 2) {
96 continue;
97 }
98 appendResult(level1.toList().at(0).toString());
99 }
100 }
101 Q_EMIT translateDone();
102}
QString i18n(const char *text, const TYPE &arg...)
QByteArray readAll()
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
bool isNull() const const
QByteArray toJson(JsonFormat format) const const
QVariant toVariant() const const
void finished(QNetworkReply *reply)
QNetworkReply * get(const QNetworkRequest &request)
void errorOccurred(QNetworkReply::NetworkError code)
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void deleteLater()
QString fromUtf8(QByteArrayView str)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
QByteArray toUtf8() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void setHost(const QString &host, ParsingMode mode)
void setPath(const QString &path, ParsingMode mode)
void setQuery(const QString &query, ParsingMode mode)
void setScheme(const QString &scheme)
void addQueryItem(const QString &key, const QString &value)
QList< QVariant > toList() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 4 2024 16:29:59 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.