File indexing completed on 2024-05-12 05:04:25
0001 // SPDX-FileCopyrightText: 2022 Carl Schwan <carl@carlschwan.eu> 0002 // SPDX-License-Identifier: LGPL-2.0-or-later 0003 0004 #include "filetransferjob.h" 0005 0006 #include "account.h" 0007 #include "tokodon_http_debug.h" 0008 0009 #include <KLocalizedString> 0010 0011 FileTransferJob::FileTransferJob(AbstractAccount *account, const QString &source, const QString &destination) 0012 : KJob() 0013 , m_account(account) 0014 , m_source(source) 0015 , m_destination(destination) 0016 , m_temporaryFile(new QSaveFile(QUrl(destination).toLocalFile())) 0017 { 0018 } 0019 0020 void FileTransferJob::start() 0021 { 0022 if (auto account = qobject_cast<Account *>(m_account); account) { 0023 auto qnam = account->qnam(); 0024 0025 auto reply = qnam->get(QNetworkRequest(QUrl(m_source))); 0026 0027 setTotalAmount(Unit::Files, 1); 0028 if (!m_temporaryFile->isReadable() && !m_temporaryFile->open(QIODevice::WriteOnly)) { 0029 qCWarning(TOKODON_HTTP) << "Couldn't open the temporary file" << m_temporaryFile->fileName() << "for writing" << m_temporaryFile->errorString(); 0030 setError(FileError); 0031 setErrorText(i18n("Could not open the temporary download file")); 0032 emitResult(); 0033 return; 0034 } 0035 connect(reply, &QNetworkReply::downloadProgress, this, [this](qint64 bytesReceived, qint64 bytesTotal) { 0036 if (bytesTotal != -1) { 0037 setTotalAmount(Unit::Bytes, bytesTotal); 0038 } 0039 setProcessedAmount(Unit::Bytes, bytesReceived); 0040 }); 0041 0042 connect(reply, &QNetworkReply::finished, this, [this, reply]() { 0043 if (reply->error() != QNetworkReply::NoError) { 0044 setError(FileError); 0045 setErrorText(reply->errorString()); 0046 emitResult(); 0047 return; 0048 } 0049 if (!m_temporaryFile->commit()) { 0050 qCWarning(TOKODON_HTTP) << "errror when saving"; 0051 } 0052 reply->deleteLater(); 0053 emitResult(); 0054 }); 0055 0056 connect(reply, &QIODevice::readyRead, this, [this, reply] { 0057 auto bytes = reply->read(reply->bytesAvailable()); 0058 if (!bytes.isEmpty()) { 0059 m_temporaryFile->write(bytes); 0060 } else { 0061 qCWarning(TOKODON_HTTP) << "Unexpected empty chunk when downloading from" << reply->url() << "to" << m_temporaryFile->fileName(); 0062 } 0063 }); 0064 0065 connect(reply, &QNetworkReply::metaDataChanged, this, [this, reply] { 0066 auto sizeHeader = reply->header(QNetworkRequest::ContentLengthHeader); 0067 if (sizeHeader.isValid()) { 0068 auto targetSize = sizeHeader.toLongLong(); 0069 if (targetSize != -1) { 0070 if (!m_temporaryFile->resize(targetSize)) { 0071 qCWarning(TOKODON_HTTP) << "Failed to allocate" << targetSize << "bytes for" << m_temporaryFile->fileName(); 0072 setError(FileError); 0073 setErrorText(i18n("Could not reserve disk space for download")); 0074 emitResult(); 0075 } 0076 } 0077 } 0078 }); 0079 0080 Q_EMIT description(this, 0081 i18nc("Job heading, like 'Copying'", "Downloading"), 0082 {i18nc("The URL being downloaded/uploaded", "Source"), m_source}, 0083 {i18nc("The location being downloaded to", "Destination"), m_destination}); 0084 } 0085 }