#include "DownloadManager.h" void DownloadManager::downloadFile(QString name) { qDebug() << "Received downloadFile signal for:" << name; this->processDownloadRequest(name); } // ---------------------------------------------------------------------------------------- void DownloadManager::processDownloadRequest(QString& filename) { // Forge URL from the given filename and the base URL. QUrl u = this->baseUrl.resolved(filename); // If download in progress, enqueue file and return. if (dip) { qDebug() << "Download in progress! Enqueueing:" << u.toString() << "(" << dlQ.size() << "in queue)"; dlQ.enqueue(u); return; } // No running downloads: enqueue and start next download. dlQ.enqueue(u); qDebug() << "Enqueueing:" << u.toString() << endl; startNextDownload(); } // ---------------------------------------------------------------------------------------- void DownloadManager::startNextDownload() { qDebug() << "Starting next download: " << dlQ.head().toString() << "(" << dlQ.size() << "in queue.)"; // TODO: needed ? if (dlQ.isEmpty()) { qDebug() << "Download queue empty! Exiting..."; return; } // Dequeue next URL to download. QUrl url = dlQ.dequeue(); //qDebug() << "Dequeueing..." << url.toString(); // Extract the filename from the URL QString path = url.path(); QString basename = QFileInfo(path).fileName(); if (basename.isEmpty()) this->filename = "download"; else this->filename = basename; outfile.setFileName(this->filename); // If error upon opening, skip this file. if (!outfile.open(QIODevice::WriteOnly)) { qDebug() << "Couldn't open file! Exiting..."; startNextDownload(); return; } qDebug() << "spot 1"; // Start the request for this URL. QNetworkRequest request(url); currentDownload = qnam->get(request); if (currentDownload->error() != QNetworkReply::NoError) { 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(this->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) { 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()) qDebug() << "Downloaded " << currentDownload->url().toString() << endl; // Close output file. outfile.close(); // If queue is empty, we are done. // TODO: not sure if this is actually needed... dip = false; if (dlQ.isEmpty()) qDebug() << "dlQ empty! returning..."; return; // Queue not empty. // Delete current reply object. currentDownload->deleteLater(); // Initialise next download. ++downloaded; // qDebug() << "DM downloaded " << downloaded << "files"; startNextDownload(); } // ---------------------------------------------------------------------------------------- // Constructor. DownloadManager::DownloadManager(const QUrl& baseUrl) { this->qnam = new QNetworkAccessManager(); this->baseUrl = baseUrl; dip = false; downloaded = 0; } // Destructor. DownloadManager::~DownloadManager() { delete[] this->qnam; }