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 based on digikam onlinetranslator code 0007 0008 */ 0009 0010 #include "libretranslateengineplugin.h" 0011 #include "libretranslateengineutil.h" 0012 #include "libretranslatetranslator_debug.h" 0013 0014 #include <KConfigGroup> 0015 #include <KLocalizedString> 0016 #include <KSharedConfig> 0017 #include <QJsonDocument> 0018 #include <QJsonObject> 0019 #include <TextTranslator/TranslatorEngineAccessManager> 0020 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0021 #include <qt5keychain/keychain.h> 0022 #else 0023 #include <qt6keychain/keychain.h> 0024 #endif 0025 0026 LibreTranslateEnginePlugin::LibreTranslateEnginePlugin(QObject *parent) 0027 : TextTranslator::TranslatorEnginePlugin(parent) 0028 { 0029 loadSettings(); 0030 } 0031 0032 LibreTranslateEnginePlugin::~LibreTranslateEnginePlugin() = default; 0033 0034 void LibreTranslateEnginePlugin::translate() 0035 { 0036 if (verifyFromAndToLanguage()) { 0037 return; 0038 } 0039 if (mServerUrl.isEmpty()) { 0040 Q_EMIT translateFailed(i18n("Server url is not defined.")); 0041 return; 0042 } 0043 if (mRequiredApiKey && mApiKey.isEmpty()) { 0044 Q_EMIT translateFailed(i18n("Server needs Api Key.")); 0045 return; 0046 } 0047 translateText(); 0048 } 0049 0050 void LibreTranslateEnginePlugin::slotConfigureChanged() 0051 { 0052 loadSettings(); 0053 } 0054 0055 void LibreTranslateEnginePlugin::translateText() 0056 { 0057 clear(); 0058 0059 QByteArray postData = "&q=" + QUrl::toPercentEncoding(inputText()) + "&source=" + from().toUtf8() + "&target=" + to().toUtf8(); 0060 if (!mApiKey.isEmpty()) { 0061 postData += "&api_key=" + mApiKey.toUtf8(); 0062 } 0063 const auto url = QUrl(QStringLiteral("%1/translate").arg(mServerUrl)); 0064 QNetworkRequest request; 0065 request.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/x-www-form-urlencoded")); 0066 request.setUrl(url); 0067 0068 qCDebug(TRANSLATOR_LIBRETRANSLATE_LOG) << " url " << url; 0069 0070 QNetworkReply *reply = TextTranslator::TranslatorEngineAccessManager::self()->networkManager()->post(request, postData); 0071 connect(reply, &QNetworkReply::errorOccurred, this, [this, reply](QNetworkReply::NetworkError error) { 0072 slotError(error); 0073 reply->deleteLater(); 0074 }); 0075 connect(reply, &QNetworkReply::finished, this, [this, reply]() { 0076 reply->deleteLater(); 0077 parseTranslation(reply); 0078 }); 0079 } 0080 0081 void LibreTranslateEnginePlugin::parseTranslation(QNetworkReply *reply) 0082 { 0083 if (reply->error() != QNetworkReply::NoError) { 0084 Q_EMIT translateFailed(reply->errorString()); 0085 reply->deleteLater(); 0086 return; 0087 } 0088 const QJsonDocument jsonResponse = QJsonDocument::fromJson(reply->readAll()); 0089 if (hasDebug()) { 0090 setJsonDebug(QString::fromUtf8(jsonResponse.toJson(QJsonDocument::Indented))); 0091 } 0092 0093 const QJsonObject responseObject = jsonResponse.object(); 0094 setResult(responseObject.value(QStringLiteral("translatedText")).toString()); 0095 reply->deleteLater(); 0096 qCDebug(TRANSLATOR_LIBRETRANSLATE_LOG) << " result " << result(); 0097 Q_EMIT translateDone(); 0098 } 0099 0100 void LibreTranslateEnginePlugin::loadSettings() 0101 { 0102 KConfigGroup myGroup(KSharedConfig::openConfig(), LibreTranslateEngineUtil::groupName()); 0103 mServerUrl = myGroup.readEntry(LibreTranslateEngineUtil::serverUrlKey(), LibreTranslateEngineUtil::defaultServerUrl()); 0104 // Fallback 0105 if (mServerUrl.isEmpty()) { 0106 mServerUrl = LibreTranslateEngineUtil::defaultServerUrl(); 0107 } 0108 mServerUrl = LibreTranslateEngineUtil::adaptUrl(mServerUrl); 0109 mRequiredApiKey = myGroup.readEntry(LibreTranslateEngineUtil::serverRequiredApiKey(), false); 0110 0111 auto readJob = new QKeychain::ReadPasswordJob(LibreTranslateEngineUtil::translatorGroupName(), this); 0112 connect(readJob, &QKeychain::Job::finished, this, &LibreTranslateEnginePlugin::slotApiKeyRead); 0113 readJob->setKey(LibreTranslateEngineUtil::apiGroupName()); 0114 readJob->start(); 0115 } 0116 0117 void LibreTranslateEnginePlugin::slotApiKeyRead(QKeychain::Job *baseJob) 0118 { 0119 auto job = qobject_cast<QKeychain::ReadPasswordJob *>(baseJob); 0120 Q_ASSERT(job); 0121 if (!job->error()) { 0122 mApiKey = job->textData(); 0123 } else { 0124 qCWarning(TRANSLATOR_LIBRETRANSLATE_LOG) << "We have an error during reading password " << job->errorString(); 0125 } 0126 } 0127 0128 #include "moc_libretranslateengineplugin.cpp"