NOISSUE simplify.
This commit is contained in:
		@@ -420,8 +420,6 @@ set(META_SOURCES
 | 
			
		||||
	meta/tasks/RemoteLoadTask.h
 | 
			
		||||
	meta/tasks/LocalLoadTask.cpp
 | 
			
		||||
	meta/tasks/LocalLoadTask.h
 | 
			
		||||
	meta/format/FormatV1.cpp
 | 
			
		||||
	meta/format/FormatV1.h
 | 
			
		||||
	meta/format/Format.cpp
 | 
			
		||||
	meta/format/Format.h
 | 
			
		||||
	meta/BaseEntity.cpp
 | 
			
		||||
 
 | 
			
		||||
@@ -124,7 +124,7 @@ void Env::initHttpMetaCache()
 | 
			
		||||
	m_metacache->addBase("root", QDir::currentPath());
 | 
			
		||||
	m_metacache->addBase("translations", QDir("translations").absolutePath());
 | 
			
		||||
	m_metacache->addBase("icons", QDir("cache/icons").absolutePath());
 | 
			
		||||
	m_metacache->addBase("meta", QDir("cache/meta").absolutePath());
 | 
			
		||||
	m_metacache->addBase("meta", QDir("meta").absolutePath());
 | 
			
		||||
	m_metacache->Load();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -24,19 +24,18 @@ BaseEntity::~BaseEntity()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BaseEntity::store() const
 | 
			
		||||
QUrl BaseEntity::url() const
 | 
			
		||||
{
 | 
			
		||||
	Json::write(serialized(), Meta::localDir().absoluteFilePath(localFilename()));
 | 
			
		||||
	return rootUrl().resolved(localFilename());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BaseEntity::notifyLocalLoadComplete()
 | 
			
		||||
{
 | 
			
		||||
	m_localLoaded = true;
 | 
			
		||||
	store();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BaseEntity::notifyRemoteLoadComplete()
 | 
			
		||||
{
 | 
			
		||||
	m_remoteLoaded = true;
 | 
			
		||||
	store();
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <QJsonObject>
 | 
			
		||||
 | 
			
		||||
#include "multimc_logic_export.h"
 | 
			
		||||
 | 
			
		||||
@@ -33,10 +34,10 @@ public:
 | 
			
		||||
	virtual std::unique_ptr<Task> remoteUpdateTask() = 0;
 | 
			
		||||
	virtual std::unique_ptr<Task> localUpdateTask() = 0;
 | 
			
		||||
	virtual void merge(const std::shared_ptr<BaseEntity> &other) = 0;
 | 
			
		||||
	virtual void parse(const QJsonObject &obj) = 0;
 | 
			
		||||
 | 
			
		||||
	void store() const;
 | 
			
		||||
	virtual QString localFilename() const = 0;
 | 
			
		||||
	virtual QJsonObject serialized() const = 0;
 | 
			
		||||
	virtual QUrl url() const;
 | 
			
		||||
 | 
			
		||||
	bool isComplete() const { return m_localLoaded || m_remoteLoaded; }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -80,29 +80,36 @@ QVariant Index::headerData(int section, Qt::Orientation orientation, int role) c
 | 
			
		||||
 | 
			
		||||
std::unique_ptr<Task> Index::remoteUpdateTask()
 | 
			
		||||
{
 | 
			
		||||
	return std::unique_ptr<IndexRemoteLoadTask>(new IndexRemoteLoadTask(this, this));
 | 
			
		||||
	return std::unique_ptr<RemoteLoadTask>(new RemoteLoadTask(this));
 | 
			
		||||
}
 | 
			
		||||
std::unique_ptr<Task> Index::localUpdateTask()
 | 
			
		||||
{
 | 
			
		||||
	return std::unique_ptr<IndexLocalLoadTask>(new IndexLocalLoadTask(this, this));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QJsonObject Index::serialized() const
 | 
			
		||||
{
 | 
			
		||||
	return Format::serializeIndex(this);
 | 
			
		||||
	return std::unique_ptr<LocalLoadTask>(new LocalLoadTask(this));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Index::hasUid(const QString &uid) const
 | 
			
		||||
{
 | 
			
		||||
	return m_uids.contains(uid);
 | 
			
		||||
}
 | 
			
		||||
VersionListPtr Index::getList(const QString &uid) const
 | 
			
		||||
 | 
			
		||||
VersionListPtr Index::get(const QString &uid)
 | 
			
		||||
{
 | 
			
		||||
	return m_uids.value(uid, nullptr);
 | 
			
		||||
}
 | 
			
		||||
VersionListPtr Index::getListGuaranteed(const QString &uid) const
 | 
			
		||||
 | 
			
		||||
VersionPtr Index::get(const QString &uid, const QString &version)
 | 
			
		||||
{
 | 
			
		||||
	return m_uids.value(uid, std::make_shared<VersionList>(uid));
 | 
			
		||||
	auto list = get(uid);
 | 
			
		||||
	if(list)
 | 
			
		||||
	{
 | 
			
		||||
		return list->getVersion(version);
 | 
			
		||||
	}
 | 
			
		||||
	return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Index::parse(const QJsonObject& obj)
 | 
			
		||||
{
 | 
			
		||||
	parseIndex(obj, this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Index::merge(const Ptr &other)
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@ class Task;
 | 
			
		||||
namespace Meta
 | 
			
		||||
{
 | 
			
		||||
using VersionListPtr = std::shared_ptr<class VersionList>;
 | 
			
		||||
using VersionPtr = std::shared_ptr<class Version>;
 | 
			
		||||
 | 
			
		||||
class MULTIMC_LOGIC_EXPORT Index : public QAbstractListModel, public BaseEntity
 | 
			
		||||
{
 | 
			
		||||
@@ -51,17 +52,21 @@ public:
 | 
			
		||||
	std::unique_ptr<Task> localUpdateTask() override;
 | 
			
		||||
 | 
			
		||||
	QString localFilename() const override { return "index.json"; }
 | 
			
		||||
	QJsonObject serialized() const override;
 | 
			
		||||
 | 
			
		||||
	// queries
 | 
			
		||||
	VersionListPtr get(const QString &uid);
 | 
			
		||||
	VersionPtr get(const QString &uid, const QString &version);
 | 
			
		||||
	bool hasUid(const QString &uid) const;
 | 
			
		||||
	/*
 | 
			
		||||
	VersionListPtr getList(const QString &uid) const;
 | 
			
		||||
	VersionListPtr getListGuaranteed(const QString &uid) const;
 | 
			
		||||
	*/
 | 
			
		||||
 | 
			
		||||
	QVector<VersionListPtr> lists() const { return m_lists; }
 | 
			
		||||
 | 
			
		||||
public: // for usage by parsers only
 | 
			
		||||
	void merge(const BaseEntity::Ptr &other) override;
 | 
			
		||||
	void parse(const QJsonObject &obj) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	QVector<VersionListPtr> m_lists;
 | 
			
		||||
 
 | 
			
		||||
@@ -27,9 +27,9 @@ slots:
 | 
			
		||||
		Meta::Index windex({std::make_shared<Meta::VersionList>("list1"), std::make_shared<Meta::VersionList>("list2"), std::make_shared<Meta::VersionList>("list3")});
 | 
			
		||||
		QVERIFY(windex.hasUid("list1"));
 | 
			
		||||
		QVERIFY(!windex.hasUid("asdf"));
 | 
			
		||||
		QVERIFY(windex.getList("list2") != nullptr);
 | 
			
		||||
		QCOMPARE(windex.getList("list2")->uid(), QString("list2"));
 | 
			
		||||
		QVERIFY(windex.getList("adsf") == nullptr);
 | 
			
		||||
		QVERIFY(windex.get("list2") != nullptr);
 | 
			
		||||
		QCOMPARE(windex.get("list2")->uid(), QString("list2"));
 | 
			
		||||
		QVERIFY(windex.get("adsf") == nullptr);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void test_merge()
 | 
			
		||||
 
 | 
			
		||||
@@ -24,8 +24,5 @@ class QDir;
 | 
			
		||||
namespace Meta
 | 
			
		||||
{
 | 
			
		||||
MULTIMC_LOGIC_EXPORT QUrl rootUrl();
 | 
			
		||||
MULTIMC_LOGIC_EXPORT QUrl indexUrl();
 | 
			
		||||
MULTIMC_LOGIC_EXPORT QUrl versionListUrl(const QString &uid);
 | 
			
		||||
MULTIMC_LOGIC_EXPORT QUrl versionUrl(const QString &uid, const QString &version);
 | 
			
		||||
MULTIMC_LOGIC_EXPORT QDir localDir();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -48,11 +48,16 @@ QDateTime Version::time() const
 | 
			
		||||
 | 
			
		||||
std::unique_ptr<Task> Version::remoteUpdateTask()
 | 
			
		||||
{
 | 
			
		||||
	return std::unique_ptr<VersionRemoteLoadTask>(new VersionRemoteLoadTask(this, this));
 | 
			
		||||
	return std::unique_ptr<RemoteLoadTask>(new RemoteLoadTask(this));
 | 
			
		||||
}
 | 
			
		||||
std::unique_ptr<Task> Version::localUpdateTask()
 | 
			
		||||
{
 | 
			
		||||
	return std::unique_ptr<VersionLocalLoadTask>(new VersionLocalLoadTask(this, this));
 | 
			
		||||
	return std::unique_ptr<LocalLoadTask>(new LocalLoadTask(this));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Version::parse(const QJsonObject& obj)
 | 
			
		||||
{
 | 
			
		||||
	parseVersion(obj, this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Version::merge(const std::shared_ptr<BaseEntity> &other)
 | 
			
		||||
@@ -78,10 +83,6 @@ QString Version::localFilename() const
 | 
			
		||||
{
 | 
			
		||||
	return m_uid + '/' + m_version + ".json";
 | 
			
		||||
}
 | 
			
		||||
QJsonObject Version::serialized() const
 | 
			
		||||
{
 | 
			
		||||
	return Format::serializeVersion(this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Version::setType(const QString &type)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -59,9 +59,9 @@ public:
 | 
			
		||||
	std::unique_ptr<Task> remoteUpdateTask() override;
 | 
			
		||||
	std::unique_ptr<Task> localUpdateTask() override;
 | 
			
		||||
	void merge(const std::shared_ptr<BaseEntity> &other) override;
 | 
			
		||||
	void parse(const QJsonObject &obj) override;
 | 
			
		||||
 | 
			
		||||
	QString localFilename() const override;
 | 
			
		||||
	QJsonObject serialized() const override;
 | 
			
		||||
 | 
			
		||||
public: // for usage by format parsers only
 | 
			
		||||
	void setType(const QString &type);
 | 
			
		||||
 
 | 
			
		||||
@@ -169,21 +169,17 @@ QHash<int, QByteArray> VersionList::roleNames() const
 | 
			
		||||
 | 
			
		||||
std::unique_ptr<Task> VersionList::remoteUpdateTask()
 | 
			
		||||
{
 | 
			
		||||
	return std::unique_ptr<VersionListRemoteLoadTask>(new VersionListRemoteLoadTask(this, this));
 | 
			
		||||
	return std::unique_ptr<RemoteLoadTask>(new RemoteLoadTask(this));
 | 
			
		||||
}
 | 
			
		||||
std::unique_ptr<Task> VersionList::localUpdateTask()
 | 
			
		||||
{
 | 
			
		||||
	return std::unique_ptr<VersionListLocalLoadTask>(new VersionListLocalLoadTask(this, this));
 | 
			
		||||
	return std::unique_ptr<LocalLoadTask>(new LocalLoadTask(this));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString VersionList::localFilename() const
 | 
			
		||||
{
 | 
			
		||||
	return m_uid + "/index.json";
 | 
			
		||||
}
 | 
			
		||||
QJsonObject VersionList::serialized() const
 | 
			
		||||
{
 | 
			
		||||
	return Format::serializeVersionList(this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString VersionList::humanReadable() const
 | 
			
		||||
{
 | 
			
		||||
@@ -224,6 +220,11 @@ void VersionList::setVersions(const QVector<VersionPtr> &versions)
 | 
			
		||||
	endResetModel();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void VersionList::parse(const QJsonObject& obj)
 | 
			
		||||
{
 | 
			
		||||
	parseVersionList(obj, this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void VersionList::merge(const BaseEntity::Ptr &other)
 | 
			
		||||
{
 | 
			
		||||
	const VersionListPtr list = std::dynamic_pointer_cast<VersionList>(other);
 | 
			
		||||
@@ -285,4 +286,5 @@ BaseVersionPtr VersionList::getRecommended() const
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "VersionList.moc"
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@
 | 
			
		||||
 | 
			
		||||
#include "BaseVersionList.h"
 | 
			
		||||
#include "BaseEntity.h"
 | 
			
		||||
#include <QJsonObject>
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
namespace Meta
 | 
			
		||||
@@ -57,7 +58,6 @@ public:
 | 
			
		||||
	std::unique_ptr<Task> localUpdateTask() override;
 | 
			
		||||
 | 
			
		||||
	QString localFilename() const override;
 | 
			
		||||
	QJsonObject serialized() const override;
 | 
			
		||||
 | 
			
		||||
	QString uid() const { return m_uid; }
 | 
			
		||||
	QString name() const { return m_name; }
 | 
			
		||||
@@ -72,6 +72,7 @@ public: // for usage only by parsers
 | 
			
		||||
	void setName(const QString &name);
 | 
			
		||||
	void setVersions(const QVector<VersionPtr> &versions);
 | 
			
		||||
	void merge(const BaseEntity::Ptr &other) override;
 | 
			
		||||
	void parse(const QJsonObject &obj) override;
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
	void nameChanged(const QString &name);
 | 
			
		||||
 
 | 
			
		||||
@@ -15,15 +15,85 @@
 | 
			
		||||
 | 
			
		||||
#include "Format.h"
 | 
			
		||||
 | 
			
		||||
#include "FormatV1.h"
 | 
			
		||||
#include "minecraft/onesix/OneSixVersionFormat.h""
 | 
			
		||||
 | 
			
		||||
#include "meta/Index.h"
 | 
			
		||||
#include "meta/Version.h"
 | 
			
		||||
#include "meta/VersionList.h"
 | 
			
		||||
 | 
			
		||||
#include "Json.h"
 | 
			
		||||
using namespace Json;
 | 
			
		||||
 | 
			
		||||
namespace Meta
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
static const int currentFormatVersion = 0;
 | 
			
		||||
 | 
			
		||||
// Index
 | 
			
		||||
static BaseEntity::Ptr parseIndexInternal(const QJsonObject &obj)
 | 
			
		||||
{
 | 
			
		||||
	const QVector<QJsonObject> objects = requireIsArrayOf<QJsonObject>(obj, "packages");
 | 
			
		||||
	QVector<VersionListPtr> lists;
 | 
			
		||||
	lists.reserve(objects.size());
 | 
			
		||||
	std::transform(objects.begin(), objects.end(), std::back_inserter(lists), [](const QJsonObject &obj)
 | 
			
		||||
	{
 | 
			
		||||
		VersionListPtr list = std::make_shared<VersionList>(requireString(obj, "uid"));
 | 
			
		||||
		list->setName(ensureString(obj, "name", QString()));
 | 
			
		||||
		return list;
 | 
			
		||||
	});
 | 
			
		||||
	return std::make_shared<Index>(lists);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Version
 | 
			
		||||
static VersionPtr parseCommonVersion(const QString &uid, const QJsonObject &obj)
 | 
			
		||||
{
 | 
			
		||||
	const QVector<QJsonObject> requiresRaw = obj.contains("requires") ? requireIsArrayOf<QJsonObject>(obj, "requires") : QVector<QJsonObject>();
 | 
			
		||||
	QVector<Reference> requires;
 | 
			
		||||
	requires.reserve(requiresRaw.size());
 | 
			
		||||
	std::transform(requiresRaw.begin(), requiresRaw.end(), std::back_inserter(requires), [](const QJsonObject &rObj)
 | 
			
		||||
	{
 | 
			
		||||
		Reference ref(requireString(rObj, "uid"));
 | 
			
		||||
		ref.setVersion(ensureString(rObj, "version", QString()));
 | 
			
		||||
		return ref;
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	VersionPtr version = std::make_shared<Version>(uid, requireString(obj, "version"));
 | 
			
		||||
	version->setTime(QDateTime::fromString(requireString(obj, "releaseTime"), Qt::ISODate).toMSecsSinceEpoch() / 1000);
 | 
			
		||||
	version->setType(ensureString(obj, "type", QString()));
 | 
			
		||||
	version->setRequires(requires);
 | 
			
		||||
	return version;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static BaseEntity::Ptr parseVersionInternal(const QJsonObject &obj)
 | 
			
		||||
{
 | 
			
		||||
	VersionPtr version = parseCommonVersion(requireString(obj, "uid"), obj);
 | 
			
		||||
 | 
			
		||||
	version->setData(OneSixVersionFormat::versionFileFromJson(QJsonDocument(obj),
 | 
			
		||||
										   QString("%1/%2.json").arg(version->uid(), version->version()),
 | 
			
		||||
										   obj.contains("order")));
 | 
			
		||||
	return version;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Version list / package
 | 
			
		||||
static BaseEntity::Ptr parseVersionListInternal(const QJsonObject &obj)
 | 
			
		||||
{
 | 
			
		||||
	const QString uid = requireString(obj, "uid");
 | 
			
		||||
 | 
			
		||||
	const QVector<QJsonObject> versionsRaw = requireIsArrayOf<QJsonObject>(obj, "versions");
 | 
			
		||||
	QVector<VersionPtr> versions;
 | 
			
		||||
	versions.reserve(versionsRaw.size());
 | 
			
		||||
	std::transform(versionsRaw.begin(), versionsRaw.end(), std::back_inserter(versions), [uid](const QJsonObject &vObj)
 | 
			
		||||
	{
 | 
			
		||||
		return parseCommonVersion(uid, vObj);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	VersionListPtr list = std::make_shared<VersionList>(uid);
 | 
			
		||||
	list->setName(ensureString(obj, "name", QString()));
 | 
			
		||||
	list->setVersions(versions);
 | 
			
		||||
	return list;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int formatVersion(const QJsonObject &obj)
 | 
			
		||||
{
 | 
			
		||||
	if (!obj.contains("formatVersion")) {
 | 
			
		||||
@@ -35,56 +105,39 @@ static int formatVersion(const QJsonObject &obj)
 | 
			
		||||
	return obj.value("formatVersion").toInt();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Format::parseIndex(const QJsonObject &obj, Index *ptr)
 | 
			
		||||
void parseIndex(const QJsonObject &obj, Index *ptr)
 | 
			
		||||
{
 | 
			
		||||
	const int version = formatVersion(obj);
 | 
			
		||||
	switch (version) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		ptr->merge(FormatV1().parseIndexInternal(obj));
 | 
			
		||||
		ptr->merge(parseIndexInternal(obj));
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		throw ParseException(QObject::tr("Unknown formatVersion: %1").arg(version));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Format::parseVersionList(const QJsonObject &obj, VersionList *ptr)
 | 
			
		||||
void parseVersionList(const QJsonObject &obj, VersionList *ptr)
 | 
			
		||||
{
 | 
			
		||||
	const int version = formatVersion(obj);
 | 
			
		||||
	switch (version) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		ptr->merge(FormatV1().parseVersionListInternal(obj));
 | 
			
		||||
		ptr->merge(parseVersionListInternal(obj));
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		throw ParseException(QObject::tr("Unknown formatVersion: %1").arg(version));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Format::parseVersion(const QJsonObject &obj, Version *ptr)
 | 
			
		||||
void parseVersion(const QJsonObject &obj, Version *ptr)
 | 
			
		||||
{
 | 
			
		||||
	const int version = formatVersion(obj);
 | 
			
		||||
	switch (version) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		ptr->merge(FormatV1().parseVersionInternal(obj));
 | 
			
		||||
		ptr->merge(parseVersionInternal(obj));
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		throw ParseException(QObject::tr("Unknown formatVersion: %1").arg(version));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
QJsonObject Format::serializeIndex(const Index *ptr)
 | 
			
		||||
{
 | 
			
		||||
	return FormatV1().serializeIndexInternal(ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QJsonObject Format::serializeVersionList(const VersionList *ptr)
 | 
			
		||||
{
 | 
			
		||||
	return FormatV1().serializeVersionListInternal(ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QJsonObject Format::serializeVersion(const Version *ptr)
 | 
			
		||||
{
 | 
			
		||||
	return FormatV1().serializeVersionInternal(ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -33,25 +33,8 @@ public:
 | 
			
		||||
	using Exception::Exception;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class Format
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	virtual ~Format() {}
 | 
			
		||||
void parseIndex(const QJsonObject &obj, Index *ptr);
 | 
			
		||||
void parseVersion(const QJsonObject &obj, Version *ptr);
 | 
			
		||||
void parseVersionList(const QJsonObject &obj, VersionList *ptr);
 | 
			
		||||
 | 
			
		||||
	static void parseIndex(const QJsonObject &obj, Index *ptr);
 | 
			
		||||
	static void parseVersion(const QJsonObject &obj, Version *ptr);
 | 
			
		||||
	static void parseVersionList(const QJsonObject &obj, VersionList *ptr);
 | 
			
		||||
 | 
			
		||||
	static QJsonObject serializeIndex(const Index *ptr);
 | 
			
		||||
	static QJsonObject serializeVersion(const Version *ptr);
 | 
			
		||||
	static QJsonObject serializeVersionList(const VersionList *ptr);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
	virtual BaseEntity::Ptr parseIndexInternal(const QJsonObject &obj) const = 0;
 | 
			
		||||
	virtual BaseEntity::Ptr parseVersionInternal(const QJsonObject &obj) const = 0;
 | 
			
		||||
	virtual BaseEntity::Ptr parseVersionListInternal(const QJsonObject &obj) const = 0;
 | 
			
		||||
	virtual QJsonObject serializeIndexInternal(const Index *ptr) const = 0;
 | 
			
		||||
	virtual QJsonObject serializeVersionInternal(const Version *ptr) const = 0;
 | 
			
		||||
	virtual QJsonObject serializeVersionListInternal(const VersionList *ptr) const = 0;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,170 +0,0 @@
 | 
			
		||||
/* Copyright 2015-2017 MultiMC Contributors
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "FormatV1.h"
 | 
			
		||||
#include <minecraft/onesix/OneSixVersionFormat.h>
 | 
			
		||||
 | 
			
		||||
#include "Json.h"
 | 
			
		||||
 | 
			
		||||
#include "meta/Index.h"
 | 
			
		||||
#include "meta/Version.h"
 | 
			
		||||
#include "meta/VersionList.h"
 | 
			
		||||
#include "Env.h"
 | 
			
		||||
 | 
			
		||||
using namespace Json;
 | 
			
		||||
 | 
			
		||||
namespace Meta
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
static const int currentFormatVersion = 0;
 | 
			
		||||
 | 
			
		||||
// Index
 | 
			
		||||
 | 
			
		||||
BaseEntity::Ptr FormatV1::parseIndexInternal(const QJsonObject &obj) const
 | 
			
		||||
{
 | 
			
		||||
	const QVector<QJsonObject> objects = requireIsArrayOf<QJsonObject>(obj, "packages");
 | 
			
		||||
	QVector<VersionListPtr> lists;
 | 
			
		||||
	lists.reserve(objects.size());
 | 
			
		||||
	std::transform(objects.begin(), objects.end(), std::back_inserter(lists), [](const QJsonObject &obj)
 | 
			
		||||
	{
 | 
			
		||||
		VersionListPtr list = std::make_shared<VersionList>(requireString(obj, "uid"));
 | 
			
		||||
		list->setName(ensureString(obj, "name", QString()));
 | 
			
		||||
		return list;
 | 
			
		||||
	});
 | 
			
		||||
	return std::make_shared<Index>(lists);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QJsonObject FormatV1::serializeIndexInternal(const Index *ptr) const
 | 
			
		||||
{
 | 
			
		||||
	QJsonArray packages;
 | 
			
		||||
	for (const VersionListPtr &list : ptr->lists())
 | 
			
		||||
	{
 | 
			
		||||
		QJsonObject out;
 | 
			
		||||
		out["uid"] = list->uid();
 | 
			
		||||
		out["name"] = list->name();
 | 
			
		||||
		packages.append(out);
 | 
			
		||||
	}
 | 
			
		||||
	QJsonObject out;
 | 
			
		||||
	out["formatVersion"] = currentFormatVersion;
 | 
			
		||||
	out["packages"] = packages;
 | 
			
		||||
	return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Version
 | 
			
		||||
 | 
			
		||||
static VersionPtr parseCommonVersion(const QString &uid, const QJsonObject &obj)
 | 
			
		||||
{
 | 
			
		||||
	const QVector<QJsonObject> requiresRaw = obj.contains("requires") ? requireIsArrayOf<QJsonObject>(obj, "requires") : QVector<QJsonObject>();
 | 
			
		||||
	QVector<Reference> requires;
 | 
			
		||||
	requires.reserve(requiresRaw.size());
 | 
			
		||||
	std::transform(requiresRaw.begin(), requiresRaw.end(), std::back_inserter(requires), [](const QJsonObject &rObj)
 | 
			
		||||
	{
 | 
			
		||||
		Reference ref(requireString(rObj, "uid"));
 | 
			
		||||
		ref.setVersion(ensureString(rObj, "version", QString()));
 | 
			
		||||
		return ref;
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	VersionPtr version = std::make_shared<Version>(uid, requireString(obj, "version"));
 | 
			
		||||
	version->setTime(QDateTime::fromString(requireString(obj, "releaseTime"), Qt::ISODate).toMSecsSinceEpoch() / 1000);
 | 
			
		||||
	version->setType(ensureString(obj, "type", QString()));
 | 
			
		||||
	version->setRequires(requires);
 | 
			
		||||
	return version;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BaseEntity::Ptr FormatV1::parseVersionInternal(const QJsonObject &obj) const
 | 
			
		||||
{
 | 
			
		||||
	VersionPtr version = parseCommonVersion(requireString(obj, "uid"), obj);
 | 
			
		||||
 | 
			
		||||
	version->setData(OneSixVersionFormat::versionFileFromJson(QJsonDocument(obj),
 | 
			
		||||
										   QString("%1/%2.json").arg(version->uid(), version->version()),
 | 
			
		||||
										   obj.contains("order")));
 | 
			
		||||
	return version;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void serializeCommonVersion(const Version *version, QJsonObject &obj)
 | 
			
		||||
{
 | 
			
		||||
	QJsonArray requires;
 | 
			
		||||
	for (const Reference &ref : version->requires())
 | 
			
		||||
	{
 | 
			
		||||
		if (ref.version().isEmpty())
 | 
			
		||||
		{
 | 
			
		||||
			QJsonObject out;
 | 
			
		||||
			out["uid"] = ref.uid();
 | 
			
		||||
			requires.append(out);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			QJsonObject out;
 | 
			
		||||
			out["uid"] = ref.uid();
 | 
			
		||||
			out["version"] = ref.version();
 | 
			
		||||
			requires.append(out);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	obj.insert("version", version->version());
 | 
			
		||||
	obj.insert("type", version->type());
 | 
			
		||||
	obj.insert("releaseTime", version->time().toString(Qt::ISODate));
 | 
			
		||||
	obj.insert("requires", requires);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QJsonObject FormatV1::serializeVersionInternal(const Version *ptr) const
 | 
			
		||||
{
 | 
			
		||||
	QJsonObject obj = OneSixVersionFormat::versionFileToJson(ptr->data(), true).object();
 | 
			
		||||
	serializeCommonVersion(ptr, obj);
 | 
			
		||||
	obj.insert("formatVersion", currentFormatVersion);
 | 
			
		||||
	obj.insert("uid", ptr->uid());
 | 
			
		||||
	// TODO: the name should be looked up in the UI based on the uid
 | 
			
		||||
	obj.insert("name", ENV.metadataIndex()->getListGuaranteed(ptr->uid())->name());
 | 
			
		||||
 | 
			
		||||
	return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Version list / package
 | 
			
		||||
 | 
			
		||||
BaseEntity::Ptr FormatV1::parseVersionListInternal(const QJsonObject &obj) const
 | 
			
		||||
{
 | 
			
		||||
	const QString uid = requireString(obj, "uid");
 | 
			
		||||
 | 
			
		||||
	const QVector<QJsonObject> versionsRaw = requireIsArrayOf<QJsonObject>(obj, "versions");
 | 
			
		||||
	QVector<VersionPtr> versions;
 | 
			
		||||
	versions.reserve(versionsRaw.size());
 | 
			
		||||
	std::transform(versionsRaw.begin(), versionsRaw.end(), std::back_inserter(versions), [this, uid](const QJsonObject &vObj)
 | 
			
		||||
	{ return parseCommonVersion(uid, vObj); });
 | 
			
		||||
 | 
			
		||||
	VersionListPtr list = std::make_shared<VersionList>(uid);
 | 
			
		||||
	list->setName(ensureString(obj, "name", QString()));
 | 
			
		||||
	list->setVersions(versions);
 | 
			
		||||
	return list;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QJsonObject FormatV1::serializeVersionListInternal(const VersionList *ptr) const
 | 
			
		||||
{
 | 
			
		||||
	QJsonArray versions;
 | 
			
		||||
	for (const VersionPtr &version : ptr->versions())
 | 
			
		||||
	{
 | 
			
		||||
		QJsonObject obj;
 | 
			
		||||
		serializeCommonVersion(version.get(), obj);
 | 
			
		||||
		versions.append(obj);
 | 
			
		||||
	}
 | 
			
		||||
	QJsonObject out;
 | 
			
		||||
	out["formatVersion"] = currentFormatVersion;
 | 
			
		||||
	out["uid"] = ptr->uid();
 | 
			
		||||
	out["name"] = ptr->name().isNull() ? QJsonValue() : ptr->name();
 | 
			
		||||
	out["versions"] = versions;
 | 
			
		||||
	return out;
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,33 +0,0 @@
 | 
			
		||||
/* Copyright 2015-2017 MultiMC Contributors
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "Format.h"
 | 
			
		||||
 | 
			
		||||
namespace Meta
 | 
			
		||||
{
 | 
			
		||||
class FormatV1 : public Format
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	BaseEntity::Ptr parseIndexInternal(const QJsonObject &obj) const override;
 | 
			
		||||
	BaseEntity::Ptr parseVersionInternal(const QJsonObject &obj) const override;
 | 
			
		||||
	BaseEntity::Ptr parseVersionListInternal(const QJsonObject &obj) const override;
 | 
			
		||||
 | 
			
		||||
	QJsonObject serializeIndexInternal(const Index *ptr) const override;
 | 
			
		||||
	QJsonObject serializeVersionInternal(const Version *ptr) const override;
 | 
			
		||||
	QJsonObject serializeVersionListInternal(const VersionList *ptr) const override;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
@@ -34,19 +34,18 @@ LocalLoadTask::LocalLoadTask(BaseEntity *entity, QObject *parent)
 | 
			
		||||
 | 
			
		||||
void LocalLoadTask::executeTask()
 | 
			
		||||
{
 | 
			
		||||
	const QString fname = Meta::localDir().absoluteFilePath(filename());
 | 
			
		||||
	const QString fname = Meta::localDir().absoluteFilePath(m_entity->localFilename());
 | 
			
		||||
	if (!QFile::exists(fname))
 | 
			
		||||
	{
 | 
			
		||||
		emitFailed(tr("File doesn't exist"));
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setStatus(tr("Reading %1...").arg(name()));
 | 
			
		||||
	setStatus(tr("Reading %1...").arg(fname));
 | 
			
		||||
	setProgress(0, 0);
 | 
			
		||||
 | 
			
		||||
	try
 | 
			
		||||
	{
 | 
			
		||||
		parse(Json::requireObject(Json::requireDocument(fname, name()), name()));
 | 
			
		||||
		m_entity->parse(Json::requireObject(Json::requireDocument(fname, fname), fname));
 | 
			
		||||
		m_entity->notifyLocalLoadComplete();
 | 
			
		||||
		emitSucceeded();
 | 
			
		||||
	}
 | 
			
		||||
@@ -55,69 +54,4 @@ void LocalLoadTask::executeTask()
 | 
			
		||||
		emitFailed(tr("Unable to parse file %1: %2").arg(fname, e.cause()));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// INDEX
 | 
			
		||||
IndexLocalLoadTask::IndexLocalLoadTask(Index *index, QObject *parent)
 | 
			
		||||
	: LocalLoadTask(index, parent)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
QString IndexLocalLoadTask::filename() const
 | 
			
		||||
{
 | 
			
		||||
	return "index.json";
 | 
			
		||||
}
 | 
			
		||||
QString IndexLocalLoadTask::name() const
 | 
			
		||||
{
 | 
			
		||||
	return tr("Metadata Index");
 | 
			
		||||
}
 | 
			
		||||
void IndexLocalLoadTask::parse(const QJsonObject &obj) const
 | 
			
		||||
{
 | 
			
		||||
	Format::parseIndex(obj, dynamic_cast<Index *>(entity()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// VERSION LIST
 | 
			
		||||
VersionListLocalLoadTask::VersionListLocalLoadTask(VersionList *list, QObject *parent)
 | 
			
		||||
	: LocalLoadTask(list, parent)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
QString VersionListLocalLoadTask::filename() const
 | 
			
		||||
{
 | 
			
		||||
	return list()->uid() + ".json";
 | 
			
		||||
}
 | 
			
		||||
QString VersionListLocalLoadTask::name() const
 | 
			
		||||
{
 | 
			
		||||
	return tr("Version List for %1").arg(list()->humanReadable());
 | 
			
		||||
}
 | 
			
		||||
void VersionListLocalLoadTask::parse(const QJsonObject &obj) const
 | 
			
		||||
{
 | 
			
		||||
	Format::parseVersionList(obj, list());
 | 
			
		||||
}
 | 
			
		||||
VersionList *VersionListLocalLoadTask::list() const
 | 
			
		||||
{
 | 
			
		||||
	return dynamic_cast<VersionList *>(entity());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// VERSION
 | 
			
		||||
VersionLocalLoadTask::VersionLocalLoadTask(Version *version, QObject *parent)
 | 
			
		||||
	: LocalLoadTask(version, parent)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
QString VersionLocalLoadTask::filename() const
 | 
			
		||||
{
 | 
			
		||||
	return version()->uid() + "/" + version()->version() + ".json";
 | 
			
		||||
}
 | 
			
		||||
QString VersionLocalLoadTask::name() const
 | 
			
		||||
{
 | 
			
		||||
	return tr(" Version for %1").arg(version()->name());
 | 
			
		||||
}
 | 
			
		||||
void VersionLocalLoadTask::parse(const QJsonObject &obj) const
 | 
			
		||||
{
 | 
			
		||||
	Format::parseVersion(obj, version());
 | 
			
		||||
}
 | 
			
		||||
Version *VersionLocalLoadTask::version() const
 | 
			
		||||
{
 | 
			
		||||
	return dynamic_cast<Version *>(entity());
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -25,60 +25,15 @@ class Index;
 | 
			
		||||
class VersionList;
 | 
			
		||||
class Version;
 | 
			
		||||
 | 
			
		||||
// FIXME: this is now just an odd function, get rid of it
 | 
			
		||||
class LocalLoadTask : public Task
 | 
			
		||||
{
 | 
			
		||||
	Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
	explicit LocalLoadTask(BaseEntity *entity, QObject *parent = nullptr);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
	virtual QString filename() const = 0;
 | 
			
		||||
	virtual QString name() const = 0;
 | 
			
		||||
	virtual void parse(const QJsonObject &obj) const = 0;
 | 
			
		||||
 | 
			
		||||
	BaseEntity *entity() const { return m_entity; }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	void executeTask() override;
 | 
			
		||||
 | 
			
		||||
	BaseEntity *m_entity;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class IndexLocalLoadTask : public LocalLoadTask
 | 
			
		||||
{
 | 
			
		||||
	Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
	explicit IndexLocalLoadTask(Index *index, QObject *parent = nullptr);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	QString filename() const override;
 | 
			
		||||
	QString name() const override;
 | 
			
		||||
	void parse(const QJsonObject &obj) const override;
 | 
			
		||||
};
 | 
			
		||||
class VersionListLocalLoadTask : public LocalLoadTask
 | 
			
		||||
{
 | 
			
		||||
	Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
	explicit VersionListLocalLoadTask(VersionList *list, QObject *parent = nullptr);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	QString filename() const override;
 | 
			
		||||
	QString name() const override;
 | 
			
		||||
	void parse(const QJsonObject &obj) const override;
 | 
			
		||||
 | 
			
		||||
	VersionList *list() const;
 | 
			
		||||
};
 | 
			
		||||
class VersionLocalLoadTask : public LocalLoadTask
 | 
			
		||||
{
 | 
			
		||||
	Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
	explicit VersionLocalLoadTask(Version *version, QObject *parent = nullptr);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	QString filename() const override;
 | 
			
		||||
	QString name() const override;
 | 
			
		||||
	void parse(const QJsonObject &obj) const override;
 | 
			
		||||
 | 
			
		||||
	Version *version() const;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -34,99 +34,70 @@ RemoteLoadTask::RemoteLoadTask(BaseEntity *entity, QObject *parent)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class ParsingValidator : public Net::Validator
 | 
			
		||||
{
 | 
			
		||||
public: /* con/des */
 | 
			
		||||
	ParsingValidator(BaseEntity *entity) : m_entity(entity)
 | 
			
		||||
	{
 | 
			
		||||
	};
 | 
			
		||||
	virtual ~ParsingValidator()
 | 
			
		||||
	{
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
public: /* methods */
 | 
			
		||||
	bool init(QNetworkRequest &) override
 | 
			
		||||
	{
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	bool write(QByteArray & data) override
 | 
			
		||||
	{
 | 
			
		||||
		this->data.append(data);
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	bool abort() override
 | 
			
		||||
	{
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	bool validate(QNetworkReply &) override
 | 
			
		||||
	{
 | 
			
		||||
		auto fname = m_entity->localFilename();
 | 
			
		||||
		try
 | 
			
		||||
		{
 | 
			
		||||
			m_entity->parse(Json::requireObject(Json::requireDocument(data, fname), fname));
 | 
			
		||||
			m_entity->notifyRemoteLoadComplete();
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		catch (Exception &e)
 | 
			
		||||
		{
 | 
			
		||||
			qWarning() << "Unable to parse response:" << e.cause();
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
private: /* data */
 | 
			
		||||
	QByteArray data;
 | 
			
		||||
	BaseEntity *m_entity;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void RemoteLoadTask::executeTask()
 | 
			
		||||
{
 | 
			
		||||
	NetJob *job = new NetJob(name());
 | 
			
		||||
	// FIXME: leak here!!!
 | 
			
		||||
	NetJob *job = new NetJob(tr("Download of meta file %1").arg(m_entity->localFilename()));
 | 
			
		||||
 | 
			
		||||
	auto entry = ENV.metacache()->resolveEntry("meta", url().toString());
 | 
			
		||||
	auto url = m_entity->url();
 | 
			
		||||
	auto entry = ENV.metacache()->resolveEntry("meta", m_entity->localFilename());
 | 
			
		||||
	entry->setStale(true);
 | 
			
		||||
	m_dl = Net::Download::makeCached(url(), entry);
 | 
			
		||||
	m_dl = Net::Download::makeCached(url, entry);
 | 
			
		||||
	/*
 | 
			
		||||
	 * The validator parses the file and loads it into the object.
 | 
			
		||||
	 * If that fails, the file is not written to storage.
 | 
			
		||||
	 */
 | 
			
		||||
	m_dl->addValidator(new ParsingValidator(m_entity));
 | 
			
		||||
	job->addNetAction(m_dl);
 | 
			
		||||
	connect(job, &NetJob::failed, this, &RemoteLoadTask::emitFailed);
 | 
			
		||||
	connect(job, &NetJob::succeeded, this, &RemoteLoadTask::networkFinished);
 | 
			
		||||
	connect(job, &NetJob::succeeded, this, &RemoteLoadTask::succeeded);
 | 
			
		||||
	connect(job, &NetJob::status, this, &RemoteLoadTask::setStatus);
 | 
			
		||||
	connect(job, &NetJob::progress, this, &RemoteLoadTask::setProgress);
 | 
			
		||||
	job->start();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RemoteLoadTask::networkFinished()
 | 
			
		||||
{
 | 
			
		||||
	setStatus(tr("Parsing..."));
 | 
			
		||||
	setProgress(0, 0);
 | 
			
		||||
 | 
			
		||||
	try
 | 
			
		||||
	{
 | 
			
		||||
		parse(Json::requireObject(Json::requireDocument(m_dl->getTargetFilepath(), name()), name()));
 | 
			
		||||
		m_entity->notifyRemoteLoadComplete();
 | 
			
		||||
		emitSucceeded();
 | 
			
		||||
	}
 | 
			
		||||
	catch (Exception &e)
 | 
			
		||||
	{
 | 
			
		||||
		emitFailed(tr("Unable to parse response: %1").arg(e.cause()));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// INDEX
 | 
			
		||||
IndexRemoteLoadTask::IndexRemoteLoadTask(Index *index, QObject *parent)
 | 
			
		||||
	: RemoteLoadTask(index, parent)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
QUrl IndexRemoteLoadTask::url() const
 | 
			
		||||
{
 | 
			
		||||
	return Meta::indexUrl();
 | 
			
		||||
}
 | 
			
		||||
QString IndexRemoteLoadTask::name() const
 | 
			
		||||
{
 | 
			
		||||
	return tr("Metadata Index");
 | 
			
		||||
}
 | 
			
		||||
void IndexRemoteLoadTask::parse(const QJsonObject &obj) const
 | 
			
		||||
{
 | 
			
		||||
	Format::parseIndex(obj, dynamic_cast<Index *>(entity()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// VERSION LIST
 | 
			
		||||
VersionListRemoteLoadTask::VersionListRemoteLoadTask(VersionList *list, QObject *parent)
 | 
			
		||||
	: RemoteLoadTask(list, parent)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
QUrl VersionListRemoteLoadTask::url() const
 | 
			
		||||
{
 | 
			
		||||
	return Meta::versionListUrl(list()->uid());
 | 
			
		||||
}
 | 
			
		||||
QString VersionListRemoteLoadTask::name() const
 | 
			
		||||
{
 | 
			
		||||
	return tr("Version List for %1").arg(list()->humanReadable());
 | 
			
		||||
}
 | 
			
		||||
void VersionListRemoteLoadTask::parse(const QJsonObject &obj) const
 | 
			
		||||
{
 | 
			
		||||
	Format::parseVersionList(obj, list());
 | 
			
		||||
}
 | 
			
		||||
VersionList* Meta::VersionListRemoteLoadTask::list() const
 | 
			
		||||
{
 | 
			
		||||
	return dynamic_cast<VersionList *>(entity());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// VERSION
 | 
			
		||||
VersionRemoteLoadTask::VersionRemoteLoadTask(Version *version, QObject *parent)
 | 
			
		||||
	: RemoteLoadTask(version, parent)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
QUrl VersionRemoteLoadTask::url() const
 | 
			
		||||
{
 | 
			
		||||
	return Meta::versionUrl(version()->uid(), version()->version());
 | 
			
		||||
}
 | 
			
		||||
QString VersionRemoteLoadTask::name() const
 | 
			
		||||
{
 | 
			
		||||
	return tr("Meta Version for %1").arg(version()->name());
 | 
			
		||||
}
 | 
			
		||||
void VersionRemoteLoadTask::parse(const QJsonObject &obj) const
 | 
			
		||||
{
 | 
			
		||||
	Format::parseVersion(obj, version());
 | 
			
		||||
}
 | 
			
		||||
Version *VersionRemoteLoadTask::version() const
 | 
			
		||||
{
 | 
			
		||||
	return dynamic_cast<Version *>(entity());
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -30,66 +30,17 @@ class Index;
 | 
			
		||||
class VersionList;
 | 
			
		||||
class Version;
 | 
			
		||||
 | 
			
		||||
// FIXME: this is now just an oddly constructed NetJob, get rid of it.
 | 
			
		||||
class RemoteLoadTask : public Task
 | 
			
		||||
{
 | 
			
		||||
	Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
	explicit RemoteLoadTask(BaseEntity *entity, QObject *parent = nullptr);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
	virtual QUrl url() const = 0;
 | 
			
		||||
	virtual QString name() const = 0;
 | 
			
		||||
	virtual void parse(const QJsonObject &obj) const = 0;
 | 
			
		||||
 | 
			
		||||
	BaseEntity *entity() const { return m_entity; }
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
	void networkFinished();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	void executeTask() override;
 | 
			
		||||
 | 
			
		||||
	BaseEntity *m_entity;
 | 
			
		||||
	std::shared_ptr<Net::Download> m_dl;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class IndexRemoteLoadTask : public RemoteLoadTask
 | 
			
		||||
{
 | 
			
		||||
	Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
	explicit IndexRemoteLoadTask(Index *index, QObject *parent = nullptr);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	QUrl url() const override;
 | 
			
		||||
	QString name() const override;
 | 
			
		||||
	void parse(const QJsonObject &obj) const override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class VersionListRemoteLoadTask : public RemoteLoadTask
 | 
			
		||||
{
 | 
			
		||||
	Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
	explicit VersionListRemoteLoadTask(VersionList *list, QObject *parent = nullptr);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	QUrl url() const override;
 | 
			
		||||
	QString name() const override;
 | 
			
		||||
	void parse(const QJsonObject &obj) const override;
 | 
			
		||||
 | 
			
		||||
	VersionList *list() const;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class VersionRemoteLoadTask : public RemoteLoadTask
 | 
			
		||||
{
 | 
			
		||||
	Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
	explicit VersionRemoteLoadTask(Version *version, QObject *parent = nullptr);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	QUrl url() const override;
 | 
			
		||||
	QString name() const override;
 | 
			
		||||
	void parse(const QJsonObject &obj) const override;
 | 
			
		||||
 | 
			
		||||
	Version *version() const;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,7 @@ static QString formatRequires(const VersionPtr &version)
 | 
			
		||||
	QStringList lines;
 | 
			
		||||
	for (const Reference &ref : version->requires())
 | 
			
		||||
	{
 | 
			
		||||
		const QString readable = ENV.metadataIndex()->hasUid(ref.uid()) ? ENV.metadataIndex()->getList(ref.uid())->humanReadable() : ref.uid();
 | 
			
		||||
		const QString readable = ENV.metadataIndex()->hasUid(ref.uid()) ? ENV.metadataIndex()->get(ref.uid())->humanReadable() : ref.uid();
 | 
			
		||||
		if (ref.version().isEmpty())
 | 
			
		||||
		{
 | 
			
		||||
			lines.append(readable);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user