File indexing completed on 2025-04-27 03:58:38
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2018-02-22 0007 * Description : A text translator using web-services - LibreTranslate methods. 0008 * 0009 * SPDX-FileCopyrightText: 2018-2022 by Hennadii Chernyshchyk <genaloner at gmail dot com> 0010 * SPDX-FileCopyrightText: 2021-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "donlinetranslator_p.h" 0017 0018 namespace Digikam 0019 { 0020 0021 void DOnlineTranslator::slotRequestLibreLangDetection() 0022 { 0023 const QString sourceText = sender()->property(Private::s_textProperty).toString(); 0024 0025 // Generate POST data 0026 0027 const QByteArray postData = "&q=" + QUrl::toPercentEncoding(sourceText) 0028 + "&api_key=" + d->libreApiKey; 0029 0030 // Setup request 0031 0032 QNetworkRequest request; 0033 request.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/x-www-form-urlencoded")); 0034 request.setUrl(QUrl(QString::fromUtf8("%1/detect").arg(d->libreUrl))); 0035 0036 // Make reply 0037 0038 d->currentReply = d->networkManager->post(request, postData); 0039 } 0040 0041 void DOnlineTranslator::slotParseLibreLangDetection() 0042 { 0043 if ((quintptr)d->currentReply.data() != sender()->property("QNetworkReply").value<quintptr>()) 0044 { 0045 return; 0046 } 0047 0048 d->currentReply->deleteLater(); 0049 0050 // Check for errors 0051 0052 if (d->currentReply->error() != QNetworkReply::NoError) 0053 { 0054 resetData(NetworkError, d->currentReply->errorString()); 0055 return; 0056 } 0057 0058 const QJsonDocument jsonResponse = QJsonDocument::fromJson(d->currentReply->readAll()); 0059 const QJsonObject responseObject = jsonResponse.array().first().toObject(); 0060 0061 if (d->sourceLang == Auto) 0062 { 0063 const QString langCode = responseObject.value(QStringLiteral("language")).toString(); 0064 d->sourceLang = language(LibreTranslate, langCode); 0065 0066 if (d->sourceLang == NoLanguage) 0067 { 0068 resetData(ParsingError, i18n("Error: Unable to parse autodetected language")); 0069 } 0070 } 0071 } 0072 0073 void DOnlineTranslator::slotRequestLibreTranslate() 0074 { 0075 const QString sourceText = sender()->property(Private::s_textProperty).toString(); 0076 0077 // Generate POST data 0078 0079 const QByteArray postData = "&q=" + QUrl::toPercentEncoding(sourceText) 0080 + "&source=" + languageApiCode(LibreTranslate, d->sourceLang).toUtf8() 0081 + "&target=" + languageApiCode(LibreTranslate, d->translationLang).toUtf8() 0082 + "&api_key=" + d->libreApiKey; 0083 0084 // Setup request 0085 0086 QNetworkRequest request; 0087 request.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/x-www-form-urlencoded")); 0088 request.setUrl(QUrl(QString::fromUtf8("%1/translate").arg(d->libreUrl))); 0089 0090 // Make reply 0091 0092 d->currentReply = d->networkManager->post(request, postData); 0093 } 0094 0095 void DOnlineTranslator::slotParseLibreTranslate() 0096 { 0097 if ((quintptr)d->currentReply.data() != sender()->property("QNetworkReply").value<quintptr>()) 0098 { 0099 return; 0100 } 0101 0102 d->currentReply->deleteLater(); 0103 0104 // Check for errors 0105 0106 if (d->currentReply->error() != QNetworkReply::NoError) 0107 { 0108 resetData(NetworkError, d->currentReply->errorString()); 0109 return; 0110 } 0111 0112 const QJsonDocument jsonResponse = QJsonDocument::fromJson(d->currentReply->readAll()); 0113 const QJsonObject responseObject = jsonResponse.object(); 0114 d->translation = responseObject.value(QStringLiteral("translatedText")).toString(); 0115 } 0116 0117 void DOnlineTranslator::buildLibreDetectStateMachine() 0118 { 0119 // States 0120 0121 auto* detectState = new QState(d->stateMachine); 0122 auto* finalState = new QFinalState(d->stateMachine); 0123 d->stateMachine->setInitialState(detectState); 0124 0125 detectState->addTransition(detectState, &QState::finished, finalState); 0126 0127 // Setup lang detection state 0128 0129 const QString text = d->source.left(getSplitIndex(d->source, Private::s_libreTranslateLimit)); 0130 0131 buildNetworkRequestState(detectState, 0132 &DOnlineTranslator::slotRequestLibreLangDetection, 0133 &DOnlineTranslator::slotParseLibreLangDetection, 0134 text); 0135 } 0136 0137 void DOnlineTranslator::buildLibreStateMachine() 0138 { 0139 // States 0140 0141 auto* languageDetectionState = new QState(d->stateMachine); 0142 auto* translationState = new QState(d->stateMachine); 0143 auto* finalState = new QFinalState(d->stateMachine); 0144 d->stateMachine->setInitialState(languageDetectionState); 0145 0146 // Transitions 0147 0148 languageDetectionState->addTransition(languageDetectionState, &QState::finished, translationState); 0149 translationState->addTransition(translationState, &QState::finished, finalState); 0150 0151 // Setup LibreTranslate lang code detection 0152 0153 buildNetworkRequestState(languageDetectionState, 0154 &DOnlineTranslator::slotRequestLibreLangDetection, 0155 &DOnlineTranslator::slotParseLibreLangDetection, 0156 d->source); 0157 0158 // Setup translation state 0159 0160 buildSplitNetworkRequest(translationState, 0161 &DOnlineTranslator::slotRequestLibreTranslate, 0162 &DOnlineTranslator::slotParseLibreTranslate, 0163 d->source, 0164 Private::s_libreTranslateLimit); 0165 } 0166 0167 } // namespace Digikam