summaryrefslogtreecommitdiffstats
path: root/src/downloadmanager.cpp
diff options
context:
space:
mode:
authorJonathan Bauer2011-03-21 11:48:32 +0100
committerJonathan Bauer2011-03-21 11:48:32 +0100
commit31050528017e11c54f408b22c92265ff6c4c4b69 (patch)
treeb3a83fc05f53548a7c6beb29b9b0d971b9c49cc3 /src/downloadmanager.cpp
parentminor code convention fixes (diff)
downloadfbgui-31050528017e11c54f408b22c92265ff6c4c4b69.tar.gz
fbgui-31050528017e11c54f408b22c92265ff6c4c4b69.tar.xz
fbgui-31050528017e11c54f408b22c92265ff6c4c4b69.zip
and the files ^^
Diffstat (limited to 'src/downloadmanager.cpp')
-rw-r--r--src/downloadmanager.cpp214
1 files changed, 214 insertions, 0 deletions
diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp
new file mode 100644
index 0000000..47582c8
--- /dev/null
+++ b/src/downloadmanager.cpp
@@ -0,0 +1,214 @@
+#include "downloadmanager.h"
+#include "fbgui.h"
+
+int DownloadManager::downloaded = 0;
+// ----------------------------------------------------------------------------------------
+DownloadManager::DownloadManager(){
+ qxtLog->debug() << "Initializing download manager...";
+ checkDownloadDirectory();
+ qnam = new QNetworkAccessManager();
+ dip = false;
+}
+// ----------------------------------------------------------------------------------------
+void DownloadManager::checkDownloadDirectory()
+{
+ // check if downloadPath exists, if not create it.
+ downloadDir = QDir(downloadPath);
+ if (!downloadDir.exists()){
+ qxtLog->debug() << "Download directory: " << downloadDir.path() << " doesn't exist.";
+ QDir::current().mkdir(downloadPath);
+ if (downloadDir.exists()){
+ qxtLog->debug() << "Created download directory: " << downloadDir.path();
+ }
+ else {
+ qxtLog->debug() << "Failed to create directory: " << downloadDir.path();
+ // try to save to /tmp/fbgui
+ downloadDir.setPath(QDir::tempPath () + "/fbgui");
+ if (!downloadDir.exists()){
+ QDir::current().mkdir(QDir::tempPath () + "/fbgui");
+ if (!downloadDir.exists()){
+ // TODO: dont exit, this shouldn't happen anyway (right?)
+ qxtLog->debug() << "Fatal, no target for downloads. Exiting...";
+ exit(EXIT_FAILURE);
+ }
+ }
+ qxtLog->debug() << "Saving downloads to: " << downloadDir.absolutePath();
+ }
+ }
+ else qxtLog->debug() << "Download directory: " << downloadDir.path() << " exists.";
+}
+// ----------------------------------------------------------------------------------------
+void DownloadManager::downloadFile(const QString& filename)
+{
+ QUrl fileUrl(baseURL.resolved(QUrl(filename)));
+ this->processDownloadRequest(fileUrl);
+}
+// ----------------------------------------------------------------------------------------
+void DownloadManager::downloadFile(const QUrl& fileUrl)
+{
+ this->processDownloadRequest(fileUrl);
+}
+// ----------------------------------------------------------------------------------------
+void DownloadManager::processDownloadRequest(const QUrl& url)
+{
+ if (url.isEmpty()){
+ qxtLog->debug() << "No URL specified for download.";
+ return;
+ }
+ // if download in progress, enqueue file and return.
+ if (dip){
+ dlQ.enqueue(url);
+ qxtLog->debug() << "Download in progress! Queued:" << url.toString()
+ << "(" << dlQ.size() << " in queue)";
+ return;
+ }
+ // no running downloads: enqueue and start next download.
+ dlQ.enqueue(url);
+ qxtLog->debug() << "Enqueueing:" << url.toString();
+ startNextDownload();
+}
+// ----------------------------------------------------------------------------------------
+void DownloadManager::startNextDownload()
+{
+ if (dlQ.isEmpty()){
+ emit downloadQueueEmpty();
+ qxtLog->debug() << "Download manager ready. (1)";
+ return;
+ }
+ qxtLog->debug() << "Starting next download: " << dlQ.head().toString()
+ << " (" << dlQ.size() - 1 << " in queue.)";
+
+ // dequeue next URL to download.
+ QUrl url = dlQ.dequeue();
+
+ // get filename from URL.
+ QString tmp = url.path();
+ tmp.remove(0, tmp.lastIndexOf(QChar('/')) + 1);
+
+ // check if filename exists on target file system
+ if (downloadDir.exists(tmp)){
+ qxtLog->debug() << "File already exists: " << downloadDir.absoluteFilePath(tmp);
+ outfile.setFileName(QString(downloadDir.absolutePath() + "/" + tmp + ".\%1").arg(downloaded));
+ }
+ else
+ outfile.setFileName(downloadDir.absoluteFilePath(tmp));
+ qxtLog->debug() << "Saving to: " << outfile.fileName();
+
+ // try to open for writing
+ if (!outfile.open(QIODevice::WriteOnly)){
+ qxtLog->debug() << "No write access to " << outfile.fileName() << " . Skipping download...";
+ 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 to process downloads
+// ----------------------------------------------------------------------------------------
+void DownloadManager::processMetaInfo()
+{
+ // fetch filesize from header & filename from URL (for now)
+ const QByteArray cltag = "Content-Length";
+ QByteArray clinfo = currentDownload->rawHeader(cltag);
+ QFileInfo fi(outfile);
+ emit downloadInfo(outfile.fileName(), clinfo.toDouble());
+}
+// ----------------------------------------------------------------------------------------
+void DownloadManager::downloadReady()
+{
+ // data ready, save it
+ outfile.write(currentDownload->readAll());
+}
+// ----------------------------------------------------------------------------------------
+void DownloadManager::downloadProgress(qint64 bytesIn, qint64 bytesTotal)
+{
+ 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);
+ qxtLog->debug() << "Download progress of " << currentDownload->url().toString()
+ << ": " << bytesIn << "/" << bytesTotal << "(" << currentProgress << "\%)";
+ }
+ return;
+}
+// ----------------------------------------------------------------------------------------
+void DownloadManager::downloadFinished()
+{
+ // check for errors
+ if (currentDownload->error()){
+ currentDownload->deleteLater();
+ outfile.remove();
+ int statusCode = currentDownload->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+ qxtLog->debug() << "Download of " << currentDownload->url().toString()
+ << " failed with HTTP error code: " << statusCode;
+ emit notify(QString("Download failed! HTTP Status Code: %1").arg(statusCode));
+ }
+ else{
+ // end download
+ currentDownload->deleteLater();
+ outfile.close();
+ downloaded++;
+ qxtLog->debug() << "Download of " << currentDownload->url().toString()
+ << " finished. (downloaded = "<< downloaded << ")";
+ emit notify(QString("Successfully downloaded %1").arg(currentDownload->url().toString()));
+ }
+ dip = false;
+ // process next in queue
+ if (dlQ.isEmpty()){
+ emit downloadQueueEmpty();
+ qxtLog->debug() << "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)) {
+ qxtLog->debug() << "Renamed file!";
+}
+else {
+ qxtLog->debug() << "Failure to rename file!";
+}
+*/