Skip to content
This repository has been archived by the owner on May 3, 2019. It is now read-only.

Commit

Permalink
#48 Add IFileDownloader and FileDownloader implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
ColinDuquesnoy committed Jul 20, 2017
1 parent 387900e commit 2f13455
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 20 deletions.
3 changes: 3 additions & 0 deletions lib/MellowPlayer/Application/IFileDownloader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "IFileDownloader.hpp"

MellowPlayer::Application::IFileDownloader::~IFileDownloader() = default;
22 changes: 22 additions & 0 deletions lib/MellowPlayer/Application/IFileDownloader.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include <QtCore/QString>
#include <QtCore/QObject>

namespace MellowPlayer::Application {

class IFileDownloader: public QObject
{
Q_OBJECT
public:
virtual ~IFileDownloader();

virtual void download(const QString& urlToDownload, const QString& filePath) = 0;
virtual double getProgress() const = 0;
virtual bool isDownloading() const = 0;

signals:
void progressChanged();
void finished(bool success);
};
}
1 change: 0 additions & 1 deletion lib/MellowPlayer/Application/IMainWindow.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,4 @@ namespace MellowPlayer::Application {
virtual void show() = 0;
virtual void hide() = 0;
};

}
4 changes: 2 additions & 2 deletions lib/MellowPlayer/Application/Updater/Updater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ Updater::Updater(IReleaseQuerier& releaseQuerier, Settings& settings):
connect(&releaseQuerier, &IReleaseQuerier::latestReceived, this, &Updater::onLatestReleaseReceived);
connect(&updateChannelSetting_, &Setting::valueChanged, this, &Updater::check);

Release* r = new Release("1.95.0", QDate::fromString("2017-06-15"), this);
setCurrentRelease(r);
// Release* r = new Release("1.95.0", QDate::fromString("2017-06-15"), this);
// setCurrentRelease(r);
}

void Updater::check() {
Expand Down
18 changes: 5 additions & 13 deletions lib/MellowPlayer/Infrastructure/AlbumArt/AlbumArtDownloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ using namespace MellowPlayer::Application;
using namespace MellowPlayer::Infrastructure;

AlbumArtDownloader::AlbumArtDownloader()
: networkAccessManager(new QNetworkAccessManager(this)),
logger(LoggingManager::instance().getLogger("AlbumArtDownloader")) {
: logger(LoggingManager::instance().getLogger("AlbumArtDownloader")) {

connect(networkAccessManager, &QNetworkAccessManager::finished, this, &AlbumArtDownloader::onDownloadFinished);
connect(&fileDownloader, &FileDownloader::finished, this, &AlbumArtDownloader::onDownloadFinished);
}

bool AlbumArtDownloader::download(const QString& url, const QString& songId) {
Expand All @@ -33,9 +32,9 @@ bool AlbumArtDownloader::download(const QString& url, const QString& songId) {
return true;
}

void AlbumArtDownloader::downloadImage(const QString& url) const {
void AlbumArtDownloader::downloadImage(const QString& url) {
LOG_DEBUG(logger, "downloading " + url + " to " + localUrl.absoluteFilePath());
networkAccessManager->get(QNetworkRequest(url));
fileDownloader.download(url, localUrl.absoluteFilePath());
}

QFileInfo AlbumArtDownloader::getLocalArtUrl(const QString &songId) {
Expand All @@ -47,15 +46,8 @@ QFileInfo AlbumArtDownloader::getLocalArtUrl(const QString &songId) {
return localArtUrl;
}

void AlbumArtDownloader::onDownloadFinished(QNetworkReply* reply) {
void AlbumArtDownloader::onDownloadFinished(bool) {
LOG_DEBUG(logger, "download finished");
QFile file(localUrl.absoluteFilePath());
if (file.open(QIODevice::WriteOnly)) {
file.write(reply->readAll());
file.close();
} else {
LOG_DEBUG(logger, "could not open file in write only mode: " +localUrl.absoluteFilePath());
}
emit downloadFinished(localUrl.absoluteFilePath());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <MellowPlayer/Application/AlbumArt/IAlbumArtDownloader.hpp>
#include <MellowPlayer/Infrastructure/FileDownloader.hpp>
#include "MellowPlayer/Infrastructure/Helpers/Base64Helper.hpp"

namespace MellowPlayer::Application {
Expand All @@ -22,18 +23,17 @@ namespace MellowPlayer::Infrastructure {
QFileInfo getLocalArtUrl(const QString &songId) override;

private slots:
void onDownloadFinished(QNetworkReply* reply);
void onDownloadFinished(bool);

private:
void downloadImage(const QString& url);
bool isBase64Image(const QString& artUrl);
bool createBase64Image(const QString base64String);

QNetworkAccessManager *networkAccessManager;
FileDownloader fileDownloader;
QFileInfo localUrl;
Application::ILogger& logger;
Base64Helper base64;

void downloadImage(const QString& url) const;
};

}
72 changes: 72 additions & 0 deletions lib/MellowPlayer/Infrastructure/FileDownloader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include <iostream>
#include "FileDownloader.hpp"

using namespace MellowPlayer::Application;
using namespace MellowPlayer::Infrastructure;


FileDownloader::FileDownloader()
{
connect(&networkAccessManager_, &QNetworkAccessManager::finished, this, &FileDownloader::onDownloadFinished);
}

void FileDownloader::download(const QString& urlToDownload, const QString& filePath)
{
if (!isDownloading()) {
progress_ = 0;
destinationPath_ = QFileInfo(filePath);
currentReply = networkAccessManager_.get(QNetworkRequest(QUrl(urlToDownload)));
connect(currentReply, &QNetworkReply::downloadProgress, this, &FileDownloader::onDownloadProgress);
}
}

double FileDownloader::getProgress() const
{
return progress_;
}

bool FileDownloader::isDownloading() const
{
return currentReply != nullptr;
}

void FileDownloader::onDownloadFinished(QNetworkReply* reply)
{
bool success = false;

currentReply = nullptr;

if (reply->error() == QNetworkReply::NoError)
{
QString redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString();

if (!redirectUrl.isEmpty()) {
download(redirectUrl, destinationPath_.absoluteFilePath());
return;
}

QByteArray replyData = reply->readAll();
QFile file(destinationPath_.absoluteFilePath());
if (file.open(QIODevice::WriteOnly)) {
file.write(replyData);
success = true;
}
}

emit finished(success);
}

void FileDownloader::onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) {

double ratio = 0;
if (bytesTotal > bytesReceived)
ratio = static_cast<double>(bytesReceived) / bytesTotal;
double progress = (ratio * 100);

std::cerr << bytesReceived << " / " << bytesTotal << " = " << progress << std::endl;

if (progress_ != progress) {
progress_ = progress;
emit progressChanged();
}
}
30 changes: 30 additions & 0 deletions lib/MellowPlayer/Infrastructure/FileDownloader.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once

#include <QtCore/QFileInfo>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <MellowPlayer/Application/IFileDownloader.hpp>

namespace MellowPlayer::Infrastructure {

class FileDownloader: public Application::IFileDownloader
{
Q_OBJECT
public:
FileDownloader();

void download(const QString& urlToDownload, const QString& filePath) override;
double getProgress() const override;
bool isDownloading() const override;

private slots:
void onDownloadFinished(QNetworkReply* reply);
void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);

private:
QNetworkAccessManager networkAccessManager_;
QFileInfo destinationPath_;
QNetworkReply* currentReply = nullptr;
double progress_ = 0;
};
}
32 changes: 32 additions & 0 deletions tests/IntegrationTests/Infrastructure/FileDownloaderTests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <catch.hpp>
#include <MellowPlayer/Infrastructure/FileDownloader.hpp>
#include <QtCore/QTemporaryDir>
#include <QtTest/qtestsystem.h>

using namespace MellowPlayer::Infrastructure;

SCENARIO("FileDownloader can download a release source archive") {
FileDownloader downloader;
QTemporaryDir dir;
QString destination = dir.path() + "/MellowPlayer.zip";
REQUIRE(!QFileInfo::exists(destination));

WHEN("downloading MellowPlayer.zip from github") {
downloader.download("https://github.com/ColinDuquesnoy/MellowPlayer/archive/2.95.0.zip", destination);

THEN("progress is updated regularly until download has finished") {
double latestProgress = -1;
while(downloader.isDownloading()) {
QTest::qWait(100);
bool validProgressUpdate = downloader.getProgress() >= latestProgress || downloader.getProgress() == 0;
REQUIRE(validProgressUpdate);
latestProgress = downloader.getProgress();
}

AND_THEN("destination file exists") {
REQUIRE(QFileInfo::exists(destination));
REQUIRE(QFileInfo(destination).size() == 20396818);
}
}
}
}

0 comments on commit 2f13455

Please sign in to comment.