File indexing completed on 2024-12-22 04:28:22
0001 /* 0002 SPDX-FileCopyrightText: 2023-2024 Laurent Montel <montel.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "voskdownloadlanguagejob.h" 0008 #include "generateinstalledlanguageinfojob.h" 0009 #include "libvoskspeechtotext_debug.h" 0010 #include "speechtotext/speechtotextengineaccessmanager.h" 0011 #include "voskextractlanguagejob.h" 0012 #include <KLocalizedString> 0013 #include <QFileInfo> 0014 #include <QNetworkReply> 0015 #include <QNetworkRequest> 0016 #include <QTemporaryFile> 0017 0018 VoskDownloadLanguageJob::VoskDownloadLanguageJob(QObject *parent) 0019 : QObject{parent} 0020 { 0021 } 0022 0023 VoskDownloadLanguageJob::~VoskDownloadLanguageJob() 0024 { 0025 delete mHash; 0026 } 0027 0028 void VoskDownloadLanguageJob::start() 0029 { 0030 if (!canStart()) { 0031 qCWarning(LIBVOSKSPEECHTOTEXT_LOG) << "Impossible to start DownloadLanguageJob"; 0032 deleteLater(); 0033 return; 0034 } 0035 mDestination = new QTemporaryFile(this); 0036 if (!mDestination->open()) { 0037 Q_EMIT errorText(i18n("Cannot open file for downloading.")); 0038 deleteLater(); 0039 return; 0040 } 0041 0042 mHash = new QCryptographicHash(QCryptographicHash::Md5); 0043 0044 QNetworkRequest request(mInfo.url); 0045 // qDebug() << " mInfo.url " << mInfo.url; 0046 QNetworkReply *reply = TextSpeechToText::SpeechToTextEngineAccessManager::self()->networkManager()->get(request); 0047 connect(reply, &QNetworkReply::errorOccurred, this, [this](QNetworkReply::NetworkError error) { 0048 if (error == QNetworkReply::ServiceUnavailableError) { 0049 Q_EMIT errorText(i18n("Error: Engine systems have detected suspicious traffic from your computer network. Please try your request again later.")); 0050 } else { 0051 Q_EMIT errorText(i18n("Impossible to access to url: %1", mInfo.url.toString())); 0052 } 0053 }); 0054 0055 connect(reply, &QNetworkReply::downloadProgress, this, &VoskDownloadLanguageJob::downloadProgress); 0056 connect(reply, &QNetworkReply::finished, this, [this, reply]() { 0057 mDestination->flush(); 0058 mDestination->seek(0); 0059 reply->deleteLater(); 0060 if (!mInfo.checksum.isEmpty() && mHash->result().toHex() != mInfo.checksum.toLatin1()) { 0061 // qDebug() << " mHash->result() " << mHash->result().toHex() << " mCheckSum " << mCheckSum; 0062 Q_EMIT errorText(i18n("CheckSum is not correct.")); 0063 deleteLater(); 0064 return; 0065 } else { 0066 extractLanguage(); 0067 } 0068 }); 0069 connect(reply, &QIODevice::readyRead, this, [this, reply] { 0070 const QByteArray buffer = reply->readAll(); 0071 if (mDestination->write(buffer) == -1) { 0072 Q_EMIT errorText(i18n("Error during writing on disk: %1", mDestination->errorString())); 0073 reply->abort(); 0074 } 0075 mHash->addData(buffer); 0076 }); 0077 } 0078 0079 bool VoskDownloadLanguageJob::canStart() const 0080 { 0081 return mInfo.isValid(); 0082 } 0083 0084 void VoskDownloadLanguageJob::extractLanguage() 0085 { 0086 auto extraJob = new VoskExtractLanguageJob(this); 0087 extraJob->setSource(mDestination->fileName()); 0088 connect(extraJob, &VoskExtractLanguageJob::errorText, this, &VoskDownloadLanguageJob::errorText); 0089 connect(extraJob, &VoskExtractLanguageJob::finished, this, &VoskDownloadLanguageJob::generateInstalledLanguageInfo); 0090 0091 extraJob->start(); 0092 } 0093 0094 void VoskDownloadLanguageJob::generateInstalledLanguageInfo() 0095 { 0096 auto generateInstalledLanguageJob = new GenerateInstalledLanguageInfoJob(this); 0097 GenerateInstalledLanguageInfoJob::LanguageInfo info; 0098 info.pathToStore = VoskEngineUtils::storageLanguagePath() + QLatin1Char('/') + mInfo.name; 0099 info.info.absoluteLanguageModelPath = VoskEngineUtils::storageLanguagePath() + QLatin1Char('/') + mInfo.name; 0100 info.info.name = mInfo.name; 0101 info.info.url = mInfo.url.toString(); 0102 info.info.versionStr = mInfo.version; 0103 generateInstalledLanguageJob->setInfo(info); 0104 0105 connect(generateInstalledLanguageJob, &GenerateInstalledLanguageInfoJob::errorText, this, &VoskDownloadLanguageJob::errorText); 0106 connect(generateInstalledLanguageJob, 0107 &GenerateInstalledLanguageInfoJob::generatedDone, 0108 this, 0109 &VoskDownloadLanguageJob::slotGenerateInstalledLanguageInfoDone); 0110 generateInstalledLanguageJob->start(); 0111 } 0112 0113 void VoskDownloadLanguageJob::slotGenerateInstalledLanguageInfoDone() 0114 { 0115 Q_EMIT extractDone(); 0116 deleteLater(); 0117 } 0118 0119 VoskDownloadLanguageJob::DownloadLanguageInfo VoskDownloadLanguageJob::info() const 0120 { 0121 return mInfo; 0122 } 0123 0124 void VoskDownloadLanguageJob::setInfo(const DownloadLanguageInfo &newInfo) 0125 { 0126 mInfo = newInfo; 0127 } 0128 0129 QDebug operator<<(QDebug d, const VoskDownloadLanguageJob::DownloadLanguageInfo &t) 0130 { 0131 d << "url " << t.url; 0132 d << "checksum " << t.checksum; 0133 d << "name " << t.name; 0134 d << "version " << t.version; 0135 return d; 0136 } 0137 0138 bool VoskDownloadLanguageJob::DownloadLanguageInfo::isValid() const 0139 { 0140 return !url.isEmpty() && !name.isEmpty(); 0141 } 0142 0143 #include "moc_voskdownloadlanguagejob.cpp"