1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
#include "DownloadManager.h"
// ----------------------------------------------------------------------------------------
void DownloadManager::downloadFile(QString& filename){
if (debug) qDebug() << "DM received signal for: " << filename;
QUrl fileUrl;
fileUrl = baseURL.resolved(QUrl(filename));
this->processDownloadRequest(fileUrl);
}
// ----------------------------------------------------------------------------------------
void DownloadManager::downloadFile(QUrl& fileUrl){
if (debug) qDebug() << "Received downloadFile signal for:" << fileUrl;
this->processDownloadRequest(fileUrl);
}
// ----------------------------------------------------------------------------------------
void DownloadManager::processDownloadRequest(QUrl& url)
{
// Forge URL from the given filename and the base URL.
// If download in progress, enqueue file and return.
if (dip)
{
if (debug) qDebug() << "Download in progress! Enqueueing:" << url.toString()
<< "(" << dlQ.size() << "in queue)";
dlQ.enqueue(url);
return;
}
// No running downloads: enqueue and start next download.
dlQ.enqueue(url);
if (debug) qDebug() << "Enqueueing:" << url.toString() << endl;
startNextDownload();
}
// ----------------------------------------------------------------------------------------
void DownloadManager::startNextDownload()
{
if (debug) qDebug() << "Starting next download: " << dlQ.head().toString()
<< "(" << dlQ.size() << "in queue.)";
if (dlQ.isEmpty())
{
if (debug) qDebug() << "Download queue empty! Exiting...";
return;
}
// Dequeue next URL to download.
QUrl url = dlQ.dequeue();
// Get filename from URL.
QString tmp = url.path();
outfile.setFileName(tmp.remove(0, tmp.lastIndexOf(QChar('/')) + 1));
// If error upon opening, skip this file.
if (!outfile.open(QIODevice::WriteOnly))
{
if (debug) qDebug() << "Couldn't open file! Exiting...";
startNextDownload();
return;
}
// Start the request for this URL.
QNetworkRequest request(url);
currentDownload = qnam->get(request);
// TODO: Error handling not working properly...
if (currentDownload->error() != QNetworkReply::NoError)
{
if (debug) qDebug() << "Network reply error, skipping download...";
return;
}
dip = true;
QObject::connect(currentDownload, SIGNAL(readyRead()), this, SLOT(downloadReady()));
QObject::connect(currentDownload, SIGNAL(downloadProgress(qint64, qint64)),
this, SLOT(downloadProgress(qint64, qint64)));
QObject::connect(currentDownload, SIGNAL(finished()), this, SLOT(downloadFinished()));
}
// ----------------------------------------------------------------------------------------
// Slots for the signals emmited by currentDownload.
// ----------------------------------------------------------------------------------------
// This slot listens to readyRead() emmited when data is available for reading.
void DownloadManager::downloadReady()
{
// readyRead() fired, so save the readable data.
outfile.write(currentDownload->readAll());
}
// ----------------------------------------------------------------------------------------
// This slot listens to the downloadProgress(..)
// which provides information on the download progress of the file.
void DownloadManager::downloadProgress(qint64 bytesIn, qint64 bytesTotal)
{
if (debug) qDebug() << "Download progress of " << currentDownload->url().toString()
<< ": " << bytesIn << "/" << bytesTotal;
qint64 tmp = ((bytesIn * 100) / bytesTotal);
emit updateProgress((int)tmp);
}
// ----------------------------------------------------------------------------------------
// This slot listens to the finished() which is emmited
// when all the data from the reply has been read.
void DownloadManager::downloadFinished()
{
// Second check if the download actually is finished.
if (currentDownload->isFinished())
if (debug) qDebug() << "Download of " << currentDownload->url().toString()
<< "finished." << endl;
// Close output file.
outfile.close();
currentDownload->deleteLater();
++downloaded;
// If queue is empty, we are done.
dip = false;
if (dlQ.isEmpty())
return;
// Queue not empty: initialise next download.
startNextDownload();
}
// ----------------------------------------------------------------------------------------
// Constructor.
DownloadManager::DownloadManager()
{
qnam = new QNetworkAccessManager();
dip = false;
downloaded = 0;
}
|