<fix, feature>(core, ui): version system upgrade.
1. can notice user withdraw version now. 2. fix software not restart when signal caught. 3. improve ui.
This commit is contained in:
parent
5cc72a35de
commit
2f64e4300b
@ -177,6 +177,7 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
} else {
|
||||
QApplication::exit(RESTART_CODE);
|
||||
QMessageBox::information(
|
||||
nullptr, _("A serious error has occurred"),
|
||||
_("Oh no! GpgFrontend caught a serious error in the software, so it "
|
||||
|
@ -8,6 +8,7 @@ aux_source_directory(./help UI_SOURCE)
|
||||
aux_source_directory(./settings UI_SOURCE)
|
||||
aux_source_directory(./function UI_SOURCE)
|
||||
aux_source_directory(./details UI_SOURCE)
|
||||
aux_source_directory(./data_struct UI_SOURCE)
|
||||
|
||||
if (SMTP_SUPPORT)
|
||||
aux_source_directory(./smtp UI_SOURCE)
|
||||
|
@ -371,8 +371,16 @@ void KeyMgmt::slotExportKeyToKeyPackage() {
|
||||
}
|
||||
|
||||
void KeyMgmt::slotExportKeyToClipboard() {
|
||||
ByteArrayPtr key_export_data = nullptr;
|
||||
|
||||
auto keys_checked = key_list_->getChecked();
|
||||
if (keys_checked->empty()) {
|
||||
QMessageBox::critical(
|
||||
this, _("Forbidden"),
|
||||
_("Please check some keys before doing this operation."));
|
||||
return;
|
||||
}
|
||||
|
||||
ByteArrayPtr key_export_data = nullptr;
|
||||
if (!GpgKeyImportExporter::GetInstance().ExportKeys(keys_checked,
|
||||
key_export_data)) {
|
||||
return;
|
||||
|
@ -117,12 +117,7 @@ void MainWindow::init() noexcept {
|
||||
emit loaded();
|
||||
|
||||
#ifdef RELEASE
|
||||
QString baseUrl =
|
||||
"https://api.github.com/repos/saturneric/gpgfrontend/releases/latest";
|
||||
QNetworkRequest request;
|
||||
request.setUrl(QUrl(baseUrl));
|
||||
auto* replay = networkAccessManager->get(request);
|
||||
auto version_thread = new VersionCheckThread(replay);
|
||||
auto version_thread = new VersionCheckThread();
|
||||
|
||||
connect(version_thread, SIGNAL(finished()), version_thread,
|
||||
SLOT(deleteLater()));
|
||||
|
@ -244,8 +244,7 @@ class MainWindow : public QMainWindow {
|
||||
/**
|
||||
* @details called when need to upgrade.
|
||||
*/
|
||||
void slotVersionUpgrade(const QString& currentVersion,
|
||||
const QString& latestVersion);
|
||||
void slotVersionUpgrade(const SoftwareVersion& version);
|
||||
|
||||
private:
|
||||
/**
|
||||
|
25
src/ui/data_struct/SoftwareVersion.cpp
Normal file
25
src/ui/data_struct/SoftwareVersion.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The initial version of the source code is inherited from gpg4usb-team.
|
||||
* Their source code version also complies with GNU General Public License.
|
||||
*
|
||||
* The source code version of this software was modified and released
|
||||
* by Saturneric<eric@bktus.com> starting on May 12, 2021.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "SoftwareVersion.h"
|
53
src/ui/data_struct/SoftwareVersion.h
Normal file
53
src/ui/data_struct/SoftwareVersion.h
Normal file
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The initial version of the source code is inherited from gpg4usb-team.
|
||||
* Their source code version also complies with GNU General Public License.
|
||||
*
|
||||
* The source code version of this software was modified and released
|
||||
* by Saturneric<eric@bktus.com> starting on May 12, 2021.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GPGFRONTEND_SOFTWAREVERSION_H
|
||||
#define GPGFRONTEND_SOFTWAREVERSION_H
|
||||
|
||||
#include <boost/date_time.hpp>
|
||||
|
||||
namespace GpgFrontend::UI {
|
||||
struct SoftwareVersion {
|
||||
std::string latest_version;
|
||||
std::string current_version;
|
||||
bool latest_prerelease = false;
|
||||
bool latest_draft = false;
|
||||
bool current_prerelease = false;
|
||||
bool current_draft = false;
|
||||
bool load_info_done = false;
|
||||
std::string publish_date;
|
||||
std::string release_note;
|
||||
|
||||
[[nodiscard]] bool NeedUpgrade() const {
|
||||
return load_info_done && !latest_prerelease && !latest_draft &&
|
||||
current_version < latest_version;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool VersionWithDrawn() const {
|
||||
return load_info_done && current_prerelease && !current_draft;
|
||||
}
|
||||
};
|
||||
} // namespace GpgFrontend::UI
|
||||
|
||||
#endif // GPGFRONTEND_SOFTWAREVERSION_H
|
@ -24,8 +24,7 @@
|
||||
|
||||
#include "VersionCheckThread.h"
|
||||
|
||||
#include <iterator>
|
||||
#include <regex>
|
||||
#include <QMetaType>
|
||||
|
||||
#include "GpgFrontendBuildInfo.h"
|
||||
#include "json/json.hpp"
|
||||
@ -33,45 +32,97 @@
|
||||
namespace GpgFrontend::UI {
|
||||
|
||||
void VersionCheckThread::run() {
|
||||
using namespace nlohmann;
|
||||
|
||||
LOG(INFO) << "get latest version from Github";
|
||||
|
||||
auto current_version = std::string("v") + std::to_string(VERSION_MAJOR) +
|
||||
"." + std::to_string(VERSION_MINOR) + "." +
|
||||
std::to_string(VERSION_PATCH);
|
||||
|
||||
while (mNetworkReply->isRunning()) {
|
||||
QApplication::processEvents();
|
||||
}
|
||||
auto manager = new QNetworkAccessManager(nullptr);
|
||||
|
||||
if (mNetworkReply->error() != QNetworkReply::NoError) {
|
||||
LOG(INFO) << "current version" << current_version;
|
||||
|
||||
std::string latest_version_url =
|
||||
"https://api.github.com/repos/saturneric/gpgfrontend/releases/latest";
|
||||
|
||||
std::string current_version_url =
|
||||
"https://api.github.com/repos/saturneric/gpgfrontend/releases/tags/" +
|
||||
current_version;
|
||||
|
||||
QNetworkRequest latest_request, current_request;
|
||||
latest_request.setUrl(QUrl(latest_version_url.c_str()));
|
||||
current_request.setUrl(QUrl(current_version_url.c_str()));
|
||||
auto reply = manager->get(latest_request);
|
||||
while (reply->isRunning()) QApplication::processEvents();
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
LOG(ERROR) << "network error";
|
||||
manager->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
auto bytes = mNetworkReply->readAll();
|
||||
|
||||
auto reply_json = nlohmann::json::parse(bytes.toStdString());
|
||||
|
||||
std::string latest_version = reply_json["tag_name"];
|
||||
|
||||
LOG(INFO) << "latest version from Github" << latest_version;
|
||||
|
||||
QRegularExpression re(R"(^[vV](\d+\.)?(\d+\.)?(\*|\d+))");
|
||||
auto version_match = re.match(latest_version.c_str());
|
||||
if (version_match.hasMatch()) {
|
||||
latest_version = version_match.captured(0).toStdString();
|
||||
LOG(INFO) << "latest version matched" << latest_version;
|
||||
} else {
|
||||
latest_version = current_version;
|
||||
LOG(WARNING) << "latest version unknown";
|
||||
latest_reply_bytes_ = reply->readAll();
|
||||
reply = manager->get(current_request);
|
||||
while (reply->isRunning()) QApplication::processEvents();
|
||||
current_reply_bytes_ = reply->readAll();
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
LOG(ERROR) << "network error";
|
||||
manager->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
emit upgradeVersion(current_version.c_str(), latest_version.c_str());
|
||||
SoftwareVersion version;
|
||||
version.current_version = current_version;
|
||||
|
||||
try {
|
||||
using namespace nlohmann;
|
||||
|
||||
auto latest_reply_json =
|
||||
nlohmann::json::parse(latest_reply_bytes_.toStdString());
|
||||
auto current_reply_json =
|
||||
nlohmann::json::parse(current_reply_bytes_.toStdString());
|
||||
|
||||
std::string latest_version = latest_reply_json["tag_name"];
|
||||
|
||||
LOG(INFO) << "latest version from Github" << latest_version;
|
||||
|
||||
QRegularExpression re(R"(^[vV](\d+\.)?(\d+\.)?(\*|\d+))");
|
||||
auto version_match = re.match(latest_version.c_str());
|
||||
if (version_match.hasMatch()) {
|
||||
latest_version = version_match.captured(0).toStdString();
|
||||
LOG(INFO) << "latest version matched" << latest_version;
|
||||
} else {
|
||||
latest_version = current_version;
|
||||
LOG(WARNING) << "latest version unknown";
|
||||
}
|
||||
|
||||
bool prerelease = latest_reply_json["prerelease"],
|
||||
draft = latest_reply_json["draft"];
|
||||
std::string publish_date = latest_reply_json["published_at"];
|
||||
std::string release_note = latest_reply_json["body"];
|
||||
version.latest_version = latest_version;
|
||||
version.latest_prerelease = prerelease;
|
||||
version.latest_draft = draft;
|
||||
version.publish_date = publish_date;
|
||||
version.release_note = release_note;
|
||||
|
||||
bool current_prerelease = current_reply_json["prerelease"],
|
||||
current_draft = current_reply_json["draft"];
|
||||
version.latest_prerelease = current_prerelease;
|
||||
version.latest_draft = current_draft;
|
||||
|
||||
// loading done
|
||||
version.load_info_done = true;
|
||||
|
||||
} catch (...) {
|
||||
LOG(INFO) << "error occurred";
|
||||
version.load_info_done = false;
|
||||
}
|
||||
|
||||
manager->deleteLater();
|
||||
|
||||
emit upgradeVersion(version);
|
||||
}
|
||||
|
||||
VersionCheckThread::VersionCheckThread(QNetworkReply* networkReply)
|
||||
: mNetworkReply(networkReply) {}
|
||||
VersionCheckThread::VersionCheckThread() : QThread(nullptr) {
|
||||
qRegisterMetaType<SoftwareVersion>("SoftwareVersion");
|
||||
};
|
||||
|
||||
} // namespace GpgFrontend::UI
|
||||
|
@ -26,6 +26,7 @@
|
||||
#define GPGFRONTEND_VERSIONCHECKTHREAD_H
|
||||
|
||||
#include "ui/GpgFrontendUI.h"
|
||||
#include "ui/data_struct/SoftwareVersion.h"
|
||||
|
||||
namespace GpgFrontend::UI {
|
||||
|
||||
@ -33,18 +34,17 @@ class VersionCheckThread : public QThread {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit VersionCheckThread(QNetworkReply* networkReply);
|
||||
explicit VersionCheckThread();
|
||||
|
||||
signals:
|
||||
|
||||
void upgradeVersion(const QString& currentVersion,
|
||||
const QString& latestVersion);
|
||||
void upgradeVersion(SoftwareVersion version);
|
||||
|
||||
protected:
|
||||
void run() override;
|
||||
|
||||
private:
|
||||
QNetworkReply* mNetworkReply;
|
||||
QByteArray latest_reply_bytes_, current_reply_bytes_;
|
||||
};
|
||||
|
||||
} // namespace GpgFrontend::UI
|
||||
|
@ -163,14 +163,6 @@ UpdateTab::UpdateTab(QWidget* parent) : QWidget(parent) {
|
||||
latestVersionLabel->setWordWrap(true);
|
||||
|
||||
upgradeLabel = new QLabel();
|
||||
upgradeLabel->setText(
|
||||
"<center>" +
|
||||
QString(_("The current version is less than the latest version on "
|
||||
"github.")) +
|
||||
"</center><center>" + _("Please click") +
|
||||
" <a "
|
||||
"href=\"https://github.com/saturneric/GpgFrontend/releases\">" +
|
||||
_("Here") + "</a> " + _("to download the latest version.") + "</center>");
|
||||
upgradeLabel->setWordWrap(true);
|
||||
upgradeLabel->setOpenExternalLinks(true);
|
||||
upgradeLabel->setHidden(true);
|
||||
@ -196,11 +188,7 @@ void UpdateTab::getLatestVersion() {
|
||||
|
||||
LOG(INFO) << _("try to get latest version");
|
||||
|
||||
QString base_url =
|
||||
"https://api.github.com/repos/saturneric/gpgfrontend/releases/latest";
|
||||
QNetworkRequest request;
|
||||
request.setUrl(QUrl(base_url));
|
||||
auto version_thread = new VersionCheckThread(manager->get(request));
|
||||
auto version_thread = new VersionCheckThread();
|
||||
|
||||
connect(version_thread, SIGNAL(finished()), version_thread,
|
||||
SLOT(deleteLater()));
|
||||
@ -210,16 +198,33 @@ void UpdateTab::getLatestVersion() {
|
||||
version_thread->start();
|
||||
}
|
||||
|
||||
void UpdateTab::slotShowVersionStatus(const QString& current,
|
||||
const QString& server) {
|
||||
void UpdateTab::slotShowVersionStatus(const SoftwareVersion& version) {
|
||||
this->pb->setHidden(true);
|
||||
|
||||
latestVersionLabel->setText("<center><b>" +
|
||||
QString(_("Latest Version From Github")) + ": " +
|
||||
server + "</b></center>");
|
||||
version.latest_version.c_str() + "</b></center>");
|
||||
|
||||
if (current < server) {
|
||||
if (version.NeedUpgrade()) {
|
||||
upgradeLabel->setText(
|
||||
"<center>" +
|
||||
QString(_("The current version is less than the latest version on "
|
||||
"github.")) +
|
||||
"</center><center>" + _("Please click") +
|
||||
" <a "
|
||||
"href=\"https://github.com/saturneric/GpgFrontend/releases\">" +
|
||||
_("Here") + "</a> " + _("to download the latest stable version.") +
|
||||
"</center>");
|
||||
upgradeLabel->show();
|
||||
} else if (version.VersionWithDrawn()) {
|
||||
upgradeLabel->setText(
|
||||
"<center>" +
|
||||
QString(_("This version has serious problems and has been withdrawn. "
|
||||
"Please stop using it immediately.")) +
|
||||
"</center><center>" + _("Please click") +
|
||||
" <a "
|
||||
"href=\"https://github.com/saturneric/GpgFrontend/releases\">" +
|
||||
_("Here") + "</a> " + _("to download the latest stable version.") +
|
||||
"</center>");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,8 @@
|
||||
|
||||
#include "gpg/GpgContext.h"
|
||||
#include "ui/GpgFrontendUI.h"
|
||||
#include "ui/data_struct/SoftwareVersion.h"
|
||||
|
||||
namespace GpgFrontend::UI {
|
||||
|
||||
/**
|
||||
@ -73,7 +75,7 @@ class UpdateTab : public QWidget {
|
||||
void getLatestVersion();
|
||||
|
||||
private slots:
|
||||
void slotShowVersionStatus(const QString& current, const QString& server);
|
||||
void slotShowVersionStatus(const SoftwareVersion& version);
|
||||
|
||||
signals:
|
||||
void replyFromUpdateServer(QByteArray data);
|
||||
|
@ -499,13 +499,12 @@ void MainWindow::uploadKeyToServer() {
|
||||
|
||||
void MainWindow::slotOpenFile(QString& path) { edit->slotOpenFile(path); }
|
||||
|
||||
void MainWindow::slotVersionUpgrade(const QString& currentVersion,
|
||||
const QString& latestVersion) {
|
||||
void MainWindow::slotVersionUpgrade(const SoftwareVersion& version) {
|
||||
LOG(INFO) << _("called");
|
||||
if (currentVersion < latestVersion) {
|
||||
if (version.NeedUpgrade()) {
|
||||
statusBar()->showMessage(
|
||||
QString(_("GpgFrontend Upgradeable (New Version: %1)."))
|
||||
.arg(latestVersion),
|
||||
.arg(version.latest_version.c_str()),
|
||||
30000);
|
||||
auto update_button = new QPushButton("Update GpgFrontend", this);
|
||||
connect(update_button, &QPushButton::clicked, [=]() {
|
||||
@ -513,17 +512,19 @@ void MainWindow::slotVersionUpgrade(const QString& currentVersion,
|
||||
about_dialog->show();
|
||||
});
|
||||
statusBar()->addPermanentWidget(update_button, 0);
|
||||
} else if (currentVersion > latestVersion) {
|
||||
} else if (version.VersionWithDrawn()) {
|
||||
QMessageBox::warning(
|
||||
this, _("Unreleased Version"),
|
||||
this, _("Withdrawn Version"),
|
||||
QString(
|
||||
_("This version(%1) has not been officially released and is not "
|
||||
"recommended for use in a production environment. <br/>"))
|
||||
.arg(currentVersion) +
|
||||
QString(
|
||||
_("You can download the latest version(%1) on Github Releases "
|
||||
"Page.<br/>"))
|
||||
.arg(latestVersion));
|
||||
_("This version(%1) may have been withdrawn by the developer due "
|
||||
"to serious problems. Please stop using this version "
|
||||
"immediately and use the latest stable version."))
|
||||
.arg(version.current_version.c_str()) +
|
||||
"<br/>" +
|
||||
QString(_("You can download the latest stable version(%1) on "
|
||||
"Github Releases "
|
||||
"Page.<br/>"))
|
||||
.arg(version.latest_version.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,16 +451,6 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="saveDraftButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save Draft</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignRight">
|
||||
<widget class="QPushButton" name="sendMailButton">
|
||||
<property name="text">
|
||||
|
Loading…
x
Reference in New Issue
Block a user