| @@ -126,17 +126,22 @@ void pluginDestroy() { | |||||
| //////////////////// | //////////////////// | ||||
| static void extract_zip(const char *dir, int zipfd) { | |||||
| static void extractZip(const char *filename, const char *dir) { | |||||
| int err = 0; | int err = 0; | ||||
| zip_t *za = zip_fdopen(zipfd, 0, &err); | |||||
| zip_t *za = zip_open(filename, 0, &err); | |||||
| printf("err: %d\n", err); | |||||
| printf("0\n"); | |||||
| if (!za) return; | if (!za) return; | ||||
| printf("1\n"); | |||||
| if (err) goto cleanup; | if (err) goto cleanup; | ||||
| printf("2\n"); | |||||
| for (int i = 0; i < zip_get_num_entries(za, 0); i++) { | for (int i = 0; i < zip_get_num_entries(za, 0); i++) { | ||||
| zip_stat_t zs; | zip_stat_t zs; | ||||
| err = zip_stat_index(za, i, 0, &zs); | err = zip_stat_index(za, i, 0, &zs); | ||||
| if (err) goto cleanup; | if (err) goto cleanup; | ||||
| int nameLen = strlen(zs.name); | int nameLen = strlen(zs.name); | ||||
| printf("3\n"); | |||||
| char path[MAXPATHLEN]; | char path[MAXPATHLEN]; | ||||
| snprintf(path, sizeof(path), "%s/%s", dir, zs.name); | snprintf(path, sizeof(path), "%s/%s", dir, zs.name); | ||||
| @@ -152,6 +157,7 @@ static void extract_zip(const char *dir, int zipfd) { | |||||
| int out = open(path, O_RDWR | O_TRUNC | O_CREAT, 0644); | int out = open(path, O_RDWR | O_TRUNC | O_CREAT, 0644); | ||||
| assert(out != -1); | assert(out != -1); | ||||
| printf("4\n"); | |||||
| while (1) { | while (1) { | ||||
| char buffer[4096]; | char buffer[4096]; | ||||
| int len = zip_fread(zf, buffer, sizeof(buffer)); | int len = zip_fread(zf, buffer, sizeof(buffer)); | ||||
| @@ -167,6 +173,7 @@ static void extract_zip(const char *dir, int zipfd) { | |||||
| } | } | ||||
| cleanup: | cleanup: | ||||
| printf("5\n"); | |||||
| zip_close(za); | zip_close(za); | ||||
| } | } | ||||
| @@ -181,9 +188,9 @@ void pluginLogIn(std::string email, std::string password) { | |||||
| json_object_set(reqJ, "email", json_string(email.c_str())); | json_object_set(reqJ, "email", json_string(email.c_str())); | ||||
| json_object_set(reqJ, "password", json_string(password.c_str())); | json_object_set(reqJ, "password", json_string(password.c_str())); | ||||
| json_t *resJ = requestJson(POST_METHOD, apiHost + "/token", reqJ); | json_t *resJ = requestJson(POST_METHOD, apiHost + "/token", reqJ); | ||||
| json_decref(reqJ); | |||||
| if (resJ) { | if (resJ) { | ||||
| // TODO parse response | |||||
| json_t *errorJ = json_object_get(resJ, "error"); | json_t *errorJ = json_object_get(resJ, "error"); | ||||
| if (errorJ) { | if (errorJ) { | ||||
| const char *errorStr = json_string_value(errorJ); | const char *errorStr = json_string_value(errorJ); | ||||
| @@ -199,7 +206,6 @@ void pluginLogIn(std::string email, std::string password) { | |||||
| } | } | ||||
| json_decref(resJ); | json_decref(resJ); | ||||
| } | } | ||||
| json_decref(reqJ); | |||||
| } | } | ||||
| void pluginLogOut() { | void pluginLogOut() { | ||||
| @@ -207,94 +213,75 @@ 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); | |||||
| const char *slug = json_string_value(slugJ); | |||||
| json_t *nameJ = json_object_get(pluginJ, "name"); | json_t *nameJ = json_object_get(pluginJ, "name"); | ||||
| if (!nameJ) return; | if (!nameJ) return; | ||||
| std::string name = json_string_value(nameJ); | |||||
| const char *name = json_string_value(nameJ); | |||||
| json_t *urlJ = json_object_get(pluginJ, "download"); | |||||
| if (!urlJ) return; | |||||
| std::string url = json_string_value(urlJ); | |||||
| json_t *downloadJ = json_object_get(pluginJ, "download"); | |||||
| if (!downloadJ) return; | |||||
| const char *download = json_string_value(downloadJ); | |||||
| // Find slug in plugins list | // Find slug in plugins list | ||||
| for (Plugin *p : gPlugins) { | for (Plugin *p : gPlugins) { | ||||
| if (p->slug == slug) { | if (p->slug == slug) { | ||||
| return; | |||||
| // return; | |||||
| } | } | ||||
| } | } | ||||
| // If plugin is not loaded, download the zip file to /plugins | // If plugin is not loaded, download the zip file to /plugins | ||||
| fprintf(stderr, "Downloading %s from %s\n", name.c_str(), url.c_str()); | |||||
| downloadName = name; | downloadName = name; | ||||
| downloadProgress = 0.0; | downloadProgress = 0.0; | ||||
| const char *dir = "plugins"; | |||||
| char path[MAXPATHLEN]; | |||||
| snprintf(path, sizeof(path), "%s/%s.zip", dir, slug.c_str()); | |||||
| int zip = open(path, O_RDWR | O_TRUNC | O_CREAT, 0644); | |||||
| // Download zip | // Download zip | ||||
| // download_file(zip, url.c_str()); | |||||
| // Unzip file | |||||
| lseek(zip, 0, SEEK_SET); | |||||
| extract_zip(dir, zip); | |||||
| // Close file | |||||
| close(zip); | |||||
| downloadName = ""; | |||||
| std::string filename = "plugins/"; | |||||
| filename += slug; | |||||
| filename += ".zip"; | |||||
| bool success = requestDownload(download, filename, &downloadProgress); | |||||
| if (success) { | |||||
| // Unzip file | |||||
| extractZip(filename.c_str(), "plugins"); | |||||
| // Load plugin | |||||
| loadPlugin(slug); | |||||
| } | |||||
| // Load plugin | |||||
| downloadName = ""; | |||||
| } | } | ||||
| 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 = ""; | ||||
| // Get plugin list from /plugin | |||||
| CURL *curl = curl_easy_init(); | |||||
| assert(curl); | |||||
| std::string url = apiUrl + "/plugins?token=" + 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); | |||||
| 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 *pluginsJ = json_object_get(rootJ, "plugins"); | |||||
| if (pluginsJ) { | |||||
| // Iterate through each plugin object | |||||
| size_t index; | |||||
| json_t *pluginJ; | |||||
| json_array_foreach(pluginsJ, index, pluginJ) { | |||||
| pluginRefreshPlugin(pluginJ); | |||||
| } | |||||
| json_t *reqJ = json_object(); | |||||
| json_object_set(reqJ, "token", json_string(token.c_str())); | |||||
| json_t *resJ = requestJson(GET_METHOD, apiHost + "/purchases", reqJ); | |||||
| json_decref(reqJ); | |||||
| if (resJ) { | |||||
| json_t *errorJ = json_object_get(resJ, "error"); | |||||
| if (errorJ) { | |||||
| const char *errorStr = json_string_value(errorJ); | |||||
| printf("Plugin refresh error: %s\n", errorStr); | |||||
| } | |||||
| else { | |||||
| json_t *purchasesJ = json_object_get(resJ, "purchases"); | |||||
| size_t index; | |||||
| json_t *purchaseJ; | |||||
| json_array_foreach(purchasesJ, index, purchaseJ) { | |||||
| pluginRefreshPlugin(purchaseJ); | |||||
| } | } | ||||
| json_decref(rootJ); | |||||
| } | } | ||||
| json_decref(resJ); | |||||
| } | } | ||||
| isDownloading = false; | isDownloading = false; | ||||
| */ | |||||
| } | } | ||||
| void pluginCancelDownload() { | void pluginCancelDownload() { | ||||