Enigma 3.2.2
A Simple, Reliable and Efficient Encryption Tool
Loading...
Searching...
No Matches
CheckForUpdates.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef ENIGMA_NETWORKING_CHECK_FOR_UPDATES_H
3#define ENIGMA_NETWORKING_CHECK_FOR_UPDATES_H
4
5#include <Core/Core.hpp>
6#include <Core/Version.hpp>
7#include <Logger/Logger.hpp>
8
9#include <memory>
10
11#pragma warning(push, 0)
13#include <cpr/cpr.h>
15#include <nlohmann/json.hpp>
16#pragma warning(pop)
17
18
20class CheckForUpdates final {
22
23 public:
25 struct Version {
26 std::uint16_t major;
27 std::uint16_t minor;
28 std::uint16_t patch;
29
30 Version() : major(0), minor(0), patch(0) {}
31 Version(const std::string& tag_name) {
32 Parse(tag_name);
33 }
34
35 void Parse(const std::string& tag_name) {
36 const std::vector<std::string> parts = StringUtils::Split(tag_name, '.');
37 ENIGMA_ASSERT_OR_THROW(parts.size() == 3, fmt::format("Version tag_name is malformed, expected major.minor.patch (%d.%d.%d) but received {}", tag_name));
38
39 // Convert string parts to std::uint16_t major minor patch
40 const auto stoui16 = [](const std::string& str) -> std::uint16_t {
41 std::uint16_t i{};
42 std::stringstream oss(str);
43 oss >> i;
44 return i;
45 };
46
47 major = stoui16(parts[0]);
48 minor = stoui16(parts[1]);
49 patch = stoui16(parts[2]);
50 }
51
52
53 constexpr bool operator>(const Version& other) const noexcept {
54 if (major > other.major) return true;
55 if (major < other.major) return false;
56 // At this point, major == other.major
57 if (minor > other.minor) return true;
58 if (minor < other.minor) return false;
59 // At this point, minor == other.minor
60 return patch > other.patch;
61 }
62
63 constexpr bool operator<(const Version& other) const noexcept {
64 if (major < other.major) return true;
65 if (major > other.major) return false;
66 // At this point, major == other.major
67 if (minor < other.minor) return true;
68 if (minor > other.minor) return false;
69 // At this point, minor == other.minor
70 return patch < other.patch;
71 }
72
73 constexpr bool operator==(const Version& other) const noexcept {
74 return major == other.major && minor == other.minor && patch == other.patch;
75 }
76
77 friend std::ostream& operator<<(std::ostream& os, const Version& v) noexcept {
78 return os << v.major << '.' << v.minor << '.' << v.patch;
79 }
80 };
81
84 std::string name; // "name": "Enigma Release (Windows x64, Linux x64)",
85 std::string tag_name; // version e.g 1.0.0
86 std::string created_at; //"created_at": "2021-02-06T11:41:26Z",
87 std::string published_at; //"published_at" : "2021-02-06T12:16:37Z",
88 std::string body; // "body": "Enigma first stable release for Windows x64 and Linux x64 using:\r\n- Crypto++ v8.4.0\r\n- GLFW v3.3.2\r\n- ImGui v1.79\r\n- spdlog v1.8.0\r\n- and other libraries"
89 std::string tarball_url; // "tarball_url": "https://api.github.com/repos/BaderEddineOuaich/Enigma/tarball/v1.0.0",
90 std::string zipball_url; // "zipball_url" : "https://api.github.com/repos/BaderEddineOuaich/Enigma/zipball/v1.0.0",
91 Version version; // parsed comparable version
92
94 : tag_name("<unknown>"),
95 name("<unknown>"),
96 created_at("<unknown>"),
97 published_at("<unknown>"),
98 body("<unknown>"),
99 tarball_url("<unknown>"),
100 zipball_url("<unknown>"),
101 version() {}
102
103 ~LatestReleaseInfo() noexcept = default;
104
105 static std::unique_ptr<LatestReleaseInfo> FromJson(const nlohmann::json& obj) {
106#define CC1(a, b) a##b
107#define CC(a, b) CC1(a, b)
108#define ASSIGN_IF(var, field, json_type) \
109 if (!obj[field].is_null() && CC(obj[field].is_, json_type)()) \
110 (var) = obj[field].get<decltype(var)>();
111
112 std::unique_ptr<LatestReleaseInfo> info = std::make_unique<LatestReleaseInfo>();
113 ASSIGN_IF(info->name, "name", string);
114 ASSIGN_IF(info->tag_name, "tag_name", string);
115 ASSIGN_IF(info->created_at, "created_at", string);
116 ASSIGN_IF(info->published_at, "published_at", string);
117 ASSIGN_IF(info->body, "body", string);
118 ASSIGN_IF(info->tarball_url, "tarball_url", string);
119 ASSIGN_IF(info->zipball_url, "zipball_url", string);
120
121 info->version.Parse(info->tag_name); // parse version by tagname
122 return info;
123
124#undef ASSIGN_IF
125#undef CC1
126#undef CC
127 }
128
129 std::string toString() noexcept {
130 std::ostringstream oss;
131 if (!name.empty())
132 oss << "name: " << name << " ";
133 if (!tag_name.empty())
134 oss << "tag name: " << tag_name << " ";
135 if (!created_at.empty())
136 oss << "created at: " << created_at << " ";
137 if (!published_at.empty())
138 oss << "published at: " << published_at << " ";
139 if (!body.empty())
140 oss << "body: " << body << " ";
141 if (!tarball_url.empty())
142 oss << "tarball_url: " << tarball_url << " ";
143 if (!zipball_url.empty())
144 oss << "zipball_url: " << zipball_url << " ";
145 return oss.str();
146 }
147 };
148
149 public:
151 static std::unique_ptr<LatestReleaseInfo> GetLatestReleaseInfo() {
152 try {
153 cpr::Url url = Constants::Links::ENIGMA_GITHUB_API_LATEST_RELEASE;
154 cpr::Response response = cpr::Get(url);
155 if (response.status_code == cpr::status::HTTP_OK) {
156 nlohmann::json data = nlohmann::json::parse(response.text);
157 return LatestReleaseInfo::FromJson(data);
158 } else
159 ENIGMA_WARN("Failed to get latest release info with status code {0}", response.status_code);
160 } catch (const std::exception& e) {
161 ENIGMA_WARN("Failed to get latest release info with exception {0}", e.what());
162 }
163 return nullptr;
164 }
165};
167
168
169#endif // !ENIGMA_NETWORKING_CHECK_FOR_UPDATES_H
#define ASSIGN_IF(var, field, json_type)
#define ENIGMA_WARN(...)
Definition Logger.hpp:42
#define NS_ENIGMA_BEGIN
Enable/Disable Assertions.
Definition Macros.hpp:13
#define NS_ENIGMA_END
Definition Macros.hpp:14
#define ENIGMA_STATIC_CLASS(Class)
Makes a class static, which will prevent creating instances from it and only use it as Class::Func()....
Definition Macros.hpp:120
#define ENIGMA_ASSERT_OR_THROW(x, msg)
Definition Macros.hpp:41
cpr: cURL c++ wrapper
static std::unique_ptr< LatestReleaseInfo > GetLatestReleaseInfo()
static std::vector< StringType > Split(const StringType &str, const typename std::string::value_type delimiter)
static std::unique_ptr< LatestReleaseInfo > FromJson(const nlohmann::json &obj)
~LatestReleaseInfo() noexcept=default
friend std::ostream & operator<<(std::ostream &os, const Version &v) noexcept
Version(const std::string &tag_name)
constexpr bool operator==(const Version &other) const noexcept
void Parse(const std::string &tag_name)
constexpr bool operator<(const Version &other) const noexcept
constexpr bool operator>(const Version &other) const noexcept