Page MenuHomePhorge

No OneTemporary

Size
26 KB
Referenced Files
None
Subscribers
None
diff --git a/src/kazv-io-job.cpp b/src/kazv-io-job.cpp
index ee675ff..0d75e31 100644
--- a/src/kazv-io-job.cpp
+++ b/src/kazv-io-job.cpp
@@ -1,353 +1,357 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2022-2023 nannanko <nannanko@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include <kazv-defs.hpp>
#include "kazv-io-job.hpp"
#include "matrix-room.hpp"
#include "kazv-log.hpp"
#include <QObject>
#include <QPointer>
#include <QSharedPointer>
#include <QSaveFile>
#include <QFile>
#include <QString>
#include <QMimeDatabase>
#include <QCryptographicHash>
#include <QLoggingCategory>
#include <KJob>
#include <KIO/TransferJob>
#include <nlohmann/json.hpp>
#include <optional>
#include <string>
using namespace Qt::Literals::StringLiterals;
struct KazvIOBaseJobPrivate
{
QPointer<KIO::TransferJob> job;
std::optional<KazvIOBaseJob::ErrorCode> result = std::nullopt;
std::optional<Kazv::AES256CTRDesc> aes = std::nullopt;
};
KazvIOBaseJob::KazvIOBaseJob(std::optional<Kazv::AES256CTRDesc> aes, QObject *parent)
: QObject(parent)
, m_d(new KazvIOBaseJobPrivate)
{
/**
* For unknown reasons, if a new AES256CTRDesc is not constructed here,
* it will cause the program to crash.
*/
if (aes != std::nullopt) {
m_d->aes = Kazv::AES256CTRDesc{aes.value().key(), aes.value().iv()};
}
// m_d->aes = aes;
connect(this, &KazvIOBaseJob::jobChanged, this, &KazvIOBaseJob::connectJob);
}
KazvIOBaseJob::~KazvIOBaseJob() = default;
float KazvIOBaseJob::progress() {
if (m_d->job.isNull()) {
return 0;
}
return static_cast<float>(m_d->job->percent()) / 100;
}
void KazvIOBaseJob::suspend()
{
if (m_d->job.isNull()) {
emitResult(KazvError);
return;
}
m_d->job->suspend();
}
void KazvIOBaseJob::resume()
{
if (m_d->job.isNull()) {
emitResult(KazvError);
return;
}
m_d->job->resume();
}
void KazvIOBaseJob::cancel()
{
if (m_d->job.isNull()) {
emitResult(KazvError);
return;
}
emitResult(UserCancel);
m_d->job->kill();
}
bool KazvIOBaseJob::isSuspended()
{
if (m_d->job.isNull()) {
return false;
}
return m_d->job->isSuspended();
}
bool KazvIOBaseJob::isResulted()
{
return m_d->result.has_value();
}
KazvIOBaseJob::ErrorCode KazvIOBaseJob::error()
{
if (m_d->result.has_value()) {
return m_d->result.value();
}
// Shouldn't call this function before result are emited
return NoError;
}
void KazvIOBaseJob::connectJob()
{
connect(m_d->job, &KJob::result, this, [this](KJob *job) {
if (job->error()) {
emitResult(KIOError);
}
});
connect(m_d->job, &KJob::percentChanged, this,
[this](KJob * /* job */, unsigned long /* percent */) { Q_EMIT progressChanged(); });
}
QPointer<KIO::TransferJob> KazvIOBaseJob::job()
{
return m_d->job;
}
void KazvIOBaseJob::setJob(QPointer<KIO::TransferJob> job)
{
m_d->job = job;
Q_EMIT jobChanged();
}
void KazvIOBaseJob::emitResult(ErrorCode ec, QString data)
{
if (m_d->result.has_value()) {
return;
}
m_d->result = ec;
Q_EMIT result(m_d->result.value(), data);
}
std::optional<Kazv::AES256CTRDesc> KazvIOBaseJob::aes()
{
return m_d->aes;
}
void KazvIOBaseJob::setAes(Kazv::AES256CTRDesc aes)
{
m_d->aes = aes;
}
struct KazvIODownloadJobPrivate
{
QSharedPointer<KazvSaveFile> file;
QString hash;
};
KazvIODownloadJob::KazvIODownloadJob(const QString &hash, std::optional<Kazv::AES256CTRDesc> aes, QObject *parent)
: KazvIOBaseJob(aes, parent)
, m_d(new KazvIODownloadJobPrivate)
{
m_d->hash = hash;
}
-KazvIODownloadJob::KazvIODownloadJob(const QString &fileName, const QUrl &serverUrl,
+KazvIODownloadJob::KazvIODownloadJob(const QString &fileName, const QUrl &serverUrl, bool showProgressBar,
const QString &hash, std::optional<Kazv::AES256CTRDesc> aes, QObject *parent)
: KazvIOBaseJob(aes, parent)
, m_d(new KazvIODownloadJobPrivate)
{
if (setFile(fileName)) {
- setJob(KIO::get(serverUrl));
+ auto flag = showProgressBar ? KIO::DefaultFlags : KIO::HideProgressInfo;
+ setJob(KIO::get(serverUrl, KIO::NoReload, flag));
}
m_d->hash = hash;
}
KazvIODownloadJob::~KazvIODownloadJob() = default;
QString KazvIODownloadJob::fileName() {
if (m_d->file.isNull()) {
return QStringLiteral("");
}
return m_d->file->fileName();
}
void KazvIODownloadJob::connectJob()
{
KazvIOBaseJob::connectJob();
connect(this->job(), &KIO::TransferJob::data, this, &KazvIODownloadJob::writeFile);
connect(this->job(), &KJob::result, this, &KazvIODownloadJob::closeFile);
}
bool KazvIODownloadJob::setFile(QString fileName)
{
m_d->file.reset(new KazvSaveFile(fileName, this->aes()));
if (m_d->file->open(QIODevice::WriteOnly)) {
return true;
}
emitResult(KazvIOBaseJob::OpenFileError);
return false;
}
void KazvIODownloadJob::writeFile(KJob *job, const QByteArray &data)
{
if (m_d->file.isNull() || !m_d->file->isOpen()) {
emitResult(KazvError);
job->kill();
return;
}
auto len = m_d->file->write(data);
if (len == -1) {
KazvIOBaseJob::emitResult(WriteFileError);
job->kill();
}
}
void KazvIODownloadJob::closeFile(KJob *job)
{
if (m_d->file.isNull()) {
emitResult(KazvError);
return;
}
if (job->error()) {
m_d->file->cancelWriting();
return;
}
if (!m_d->hash.isEmpty() && QString::fromUtf8(m_d->file->hash()) != m_d->hash) {
emitResult(HashError);
return;
}
m_d->file->commit();
emitResult(NoError);
}
struct KazvIOUploadJobPrivate
{
QSharedPointer<KazvFile> file;
QString response;
QSharedPointer<MatrixRoom> room;
QString mimeType;
QString mxcUri;
QString relType;
QString relatedTo;
};
KazvIOUploadJob::KazvIOUploadJob(std::optional<Kazv::AES256CTRDesc> aes,
const QString &relType, const QString &relatedTo, QObject *parent)
: KazvIOBaseJob(aes, parent)
, m_d(new KazvIOUploadJobPrivate)
{
m_d->relType = relType;
m_d->relatedTo = relatedTo;
}
KazvIOUploadJob::KazvIOUploadJob(const QString fileName, const QUrl serverUrl,
- MatrixRoomList *roomList, const QString &roomId, const QString token,
- std::optional<Kazv::AES256CTRDesc> aes,
+ const bool showProgressBar, MatrixRoomList *roomList, const QString &roomId,
+ const QString token, std::optional<Kazv::AES256CTRDesc> aes,
const QString &relType, const QString &relatedTo, QObject *parent)
: KazvIOBaseJob(aes, parent)
, m_d(new KazvIOUploadJobPrivate)
{
m_d->relType = relType;
m_d->relatedTo = relatedTo;
if (setFile(fileName)) {
auto kazvUploadJob = Kazv::Api::UploadContentJob(serverUrl.toString().toStdString(),
token.toStdString(), Kazv::FileDesc(std::string()));
- auto job = KIO::http_post(QUrl(QString::fromStdString(kazvUploadJob.url())), m_d->file.data());
+ auto jobFlag = showProgressBar ? KIO::DefaultFlags : KIO::HideProgressInfo;
+ auto job = KIO::http_post(
+ QUrl(QString::fromStdString(kazvUploadJob.url())),
+ m_d->file.data(), jobFlag);
job->addMetaData(u"customHTTPHeader"_s, QStringLiteral("Authorization: ")
.append(QString::fromStdString(kazvUploadJob.requestHeader()->at("Authorization"))));
job->addMetaData(u"PropagateHttpHeader"_s, u"true"_s);
setJob(job);
if (roomList) {
m_d->room.reset(roomList->room(roomId));
}
}
}
KazvIOUploadJob::~KazvIOUploadJob() = default;
QString KazvIOUploadJob::fileName()
{
if (m_d->file.isNull()) {
return QStringLiteral("");
}
return m_d->file->fileName();
}
void KazvIOUploadJob::connectJob()
{
KazvIOBaseJob::connectJob();
connect(this->job(), &KIO::TransferJob::data, this,
[this](KJob * /* job */, const QByteArray &data) { m_d->response.append(QString::fromUtf8(data)); });
connect(this->job(), &KJob::result, this, &KazvIOUploadJob::handleResult);
connect(this->job(), &KIO::TransferJob::mimeTypeFound, this,
[this](KJob * /* job */, const QString &mimeType) { m_d->mimeType = mimeType; });
}
void KazvIOUploadJob::handleResult(KJob *job)
{
if (m_d->file.isNull()) {
emitResult(KazvError);
return;
}
m_d->file->close();
if (job->error()) {
return;
}
nlohmann::json j;
try {
j = nlohmann::json::parse(m_d->response.toStdString());
} catch(...) {
emitResult(ResponseError);
qCWarning(kazvLog) << "Get a invaild response from server.";
return;
}
QString mxcUri{};
if (j.contains("content_uri") && j["content_uri"].is_string()) {
mxcUri = QString::fromStdString(j["content_uri"].template get<std::string>());
} else {
emitResult(ResponseError);
qCWarning(kazvLog) << "There is no \"content_uri\" field in response.";
return;
}
auto shouldSendMessage = !!m_d->room;
if (shouldSendMessage) {
auto aes = this->aes();
if (aes.has_value()) {
m_d->room->sendEncryptedFileMessage(QUrl::fromLocalFile(m_d->file->fileName()).fileName(),
QMimeDatabase().mimeTypeForFile(m_d->file.data()->fileName()).name(),
m_d->file->size(), mxcUri,
QString::fromStdString(aes.value().key()), QString::fromStdString(aes.value().iv()),
m_d->file->hash(), m_d->relType, m_d->relatedTo);
} else {
m_d->room->sendMediaFileMessage(QUrl::fromLocalFile(m_d->file->fileName()).fileName(),
QMimeDatabase().mimeTypeForData(m_d->file.data()).name(),
m_d->file->size(), mxcUri, m_d->relType, m_d->relatedTo);
}
}
KazvIOBaseJob::emitResult(NoError, mxcUri);
}
bool KazvIOUploadJob::setFile(const QString fileName)
{
m_d->file.reset(new KazvFile(fileName, this->aes()));
if (m_d->file->open(QIODevice::ReadOnly)) {
return true;
}
emitResult(KazvIOBaseJob::OpenFileError);
return false;
}
diff --git a/src/kazv-io-job.hpp b/src/kazv-io-job.hpp
index bb42234..a9a374e 100644
--- a/src/kazv-io-job.hpp
+++ b/src/kazv-io-job.hpp
@@ -1,164 +1,165 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2022-2023 nannanko <nannanko@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#pragma once
#include <kazv-defs.hpp>
#include "matrix-room.hpp"
#include "matrix-room-list.hpp"
#include "kazv-file.hpp"
#include <aes-256-ctr.hpp>
#include <QObject>
#include <QPointer>
#include <QString>
#include <QUrl>
#include <KIO/TransferJob>
#include <memory>
#include <optional>
struct KazvIOBaseJobPrivate;
class KazvIOBaseJob : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("")
Q_PROPERTY(float progress READ progress NOTIFY progressChanged)
std::unique_ptr<KazvIOBaseJobPrivate> m_d;
public:
enum ErrorCode {
/**
* No Error or the signal result has not been emitted yet.
*/
NoError = 0,
/**
* The user actively canceled the job.
*/
UserCancel,
/**
* Open File Error.
*/
OpenFileError,
/**
* Write File Error
*/
WriteFileError,
/**
* Errors caused by KIO, such network error.
*/
KIOError,
/**
* Error caused by hash error
*/
HashError,
/**
* Error caused by invalid response.
* KIO reported no error, but got an invalid JSON response.
*/
ResponseError,
/**
* Errors caused by bad code, means the bug is somewhere.
*/
KazvError
};
Q_ENUM(ErrorCode)
KazvIOBaseJob(std::optional<Kazv::AES256CTRDesc> aes = std::nullopt, QObject *parent = 0);
~KazvIOBaseJob();
float progress();
Q_INVOKABLE void suspend();
Q_INVOKABLE void resume();
Q_INVOKABLE void cancel();
Q_INVOKABLE bool isSuspended();
Q_INVOKABLE bool isResulted();
/**
* Only use it after emitted the result signal
*/
Q_INVOKABLE ErrorCode error();
Q_SIGNALS:
void jobChanged();
void progressChanged();
/**
* @param data the mxcUri if this is an upload job.
*/
void result(ErrorCode ec, QString data);
protected Q_SLOTS:
virtual void connectJob();
protected:
QPointer<KIO::TransferJob> job();
void setJob(QPointer<KIO::TransferJob> job);
std::optional<Kazv::AES256CTRDesc> aes();
void setAes(Kazv::AES256CTRDesc);
void emitResult(ErrorCode ec, QString data = QString());
};
struct KazvIODownloadJobPrivate;
class KazvIODownloadJob : public KazvIOBaseJob
{
Q_OBJECT
std::unique_ptr<KazvIODownloadJobPrivate> m_d;
bool setFile(QString fileName);
public:
KazvIODownloadJob(const QString &hash, std::optional<Kazv::AES256CTRDesc> aes = std::nullopt, QObject *parent = 0);
- KazvIODownloadJob(const QString &fileName, const QUrl &serverUrl, const QString &hash,
+ KazvIODownloadJob(const QString &fileName, const QUrl &serverUrl, const bool showProgressBar, const QString &hash,
std::optional<Kazv::AES256CTRDesc> aes = std::nullopt, QObject *parent = 0);
~KazvIODownloadJob();
Q_INVOKABLE QString fileName();
private Q_SLOTS:
void writeFile(KJob *job, const QByteArray &data);
void closeFile(KJob *job);
protected Q_SLOTS:
void connectJob() override;
};
struct KazvIOUploadJobPrivate;
class KazvIOUploadJob : public KazvIOBaseJob
{
Q_OBJECT
std::unique_ptr<KazvIOUploadJobPrivate> m_d;
bool setFile(const QString fileName);
public:
KazvIOUploadJob(std::optional<Kazv::AES256CTRDesc> aes = std::nullopt,
const QString &relType = QStringLiteral(""),
const QString &relatedTo = QStringLiteral(""), QObject *parent = 0);
- KazvIOUploadJob(const QString fileName, const QUrl serverUrl, MatrixRoomList *roomList,
+ KazvIOUploadJob(const QString fileName, const QUrl serverUrl,
+ const bool showProgressBar, MatrixRoomList *roomList,
const QString &roomId, const QString token,
std::optional<Kazv::AES256CTRDesc> aes = std::nullopt,
const QString &relType = QStringLiteral(""),
const QString &relatedTo = QStringLiteral(""), QObject *parent = 0);
~KazvIOUploadJob();
Q_INVOKABLE QString fileName();
private Q_SLOTS:
void handleResult(KJob *job);
protected Q_SLOTS:
void connectJob() override;
};
diff --git a/src/kazv-io-manager.cpp b/src/kazv-io-manager.cpp
index 328a839..0e6f5cc 100644
--- a/src/kazv-io-manager.cpp
+++ b/src/kazv-io-manager.cpp
@@ -1,223 +1,229 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2022-2023 nannanko <nannanko@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include <kazv-defs.hpp>
#include "kazv-io-manager.hpp"
#include "kazv-io-job.hpp"
#include "matrix-room.hpp"
#include "upload-job-model.hpp"
#include "qt-rand-adapter.hpp"
#include <api/csapi/content-repo.hpp>
#include <file-desc.hpp>
#include <QObject>
#include <QIODevice>
#include <QFile>
#include <QSaveFile>
#include <QPointer>
#include <QSharedPointer>
#include <QUrl>
#include <QMap>
#include <QMultiMap>
#include <QTemporaryDir>
#include <string>
#include <algorithm>
using namespace Qt::Literals::StringLiterals;
static const QString ROOMLESS = QStringLiteral("not-a-room");
struct KazvIOManagerPrivate
{
/**
* Used to store various temporary files.
* If the user does not specify a cache directory,
* this directory is also used as a cache directory.
*/
QTemporaryDir tmpDir = QTemporaryDir{};
/**
* Stores files that need to be previewed (e.g. in a timeline)
* and are not downloaded by the user, such as images, audio, video covers, and videos.
*/
QDir cacheDir{tmpDir.path()};
Kazv::RandomInterface randomGenerator = QtRandAdapter{};
QMap<QString, QPointer<KazvIODownloadJob>> cacheJobs;
QMap<QString, QSharedPointer<KazvIODownloadJob>> downloadJobs;
QMap<QString, QSharedPointer<UploadJobModel>> uploadJobs;
};
KazvIOManager::KazvIOManager(QObject *parent)
: QObject(parent)
, m_d(new KazvIOManagerPrivate)
{
}
KazvIOManager::~KazvIOManager() = default;
QPointer<KazvIODownloadJob> KazvIOManager::makeDownloadJob(
- const QUrl &serverUrl, const QUrl &localFileUrl, const QString &hash,
+ const QUrl &serverUrl, const QUrl &localFileUrl,
+ const bool showPrograssBar, const QString &hash,
const QString &key, const QString &iv) const
{
QPointer<KazvIODownloadJob> job{};
if (key.isEmpty()) {
- job = new KazvIODownloadJob{localFileUrl.toLocalFile(), serverUrl, hash, std::nullopt};
+ job = new KazvIODownloadJob{localFileUrl.toLocalFile(),
+ serverUrl, showPrograssBar, hash, std::nullopt};
} else {
auto aes = Kazv::AES256CTRDesc{key.toStdString(), iv.toStdString()};
- job = new KazvIODownloadJob{localFileUrl.toLocalFile(), serverUrl, hash, aes};
+ job = new KazvIODownloadJob{localFileUrl.toLocalFile(),
+ serverUrl, showPrograssBar, hash, aes};
}
return job;
}
QUrl KazvIOManager::cacheFile(const QUrl &fileUrl, const QString &id, const QString &hash,
const QString &key, const QString &iv)
{
const QString filePath = m_d->cacheDir.filePath(id);
QDir dir(m_d->cacheDir.path());
if (!dir.exists(id) && this->getCacheJob(id) == nullptr) {
- auto job = this->makeDownloadJob(fileUrl, QUrl::fromLocalFile(filePath), hash, key, iv);
+ auto job = this->makeDownloadJob(fileUrl,
+ QUrl::fromLocalFile(filePath),
+ /* showProgressBar = */ false, hash, key, iv);
m_d->cacheJobs[id] = job;
connect(job, &KazvIOBaseJob::result, this, [this, id](auto /* result */) {
m_d->cacheJobs[id]->deleteLater();
m_d->cacheJobs.remove(id);
});
}
return QUrl::fromLocalFile(filePath);
}
KazvIOBaseJob *KazvIOManager::startNewDownloadJob(const QUrl &serverUrl, const QUrl &localFileUrl,
const QString &jobId, const QString &hash, const QString &key, const QString &iv)
{
- auto downloadJob = this->makeDownloadJob(serverUrl, localFileUrl, hash, key, iv);
+ auto downloadJob = this->makeDownloadJob(serverUrl, localFileUrl,
+ /* showProgressBar = */ true, hash, key, iv);
m_d->downloadJobs[jobId].reset(downloadJob);
QQmlEngine::setObjectOwnership(downloadJob.data(), QQmlEngine::CppOwnership);
return downloadJob.data();
}
KazvIOBaseJob *KazvIOManager::startNewUploadJob(
const QUrl &serverUrl, const QUrl &localFileUrl, const QString &token,
const QString &roomId, MatrixRoomList *roomList, const bool encrypted,
const QString &relType, const QString &relatedTo)
{
auto uploadJob = QPointer<KazvIOUploadJob>();
if (encrypted) {
auto aes = Kazv::AES256CTRDesc::fromRandom(
m_d->randomGenerator.generateRange<Kazv::RandomData>(Kazv::AES256CTRDesc::randomSize));
uploadJob = new KazvIOUploadJob(localFileUrl.toLocalFile(), serverUrl,
- roomList, roomId, token, aes, relType, relatedTo);
+ /* showProgressBar = */ true, roomList, roomId, token, aes, relType, relatedTo);
} else {
uploadJob = new KazvIOUploadJob(localFileUrl.toLocalFile(), serverUrl,
- roomList, roomId, token, std::nullopt, relType, relatedTo);
+ /* showProgressBar = */ true, roomList, roomId, token, std::nullopt, relType, relatedTo);
}
if (!m_d->uploadJobs.contains(roomId) || m_d->uploadJobs[roomId].isNull()) {
m_d->uploadJobs[roomId].reset(new UploadJobModel());
}
m_d->uploadJobs[roomId]->addJob(uploadJob);
QQmlEngine::setObjectOwnership(uploadJob.data(), QQmlEngine::CppOwnership);
return uploadJob.data();
}
KazvIOBaseJob *KazvIOManager::startNewRoomlessUploadJob(const QUrl &serverUrl, const QUrl &localFileUrl, const QString &token)
{
return startNewUploadJob(
serverUrl, localFileUrl, token, ROOMLESS, 0, false,
QStringLiteral(""), QStringLiteral(""));
}
KazvIOBaseJob *KazvIOManager::getCacheJob(const QString &jobId) const
{
auto targetJob = m_d->cacheJobs.find(jobId);
if (targetJob == m_d->cacheJobs.end()) {
return nullptr;
}
QQmlEngine::setObjectOwnership(targetJob.value().data(), QQmlEngine::CppOwnership);
return targetJob.value().data();
}
KazvIOBaseJob *KazvIOManager::getDownloadJob(const QString &jobId)
{
auto targetJob = m_d->downloadJobs.find(jobId);
if (targetJob == m_d->downloadJobs.end()) {
return nullptr;
}
QQmlEngine::setObjectOwnership(targetJob.value().data(), QQmlEngine::CppOwnership);
return targetJob.value().data();
}
void KazvIOManager::deleteDownloadJob(const QString &jobId)
{
m_d->downloadJobs.remove(jobId);
}
UploadJobModel *KazvIOManager::getUploadJobs(const QString &roomId)
{
if (!m_d->uploadJobs.contains(roomId) || m_d->uploadJobs[roomId].isNull()) {
m_d->uploadJobs[roomId].reset(new UploadJobModel());
}
QQmlEngine::setObjectOwnership(m_d->uploadJobs[roomId].data(), QQmlEngine::CppOwnership);
return m_d->uploadJobs[roomId].data();
}
void KazvIOManager::deleteUploadJob(const QString &roomId, KazvIOBaseJob *job)
{
m_d->uploadJobs[roomId]->removeJob(QPointer<KazvIOUploadJob>(qobject_cast<KazvIOUploadJob*>(job)));
}
void KazvIOManager::deleteRoomlessUploadJob(KazvIOBaseJob *job)
{
deleteUploadJob(ROOMLESS, job);
}
void KazvIOManager::deleteModelIfEmpty(const QString &roomId)
{
if (!m_d->uploadJobs.contains(roomId)) {
return;
}
if (m_d->uploadJobs[roomId]->rowCount() == 0) {
m_d->uploadJobs.remove(roomId);
}
}
void KazvIOManager::clearJobs()
{
/**
* KazvIOBaseJob::cancel() for cache jobs will remove itself from cacheJobs,
* so iterators and loops for m_d->cacheJobs cannot be used reliably.
*/
for (auto key : m_d->cacheJobs.keys()) {
m_d->cacheJobs[key]->cancel();
}
std::for_each(m_d->downloadJobs.begin(), m_d->downloadJobs.end(), [this](auto job){
job->cancel();
});
std::for_each(m_d->uploadJobs.begin(), m_d->uploadJobs.end(), [this](auto room) {
room->clearJobs();
});
m_d->downloadJobs.clear();
m_d->uploadJobs.clear();
}
QString KazvIOManager::cacheDirectory() const
{
return m_d->cacheDir.path();
}
void KazvIOManager::setCacheDirectory(QString cacheDirectory)
{
if (cacheDirectory.isEmpty()) {
m_d->cacheDir = QDir{m_d->tmpDir.path()};
} else {
auto cacheDir = QDir{QUrl{cacheDirectory}.toLocalFile()};
if (!cacheDir.mkpath(u"."_s)) {
return;
}
m_d->cacheDir = cacheDir;
}
m_d->downloadJobs.clear();
Q_EMIT cacheDirectoryChanged();
}
diff --git a/src/kazv-io-manager.hpp b/src/kazv-io-manager.hpp
index f0e6c4f..dead687 100644
--- a/src/kazv-io-manager.hpp
+++ b/src/kazv-io-manager.hpp
@@ -1,73 +1,74 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2022-2023 nannanko <nannanko@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#pragma once
#include <kazv-defs.hpp>
#include "kazv-io-job.hpp"
#include "matrix-room.hpp"
#include "upload-job-model.hpp"
#include "matrix-room-list.hpp"
#include "matrix-sdk.hpp"
#include <QObject>
#include <QtQml>
#include <QUrl>
#include <QString>
#include <KIO/TransferJob>
#include <QPointer>
#include <memory>
struct KazvIOManagerPrivate;
class KazvIOManager : public QObject
{
Q_OBJECT
QML_ELEMENT
std::unique_ptr<KazvIOManagerPrivate> m_d;
Q_PROPERTY(QString cacheDirectory READ cacheDirectory WRITE setCacheDirectory NOTIFY cacheDirectoryChanged)
QPointer<KazvIODownloadJob> makeDownloadJob(
- const QUrl &serverUrl, const QUrl &localFileUrl, const QString &hash,
+ const QUrl &serverUrl, const QUrl &localFileUrl,
+ const bool showPrograssBar, const QString &hash,
const QString &key = QStringLiteral(""),
const QString &iv = QStringLiteral("")) const;
public:
explicit KazvIOManager(QObject *parent = 0);
~KazvIOManager() override;
/**
* Cache the file specified by fileUrl into a temporary folder
* Multiple calls do not repeat downloads
* Returns the local url of the cached file.
*/
Q_INVOKABLE QUrl cacheFile(const QUrl &fileUrl, const QString &id, const QString &hash = QStringLiteral(""),
const QString &key = QStringLiteral(""), const QString &iv = QStringLiteral(""));
Q_INVOKABLE KazvIOBaseJob *startNewDownloadJob(const QUrl &serverUrl, const QUrl &localFileName,
const QString &jobId, const QString &hash,
const QString &key = QStringLiteral(""), const QString &iv = QStringLiteral(""));
Q_INVOKABLE KazvIOBaseJob *startNewUploadJob(
const QUrl &serverUrl, const QUrl &localFileName, const QString &token,
const QString &roomId, MatrixRoomList *roomList, const bool encrypted,
const QString &relType, const QString &relatedTo);
Q_INVOKABLE KazvIOBaseJob *startNewRoomlessUploadJob(const QUrl &serverUrl, const QUrl &localFileName, const QString &token);
Q_INVOKABLE KazvIOBaseJob *getCacheJob(const QString &jobId) const;
Q_INVOKABLE KazvIOBaseJob *getDownloadJob(const QString &jobId);
Q_INVOKABLE void deleteDownloadJob(const QString &jobId);
Q_INVOKABLE UploadJobModel *getUploadJobs(const QString &roomId);
Q_INVOKABLE void deleteUploadJob(const QString &roomId, KazvIOBaseJob *job);
Q_INVOKABLE void deleteRoomlessUploadJob(KazvIOBaseJob *job);
Q_INVOKABLE void deleteModelIfEmpty(const QString &roomId);
Q_INVOKABLE void clearJobs();
QString cacheDirectory() const;
void setCacheDirectory(QString cacheDirectory);
Q_SIGNALS:
void cacheDirectoryChanged();
};

File Metadata

Mime Type
text/x-diff
Expires
Thu, Oct 8, 10:11 PM (14 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1784314
Default Alt Text
(26 KB)

Event Timeline