mirror of
https://github.com/xemu-project/xemu.git
synced 2026-07-11 01:24:41 +02:00
ui: Fetch latest release info via GitHub API
This commit is contained in:
committed by
mborgerson
parent
26fcbe54f1
commit
ec7f5e438a
+44
-17
@@ -25,20 +25,19 @@
|
||||
#include <SDL_filesystem.h>
|
||||
#include "util/miniz/miniz.h"
|
||||
#include "xemu-version.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
const char *releases_url = "https://api.github.com/repos/xemu-project/xemu/releases/latest";
|
||||
|
||||
#if defined(_WIN32)
|
||||
const char *version_url = "https://raw.githubusercontent.com/xemu-project/xemu/ppa-snapshot/XEMU_VERSION";
|
||||
#if defined(__x86_64__)
|
||||
const char *download_url = "https://github.com/xemu-project/xemu/releases/latest/download/xemu-win-x86_64-release.zip";
|
||||
#define PACKAGE_ARCH "x86_64"
|
||||
#elif defined(__aarch64__)
|
||||
const char *download_url = "https://github.com/xemu-project/xemu/releases/latest/download/xemu-win-aarch64-release.zip";
|
||||
#define PACKAGE_ARCH "arm64"
|
||||
#else
|
||||
#error Unknown update path
|
||||
#error Unhandled package arch
|
||||
#endif
|
||||
#else
|
||||
FIXME
|
||||
#endif
|
||||
|
||||
|
||||
#define DPRINTF(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__);
|
||||
|
||||
@@ -89,6 +88,7 @@ void AutoUpdateWindow::Draw()
|
||||
}
|
||||
|
||||
if (updater.is_updating()) {
|
||||
ImGui::Dummy(ImVec2(0.0f, ImGui::GetStyle().ItemSpacing.y));
|
||||
ImGui::ProgressBar(updater.get_update_progress_percentage()/100.0f,
|
||||
ImVec2(-1.0f, 0.0f));
|
||||
}
|
||||
@@ -129,7 +129,7 @@ Updater::Updater()
|
||||
m_status = UPDATER_IDLE;
|
||||
m_update_availability = UPDATE_AVAILABILITY_UNKNOWN;
|
||||
m_update_percentage = 0;
|
||||
m_latest_version = "Unknown";
|
||||
m_release_version = "Unknown";
|
||||
m_should_cancel = false;
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ void *Updater::checker_thread_worker_func(void *updater)
|
||||
void Updater::check_for_update_internal()
|
||||
{
|
||||
g_autoptr(GByteArray) data = g_byte_array_new();
|
||||
int res = http_get(version_url, data, NULL, NULL);
|
||||
int res = http_get(releases_url, data, NULL, NULL);
|
||||
|
||||
if (m_should_cancel) {
|
||||
m_should_cancel = false;
|
||||
@@ -163,12 +163,39 @@ void Updater::check_for_update_internal()
|
||||
goto finished;
|
||||
}
|
||||
|
||||
m_latest_version = std::string((const char *)data->data, data->len);
|
||||
try {
|
||||
json release = json::parse(std::string((const char *)data->data, data->len));
|
||||
m_release_url = release.value("html_url", "https://github.com/xemu-project/xemu/releases/latest");
|
||||
m_release_version = release["tag_name"].get<std::string>();
|
||||
if (!m_release_version.empty() && m_release_version[0] == 'v') {
|
||||
m_release_version = m_release_version.substr(1);
|
||||
}
|
||||
|
||||
if (m_latest_version != xemu_version) {
|
||||
m_update_availability = UPDATE_AVAILABLE;
|
||||
} else {
|
||||
m_update_availability = UPDATE_NOT_AVAILABLE;
|
||||
m_release_package_url.clear();
|
||||
std::string expected_filename = "xemu-" + m_release_version + "-windows-" PACKAGE_ARCH ".zip";
|
||||
for (const auto &asset : release["assets"]) {
|
||||
std::string name = asset["name"].get<std::string>();
|
||||
if (name == expected_filename) {
|
||||
m_release_package_url = asset["browser_download_url"].get<std::string>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_release_package_url.empty()) {
|
||||
DPRINTF("Could not find asset matching %s\n", expected_filename.c_str());
|
||||
m_status = UPDATER_ERROR;
|
||||
goto finished;
|
||||
}
|
||||
|
||||
if (m_release_version != xemu_version) {
|
||||
m_update_availability = UPDATE_AVAILABLE;
|
||||
} else {
|
||||
m_update_availability = UPDATE_NOT_AVAILABLE;
|
||||
}
|
||||
} catch (const json::exception &e) {
|
||||
DPRINTF("JSON parse error: %s\n", e.what());
|
||||
m_status = UPDATER_ERROR;
|
||||
goto finished;
|
||||
}
|
||||
|
||||
m_status = UPDATER_IDLE;
|
||||
@@ -215,7 +242,7 @@ void Updater::update_internal()
|
||||
return static_cast<Updater *>(info->userptr)->progress_cb(info);
|
||||
};
|
||||
|
||||
int res = http_get(download_url, data, &progress_info, NULL);
|
||||
int res = http_get(m_release_package_url.c_str(), data, &progress_info, NULL);
|
||||
|
||||
if (m_should_cancel) {
|
||||
m_should_cancel = false;
|
||||
|
||||
+5
-2
@@ -49,7 +49,9 @@ private:
|
||||
UpdateAvailability m_update_availability;
|
||||
int m_update_percentage;
|
||||
QemuThread m_thread;
|
||||
std::string m_latest_version;
|
||||
std::string m_release_version;
|
||||
std::string m_release_url;
|
||||
std::string m_release_package_url;
|
||||
bool m_should_cancel;
|
||||
UpdateStatus m_status;
|
||||
UpdaterCallback m_on_complete;
|
||||
@@ -66,7 +68,8 @@ public:
|
||||
bool is_update_available() { return m_update_availability == UPDATE_AVAILABLE; }
|
||||
bool is_checking_for_update() { return m_status == UPDATER_CHECKING_FOR_UPDATE; }
|
||||
bool is_updating() { return m_status == UPDATER_UPDATING; }
|
||||
std::string get_update_version() { return m_latest_version; }
|
||||
const std::string& get_release_version() { return m_release_version; }
|
||||
const std::string& get_release_url() { return m_release_url; }
|
||||
void cancel() { m_should_cancel = true; }
|
||||
void update();
|
||||
void update_internal();
|
||||
|
||||
+12
-1
@@ -20,6 +20,7 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/http.h"
|
||||
#include "xemu-version.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <fcntl.h>
|
||||
@@ -29,6 +30,13 @@
|
||||
|
||||
static bool libcurl_init_called = false;
|
||||
static bool libcurl_init_success = false;
|
||||
static char *xemu_user_agent = NULL;
|
||||
|
||||
static void libcurl_cleanup(void)
|
||||
{
|
||||
curl_global_cleanup();
|
||||
g_free(xemu_user_agent);
|
||||
}
|
||||
|
||||
static bool ensure_libcurl_initialized(Error **errp)
|
||||
{
|
||||
@@ -37,7 +45,8 @@ static bool ensure_libcurl_initialized(Error **errp)
|
||||
libcurl_init_called = true;
|
||||
if (res == CURLE_OK) {
|
||||
libcurl_init_success = true;
|
||||
atexit(curl_global_cleanup);
|
||||
xemu_user_agent = g_strdup_printf("xemu/%s", xemu_version);
|
||||
atexit(libcurl_cleanup);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +97,7 @@ int http_get(const char *url, GByteArray *response_body,
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_get_cb);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, response_body);
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // Follow redirects
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, xemu_user_agent);
|
||||
#if ALLOW_INSECURE_HOSTS
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
@@ -136,6 +146,7 @@ int http_post_json(const char *url, const char *json_data, Error **errp)
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, xemu_user_agent);
|
||||
#if ALLOW_INSECURE_HOSTS
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
|
||||
Reference in New Issue
Block a user