268 lines
8.7 KiB
C++
268 lines
8.7 KiB
C++
|
|
#include "crapup.h"
|
|
#include "ui_crapup.h"
|
|
|
|
#include "globals/global_configs.h"
|
|
|
|
#include "modules/stylesheets.h"
|
|
|
|
#include "modules/exceptions.h"
|
|
|
|
#include <QFontDatabase>
|
|
#include <QRegularExpression>
|
|
#include <QNetworkAccessManager>
|
|
#include <QNetworkReply>
|
|
#include <QEventLoop>
|
|
#include <QPixmap>
|
|
#include <QTimer>
|
|
|
|
|
|
namespace /*private*/
|
|
{
|
|
|
|
enum class ErrCode : uint8_t {
|
|
CONNECTION_ERROR,
|
|
CONNECTION_TIMEOUT,
|
|
VERSION_NOT_FOUND,
|
|
VERSION_MALFORMED,
|
|
UNEXPECTED_VERSION
|
|
};
|
|
|
|
} // namespacce (private)
|
|
|
|
|
|
Crapup::Crapup( QWidget* parent )
|
|
: QWidget{ parent }
|
|
, ui{ new Ui::Crapup }
|
|
, img_checking{ ":/icons/icons/"+GlobalConfigs::icons_set+"/checking.png" }
|
|
{
|
|
this->ui->setupUi(this);
|
|
|
|
this->setStyleSheet( StyleSec::Crapup::getStyleSheet() );
|
|
|
|
// fonts
|
|
const QString ff{ QFontDatabase::applicationFontFamilies(
|
|
QFontDatabase::addApplicationFont(":/fonts/Metropolis")).at(0) };
|
|
const QFont font{ ff, 13 };
|
|
const QFont font_big{ ff, 16 };
|
|
|
|
// apply the fonts
|
|
this->ui->label_Title->setFont( font_big );
|
|
this->ui->label_Message->setFont( font );
|
|
|
|
this->ui->label_Title->setText( Crapup::tr("Checking for updates") );
|
|
this->adjustSize();
|
|
}
|
|
|
|
Crapup::~Crapup()
|
|
{
|
|
if ( !this->reply.isNull() ) {
|
|
this->deleteReply();
|
|
}
|
|
}
|
|
|
|
void Crapup::closeEvent( QCloseEvent* event )
|
|
{
|
|
Q_UNUSED(event)
|
|
this->quitting |= true;
|
|
if ( !this->img_timer.isNull() ) {
|
|
if ( this->img_timer->isActive() ) {
|
|
this->img_timer->stop();
|
|
}
|
|
}
|
|
if ( !this->request_timer.isNull() ) {
|
|
if ( this->request_timer->isActive() ) {
|
|
this->request_timer->stop();
|
|
}
|
|
}
|
|
if ( !this->reply.isNull() ) {
|
|
this->requestTimeout();
|
|
}
|
|
}
|
|
|
|
|
|
void Crapup::versionCheck( const float v )
|
|
{
|
|
bool successful{ false };
|
|
float version{ -1.0 };
|
|
ErrCode err{ ErrCode::CONNECTION_ERROR };
|
|
|
|
this->img_timer.reset( new QTimer(this) );
|
|
connect( this->img_timer.get(), &QTimer::timeout, this, &Crapup::rotateImg );
|
|
this->img_timer->start(100);
|
|
|
|
const QByteArray ua{ QByteArray::fromStdString("LogDoctor/"+std::to_string(v)+" (version check)") };
|
|
|
|
const QStringList links{ "https://raw.githubusercontent.com/elB4RTO/LogDoctor/main/version.txt",
|
|
"https://git.disroot.org/elB4RTO/LogDoctor/raw/branch//main/version.txt",
|
|
"https://gitlab.com/elB4RTO/LogDoctor/-/raw/main/version.txt",
|
|
"https://bitbucket.org/elb4rto/logdoctor/src/main/version.txt" };
|
|
|
|
static const QRegularExpression regex(".:!¦version¦!:.[0-9.]*.:!¦version¦!:.");
|
|
|
|
QNetworkAccessManager networkMgr{ this };
|
|
|
|
|
|
for ( const QString& URL : links ) {
|
|
|
|
// reset the reply
|
|
this->request_aborted &= false;
|
|
|
|
// request timeout timer
|
|
this->request_timer.reset( new QTimer(this) );
|
|
this->request_timer->setSingleShot( true );
|
|
connect( this->request_timer.get(), &QTimer::timeout, this, &Crapup::requestTimeout );
|
|
|
|
// set the URL and make the request
|
|
QNetworkRequest request;
|
|
request.setRawHeader( "User-Agent", ua );
|
|
request.setUrl( QUrl( URL ) );
|
|
request.setTransferTimeout( this->timeout_msec );
|
|
this->reply.reset( networkMgr.get( request ) );
|
|
|
|
// reply waiter loop
|
|
QEventLoop wait_reply;
|
|
connect( this->reply.get(), &QNetworkReply::readyRead, &wait_reply, &QEventLoop::quit );
|
|
connect( this, &Crapup::abortRequest, &wait_reply, &QEventLoop::quit );
|
|
|
|
// make the request
|
|
this->request_timer->start( this->timeout_msec+1000 );
|
|
wait_reply.exec();
|
|
|
|
// request is over, in a way or another
|
|
if ( this->quitting ) {
|
|
networkMgr.disconnect();
|
|
return;
|
|
}
|
|
if ( this->request_timer->isActive() ) {
|
|
this->request_timer->stop();
|
|
}
|
|
if ( this->reply.isNull() ) {
|
|
err = ErrCode::CONNECTION_TIMEOUT;
|
|
continue;
|
|
} else if ( this->reply->error() ) {
|
|
err = ErrCode::CONNECTION_ERROR;
|
|
continue;
|
|
} else {
|
|
// connection successful, get the content
|
|
const QString content{ this->reply->readAll() };
|
|
// search for the version mark
|
|
if ( content.contains( regex ) ) {
|
|
// get the version
|
|
QScopedPointer<bool> ok{ new bool(false) };
|
|
version = content.section(".:!¦version¦!:.", 1, 1 ).toFloat(ok.get());
|
|
if ( ok.get() ) {
|
|
successful |= true;
|
|
break;
|
|
} else {
|
|
// failed to convert string to float
|
|
err = ErrCode::VERSION_MALFORMED;
|
|
}
|
|
} else {
|
|
// version mark not found
|
|
err = ErrCode::VERSION_NOT_FOUND;
|
|
}
|
|
}
|
|
}
|
|
if ( !this->reply.isNull() ) {
|
|
this->deleteReply();
|
|
}
|
|
networkMgr.disconnect();
|
|
this->img_timer->stop();
|
|
this->ui->label_Image->setVisible( false );
|
|
|
|
if ( successful ) {
|
|
// check the versions
|
|
if ( version > v ) {
|
|
// new version available
|
|
this->ui->label_Title->setText( Crapup::tr("New version available") );
|
|
this->ui->label_Message->setText( Crapup::tr(
|
|
"A new version is available!\n"
|
|
"Please visit LogDoctor's git repository and follow the instruction about how to update" ) );
|
|
} else if ( version == v ) {
|
|
// same version
|
|
this->ui->label_Title->setText( Crapup::tr("No update found") );
|
|
this->ui->label_Message->setText( Crapup::tr(
|
|
"LogDoctor is up-to-date" ) );
|
|
} else if ( version > 0.0f ) {
|
|
// this version is beyond the current upstream version
|
|
this->ui->label_Title->setText( Crapup::tr(":/") );
|
|
this->ui->label_Message->setText( Crapup::tr(
|
|
"You're running a version from the future!\n"
|
|
"Your version is beyond the current upstream version\n"
|
|
"Are you running the original LogDoctor?\n"
|
|
"Please visit the LogDoctor's repository and get a fresh version of it" ) );
|
|
} else {
|
|
// something went wrong, can't be successful if version is less than 0
|
|
successful &= false;
|
|
err = ErrCode::UNEXPECTED_VERSION;
|
|
}
|
|
}
|
|
if ( !successful ) {
|
|
switch ( err ) {
|
|
case ErrCode::CONNECTION_ERROR:
|
|
this->ui->label_Title->setText( Crapup::tr("Failed to establish a connection") );
|
|
this->ui->label_Message->setText( Crapup::tr(
|
|
"Connection error, please try again later" ) );
|
|
break;
|
|
case ErrCode::CONNECTION_TIMEOUT:
|
|
this->ui->label_Title->setText( Crapup::tr("Failed to establish a connection") );
|
|
this->ui->label_Message->setText( Crapup::tr(
|
|
"Connection timed out" ) );
|
|
break;
|
|
case ErrCode::VERSION_NOT_FOUND:
|
|
this->ui->label_Title->setText( Crapup::tr("Version check failed") );
|
|
this->ui->label_Message->setText( Crapup::tr(
|
|
"An error occured while parsing:\n"
|
|
"version mark not found" ) );
|
|
break;
|
|
case ErrCode::VERSION_MALFORMED:
|
|
this->ui->label_Title->setText( Crapup::tr("Version check failed") );
|
|
this->ui->label_Message->setText( Crapup::tr(
|
|
"An error occured while parsing:\n"
|
|
"malformed version" ) );
|
|
break;
|
|
case ErrCode::UNEXPECTED_VERSION:
|
|
this->ui->label_Title->setText( Crapup::tr("Version check failed") );
|
|
this->ui->label_Message->setText( Crapup::tr(
|
|
"An error occured while comparing:\n"
|
|
"malformed upstream version" ) );
|
|
break;
|
|
default:
|
|
throw GenericException("Unexpected ErrCode in VersionCheck: "+std::to_string(static_cast<uint8_t>(err)));
|
|
break;
|
|
}
|
|
}
|
|
this->adjustSize();
|
|
}
|
|
|
|
|
|
|
|
void Crapup::requestTimeout()
|
|
{
|
|
this->request_aborted |= true;
|
|
this->deleteReply();
|
|
emit this->abortRequest();
|
|
}
|
|
|
|
void Crapup::deleteReply()
|
|
{
|
|
if ( this->reply->isOpen() ) {
|
|
this->reply->abort();
|
|
}
|
|
this->reply.reset();
|
|
}
|
|
|
|
|
|
|
|
void Crapup::rotateImg()
|
|
{
|
|
this->img_orientation += 36.0f;
|
|
if ( this->img_orientation >= 360.0f ) {
|
|
this->img_orientation = 0.0f;
|
|
}
|
|
this->ui->label_Image->setPixmap(
|
|
this->img_checking.transformed(
|
|
QTransform().rotate( this->img_orientation ) ) );
|
|
}
|