119 lines
3.4 KiB
C++
119 lines
3.4 KiB
C++
// MassBuilderSaveTool
|
|
// Copyright (C) 2021-2023 Guillaume Jacquemin
|
|
//
|
|
// This program 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.
|
|
//
|
|
// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
#include <Corrade/Containers/ScopeGuard.h>
|
|
#include <Corrade/Containers/String.h>
|
|
#include <Corrade/Containers/StringView.h>
|
|
#include <Corrade/Utility/Format.h>
|
|
|
|
#include <curl/curl.h>
|
|
|
|
#include "../Logger/Logger.h"
|
|
|
|
#include "UpdateChecker.h"
|
|
|
|
using namespace Corrade;
|
|
|
|
UpdateChecker::UpdateChecker() {
|
|
LOG_INFO("Initialising update checker.");
|
|
curl_global_init(CURL_GLOBAL_DEFAULT);
|
|
}
|
|
|
|
UpdateChecker::~UpdateChecker() {
|
|
LOG_INFO("Shutting libcurl down.");
|
|
curl_global_cleanup();
|
|
}
|
|
|
|
inline
|
|
std::size_t
|
|
writeCallback(char* data, std::size_t size, std::size_t nmemb, void* user_data) {
|
|
if(!data || !user_data) return std::size_t{};
|
|
|
|
auto* s = static_cast<Containers::String*>(user_data);
|
|
(*s) = (*s) + Containers::StringView{data, size * nmemb};
|
|
|
|
return size * nmemb;
|
|
}
|
|
|
|
UpdateChecker::Result
|
|
UpdateChecker::check() {
|
|
auto curl = curl_easy_init();
|
|
if(!curl) {
|
|
return Result::CurlInitFailed;
|
|
}
|
|
|
|
Containers::ScopeGuard guard(curl, curl_easy_cleanup);
|
|
|
|
Containers::String response_body{Containers::AllocatedInit, ""};
|
|
Containers::String error_buffer{ValueInit, CURL_ERROR_SIZE};
|
|
|
|
curl_easy_setopt(curl, CURLOPT_URL, "https://williamjcm.ovh/mbst/version");
|
|
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
|
|
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
|
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
|
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_body);
|
|
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_buffer.data());
|
|
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 0L);
|
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
|
|
|
|
auto code = curl_easy_perform(curl);
|
|
|
|
if(code == CURLE_OK) {
|
|
long status = 0;
|
|
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
|
|
|
|
if(status != 200) {
|
|
_error = Utility::format("The request failed with error code {}.", status);
|
|
return Result::HttpError;
|
|
}
|
|
|
|
auto parts = response_body.splitOnAnyWithoutEmptyParts("\r\n");
|
|
|
|
_foundVersion = Version{parts.front()};
|
|
_downloadLink = parts.back();
|
|
LOG_INFO_FORMAT("Found version: {}", Containers::String{_foundVersion});
|
|
|
|
return Result::Success;
|
|
}
|
|
else if(code == CURLE_OPERATION_TIMEDOUT) {
|
|
return Result::CurlTimeout;
|
|
}
|
|
else {
|
|
_error = Utility::format("{}: {}", curl_easy_strerror(code), error_buffer);
|
|
return Result::CurlError;
|
|
}
|
|
}
|
|
|
|
Containers::StringView
|
|
UpdateChecker::error() const {
|
|
return _error;
|
|
}
|
|
|
|
bool
|
|
UpdateChecker::updateAvailable() const {
|
|
return _foundVersion > current_version;
|
|
}
|
|
|
|
const Version&
|
|
UpdateChecker::version() const {
|
|
return _foundVersion;
|
|
}
|
|
|
|
Containers::StringView
|
|
UpdateChecker::downloadLink() const {
|
|
return _downloadLink;
|
|
}
|