Fix/re-enable checking for updates

We can (again) check for updates and, if an update is available, send
the user to the site to download them.

The old format (a .json specifying a version number and download URL)
was kept. The address for this file is now specified in the settings.
preferencesAboutTextFull
Craig Watson 8 years ago
parent 6ff78892c0
commit 3d46bd0bc5
  1. 120
      src/core/UBApplicationController.cpp
  2. 15
      src/core/UBApplicationController.h
  3. 1
      src/core/UBSettings.cpp
  4. 1
      src/core/UBSettings.h
  5. 25
      src/frameworks/UBVersion.cpp

@ -90,7 +90,6 @@ UBApplicationController::UBApplicationController(UBBoardView *pControlView,
, mAutomaticCheckForUpdates(false) , mAutomaticCheckForUpdates(false)
, mCheckingForUpdates(false) , mCheckingForUpdates(false)
, mIsShowingDesktop(false) , mIsShowingDesktop(false)
, mHttp(0)
{ {
mDisplayManager = new UBDisplayManager(this); mDisplayManager = new UBDisplayManager(this);
@ -121,7 +120,7 @@ UBApplicationController::UBApplicationController(UBBoardView *pControlView,
connect(UBApplication::webController, SIGNAL(imageCaptured(const QPixmap &, bool, const QUrl&)) connect(UBApplication::webController, SIGNAL(imageCaptured(const QPixmap &, bool, const QUrl&))
, this, SLOT(addCapturedPixmap(const QPixmap &, bool, const QUrl&))); , this, SLOT(addCapturedPixmap(const QPixmap &, bool, const QUrl&)));
networkAccessManager = new QNetworkAccessManager (this); mNetworkAccessManager = new QNetworkAccessManager (this);
QTimer::singleShot (1000, this, SLOT (checkAtLaunch())); QTimer::singleShot (1000, this, SLOT (checkAtLaunch()));
} }
@ -136,8 +135,6 @@ UBApplicationController::~UBApplicationController()
delete mBlackScene; delete mBlackScene;
delete mMirror; delete mMirror;
if (mHttp) delete mHttp;
delete(mOpenSankoreImporter); delete(mOpenSankoreImporter);
mOpenSankoreImporter = NULL; mOpenSankoreImporter = NULL;
} }
@ -478,85 +475,71 @@ void UBApplicationController::showDesktop(bool dontSwitchFrontProcess)
} }
void UBApplicationController::checkUpdate(QString urlString) void UBApplicationController::checkUpdate(const QUrl& url)
{ {
QUrl jsonUrl = url;
if (url.isEmpty())
jsonUrl = UBSettings::settings()->appSoftwareUpdateURI->get().toUrl();
qDebug() << "Checking for update at url: " << jsonUrl.toString();
#if defined(QT_NO_DEBUG) connect(mNetworkAccessManager, SIGNAL(finished(QNetworkReply*)),
/* this, SLOT(updateRequestFinished(QNetworkReply*)));
if(mHttp)
mHttp->deleteLater();
QUrl url(urlString);
mHttp = new QHttpPart(url.host());
connect(mHttp, SIGNAL(requestFinished(int,bool)), this, SLOT(updateRequestFinished(int,bool)));
connect(mHttp, SIGNAL(responseHeaderReceived(QHttpResponseHeader)), this, SLOT(updateHeaderReceived(QHttpResponseHeader)));
mHttp->get(url.path()); mNetworkAccessManager->get(QNetworkRequest(jsonUrl));
*/ }
#else
if(mHttpreply)
mHttpreply->deleteLater();
QUrl url(urlString);
mHttpreply = qnam.get(QNetworkRequest(url));
connect(mHttpreply, SIGNAL(requestFinished(int,bool)), this, SLOT(updateRequestFinished(int,bool)));
connect(mHttpreply, SIGNAL(responseHeaderReceived(QHttpResponseHeader)), this, SLOT(updateHeaderReceived(QHttpResponseHeader)));
// mHttpreply->setUrl(url.path());
//mHttp->get(url.path());
#endif
}
/* void UBApplicationController::updateRequestFinished(QNetworkReply * reply)
void UBApplicationController::updateHeaderReceived(QHttpResponseHeader header)
{ {
if(header.statusCode() == 302 && header.hasKey("Location")){ if (reply->error()) {
mHttp->close(); qWarning() << "Error downloading update file: " << reply->errorString();
checkUpdate(header.value("Location")); return;
} }
} // Check if we are being redirected. If so, call checkUpdate again
*/
void UBApplicationController::updateHeaderReceived(QNetworkRequest header )
{
//if(header.attribute(QNetworkRequest::HttpStatusCodeAttribute) == 302 && header.header(QNetworkRequest::LocationHeader)){
// mHttp->close();
mHttpreply->close();
//checkUpdate(header.value("Location"));
// }
}
void UBApplicationController::updateRequestFinished(int id, bool error) QVariant redirect_target = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
{ if (!redirect_target.isNull()) {
if (error){ // The returned URL might be relative. resolved() creates an absolute url from it
qWarning() << "http command id" << id << "return an error"; QUrl redirect_url(reply->url().resolved(redirect_target.toUrl()));
}
else{ checkUpdate(redirect_url);
/* QString responseString = QString(mHttp->readAll()); return;
qDebug() << responseString;
if (!responseString.isEmpty() && responseString.contains("version") && responseString.contains("url")){
mHttp->close();
mHttp->deleteLater();
mHttp = 0;
downloadJsonFinished(responseString);
} }
*/
QString responseString = QString(mHttpreply->readAll()); // No error and no redirect => we read the whole response
qDebug() << responseString;
if (!responseString.isEmpty() && responseString.contains("version") && responseString.contains("url")){ QString responseString = QString(reply->readAll());
mHttpreply->close();
mHttpreply->deleteLater(); if (!responseString.isEmpty() &&
mHttpreply = 0; responseString.contains("version") &&
responseString.contains("url")) {
reply->close();
reply->deleteLater();
downloadJsonFinished(responseString); downloadJsonFinished(responseString);
} }
} }
}
void UBApplicationController::downloadJsonFinished(QString currentJson) void UBApplicationController::downloadJsonFinished(QString currentJson)
{ {
/*
The .json files simply specify the latest version number available, and
the URL to send the user to, so they can download it.
They look like:
{
"version": "1.3.5",
"url": "http://openboard.ch"
}
*/
QScriptValue scriptValue; QScriptValue scriptValue;
QScriptEngine scriptEngine; QScriptEngine scriptEngine;
scriptValue = scriptEngine.evaluate ("(" + currentJson + ")"); scriptValue = scriptEngine.evaluate ("(" + currentJson + ")");
@ -564,18 +547,19 @@ void UBApplicationController::downloadJsonFinished(QString currentJson)
UBVersion installedVersion (qApp->applicationVersion()); UBVersion installedVersion (qApp->applicationVersion());
UBVersion jsonVersion (scriptValue.property("version").toString()); UBVersion jsonVersion (scriptValue.property("version").toString());
qDebug() << "json version: " << jsonVersion.toUInt();
qDebug() << "installed version: " << installedVersion.toUInt();
if (jsonVersion > installedVersion) { if (jsonVersion > installedVersion) {
if (UBApplication::mainWindow->yesNoQuestion(tr("Update available"), tr ("New update available, would you go to the web page ?"))){ if (UBApplication::mainWindow->yesNoQuestion(tr("Update available"), tr ("New update available, would you go to the web page ?"))){
QUrl url(scriptValue.property("url").toString()); QUrl url(scriptValue.property("url").toString());
QDesktopServices::openUrl(url); QDesktopServices::openUrl(url);
} }
} }
else { else if (isNoUpdateDisplayed) {
if (isNoUpdateDisplayed) {
mMainWindow->information(tr("Update"), tr("No update available")); mMainWindow->information(tr("Update"), tr("No update available"));
} }
} }
}
void UBApplicationController::checkAtLaunch() void UBApplicationController::checkAtLaunch()
{ {
@ -583,14 +567,14 @@ void UBApplicationController::checkAtLaunch()
if(UBSettings::settings()->appEnableAutomaticSoftwareUpdates->get().toBool()){ if(UBSettings::settings()->appEnableAutomaticSoftwareUpdates->get().toBool()){
isNoUpdateDisplayed = false; isNoUpdateDisplayed = false;
//checkUpdate (); checkUpdate();
} }
} }
void UBApplicationController::checkUpdateRequest() void UBApplicationController::checkUpdateRequest()
{ {
isNoUpdateDisplayed = true; isNoUpdateDisplayed = true;
//checkUpdate (); checkUpdate();
} }
void UBApplicationController::hideDesktop() void UBApplicationController::hideDesktop()

@ -53,12 +53,8 @@ class UBVersion;
class UBSoftwareUpdate; class UBSoftwareUpdate;
class QNetworkAccessManager; class QNetworkAccessManager;
class QNetworkReply; class QNetworkReply;
class QHttpPart;
class UBRightPalette; class UBRightPalette;
class UBOpenSankoreImporter; class UBOpenSankoreImporter;
class QScriptValue;
class QScriptEngine;
class QNetworkReply;
class UBApplicationController : public QObject class UBApplicationController : public QObject
{ {
@ -158,8 +154,8 @@ class UBApplicationController : public QObject
void checkAtLaunch(); void checkAtLaunch();
private slots: private slots:
void updateRequestFinished(int id, bool error); void updateRequestFinished(QNetworkReply * reply);
void updateHeaderReceived(QNetworkRequest header );
protected: protected:
@ -193,13 +189,10 @@ class UBApplicationController : public QObject
bool mIsShowingDesktop; bool mIsShowingDesktop;
bool isNoUpdateDisplayed; bool isNoUpdateDisplayed;
void checkUpdate (QString urlString = "http://get.openboard.org/update.json"); void checkUpdate(const QUrl &url = QUrl());
QNetworkAccessManager *networkAccessManager; QNetworkAccessManager * mNetworkAccessManager;
void downloadJsonFinished(QString updateString); void downloadJsonFinished(QString updateString);
QHttpPart* mHttp;
QNetworkAccessManager qnam;
QNetworkReply *mHttpreply;
}; };
#endif /* UBAPPLICATIONCONTROLLER_H_ */ #endif /* UBAPPLICATIONCONTROLLER_H_ */

@ -226,6 +226,7 @@ void UBSettings::init()
appToolBarDisplayText = new UBSetting(this, "App", "ToolBarDisplayText", true); appToolBarDisplayText = new UBSetting(this, "App", "ToolBarDisplayText", true);
appEnableAutomaticSoftwareUpdates = new UBSetting(this, "App", "EnableAutomaticSoftwareUpdates", false); appEnableAutomaticSoftwareUpdates = new UBSetting(this, "App", "EnableAutomaticSoftwareUpdates", false);
appEnableSoftwareUpdates = new UBSetting(this, "App", "EnableSoftwareUpdates", true); appEnableSoftwareUpdates = new UBSetting(this, "App", "EnableSoftwareUpdates", true);
appSoftwareUpdateURI = new UBSetting(this, "App", "SoftwareUpdateURI", "http://www.openboard.ch/update.json");
appToolBarOrientationVertical = new UBSetting(this, "App", "ToolBarOrientationVertical", false); appToolBarOrientationVertical = new UBSetting(this, "App", "ToolBarOrientationVertical", false);
appPreferredLanguage = new UBSetting(this,"App","PreferredLanguage", ""); appPreferredLanguage = new UBSetting(this,"App","PreferredLanguage", "");

@ -240,6 +240,7 @@ class UBSettings : public QObject
UBSetting* appToolBarDisplayText; UBSetting* appToolBarDisplayText;
UBSetting* appEnableAutomaticSoftwareUpdates; UBSetting* appEnableAutomaticSoftwareUpdates;
UBSetting* appEnableSoftwareUpdates; UBSetting* appEnableSoftwareUpdates;
UBSetting* appSoftwareUpdateURI;
UBSetting* appToolBarOrientationVertical; UBSetting* appToolBarOrientationVertical;
UBSetting* appPreferredLanguage; UBSetting* appPreferredLanguage;

@ -42,21 +42,32 @@ UBVersion::UBVersion(const QString &string)
uint UBVersion::toUInt() const uint UBVersion::toUInt() const
{ {
/* Based on semantic versioning, version numbers look like:
* Major.Minor.Patch-Type.Build
*
* To compare version numbers, the string is split into each part, and they are multiplied
* to give a number where the first two digits are the Major version, the next two are the
* Minor version, and so on.
*
* i.e if Major, Minor etc. are named A, B, C, D, E, the number will look like:
* AABBCCDDEE
*/
uint result = 0; uint result = 0;
QStringList list = mString.split("."); QStringList list = mString.split(QRegExp("[-\\.]"));
switch (list.count()) { switch (list.count()) {
case 2: case 2:
//short version 1.0 //short version 1.0
result = (list.at(0).toUInt() * 1000000) + (list.at(1).toUInt() * 10000) + (Release * 100); result = (list.at(0).toUInt() * 100000000) + (list.at(1).toUInt() * 1000000) + (Release * 100);
break; break;
case 3: case 3:
//release version 1.0.0 //release version 1.0.0
result = (list.at(0).toUInt() * 1000000) + (list.at(1).toUInt() * 10000) + (Release * 100) + list.at(2).toUInt(); result = (list.at(0).toUInt() * 100000000) + (list.at(1).toUInt() * 1000000) + list.at(2).toUInt()*10000 + (Release * 100);
break; break;
case 4:{ case 5:{
//standard version 1.0.a/b/r.0 //standard version 1.0.0.a/b/rc.0
uint releaseStage = list.at(2).startsWith("a") ? Alpha :(list.at(2).startsWith("b") ? Beta : ReleaseCandidate); uint releaseStage = list.at(3).startsWith("a") ? Alpha :(list.at(3).startsWith("b") ? Beta : ReleaseCandidate);
result = (list.at(0).toUInt() * 1000000) + (list.at(1).toUInt() * 10000) + (releaseStage * 100) + list.at(3).toUInt(); result = (list.at(0).toUInt() * 100000000) + (list.at(1).toUInt() * 1000000) + (list.at(2).toUInt() * 10000) + (releaseStage * 100) + list.at(4).toUInt();
break; break;
} }
default: default:

Loading…
Cancel
Save