LCOV - code coverage report
Current view: top level - src/gui - gui_manager_update.cpp (source / functions) Coverage Total Hit
Test: merged.info Lines: 84.6 % 65 55
Test Date: 2026-06-01 11:15:25 Functions: 100.0 % 2 2

            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
        

Generated by: LCOV version 2.0-1