Browse Source

Add updater.hpp/cpp and more advanced app updating functionality.

tags/v1.1.1
Andrew Belt 4 years ago
parent
commit
923537402e
8 changed files with 179 additions and 72 deletions
  1. +2
    -2
      Makefile
  2. +10
    -11
      include/app/common.hpp
  3. +26
    -0
      include/updater.hpp
  4. +40
    -13
      src/app/MenuBar.cpp
  5. +14
    -35
      src/app/common.cpp
  6. +2
    -1
      src/main.cpp
  7. +2
    -10
      src/plugin.cpp
  8. +83
    -0
      src/updater.cpp

+ 2
- 2
Makefile View File

@@ -1,6 +1,6 @@
RACK_DIR ?= .
# VERSION := 1.dev.$(shell git rev-parse --short HEAD)
VERSION := 1.1.0
VERSION := 1.dev.$(shell git rev-parse --short HEAD)
# VERSION := 1.1.0

FLAGS += -DVERSION=$(VERSION)
FLAGS += -Iinclude -Idep/include


+ 10
- 11
include/app/common.hpp View File

@@ -12,15 +12,17 @@ namespace rack {
namespace app {


extern std::string APP_NAME;
extern std::string APP_VERSION;
extern std::string APP_VERSION_UPDATE;
extern std::string API_URL;
extern std::string API_VERSION;
extern std::string ABI_VERSION;
extern const std::string APP_NAME;
extern const std::string APP_VERSION;
extern const std::string APP_ARCH;

static const float SVG_DPI = 75.0;
static const float MM_PER_IN = 25.4;
extern const std::string ABI_VERSION;

extern const std::string API_URL;
extern const std::string API_VERSION;

static const float SVG_DPI = 75.f;
static const float MM_PER_IN = 25.4f;


/** Converts inch measurements to pixels */
@@ -50,8 +52,5 @@ static const math::Vec RACK_OFFSET = RACK_GRID_SIZE.mult(math::Vec(2000, 100));
static const math::Vec BUS_BOARD_GRID_SIZE = math::Vec(RACK_GRID_WIDTH * 20, RACK_GRID_HEIGHT);


void init();


} // namespace app
} // namespace rack

+ 26
- 0
include/updater.hpp View File

@@ -0,0 +1,26 @@
#pragma once
#include <common.hpp>


namespace rack {


/** Automatically updates the application.
*/
namespace updater {


extern std::string version;
extern std::string changelogUrl;
extern float progress;

void init();
bool isUpdateAvailable();
/** Updates Rack automatically or opens the browser to the URL.
Blocking. Call on a detached thread.
*/
void update();


} // namespace updater
} // namespace rack

+ 40
- 13
src/app/MenuBar.cpp View File

@@ -15,6 +15,7 @@
#include <system.hpp>
#include <plugin.hpp>
#include <patch.hpp>
#include <updater.hpp>
#include <osdialog.h>
#include <thread>

@@ -61,6 +62,16 @@ struct UrlItem : ui::MenuItem {
}
};

struct FolderItem : ui::MenuItem {
std::string path;
void onAction(const event::Action &e) override {
std::thread t([=] {
system::openFolder(path);
});
t.detach();
}
};

////////////////////
// File
////////////////////
@@ -701,15 +712,35 @@ struct LibraryButton : MenuButton {
// Help
////////////////////

struct UserFolderItem : ui::MenuItem {
struct UpdateItem : ui::MenuItem {
ui::Menu *createChildMenu() override {
ui::Menu *menu = new ui::Menu;

UrlItem *changelogUrl = new UrlItem;
changelogUrl->text = "Changelog";
changelogUrl->url = updater::changelogUrl;
menu->addChild(changelogUrl);

return menu;
}

void step() override {
if (updater::progress > 0) {
rightText = string::f("%.0f%%", updater::progress * 100.f);
}
MenuItem::step();
}

void onAction(const event::Action &e) override {
std::thread t([] {
system::openFolder(asset::user(""));
std::thread t([=] {
updater::update();
});
t.detach();
e.consume(NULL);
}
};


struct HelpButton : MenuButton {
NotificationIcon *notification;

@@ -723,11 +754,10 @@ struct HelpButton : MenuButton {
menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y));
menu->box.size.x = box.size.x;

if (hasUpdate()) {
UrlItem *updateItem = new UrlItem;
if (updater::isUpdateAvailable()) {
UpdateItem *updateItem = new UpdateItem;
updateItem->text = "Update " + APP_NAME;
updateItem->rightText = APP_VERSION + " → " + APP_VERSION_UPDATE;
updateItem->url = "https://vcvrack.com/";
updateItem->rightText = APP_VERSION + " → " + updater::version;
menu->addChild(updateItem);
}

@@ -742,20 +772,17 @@ struct HelpButton : MenuButton {
websiteItem->url = "https://vcvrack.com/";
menu->addChild(websiteItem);

UserFolderItem *folderItem = new UserFolderItem;
FolderItem *folderItem = new FolderItem;
folderItem->text = "Open user folder";
folderItem->path = asset::user("");
menu->addChild(folderItem);
}

void step() override {
notification->box.pos = math::Vec(0, 0);
notification->visible = hasUpdate();
notification->visible = updater::isUpdateAvailable();
MenuButton::step();
}

bool hasUpdate() {
return !APP_VERSION_UPDATE.empty() && APP_VERSION_UPDATE != APP_VERSION;
}
};

////////////////////


+ 14
- 35
src/app/common.cpp View File

@@ -1,45 +1,24 @@
#include <app/common.hpp>
#include <settings.hpp>
#include <network.hpp>
#include <thread>


namespace rack {
namespace app {


std::string APP_NAME = "VCV Rack";
std::string APP_VERSION = TOSTRING(VERSION);
std::string APP_VERSION_UPDATE;
std::string API_URL = "https://api.vcvrack.com";
std::string API_VERSION = "1";
std::string ABI_VERSION = "1";


static void checkVersion() {
std::string versionUrl = app::API_URL + "/version";
json_t *versionResJ = network::requestJson(network::METHOD_GET, versionUrl, NULL);
if (!versionResJ) {
WARN("Request for version failed");
return;
}
DEFER({
json_decref(versionResJ);
});

json_t *versionJ = json_object_get(versionResJ, "version");
if (versionJ)
APP_VERSION_UPDATE = json_string_value(versionJ);
}

void init() {
if (!settings::devMode) {
std::thread t([] {
checkVersion();
});
t.detach();
}
}
const std::string APP_NAME = "VCV Rack";
const std::string APP_VERSION = TOSTRING(VERSION);
#if defined ARCH_WIN
const std::string APP_ARCH = "win";
#elif ARCH_MAC
const std::string APP_ARCH = "mac";
#elif defined ARCH_LIN
const std::string APP_ARCH = "lin";
#endif

const std::string ABI_VERSION = "1";

const std::string API_URL = "https://api.vcvrack.com";
const std::string API_VERSION = "1";


} // namespace app


+ 2
- 1
src/main.cpp View File

@@ -16,6 +16,7 @@
#include <ui.hpp>
#include <system.hpp>
#include <string.hpp>
#include <updater.hpp>

#include <osdialog.h>
#include <thread>
@@ -150,7 +151,7 @@ int main(int argc, char *argv[]) {
keyboard::init();
gamepad::init();
plugin::init();
app::init();
updater::init();
if (!settings::headless) {
ui::init();
windowInit();


+ 2
- 10
src/plugin.cpp View File

@@ -476,21 +476,13 @@ void syncUpdate(Update *update) {
isSyncingUpdate = false;
});

#if defined ARCH_WIN
std::string arch = "win";
#elif ARCH_MAC
std::string arch = "mac";
#elif defined ARCH_LIN
std::string arch = "lin";
#endif

std::string downloadUrl = app::API_URL + "/download";
downloadUrl += "?token=" + network::encodeUrl(settings::token);
downloadUrl += "&slug=" + network::encodeUrl(update->pluginSlug);
downloadUrl += "&version=" + network::encodeUrl(update->version);
downloadUrl += "&arch=" + network::encodeUrl(arch);
downloadUrl += "&arch=" + network::encodeUrl(app::APP_ARCH);

INFO("Downloading plugin %s %s %s", update->pluginSlug.c_str(), update->version.c_str(), arch.c_str());
INFO("Downloading plugin %s %s %s", update->pluginSlug.c_str(), update->version.c_str(), app::APP_ARCH.c_str());

// Download zip
std::string pluginDest = asset::pluginsPath + "/" + update->pluginSlug + ".zip";


+ 83
- 0
src/updater.cpp View File

@@ -0,0 +1,83 @@
#include <updater.hpp>
#include <settings.hpp>
#include <app/common.hpp>
#include <network.hpp>
#include <system.hpp>
#include <app.hpp>
#include <window.hpp>
#include <thread>


namespace rack {
namespace updater {


std::string version;
std::string changelogUrl;
float progress = 0.f;
static std::string downloadUrl;


static void checkVersion() {
std::string versionUrl = app::API_URL + "/version";
json_t *resJ = network::requestJson(network::METHOD_GET, versionUrl, NULL);
if (!resJ) {
WARN("Request for version failed");
return;
}
DEFER({
json_decref(resJ);
});

json_t *versionJ = json_object_get(resJ, "version");
if (versionJ)
version = json_string_value(versionJ);

json_t *changelogUrlJ = json_object_get(resJ, "changelogUrl");
if (changelogUrlJ)
changelogUrl = json_string_value(changelogUrlJ);

json_t *downloadUrlsJ = json_object_get(resJ, "downloadUrls");
if (downloadUrlsJ) {
json_t *downloadUrlJ = json_object_get(downloadUrlsJ, app::APP_ARCH.c_str());
if (downloadUrlJ)
downloadUrl = json_string_value(downloadUrlJ);
}
}


void init() {
if (!settings::devMode) {
std::thread t([] {
checkVersion();
});
t.detach();
}
}


void update() {
if (downloadUrl == "")
return;

#if defined ARCH_WIN
// Download and launch the installer on Windows
std::string path = asset::user("Rack-setup.exe");
network::requestDownload(downloadUrl, path, &progress);
system::runProcessDetached(path);
#else
// Open the browser on Mac and Linux. The user will know what to do.
system::openBrowser(downloadUrl);
#endif

APP->window->close();
}


bool isUpdateAvailable() {
return (version != "") && (version != app::APP_VERSION);
}


} // namespace updater
} // namespace rack

Loading…
Cancel
Save