#include "downloadManager.h" #include #include int downloadManager::downloaded = 0; // ---------------------------------------------------------------------------------------- downloadManager::downloadManager() { qnam = new QNetworkAccessManager(); dip = false; infoSent = false; downloadDir = QDir(downloadPath); /* Check if downloadPath exists, if not create it. */ if (!downloadDir.exists()){ if (debug) qDebug() << "Download directory: " << downloadDir.path() << "doesn't exist."; QDir::current().mkdir(downloadPath); if (downloadDir.exists() && debug) qDebug() << "Created download directory: " << downloadDir.path(); } else if (debug) qDebug() << "Download directory: " << downloadDir.path() << "exists."; } // ---------------------------------------------------------------------------------------- void downloadManager::downloadFile(QString& filename) { if (debug) qDebug() << "Received downloadFile signal for:" << filename; QUrl fileUrl; fileUrl = baseURL.resolved(QUrl(filename)); if (debug) qDebug() << "fileUrl: " << fileUrl; this->processDownloadRequest(fileUrl); } // ---------------------------------------------------------------------------------------- void downloadManager::downloadFile(QUrl& fileUrl) { if (debug) qDebug() << "Received downloadFile signal for:" << fileUrl; this->processDownloadRequest(fileUrl); } // ---------------------------------------------------------------------------------------- void downloadManager::processDownloadRequest(QUrl& url) { if (url.isEmpty()){ if (debug) qDebug() << "No URL specified for download."; return; } /* 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 (dlQ.isEmpty()) { emit downloadQueueEmpty(); if (debug) qDebug() << "Download manager ready. (1)"; return; } if (debug) qDebug() << "Starting next download: " << dlQ.head().toString() << "(" << dlQ.size() << "in queue.)"; /* Dequeue next URL to download. */ QUrl url = dlQ.dequeue(); /* Get temporary filename from URL. */ QString tmp = url.path(); tmp.remove(0, tmp.lastIndexOf(QChar('/')) + 1); if (debug) qDebug() << "Extracted " << tmp << "from " << url.toString(); outfile.setFileName(downloadPath + "/" + tmp); if (!outfile.open(QIODevice::WriteOnly)) { if (debug) qDebug() << "Couldn't open file! Skipping..."; return; } /* Send the request for the file */ QNetworkRequest request(url); currentDownload = qnam->get(request); lastProgress = 0; currentProgress = 0; dip = true; dltime.start(); QObject::connect(currentDownload, SIGNAL(readyRead()), this, SLOT(downloadReady())); QObject::connect(currentDownload, SIGNAL(metaDataChanged()), this, SLOT(processMetaInfo())); QObject::connect(currentDownload, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgress(qint64, qint64))); QObject::connect(currentDownload, SIGNAL(finished()), this, SLOT(downloadFinished())); } // ---------------------------------------------------------------------------------------- // Private slots // ---------------------------------------------------------------------------------------- void downloadManager::processMetaInfo(){ const QByteArray cltag = "Content-Length"; QByteArray clinfo = currentDownload->rawHeader(cltag); qDebug() << "feel spammy?"; if (!infoSent){ if (debug) qDebug() << "MetaChanged: " << outfile.fileName() << ""; QFileInfo fi(outfile); emit downloadInfo(outfile.fileName(), clinfo.toDouble()); infoSent = true; } } // ---------------------------------------------------------------------------------------- void downloadManager::downloadReady() { /* Send file information */ /* Data ready, save it */ outfile.write(currentDownload->readAll()); } // ---------------------------------------------------------------------------------------- void downloadManager::downloadProgress(qint64 bytesIn, qint64 bytesTotal) { // "fix" for the weird bytesTotal = -1 initial reading... if (bytesIn > bytesTotal) return; /* Calculate current speed */ double speed = bytesIn * 1000 / dltime.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"; } /* Update progress only if difference higher than the updateInterval setting */ currentProgress = ((bytesIn * 100) / bytesTotal); if (currentProgress - lastProgress >= updateInterval){ lastProgress = currentProgress; emit updateProgress(currentProgress, speed, unit); if (debug) qDebug() << "Download progress of " << currentDownload->url().toString() << ": " << bytesIn << "/" << bytesTotal << "(" << currentProgress << "\%)"; } return; } // ---------------------------------------------------------------------------------------- void downloadManager::downloadFinished() { if (currentDownload->error()){ if (debug) qDebug() << "Download of" << currentDownload->url().toString() << "failed with status code: " << currentDownload->error(); currentDownload->deleteLater(); outfile.remove(); return; } // TODO Handle errors. if (debug) qDebug() << "NetworkCode: " << currentDownload->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); outfile.close(); currentDownload->deleteLater(); downloaded++; dip = false; infoSent = false; if (debug) qDebug() << "Download of " << currentDownload->url().toString() << "finished. (dlcount = "<< downloaded << ")"; if (dlQ.isEmpty()){ emit downloadQueueEmpty(); if (debug) qDebug() << "Download manager ready. (2)"; return; } startNextDownload(); } /* ---------------------------------------------------------------------------------------- * ** dead code: Header filename fetching & renaming ** const QByteArray cd = "Content-Disposition"; QByteArray cdc = currentDownload->rawHeader(cd); int x = cdc.indexOf("filename=\"") + 10; cdc.remove(0, x).chop(1); if (!cdc.isEmpty()) currentTargetFilename = cdc; else currentTargetFilename = QString("download.\%1").arg(downloaded); QString tmp = outfile.fileName(); tmp.remove(0, tmp.lastIndexOf(QChar('/')) + 1); qDebug() << "Trying to rename " << tmp << " to --> " << currentTargetFilename; if (outfile.rename(downloadPath + "/" + currentTargetFilename)) { if (debug) qDebug() << "Renamed file!"; } else { if (debug) qDebug() << "Failure to rename file!"; } */