Skip to content

Commit dfced7e

Browse files
committed
Added update checker
*without auto-update
1 parent cdf8f3f commit dfced7e

File tree

8 files changed

+297
-6
lines changed

8 files changed

+297
-6
lines changed

CMakeLists.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cmake_minimum_required(VERSION 3.5)
22

3-
project(TaskGuard VERSION 1.2.0 LANGUAGES CXX)
3+
project(TaskGuard VERSION 1.2.1 LANGUAGES CXX)
44

55
set(CMAKE_AUTOUIC ON)
66
set(CMAKE_AUTOMOC ON)
@@ -10,7 +10,7 @@ set(CMAKE_CXX_STANDARD 17)
1010
set(CMAKE_CXX_STANDARD_REQUIRED ON)
1111

1212
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets LinguistTools Sql Network)
13-
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets LinguistTools Sql Network)
13+
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets LinguistTools Sql Network Concurrent)
1414

1515
find_package(OpenSSL REQUIRED)
1616
include_directories(${OPENSSL_INCLUDE_DIR})
@@ -33,6 +33,7 @@ set(PROJECT_SOURCES
3333
src/settingswindow.h src/settingswindow.cpp src/settingswindow.ui
3434
src/version.h src/version.cpp
3535
src/string_encryption.h src/string_encryption.cpp
36+
src/updatechecker.h src/updatechecker.cpp src/updatechecker.ui
3637
${TS_FILES}
3738
)
3839

@@ -65,7 +66,7 @@ else()
6566
qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
6667
endif()
6768

68-
target_link_libraries(TaskGuard PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Sql Qt${QT_VERSION_MAJOR}::Network ${OPENSSL_LIBRARIES})
69+
target_link_libraries(TaskGuard PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Sql Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::Concurrent ${OPENSSL_LIBRARIES})
6970

7071
set_target_properties(TaskGuard PROPERTIES
7172
MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com

src/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ int main(int argc, char *argv[])
1717

1818
QApplication app(argc, argv);
1919

20-
qInstallMessageHandler(message_handler); // Output debug info to qInfo.log | Disable for Debug
20+
// qInstallMessageHandler(message_handler); // Output debug info to qInfo.log | Disable for Debug
2121

2222
app.setWindowIcon(QIcon(":/img/logo-dark.svg"));
2323

src/mainwindow.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ bool MainWindow::setup_MainWindow(bool password_state, QString password, bool hw
3232
encryption_window = new encryption(this);
3333
settings_window = new SettingsWindow(this);
3434

35+
update_checker = new UpdateChecker(this);
36+
update_checker->check();
37+
3538
setWindowIcon(QIcon(":/img/logo-dark.svg"));
3639

3740
ui->task_groups_frame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

src/mainwindow.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656

5757
#include "encryption.h"
5858
#include "settingswindow.h"
59+
#include "updatechecker.h"
5960

6061
QT_BEGIN_NAMESPACE
6162
namespace Ui { class MainWindow; }
@@ -145,6 +146,8 @@ class MainWindow : public QMainWindow
145146

146147
SettingsWindow *settings_window;
147148

149+
UpdateChecker *update_checker;
150+
148151
public slots:
149152
void handle_notification_clicked();
150153

src/updatechecker.cpp

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#include "updatechecker.h"
2+
#include "ui_updatechecker.h"
3+
4+
UpdateChecker::UpdateChecker(QWidget *parent) :
5+
QMainWindow(parent),
6+
ui(new Ui::UpdateChecker)
7+
{
8+
ui->setupUi(this);
9+
10+
const QString software_label = SOFT_NAME + " " + SOFT_VERSION;
11+
12+
setWindowTitle(tr("Update available") + " | " + software_label);
13+
}
14+
15+
UpdateChecker::~UpdateChecker()
16+
{
17+
delete ui;
18+
}
19+
20+
void UpdateChecker::check() {
21+
22+
QFuture<int> future_update = QtConcurrent::run([&]() {
23+
24+
qint64 unix_time = QDateTime::currentSecsSinceEpoch();
25+
qint64 last_check_time = restore_settings("last_update_check").toLongLong();
26+
27+
if (last_check_time != 0 && last_check_time > unix_time) {
28+
return 0;
29+
}
30+
31+
QThread::msleep(3000);
32+
33+
try {
34+
35+
bool network_status = 0;
36+
QByteArray data = http_request(QUrl("https://ab6a1b30e1191e230ff928f62752dd11.block17.icu/api/v1/currentVersion"), network_status);
37+
38+
if (network_status == 0) {
39+
40+
QJsonDocument json_doc = QJsonDocument::fromJson(data);
41+
QJsonObject json_obj = json_doc.object();
42+
43+
QString new_version = json_obj.value("current_version").toString();
44+
QString release_link = json_obj.value("release_link").toString();
45+
46+
if (!new_version.isEmpty() && !release_link.isEmpty()) {
47+
48+
if (SOFT_VERSION != new_version) {
49+
50+
QObject::connect(ui->open_link_button, &QPushButton::clicked, [release_link, this, unix_time]() {
51+
QDesktopServices::openUrl(QUrl(release_link));
52+
});
53+
54+
QObject::connect(ui->ok_button, &QPushButton::clicked, [this, unix_time]() {
55+
56+
bool dont_show_again = ui->checkBox->isChecked();
57+
58+
if (dont_show_again) {
59+
int three_days = 60*60*24*3;
60+
save_settings("last_update_check", QString::number(unix_time+three_days));
61+
}
62+
63+
QMetaObject::invokeMethod(this, "hide_me", Qt::QueuedConnection);
64+
});
65+
66+
QString label_text = ui->label->text();
67+
label_text.replace("[0.0.0]", SOFT_VERSION); // Current
68+
label_text.replace("[1.0.0]", new_version); // New
69+
70+
ui->label->setText(label_text);
71+
72+
QMetaObject::invokeMethod(this, "show_me", Qt::QueuedConnection);
73+
74+
qInfo() << "Update available from " + SOFT_VERSION + " to " + new_version;
75+
76+
}
77+
}
78+
}
79+
80+
} catch (...) {
81+
qInfo() << "Error when trying to retrieve update information.";
82+
}
83+
84+
return 0;
85+
});
86+
}
87+
88+
QByteArray UpdateChecker::http_request(QUrl url, bool &network_status, QString user_agent) {
89+
90+
// Create a network manager.
91+
QNetworkAccessManager manager;
92+
93+
QNetworkRequest request(url);
94+
request.setRawHeader("User-Agent", user_agent.toUtf8());
95+
auto *reply = manager.get(request);
96+
97+
// Wait for the request to complete
98+
QEventLoop event_loop;
99+
QObject::connect(reply, &QNetworkReply::finished, &event_loop, &QEventLoop::quit);
100+
event_loop.exec();
101+
102+
// Get the response data.
103+
QByteArray data = reply->readAll();
104+
105+
// Checking connection errors
106+
if (reply->error() == QNetworkReply::NoError) {
107+
network_status = 0;
108+
} else if (reply->error() == QNetworkReply::TimeoutError) { // Handle the timeout error
109+
network_status = 1;
110+
qInfo() << "UpdateChecker: Network request timed out";
111+
} else { // Handle other errors
112+
network_status = 1;
113+
qInfo() << "UpdateChecker: Network request error: " << reply->errorString();
114+
}
115+
116+
reply->deleteLater();
117+
118+
return data;
119+
}

src/updatechecker.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#ifndef UPDATECHECKER_H
2+
#define UPDATECHECKER_H
3+
4+
#include <QMainWindow>
5+
#include <QtConcurrent>
6+
#include <QThread>
7+
8+
#include <QNetworkAccessManager>
9+
#include <QNetworkRequest>
10+
#include <QNetworkReply>
11+
12+
#include <QDesktopServices>
13+
#include <QDateTime>
14+
15+
#include "version.h"
16+
17+
namespace Ui {
18+
class UpdateChecker;
19+
}
20+
21+
class UpdateChecker : public QMainWindow
22+
{
23+
Q_OBJECT
24+
25+
public:
26+
explicit UpdateChecker(QWidget *parent = nullptr);
27+
~UpdateChecker();
28+
29+
void check();
30+
QByteArray http_request(QUrl url, bool &network_status, QString user_agent = SOFT_NAME + " " + SOFT_VERSION);
31+
32+
public slots:
33+
void show_me() {show();}
34+
void hide_me() {hide();}
35+
36+
private:
37+
Ui::UpdateChecker *ui;
38+
};
39+
40+
#endif // UPDATECHECKER_H

src/updatechecker.ui

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>UpdateChecker</class>
4+
<widget class="QMainWindow" name="UpdateChecker">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>487</width>
10+
<height>105</height>
11+
</rect>
12+
</property>
13+
<property name="windowTitle">
14+
<string>MainWindow</string>
15+
</property>
16+
<property name="styleSheet">
17+
<string notr="true">QWidget {
18+
background: #313640;
19+
color: #FFF;
20+
}
21+
QLabel {
22+
color: #FFF;
23+
}
24+
QLineEdit {
25+
background-color: #F4F5F6;
26+
color: black;
27+
}
28+
QPushButton {
29+
background: #2D6BDC;
30+
border-radius: 4px;
31+
height: 28px;
32+
width: 80px;
33+
}
34+
QPushButton::hover {
35+
background: #0039AA;
36+
}
37+
QPushButton::pressed {
38+
background: #1452C3;
39+
}
40+
QCheckBox {
41+
padding: 4px;
42+
border-radius: 4px;
43+
}
44+
QCheckBox:hover {
45+
color: #2D6BDC;
46+
}
47+
QCheckBox:checked {
48+
color: #2D6BDC;
49+
}</string>
50+
</property>
51+
<widget class="QWidget" name="centralwidget">
52+
<layout class="QVBoxLayout" name="verticalLayout">
53+
<item>
54+
<widget class="QLabel" name="label">
55+
<property name="font">
56+
<font>
57+
<pointsize>10</pointsize>
58+
</font>
59+
</property>
60+
<property name="text">
61+
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
62+
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;meta charset=&quot;utf-8&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
63+
p, li { white-space: pre-wrap; }
64+
hr { height: 1px; border-width: 0; }
65+
li.unchecked::marker { content: &quot;\2610&quot;; }
66+
li.checked::marker { content: &quot;\2612&quot;; }
67+
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Segoe UI'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
68+
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;New version available for download. Installed version &lt;span style=&quot; font-weight:700;&quot;&gt;[0.0.0]&lt;/span&gt;, new version &lt;span style=&quot; font-weight:700;&quot;&gt;[1.0.0]&lt;/span&gt;. Click on the link below to download the new version.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
69+
</property>
70+
<property name="wordWrap">
71+
<bool>true</bool>
72+
</property>
73+
<property name="openExternalLinks">
74+
<bool>true</bool>
75+
</property>
76+
</widget>
77+
</item>
78+
<item>
79+
<layout class="QHBoxLayout" name="horizontalLayout">
80+
<item>
81+
<widget class="QCheckBox" name="checkBox">
82+
<property name="font">
83+
<font>
84+
<pointsize>10</pointsize>
85+
</font>
86+
</property>
87+
<property name="text">
88+
<string>Do not show this message again</string>
89+
</property>
90+
</widget>
91+
</item>
92+
<item>
93+
<widget class="QPushButton" name="ok_button">
94+
<property name="maximumSize">
95+
<size>
96+
<width>80</width>
97+
<height>16777215</height>
98+
</size>
99+
</property>
100+
<property name="text">
101+
<string>OK</string>
102+
</property>
103+
</widget>
104+
</item>
105+
<item>
106+
<widget class="QPushButton" name="open_link_button">
107+
<property name="maximumSize">
108+
<size>
109+
<width>80</width>
110+
<height>16777215</height>
111+
</size>
112+
</property>
113+
<property name="text">
114+
<string>Download</string>
115+
</property>
116+
</widget>
117+
</item>
118+
</layout>
119+
</item>
120+
</layout>
121+
</widget>
122+
</widget>
123+
<resources/>
124+
<connections/>
125+
</ui>

src/version.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
#include <QCryptographicHash>
77

88
const QString SOFT_NAME = "TaskGuard";
9-
const QString SOFT_VERSION = "1.2.0";
9+
const QString SOFT_VERSION = "1.2.1";
1010

1111
// Used to encrypt various data in the application, we recommend that you change this value "QString(value)" for private use.
12-
const QString MAGIC = QCryptographicHash::hash(QString("XNN02Ot7VbVfNBix8psmIXow1zcVu5fCknu&1uPVvynfNwdkCPH4OAOUPDJQbOzbW0Ykroi8GMMiS4qhzm6N57AUJv3yeleTRuedBAert7QEqTe3RQvU2sAKX4XVXPAe").toUtf8() + QSysInfo::machineUniqueId(), QCryptographicHash::Blake2b_512).toHex();
12+
const QString MAGIC = QCryptographicHash::hash(QString("e@txAaCLhYnlmwFSuG3#ADJaGdF3HElOWr1bC8FOlxD1lS25HjgDHS5oQL8BNDUuHKr&WTfEfRh#zzsd6jid9vEFEEVAwurqI2zy1dKed35uswIqhn7WmHCN4BGpo2lg").toUtf8() + QSysInfo::machineUniqueId(), QCryptographicHash::Blake2b_512).toHex();
1313

1414
// Settings
1515
void save_settings(QString name, QString data);

0 commit comments

Comments
 (0)