使用 Qt 讀取、分析 GitHub 的 release 資訊


這篇算是 Heresy 自己在寫《角色截圖合併程式》這個 Qt 小程式的時候,想做版本更新檢查的小記錄了。

這邊主要的程式碼是在「QUpdateCheck.cpp」這個檔案(GitHub),試了一陣子,感覺應該是沒問題的。

所以,這邊就稍微紀錄一下吧。


首先,GitHub 本身可以透過 Release 的功能,讓開發者釋出自己編譯好的程式,讓使用者可以下載。

而要存取這邊的資訊,GitHub 則也有提供「Releases API」(官方文件),讓使用者可以透過 https 的形式,來取得 JSON 格式的 release 資訊。

以 Heresy 的這個專案(連結)來說,他的 Release API URL 就是「https://api.github.com/repos/KHeresy/SAOMD-ListImage/releases」;這個 API 沒有權限控管,所有人都可以直接讀取。

所以如果要做更新檢查的話,感覺透過這個 API 應該是個不錯的方法。

至於內容呢,基本上就是各項 release 相關的資料了,其實看起來還滿雜的,這邊就不貼了。


由於 Heresy 在寫這個程式的時候,是想盡量不要多用額外的函式庫,所以網路的部分,也是直接使用 Qt 的 network 模組。(否則之前也曾經用 Boost.Beast 寫過簡單的 http client

要存取 Https 的話,基本上可以寫成下面的樣子:

QNetworkRequest qRequest;
QNetworkAccessManager* qManager = new QNetworkAccessManager(this);
QObject::connect(qManager, SIGNAL(finished(QNetworkReply*)),
                 this,     SLOT(requestFinished(QNetworkReply*))); QSslConfiguration config = QSslConfiguration::defaultConfiguration(); config.setProtocol(QSsl::AnyProtocol); qRequest.setSslConfiguration(config); qRequest.setUrl(QUrl("https://api.github.com/repos/KHeresy/SAOMD-ListImage/releases")); QNetworkReply* qReply = qManager->get(qRequest);

這樣當 https 要求得到回覆後,就會去執行 requestFinished() 這個函式了。

它的內容大致上會像下面這樣:

void QtGuiApplication::requestFinished(QNetworkReply* reply) {
  QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
  if (statusCode.isValid())
    qDebug() << "status code=" << statusCode.toInt();
 
  QVariant reason = reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
  if (reason.isValid())
    qDebug() << "reason=" << reason.toString();
 
  QNetworkReply::NetworkError err = reply->error();
  if (err != QNetworkReply::NoError) {
    qDebug() << "Failed: " << reply->errorString();
  }
  else {
    qDebug() << reply->readAll();
  }
}

這邊可以透過 QNetworkReply 取得狀態碼,判斷要求的結果;如果完全沒問題的話,應該會是 200,但是實際上還是有相當多的可能的。

如果一切正確的話,就是上面黃色的區塊了。

不過這邊要注意的是,如果是要存取 Https 的話,Qt 雖然有提供 QSslConfiguration 這個類別可以產生 SSL 相關的設定,但是實際上他是需要另外準備 OpenSSL 的後台的。

Heresy 這邊是另外去 fire Daemon 下載預先編譯好的 OpenSSL Windows DLL(連結),把 libcrypto-1_1-x64.dll 和 libssl-1_1-x64.dll 這兩個檔案放到和 Qt DLL 同樣的位置,才可以跑得。


由於 GitHub API 都是回傳 JSON 的格式,所以這邊就是用 QJsonDocument 來讀取了~這部分的程式基本上如下:

QJsonDocument qDoc = QJsonDocument::fromJson(qReply->readAll());
if (qDoc.isArray())
{
  QJsonArray qRelSet = qDoc.array();
  if (qRelSet.size() > 0)
  {
    QJsonObject qRelease = qRelSet[0].toObject();
    QString sTagName = qRelease["tag_name"].toString();
    //QString sDate = qRelease["created_at"].toString().mid(0,10);
    QString sContent = qRelease["body"].toString();

    if (!sTagName.isEmpty())
    {
      if (CVersion(SQOMDLI_VER) < CVersion(sTagName))
      {
        QJsonArray qAssets = qRelease["assets"].toArray();
        if (qAssets.size() == 1)
        {
          QString sLink = qAssets[0].toObject()["browser_download_url"].toString();

          // New version found
          return;
        }
      }
      else
      {
        // No New version
        return;
      }
    }
  }
}
//error

在上面的程式碼中,可以抓到版本編號(sTagName)、版本的說明(sContent),以及下載的連結(sLink);如果需要其他的資訊,也都可以自己看是 JSON 裡的哪個 tag,然後再撈出來。

至於拿到這些資訊後,要怎麼處理,則是另一個問題了。

Heresy 這邊是簡單地提供一個按鈕,讓使用者點下去就可以用瀏覽器下載而已了。
因為如果真的要做完整的自動更新,其實會更麻煩一點…


參考:Qt 實現 HTTP 的 Get/Post 請求

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.