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

Commit

Permalink
#48 Check for update mechanism
Browse files Browse the repository at this point in the history
Working on the backend
  • Loading branch information
ColinDuquesnoy committed Jul 16, 2017
1 parent 515349c commit b980304
Show file tree
Hide file tree
Showing 26 changed files with 3,313 additions and 2 deletions.
4 changes: 4 additions & 0 deletions lib/MellowPlayer/Application/Settings/SettingKey.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ namespace MellowPlayer::Application {
APPEARANCE_SECONDARY_BACKGROUND,
APPEARANCE_SECONDARY_FOREGROUND,
APPEARANCE_THEME,
MAIN_CHECK_FOR_UPDATES,
MAIN_CLOSE_TO_TRAY,
MAIN_CONFIRM_EXIT,
MAIN_SHOW_TRAY_ICON,
MAIN_UPDATE_CHANNEL,
NOTIFICATIONS_ENABLED,
NOTIFICATIONS_NEW_SONG,
NOTIFICATIONS_NEW_VERSION,
Expand Down Expand Up @@ -57,9 +59,11 @@ namespace MellowPlayer::Application {
enumToString << "appearance/secondary-background";
enumToString << "appearance/secondary-foreground";
enumToString << "appearance/theme";
enumToString << "main/check-for-updates";
enumToString << "main/close-to-tray";
enumToString << "main/confirm-exit";
enumToString << "main/show-tray-icon";
enumToString << "main/update-channel";
enumToString << "notifications/enabled";
enumToString << "notifications/new-song";
enumToString << "notifications/new-version";
Expand Down
17 changes: 16 additions & 1 deletion lib/MellowPlayer/Application/Settings/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,22 @@
"default": true,
"key": "show-tray-icon",
"enabled": "main/close-to-tray"
}
},
{
"name": "Check for updates",
"tooltip": "Automatically check for updates",
"type": "bool",
"default": true,
"key": "check-for-updates"
},
{
"name": "Update channel",
"tooltip": "Choose which update channel to use",
"type": "enum[Stable, Beta, Continuous]",
"default": "Stable",
"key": "update-channel",
"enabled": "main/check-for-updates"
}
]
},
{
Expand Down
32 changes: 32 additions & 0 deletions lib/MellowPlayer/Application/Updater/Asset.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <QtCore/QUrl>
#include "Asset.hpp"

using namespace MellowPlayer::Application;

Asset::Asset(const QString& name, const QString& url): name_(name), url_(url) {

}

QString Asset::getName() const {
return name_;
}

QString Asset::getUrl() {
return url_;
}

bool Asset::isAppImage() const {
return name_.endsWith(".AppImage");
}

bool Asset::isWindowsInstaller() const {
return name_.endsWith("_Setup.exe");
}

bool Asset::isDmg() const {
return name_.endsWith(".dmg");
}

bool Asset::isValid() const {
return QUrl(url_).isValid() && (isAppImage() || isWindowsInstaller() || isDmg());
}
25 changes: 25 additions & 0 deletions lib/MellowPlayer/Application/Updater/Asset.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include <QtCore/QString>

namespace MellowPlayer::Application {

class Asset {
public:
Asset(const QString& name, const QString& url);

QString getName() const;
QString getUrl();

bool isAppImage() const;
bool isWindowsInstaller() const;
bool isDmg() const;

bool isValid() const;

private:
QString name_;
QString url_;
};

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include <QtCore/QJsonDocument>
#include <MellowPlayer/Application/Updater/Release.hpp>
#include "GithubReleaseQuerier.hpp"


#define CONTINUOUS_RELEASE_NAME "Continuous"

using namespace MellowPlayer::Application;

GithubReleaseQuerier::GithubReleaseQuerier(IHttpClient& httpClient):
httpClient_(httpClient) {
connect(&httpClient, &IHttpClient::replyReceived,
this, &GithubReleaseQuerier::onReplyReceived);
connect(&replyParser_, &GithubReleasesReplyParser::ready, this, &GithubReleaseQuerier::onReleaseReady);
}

void GithubReleaseQuerier::setChannel(UpdateChannel channel) {
channel_ = channel;
}

void GithubReleaseQuerier::getLatest() {
httpClient_.get("https://api.github.com/repos/ColinDuquesnoy/MellowPlayer/releases");
}

void GithubReleaseQuerier::onReplyReceived(const QByteArray& replyData) {
replyParser_.parse(replyData);
}

void GithubReleaseQuerier::onReleaseReady(const Release* release) {
if (release != nullptr && accept(release)) {
emit latestReceived(release);
replyParser_.stop();
}
}

bool GithubReleaseQuerier::accept(const Release* release) {
bool accepted;

switch (channel_) {
case UpdateChannel::Continuous:
accepted = release->getName() == CONTINUOUS_RELEASE_NAME;
break;
case UpdateChannel::Beta:
accepted = release->isPreRelease() && release->getName() != CONTINUOUS_RELEASE_NAME;
break;
case UpdateChannel::Stable:
accepted = !release->isPreRelease() && release->getName() != CONTINUOUS_RELEASE_NAME;
break;
}

return accepted;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once

#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <MellowPlayer/Application/Updater/IReleaseQuerier.hpp>
#include <MellowPlayer/Application/Updater/IHttpClient.hpp>
#include "GithubReleasesReplyParser.hpp"

namespace MellowPlayer::Application {

class GithubReleaseQuerier: public IReleaseQuerier {
public:
GithubReleaseQuerier(IHttpClient& httpClient);

void setChannel(Application::UpdateChannel channel) override;
void getLatest() override;

private slots:
void onReplyReceived(const QByteArray& replyData);
void onReleaseReady(const Application::Release* release);
bool accept(const Application::Release* release);

private:
GithubReleasesReplyParser replyParser_;
IHttpClient& httpClient_;
Application::UpdateChannel channel_ = Application::UpdateChannel::Stable;
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include <cassert>
#include <QtCore/QJsonArray>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
#include "GithubReleasesReplyParser.hpp"

using namespace MellowPlayer::Application;

void GithubReleasesReplyParser::parse(const QByteArray& replyData) {
stopRequested_ = false;
QJsonDocument jsonDocument = QJsonDocument::fromJson(replyData);
assert(jsonDocument.isArray());
QJsonArray array = jsonDocument.array();
for(int releaseIndex=0; releaseIndex < array.count(); ++releaseIndex) {
QJsonObject obj = array.at(releaseIndex).toObject();
QString url = obj.value("html_url").toString();
QString version = obj.value("name").toString();
QDate date = QDateTime::fromString(obj.value("created_at").toString(), Qt::ISODate).date();
QString description = obj.value("body").toString();
bool preRelease = obj.value("prerelease").toBool();
AssetList assets;
QJsonArray assetArray = obj.value("assets").toArray();
for (int assetIndex = 0; assetIndex < assetArray.count(); ++assetIndex) {
QJsonObject assetObj = assetArray.at(assetIndex).toObject();
Asset asset(assetObj.value("name").toString(), assetObj.value("browser_download_url").toString());
assets << asset;
}

Release* release = new Release(url, version, date, description, assets, preRelease, this);

emit ready(release);

if (stopRequested_)
return;
}
}

void GithubReleasesReplyParser::stop() {
stopRequested_ = true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include <QtCore/QByteArray>
#include <QtCore/QJsonDocument>
#include <MellowPlayer/Application/Updater/Release.hpp>

namespace MellowPlayer::Application {

class GithubReleasesReplyParser: public QObject {
Q_OBJECT
public:
void parse(const QByteArray& replyData);
void stop();

signals:
void ready(const Release* release);

private:
bool stopRequested_ = false;
};
}
5 changes: 5 additions & 0 deletions lib/MellowPlayer/Application/Updater/IHttpClient.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "IHttpClient.hpp"

using namespace MellowPlayer::Application;

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

#include <QtCore/QObject>

namespace MellowPlayer::Application {

class IHttpClient: public QObject {
Q_OBJECT
public:
virtual ~IHttpClient();
virtual void get(const QString& url) = 0;

signals:
void replyReceived(const QByteArray& replyData);

};

}
22 changes: 22 additions & 0 deletions lib/MellowPlayer/Application/Updater/IReleaseQuerier.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include <QtCore/QObject>
#include "UpdateChannel.hpp"

namespace MellowPlayer::Application {

class Release;

class IReleaseQuerier: public QObject {
Q_OBJECT
public:
virtual ~IReleaseQuerier() = default;

virtual void setChannel(UpdateChannel channel) = 0;
virtual void getLatest() = 0;

signals:
void latestReceived(const Release* release);
};

}
Loading

0 comments on commit b980304

Please sign in to comment.