Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto update manager #18

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ log.*

# Test files
[Tt]est/
private

# *nix related
# Common convention for backup or temporary files
Expand Down
3 changes: 2 additions & 1 deletion CCR-Plus.pro
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
TEMPLATE = subdirs

SUBDIRS += ccr-plus \
src/tools/checker
src/tools/checker \
src/updater

unix: SUBDIRS += src/tools/monitor

Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions resources/image.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
<file>folder.png</file>
<file>logo.png</file>
<file>logo2.png</file>
<file>update.ico</file>
</qresource>
</RCC>
Binary file added resources/update.ico
Binary file not shown.
36 changes: 36 additions & 0 deletions resources/updater_icon.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
IDI_ICON1 ICON DISCARDABLE "update.ico"
#if defined(UNDER_CE)
#include <winbase.h>
#else
#include <winver.h>
#endif
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,1,0,0
PRODUCTVERSION 1,1,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS__WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080404b0"
BEGIN
VALUE "CompanyName", "����һ�� ��Խ��"
VALUE "FileDescription", "CCR Plus ���³���"
VALUE "ProductName", "CCR Plus"
VALUE "OriginalFilename", "upgrader.exe"
VALUE "ProductVersion", "1.1.0"
VALUE "LegalCopyright", "Copyright (C) 2017 Yuekai Jia. All Rights Reserved."
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x804, 1200
END
END
2 changes: 1 addition & 1 deletion src/CCR-Plus.pro
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,6 @@ FORMS += configure/configuredialog.ui \
RESOURCES = ../resources/image.qrc \
../resources/trans.qrc

RC_FILE = ../resources/icon.rc
RC_FILE = ../resources/CCR_icon.rc

win32: LIBS += -lpsapi
17 changes: 17 additions & 0 deletions src/mainwindow/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
#include <QToolButton>
#include <QMessageBox>
#include <QFileDialog>
#include <QProcess>
#include <QSettings>
#include <QMimeData>
#include <QCloseEvent>
#include <QDesktopServices>

#include "updater/updaterconst.h"
#include "common/global.h"
#include "common/player.h"
#include "common/problem.h"
Expand Down Expand Up @@ -66,6 +68,7 @@ MainWindow::MainWindow(QWidget* parent) :

CreateActions();
UpdateRecentContest(true);
CheckUpdates(true);

this->activateWindow();
}
Expand All @@ -90,6 +93,15 @@ void MainWindow::UnlockTable()
detail_table->Unlock();
}

void MainWindow::CheckUpdates(bool dontShowError)
{
QString dir = QCoreApplication::applicationDirPath();
QStringList arguments = { "-c", "-p" };
arguments.append(QString("%1").arg(QCoreApplication::applicationPid()));
if (dontShowError) arguments.append("-n");
QProcess::startDetached(dir + "/" + Updater::UPDATER_NAME, arguments, dir);
}

// Last contest path
static QString lastContest;

Expand Down Expand Up @@ -773,6 +785,11 @@ void MainWindow::on_action_help_triggered()

}

void MainWindow::on_action_update_triggered()
{
CheckUpdates(false);
}

void MainWindow::on_action_about_triggered()
{
QMessageBox msgBox(this);
Expand Down
4 changes: 4 additions & 0 deletions src/mainwindow/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ class MainWindow : public QMainWindow
void LockTable();
void UnlockTable();

/// 检查更新,是否只当有更新时才显示对话框
void CheckUpdates(bool dontShowError);

/// 更新最近打开的竞赛列表,是否更新 listWidget_recent
void UpdateRecentContest(bool);

Expand Down Expand Up @@ -107,6 +110,7 @@ private slots:

// Help menu actions
void on_action_help_triggered();
void on_action_update_triggered();
void on_action_about_triggered();

protected:
Expand Down
6 changes: 6 additions & 0 deletions src/mainwindow/mainwindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ QMainWindow
<string>帮助(&amp;H)</string>
</property>
<addaction name="action_help"/>
<addaction name="action_update"/>
<addaction name="separator"/>
<addaction name="action_about"/>
</widget>
Expand Down Expand Up @@ -338,6 +339,11 @@ QMainWindow
<string>F1</string>
</property>
</action>
<action name="action_update">
<property name="text">
<string>检查更新(&amp;U)...</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
Expand Down
193 changes: 193 additions & 0 deletions src/updater/checkupdatesdialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
#include <QDebug>
#include <QTimer>
#include <QPushButton>
#include <QJsonArray>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QNetworkAccessManager>

#include "../common/version.h"
#include "updaterconst.h"
#include "checkupdatesdialog.h"
#include "ui_checkupdatesdialog.h"

CheckUpdatesDialog::CheckUpdatesDialog(bool dontShowError, QWidget* parent) :
QDialog(parent),
ui(new Ui::CheckUpdatesDialog),
download_button(new QPushButton("立即下载(&D)", this)),
manager(new QNetworkAccessManager(this)), timer(new QTimer(this)), dont_show_error(dontShowError), need_recheck(false)
{
ui->setupUi(this);
this->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);

ui->label_now->setText(VERSION_SHORT);
ui->label_1->hide();
ui->label_2->hide();
ui->label_3->hide();
ui->label_now->hide();
ui->label_latest->hide();
ui->plainTextEdit->hide();
download_button->hide();
this->setFixedHeight(120);
this->setVisible(!dontShowError);

qDebug() << "Request URL:" << Updater::RELEASE_INFO_URL;
reply = manager->get(QNetworkRequest(QUrl(Updater::RELEASE_INFO_URL)));

connect(this, &QDialog::finished, reply, &QNetworkReply::abort);
connect(timer, &QTimer::timeout, this, [this]()
{
if (reply->isRunning())
{
reply->abort();
showError("检查更新失败: 连接超时,请检查网络连接。");
}
});
connect(manager, &QNetworkAccessManager::finished, this, &CheckUpdatesDialog::onReplyFinished);

timer->setSingleShot(true);
timer->start(Updater::CONNECT_TIME_OUT);
}

CheckUpdatesDialog::~CheckUpdatesDialog()
{
delete ui;
}

int CheckUpdatesDialog::exec()
{
if (dont_show_error)
{
QEventLoop loop;
connect(this, &QDialog::finished, &loop, &QEventLoop::quit);
loop.exec();
return this->result();
}
else
return QDialog::exec();
}



void CheckUpdatesDialog::showError(const QString& msg)
{
if (dont_show_error)
{
qDebug() << msg;
QDialog::reject();
return;
}

if (need_recheck) return;
need_recheck = true;

ui->label_info->setText(msg);
ui->progressBar->hide();
ui->buttonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Retry);

QEventLoop loop;
connect(this, &QDialog::finished, &loop, &QEventLoop::quit);
loop.exec();
}

void CheckUpdatesDialog::noUpdates()
{
if (dont_show_error)
{
qDebug() << "没有更新";
QDialog::reject();
return;
}

this->setWindowTitle("没有更新");
ui->label_info->setText(QString("%1 已是最新版本 %2。").arg(Updater::APP_NAME).arg(VERSION_SHORT));
ui->progressBar->hide();
}

void CheckUpdatesDialog::foundUpdates(const QString& version, const QString& log, int bytes)
{
this->setWindowTitle("发现新版本");
ui->label_latest->setText(version);
ui->label_info->setText(QString("将会下载 %1。").arg(Updater::FormatFileSize(bytes)));
ui->plainTextEdit->setPlainText(log);
ui->buttonBox->addButton(download_button, QDialogButtonBox::AcceptRole);

ui->label_1->show();
ui->label_2->show();
ui->label_3->show();
ui->label_now->show();
ui->label_latest->show();
ui->plainTextEdit->show();
ui->progressBar->hide();
download_button->show();

this->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
this->resize(400, 300);
this->show();
}



void CheckUpdatesDialog::onReplyFinished()
{
qDebug() << "Status Code:" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

timer->stop();
if (reply->error() != QNetworkReply::NoError)
{
if (reply->error() != QNetworkReply::OperationCanceledError)
showError(QString("检查更新失败: 无法访问更新服务器(错误代码 %1),请检查网络连接。").arg(reply->error()));
reply->deleteLater();
}
else if (download_url.isEmpty())
{
QString errorString;
QJsonObject json = Updater::ParseToJson(reply->readAll(), &errorString);
if (!errorString.isEmpty())
{
showError(QString("检查更新失败: %1").arg(errorString));
reply->deleteLater();
return;
}

QString latestVersion = json.value("tag_name").toString();
if (latestVersion.isEmpty())
{
showError("检查更新失败: 无法获取新版本信息。");
reply->deleteLater();
return;
}
qDebug() << "Latest Version:" << latestVersion;

if (latestVersion != VERSION_SHORT)
{
download_size = 0;
QJsonArray array = json.value("assets").toArray();
for (int i = 0; i < array.size(); i++)
{
QJsonObject obj = array[i].toObject();
if (obj.value("name") == Updater::GetFileNameByPlatform(latestVersion))
{
download_url = obj.value("browser_download_url").toString();
download_size = obj.value("size").toInt();
break;
}
}
if (download_url.isEmpty() || !download_size)
{
showError("检查更新失败: 无法获取新版本下载地址。");
reply->deleteLater();
return;
}

reply->deleteLater();
QString log = json.value("body").toString();
foundUpdates(latestVersion, log, download_size);
}
else
{
noUpdates();
reply->deleteLater();
}
}
}
Loading