Skip to content

Commit

Permalink
fix update logic:
Browse files Browse the repository at this point in the history
1) stop checking updates if user declined updates
2) add request to update in custom menu
3) make random interval for checking update (from 1 to 5 hours)
  • Loading branch information
alexeylysenko committed Nov 20, 2014
1 parent 2c1da6a commit 3ef3b64
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 42 deletions.
4 changes: 2 additions & 2 deletions KazooPopup.pro
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ TEMPLATE = app
CONFIG += c++11

# Application version
VERSION_MAJOR=1
VERSION_MINOR=0
VERSION_MAJOR=0
VERSION_MINOR=9
VERSION_PATCH=0
DEFINES += APP_VERSION=\\\"$${VERSION_MAJOR}.$${VERSION_MINOR}.$${VERSION_PATCH}\\\"

Expand Down
3 changes: 0 additions & 3 deletions main.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "mainwindow.h"
#include "logger.h"
#include "updatemanager.h"

#include <QtSingleApplication>

Expand All @@ -16,8 +15,6 @@ int main(int argc, char *argv[])

Logger::instance()->start();

UpdateManager::instance()->start();

MainWindow w;
w.hide();

Expand Down
43 changes: 43 additions & 0 deletions mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "informerdialog.h"
#include "websocketmanager.h"
#include "debugdialog.h"
#include "updatemanager.h"

#include <QSystemTrayIcon>
#include <QMenu>
Expand Down Expand Up @@ -63,6 +64,13 @@ MainWindow::MainWindow(QWidget *parent) :

m_wsMan->start();

UpdateManager *updateManager = UpdateManager::instance();
connect(updateManager, &UpdateManager::updateAvailable,
this, &MainWindow::processUpdateAvailable);
connect(updateManager, &UpdateManager::noUpdate,
this, &MainWindow::processNoUpdate);
updateManager->start();

qDebug("app version: %s", APP_VERSION);
}

Expand All @@ -80,6 +88,7 @@ void MainWindow::createTrayIcon()
QAction *stateAction = menu->addAction(tr("Connecting"));
stateAction->setDisabled(true);
menu->addSeparator();
menu->addAction(tr("Update"), this, SLOT(updateApp()));
menu->addAction(tr("Settings"), this, SLOT(show()));
menu->addAction(tr("Debug logs"), this, SLOT(showDebugDialog()));
menu->addAction(tr("Close all popups"), this, SLOT(closeAllPopups()));
Expand All @@ -90,6 +99,34 @@ void MainWindow::createTrayIcon()
m_trayIcon->show();
}

void MainWindow::processUpdateAvailable()
{
QMessageBox msgBox;
msgBox.setWindowTitle(qApp->applicationName());
msgBox.setText(tr("New version is available. "
"Would you like to update?"));
msgBox.setWindowIcon(QIcon(":/res/kazoo_32.png"));
msgBox.setIcon(QMessageBox::Question);
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
int answer = msgBox.exec();

if (answer != QMessageBox::Yes)
{
qDebug("User declined update");
return;
}

UpdateManager::instance()->doUpdate();
}

void MainWindow::processNoUpdate()
{
qDebug("User have the latest version");
QMessageBox::information(this,
qApp->applicationName(),
tr("You have the latest Kazoo Popup version"));
}

void MainWindow::onChannelCreated(const QString &callId, const Caller &caller)
{
InformerDialog *informerDialog = new InformerDialog();
Expand Down Expand Up @@ -376,6 +413,12 @@ void MainWindow::processDialogAttached(bool attached)
}
}

void MainWindow::updateApp()
{
qDebug("User has requested to update");
UpdateManager::instance()->quietUpdate();
}

void MainWindow::showDebugDialog()
{
if (m_debugDialog == nullptr)
Expand Down
4 changes: 4 additions & 0 deletions mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ private slots:
void processDialogFinished();
void processDialogAttached(bool attached);

void processUpdateAvailable();
void processNoUpdate();

void updateApp();
void showDebugDialog();
void closeAllPopups();
void quit();
Expand Down
90 changes: 54 additions & 36 deletions updatemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,15 @@
#include <QNetworkAccessManager>
#include <QNetworkReply>

#include <QMessageBox>
#include <QIcon>

#ifdef Q_OS_WIN
# include <windows.h>
# include <shellapi.h>
#endif

UpdateManager *UpdateManager::m_instance = nullptr;

static int kUpdateTimerInterval = 3600; // timer interval in seconds
static int kUpdateMinInterval = 1; // 1 hour min interval
static int kUpdateMaxInterval = 5; // 5 hours max interval
static const char * const kCheckUpdateUrl = "http://localhost/checkupdate.php";

#ifdef Q_OS_WIN
Expand All @@ -34,31 +32,43 @@ UpdateManager::UpdateManager(QObject *parent) :
QObject(parent)
{
m_timer = new QTimer();
m_timer->setInterval(kUpdateTimerInterval * 1000);
qsrand(QDateTime::currentMSecsSinceEpoch());
connect(m_timer, &QTimer::timeout,
this, &UpdateManager::checkUpdate);
this, &UpdateManager::processTimeout);
}

UpdateManager *UpdateManager::instance()
{
if (!m_instance)
if (m_instance == nullptr)
{
static QMutex mutex;
mutex.lock();
if (!m_instance)
if (m_instance == nullptr)
m_instance = new UpdateManager;
mutex.unlock();
}
return m_instance;
}

void UpdateManager::start()
{
processTimeout();
}

void UpdateManager::stop()
{
m_timer->stop();
}

void UpdateManager::processTimeout()
{
checkUpdate();
m_timer->start();

int randValue = (qrand() % (kUpdateMaxInterval - kUpdateMinInterval + 1)) + kUpdateMinInterval;
m_timer->start(randValue * 60 * 60 * 1000);
}

void UpdateManager::checkUpdate()
void UpdateManager::checkUpdate(bool quiet)
{
QNetworkAccessManager *nam = new QNetworkAccessManager(this);

Expand All @@ -69,45 +79,44 @@ void UpdateManager::checkUpdate()
QString query("app=kazoo&platform=%1&ver=%2");
url.setQuery(query.arg(detectPlatform()).arg(APP_VERSION));

nam->get(QNetworkRequest(url));
QNetworkReply *reply = nam->get(QNetworkRequest(url));
reply->setProperty("quiet", quiet);
}

void UpdateManager::onReplyFinished(QNetworkReply *reply)
{
QString data = reply->readAll();
if (data.isEmpty() || !data.startsWith("http"))
bool quiet = reply->property("quiet").toBool();
if (!data.isEmpty() && data.startsWith("http"))
{
reply->manager()->deleteLater();
reply->deleteLater();
return;
qDebug("New version is available");
m_updateUrl = data;
stop();

if (quiet)
doUpdate();
else
emit updateAvailable();
}

QMessageBox msgBox;
msgBox.setWindowTitle(qApp->applicationName());
msgBox.setText(tr("New version is available. "
"Would you like to update?"));
msgBox.setWindowIcon(QIcon(":/res/kazoo_32.png"));
msgBox.setIcon(QMessageBox::Question);
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);

int answer = msgBox.exec();
if (answer != QMessageBox::Yes)
else
{
reply->manager()->deleteLater();
reply->deleteLater();
return;
if (quiet)
emit noUpdate();
}

reply->manager()->deleteLater();
reply->deleteLater();
}

bool UpdateManager::doUpdate() const
{
QString updaterPath("%1/%2");
updaterPath = updaterPath.arg(qApp->applicationDirPath(), kUpdaterFileName);
QStringList arguments("update");
arguments.append(data);

bool ok;
#ifdef Q_OS_WIN
QString parameters("\"update\" \"");
parameters.append(data);
parameters.append("\"");
QString parameters("\"update\" \"%1\"");
parameters = parameters.arg(m_updateUrl);
int result = (int)ShellExecute(0,
L"open",
(const WCHAR*)updaterPath.utf16(),
Expand All @@ -126,14 +135,23 @@ void UpdateManager::onReplyFinished(QNetworkReply *reply)
}
ok = (result > kSuccessShellExecute);
#elif defined Q_OS_MAC
QStringList arguments("update");
arguments.append(m_updateUrl);
ok = QProcess::startDetached(updaterPath, arguments);
#endif
if (!ok)
qWarning() << "Unable to start updater from path: " << updaterPath;
else
QTimer::singleShot(0, qApp, SLOT(quit()));

reply->manager()->deleteLater();
reply->deleteLater();
return ok;
}

void UpdateManager::quietUpdate()
{
if (m_updateUrl.isEmpty())
checkUpdate(true);
else
doUpdate();
}

12 changes: 11 additions & 1 deletion updatemanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,25 @@ class UpdateManager : public QObject
static UpdateManager *instance();

void start();
bool doUpdate() const;
void quietUpdate();

signals:
void updateAvailable();
void noUpdate();

private:
explicit UpdateManager(QObject *parent = 0);

void checkUpdate(bool quiet = false);
void stop();

static UpdateManager *m_instance;
QTimer *m_timer;
QString m_updateUrl;

private slots:
void checkUpdate();
void processTimeout();

void onReplyFinished(QNetworkReply *reply);

Expand Down

0 comments on commit 3ef3b64

Please sign in to comment.