1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
/*
SPDX-FileCopyrightText: 2022-2026 Laurent Montel <montel@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
based on digikam onlinetranslator code
*/
#include "deeplengineplugin.h"
using namespace Qt::Literals::StringLiterals;
#include "deeplengineutil.h"
#include "deepltranslator_debug.h"
#include <KConfigGroup>
#include <KLocalizedString>
#include <KSharedConfig>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QUrlQuery>
#include <TextTranslator/TranslatorEngineAccessManager>
#include <qt6keychain/keychain.h>
DeeplEnginePlugin::DeeplEnginePlugin(QObject *parent)
: TextTranslator::TranslatorEnginePlugin(parent)
{
loadSettings();
}
DeeplEnginePlugin::~DeeplEnginePlugin() = default;
void DeeplEnginePlugin::translate()
{
if (verifyFromAndToLanguage()) {
return;
}
if (mApiKey.isEmpty()) {
Q_EMIT translateFailed(i18n("Server needs Api Key."));
return;
}
translateText();
}
void DeeplEnginePlugin::translateText()
{
clear();
QUrl url(mServerUrl);
QUrlQuery query;
query.addQueryItem(u"text"_s, inputText());
query.addQueryItem(u"source_lang"_s, languageCode(from()));
query.addQueryItem(u"target_lang"_s, languageCode(to()));
url.setQuery(query);
QNetworkRequest request(url);
request.setRawHeader(QByteArrayLiteral("Authorization"), "DeepL-Auth-Key " + mApiKey.toLocal8Bit());
request.setHeader(QNetworkRequest::ContentTypeHeader, u"application/x-www-form-urlencoded"_s);
QNetworkReply *reply = TextTranslator::TranslatorEngineAccessManager::self()->networkManager()->post(request, QByteArray());
connect(reply, &QNetworkReply::errorOccurred, this, [this, reply](QNetworkReply::NetworkError error) {
slotError(error);
reply->deleteLater();
});
connect(reply, &QNetworkReply::finished, this, [this, reply]() {
reply->deleteLater();
parseTranslation(reply);
});
}
void DeeplEnginePlugin::parseTranslation(QNetworkReply *reply)
{
if (reply->error() != QNetworkReply::NoError) {
Q_EMIT translateFailed(reply->errorString());
reply->deleteLater();
return;
}
const QJsonDocument jsonResponse = QJsonDocument::fromJson(reply->readAll());
if (hasDebug()) {
setJsonDebug(QString::fromUtf8(jsonResponse.toJson(QJsonDocument::Indented)));
}
const QJsonObject responseObject = jsonResponse.object();
// QJsonObject({"translations":[{"detected_source_language":"EN","text":"Bonjour le monde"}]})
qCDebug(TRANSLATOR_DEEPL_LOG) << " responseObject " << responseObject;
const QJsonArray arrayTranslation = responseObject.value(u"translations"_s).toArray();
qCDebug(TRANSLATOR_DEEPL_LOG) << " arrayTranslation " << arrayTranslation;
const QJsonObject obj = arrayTranslation.at(0).toObject();
setResult(obj.value(u"text"_s).toString());
reply->deleteLater();
qCDebug(TRANSLATOR_DEEPL_LOG) << " result " << result();
Q_EMIT translateDone();
}
void DeeplEnginePlugin::loadSettings()
{
KConfigGroup myGroup(KSharedConfig::openConfig(), DeeplEngineUtil::groupName());
mUseFreeLicense = myGroup.readEntry(DeeplEngineUtil::freeLicenseKey(), false);
mServerUrl = mUseFreeLicense ? u"https://api-free.deepl.com/v2/translate"_s : u"https://api.deepl.com/v2/translate"_s;
auto readJob = new QKeychain::ReadPasswordJob(DeeplEngineUtil::translatorGroupName(), this);
connect(readJob, &QKeychain::Job::finished, this, &DeeplEnginePlugin::slotApiKeyRead);
readJob->setKey(DeeplEngineUtil::apiGroupName());
readJob->start();
}
void DeeplEnginePlugin::slotApiKeyRead(QKeychain::Job *baseJob)
{
auto job = qobject_cast<QKeychain::ReadPasswordJob *>(baseJob);
Q_ASSERT(job);
if (!job->error()) {
mApiKey = job->textData();
} else {
qCWarning(TRANSLATOR_DEEPL_LOG) << "We have an error during reading password " << job->errorString();
}
}
void DeeplEnginePlugin::slotConfigureChanged()
{
loadSettings();
}
QString DeeplEnginePlugin::languageCode(const QString &langStr)
{
if (langStr == "auto"_L1) {
return u"auto-detect"_s;
} else if (langStr == "zh-CN"_L1) {
return u"zh"_s;
}
return langStr;
}
#include "moc_deeplengineplugin.cpp"
|