# HG changeset patch # User Hasan Yavuz Ă–ZDERYA # Date 2017-08-17 12:27:52 # Node ID 30dd8e7784b01e426058a08bd1c717dccd890341 # Parent 0d495816e66c8643158c83eaec0378ea46f803f4 getting file list from bitbucket downloads page via api diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -126,6 +126,7 @@ add_executable(${PROGRAM_NAME} WIN32 src/framedreadersettings.cpp src/plotmanager.cpp src/numberformat.cpp + src/updatechecker.cpp misc/windows_icon.rc ${UI_FILES} ${RES_FILES} @@ -136,7 +137,7 @@ target_link_libraries(${PROGRAM_NAME} ${QWT_LIBRARY} ${QTCOLORWIDGETS_LIBRARIES} ) -qt5_use_modules(${PROGRAM_NAME} Widgets SerialPort) +qt5_use_modules(${PROGRAM_NAME} Widgets SerialPort Network) if (BUILD_QWT) add_dependencies(${PROGRAM_NAME} QWT) diff --git a/serialplot.pro b/serialplot.pro --- a/serialplot.pro +++ b/serialplot.pro @@ -68,7 +68,8 @@ SOURCES += \ src/framedreader.cpp \ src/plotmanager.cpp \ src/numberformat.cpp \ - src/recordpanel.cpp + src/recordpanel.cpp \ + src/updatechecker.cpp HEADERS += \ src/mainwindow.h \ @@ -108,7 +109,8 @@ HEADERS += \ src/plotmanager.h \ src/setting_defines.h \ src/numberformat.h \ - src/recordpanel.h + src/recordpanel.h \ + src/updatechecker.h FORMS += \ src/mainwindow.ui \ diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -60,6 +60,7 @@ MainWindow::MainWindow(QWidget *parent) aboutDialog(this), portControl(&serialPort), channelMan(1, 1, this), + updateChecker(this), snapshotMan(this, &channelMan), commandPanel(&serialPort), dataFormatPanel(&serialPort, &channelMan, &recorder), @@ -238,6 +239,9 @@ MainWindow::MainWindow(QWidget *parent) QObject::connect(ui->actionDemoMode, &QAction::toggled, plotMan, &PlotManager::showDemoIndicator); + // TEST UPDATE CHECKER + updateChecker.checkUpdate(); + // load default settings QSettings settings("serialplot", "serialplot"); loadAllSettings(&settings); diff --git a/src/mainwindow.h b/src/mainwindow.h --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -45,6 +45,7 @@ #include "snapshotmanager.h" #include "plotmanager.h" #include "datarecorder.h" +#include "updatechecker.h" namespace Ui { class MainWindow; @@ -79,6 +80,7 @@ private: PlotManager* plotMan; SnapshotManager snapshotMan; DataRecorder recorder; // operated by `recordPanel` + UpdateChecker updateChecker; QLabel spsLabel; CommandPanel commandPanel; diff --git a/src/updatechecker.cpp b/src/updatechecker.cpp new file mode 100644 --- /dev/null +++ b/src/updatechecker.cpp @@ -0,0 +1,107 @@ +#include "updatechecker.h" +#include +#include +#include +#include +#include + +// This returns the list of downloads in JSON format. Note that we only use the first +// page because results are sorted in new to old. +const char BB_DOWNLOADS_URL[] = "https://api.bitbucket.org/2.0/repositories/hyozd/serialplot/downloads?fields=values.name,values.links.self.href"; + +UpdateChecker::UpdateChecker(QObject *parent) : + QObject(parent), nam(this) +{ + connect(&nam, &QNetworkAccessManager::finished, + this, &UpdateChecker::onReqFinished); +} + +void UpdateChecker::checkUpdate() +{ + auto req = QNetworkRequest(QUrl(BB_DOWNLOADS_URL)); + nam.get(req); +} + +void UpdateChecker::onReqFinished(QNetworkReply* reply) +{ + qDebug() << "finished"; + if (reply->error() != QNetworkReply::NoError) + { + emit checkFailed(QString("Network error: ") + reply->errorString()); + } + else + { + QJsonParseError error; + auto data = QJsonDocument::fromJson(reply->readAll(), &error); + if (error.error != QJsonParseError::NoError) + { + emit checkFailed(QString("JSon parsing error: ") + error.errorString()); + } + else + { + QList files; + if (!parseData(data, files)) + { + // TODO: emit detailed data contents for logging + emit checkFailed("Data parsing error."); + qDebug() << "Data parsing error."; + } + else + { + for (auto f : files) + { + qDebug() << f.name << f.link; + } + } + } + } + reply->deleteLater(); +} + +bool UpdateChecker::parseData(const QJsonDocument& data, QList& files) +{ + /* Data is expected to be in this form: + + { + "values": [ + { + "name": "serialplot-0.9.1-x86_64.AppImage", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/hyOzd/serialplot/downloads/serialplot-0.9.1-x86_64.AppImage" + } + } + }, ... ] + } + */ + + if (!data.isObject()) return false; + + auto values = data.object()["values"]; + if (values == QJsonValue::Undefined || !values.isArray()) return false; + + for (auto value : values.toArray()) + { + if (!value.isObject()) return false; + + auto name = value.toObject().value("name"); + if (name.isUndefined() || !name.isString()) + return false; + + auto links = value.toObject().value("links"); + if (links.isUndefined() || !links.isObject()) + return false; + + auto self = links.toObject().value("self"); + if (self.isUndefined() || !self.isObject()) + return false; + + auto href = self.toObject().value("href"); + if (href.isUndefined() || !href.isString()) + return false; + + files += {name.toString(), href.toString()}; + } + + return true; +} diff --git a/src/updatechecker.h b/src/updatechecker.h new file mode 100644 --- /dev/null +++ b/src/updatechecker.h @@ -0,0 +1,37 @@ +#ifndef UPDATECHECKER_H +#define UPDATECHECKER_H + +#include +#include +#include +#include + +class UpdateChecker : public QObject +{ + Q_OBJECT +public: + explicit UpdateChecker(QObject *parent = 0); + +signals: + void updateFound(); + void checkFinished(bool found, QString newVersion, QString downloadUrl); + void checkFailed(QString errorMessage); + +public slots: + void checkUpdate(); + +private: + struct FileInfo + { + QString name; + QString link; + }; + + QNetworkAccessManager nam; + bool parseData(const QJsonDocument& data, QList& files); + +private slots: + void onReqFinished(QNetworkReply* reply); +}; + +#endif // UPDATECHECKER_H