/src/components/update/UpdateChecker.cpp

https://github.com/Qv2ray/Qv2ray · C++ · 103 lines · 88 code · 9 blank · 6 comment · 10 complexity · ef72b41ac0d5f38d3df3d21f088419ae MD5 · raw file

  1. #include "UpdateChecker.hpp"
  2. #include "3rdparty/libsemver/version.hpp"
  3. #include "base/Qv2rayBase.hpp"
  4. #include "common/HTTPRequestHelper.hpp"
  5. #include "common/QvHelpers.hpp"
  6. #include "core/settings/SettingsBackend.hpp"
  7. #include <QDesktopServices>
  8. #include <QVersionNumber>
  9. const inline QMap<int, QString> UpdateChannelLink //
  10. {
  11. { 0, "https://api.github.com/repos/Qv2ray/Qv2ray/releases/latest" }, //
  12. { 1, "https://api.github.com/repos/Qv2ray/Qv2ray/releases?per_page=1" } //
  13. };
  14. namespace Qv2ray::components
  15. {
  16. QvUpdateChecker::QvUpdateChecker(QObject *parent) : QObject(parent)
  17. {
  18. requestHelper = new NetworkRequestHelper(this);
  19. }
  20. QvUpdateChecker::~QvUpdateChecker()
  21. {
  22. }
  23. void QvUpdateChecker::CheckUpdate()
  24. {
  25. #ifndef DISABLE_AUTO_UPDATE
  26. if (QFile(QV2RAY_CONFIG_DIR + "QV2RAY_FEATURE_DISABLE_AUTO_UPDATE").exists())
  27. return;
  28. const auto &updateChannel = GlobalConfig.updateConfig.updateChannel;
  29. LOG(MODULE_NETWORK, "Start checking update for channel ID: " + QSTRN(updateChannel))
  30. requestHelper->AsyncHttpGet(UpdateChannelLink[updateChannel], &QvUpdateChecker::VersionUpdate);
  31. #endif
  32. }
  33. void QvUpdateChecker::VersionUpdate(const QByteArray &data)
  34. {
  35. // Version update handler.
  36. const auto doc = QJsonDocument::fromJson(data);
  37. const auto root = doc.isArray() ? doc.array().first().toObject() : doc.object();
  38. if (root.isEmpty())
  39. return;
  40. const auto newVersionStr = root["tag_name"].toString("v").mid(1);
  41. const auto currentVersionStr = QString(QV2RAY_VERSION_STRING);
  42. const auto ignoredVersionStr = GlobalConfig.updateConfig.ignoredVersion.isEmpty() ? "0.0.0" : GlobalConfig.updateConfig.ignoredVersion;
  43. //
  44. bool hasUpdate = false;
  45. try
  46. {
  47. const auto newVersion = semver::version::from_string(newVersionStr.toStdString());
  48. const auto currentVersion = semver::version::from_string(currentVersionStr.toStdString());
  49. const auto ignoredVersion = semver::version::from_string(ignoredVersionStr.toStdString());
  50. //
  51. LOG(MODULE_UPDATE, QString("Received update info:") + NEWLINE + //
  52. " --> Latest: " + newVersionStr + NEWLINE + //
  53. " --> Current: " + currentVersionStr + NEWLINE + //
  54. " --> Ignored: " + ignoredVersionStr)
  55. // If the version is newer than us.
  56. // And new version is newer than the ignored version.
  57. hasUpdate = (newVersion > currentVersion && newVersion > ignoredVersion);
  58. }
  59. catch (...)
  60. {
  61. LOG(MODULE_UPDATE, "Some strange exception occured, cannot check update.")
  62. }
  63. if (hasUpdate)
  64. {
  65. const auto name = root["name"].toString("");
  66. if (name.contains("NO_RELEASE"))
  67. {
  68. LOG(MODULE_UPDATE, "Found the recent release title with NO_RELEASE tag. Ignoring")
  69. return;
  70. }
  71. const auto link = root["html_url"].toString("");
  72. auto result = QvMessageBoxAsk(nullptr, tr("Qv2ray Update"),
  73. tr("A new version of Qv2ray has been found:") + //
  74. "v" + newVersionStr + NEWLINE + NEWLINE + //
  75. name + NEWLINE "------------" NEWLINE + //
  76. root["body"].toString(""),
  77. QMessageBox::Ignore);
  78. if (result == QMessageBox::Yes)
  79. {
  80. QDesktopServices::openUrl(link);
  81. }
  82. else if (result == QMessageBox::Ignore)
  83. {
  84. // Set and save ingored version.
  85. GlobalConfig.updateConfig.ignoredVersion = newVersionStr;
  86. SaveGlobalSettings();
  87. }
  88. }
  89. else
  90. {
  91. LOG(MODULE_UPDATE, "No suitable updates found on channel " + QSTRN(GlobalConfig.updateConfig.updateChannel))
  92. }
  93. }
  94. } // namespace Qv2ray::components