Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit b3e63b4b authored by Linus Jahn's avatar Linus Jahn Committed by Jonah Brüchert

Clean up DownloadManager and TransferCache

parent 511518ca
Pipeline #28153 passed with stages
in 28 minutes and 46 seconds
......@@ -67,8 +67,7 @@ ClientWorker::ClientWorker(Caches *caches, Kaidan *kaidan, bool enableLogging, Q
m_msgHandler = new MessageHandler(kaidan, this, m_client, caches->msgModel);
m_discoManager = new DiscoveryManager(m_client, this);
m_uploadManager = new UploadManager(m_client, m_rosterManager, this);
m_downloadManager = new DownloadManager(kaidan, caches->transferCache,
caches->msgModel, this);
m_downloadManager = new DownloadManager(caches->transferCache, caches->msgModel, this);
connect(m_client, &QXmppClient::presenceReceived,
caches->presCache, &PresenceCache::updatePresence);
......@@ -358,7 +357,7 @@ void ClientWorker::setIsApplicationWindowActive(bool active)
m_isApplicationWindowActive = active;
}
QString ClientWorker::generateJidResourceWithRandomSuffix(const QString jidResourcePrefix , unsigned int length) const
QString ClientWorker::generateJidResourceWithRandomSuffix(const QString jidResourcePrefix, unsigned int length) const
{
return jidResourcePrefix % "." % QXmppUtils::generateStanzaHash(length);
}
......@@ -28,12 +28,7 @@
* along with Kaidan. If not, see <http://www.gnu.org/licenses/>.
*/
// Kaidan
#include "DownloadManager.h"
#include "Globals.h"
#include "Kaidan.h"
#include "MessageModel.h"
#include "TransferCache.h"
// C++
#include <utility>
// Qt
......@@ -42,52 +37,48 @@
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QStandardPaths>
// Kaidan
#include "Globals.h"
#include "Kaidan.h"
#include "MessageModel.h"
#include "TransferCache.h"
DownloadManager::DownloadManager(Kaidan *kaidan, TransferCache *transferCache,
MessageModel *model, QObject *parent)
: QObject(parent), thread(new DownloadThread()),
netMngr(new QNetworkAccessManager), kaidan(kaidan),
transferCache(transferCache), model(model)
DownloadManager::DownloadManager(TransferCache *transferCache, MessageModel *model, QObject *parent)
: QObject(parent),
m_netMngr(new QNetworkAccessManager(this)),
m_transferCache(transferCache),
m_model(model)
{
connect(this, &DownloadManager::startDownloadRequested,
this, &DownloadManager::startDownload);
connect(this, &DownloadManager::abortDownloadRequested,
this, &DownloadManager::abortDownload);
connect(kaidan, &Kaidan::downloadMedia, this, &DownloadManager::startDownload);
connect(this, &DownloadManager::abortDownloadRequested, this, &DownloadManager::abortDownload);
netMngr->moveToThread(thread);
thread->start();
connect(Kaidan::instance(), &Kaidan::downloadMedia, this, &DownloadManager::startDownload);
}
DownloadManager::~DownloadManager()
{
delete netMngr;
delete thread;
}
void DownloadManager::startDownload(const QString &msgId, const QString &url)
{
// don't download the same file twice and in parallel
if (downloads.contains(msgId)) {
if (m_downloads.contains(msgId)) {
qWarning() << "Tried to download a file that is currently being "
"downloaded.";
return;
}
// we want to save files to 'Downloads/Kaidan/'
QString dirPath =
QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)
+ QDir::separator() + APPLICATION_DISPLAY_NAME + QDir::separator();
QString dirPath = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) +
QDir::separator() + APPLICATION_DISPLAY_NAME + QDir::separator();
DownloadJob *dl = new DownloadJob(msgId, QUrl(url), dirPath, netMngr,
transferCache, kaidan);
dl->moveToThread(thread);
downloads[msgId] = dl;
auto *dl = new DownloadJob(msgId, QUrl(url), dirPath, m_netMngr, m_transferCache);
m_downloads[msgId] = dl;
connect(dl, &DownloadJob::finished, this, [=]() {
const QString mediaLocation = dl->downloadLocation();
emit model->updateMessageRequested(msgId, [=] (Message &msg) {
const QString &mediaLocation = dl->downloadLocation();
emit m_model->updateMessageRequested(msgId, [=] (Message &msg) {
msg.setMediaLocation(mediaLocation);
});
......@@ -102,26 +93,24 @@ void DownloadManager::startDownload(const QString &msgId, const QString &url)
void DownloadManager::abortDownload(const QString &msgId)
{
DownloadJob *job = downloads.value(msgId);
delete job;
downloads.remove(msgId);
auto *job = m_downloads.value(msgId);
job->deleteLater();
m_downloads.remove(msgId);
emit transferCache->removeJobRequested(msgId);
emit m_transferCache->removeJobRequested(msgId);
}
DownloadJob::DownloadJob(QString msgId,
QUrl source,
QString filePath,
QNetworkAccessManager *netMngr,
TransferCache *transferCache,
Kaidan *kaidan)
: QObject(nullptr),
msgId(std::move(msgId)),
source(std::move(source)),
filePath(std::move(filePath)),
netMngr(netMngr),
transferCache(transferCache),
kaidan(kaidan)
DownloadJob::DownloadJob(const QString &msgId,
const QUrl &source,
const QString &filePath,
QNetworkAccessManager *netMngr,
TransferCache *transferCache)
: QObject(nullptr),
m_msgId(msgId),
m_source(source),
m_filePath(filePath),
m_netMngr(netMngr),
m_transferCache(transferCache)
{
connect(this, &DownloadJob::startDownloadRequested,
this, &DownloadJob::startDownload);
......@@ -129,54 +118,51 @@ DownloadJob::DownloadJob(QString msgId,
void DownloadJob::startDownload()
{
QDir dlDir(filePath);
QDir dlDir(m_filePath);
if (!dlDir.exists())
dlDir.mkpath(".");
// don't override other files
file.setFileName(filePath + source.fileName());
m_file.setFileName(m_filePath + m_source.fileName());
int counter = 1;
while (file.exists()) {
file.setFileName(filePath + source.fileName() + "-"
+ QString::number(counter++));
while (m_file.exists()) {
m_file.setFileName(
m_filePath + m_source.fileName() + "-" + QString::number(counter++));
}
if (!file.open(QIODevice::WriteOnly)) {
qWarning() << "Could not open file for writing:"
<< file.errorString();
emit kaidan->passiveNotificationRequested(
tr("Could not save file: %1").arg(file.errorString()));
if (!m_file.open(QIODevice::WriteOnly)) {
qWarning() << "Could not open file for writing:" << m_file.errorString();
emit Kaidan::instance()->passiveNotificationRequested(
tr("Could not save file: %1").arg(m_file.errorString()));
emit failed();
return;
}
QNetworkRequest request(source);
QNetworkReply *reply = netMngr->get(request);
QNetworkRequest request(m_source);
QNetworkReply *reply = m_netMngr->get(request);
emit transferCache->addJobRequested(msgId, 0);
emit m_transferCache->addJobRequested(m_msgId, 0);
connect(reply, &QNetworkReply::downloadProgress,
this, [this] (qint64 bytesReceived, qint64 bytesTotal) {
emit transferCache->setJobProgressRequested(msgId, bytesReceived, bytesTotal);
connect(reply, &QNetworkReply::downloadProgress, this, [this](qint64 bytesReceived, qint64 bytesTotal) {
emit m_transferCache->setJobProgressRequested(m_msgId, bytesReceived, bytesTotal);
});
connect(reply, &QNetworkReply::finished, this, [=] () {
emit transferCache->removeJobRequested(msgId);
connect(reply, &QNetworkReply::finished, this, [=]() {
emit m_transferCache->removeJobRequested(m_msgId);
emit finished();
});
connect(reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
this, [=] () {
emit transferCache->removeJobRequested(msgId);
connect(reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error), this, [=]() {
emit m_transferCache->removeJobRequested(m_msgId);
qWarning() << "Couldn't download file:" << reply->errorString();
emit kaidan->passiveNotificationRequested(
tr("Download failed: %1").arg(reply->errorString()));
emit Kaidan::instance()->passiveNotificationRequested(
tr("Download failed: %1").arg(reply->errorString()));
emit finished();
});
connect(reply, &QNetworkReply::readyRead, this, [=](){
file.write(reply->readAll());
connect(reply, &QNetworkReply::readyRead, this, [=]() {
m_file.write(reply->readAll());
});
}
QString DownloadJob::downloadLocation() const
{
return file.fileName();
return m_file.fileName();
}
......@@ -45,12 +45,11 @@ class DownloadJob : public QObject
{
Q_OBJECT
public:
DownloadJob(QString msgId,
QUrl source,
QString filePath,
QNetworkAccessManager *netMngr,
TransferCache *transferCache,
Kaidan *kaidan);
DownloadJob(const QString &msgId,
const QUrl &source,
const QString &filePath,
QNetworkAccessManager *netMngr,
TransferCache *transferCache);
QString downloadLocation() const;
......@@ -63,53 +62,33 @@ private slots:
void startDownload();
private:
QString msgId;
QUrl source;
QString filePath;
QNetworkAccessManager *netMngr;
TransferCache *transferCache;
Kaidan *kaidan;
QFile file;
};
class DownloadThread : public QThread
{
Q_OBJECT
public:
DownloadThread()
{
setObjectName("DownloadManager");
}
protected:
void run() override
{
exec();
}
QString m_msgId;
QUrl m_source;
QString m_filePath;
QNetworkAccessManager *m_netMngr;
TransferCache *m_transferCache;
QFile m_file;
};
class DownloadManager : public QObject
{
Q_OBJECT
public:
DownloadManager(Kaidan *kaidan, TransferCache *transferCache,
MessageModel *model, QObject *parent = nullptr);
DownloadManager(TransferCache *m_transferCache, MessageModel *m_model, QObject *parent = nullptr);
~DownloadManager();
signals:
void startDownloadRequested(const QString msgId, const QString url);
void abortDownloadRequested(const QString msgId);
void startDownloadRequested(const QString &msgId, const QString &url);
void abortDownloadRequested(const QString &msgId);
public slots:
void startDownload(const QString &msgId, const QString &url);
void abortDownload(const QString &msgId);
private:
DownloadThread *thread;
QNetworkAccessManager *netMngr;
Kaidan *kaidan;
TransferCache *transferCache;
MessageModel *model;
QNetworkAccessManager *m_netMngr;
TransferCache *m_transferCache;
MessageModel *m_model;
QMap<QString, DownloadJob*> downloads;
QMap<QString, DownloadJob *> m_downloads;
};
......@@ -33,36 +33,38 @@
#include <QMutexLocker>
TransferJob::TransferJob(qint64 bytesTotal)
: progress(0.0), bytesSent(0), bytesTotal(bytesTotal)
: m_progress(0.0), m_bytesSent(0), m_bytesTotal(bytesTotal)
{
}
void TransferJob::setProgress(qreal progress)
{
if (this->progress == progress)
if (m_progress == progress)
return;
this->progress = progress;
m_progress = progress;
emit progressChanged();
}
void TransferJob::setBytesSent(qint64 bytesSent)
{
if (this->bytesSent == bytesSent)
if (m_bytesSent == bytesSent)
return;
this->bytesSent = bytesSent;
m_bytesSent = bytesSent;
emit bytesSentChanged();
if (bytesTotal != 0)
setProgress(qreal(bytesSent) / qreal(bytesTotal));
if (m_bytesTotal != 0)
setProgress(qreal(bytesSent) / qreal(m_bytesTotal));
}
void TransferJob::setBytesTotal(qint64 bytesTotal)
{
if (this->bytesTotal == bytesTotal)
if (m_bytesTotal == bytesTotal)
return;
this->bytesTotal = bytesTotal;
m_bytesTotal = bytesTotal;
emit bytesTotalChanged();
if (bytesTotal != 0)
setProgress(qreal(bytesSent) / qreal(bytesTotal));
setProgress(qreal(m_bytesSent) / qreal(bytesTotal));
}
TransferCache::TransferCache(QObject *parent)
......@@ -80,13 +82,13 @@ TransferCache::TransferCache(QObject *parent)
TransferCache::~TransferCache()
{
// wait for other threads to finish
QMutexLocker locker(&mutex);
QMutexLocker locker(&m_mutex);
}
void TransferCache::addJob(const QString& msgId, qint64 bytesTotal)
{
QMutexLocker locker(&mutex);
uploads.insert(msgId, new TransferJob(bytesTotal));
QMutexLocker locker(&m_mutex);
m_uploads.insert(msgId, new TransferJob(bytesTotal));
locker.unlock();
emit jobsChanged();
......@@ -94,9 +96,9 @@ void TransferCache::addJob(const QString& msgId, qint64 bytesTotal)
void TransferCache::removeJob(const QString& msgId)
{
QMutexLocker locker(&mutex);
delete uploads[msgId];
uploads.remove(msgId);
QMutexLocker locker(&m_mutex);
auto upload = m_uploads.take(msgId);
upload->deleteLater();
locker.unlock();
emit jobsChanged();
......@@ -104,16 +106,16 @@ void TransferCache::removeJob(const QString& msgId)
bool TransferCache::hasUpload(QString msgId) const
{
QMutexLocker locker(&mutex);
return uploads.contains(msgId);
QMutexLocker locker(&m_mutex);
return m_uploads.contains(msgId);
}
TransferJob* TransferCache::jobByMessageId(QString msgId) const
{
QMutexLocker locker(&mutex);
TransferJob* job = uploads.value(msgId);
QMutexLocker locker(&m_mutex);
TransferJob *job = m_uploads.value(msgId);
if (job == nullptr)
return emptyJob;
return m_emptyJob;
return job;
}
......@@ -121,7 +123,7 @@ void TransferCache::setJobProgress(const QString &msgId, qint64 bytesSent, qint6
{
TransferJob* job = jobByMessageId(msgId);
QMutexLocker locker(&mutex);
QMutexLocker locker(&m_mutex);
job->setBytesTotal(bytesTotal);
job->setBytesSent(bytesSent);
}
......@@ -130,6 +132,6 @@ void TransferCache::setJobBytesSent(const QString &msgId, qint64 bytesSent)
{
TransferJob* job = jobByMessageId(msgId);
QMutexLocker locker(&mutex);
QMutexLocker locker(&m_mutex);
job->setBytesSent(bytesSent);
}
......@@ -40,16 +40,16 @@
class TransferJob : public QObject
{
Q_OBJECT
Q_PROPERTY(qreal progress MEMBER progress NOTIFY progressChanged)
Q_PROPERTY(qint64 bytesSent MEMBER bytesSent NOTIFY bytesSentChanged)
Q_PROPERTY(qint64 bytesTotal MEMBER bytesTotal NOTIFY bytesTotalChanged)
Q_PROPERTY(qreal progress MEMBER m_progress NOTIFY progressChanged)
Q_PROPERTY(qint64 bytesSent MEMBER m_bytesSent NOTIFY bytesSentChanged)
Q_PROPERTY(qint64 bytesTotal MEMBER m_bytesTotal NOTIFY bytesTotalChanged)
public:
TransferJob(qint64 bytesTotal);
Q_INVOKABLE void setProgress(qreal progress);
Q_INVOKABLE void setBytesSent(qint64 bytesSent);
Q_INVOKABLE void setBytesTotal(qint64 bytesTotal);
Q_INVOKABLE void setProgress(qreal m_progress);
Q_INVOKABLE void setBytesSent(qint64 m_bytesSent);
Q_INVOKABLE void setBytesTotal(qint64 m_bytesTotal);
signals:
void progressChanged();
......@@ -57,9 +57,9 @@ signals:
void bytesTotalChanged();
private:
qreal progress;
qint64 bytesSent;
qint64 bytesTotal;
qreal m_progress;
qint64 m_bytesSent;
qint64 m_bytesTotal;
};
/**
......@@ -86,11 +86,10 @@ public:
Q_INVOKABLE TransferJob* jobByMessageId(QString msgId) const;
public slots:
Q_INVOKABLE void addJob(const QString &msgId, qint64 bytesTotal);
Q_INVOKABLE void removeJob(const QString& msgId);
Q_INVOKABLE void setJobBytesSent(const QString& msgId, qint64 bytesSent);
Q_INVOKABLE void setJobProgress(const QString& msgId, qint64 bytesSent,
qint64 bytesTotal);
void addJob(const QString &msgId, qint64 bytesTotal);
void removeJob(const QString &msgId);
void setJobBytesSent(const QString &msgId, qint64 bytesSent);
void setJobProgress(const QString &msgId, qint64 bytesSent, qint64 bytesTotal);
signals:
/**
......@@ -105,8 +104,8 @@ signals:
qint64 bytesTotal);
private:
QMap<QString, TransferJob*> uploads;
TransferJob* emptyJob;
QMap<QString, TransferJob *> m_uploads;
TransferJob *m_emptyJob;
mutable QMutex mutex;
mutable QMutex m_mutex;
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment