diff --git a/src/updatechecker.cpp b/src/updatechecker.cpp deleted file mode 100644 --- a/src/updatechecker.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/* - Copyright © 2018 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 - -#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) : - QObject(parent), nam(this) -{ - activeReply = NULL; - - connect(&nam, &QNetworkAccessManager::finished, - this, &UpdateChecker::onReqFinished); -} - -bool UpdateChecker::isChecking() const -{ - return activeReply != NULL && !activeReply->isFinished(); -} - -void UpdateChecker::checkUpdate() -{ - if (isChecking()) return; - - auto req = QNetworkRequest(QUrl(BB_DOWNLOADS_URL)); - activeReply = nam.get(req); -} - -void UpdateChecker::cancelCheck() -{ - if (activeReply != NULL) activeReply->abort(); -} - -void UpdateChecker::onReqFinished(QNetworkReply* reply) -{ - 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."); - } - else - { - FileInfo updateFile; - if (findUpdate(files, updateFile)) - { - emit checkFinished( - true, updateFile.version.toString(), updateFile.link); - } - else - { - emit checkFinished(false, "", ""); - } - } - } - } - reply->deleteLater(); - activeReply = NULL; -} - -bool UpdateChecker::parseData(const QJsonDocument& data, QList& files) const -{ - /* 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().value("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; - - 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; - } -}