diff options
Diffstat (limited to '')
| -rw-r--r-- | src/m_ver_check/SoftwareVersion.cpp | 19 | ||||
| -rw-r--r-- | src/m_ver_check/SoftwareVersion.h | 15 | ||||
| -rw-r--r-- | src/m_ver_check/UpdateTab.cpp | 14 | ||||
| -rw-r--r-- | src/m_ver_check/VersionCheckTask.cpp | 217 | ||||
| -rw-r--r-- | src/m_ver_check/VersionCheckTask.h | 27 | ||||
| -rw-r--r-- | src/m_ver_check/VersionCheckingModule.cpp | 2 | 
6 files changed, 183 insertions, 111 deletions
diff --git a/src/m_ver_check/SoftwareVersion.cpp b/src/m_ver_check/SoftwareVersion.cpp index becc396..6c4ccf1 100644 --- a/src/m_ver_check/SoftwareVersion.cpp +++ b/src/m_ver_check/SoftwareVersion.cpp @@ -44,21 +44,24 @@ auto SoftwareVersion::NeedUpgrade() const -> bool {                      GFModuleStrDup(current_version.toUtf8()),                      GFModuleStrDup(latest_version.toUtf8())))); -  MLogDebug(QString("load done: %1, pre-release: %2, draft: %3") -                .arg(static_cast<int>(loading_done)) -                .arg(static_cast<int>(latest_prerelease_version_from_remote)) -                .arg(static_cast<int>(latest_draft_from_remote))); -  return loading_done && !latest_prerelease_version_from_remote && +  FLOG_DEBUG("load done: %1, pre-release: %2, draft: %3", latest_version, +             latest_prerelease_version_from_remote, latest_draft_from_remote); +  return !latest_version.isEmpty() && !latest_prerelease_version_from_remote &&           !latest_draft_from_remote &&           GFCompareSoftwareVersion(GFModuleStrDup(current_version.toUtf8()),                                    GFModuleStrDup(latest_version.toUtf8())) < 0;  }  auto SoftwareVersion::VersionWithdrawn() const -> bool { -  return loading_done && !current_version_publish_in_remote && +  return !latest_version.isEmpty() && !current_version_publish_in_remote &&           current_version_is_a_prerelease && !current_version_is_drafted;  }  auto SoftwareVersion::CurrentVersionReleased() const -> bool { -  return loading_done && current_version_publish_in_remote; -}
\ No newline at end of file +  return !latest_version.isEmpty() && current_version_publish_in_remote; +} + +auto SoftwareVersion::GitCommitHashMismatch() const -> bool { +  if (remote_commit_hash_by_tag.isEmpty()) return false; +  return remote_commit_hash_by_tag.trimmed() != local_commit_hash.trimmed(); +} diff --git a/src/m_ver_check/SoftwareVersion.h b/src/m_ver_check/SoftwareVersion.h index 89158aa..f66c0dd 100644 --- a/src/m_ver_check/SoftwareVersion.h +++ b/src/m_ver_check/SoftwareVersion.h @@ -41,10 +41,11 @@ struct SoftwareVersion {    bool latest_draft_from_remote = false;               ///<    bool current_version_is_a_prerelease = false;        ///<    bool current_version_is_drafted = false;             ///< -  bool loading_done = false;                           ///<    bool current_version_publish_in_remote = false;      ///<    QString publish_date;                                ///<    QString release_note;                                ///< +  QString remote_commit_hash_by_tag; +  QString local_commit_hash;    /**     * @brief @@ -52,7 +53,9 @@ struct SoftwareVersion {     * @return true     * @return false     */ -  [[nodiscard]] auto InfoValid() const -> bool { return loading_done; } +  [[nodiscard]] auto IsInfoValid() const -> bool { +    return !latest_version.isEmpty(); +  }    /**     * @brief @@ -76,6 +79,14 @@ struct SoftwareVersion {     * @return true     * @return false     */ +  [[nodiscard]] auto GitCommitHashMismatch() const -> bool; + +  /** +   * @brief +   * +   * @return true +   * @return false +   */    [[nodiscard]] auto CurrentVersionReleased() const -> bool;   private: diff --git a/src/m_ver_check/UpdateTab.cpp b/src/m_ver_check/UpdateTab.cpp index 3c4c2c4..64c2a86 100644 --- a/src/m_ver_check/UpdateTab.cpp +++ b/src/m_ver_check/UpdateTab.cpp @@ -120,6 +120,9 @@ void UpdateTab::slot_show_version_status() {    auto is_current_version_released = GFModuleRetrieveRTValueOrDefaultBool(        GFGetModuleID(), GFModuleStrDup("version.current_version_released"), 0); +  auto is_git_commit_hash_mismatch = GFModuleRetrieveRTValueOrDefaultBool( +      GFGetModuleID(), GFModuleStrDup("version.git_commit_hash_mismatch"), 0); +    QString const latest_version = UDUP(GFModuleRetrieveRTValueOrDefault(        GFGetModuleID(), GFModuleStrDup("version.latest_version"),        GFModuleStrDup(""))); @@ -160,6 +163,17 @@ void UpdateTab::slot_show_version_status() {          tr("here") + "</a> " + tr("to download the latest stable version.") +          "</center>");      upgrade_label_->show(); +  } else if (is_git_commit_hash_mismatch != 0) { +    upgrade_label_->setText( +        "<center>" + +        tr("The current version's commit hash does not match the official " +           "release. This may indicate a modified or unofficial build.") + +        "</center><center>" + tr("Click") + +        " <a href=\"https://www.gpgfrontend.bktus.com/overview/downloads/\">" + +        tr("here") + "</a> " + +        tr("to verify your installation or download the official version.") + +        "</center>"); +    upgrade_label_->show();    } else {      upgrade_label_->setText(          "<center>" + diff --git a/src/m_ver_check/VersionCheckTask.cpp b/src/m_ver_check/VersionCheckTask.cpp index 38572cc..f0da4bb 100644 --- a/src/m_ver_check/VersionCheckTask.cpp +++ b/src/m_ver_check/VersionCheckTask.cpp @@ -44,123 +44,146 @@ VersionCheckTask::VersionCheckTask()      : network_manager_(new QNetworkAccessManager(this)),        current_version_(GFProjectVersion()) {    qRegisterMetaType<SoftwareVersion>("SoftwareVersion"); -  version_.current_version = current_version_; +  version_meta_data_.current_version = current_version_; +  version_meta_data_.local_commit_hash = GFProjectGitCommitHash();  }  auto VersionCheckTask::Run() -> int { -  QString latest_version_url = -      "https://api.github.com/repos/saturneric/gpgfrontend/releases/latest"; - -  QNetworkRequest latest_request(latest_version_url); -  latest_request.setHeader(QNetworkRequest::UserAgentHeader, -                           GFHttpRequestUserAgent()); +  QString base_url = "https://api.github.com/repos/saturneric/gpgfrontend"; +  QList<QUrl> urls = { +      {base_url + "/releases/latest"}, +      {base_url + "/releases/tags/" + current_version_}, +      {base_url + "/git/ref/tags/" + current_version_}, +  }; + +  connect(network_manager_, &QNetworkAccessManager::finished, this, +          &VersionCheckTask::slot_parse_reply); + +  for (const QUrl& url : urls) { +    QNetworkRequest request(url); +    request.setHeader(QNetworkRequest::UserAgentHeader, +                      GFHttpRequestUserAgent()); +    QNetworkReply* reply = network_manager_->get(request); +    replies_.append(reply); +  } -  latest_reply_ = network_manager_->get(latest_request); -  connect(latest_reply_, &QNetworkReply::finished, this, -          &VersionCheckTask::slot_parse_latest_version_info);    return 0;  } -void VersionCheckTask::slot_parse_latest_version_info() { -  if (latest_reply_ == nullptr) { -    version_.latest_version = current_version_; -    version_.loading_done = false; -  } else if (latest_reply_->error() != QNetworkReply::NoError) { -    MLogError(QString("latest version request error: %1") -                  .arg(latest_reply_->errorString())); -    version_.latest_version = current_version_; +void VersionCheckTask::slot_parse_reply(QNetworkReply* reply) { +  if (reply->error() == QNetworkReply::NoError) { +    FLOG_DEBUG("get reply from url: %1", reply->url().toString());    } else { -    latest_reply_bytes_ = latest_reply_->readAll(); -    auto latest_reply_json = QJsonDocument::fromJson(latest_reply_bytes_); - -    if (latest_reply_json.isObject()) { -      QString latest_version = latest_reply_json["tag_name"].toString(); - -      QRegularExpression re(R"(^[vV](\d+\.)?(\d+\.)?(\*|\d+))"); -      auto version_match = re.match(latest_version); -      if (version_match.hasMatch()) { -        latest_version = version_match.captured(0); -      } else { -        latest_version = current_version_; -        MLogWarn(QString("latest version unknown, set to current version: %1") -                     .arg(current_version_)); -      } - -      bool prerelease = latest_reply_json["prerelease"].toBool(); -      bool draft = latest_reply_json["draft"].toBool(); -      auto publish_date = latest_reply_json["published_at"].toString(); -      auto release_note = latest_reply_json["body"].toString(); -      version_.latest_version = latest_version; -      version_.latest_prerelease_version_from_remote = prerelease; -      version_.latest_draft_from_remote = draft; -      version_.publish_date = publish_date; -      version_.release_note = release_note; -    } else { -      MLogWarn(QString("cannot parse data got from github: %1") -                   .arg(latest_reply_bytes_)); -    } +    FLOG_DEBUG("get reply from url: %1, error: %2", reply->url().toString(), +               reply->errorString()); +  } + +  switch (replies_.indexOf(reply)) { +    case 0: +      slot_parse_latest_version_info(reply); +      break; +    case 1: +      slot_parse_current_version_info(reply); +      break; +    case 2: +      slot_parse_current_tag_info(reply); +      break; +  } + +  replies_.removeAll(reply); +  reply->deleteLater(); + +  if (replies_.isEmpty()) { +    slot_fill_grt_with_version_info(version_meta_data_); +    emit SignalUpgradeVersion(version_meta_data_); +  } +} + +void VersionCheckTask::slot_parse_latest_version_info(QNetworkReply* reply) { +  if (reply == nullptr || reply->error() != QNetworkReply::NoError) { +    return; +  } + +  auto reply_bytes = reply->readAll(); +  auto latest_reply_json = QJsonDocument::fromJson(reply_bytes); + +  if (!latest_reply_json.isObject()) { +    FLOG_WARN("cannot parse data from github: %1", reply_bytes); +    return;    } -  if (latest_reply_ != nullptr) { -    latest_reply_->deleteLater(); +  QString latest_version = latest_reply_json["tag_name"].toString(); + +  QRegularExpression re(R"(^[vV](\d+\.)?(\d+\.)?(\*|\d+))"); +  auto version_match = re.match(latest_version); +  if (version_match.hasMatch()) { +    latest_version = version_match.captured(0); +  } else { +    latest_version = current_version_; +    MLogWarn(QString("latest version unknown, set to current version: %1") +                 .arg(current_version_));    } -  try { -    QString current_version_url = -        "https://api.github.com/repos/saturneric/gpgfrontend/releases/tags/" + -        current_version_; +  bool prerelease = latest_reply_json["prerelease"].toBool(); +  bool draft = latest_reply_json["draft"].toBool(); +  auto publish_date = latest_reply_json["published_at"].toString(); +  auto release_note = latest_reply_json["body"].toString(); +  version_meta_data_.latest_version = latest_version; +  version_meta_data_.latest_prerelease_version_from_remote = prerelease; +  version_meta_data_.latest_draft_from_remote = draft; +  version_meta_data_.publish_date = publish_date; +  version_meta_data_.release_note = release_note; +} -    QNetworkRequest current_request(current_version_url); -    current_request.setHeader(QNetworkRequest::UserAgentHeader, -                              GFHttpRequestUserAgent()); +void VersionCheckTask::slot_parse_current_version_info(QNetworkReply* reply) { +  if (reply == nullptr || reply->error() != QNetworkReply::NoError) { +    version_meta_data_.current_version_publish_in_remote = false; +    return; +  } -    current_reply_ = network_manager_->get(current_request); +  version_meta_data_.current_version_publish_in_remote = true; +  auto reply_bytes = reply->readAll(); +  auto current_reply_json = QJsonDocument::fromJson(reply_bytes); -    connect(current_reply_, &QNetworkReply::finished, this, -            &VersionCheckTask::slot_parse_current_version_info); -  } catch (...) { -    GFModuleLogError("current version request create error"); +  if (!current_reply_json.isObject()) { +    FLOG_WARN("cannot parse data from github: %1", reply_bytes); +    return;    } + +  bool current_prerelease = current_reply_json["prerelease"].toBool(); +  bool current_draft = current_reply_json["draft"].toBool(); +  version_meta_data_.latest_prerelease_version_from_remote = current_prerelease; +  version_meta_data_.latest_draft_from_remote = current_draft;  } -void VersionCheckTask::slot_parse_current_version_info() { -  if (current_reply_ == nullptr) { -    // loading done -    version_.loading_done = false; +void VersionCheckTask::slot_parse_current_tag_info(QNetworkReply* reply) { +  if (reply == nullptr || reply->error() != QNetworkReply::NoError) { +    version_meta_data_.current_version_publish_in_remote = false; +    return; +  } -  } else if (current_reply_->error() != QNetworkReply::NoError) { -    MLogError(QString("current version request network error: {}") -                  .arg(current_reply_->errorString())); +  version_meta_data_.current_version_publish_in_remote = true; +  auto reply_bytes = reply->readAll(); +  auto current_reply_json = QJsonDocument::fromJson(reply_bytes); -    // loading done -    version_.loading_done = true; -    version_.current_version_publish_in_remote = false; -  } else { -    version_.current_version_publish_in_remote = true; -    current_reply_bytes_ = current_reply_->readAll(); -    auto current_reply_json = QJsonDocument::fromJson(current_reply_bytes_); - -    if (current_reply_json.isObject()) { -      bool current_prerelease = current_reply_json["prerelease"].toBool(); -      bool current_draft = current_reply_json["draft"].toBool(); -      version_.latest_prerelease_version_from_remote = current_prerelease; -      version_.latest_draft_from_remote = current_draft; -      // loading done -      version_.loading_done = true; -    } else { -      MLogWarn(QString("cannot parse data got from github: %1") -                   .arg(current_reply_bytes_)); -    } +  if (!current_reply_json.isObject()) { +    FLOG_WARN("cannot parse data from github: %1", reply_bytes); +    return;    } -  if (current_reply_ != nullptr) current_reply_->deleteLater(); +  auto object = current_reply_json["object"].toObject(); +  if (object["type"].toString() != "commit") { +    FLOG_WARN("remote tag: %1 is not a ref: %2", +              version_meta_data_.current_version, object["type"].toString()); +    return; +  } -  slot_fill_grt_with_version_info(version_); -  emit SignalUpgradeVersion(version_); +  auto sha = object["sha"].toString(); +  version_meta_data_.remote_commit_hash_by_tag = sha;  }  void VersionCheckTask::slot_fill_grt_with_version_info( -    const SoftwareVersion &version) { +    const SoftwareVersion& version) {    GFModuleLogDebug("filling software information info in rt...");    GFModuleUpsertRTValue(GFGetModuleID(), @@ -169,6 +192,13 @@ void VersionCheckTask::slot_fill_grt_with_version_info(    GFModuleUpsertRTValue(GFGetModuleID(),                          GFModuleStrDup("version.latest_version"),                          GFModuleStrDup(version.latest_version.toUtf8())); +  GFModuleUpsertRTValue( +      GFGetModuleID(), GFModuleStrDup("version.remote_commit_hash_by_tag"), +      GFModuleStrDup(version.remote_commit_hash_by_tag.toUtf8())); +  GFModuleUpsertRTValue(GFGetModuleID(), +                        GFModuleStrDup("version.local_commit_hash"), +                        GFModuleStrDup(version.local_commit_hash.toUtf8())); +    GFModuleUpsertRTValueBool(        GFGetModuleID(), GFModuleStrDup("version.current_version_is_drafted"),        version.current_version_is_drafted ? 1 : 0); @@ -193,12 +223,15 @@ void VersionCheckTask::slot_fill_grt_with_version_info(    GFModuleUpsertRTValueBool(        GFGetModuleID(), GFModuleStrDup("version.current_a_withdrawn_version"),        version.VersionWithdrawn() ? 1 : 0); +  GFModuleUpsertRTValueBool(GFGetModuleID(), +                            GFModuleStrDup("version.git_commit_hash_mismatch"), +                            version.GitCommitHashMismatch() ? 1 : 0);    GFModuleUpsertRTValue(GFGetModuleID(), GFModuleStrDup("version.release_note"),                          GFModuleStrDup(version.release_note.toUtf8()));    GFModuleUpsertRTValueBool(GFGetModuleID(),                              GFModuleStrDup("version.loading_done"), -                            version.loading_done ? 1 : 0); +                            version.IsInfoValid() ? 1 : 0);    GFModuleLogDebug("software information filled in rt");  } diff --git a/src/m_ver_check/VersionCheckTask.h b/src/m_ver_check/VersionCheckTask.h index 3d9c6b6..764c46e 100644 --- a/src/m_ver_check/VersionCheckTask.h +++ b/src/m_ver_check/VersionCheckTask.h @@ -70,26 +70,37 @@ class VersionCheckTask : public QObject {     * @brief     *     */ -  void slot_parse_latest_version_info(); +  void slot_parse_reply(QNetworkReply* reply);    /**     * @brief     * +   * @param reply     */ -  void slot_parse_current_version_info(); +  void slot_parse_latest_version_info(QNetworkReply* reply);    /**     * @brief     * +   * @param reply +   */ +  void slot_parse_current_version_info(QNetworkReply* reply); + +  /** +   * @brief +   * +   * @param reply +   */ +  void slot_parse_current_tag_info(QNetworkReply* reply); +  /** +   * @brief +   *     */    void slot_fill_grt_with_version_info(const SoftwareVersion&);   private: -  QByteArray latest_reply_bytes_;           ///< -  QByteArray current_reply_bytes_;          ///< -  QNetworkReply* latest_reply_ = nullptr;   ///< latest version info reply -  QNetworkReply* current_reply_ = nullptr;  ///< current version info reply +  QList<QNetworkReply*> replies_;           ///<    QNetworkAccessManager* network_manager_;  ///< -  QString current_version_; -  SoftwareVersion version_; +  QString current_version_;                 ///< +  SoftwareVersion version_meta_data_;  }; diff --git a/src/m_ver_check/VersionCheckingModule.cpp b/src/m_ver_check/VersionCheckingModule.cpp index 723e833..d672fe7 100644 --- a/src/m_ver_check/VersionCheckingModule.cpp +++ b/src/m_ver_check/VersionCheckingModule.cpp @@ -44,7 +44,7 @@  #include "VersionCheckTask.h"  GF_MODULE_API_DEFINE("com.bktus.gpgfrontend.module.version_checking", -                     "VersionChecking", "1.1.0", +                     "VersionChecking", "1.2.0",                       "Try checking GpgFrontend version.", "Saturneric");  DEFINE_TRANSLATIONS_STRUCTURE(ModuleVersionChecking);  | 
