/qtclient/JammrUpdateChecker.cpp

https://github.com/wahjam/wahjam · C++ · 151 lines · 111 code · 22 blank · 18 comment · 21 complexity · c21ae6cb45cd3547d7ac1badb526caa0 MD5 · raw file

  1. /*
  2. Copyright (C) 2013 Stefan Hajnoczi <stefanha@gmail.com>
  3. Wahjam is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. Wahjam is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with Wahjam; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  14. */
  15. #include <QNetworkRequest>
  16. #include <QMessageBox>
  17. #include <QDesktopServices>
  18. #include <QCoreApplication>
  19. #include "JammrUpdateChecker.h"
  20. JammrUpdateChecker::JammrUpdateChecker(QWidget *parent_, QNetworkAccessManager *netManager_)
  21. : QObject(parent_), parent(parent_), netManager(netManager_), reply(nullptr)
  22. {
  23. }
  24. JammrUpdateChecker::~JammrUpdateChecker()
  25. {
  26. if (reply) {
  27. reply->abort();
  28. }
  29. }
  30. void JammrUpdateChecker::setUpdateUrl(const QUrl &updateUrl_)
  31. {
  32. updateUrl = updateUrl_;
  33. }
  34. void JammrUpdateChecker::setDownloadUrl(const QUrl &downloadUrl_)
  35. {
  36. downloadUrl = downloadUrl_;
  37. }
  38. void JammrUpdateChecker::start()
  39. {
  40. if (updateUrl.isEmpty()) {
  41. return;
  42. }
  43. QNetworkRequest request(updateUrl);
  44. reply = netManager->get(request);
  45. connect(reply, SIGNAL(finished()), this, SLOT(requestFinished()));
  46. connect(reply, &QNetworkReply::sslErrors,
  47. this, &JammrUpdateChecker::requestSslErrors);
  48. qDebug("Checking for updates from %s", updateUrl.toString().toLatin1().data());
  49. }
  50. /* Parse a major.minor.version string into numbers */
  51. static void parseVersionString(const QString &str,
  52. unsigned *major,
  53. unsigned *minor,
  54. unsigned *patch)
  55. {
  56. QStringList fields = str.split('.');
  57. if (fields.size() != 3) {
  58. *major = 0;
  59. *minor = 0;
  60. *patch = 0;
  61. return;
  62. }
  63. *major = fields.at(0).toUInt();
  64. *minor = fields.at(1).toUInt();
  65. *patch = fields.at(2).toUInt();
  66. }
  67. static bool isUpToDate(const QString &ourVersion, const QString &latestVersion)
  68. {
  69. unsigned ourMajor, ourMinor, ourPatch;
  70. parseVersionString(ourVersion, &ourMajor, &ourMinor, &ourPatch);
  71. unsigned latestMajor, latestMinor, latestPatch;
  72. parseVersionString(latestVersion, &latestMajor, &latestMinor, &latestPatch);
  73. if (ourMajor > latestMajor) {
  74. return true;
  75. }
  76. if (ourMajor == latestMajor) {
  77. if (ourMinor > latestMinor) {
  78. return true;
  79. }
  80. if (ourMinor == latestMinor) {
  81. return ourPatch >= latestPatch;
  82. }
  83. }
  84. return false;
  85. }
  86. void JammrUpdateChecker::requestSslErrors(const QList<QSslError> &errors)
  87. {
  88. for (const QSslError &error : errors) {
  89. qCritical("SSL error: %s", error.errorString().toLatin1().constData());
  90. }
  91. }
  92. void JammrUpdateChecker::requestFinished()
  93. {
  94. QNetworkReply *theReply = reply;
  95. reply->deleteLater();
  96. reply = nullptr;
  97. QNetworkReply::NetworkError err = theReply->error();
  98. if (err == QNetworkReply::OperationCanceledError) {
  99. return;
  100. } else if (err != QNetworkReply::NoError) {
  101. qCritical("Update checker network reply failed (error=%d, "
  102. "errorString=\"%s\")",
  103. err, theReply->errorString().toLatin1().constData());
  104. return;
  105. }
  106. int statusCode = theReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
  107. if (statusCode != 200 /* HTTP SUCCESS */) {
  108. qCritical("Update checker HTTP reply failed (status=%d)", statusCode);
  109. return;
  110. }
  111. QString latestVersion = QString::fromUtf8(theReply->readAll()).trimmed();
  112. qDebug("Update checker finished, current \"%s\" latest \"%s\"",
  113. VERSION, latestVersion.toLatin1().data());
  114. if (isUpToDate(VERSION, latestVersion)) {
  115. return;
  116. }
  117. QMessageBox::StandardButton button = QMessageBox::information(parent,
  118. tr("Updates available..."),
  119. tr("It is recommended that you update to version %1. Close jammr and download updates now?").arg(latestVersion),
  120. QMessageBox::Yes | QMessageBox::No,
  121. QMessageBox::Yes);
  122. if (button == QMessageBox::Yes) {
  123. QDesktopServices::openUrl(downloadUrl);
  124. QCoreApplication::quit();
  125. }
  126. }