diff options
Diffstat (limited to 'rbutil/rbutilqt/base/playerbuildinfo.cpp')
-rw-r--r-- | rbutil/rbutilqt/base/playerbuildinfo.cpp | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/rbutil/rbutilqt/base/playerbuildinfo.cpp b/rbutil/rbutilqt/base/playerbuildinfo.cpp new file mode 100644 index 0000000000..fb8b121e8f --- /dev/null +++ b/rbutil/rbutilqt/base/playerbuildinfo.cpp | |||
@@ -0,0 +1,265 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * Copyright (C) 2020 by Dominik Riebeling | ||
10 | * | ||
11 | * All files in this archive are subject to the GNU General Public License. | ||
12 | * See the file COPYING in the source tree root for full license agreement. | ||
13 | * | ||
14 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
15 | * KIND, either express or implied. | ||
16 | * | ||
17 | ****************************************************************************/ | ||
18 | |||
19 | #include "playerbuildinfo.h" | ||
20 | #include "rbsettings.h" | ||
21 | #include "Logger.h" | ||
22 | |||
23 | PlayerBuildInfo* PlayerBuildInfo::infoInstance = nullptr; | ||
24 | |||
25 | PlayerBuildInfo* PlayerBuildInfo::instance() | ||
26 | { | ||
27 | if (infoInstance == nullptr) { | ||
28 | infoInstance = new PlayerBuildInfo(); | ||
29 | } | ||
30 | return infoInstance; | ||
31 | } | ||
32 | |||
33 | // server infos | ||
34 | const static struct { | ||
35 | PlayerBuildInfo::BuildInfo item; | ||
36 | const char* name; | ||
37 | } ServerInfoList[] = { | ||
38 | { PlayerBuildInfo::BuildVoiceLangs, "voices/:version:" }, | ||
39 | { PlayerBuildInfo::BuildVersion, ":build:/:target:" }, | ||
40 | { PlayerBuildInfo::BuildUrl, ":build:/build_url" }, | ||
41 | { PlayerBuildInfo::BuildVoiceUrl, ":build:/voice_url" }, | ||
42 | { PlayerBuildInfo::BuildManualUrl, ":build:/manual_url" }, | ||
43 | { PlayerBuildInfo::BuildSourceUrl, ":build:/source_url" }, | ||
44 | { PlayerBuildInfo::BuildFontUrl, ":build:/font_url" }, | ||
45 | |||
46 | // other URLs -- those are not directly related to the build, but handled here. | ||
47 | { PlayerBuildInfo::DoomUrl, "other/doom_url" }, | ||
48 | { PlayerBuildInfo::Duke3DUrl, "other/duke3d_url" }, | ||
49 | { PlayerBuildInfo::PuzzFontsUrl, "other/puzzfonts_url" }, | ||
50 | { PlayerBuildInfo::QuakeUrl, "other/quake_url" }, | ||
51 | { PlayerBuildInfo::Wolf3DUrl, "other/wolf3d_url" }, | ||
52 | { PlayerBuildInfo::XWorldUrl, "other/xworld_url" }, | ||
53 | { PlayerBuildInfo::MidiPatchsetUrl, "other/patcheset_url" }, | ||
54 | }; | ||
55 | |||
56 | const static struct { | ||
57 | PlayerBuildInfo::DeviceInfo item; | ||
58 | const char* name; | ||
59 | } PlayerInfoList[] = { | ||
60 | { PlayerBuildInfo::BuildStatus, "status/:target:" }, | ||
61 | { PlayerBuildInfo::DisplayName, ":target:/name" }, | ||
62 | { PlayerBuildInfo::BootloaderMethod, ":target:/bootloadermethod" }, | ||
63 | { PlayerBuildInfo::BootloaderName, ":target:/bootloadername" }, | ||
64 | { PlayerBuildInfo::BootloaderFile, ":target:/bootloaderfile" }, | ||
65 | { PlayerBuildInfo::BootloaderFilter, ":target:/bootloaderfilter" }, | ||
66 | { PlayerBuildInfo::Encoder, ":target:/encoder" }, | ||
67 | { PlayerBuildInfo::Brand, ":target:/brand" }, | ||
68 | { PlayerBuildInfo::PlayerPicture, ":target:/playerpic" }, | ||
69 | }; | ||
70 | |||
71 | const static struct { | ||
72 | PlayerBuildInfo::SystemUrl item; | ||
73 | const char* name; | ||
74 | } PlayerSystemUrls[] = { | ||
75 | { PlayerBuildInfo::BootloaderUrl, "bootloader/download_url" }, | ||
76 | { PlayerBuildInfo::BuildInfoUrl, "build_info_url" }, | ||
77 | { PlayerBuildInfo::GenlangUrl, "genlang_url" }, | ||
78 | { PlayerBuildInfo::ThemesUrl, "themes_url" }, | ||
79 | { PlayerBuildInfo::ThemesInfoUrl, "themes_info_url" }, | ||
80 | { PlayerBuildInfo::RbutilUrl, "rbutil_url" }, | ||
81 | }; | ||
82 | |||
83 | PlayerBuildInfo::PlayerBuildInfo() : | ||
84 | serverInfo(nullptr), | ||
85 | playerInfo(":/ini/rbutil.ini", QSettings::IniFormat) | ||
86 | { | ||
87 | |||
88 | } | ||
89 | |||
90 | void PlayerBuildInfo::setBuildInfo(QString file) | ||
91 | { | ||
92 | if (serverInfo) | ||
93 | delete serverInfo; | ||
94 | LOG_INFO() << "updated:" << file; | ||
95 | serverInfo = new QSettings(file, QSettings::IniFormat); | ||
96 | } | ||
97 | |||
98 | QVariant PlayerBuildInfo::value(BuildInfo item, BuildType type) | ||
99 | { | ||
100 | // locate setting item in server info file | ||
101 | int i = 0; | ||
102 | while(ServerInfoList[i].item != item) | ||
103 | i++; | ||
104 | |||
105 | // split of variant for target. | ||
106 | // we can have an optional variant part in the target string. | ||
107 | // For build info we don't use that. | ||
108 | QString target = RbSettings::value(RbSettings::CurrentPlatform).toString().split('.').at(0); | ||
109 | |||
110 | QString s = ServerInfoList[i].name; | ||
111 | s.replace(":target:", target); | ||
112 | QString v; | ||
113 | switch(type) { | ||
114 | case TypeRelease: | ||
115 | v = "release"; | ||
116 | break; | ||
117 | case TypeCandidate: | ||
118 | v = "release-candidate"; | ||
119 | break; | ||
120 | case TypeDaily: | ||
121 | v = "daily"; | ||
122 | break; | ||
123 | case TypeDevel: | ||
124 | v = "development"; | ||
125 | break; | ||
126 | } | ||
127 | |||
128 | QVariant result = QString(); | ||
129 | if (!serverInfo) | ||
130 | return result; | ||
131 | QStringList version = serverInfo->value(v + "/" + target, "").toStringList(); | ||
132 | s.replace(":build:", v); | ||
133 | s.replace(":version:", version.at(0)); | ||
134 | |||
135 | // get value from server build-info | ||
136 | // we need to get a version string, otherwise the data is invalid. | ||
137 | // For invalid data return an empty string. | ||
138 | if(version.at(0).isEmpty()) { | ||
139 | LOG_INFO() << s << "(version invalid)"; | ||
140 | return result; | ||
141 | } | ||
142 | if(!s.isEmpty()) | ||
143 | result = serverInfo->value(s); | ||
144 | |||
145 | // depending on the actual value we need more replacements. | ||
146 | switch(item) { | ||
147 | case BuildVersion: | ||
148 | result = result.toStringList().at(0); | ||
149 | break; | ||
150 | |||
151 | case BuildUrl: | ||
152 | if(version.size() > 1) { | ||
153 | // version info has an URL appended. Takes precendence. | ||
154 | result = version.at(1); | ||
155 | } | ||
156 | break; | ||
157 | |||
158 | case BuildVoiceLangs: | ||
159 | if (type == TypeDaily) | ||
160 | s = "voices/daily"; | ||
161 | result = serverInfo->value(s); | ||
162 | break; | ||
163 | |||
164 | case BuildManualUrl: | ||
165 | { | ||
166 | // special case: if playerInfo has a non-empty manualname entry for the | ||
167 | // target, use that as target for the manual name. | ||
168 | QString manualtarget = playerInfo.value(target + "/manualname", "").toString(); | ||
169 | if(!manualtarget.isEmpty()) | ||
170 | target = manualtarget; | ||
171 | break; | ||
172 | } | ||
173 | |||
174 | default: | ||
175 | break; | ||
176 | } | ||
177 | // if the value is a string we can replace some patterns. | ||
178 | // if we cannot convert it (f.e. for a QStringList) we leave as-is, since | ||
179 | // the conversion would return an empty type. | ||
180 | if (result.canConvert(QMetaType::QString)) | ||
181 | result = result.toString() | ||
182 | .replace("%TARGET%", target) | ||
183 | .replace("%VERSION%", version.at(0)); | ||
184 | |||
185 | LOG_INFO() << "B:" << s << result; | ||
186 | return result; | ||
187 | } | ||
188 | |||
189 | QVariant PlayerBuildInfo::value(DeviceInfo item, QString target) | ||
190 | { | ||
191 | // locate setting item in server info file | ||
192 | int i = 0; | ||
193 | while(PlayerInfoList[i].item != item) | ||
194 | i++; | ||
195 | |||
196 | // split of variant for target. | ||
197 | // we can have an optional variant part in the target string. | ||
198 | // For device info we use this. | ||
199 | if (target.isEmpty()) | ||
200 | target = RbSettings::value(RbSettings::CurrentPlatform).toString(); | ||
201 | |||
202 | QVariant result = QString(); | ||
203 | |||
204 | QString s = PlayerInfoList[i].name; | ||
205 | s.replace(":target:", target); | ||
206 | |||
207 | switch(item) { | ||
208 | case BuildStatus: | ||
209 | { | ||
210 | // build status is the only value that doesn't depend on the version | ||
211 | // but the selected target instead. | ||
212 | bool ok = false; | ||
213 | if (serverInfo) | ||
214 | result = serverInfo->value(s).toInt(&ok); | ||
215 | if (!ok) | ||
216 | result = -1; | ||
217 | break; | ||
218 | } | ||
219 | |||
220 | default: | ||
221 | result = playerInfo.value(s); | ||
222 | break; | ||
223 | } | ||
224 | |||
225 | LOG_INFO() << "T:" << s << result; | ||
226 | return result; | ||
227 | } | ||
228 | |||
229 | QVariant PlayerBuildInfo::value(SystemUrl item) | ||
230 | { | ||
231 | // locate setting item in server info file | ||
232 | int i = 0; | ||
233 | while(PlayerSystemUrls[i].item != item) | ||
234 | i++; | ||
235 | |||
236 | QVariant result = playerInfo.value(PlayerSystemUrls[i].name); | ||
237 | LOG_INFO() << "U:" << PlayerSystemUrls[i].name << result; | ||
238 | return result; | ||
239 | } | ||
240 | |||
241 | |||
242 | QString PlayerBuildInfo::statusAsString(QString platform) | ||
243 | { | ||
244 | QString result; | ||
245 | switch(value(BuildStatus, platform).toInt()) | ||
246 | { | ||
247 | case STATUS_RETIRED: | ||
248 | result = tr("Stable (Retired)"); | ||
249 | break; | ||
250 | case STATUS_UNUSABLE: | ||
251 | result = tr("Unusable"); | ||
252 | break; | ||
253 | case STATUS_UNSTABLE: | ||
254 | result = tr("Unstable"); | ||
255 | break; | ||
256 | case STATUS_STABLE: | ||
257 | result = tr("Stable"); | ||
258 | break; | ||
259 | default: | ||
260 | result = tr("Unknown"); | ||
261 | break; | ||
262 | } | ||
263 | |||
264 | return result; | ||
265 | } | ||