Browse Source

Updated plugin API to latest server, reenabled PluginManagerWidget

tags/v0.3.0
Andrew Belt 7 years ago
parent
commit
d2ce7245e2
6 changed files with 73 additions and 89 deletions
  1. +1
    -1
      include/plugin.hpp
  2. +1
    -0
      include/util.hpp
  3. +12
    -2
      src/app/PluginManagerWidget.cpp
  4. +7
    -7
      src/app/Toolbar.cpp
  5. +37
    -79
      src/plugin.cpp
  6. +15
    -0
      src/util.cpp

+ 1
- 1
include/plugin.hpp View File

@@ -37,7 +37,6 @@ extern std::list<Plugin*> gPlugins;
void pluginInit(); void pluginInit();
void pluginDestroy(); void pluginDestroy();


void pluginOpenBrowser(std::string url);
void pluginLogIn(std::string email, std::string password); void pluginLogIn(std::string email, std::string password);
void pluginLogOut(); void pluginLogOut();
void pluginRefresh(); void pluginRefresh();
@@ -46,6 +45,7 @@ bool pluginIsLoggedIn();
bool pluginIsDownloading(); bool pluginIsDownloading();
float pluginGetDownloadProgress(); float pluginGetDownloadProgress();
std::string pluginGetDownloadName(); std::string pluginGetDownloadName();
std::string pluginGetLoginStatus();


} // namespace rack } // namespace rack




+ 1
- 0
include/util.hpp View File

@@ -52,6 +52,7 @@ std::string stringf(const char *format, ...);
/** Truncates and adds "..." to a string, not exceeding `len` characters */ /** Truncates and adds "..." to a string, not exceeding `len` characters */
std::string ellipsize(std::string s, size_t len); std::string ellipsize(std::string s, size_t len);


void openBrowser(std::string url);


/** Threads which obtain a VIPLock will cause wait() to block for other less important threads. /** Threads which obtain a VIPLock will cause wait() to block for other less important threads.
This does not provide the VIPs with an exclusive lock. That should be left up to another mutex shared between the less important thread. This does not provide the VIPs with an exclusive lock. That should be left up to another mutex shared between the less important thread.


+ 12
- 2
src/app/PluginManagerWidget.cpp View File

@@ -16,7 +16,7 @@ PluginManagerWidget::PluginManagerWidget() {


struct RegisterButton : Button { struct RegisterButton : Button {
void onAction() { void onAction() {
std::thread t(pluginOpenBrowser, "http://vcvrack.com/");
std::thread t(openBrowser, "http://vcvrack.com/");
t.detach(); t.detach();
} }
}; };
@@ -60,6 +60,16 @@ PluginManagerWidget::PluginManagerWidget() {
logInButton->emailField = emailField; logInButton->emailField = emailField;
logInButton->passwordField = passwordField; logInButton->passwordField = passwordField;
loginWidget->addChild(logInButton); loginWidget->addChild(logInButton);
pos.x += logInButton->box.size.x;

struct StatusLabel : Label {
void step() {
text = pluginGetLoginStatus();
}
};
Label *label = new StatusLabel();
label->box.pos = pos;
loginWidget->addChild(label);


addChild(loginWidget); addChild(loginWidget);
} }
@@ -70,7 +80,7 @@ PluginManagerWidget::PluginManagerWidget() {


struct ManageButton : Button { struct ManageButton : Button {
void onAction() { void onAction() {
std::thread t(pluginOpenBrowser, "http://vcvrack.com/");
std::thread t(openBrowser, "http://vcvrack.com/");
t.detach(); t.detach();
} }
}; };


+ 7
- 7
src/app/Toolbar.cpp View File

@@ -151,13 +151,13 @@ Toolbar::Toolbar() {
xPos += cpuUsageButton->box.size.x; xPos += cpuUsageButton->box.size.x;
} }


// xPos += margin;
// {
// Widget *pluginManager = new PluginManagerWidget();
// pluginManager->box.pos = Vec(xPos, margin);
// addChild(pluginManager);
// xPos += pluginManager->box.size.x;
// }
xPos += margin;
{
Widget *pluginManager = new PluginManagerWidget();
pluginManager->box.pos = Vec(xPos, margin);
addChild(pluginManager);
xPos += pluginManager->box.size.x;
}
} }


void Toolbar::draw(NVGcontext *vg) { void Toolbar::draw(NVGcontext *vg) {


+ 37
- 79
src/plugin.cpp View File

@@ -8,7 +8,6 @@
#include <sys/param.h> // for MAXPATHLEN #include <sys/param.h> // for MAXPATHLEN
#include <fcntl.h> #include <fcntl.h>


#include <curl/curl.h>
#include <zip.h> #include <zip.h>
#include <jansson.h> #include <jansson.h>


@@ -23,17 +22,18 @@
#include <dirent.h> #include <dirent.h>


#include "plugin.hpp" #include "plugin.hpp"
#include "util/request.hpp"




namespace rack { namespace rack {


std::list<Plugin*> gPlugins; std::list<Plugin*> gPlugins;


static const std::string apiUrl = "http://localhost:8081";
static std::string token; static std::string token;
static bool isDownloading = false; static bool isDownloading = false;
static float downloadProgress = 0.0; static float downloadProgress = 0.0;
static std::string downloadName; static std::string downloadName;
static std::string loginStatus;




Plugin::~Plugin() { Plugin::~Plugin() {
@@ -92,7 +92,7 @@ static int loadPlugin(std::string slug) {
} }


void pluginInit() { void pluginInit() {
curl_global_init(CURL_GLOBAL_NOTHING);
requestInit();


// Load core // Load core
// This function is defined in core.cpp // This function is defined in core.cpp
@@ -118,49 +118,13 @@ void pluginDestroy() {
delete plugin; delete plugin;
} }
gPlugins.clear(); gPlugins.clear();
curl_global_cleanup();
requestDestroy();
} }


//////////////////// ////////////////////
// CURL and libzip helpers // CURL and libzip helpers
//////////////////// ////////////////////


static size_t write_file_callback(void *data, size_t size, size_t nmemb, void *p) {
int fd = *((int*)p);
ssize_t len = write(fd, data, size*nmemb);
return len;
}

static int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) {
if (dltotal == 0.0)
return 0;
float progress = dlnow / dltotal;
downloadProgress = progress;
return 0;
}

static CURLcode download_file(int fd, const char *url) {
CURL *curl = curl_easy_init();

curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_file_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fd);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback);
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, NULL);
CURLcode res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
return res;
}

static size_t write_string_callback(void *data, size_t size, size_t nmemb, void *p) {
std::string &text = *((std::string*)p);
char *dataStr = (char*) data;
size_t len = size * nmemb;
text.append(dataStr, len);
return len;
}


static void extract_zip(const char *dir, int zipfd) { static void extract_zip(const char *dir, int zipfd) {
int err = 0; int err = 0;
@@ -210,50 +174,32 @@ cleanup:
// plugin manager // plugin manager
//////////////////// ////////////////////


void pluginOpenBrowser(std::string url) {
// shell injection is possible, so make sure the URL is trusted
#if ARCH_LIN
std::string command = "xdg-open " + url;
system(command.c_str());
#endif
#if ARCH_MAC
std::string command = "open " + url;
system(command.c_str());
#endif
#if ARCH_WIN
ShellExecute(NULL, "open", url.c_str(), NULL, NULL, SW_SHOWNORMAL);
#endif
}
static std::string apiHost = "http://api.vcvrack.com";


void pluginLogIn(std::string email, std::string password) { void pluginLogIn(std::string email, std::string password) {
CURL *curl = curl_easy_init();
assert(curl);

std::string postFields = "email=" + email + "&password=" + password;
std::string url = apiUrl + "/token";
std::string resText;

curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_string_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resText);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postFields.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, postFields.size());
CURLcode res = curl_easy_perform(curl);
curl_easy_cleanup(curl);

if (res == CURLE_OK) {
// Parse JSON response
json_error_t error;
json_t *rootJ = json_loads(resText.c_str(), 0, &error);
if (rootJ) {
json_t *tokenJ = json_object_get(rootJ, "token");
json_t *reqJ = json_object();
json_object_set(reqJ, "email", json_string(email.c_str()));
json_object_set(reqJ, "password", json_string(password.c_str()));
json_t *resJ = requestJson(POST_METHOD, apiHost + "/token", reqJ);

if (resJ) {
// TODO parse response
json_t *errorJ = json_object_get(resJ, "error");
if (errorJ) {
const char *errorStr = json_string_value(errorJ);
loginStatus = errorStr;
}
else {
json_t *tokenJ = json_object_get(resJ, "token");
if (tokenJ) { if (tokenJ) {
// Set the token, which logs the user in
token = json_string_value(tokenJ);
const char *tokenStr = json_string_value(tokenJ);
token = tokenStr;
loginStatus = "";
} }
json_decref(rootJ);
} }
json_decref(resJ);
} }
json_decref(reqJ);
} }


void pluginLogOut() { void pluginLogOut() {
@@ -261,6 +207,9 @@ void pluginLogOut() {
} }


static void pluginRefreshPlugin(json_t *pluginJ) { static void pluginRefreshPlugin(json_t *pluginJ) {
// TODO
// Refactor

json_t *slugJ = json_object_get(pluginJ, "slug"); json_t *slugJ = json_object_get(pluginJ, "slug");
if (!slugJ) return; if (!slugJ) return;
std::string slug = json_string_value(slugJ); std::string slug = json_string_value(slugJ);
@@ -290,7 +239,7 @@ static void pluginRefreshPlugin(json_t *pluginJ) {
snprintf(path, sizeof(path), "%s/%s.zip", dir, slug.c_str()); snprintf(path, sizeof(path), "%s/%s.zip", dir, slug.c_str());
int zip = open(path, O_RDWR | O_TRUNC | O_CREAT, 0644); int zip = open(path, O_RDWR | O_TRUNC | O_CREAT, 0644);
// Download zip // Download zip
download_file(zip, url.c_str());
// download_file(zip, url.c_str());
// Unzip file // Unzip file
lseek(zip, 0, SEEK_SET); lseek(zip, 0, SEEK_SET);
extract_zip(dir, zip); extract_zip(dir, zip);
@@ -302,9 +251,13 @@ static void pluginRefreshPlugin(json_t *pluginJ) {
} }


void pluginRefresh() { void pluginRefresh() {
// TODO
// Refactor with requestJson()

if (token.empty()) if (token.empty())
return; return;


/*
isDownloading = true; isDownloading = true;
downloadProgress = 0.0; downloadProgress = 0.0;
downloadName = ""; downloadName = "";
@@ -341,6 +294,7 @@ void pluginRefresh() {
} }


isDownloading = false; isDownloading = false;
*/
} }


void pluginCancelDownload() { void pluginCancelDownload() {
@@ -363,5 +317,9 @@ std::string pluginGetDownloadName() {
return downloadName; return downloadName;
} }


std::string pluginGetLoginStatus() {
return loginStatus;
}



} // namespace rack } // namespace rack

+ 15
- 0
src/util.cpp View File

@@ -49,5 +49,20 @@ std::string ellipsize(std::string s, size_t len) {
return s.substr(0, len - 3) + "..."; return s.substr(0, len - 3) + "...";
} }


void openBrowser(std::string url) {
// shell injection is possible, so make sure the URL is trusted or hard coded
#if ARCH_LIN
std::string command = "xdg-open " + url;
system(command.c_str());
#endif
#if ARCH_MAC
std::string command = "open " + url;
system(command.c_str());
#endif
#if ARCH_WIN
ShellExecute(NULL, "open", url.c_str(), NULL, NULL, SW_SHOWNORMAL);
#endif
}



} // namespace rack } // namespace rack

Loading…
Cancel
Save