mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-26 15:06:08 +03:00
Updater: Fix corner cases related to failed auto-updates
- Don't re-download updates whom's auto-install has clearly failed before - Don't signal newly available auto-upgrade if it has failed once - Remove downloaded update after (un)successful auto-update - Remove as many temporary keys after an (un)successful auto-update
This commit is contained in:
parent
4c6e0b5c07
commit
b3683976ca
6 changed files with 48 additions and 44 deletions
|
@ -80,6 +80,7 @@ void GeneralSettings::slotUpdateInfo()
|
|||
{
|
||||
connect(updater, SIGNAL(downloadStateChanged()), SLOT(slotUpdateInfo()), Qt::UniqueConnection);
|
||||
connect(_ui->restartButton, SIGNAL(clicked()), updater, SLOT(slotStartInstaller()), Qt::UniqueConnection);
|
||||
connect(_ui->restartButton, SIGNAL(clicked()), qApp, SLOT(quit()), Qt::UniqueConnection);
|
||||
_ui->updateStateLabel->setText(updater->statusString());
|
||||
_ui->restartButton->setVisible(updater->downloadState() == OCUpdater::DownloadComplete);
|
||||
} else {
|
||||
|
|
|
@ -57,7 +57,6 @@ static const char useDownloadLimitC[] = "BWLimit/useDownloadLimit";
|
|||
static const char uploadLimitC[] = "BWLimit/uploadLimit";
|
||||
static const char downloadLimitC[] = "BWLimit/downloadLimit";
|
||||
|
||||
static const char seenVersionC[] = "Updater/seenVersion";
|
||||
static const char maxLogLinesC[] = "Logging/maxLogLines";
|
||||
|
||||
QString MirallConfigFile::_confDir = QString::null;
|
||||
|
@ -108,19 +107,6 @@ void MirallConfigFile::setOptionalDesktopNotifications(bool show)
|
|||
settings.sync();
|
||||
}
|
||||
|
||||
QString MirallConfigFile::seenVersion() const
|
||||
{
|
||||
QSettings settings(configFile(), QSettings::IniFormat);
|
||||
return settings.value(QLatin1String(seenVersionC)).toString();
|
||||
}
|
||||
|
||||
void MirallConfigFile::setSeenVersion(const QString &version)
|
||||
{
|
||||
QSettings settings(configFile(), QSettings::IniFormat);
|
||||
settings.setValue(QLatin1String(seenVersionC), version);
|
||||
settings.sync();
|
||||
}
|
||||
|
||||
void MirallConfigFile::saveGeometry(QWidget *w)
|
||||
{
|
||||
Q_ASSERT(!w->objectName().isNull());
|
||||
|
|
|
@ -106,9 +106,6 @@ public:
|
|||
QString lastVersion() const;
|
||||
void setLastVersion(const QString &version);
|
||||
|
||||
QString seenVersion() const;
|
||||
void setSeenVersion(const QString &version);
|
||||
|
||||
void saveGeometryHeader(QHeaderView *header);
|
||||
void restoreGeometryHeader(QHeaderView *header);
|
||||
protected:
|
||||
|
|
|
@ -32,7 +32,9 @@
|
|||
namespace Mirall {
|
||||
|
||||
static const char updateAvailableC[] = "Updater/updateAvailable";
|
||||
static const char lastVersionC[] = "Updater/lastVersion";
|
||||
static const char updateTargetVersionC[] = "Updater/updateTargetVersion";
|
||||
static const char seenVersionC[] = "Updater/seenVersion";
|
||||
static const char autoUpdateFailedVersionC[] = "Updater/autoUpdateFailedVersion";
|
||||
static const char ranUpdateC[] = "Updater/ranUpdate";
|
||||
|
||||
OCUpdater::OCUpdater(const QUrl &url, QObject *parent) :
|
||||
|
@ -107,9 +109,9 @@ void OCUpdater::slotStartInstaller()
|
|||
QSettings settings(cfg.configFile(), QSettings::IniFormat);
|
||||
QString updateFile = settings.value(updateAvailableC).toString();
|
||||
settings.setValue(ranUpdateC, true);
|
||||
settings.sync();
|
||||
qDebug() << "Running updater" << updateFile;
|
||||
QProcess::startDetached(updateFile, QStringList() << "/S" << "/launch");
|
||||
qApp->quit();
|
||||
}
|
||||
|
||||
void OCUpdater::checkForUpdate()
|
||||
|
@ -145,12 +147,6 @@ void OCUpdater::slotOpenUpdateUrl()
|
|||
QDesktopServices::openUrl(_updateInfo.web());
|
||||
}
|
||||
|
||||
void OCUpdater::slotSetVersionSeen()
|
||||
{
|
||||
MirallConfigFile cfg;
|
||||
cfg.setSeenVersion(_updateInfo.version());
|
||||
}
|
||||
|
||||
QString OCUpdater::getSystemInfo()
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
|
@ -171,8 +167,8 @@ bool OCUpdater::updateSucceeded() const
|
|||
{
|
||||
MirallConfigFile cfg;
|
||||
QSettings settings(cfg.configFile(), QSettings::IniFormat);
|
||||
qint64 oldVersionInt = Helper::stringVersionToInt(settings.value(lastVersionC).toString().toLatin1());
|
||||
return Helper::currentVersionToInt() > oldVersionInt;
|
||||
qint64 targetVersionInt = Helper::stringVersionToInt(settings.value(updateTargetVersionC).toString());
|
||||
return Helper::currentVersionToInt() >= targetVersionInt;
|
||||
}
|
||||
|
||||
QString OCUpdater::clientVersion() const
|
||||
|
@ -236,27 +232,25 @@ void NSISUpdater::slotDownloadFinished()
|
|||
qDebug() << "Downloaded" << url.toString() << "to" << _targetFile;
|
||||
MirallConfigFile cfg;
|
||||
QSettings settings(cfg.configFile(), QSettings::IniFormat);
|
||||
settings.setValue(lastVersionC, clientVersion());
|
||||
settings.setValue(updateTargetVersionC, updateInfo().version());
|
||||
settings.setValue(updateAvailableC, _targetFile);
|
||||
}
|
||||
|
||||
void NSISUpdater::showFallbackMessage()
|
||||
{
|
||||
_showFallbackMessage = true;
|
||||
}
|
||||
|
||||
void NSISUpdater::versionInfoArrived(const UpdateInfo &info)
|
||||
{
|
||||
MirallConfigFile cfg;
|
||||
QSettings settings(cfg.configFile(), QSettings::IniFormat);
|
||||
qint64 infoVersion = Helper::stringVersionToInt(info.version());
|
||||
qint64 seenVersion = Helper::stringVersionToInt(cfg.seenVersion());
|
||||
qint64 seenVersion = Helper::stringVersionToInt(settings.value(seenVersionC).toString());
|
||||
|
||||
if(info.version().isEmpty() || infoVersion <= seenVersion ) {
|
||||
qDebug() << "Client is on latest version!";
|
||||
setDownloadState(UpToDate);
|
||||
} else {
|
||||
QString url = info.downloadUrl();
|
||||
if (url.isEmpty() || _showFallbackMessage) {
|
||||
qint64 autoUpdateFailedVersion =
|
||||
Helper::stringVersionToInt(settings.value(autoUpdateFailedVersionC).toString());
|
||||
if (url.isEmpty() || _showFallbackMessage || infoVersion == autoUpdateFailedVersion) {
|
||||
showDialog(info);
|
||||
}
|
||||
if (!url.isEmpty()) {
|
||||
|
@ -318,7 +312,7 @@ void NSISUpdater::showDialog(const UpdateInfo &info)
|
|||
connect(reject, SIGNAL(clicked()), msgBox, SLOT(reject()));
|
||||
connect(getupdate, SIGNAL(clicked()), msgBox, SLOT(accept()));
|
||||
|
||||
connect(skip, SIGNAL(clicked()), SLOT(slotSetVersionSeen()));
|
||||
connect(skip, SIGNAL(clicked()), SLOT(slotSetSeenVersion()));
|
||||
connect(getupdate, SIGNAL(clicked()), SLOT(slotOpenUpdateUrl()));
|
||||
|
||||
layout->addWidget(bb);
|
||||
|
@ -326,7 +320,7 @@ void NSISUpdater::showDialog(const UpdateInfo &info)
|
|||
msgBox->open();
|
||||
}
|
||||
|
||||
NSISUpdater::UpdateState NSISUpdater::updateState() const
|
||||
NSISUpdater::UpdateState NSISUpdater::updateState()
|
||||
{
|
||||
MirallConfigFile cfg;
|
||||
QSettings settings(cfg.configFile(), QSettings::IniFormat);
|
||||
|
@ -336,14 +330,27 @@ NSISUpdater::UpdateState NSISUpdater::updateState() const
|
|||
// we have an update, did we succeed running it?
|
||||
bool ranUpdate = settings.value(ranUpdateC, false).toBool();
|
||||
if (ranUpdate) {
|
||||
// regardless if things went well or not
|
||||
QFile::remove(updateFile);
|
||||
settings.remove(ranUpdateC);
|
||||
if (updateSucceeded()) {
|
||||
settings.remove(ranUpdateC);
|
||||
settings.remove(updateTargetVersionC);
|
||||
settings.remove(autoUpdateFailedVersionC);
|
||||
slotSetSeenVersion();
|
||||
return NoUpdate;
|
||||
} else {
|
||||
QString targetVersion = settings.value(updateTargetVersionC).toString();
|
||||
settings.setValue(autoUpdateFailedVersionC, targetVersion);
|
||||
settings.remove(updateTargetVersionC);
|
||||
return UpdateFailed;
|
||||
}
|
||||
} else {
|
||||
return UpdateAvailable;
|
||||
if (settings.contains(autoUpdateFailedVersionC)) {
|
||||
return NoUpdate;
|
||||
} else {
|
||||
return UpdateAvailable;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return NoUpdate;
|
||||
|
@ -356,7 +363,7 @@ bool NSISUpdater::handleStartup()
|
|||
case NSISUpdater::UpdateAvailable:
|
||||
return performUpdate();
|
||||
case NSISUpdater::UpdateFailed:
|
||||
showFallbackMessage();
|
||||
_showFallbackMessage = true;
|
||||
return false;
|
||||
case NSISUpdater::NoUpdate:
|
||||
default:
|
||||
|
@ -364,6 +371,13 @@ bool NSISUpdater::handleStartup()
|
|||
}
|
||||
}
|
||||
|
||||
void NSISUpdater::slotSetSeenVersion()
|
||||
{
|
||||
MirallConfigFile cfg;
|
||||
QSettings settings(cfg.configFile(), QSettings::IniFormat);
|
||||
settings.setValue(seenVersionC, updateInfo().version());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PassiveUpdateNotifier::PassiveUpdateNotifier(const QUrl &url, QObject *parent)
|
||||
|
@ -375,7 +389,12 @@ PassiveUpdateNotifier::PassiveUpdateNotifier(const QUrl &url, QObject *parent)
|
|||
void PassiveUpdateNotifier::versionInfoArrived(const UpdateInfo &info)
|
||||
{
|
||||
MirallConfigFile cfg;
|
||||
if( info.version().isEmpty() || info.version() == cfg.seenVersion() ) {
|
||||
QSettings settings(cfg.configFile(), QSettings::IniFormat);
|
||||
QString seenVersion = settings.value(seenVersionC).toString();
|
||||
if( info.version().isEmpty() ||
|
||||
Helper::stringVersionToInt(info.version())
|
||||
>= Helper::stringVersionToInt(seenVersion))
|
||||
{
|
||||
qDebug() << "Client is on latest version!";
|
||||
setDownloadState(UpToDate);
|
||||
} else {
|
||||
|
|
|
@ -55,7 +55,6 @@ public slots:
|
|||
|
||||
private slots:
|
||||
void slotOpenUpdateUrl();
|
||||
void slotSetVersionSeen();
|
||||
void slotVersionInfoArrived();
|
||||
void slotTimedOut();
|
||||
|
||||
|
@ -65,7 +64,7 @@ protected:
|
|||
QString clientVersion() const;
|
||||
QString getSystemInfo();
|
||||
QNetworkAccessManager* qnam() const { return _accessManager; }
|
||||
|
||||
UpdateInfo updateInfo() const { return _updateInfo; }
|
||||
private:
|
||||
QUrl _updateUrl;
|
||||
int _state;
|
||||
|
@ -82,12 +81,12 @@ public:
|
|||
explicit NSISUpdater(const QUrl &url, QObject *parent = 0);
|
||||
bool handleStartup();
|
||||
private slots:
|
||||
void slotSetSeenVersion();
|
||||
void slotDownloadFinished();
|
||||
void slotWriteFile();
|
||||
private:
|
||||
NSISUpdater::UpdateState updateState() const;
|
||||
NSISUpdater::UpdateState updateState();
|
||||
void showDialog(const UpdateInfo &info);
|
||||
void showFallbackMessage();
|
||||
void versionInfoArrived(const UpdateInfo &info);
|
||||
QScopedPointer<QTemporaryFile> _file;
|
||||
QString _targetFile;
|
||||
|
|
|
@ -58,6 +58,8 @@ qint64 Updater::Helper::currentVersionToInt()
|
|||
|
||||
qint64 Updater::Helper::stringVersionToInt(const QString& version)
|
||||
{
|
||||
if (version.isEmpty())
|
||||
return 0;
|
||||
QByteArray baVersion = version.toLatin1();
|
||||
int major = 0, minor = 0, patch = 0, build = 0;
|
||||
sscanf(baVersion, "%d.%d.%d.%d", &major, &minor, &patch, &build);
|
||||
|
|
Loading…
Reference in a new issue