DownloadManager.cpp Example File
downloadmanager/src/DownloadManager.cpp
#include "DownloadManager.hpp"
#include <QtCore/QFileInfo>
#include <QtCore/QTimer>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkRequest>
DownloadManager::DownloadManager(QObject *parent)
: QObject(parent), m_currentDownload(0), m_downloadedCount(0), m_totalCount(0), m_progressTotal(0), m_progressValue(0)
{
}
QString DownloadManager::errorMessage() const
{
return m_errorMessage.join("\n");
}
QString DownloadManager::statusMessage() const
{
return m_statusMessage.join("\n");
}
int DownloadManager::activeDownloads() const
{
return m_downloadQueue.count();
}
int DownloadManager::progressTotal() const
{
return m_progressTotal;
}
int DownloadManager::progressValue() const
{
return m_progressValue;
}
QString DownloadManager::progressMessage() const
{
return m_progressMessage;
}
void DownloadManager::downloadUrl(const QString &url)
{
append(QUrl(url));
}
void DownloadManager::append(const QUrl &url)
{
if (m_downloadQueue.isEmpty() && !m_currentDownload)
QTimer::singleShot(0, this, SLOT(startNextDownload()));
m_downloadQueue.enqueue(url);
emit activeDownloadsChanged();
++m_totalCount;
}
QString DownloadManager::saveFileName(const QUrl &url)
{
const QString path = url.path();
QString basename = QFileInfo(path).fileName();
if (basename.isEmpty())
basename = "download";
basename = "tmp/" + basename;
if (QFile::exists(basename)) {
int i = 0;
basename += '.';
while (QFile::exists(basename + QString::number(i)))
++i;
basename += QString::number(i);
}
return basename;
}
void DownloadManager::addErrorMessage(const QString &message)
{
m_errorMessage.append(message);
emit errorMessageChanged();
}
void DownloadManager::addStatusMessage(const QString &message)
{
m_statusMessage.append(message);
emit statusMessageChanged();
}
void DownloadManager::startNextDownload()
{
if (m_downloadQueue.isEmpty()) {
addStatusMessage(QString("%1/%2 files downloaded successfully").arg(m_downloadedCount).arg(m_totalCount));
return;
}
const QUrl url = m_downloadQueue.dequeue();
const QString filename = saveFileName(url);
m_output.setFileName(filename);
if (!m_output.open(QIODevice::WriteOnly)) {
addErrorMessage(QString("Problem opening save file '%1' for download '%2': %3").arg(filename, url.toString(), m_output.errorString()));
startNextDownload();
return;
}
QNetworkRequest request(url);
m_currentDownload = m_manager.get(request);
connect(m_currentDownload, SIGNAL(downloadProgress(qint64, qint64)),
SLOT(downloadProgress(qint64, qint64)));
connect(m_currentDownload, SIGNAL(finished()), SLOT(downloadFinished()));
connect(m_currentDownload, SIGNAL(readyRead()), SLOT(downloadReadyRead()));
addStatusMessage(QString("Downloading %1...").arg(url.toString()));
m_downloadTime.start();
}
void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
m_progressTotal = bytesTotal;
m_progressValue = bytesReceived;
emit progressTotalChanged();
emit progressValueChanged();
double speed = bytesReceived * 1000.0 / m_downloadTime.elapsed();
QString unit;
if (speed < 1024) {
unit = "bytes/sec";
} else if (speed < 1024 * 1024) {
speed /= 1024;
unit = "kB/s";
} else {
speed /= 1024 * 1024;
unit = "MB/s";
}
m_progressMessage = QString("%1 %2").arg(speed, 3, 'f', 1).arg(unit);
emit progressMessageChanged();
}
void DownloadManager::downloadFinished()
{
m_progressTotal = 0;
m_progressValue = 0;
m_progressMessage.clear();
emit progressValueChanged();
emit progressTotalChanged();
emit progressMessageChanged();
m_output.close();
if (m_currentDownload->error()) {
addErrorMessage(QString("Failed: %1").arg(m_currentDownload->errorString()));
} else {
addStatusMessage("Succeeded.");
++m_downloadedCount;
}
m_currentDownload->deleteLater();
m_currentDownload = 0;
emit activeDownloadsChanged();
startNextDownload();
}
void DownloadManager::downloadReadyRead()
{
m_output.write(m_currentDownload->readAll());
}