mirror of
https://gitlab.com/pholy/OSCAR-code.git
synced 2025-04-04 02:00:43 +00:00
334 lines
11 KiB
C++
334 lines
11 KiB
C++
/* UpdateParser Implementation (Autoupdater component)
|
|
*
|
|
* Copyright (c) 2019-2024 The OSCAR Team
|
|
* Copyright (c) 2011-2018 Mark Watkins
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU General Public
|
|
* License. See the file COPYING in the main directory of the source code
|
|
* for more details. */
|
|
|
|
#include <QDebug>
|
|
#include <QXmlStreamAttribute>
|
|
|
|
#include "updateparser.h"
|
|
|
|
Update::Update()
|
|
{
|
|
size = 0;
|
|
}
|
|
Update::Update(const Update ©)
|
|
{
|
|
type = copy.type;
|
|
version = copy.version;
|
|
platform = copy.platform;
|
|
date = copy.date;
|
|
filename = copy.filename;
|
|
url = copy.url;
|
|
hash = copy.hash;
|
|
size = copy.size;
|
|
notes = copy.notes;
|
|
unzipped_path = copy.unzipped_path;
|
|
}
|
|
|
|
Update::Update(QString _type, QString _version, QString _platform, QDate _date)
|
|
{
|
|
type = _type;
|
|
version = _version;
|
|
platform = _platform;
|
|
date = _date;
|
|
size = 0;
|
|
}
|
|
|
|
bool UpdateParser::startDocument()
|
|
{
|
|
inRelease = false;
|
|
inUpdate = false;
|
|
inNotes = false;
|
|
inUpdateNotes = false;
|
|
release = nullptr;
|
|
update = nullptr;
|
|
return true;
|
|
}
|
|
|
|
bool UpdateParser::endElement(const QString &namespaceURI, const QString &localName,
|
|
const QString &qName)
|
|
{
|
|
Q_UNUSED(namespaceURI)
|
|
Q_UNUSED(localName)
|
|
QString name = qName.toLower();
|
|
|
|
if (name == "release") {
|
|
inRelease = false;
|
|
release = nullptr;
|
|
} else if (inRelease && name == "update") {
|
|
inUpdate = false;
|
|
update = nullptr;
|
|
} else if (inUpdate && name == "notes") {
|
|
inUpdateNotes = false;
|
|
} else if (inRelease && name == "notes") {
|
|
inNotes = false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
bool UpdateParser::characters(const QString &ch)
|
|
{
|
|
if (inUpdateNotes) {
|
|
update->notes = ch;
|
|
} else if (inNotes) {
|
|
release->notes[platform] = ch;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
UpdateStatus lookupUpdateStatus(QString stat)
|
|
{
|
|
UpdateStatus status = UPDATE_TESTING;
|
|
|
|
if (stat == "testing") { status = UPDATE_TESTING; }
|
|
else if (stat == "beta") { status = UPDATE_BETA; }
|
|
else if (stat == "stable") { status = UPDATE_STABLE; }
|
|
else if (stat == "critical") { status = UPDATE_CRITICAL; }
|
|
|
|
return status;
|
|
}
|
|
bool UpdateParser::startElement(const QString &namespaceURI, const QString &localName,
|
|
const QString &qName, const QXmlAttributes &atts)
|
|
{
|
|
Q_UNUSED(namespaceURI)
|
|
Q_UNUSED(localName)
|
|
QString name = qName.toLower();
|
|
|
|
if (inRelease && name == "update") {
|
|
QString ver, type;
|
|
UpdateStatus updatestatus = UPDATE_TESTING;
|
|
|
|
for (int i = 0; i < atts.count(); i++) {
|
|
if (atts.localName(i) == "type") {
|
|
type = atts.value(i).toLower();
|
|
}
|
|
|
|
if (atts.localName(i) == "version") {
|
|
ver = atts.value(i).toLower();
|
|
}
|
|
|
|
if (atts.localName(i) == "platform") {
|
|
platform = atts.value(i).toLower();
|
|
}
|
|
|
|
if (atts.localName(i) == "release_date") {
|
|
release_date = atts.value(i);
|
|
}
|
|
|
|
if (atts.localName(i) == "status") {
|
|
updatestatus = lookupUpdateStatus(atts.value(i).toLower());
|
|
}
|
|
}
|
|
|
|
QDate date = QDate::fromString(release_date, "yyyy-MM-dd");
|
|
|
|
if (!date.isValid()) { date = QDate::currentDate(); }
|
|
|
|
release->updates[platform].push_back(Update(type, ver, platform, date));
|
|
update = &release->updates[platform][release->updates[platform].size() - 1];
|
|
update->status = updatestatus;
|
|
inUpdate = true;
|
|
} else if (inRelease && name == "info") {
|
|
QString tmp = atts.value("url");
|
|
|
|
if (tmp.isEmpty()) { return false; }
|
|
|
|
release->info_url = tmp;
|
|
} else if (inUpdate && name == "file") {
|
|
for (int i = 0; i < atts.count(); i++) {
|
|
if (atts.localName(i) == "name") {
|
|
update->filename = atts.value(i);
|
|
}
|
|
|
|
if (atts.localName(i) == "size") {
|
|
bool ok;
|
|
update->size = atts.value(i).toLongLong(&ok);
|
|
//if (!ok) return false;
|
|
}
|
|
|
|
if (atts.localName(i) == "url") {
|
|
update->url = atts.value(i);
|
|
}
|
|
|
|
if (atts.localName(i) == "hash") {
|
|
update->hash = atts.value(i).toLower();
|
|
}
|
|
}
|
|
} else if (inUpdate && name == "notes") {
|
|
inUpdateNotes = true;
|
|
} else if (inRelease && name == "notes") {
|
|
platform = "";
|
|
|
|
if (atts.count() >= 1) {
|
|
if (atts.localName(0) == "platform") {
|
|
platform = atts.value(0);
|
|
}
|
|
}
|
|
|
|
inNotes = true;
|
|
} else if (name == "release") {
|
|
inRelease = true;
|
|
QString codename;
|
|
UpdateStatus status = UPDATE_TESTING;
|
|
|
|
for (int i = 0; i < atts.count(); i++) {
|
|
if (atts.localName(i) == "version") {
|
|
version = atts.value(i).toLower();
|
|
}
|
|
|
|
if (atts.localName(i) == "codename") {
|
|
codename = atts.value(i);
|
|
}
|
|
|
|
if (atts.localName(i) == "status") {
|
|
status = lookupUpdateStatus(atts.value(i).toLower());
|
|
}
|
|
}
|
|
|
|
releases[version] = Release(version, codename, status);
|
|
release = &releases[version];
|
|
|
|
if (version > latest_version) { latest_version = version; }
|
|
}
|
|
|
|
return true;
|
|
}
|
|
bool UpdateParser::endDocument()
|
|
{
|
|
/*for (QHash<QString,Release>::iterator r=releases.begin();r!=releases.end();r++) {
|
|
Release & rel=r.value();
|
|
qDebug() << "New Version" << r.key() << rel.codename << rel.notes;
|
|
for (QHash<QString,Update>::iterator u=rel.files.begin();u!=rel.files.end();u++) {
|
|
Update & up=u.value();
|
|
qDebug() << "Platform:" << u.key() << up.filename << up.date;
|
|
}
|
|
}*/
|
|
return true;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// Updates Parser implementation
|
|
/////////////////////////////////////////////////////////////////////
|
|
UpdatesParser::UpdatesParser()
|
|
{
|
|
}
|
|
|
|
QString UpdatesParser::errorString() const
|
|
{
|
|
return QObject::tr("%1\nLine %2, column %3")
|
|
.arg(xml.errorString())
|
|
.arg(xml.lineNumber())
|
|
.arg(xml.columnNumber());
|
|
}
|
|
bool UpdatesParser::read(QIODevice *device)
|
|
{
|
|
xml.setDevice(device);
|
|
|
|
if (xml.readNextStartElement()) {
|
|
if (xml.name() == "Updates") { // && xml.attributes().value("version") == "1.0")
|
|
readUpdates();
|
|
} else {
|
|
xml.raiseError(QObject::tr("Could not parse Updates.xml file."));
|
|
}
|
|
}
|
|
|
|
return !xml.error();
|
|
}
|
|
|
|
void UpdatesParser::readUpdates()
|
|
{
|
|
if (!xml.isStartElement() || (xml.name() != "Updates")) {
|
|
qWarning() << "UpdatesParser::readUpdates() condition check failed";
|
|
}
|
|
// Q_ ASSERT(xml.isStartElement() && xml.name() == "Updates");
|
|
|
|
while (xml.readNextStartElement()) {
|
|
if (xml.name().compare(QLatin1String("PackageUpdate"),Qt::CaseInsensitive)==0) {
|
|
readPackageUpdate();
|
|
} else {
|
|
qDebug() << "Skipping Updates.xml tag" << xml.name();
|
|
xml.skipCurrentElement();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void UpdatesParser::readPackageUpdate()
|
|
{
|
|
if (!xml.isStartElement() || (xml.name().compare(QLatin1String("PackageUpdate"),Qt::CaseInsensitive)!=0)) {
|
|
qWarning() << "UpdatesParser::readPackageUpdate() condition check failed";
|
|
return;
|
|
}
|
|
package = PackageUpdate();
|
|
|
|
while (xml.readNextStartElement()) {
|
|
if (xml.name().compare(QLatin1String("Name"),Qt::CaseInsensitive)==0) {
|
|
package.name = xml.readElementText().toLower();
|
|
} else if (xml.name().compare(QLatin1String("DisplayName"),Qt::CaseInsensitive)==0) {
|
|
package.displayName = xml.readElementText();
|
|
} else if (xml.name().compare(QLatin1String("Description"),Qt::CaseInsensitive)==0) {
|
|
package.description = xml.readElementText();
|
|
} else if (xml.name().compare(QLatin1String("Version"),Qt::CaseInsensitive)==0) {
|
|
package.versionString = xml.readElementText();
|
|
} else if (xml.name().compare(QLatin1String("ReleaseDate"),Qt::CaseInsensitive)==0) {
|
|
package.releaseDate = QDate().fromString(xml.readElementText(), "yyyy-MM-dd");
|
|
} else if (xml.name().compare(QLatin1String("Default"),Qt::CaseInsensitive)==0) {
|
|
package.defaultInstall = xml.readElementText().compare("true") == 0;
|
|
} else if (xml.name().compare(QLatin1String("ForcedInstallation"),Qt::CaseInsensitive)==0) {
|
|
package.forcedInstall = xml.readElementText().compare("true") == 0;
|
|
} else if (xml.name().compare(QLatin1String("Script"),Qt::CaseInsensitive)==0) {
|
|
package.script = xml.readElementText();
|
|
} else if (xml.name().compare(QLatin1String("Dependencies"),Qt::CaseInsensitive)==0) {
|
|
package.dependencies = xml.readElementText().split(",");
|
|
} else if (xml.name().compare(QLatin1String("UpdateFile"),Qt::CaseInsensitive)==0) {
|
|
for (int i=0; i<xml.attributes().size(); ++i) {
|
|
const QXmlStreamAttribute & at = xml.attributes().at(i);
|
|
if (at.name().compare(QLatin1String("CompressedSize"), Qt::CaseInsensitive)==0) {
|
|
package.compressedSize = at.value().toLong();
|
|
} else if (at.name().compare(QLatin1String("UncompressedSize"),Qt::CaseInsensitive)==0) {
|
|
package.uncompressedSize = at.value().toLong();
|
|
} else if (at.name().compare(QLatin1String("OS"),Qt::CaseInsensitive)==0) {
|
|
package.os = at.value().toString();
|
|
}
|
|
}
|
|
xml.skipCurrentElement();
|
|
} else if (xml.name().compare(QLatin1String("DownloadableArchives"))==0) {
|
|
package.downloadArchives = xml.readElementText().split(",");
|
|
} else if (xml.name().compare(QLatin1String("Licenses"),Qt::CaseInsensitive)==0) {
|
|
while (xml.readNextStartElement()) {
|
|
if (xml.name().compare(QLatin1String("License"),Qt::CaseInsensitive)==0) {
|
|
QString name;
|
|
QString file;
|
|
for (int i=0; i<xml.attributes().size(); ++i) {
|
|
const QXmlStreamAttribute & at = xml.attributes().at(i);
|
|
if (at.name().compare(QLatin1String("name"), Qt::CaseInsensitive)==0) {
|
|
name = at.value().toString();
|
|
} else if (at.name().compare(QLatin1String("file"),Qt::CaseInsensitive)==0) {
|
|
file = at.value().toString();
|
|
}
|
|
}
|
|
package.license[name]=file;
|
|
xml.skipCurrentElement();
|
|
} else {
|
|
qDebug() << "Lic Skipping Updates.xml tag" << xml.name();
|
|
|
|
xml.skipCurrentElement();
|
|
}
|
|
}
|
|
} else if (xml.name().compare(QLatin1String("SHA1"),Qt::CaseInsensitive)==0) {
|
|
package.sha1 = xml.readElementText();
|
|
} else {
|
|
qDebug() << "UP Skipping Updates.xml tag" << xml.name();
|
|
|
|
xml.skipCurrentElement();
|
|
}
|
|
};
|
|
packages[package.name] = package;
|
|
}
|