diff options
author | saturneric <[email protected]> | 2025-05-31 23:18:00 +0000 |
---|---|---|
committer | saturneric <[email protected]> | 2025-05-31 23:18:00 +0000 |
commit | 872c57068f22a25580a99504f216c30993b4b2a1 (patch) | |
tree | 82b6ef3a6fc80a438633828898bde7610bb7f0fd /src/m_ver_check/GitHubVersionCheckTask.cpp | |
parent | fix: use register_module (diff) | |
download | Modules-872c57068f22a25580a99504f216c30993b4b2a1.tar.gz Modules-872c57068f22a25580a99504f216c30993b4b2a1.zip |
feat(ver_check): add bktus version check support
- implement BKTUSVersionCheckTask for bktus.com version checking
- refactor version checking logic into Utils.cpp
- update version checking module to support multiple sources
- improve version status display messages
Diffstat (limited to 'src/m_ver_check/GitHubVersionCheckTask.cpp')
-rw-r--r-- | src/m_ver_check/GitHubVersionCheckTask.cpp | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/src/m_ver_check/GitHubVersionCheckTask.cpp b/src/m_ver_check/GitHubVersionCheckTask.cpp new file mode 100644 index 0000000..3a1419a --- /dev/null +++ b/src/m_ver_check/GitHubVersionCheckTask.cpp @@ -0,0 +1,180 @@ +/** + * Copyright (C) 2021-2024 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GitHubVersionCheckTask.h" + +#include <GFSDKBasic.h> +#include <GFSDKExtra.h> +#include <GFSDKLog.h> +#include <qobject.h> + +#include <QMetaType> +#include <QtNetwork> + +#include "GFModuleCommonUtils.hpp" +#include "SoftwareVersion.h" +#include "Utils.h" +#include "VersionCheckingModule.h" + +GitHubVersionCheckTask::GitHubVersionCheckTask() + : network_manager_(new QNetworkAccessManager(this)), + current_version_(GFProjectVersion()) { + qRegisterMetaType<SoftwareVersion>("SoftwareVersion"); + version_meta_data_.current_version = current_version_; + version_meta_data_.local_commit_hash = GFProjectGitCommitHash(); +} + +auto GitHubVersionCheckTask::Run() -> int { + QString base_url = "https://api.github.com/repos/saturneric/gpgfrontend"; + QList<QUrl> urls = { + {base_url + "/releases/latest"}, + {base_url + "/releases/tags/" + current_version_}, + {base_url + "/git/ref/tags/" + current_version_}, + }; + + connect(network_manager_, &QNetworkAccessManager::finished, this, + &GitHubVersionCheckTask::slot_parse_reply); + + for (const QUrl& url : urls) { + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::UserAgentHeader, + GFHttpRequestUserAgent()); + QNetworkReply* reply = network_manager_->get(request); + replies_.append(reply); + } + + return 0; +} + +void GitHubVersionCheckTask::slot_parse_reply(QNetworkReply* reply) { + if (reply->error() == QNetworkReply::NoError) { + FLOG_DEBUG("get reply from url: %1", reply->url().toString()); + switch (replies_.indexOf(reply)) { + case 0: + slot_parse_latest_version_info(reply); + break; + case 1: + slot_parse_current_version_info(reply); + break; + case 2: + slot_parse_current_tag_info(reply); + break; + default: + break; + } + } else { + FLOG_DEBUG("get reply from url: %1, error: %2 %3", reply->url().toString(), + reply->errorString(), reply->readAll()); + } + + replies_.removeAll(reply); + reply->deleteLater(); + + if (replies_.isEmpty()) { + FillGrtWithVersionInfo(version_meta_data_); + emit SignalUpgradeVersion(version_meta_data_); + } +} + +void GitHubVersionCheckTask::slot_parse_latest_version_info( + QNetworkReply* reply) { + if (reply == nullptr || reply->error() != QNetworkReply::NoError) { + return; + } + + auto reply_bytes = reply->readAll(); + auto latest_reply_json = QJsonDocument::fromJson(reply_bytes); + + if (!latest_reply_json.isObject()) { + FLOG_WARN("cannot parse data from github: %1", reply_bytes); + return; + } + + QString latest_version = latest_reply_json["tag_name"].toString(); + FLOG_DEBUG("raw tag name from github: %1", latest_version); + + QRegularExpression re(R"(^[vV](\d+\.)?(\d+\.)?(\*|\d+))"); + auto version_match = re.match(latest_version); + if (version_match.hasMatch()) { + latest_version = version_match.captured(0); + } else { + latest_version = ""; + FLOG_WARN("the raw tag name from github: %1 cannot match regex rules", + latest_version); + } + + auto publish_date = latest_reply_json["published_at"].toString(); + auto release_note = latest_reply_json["body"].toString(); + + version_meta_data_.latest_version = latest_version; + version_meta_data_.publish_date = publish_date; + version_meta_data_.release_note = release_note; +} + +void GitHubVersionCheckTask::slot_parse_current_version_info( + QNetworkReply* reply) { + if (reply == nullptr || reply->error() != QNetworkReply::NoError) return; + + auto reply_bytes = reply->readAll(); + auto current_reply_json = QJsonDocument::fromJson(reply_bytes); + + if (!current_reply_json.isObject()) { + FLOG_WARN("cannot parse data from github: %1", reply_bytes); + return; + } + + version_meta_data_.current_version_publish_in_remote = true; +} + +void GitHubVersionCheckTask::slot_parse_current_tag_info(QNetworkReply* reply) { + if (reply == nullptr || reply->error() != QNetworkReply::NoError) { + version_meta_data_.current_version_publish_in_remote = false; + return; + } + + version_meta_data_.current_version_publish_in_remote = true; + auto reply_bytes = reply->readAll(); + auto current_reply_json = QJsonDocument::fromJson(reply_bytes); + + if (!current_reply_json.isObject()) { + FLOG_WARN("cannot parse data from github: %1", reply_bytes); + return; + } + + auto object = current_reply_json["object"].toObject(); + if (object["type"].toString() != "commit") { + FLOG_WARN("remote tag: %1 is not a ref: %2", + version_meta_data_.current_version, object["type"].toString()); + return; + } + + auto sha = object["sha"].toString(); + version_meta_data_.remote_commit_hash_by_tag = sha.trimmed(); + FLOG_DEBUG("got remote commit hash: %1", + version_meta_data_.remote_commit_hash_by_tag); +} |