NOISSUE simplify.

This commit is contained in:
Petr Mrázek 2017-03-17 01:48:54 +01:00
parent 40cf38bc32
commit 0060b50625
21 changed files with 193 additions and 538 deletions

View File

@ -420,8 +420,6 @@ set(META_SOURCES
meta/tasks/RemoteLoadTask.h meta/tasks/RemoteLoadTask.h
meta/tasks/LocalLoadTask.cpp meta/tasks/LocalLoadTask.cpp
meta/tasks/LocalLoadTask.h meta/tasks/LocalLoadTask.h
meta/format/FormatV1.cpp
meta/format/FormatV1.h
meta/format/Format.cpp meta/format/Format.cpp
meta/format/Format.h meta/format/Format.h
meta/BaseEntity.cpp meta/BaseEntity.cpp

View File

@ -124,7 +124,7 @@ void Env::initHttpMetaCache()
m_metacache->addBase("root", QDir::currentPath()); m_metacache->addBase("root", QDir::currentPath());
m_metacache->addBase("translations", QDir("translations").absolutePath()); m_metacache->addBase("translations", QDir("translations").absolutePath());
m_metacache->addBase("icons", QDir("cache/icons").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(); m_metacache->Load();
} }

View File

@ -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() void BaseEntity::notifyLocalLoadComplete()
{ {
m_localLoaded = true; m_localLoaded = true;
store();
} }
void BaseEntity::notifyRemoteLoadComplete() void BaseEntity::notifyRemoteLoadComplete()
{ {
m_remoteLoaded = true; m_remoteLoaded = true;
store();
} }
} }

View File

@ -17,6 +17,7 @@
#include <QObject> #include <QObject>
#include <memory> #include <memory>
#include <QJsonObject>
#include "multimc_logic_export.h" #include "multimc_logic_export.h"
@ -33,10 +34,10 @@ public:
virtual std::unique_ptr<Task> remoteUpdateTask() = 0; virtual std::unique_ptr<Task> remoteUpdateTask() = 0;
virtual std::unique_ptr<Task> localUpdateTask() = 0; virtual std::unique_ptr<Task> localUpdateTask() = 0;
virtual void merge(const std::shared_ptr<BaseEntity> &other) = 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 QString localFilename() const = 0;
virtual QJsonObject serialized() const = 0; virtual QUrl url() const;
bool isComplete() const { return m_localLoaded || m_remoteLoaded; } bool isComplete() const { return m_localLoaded || m_remoteLoaded; }

View File

@ -80,29 +80,36 @@ QVariant Index::headerData(int section, Qt::Orientation orientation, int role) c
std::unique_ptr<Task> Index::remoteUpdateTask() 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() std::unique_ptr<Task> Index::localUpdateTask()
{ {
return std::unique_ptr<IndexLocalLoadTask>(new IndexLocalLoadTask(this, this)); return std::unique_ptr<LocalLoadTask>(new LocalLoadTask(this));
}
QJsonObject Index::serialized() const
{
return Format::serializeIndex(this);
} }
bool Index::hasUid(const QString &uid) const bool Index::hasUid(const QString &uid) const
{ {
return m_uids.contains(uid); return m_uids.contains(uid);
} }
VersionListPtr Index::getList(const QString &uid) const
VersionListPtr Index::get(const QString &uid)
{ {
return m_uids.value(uid, nullptr); 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) void Index::merge(const Ptr &other)

View File

@ -27,6 +27,7 @@ class Task;
namespace Meta namespace Meta
{ {
using VersionListPtr = std::shared_ptr<class VersionList>; using VersionListPtr = std::shared_ptr<class VersionList>;
using VersionPtr = std::shared_ptr<class Version>;
class MULTIMC_LOGIC_EXPORT Index : public QAbstractListModel, public BaseEntity class MULTIMC_LOGIC_EXPORT Index : public QAbstractListModel, public BaseEntity
{ {
@ -51,17 +52,21 @@ public:
std::unique_ptr<Task> localUpdateTask() override; std::unique_ptr<Task> localUpdateTask() override;
QString localFilename() const override { return "index.json"; } QString localFilename() const override { return "index.json"; }
QJsonObject serialized() const override;
// queries // queries
VersionListPtr get(const QString &uid);
VersionPtr get(const QString &uid, const QString &version);
bool hasUid(const QString &uid) const; bool hasUid(const QString &uid) const;
/*
VersionListPtr getList(const QString &uid) const; VersionListPtr getList(const QString &uid) const;
VersionListPtr getListGuaranteed(const QString &uid) const; VersionListPtr getListGuaranteed(const QString &uid) const;
*/
QVector<VersionListPtr> lists() const { return m_lists; } QVector<VersionListPtr> lists() const { return m_lists; }
public: // for usage by parsers only public: // for usage by parsers only
void merge(const BaseEntity::Ptr &other) override; void merge(const BaseEntity::Ptr &other) override;
void parse(const QJsonObject &obj) override;
private: private:
QVector<VersionListPtr> m_lists; QVector<VersionListPtr> m_lists;

View File

@ -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")}); 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("list1"));
QVERIFY(!windex.hasUid("asdf")); QVERIFY(!windex.hasUid("asdf"));
QVERIFY(windex.getList("list2") != nullptr); QVERIFY(windex.get("list2") != nullptr);
QCOMPARE(windex.getList("list2")->uid(), QString("list2")); QCOMPARE(windex.get("list2")->uid(), QString("list2"));
QVERIFY(windex.getList("adsf") == nullptr); QVERIFY(windex.get("adsf") == nullptr);
} }
void test_merge() void test_merge()

View File

@ -24,8 +24,5 @@ class QDir;
namespace Meta namespace Meta
{ {
MULTIMC_LOGIC_EXPORT QUrl rootUrl(); 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(); MULTIMC_LOGIC_EXPORT QDir localDir();
} }

View File

@ -48,11 +48,16 @@ QDateTime Version::time() const
std::unique_ptr<Task> Version::remoteUpdateTask() 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() 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) void Version::merge(const std::shared_ptr<BaseEntity> &other)
@ -78,10 +83,6 @@ QString Version::localFilename() const
{ {
return m_uid + '/' + m_version + ".json"; return m_uid + '/' + m_version + ".json";
} }
QJsonObject Version::serialized() const
{
return Format::serializeVersion(this);
}
void Version::setType(const QString &type) void Version::setType(const QString &type)
{ {

View File

@ -59,9 +59,9 @@ public:
std::unique_ptr<Task> remoteUpdateTask() override; std::unique_ptr<Task> remoteUpdateTask() override;
std::unique_ptr<Task> localUpdateTask() override; std::unique_ptr<Task> localUpdateTask() override;
void merge(const std::shared_ptr<BaseEntity> &other) override; void merge(const std::shared_ptr<BaseEntity> &other) override;
void parse(const QJsonObject &obj) override;
QString localFilename() const override; QString localFilename() const override;
QJsonObject serialized() const override;
public: // for usage by format parsers only public: // for usage by format parsers only
void setType(const QString &type); void setType(const QString &type);

View File

@ -169,21 +169,17 @@ QHash<int, QByteArray> VersionList::roleNames() const
std::unique_ptr<Task> VersionList::remoteUpdateTask() 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() 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 QString VersionList::localFilename() const
{ {
return m_uid + "/index.json"; return m_uid + "/index.json";
} }
QJsonObject VersionList::serialized() const
{
return Format::serializeVersionList(this);
}
QString VersionList::humanReadable() const QString VersionList::humanReadable() const
{ {
@ -224,6 +220,11 @@ void VersionList::setVersions(const QVector<VersionPtr> &versions)
endResetModel(); endResetModel();
} }
void VersionList::parse(const QJsonObject& obj)
{
parseVersionList(obj, this);
}
void VersionList::merge(const BaseEntity::Ptr &other) void VersionList::merge(const BaseEntity::Ptr &other)
{ {
const VersionListPtr list = std::dynamic_pointer_cast<VersionList>(other); const VersionListPtr list = std::dynamic_pointer_cast<VersionList>(other);
@ -285,4 +286,5 @@ BaseVersionPtr VersionList::getRecommended() const
} }
#include "VersionList.moc" #include "VersionList.moc"

View File

@ -17,6 +17,7 @@
#include "BaseVersionList.h" #include "BaseVersionList.h"
#include "BaseEntity.h" #include "BaseEntity.h"
#include <QJsonObject>
#include <memory> #include <memory>
namespace Meta namespace Meta
@ -57,7 +58,6 @@ public:
std::unique_ptr<Task> localUpdateTask() override; std::unique_ptr<Task> localUpdateTask() override;
QString localFilename() const override; QString localFilename() const override;
QJsonObject serialized() const override;
QString uid() const { return m_uid; } QString uid() const { return m_uid; }
QString name() const { return m_name; } QString name() const { return m_name; }
@ -72,6 +72,7 @@ public: // for usage only by parsers
void setName(const QString &name); void setName(const QString &name);
void setVersions(const QVector<VersionPtr> &versions); void setVersions(const QVector<VersionPtr> &versions);
void merge(const BaseEntity::Ptr &other) override; void merge(const BaseEntity::Ptr &other) override;
void parse(const QJsonObject &obj) override;
signals: signals:
void nameChanged(const QString &name); void nameChanged(const QString &name);

View File

@ -15,15 +15,85 @@
#include "Format.h" #include "Format.h"
#include "FormatV1.h" #include "minecraft/onesix/OneSixVersionFormat.h""
#include "meta/Index.h" #include "meta/Index.h"
#include "meta/Version.h" #include "meta/Version.h"
#include "meta/VersionList.h" #include "meta/VersionList.h"
#include "Json.h"
using namespace Json;
namespace Meta 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) static int formatVersion(const QJsonObject &obj)
{ {
if (!obj.contains("formatVersion")) { if (!obj.contains("formatVersion")) {
@ -35,56 +105,39 @@ static int formatVersion(const QJsonObject &obj)
return obj.value("formatVersion").toInt(); 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); const int version = formatVersion(obj);
switch (version) { switch (version) {
case 0: case 0:
ptr->merge(FormatV1().parseIndexInternal(obj)); ptr->merge(parseIndexInternal(obj));
break; break;
default: default:
throw ParseException(QObject::tr("Unknown formatVersion: %1").arg(version)); 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); const int version = formatVersion(obj);
switch (version) { switch (version) {
case 0: case 0:
ptr->merge(FormatV1().parseVersionListInternal(obj)); ptr->merge(parseVersionListInternal(obj));
break; break;
default: default:
throw ParseException(QObject::tr("Unknown formatVersion: %1").arg(version)); 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); const int version = formatVersion(obj);
switch (version) { switch (version) {
case 0: case 0:
ptr->merge(FormatV1().parseVersionInternal(obj)); ptr->merge(parseVersionInternal(obj));
break; break;
default: default:
throw ParseException(QObject::tr("Unknown formatVersion: %1").arg(version)); 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);
}
} }

View File

@ -33,25 +33,8 @@ public:
using Exception::Exception; using Exception::Exception;
}; };
class Format void parseIndex(const QJsonObject &obj, Index *ptr);
{ void parseVersion(const QJsonObject &obj, Version *ptr);
public: void parseVersionList(const QJsonObject &obj, VersionList *ptr);
virtual ~Format() {}
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;
};
} }

View File

@ -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;
}
}

View File

@ -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;
};
}

View File

@ -34,19 +34,18 @@ LocalLoadTask::LocalLoadTask(BaseEntity *entity, QObject *parent)
void LocalLoadTask::executeTask() void LocalLoadTask::executeTask()
{ {
const QString fname = Meta::localDir().absoluteFilePath(filename()); const QString fname = Meta::localDir().absoluteFilePath(m_entity->localFilename());
if (!QFile::exists(fname)) if (!QFile::exists(fname))
{ {
emitFailed(tr("File doesn't exist")); emitFailed(tr("File doesn't exist"));
return; return;
} }
setStatus(tr("Reading %1...").arg(fname));
setStatus(tr("Reading %1...").arg(name()));
setProgress(0, 0); setProgress(0, 0);
try try
{ {
parse(Json::requireObject(Json::requireDocument(fname, name()), name())); m_entity->parse(Json::requireObject(Json::requireDocument(fname, fname), fname));
m_entity->notifyLocalLoadComplete(); m_entity->notifyLocalLoadComplete();
emitSucceeded(); emitSucceeded();
} }
@ -55,69 +54,4 @@ void LocalLoadTask::executeTask()
emitFailed(tr("Unable to parse file %1: %2").arg(fname, e.cause())); 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());
}
} }

View File

@ -25,60 +25,15 @@ class Index;
class VersionList; class VersionList;
class Version; class Version;
// FIXME: this is now just an odd function, get rid of it
class LocalLoadTask : public Task class LocalLoadTask : public Task
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit LocalLoadTask(BaseEntity *entity, QObject *parent = nullptr); 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: private:
void executeTask() override; void executeTask() override;
BaseEntity *m_entity; 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;
};
} }

View File

@ -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() 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); 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); job->addNetAction(m_dl);
connect(job, &NetJob::failed, this, &RemoteLoadTask::emitFailed); 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::status, this, &RemoteLoadTask::setStatus);
connect(job, &NetJob::progress, this, &RemoteLoadTask::setProgress); connect(job, &NetJob::progress, this, &RemoteLoadTask::setProgress);
job->start(); 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());
}
} }

View File

@ -30,66 +30,17 @@ class Index;
class VersionList; class VersionList;
class Version; class Version;
// FIXME: this is now just an oddly constructed NetJob, get rid of it.
class RemoteLoadTask : public Task class RemoteLoadTask : public Task
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit RemoteLoadTask(BaseEntity *entity, QObject *parent = nullptr); 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: private:
void executeTask() override; void executeTask() override;
BaseEntity *m_entity; BaseEntity *m_entity;
std::shared_ptr<Net::Download> m_dl; 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;
};
} }

View File

@ -36,7 +36,7 @@ static QString formatRequires(const VersionPtr &version)
QStringList lines; QStringList lines;
for (const Reference &ref : version->requires()) 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()) if (ref.version().isEmpty())
{ {
lines.append(readable); lines.append(readable);