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
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...)
KTEXTEDITOR_EXPORT QDebug operator<<(QDebug s, const MovingCursor &cursor)
QByteArray toHex(char separator) const const
bool addData(QIODevice *device)
QByteArray result() const const
bool flush()
virtual bool seek(qint64 pos) override
QString errorString() const const
QByteArray readAll()
void readyRead()
qint64 write(const QByteArray &data)
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()
bool isEmpty() const const
QByteArray toLatin1() const const
virtual QString fileName() const const override
bool isEmpty() const const
QString toString(FormattingOptions options) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 3 2025 11:46:56 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.