KTextAddons

voskdownloadlanguagejob.cpp
1/*
2 SPDX-FileCopyrightText: 2023-2025 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "voskdownloadlanguagejob.h"
8#include "generateinstalledlanguageinfojob.h"
9#include "libvoskspeechtotext_debug.h"
10#include "speechtotext/speechtotextengineaccessmanager.h"
11#include "voskextractlanguagejob.h"
12#include <KLocalizedString>
13#include <QNetworkReply>
14#include <QNetworkRequest>
15#include <QTemporaryFile>
16
17VoskDownloadLanguageJob::VoskDownloadLanguageJob(QObject *parent)
18 : QObject{parent}
19{
20}
21
22VoskDownloadLanguageJob::~VoskDownloadLanguageJob()
23{
24 delete mHash;
25}
26
27void VoskDownloadLanguageJob::start()
28{
29 if (!canStart()) {
30 qCWarning(LIBVOSKSPEECHTOTEXT_LOG) << "Impossible to start DownloadLanguageJob";
32 return;
33 }
34 mDestination = new QTemporaryFile(this);
35 if (!mDestination->open()) {
36 Q_EMIT errorText(i18n("Cannot open file for downloading."));
38 return;
39 }
40
41 mHash = new QCryptographicHash(QCryptographicHash::Md5);
42
43 QNetworkRequest request(mInfo.url);
44 // qDebug() << " mInfo.url " << mInfo.url;
45 QNetworkReply *reply = TextSpeechToText::SpeechToTextEngineAccessManager::self()->networkManager()->get(request);
48 Q_EMIT errorText(i18n("Error: Engine systems have detected suspicious traffic from your computer network. Please try your request again later."));
49 } else {
50 Q_EMIT errorText(i18n("Impossible to access to url: %1", mInfo.url.toString()));
51 }
52 });
53
54 connect(reply, &QNetworkReply::downloadProgress, this, &VoskDownloadLanguageJob::downloadProgress);
55 connect(reply, &QNetworkReply::finished, this, [this, reply]() {
56 mDestination->flush();
57 mDestination->seek(0);
58 reply->deleteLater();
59 if (!mInfo.checksum.isEmpty() && mHash->result().toHex() != mInfo.checksum.toLatin1()) {
60 // qDebug() << " mHash->result() " << mHash->result().toHex() << " mCheckSum " << mCheckSum;
61 Q_EMIT errorText(i18n("CheckSum is not correct."));
63 return;
64 } else {
65 extractLanguage();
66 }
67 });
68 connect(reply, &QIODevice::readyRead, this, [this, reply] {
69 const QByteArray buffer = reply->readAll();
70 if (mDestination->write(buffer) == -1) {
71 Q_EMIT errorText(i18n("Error during writing on disk: %1", mDestination->errorString()));
72 reply->abort();
73 }
74 mHash->addData(buffer);
75 });
76}
77
78bool VoskDownloadLanguageJob::canStart() const
79{
80 return mInfo.isValid();
81}
82
83void VoskDownloadLanguageJob::extractLanguage()
84{
85 auto extraJob = new VoskExtractLanguageJob(this);
86 extraJob->setSource(mDestination->fileName());
87 connect(extraJob, &VoskExtractLanguageJob::errorText, this, &VoskDownloadLanguageJob::errorText);
88 connect(extraJob, &VoskExtractLanguageJob::finished, this, &VoskDownloadLanguageJob::generateInstalledLanguageInfo);
89
90 extraJob->start();
91}
92
93void VoskDownloadLanguageJob::generateInstalledLanguageInfo()
94{
95 auto generateInstalledLanguageJob = new GenerateInstalledLanguageInfoJob(this);
96 GenerateInstalledLanguageInfoJob::LanguageInfo info;
97 info.pathToStore = VoskEngineUtils::storageLanguagePath() + QLatin1Char('/') + mInfo.name;
98 info.info.absoluteLanguageModelPath = VoskEngineUtils::storageLanguagePath() + QLatin1Char('/') + mInfo.name;
99 info.info.name = mInfo.name;
100 info.info.url = mInfo.url.toString();
101 info.info.versionStr = mInfo.version;
102 generateInstalledLanguageJob->setInfo(info);
103
104 connect(generateInstalledLanguageJob, &GenerateInstalledLanguageInfoJob::errorText, this, &VoskDownloadLanguageJob::errorText);
105 connect(generateInstalledLanguageJob,
106 &GenerateInstalledLanguageInfoJob::generatedDone,
107 this,
108 &VoskDownloadLanguageJob::slotGenerateInstalledLanguageInfoDone);
109 generateInstalledLanguageJob->start();
110}
111
112void VoskDownloadLanguageJob::slotGenerateInstalledLanguageInfoDone()
113{
114 Q_EMIT extractDone();
115 deleteLater();
116}
117
118VoskDownloadLanguageJob::DownloadLanguageInfo VoskDownloadLanguageJob::info() const
119{
120 return mInfo;
121}
122
123void VoskDownloadLanguageJob::setInfo(const DownloadLanguageInfo &newInfo)
124{
125 mInfo = newInfo;
126}
127
128QDebug operator<<(QDebug d, const VoskDownloadLanguageJob::DownloadLanguageInfo &t)
129{
130 d << "url " << t.url;
131 d << "checksum " << t.checksum;
132 d << "name " << t.name;
133 d << "version " << t.version;
134 return d;
135}
136
137bool VoskDownloadLanguageJob::DownloadLanguageInfo::isValid() const
138{
139 return !url.isEmpty() && !name.isEmpty();
140}
141
142#include "moc_voskdownloadlanguagejob.cpp"
QString i18n(const char *text, const TYPE &arg...)
QByteArray readAll()
void readyRead()
QNetworkReply * get(const QNetworkRequest &request)
virtual void abort()=0
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
void errorOccurred(QNetworkReply::NetworkError code)
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void deleteLater()
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 24 2025 11:49:24 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.