This commit is contained in:
Luke Street
2026-09-09 22:14:46 -06:00
parent d62360567b
commit b84f8f56de
6 changed files with 20 additions and 35 deletions
-7
View File
@@ -297,13 +297,11 @@ Detail parse_detail(std::string_view body) {
const json root = json::parse(body);
Detail detail{
.mod = parse_mod(root),
.slug = required_string(root, "slug"),
.siteUrl = required_string(root, "site_url"),
.sourceUrl = optional_string(root, "source_url"),
.license = optional_string(root, "license"),
.descriptionHtml = required_string(root, "description_html"),
.changelogHtml = required_string(root, "changelog_html"),
.packageSha256 = required_string(root, "package_sha256"),
};
const auto& download = required_field(root, "download");
@@ -325,11 +323,6 @@ Detail parse_detail(std::string_view body) {
detail.modAbi = static_cast<uint32_t>(value);
}
const auto& banner = required_field(root, "banner");
if (!banner.is_null()) {
detail.banner = parse_image(banner);
}
const auto& screenshots = required_field(root, "screenshots");
if (!screenshots.is_array()) {
throw std::runtime_error{"field 'screenshots' is not an array"};
+1 -4
View File
@@ -92,16 +92,13 @@ struct Download {
struct Detail {
Mod mod;
std::string slug;
std::string siteUrl;
std::optional<std::string> sourceUrl;
std::optional<std::string> license;
std::string descriptionHtml;
std::string changelogHtml;
std::string packageSha256;
Download download;
std::optional<uint32_t> modAbi;
std::optional<Image> banner;
std::vector<Screenshot> screenshots;
std::vector<ServiceImport> serviceImports;
};
@@ -129,7 +126,7 @@ struct DetailFetchResult {
std::string error;
};
/** Fetches one filtered page from the configured Dusklight catalog. */
/** Fetches one filtered page from the Dusklight catalog. */
borealis::Task<FetchResult> fetch_page(Query query);
/** Fetches the full catalog record for one mod. */
+12 -8
View File
@@ -55,7 +55,7 @@ struct QueueItem {
};
std::vector<QueueItem> queueItems;
uint64_t nextLocalKey = 1;
uint64_t nextQueueKey = 1;
QueueItem* find_queue_item(std::string_view key) {
const auto item = std::ranges::find(queueItems, key,
@@ -161,9 +161,9 @@ bool copy_to_staging(const std::filesystem::path& source, const std::filesystem:
context.report_progress(completed, total);
}
}
output.close();
if (!input.eof() || !output) {
error = "Could not copy the local package";
output.close();
std::filesystem::remove(destination, filesystemError);
return false;
}
@@ -227,15 +227,17 @@ VerifyResult verify_local_package(const LocalFile& source, const std::filesystem
return {.error = fmt::format("Could not read the local package: {}", ec.message())};
}
context.report_progress(0, size);
ModMetadata metadata;
const auto stagedPath = stagingDir / fmt::format("{}.dusk.part", key);
std::string error;
if (!inspect_mod_bundle(source.path, metadata, error)) {
return {.error = fmt::format("Invalid mod package: {}", error)};
}
const auto stagedPath = staging_path(stagingDir, metadata.id, key);
if (!copy_to_staging(source.path, stagedPath, size, context, error)) {
return {.error = std::move(error), .canceled = context.cancel_requested()};
}
// Validate the bytes handed to the loader; the source may change during copying.
ModMetadata metadata;
if (!inspect_mod_bundle(stagedPath, metadata, error)) {
std::filesystem::remove(stagedPath, ec);
return {.error = fmt::format("Invalid mod package: {}", error)};
}
return {.metadata = std::move(metadata), .stagedPath = stagedPath};
}
@@ -446,6 +448,8 @@ void finish_verification(QueueItem& item) {
fail(item, std::move(result.error), true);
return;
}
remove_partial(item);
item.partialPath = result.stagedPath;
if (const auto duplicate = find_queue_item_by_mod_id(result.metadata.id);
duplicate != nullptr && duplicate != &item && !is_terminal(duplicate->state))
{
@@ -535,7 +539,7 @@ bool enqueue(Request request, std::string* keyOut) {
return true;
}
const auto key = source != nullptr ? request.id : fmt::format("local-{}", nextLocalKey++);
const auto key = fmt::format("queue-{}", nextQueueKey++);
if (keyOut != nullptr) {
*keyOut = key;
}
+1 -1
View File
@@ -60,7 +60,7 @@ struct Request {
};
struct Item {
// Queue key. URL installs use their mod ID; local installs receive a generated key.
// Queue key, independent of the mod ID.
std::string id;
std::string modId;
std::string name;
+2 -11
View File
@@ -574,8 +574,8 @@ DetailContent::DetailContent(
.verticalBoundary = Boundary::Stop,
}} {
auto* hero = append(mRoot, "catalog-detail-hero");
if (detail.banner) {
set_image(hero, *detail.banner, 1280);
if (detail.mod.banner) {
set_image(hero, *detail.mod.banner, 1280);
} else if (detail.mod.icon) {
set_image(hero, *detail.mod.icon, 512);
}
@@ -627,15 +627,6 @@ DetailContent::DetailContent(
append_stat(stats, "\uF090", format_count(detail.mod.downloads), " downloads");
append_stat(stats, "\uE87D", format_count(detail.mod.endorsements), " endorsements");
append_stat(stats, "", format_bytes(detail.mod.packageSize), " package");
// TODO replace with common banner component
// if (detail.mod.containsNativeCode) {
// auto* warning = append(mRoot, "catalog-native-warning");
// append_text(append(warning, "icon"), "\uE002");
// auto* copy = append(warning, "catalog-warning-copy");
// append_text_element(copy, "catalog-warning-title", "Contains native code");
// append_text_element(
// copy, "catalog-warning-message", "Review the source and author before installing.");
// }
auto* body = append(mRoot, "catalog-detail-body");
auto* main = append(body, "main");
+4 -4
View File
@@ -75,13 +75,13 @@ struct RemoteSource {
};
std::unordered_map<std::string, Entry>& image_cache() {
static auto* cache = new std::unordered_map<std::string, Entry>();
return *cache;
static std::unordered_map<std::string, Entry> cache;
return cache;
}
uint64_t& use_counter() {
static auto* counter = new uint64_t{};
return *counter;
static uint64_t counter = 0;
return counter;
}
RemoteSource parse_remote_source(std::string_view source) noexcept {