#include "DownloadManager.h" int DownloadManager::downloaded = 0; // ---------------------------------------------------------------------------------------- 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(); tmp.remove(0, tmp.lastIndexOf(QChar('/')) + 1); outfile.setFileName(downloadDirectory.path() + "/" + tmp); if (debug) qDebug() << "DM: Absolute path: " << downloadDirectory.path() + "/" + tmp; if (outfile.exists()){ if (debug) qDebug() << "File already exists. Skipping: " << url.toString(); startNextDownload(); return; } // 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. if (debug) qDebug() << "Saving " << url.toString() << "to " << outfile.fileName(); 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; }