Ref T203, adjustments for distribution class

* distribution is just the channel, no more the concrete file
* masterdir no longer part of distribution
* using QStringList instead of QSet in some place so sort order is kept
* new utility functions
This commit is contained in:
Klaus Basan
2017-12-09 19:38:35 +01:00
parent 340dad19a3
commit de7312a869
4 changed files with 123 additions and 301 deletions

View File

@@ -22,8 +22,8 @@ namespace BlackMisc
CDistribution::CDistribution()
{ }
CDistribution::CDistribution(const QString &channel, bool restricted) :
m_channel(channel.trimmed().toUpper()), m_restricted(restricted)
CDistribution::CDistribution(const QString &channel, int stability, bool restricted) :
m_channel(channel.trimmed().toUpper()), m_stability(stability), m_restricted(restricted)
{ }
void CDistribution::setChannel(const QString &channel)
@@ -31,99 +31,6 @@ namespace BlackMisc
m_channel = channel.trimmed().toUpper();
}
QStringList CDistribution::getPlatforms() const
{
QStringList platforms = m_platformFiles.keys();
platforms.sort();
return platforms;
}
bool CDistribution::supportsPlatform(const QString &platform) const
{
QStringList platforms = m_platformFiles.keys();
return !platform.isEmpty() && platforms.contains(platform);
}
QString CDistribution::guessMyPlatform() const
{
const QStringList platforms(getPlatforms());
if (platforms.isEmpty()) { return ""; }
QStringList reduced;
for (const QString &p : platforms)
{
if (CBuildConfig::isRunningOnWindowsNtPlatform())
{
if (!p.contains("win", Qt::CaseInsensitive)) continue;
}
else if (CBuildConfig::isRunningOnLinuxPlatform())
{
if (!p.contains("linux", Qt::CaseInsensitive)) continue;
}
else if (CBuildConfig::isRunningOnMacOSPlatform())
{
if (!(p.contains("mac", Qt::CaseInsensitive) ||
p.contains("macos", Qt::CaseInsensitive) ||
p.contains("osx", Qt::CaseInsensitive)))
{
continue;
}
}
reduced << p;
}
if (reduced.size() > 1)
{
// further reduce by VATSIM flag
QStringList furtherReduced;
for (const QString &p : as_const(reduced))
{
if (CBuildConfig::isVatsimVersion())
{
if (p.contains("vatsim")) { furtherReduced << p; }
}
else
{
if (!p.contains("vatsim")) { furtherReduced << p; }
}
}
if (!furtherReduced.isEmpty()) { reduced = furtherReduced; }
}
int wordSize = CBuildConfig::buildWordSize();
if (wordSize >= 32 && reduced.size() > 1)
{
// further reduce by word size 32/64
QStringList furtherReduced;
const QString wsString = QString::number(wordSize);
for (const QString &p : as_const(reduced))
{
if (!p.contains(wsString)) { continue; }
furtherReduced << p;
}
if (!furtherReduced.isEmpty()) { reduced = furtherReduced; }
}
if (reduced.isEmpty()) { return ""; }
return reduced.front();
}
QString CDistribution::getVersionString(const QString &platform) const
{
if (platform.isEmpty()) { return ""; }
return m_platformVersions.value(platform);
}
QVersionNumber CDistribution::getQVersion(const QString &platform) const
{
return QVersionNumber::fromString(getVersionString(platform));
}
QString CDistribution::getFilename(const QString &platform) const
{
if (platform.isEmpty()) { return ""; }
return m_platformFiles.value(platform);
}
void CDistribution::addDownloadUrl(const CUrl &url)
{
if (url.isEmpty()) { return; }
@@ -135,6 +42,21 @@ namespace BlackMisc
return !m_downloadUrls.isEmpty();
}
CIcon CDistribution::getRestrictionIcon() const
{
return CIcon::iconByIndex(m_restricted ? CIcons::StandardIconLockClosed16 : CIcons::StandardIconLockOpen16);
}
bool CDistribution::isStabilitySameOrBetter(const CDistribution &otherDistribution) const
{
return m_stability >= otherDistribution.m_stability;
}
bool CDistribution::isStabilityBetter(const CDistribution &otherDistribution) const
{
return m_stability > otherDistribution.m_stability;
}
QString CDistribution::convertToQString(bool i18n) const
{
return convertToQString(", ", i18n);
@@ -148,13 +70,15 @@ namespace BlackMisc
QLatin1String("download URLs: ") %
getDownloadUrls().toQString(i18n) %
separator %
QLatin1String("platforms: ") %
getPlatforms().join(", ") %
separator %
QLatin1String("timestamp: ") %
this->getFormattedUtcTimestampYmdhms();
}
CIcon CDistribution::toIcon() const
{
return this->getRestrictionIcon();
}
CVariant CDistribution::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
{
if (index.isMyself()) { return CVariant::from(*this); }
@@ -164,10 +88,9 @@ namespace BlackMisc
switch (i)
{
case IndexChannel: return CVariant::fromValue(m_channel);
case IndexStability : return CVariant::fromValue(m_stability);
case IndexDownloadUrls: return CVariant::fromValue(m_downloadUrls);
case IndexRestricted: return CVariant::fromValue(m_restricted);
case IndexPlatforms: return CVariant::fromValue(this->getPlatforms());
case IndexPlatformFiles: return CVariant::fromValue(m_platformFiles);
default: return CValueObject::propertyByIndex(index);
}
}
@@ -185,9 +108,9 @@ namespace BlackMisc
switch (i)
{
case IndexChannel: this->setChannel(variant.value<QString>()); break;
case IndexStability: m_stability = variant.toInt(); break;
case IndexDownloadUrls: m_downloadUrls = variant.value<CUrlList>(); break;
case IndexRestricted: m_restricted = variant.toBool(); break;
case IndexPlatformFiles: m_platformFiles = variant.value<CPlatformDictionary>(); break;
default: CValueObject::setPropertyByIndex(index, variant); break;
}
}
@@ -197,8 +120,10 @@ namespace BlackMisc
Q_UNUSED(prefix); // not nested
const QString channel(json.value("channel").toString());
const bool restricted(json.value("restricted").toBool());
CDistribution distribution(channel, restricted);
const bool restricted = json.value("restricted").toBool();
const int stability = json.value("stability").toInt();
CDistribution distribution(channel, stability, restricted);
distribution.setKeyAndTimestampFromDatabaseJson(json);
// add the URLs
for (int i = 0; i < 5; i++)
@@ -208,84 +133,7 @@ namespace BlackMisc
if (url.isEmpty()) { continue; }
distribution.addDownloadUrl(CUrl(url));
}
const QJsonObject platforms = json.value("platforms").toObject();
const QStringList platformsKeys = platforms.keys();
if (platformsKeys.isEmpty()) { return CDistribution(); } // no platforms, then the whole distribution is useless
for (const QString platformKey : as_const(platformsKeys))
{
QStringList platformFileNames;
QJsonArray platformFiles = platforms.value(platformKey).toArray();
for (const QJsonValue &platformFile : platformFiles)
{
const QString filename = platformFile.toString();
if (filename.isEmpty()) { continue; }
platformFileNames << filename;
}
const QPair<QString, QVersionNumber> latestFileInfo = findLatestVersion(platformFileNames);
if (!latestFileInfo.first.isEmpty())
{
distribution.m_platformFiles.insert(platformKey, latestFileInfo.first);
distribution.m_platformVersions.insert(platformKey, latestFileInfo.second.toString());
}
}
distribution.setKeyAndTimestampFromDatabaseJson(json);
return distribution;
}
QVersionNumber CDistribution::versionNumberFromFilename(const QString &filename)
{
if (filename.isEmpty()) { return QVersionNumber(); }
// swift-installer-linux-64-0.7.3_2017-03-25_11-24-50.run
thread_local const QRegularExpression firstSegments("\\d+\\.\\d+\\.\\d+");
QRegularExpressionMatch firstSegmentsMatch = firstSegments.match(filename);
if (!firstSegmentsMatch.hasMatch())
{
return QVersionNumber(); // no version, invalid
}
QString v = firstSegmentsMatch.captured(0); // first 3 segments, like 0.9.3
if (!v.endsWith('.')) { v += '.'; }
thread_local const QRegularExpression ts1("\\d{4}.?\\d{2}.?\\d{2}.?\\d{2}.?\\d{2}.?\\d{2}");
QRegularExpressionMatch ts1Match = ts1.match(filename);
if (!ts1Match.hasMatch())
{
// version without timestamp
v += "0";
return QVersionNumber::fromString(v);
}
const QString lastSegment = BlackMisc::digitOnlyString(ts1Match.captured(0));
v += lastSegment;
return QVersionNumber::fromString(v);
}
QPair<QString, QVersionNumber> CDistribution::findLatestVersion(const QStringList &filenames)
{
if (filenames.isEmpty()) return QPair<QString, QVersionNumber>();
if (filenames.size() == 1) return QPair<QString, QVersionNumber>(filenames.first(), versionNumberFromFilename(filenames.first()));
QString latest;
QVersionNumber latestVersion;
for (const QString &fn : filenames)
{
if (latest.isEmpty())
{
latest = fn;
latestVersion = versionNumberFromFilename(fn);
continue;
}
const QVersionNumber version = versionNumberFromFilename(fn);
if (version > latestVersion)
{
latest = fn;
latestVersion = versionNumberFromFilename(fn);
}
}
return QPair<QString, QVersionNumber>(latest, latestVersion);
}
} // ns
} // ns