//HEADER FILE
#ifndef DOWNLOADMANAGER_H
#define DOWNLOADMANAGER_H
#include <QFile>
#include <QObject>
#include <QQueue>
#include <QTime>
#include <QUrl>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QSslError>
#include <QtNetwork/QAuthenticator>
class DownloadManager: public QObject
{
Q_OBJECT
public:
DownloadManager(QObject *parent = 0);
void appendToQueue(const QUrl &url);
void appendToQueue(const QStringList &urlList,const QString &sTargetFolder);
QString getTargetFolder();
void setTargetFolder(const QString &strTargetFolder);
Q_SIGNALS:
void finished();
void downloadComplete(bool,QString);
private slots:
void startNextDownload();
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
void downloadFinished();
void downloadReadyRead();
void errorNetworkReply(QNetworkReply::NetworkError);
void authenticationRequired(QNetworkReply*,QAuthenticator*);
void sslErrors(QNetworkReply*,QList<QSslError>);
bool isDownloadDone();
QString saveFileName(const QUrl &url);
private:
QString m_sTargetFolder;
QNetworkAccessManager manager;
QQueue<QUrl> downloadQueue;
QNetworkReply *currentDownload;
QFile output;
QTime downloadTime;
int downloadedCount;
int totalCount;
};
#endif
//CPP FILE
#include "downloadmanager.h"
#include <QFileInfo>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include <QString>
#include <QStringList>
#include <QTimer>
#include <QDebug>
#include <QDir>
DownloadManager::DownloadManager(QObject *parent)
: QObject(parent), downloadedCount(0), totalCount(0)
{
}
void DownloadManager::sslErrors(QNetworkReply*,QList<QSslError>)
{
//FIXME: implement this
}
void DownloadManager::appendToQueue(const QStringList &urlList,const QString &sTargetFolder)
{
setTargetFolder(sTargetFolder);
foreach (QString url, urlList)
{
if(!url.isEmpty())
appendToQueue(QUrl::fromEncoded(url.toLocal8Bit(),QUrl::StrictMode));
}
if (downloadQueue.isEmpty())
QTimer::singleShot(0, this, SIGNAL(finished()));
}
void DownloadManager::appendToQueue(const QUrl &url)
{
if (downloadQueue.isEmpty())
QTimer::singleShot(0, this, SLOT(startNextDownload()));
downloadQueue.enqueue(url);
++totalCount;
}
QString DownloadManager::saveFileName(const QUrl &url)
{
QString path = url.path();
path.replace('/','_');
return m_sTargetFolder + "/" + path;
}
void DownloadManager::startNextDownload()
{
if (downloadQueue.isEmpty()) {
qDebug() << QString("%1/%2 files downloaded successfully\n").arg(downloadedCount).arg(totalCount);
emit finished();
return;
}
QUrl url = downloadQueue.dequeue();
QString filename = saveFileName(url);
output.setFileName(filename);
if (!output.open(QIODevice::WriteOnly)) {
fprintf(stderr, "Problem opening save file '%s' for download '%s': %s\n",
qPrintable(filename), url.toEncoded().constData(),
qPrintable(output.errorString()));
startNextDownload();
return; // skip this download
}
QNetworkRequest request(url);
currentDownload = manager.get(request);
connect(currentDownload,SIGNAL(error(QNetworkReply::NetworkError)),this,
SLOT(errorNetworkReply(QNetworkReply::NetworkError)));
connect(currentDownload, SIGNAL(downloadProgress(qint64,qint64)),
SLOT(downloadProgress(qint64,qint64)));
connect(currentDownload, SIGNAL(finished()),
SLOT(downloadFinished()));
connect(currentDownload, SIGNAL(readyRead()),
SLOT(downloadReadyRead()));
// connect(&manager,SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
// SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*)));
connect(&manager,SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),SLOT(sslErrors(QNetworkReply*,QList<QSslError>)));
// prepare the output
printf("Downloading %s...\n", url.toEncoded().constData());
downloadTime.start();
}
void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
qDebug() << QString("\n%1 data of %2 downloaded").arg(QString::number(bytesReceived)).arg(QString::number(bytesTotal));
}
void DownloadManager::downloadFinished()
{
output.close();
if (currentDownload->error()) {
// download failed
qDebug() << L"Download Status : Failed. \t Error Msg : " << currentDownload->errorString();
emit downloadComplete(false,QFileInfo(output).absoluteFilePath());
} else {
++downloadedCount;
qDebug() << L"Download Status : Succeeded." ;
emit downloadComplete(true,QFileInfo(output).absoluteFilePath());
}
currentDownload->deleteLater();
startNextDownload();
}
void DownloadManager::downloadReadyRead()
{
output.write(currentDownload->readAll());
}
//void DownloadManager::networkAccessibleChangedSlot(QNetworkAccessManager::NetworkAccessibility access)
//{
//
// if(access == QNetworkAccessManager::NotAccessible)
// qDebug() << "\n Net gone...................:)";
//}
void DownloadManager::errorNetworkReply(QNetworkReply::NetworkError code)
{
qDebug() << "\nNetwork Error : " + QString::number(code);
}
void DownloadManager::setTargetFolder(const QString &strTargetFolder)
{
m_sTargetFolder = strTargetFolder;
QDir dirTarget;
if(!dirTarget.exists())
dirTarget.mkpath(sTargetFolder);
}
QString DownloadManager::getTargetFolder()
{
return m_sTargetFolder;
}
bool DownloadManager::isDownloadDone()
{
return totalCount == downloadedCount;
}
void DownloadManager::authenticationRequired(QNetworkReply *reply,QAuthenticator *auth)
{
if(reply && reply->isRunning())
{
auth->setUser(reply->url().userName());
auth->setPassword(reply->url().password());
}
}