rockbox/rbutil/rbutilqt/base/playerbuildinfo.cpp

266 lines
8.3 KiB
C++
Raw Normal View History

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2020 by Dominik Riebeling
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "playerbuildinfo.h"
#include "rbsettings.h"
#include "Logger.h"
PlayerBuildInfo* PlayerBuildInfo::infoInstance = nullptr;
PlayerBuildInfo* PlayerBuildInfo::instance()
{
if (infoInstance == nullptr) {
infoInstance = new PlayerBuildInfo();
}
return infoInstance;
}
// server infos
const static struct {
PlayerBuildInfo::BuildInfo item;
const char* name;
} ServerInfoList[] = {
{ PlayerBuildInfo::BuildVoiceLangs, "voices/:version:" },
{ PlayerBuildInfo::BuildVersion, ":build:/:target:" },
{ PlayerBuildInfo::BuildUrl, ":build:/build_url" },
{ PlayerBuildInfo::BuildVoiceUrl, ":build:/voice_url" },
{ PlayerBuildInfo::BuildManualUrl, ":build:/manual_url" },
{ PlayerBuildInfo::BuildSourceUrl, ":build:/source_url" },
{ PlayerBuildInfo::BuildFontUrl, ":build:/font_url" },
// other URLs -- those are not directly related to the build, but handled here.
{ PlayerBuildInfo::DoomUrl, "other/doom_url" },
{ PlayerBuildInfo::Duke3DUrl, "other/duke3d_url" },
{ PlayerBuildInfo::PuzzFontsUrl, "other/puzzfonts_url" },
{ PlayerBuildInfo::QuakeUrl, "other/quake_url" },
{ PlayerBuildInfo::Wolf3DUrl, "other/wolf3d_url" },
{ PlayerBuildInfo::XWorldUrl, "other/xworld_url" },
{ PlayerBuildInfo::MidiPatchsetUrl, "other/patcheset_url" },
};
const static struct {
PlayerBuildInfo::DeviceInfo item;
const char* name;
} PlayerInfoList[] = {
{ PlayerBuildInfo::BuildStatus, "status/:target:" },
{ PlayerBuildInfo::DisplayName, ":target:/name" },
{ PlayerBuildInfo::BootloaderMethod, ":target:/bootloadermethod" },
{ PlayerBuildInfo::BootloaderName, ":target:/bootloadername" },
{ PlayerBuildInfo::BootloaderFile, ":target:/bootloaderfile" },
{ PlayerBuildInfo::BootloaderFilter, ":target:/bootloaderfilter" },
{ PlayerBuildInfo::Encoder, ":target:/encoder" },
{ PlayerBuildInfo::Brand, ":target:/brand" },
{ PlayerBuildInfo::PlayerPicture, ":target:/playerpic" },
};
const static struct {
PlayerBuildInfo::SystemUrl item;
const char* name;
} PlayerSystemUrls[] = {
{ PlayerBuildInfo::BootloaderUrl, "bootloader/download_url" },
{ PlayerBuildInfo::BuildInfoUrl, "build_info_url" },
{ PlayerBuildInfo::GenlangUrl, "genlang_url" },
{ PlayerBuildInfo::ThemesUrl, "themes_url" },
{ PlayerBuildInfo::ThemesInfoUrl, "themes_info_url" },
{ PlayerBuildInfo::RbutilUrl, "rbutil_url" },
};
PlayerBuildInfo::PlayerBuildInfo() :
serverInfo(nullptr),
playerInfo(":/ini/rbutil.ini", QSettings::IniFormat)
{
}
void PlayerBuildInfo::setBuildInfo(QString file)
{
if (serverInfo)
delete serverInfo;
LOG_INFO() << "updated:" << file;
serverInfo = new QSettings(file, QSettings::IniFormat);
}
QVariant PlayerBuildInfo::value(BuildInfo item, BuildType type)
{
// locate setting item in server info file
int i = 0;
while(ServerInfoList[i].item != item)
i++;
// split of variant for target.
// we can have an optional variant part in the target string.
// For build info we don't use that.
QString target = RbSettings::value(RbSettings::CurrentPlatform).toString().split('.').at(0);
QString s = ServerInfoList[i].name;
s.replace(":target:", target);
QString v;
switch(type) {
case TypeRelease:
v = "release";
break;
case TypeCandidate:
v = "release-candidate";
break;
case TypeDaily:
v = "daily";
break;
case TypeDevel:
v = "development";
break;
}
QVariant result = QString();
if (!serverInfo)
return result;
QStringList version = serverInfo->value(v + "/" + target, "").toStringList();
s.replace(":build:", v);
s.replace(":version:", version.at(0));
// get value from server build-info
// we need to get a version string, otherwise the data is invalid.
// For invalid data return an empty string.
if(version.at(0).isEmpty()) {
LOG_INFO() << s << "(version invalid)";
return result;
}
if(!s.isEmpty())
result = serverInfo->value(s);
// depending on the actual value we need more replacements.
switch(item) {
case BuildVersion:
result = result.toStringList().at(0);
break;
case BuildUrl:
if(version.size() > 1) {
// version info has an URL appended. Takes precendence.
result = version.at(1);
}
break;
case BuildVoiceLangs:
if (type == TypeDaily)
s = "voices/daily";
result = serverInfo->value(s);
break;
case BuildManualUrl:
{
// special case: if playerInfo has a non-empty manualname entry for the
// target, use that as target for the manual name.
QString manualtarget = playerInfo.value(target + "/manualname", "").toString();
if(!manualtarget.isEmpty())
target = manualtarget;
break;
}
default:
break;
}
// if the value is a string we can replace some patterns.
// if we cannot convert it (f.e. for a QStringList) we leave as-is, since
// the conversion would return an empty type.
if (result.canConvert(QMetaType::QString))
result = result.toString()
.replace("%TARGET%", target)
.replace("%VERSION%", version.at(0));
LOG_INFO() << "B:" << s << result;
return result;
}
QVariant PlayerBuildInfo::value(DeviceInfo item, QString target)
{
// locate setting item in server info file
int i = 0;
while(PlayerInfoList[i].item != item)
i++;
// split of variant for target.
// we can have an optional variant part in the target string.
// For device info we use this.
if (target.isEmpty())
target = RbSettings::value(RbSettings::CurrentPlatform).toString();
QVariant result = QString();
QString s = PlayerInfoList[i].name;
s.replace(":target:", target);
switch(item) {
case BuildStatus:
{
// build status is the only value that doesn't depend on the version
// but the selected target instead.
bool ok = false;
if (serverInfo)
result = serverInfo->value(s).toInt(&ok);
if (!ok)
result = -1;
break;
}
default:
result = playerInfo.value(s);
break;
}
LOG_INFO() << "T:" << s << result;
return result;
}
QVariant PlayerBuildInfo::value(SystemUrl item)
{
// locate setting item in server info file
int i = 0;
while(PlayerSystemUrls[i].item != item)
i++;
QVariant result = playerInfo.value(PlayerSystemUrls[i].name);
LOG_INFO() << "U:" << PlayerSystemUrls[i].name << result;
return result;
}
QString PlayerBuildInfo::statusAsString(QString platform)
{
QString result;
switch(value(BuildStatus, platform).toInt())
{
case STATUS_RETIRED:
result = tr("Stable (Retired)");
break;
case STATUS_UNUSABLE:
result = tr("Unusable");
break;
case STATUS_UNSTABLE:
result = tr("Unstable");
break;
case STATUS_STABLE:
result = tr("Stable");
break;
default:
result = tr("Unknown");
break;
}
return result;
}