Line data Source code
1 : #include "gui/gui_manager.h"
2 : #include <cstdio>
3 : #include <string>
4 : #include <vector>
5 : #include <algorithm>
6 :
7 : namespace Amplitron {
8 :
9 3 : void GuiManager::check_for_updates() {
10 : #ifndef AMPLITRON_NO_DESKTOP_SHELL
11 3 : FILE* pipe = nullptr;
12 : #ifdef _WIN32
13 1 : pipe = _popen("curl -s --fail --connect-timeout 5 --max-time 10 https://api.github.com/repos/sudip-mondal-2002/Amplitron/releases", "r");
14 : #else
15 2 : pipe = popen("curl -s --fail --connect-timeout 5 --max-time 10 https://api.github.com/repos/sudip-mondal-2002/Amplitron/releases", "r");
16 : #endif
17 :
18 3 : if (!pipe) return;
19 :
20 3 : std::string result = "";
21 1 : char buffer[256];
22 13620 : while (!feof(pipe)) {
23 13615 : if (fgets(buffer, 256, pipe) != nullptr)
24 20420 : result += buffer;
25 : }
26 : #ifdef _WIN32
27 1 : int ret = _pclose(pipe);
28 : #else
29 2 : int ret = pclose(pipe);
30 : #endif
31 :
32 : // If curl failed, discard the result and return
33 3 : if (ret != 0) return;
34 :
35 2 : std::string search_str = "\"tag_name\": \"";
36 2 : size_t pos = result.find(search_str);
37 2 : if (pos != std::string::npos) {
38 2 : pos += search_str.length();
39 2 : size_t end_pos = result.find("\"", pos);
40 2 : if (end_pos != std::string::npos) {
41 2 : std::string latest_version = result.substr(pos, end_pos - pos);
42 :
43 3 : std::string html_url = "";
44 2 : std::string url_search_str = "\"html_url\": \"";
45 2 : size_t url_pos = result.find(url_search_str);
46 2 : if (url_pos != std::string::npos) {
47 2 : url_pos += url_search_str.length();
48 2 : size_t url_end_pos = result.find("\"", url_pos);
49 2 : if (url_end_pos != std::string::npos) {
50 2 : html_url = result.substr(url_pos, url_end_pos - url_pos);
51 0 : }
52 0 : }
53 :
54 5 : auto parse_version = [](const std::string& v) -> std::vector<int> {
55 4 : std::vector<int> parts;
56 4 : std::string s = v;
57 4 : if (!s.empty() && s[0] == 'v') s = s.substr(1);
58 2 : size_t pos = 0;
59 16 : while (pos < s.size()) {
60 12 : size_t dot = s.find('.', pos);
61 12 : if (dot == std::string::npos) dot = s.size();
62 18 : try { parts.push_back(std::stoi(s.substr(pos, dot - pos))); }
63 0 : catch (...) { parts.push_back(0); }
64 12 : pos = dot + 1;
65 : }
66 6 : return parts;
67 4 : };
68 :
69 2 : std::string current_version = "v" AMPLITRON_VERSION;
70 2 : if (!latest_version.empty()) {
71 2 : auto latest_parts = parse_version(latest_version);
72 2 : auto current_parts = parse_version(current_version);
73 2 : bool is_newer = false;
74 2 : size_t max_len = std::max(latest_parts.size(), current_parts.size());
75 6 : for (size_t i = 0; i < max_len; ++i) {
76 6 : int lv = (i < latest_parts.size()) ? latest_parts[i] : 0;
77 6 : int cv = (i < current_parts.size()) ? current_parts[i] : 0;
78 6 : if (lv > cv) { is_newer = true; break; }
79 6 : if (lv < cv) { break; }
80 0 : }
81 2 : if (is_newer) {
82 0 : std::lock_guard<std::mutex> lock(update_mutex_);
83 0 : new_release_version_ = latest_version;
84 0 : new_release_url_ = html_url;
85 0 : has_new_release_ = true;
86 0 : }
87 2 : }
88 2 : }
89 0 : }
90 : #endif
91 3 : }
92 :
93 : } // namespace Amplitron
|