# HG changeset patch # User Hasan Yavuz ÖZDERYA # Date 2017-08-19 14:25:33 # Node ID be15373e2a3899a25fb80b24eb071cd5c113d4e8 # Parent 69502eaef6c8872c719dce634de01782686a2625 filter file list and find update diff --git a/src/updatechecker.cpp b/src/updatechecker.cpp --- a/src/updatechecker.cpp +++ b/src/updatechecker.cpp @@ -1,12 +1,34 @@ -#include "updatechecker.h" -#include +/* + Copyright © 2017 Hasan Yavuz Özderya + + This file is part of serialplot. + + serialplot is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + serialplot is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with serialplot. If not, see . +*/ + #include #include #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. +#include "updatechecker.h" + +// This link returns the list of downloads in JSON format. Note that we only use +// the first page because results are sorted 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) : @@ -24,7 +46,6 @@ void UpdateChecker::checkUpdate() void UpdateChecker::onReqFinished(QNetworkReply* reply) { - qDebug() << "finished"; if (reply->error() != QNetworkReply::NoError) { emit checkFailed(QString("Network error: ") + reply->errorString()); @@ -44,13 +65,18 @@ void UpdateChecker::onReqFinished(QNetwo { // TODO: emit detailed data contents for logging emit checkFailed("Data parsing error."); - qDebug() << "Data parsing error."; } else { - for (auto f : files) + FileInfo updateFile; + if (findUpdate(files, updateFile)) { - qDebug() << f.name << f.link; + emit checkFinished( + true, updateFile.version.toString(), updateFile.link); + } + else + { + emit checkFinished(false, "", ""); } } } @@ -58,7 +84,7 @@ void UpdateChecker::onReqFinished(QNetwo reply->deleteLater(); } -bool UpdateChecker::parseData(const QJsonDocument& data, QList& files) +bool UpdateChecker::parseData(const QJsonDocument& data, QList& files) const { /* Data is expected to be in this form: @@ -100,8 +126,82 @@ bool UpdateChecker::parseData(const QJso if (href.isUndefined() || !href.isString()) return false; - files += {name.toString(), href.toString()}; + FileInfo finfo; + finfo.name = name.toString(); + finfo.link = href.toString(); + finfo.hasVersion = VersionNumber::extract(name.toString(), finfo.version); + + if (finfo.name.contains("amd64") || + finfo.name.contains("x86_64") || + finfo.name.contains("win64")) + { + finfo.arch = FileArch::amd64; + } + else if (finfo.name.contains("win32") || + finfo.name.contains("i386")) + { + finfo.arch = FileArch::i386; + } + else + { + finfo.arch = FileArch::unknown; + } + + files += finfo; } return true; } + +bool UpdateChecker::findUpdate(const QList& files, FileInfo& foundFile) const +{ + QList fflist; + + // filter the file list according to extension and version number + for (int i = 0; i < files.length(); i++) + { + // file type to look +#if defined(Q_OS_WIN) + const char ext[] = ".exe"; +#else // of course linux + const char ext[] = ".appimage"; +#endif + + // file architecture to look +#if defined(Q_PROCESSOR_X86_64) + const FileArch arch = FileArch::amd64; +#elif defined(Q_PROCESSOR_X86_32) + const FileArch arch = FileArch::i386; +#elif defined(Q_PROCESSOR_ARM) + const FileArch arch = FileArch::arm; +#else + #error Unknown architecture for update file detection. +#endif + + // filter the file list + auto file = files[i]; + if (file.name.contains(ext, Qt::CaseInsensitive) && + file.arch == arch && + file.hasVersion && file.version > CurrentVersion) + { + fflist += file; + } + } + + // sort and find most up to date file + if (!fflist.empty()) + { + std::sort(fflist.begin(), fflist.end(), + [](const FileInfo& a, const FileInfo& b) + { + return a.version > b.version; + }); + + foundFile = fflist[0]; + return true; + } + else + { + return false; + } +} diff --git a/src/updatechecker.h b/src/updatechecker.h --- a/src/updatechecker.h +++ b/src/updatechecker.h @@ -1,3 +1,22 @@ +/* + Copyright © 2017 Hasan Yavuz Özderya + + This file is part of serialplot. + + serialplot is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + serialplot is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with serialplot. If not, see . +*/ + #ifndef UPDATECHECKER_H #define UPDATECHECKER_H @@ -6,6 +25,8 @@ #include #include +#include "versionnumber.h" + class UpdateChecker : public QObject { Q_OBJECT @@ -13,7 +34,6 @@ public: explicit UpdateChecker(QObject *parent = 0); signals: - void updateFound(); void checkFinished(bool found, QString newVersion, QString downloadUrl); void checkFailed(QString errorMessage); @@ -21,14 +41,29 @@ public slots: void checkUpdate(); private: + enum class FileArch + { + unknown, + i386, + amd64, + arm + }; + struct FileInfo { QString name; QString link; + bool hasVersion; + VersionNumber version; + FileArch arch; }; QNetworkAccessManager nam; - bool parseData(const QJsonDocument& data, QList& files); + /// Parses json and creates a list of files + bool parseData(const QJsonDocument& data, QList& files) const; + /// Finds the update file in the file list. Returns `-1` if no new version + /// is found. + bool findUpdate(const QList& files, FileInfo& foundFile) const; private slots: void onReqFinished(QNetworkReply* reply);