diff --git a/assets/romfs/github/ftpsrv.json b/assets/romfs/github/ftpsrv.json index 2333634..fcee8f9 100644 --- a/assets/romfs/github/ftpsrv.json +++ b/assets/romfs/github/ftpsrv.json @@ -1,12 +1,8 @@ { - "owner": "ITotalJustice", - "repo": "ftpsrv", + "url": "https://github.com/ITotalJustice/ftpsrv", "assets": [ { - "name": "switch_application.zip" - }, - { - "name": "switch_sysmod.zip" + "name": "switch" } ] } diff --git a/assets/romfs/github/sphaira.json b/assets/romfs/github/sphaira.json index 01274b6..a3c0a0d 100644 --- a/assets/romfs/github/sphaira.json +++ b/assets/romfs/github/sphaira.json @@ -1,4 +1,3 @@ { - "owner": "ITotalJustice", - "repo": "sphaira" + "url": "https://github.com/ITotalJustice/sphaira" } diff --git a/assets/romfs/github/untitled.json b/assets/romfs/github/untitled.json index b299b63..0c4c587 100644 --- a/assets/romfs/github/untitled.json +++ b/assets/romfs/github/untitled.json @@ -1,4 +1,3 @@ { - "owner": "ITotalJustice", - "repo": "untitled" + "url": "https://github.com/ITotalJustice/untitled" } diff --git a/sphaira/include/ui/menus/ghdl.hpp b/sphaira/include/ui/menus/ghdl.hpp index 0aa9ea3..6154054 100644 --- a/sphaira/include/ui/menus/ghdl.hpp +++ b/sphaira/include/ui/menus/ghdl.hpp @@ -17,8 +17,10 @@ struct AssetEntry { struct Entry { fs::FsPath json_path; + std::string url; std::string owner; std::string repo; + std::string tag; std::string pre_install_message; std::string post_install_message; std::vector assets; diff --git a/sphaira/source/ui/menus/ghdl.cpp b/sphaira/source/ui/menus/ghdl.cpp index b95e0dd..e1c96b9 100644 --- a/sphaira/source/ui/menus/ghdl.cpp +++ b/sphaira/source/ui/menus/ghdl.cpp @@ -27,7 +27,11 @@ namespace { constexpr auto CACHE_PATH = "/switch/sphaira/cache/github"; auto GenerateApiUrl(const Entry& e) { - return "https://api.github.com/repos/" + e.owner + "/" + e.repo + "/releases/latest"; + if (e.tag == "latest") { + return "https://api.github.com/repos/" + e.owner + "/" + e.repo + "/releases/latest"; + } else { + return "https://api.github.com/repos/" + e.owner + "/" + e.repo + "/releases/tags/" + e.tag; + } } auto apiBuildAssetCache(const std::string& url) -> fs::FsPath { @@ -48,8 +52,10 @@ void from_json(yyjson_val* json, AssetEntry& e) { void from_json(const fs::FsPath& path, Entry& e) { JSON_INIT_VEC_FILE(path, nullptr, nullptr); JSON_OBJ_ITR( + JSON_SET_STR(url); JSON_SET_STR(owner); JSON_SET_STR(repo); + JSON_SET_STR(tag); JSON_SET_STR(pre_install_message); JSON_SET_STR(post_install_message); JSON_SET_ARR_OBJ(assets); @@ -109,7 +115,7 @@ auto DownloadApp(ProgressBox* pbox, const GhApiAsset& gh_asset, const AssetEntry } // 3. extract the zip / file - if (gh_asset.content_type == "application/zip") { + if (gh_asset.content_type.find("zip") != gh_asset.content_type.npos) { log_write("found zip\n"); auto zfile = unzOpen64(temp_file); if (!zfile) { @@ -153,7 +159,11 @@ auto DownloadApp(ProgressBox* pbox, const GhApiAsset& gh_asset, const AssetEntry return false; } } else { - Result rc; + if (R_FAILED(rc = fs.CreateDirectoryRecursivelyWithPath(file_path, true)) && rc != FsError_PathAlreadyExists) { + log_write("failed to create folder: %s 0x%04X\n", file_path, rc); + return false; + } + if (R_FAILED(rc = fs.CreateFile(file_path, info.uncompressed_size, 0, true)) && rc != FsError_PathAlreadyExists) { log_write("failed to create file: %s 0x%04X\n", file_path, rc); return false; @@ -335,7 +345,7 @@ Menu::Menu() : MenuBase{"GitHub"_i18n} { if (!pre_install_message.empty()) { App::Push(std::make_shared( pre_install_message, - "Back"_i18n, "Donwload"_i18n, 1, [this, func](auto op_index){ + "Back"_i18n, "Download"_i18n, 1, [this, func](auto op_index){ if (op_index && *op_index) { func(); } @@ -420,7 +430,7 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) { gfx::drawTextArgs(vg, x + text_xoffset, y + (h / 2.f), 20.f, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE, theme->elements[text_id].colour, "%s By %s", e.repo.c_str(), e.owner.c_str()); nvgRestore(vg); - gfx::drawTextArgs(vg, x + w - text_xoffset, y + (h / 2.f), 16.f, NVG_ALIGN_RIGHT | NVG_ALIGN_MIDDLE, theme->elements[text_id].colour, GenerateApiUrl(e).c_str()); + gfx::drawTextArgs(vg, x + w - text_xoffset, y + (h / 2.f), 16.f, NVG_ALIGN_RIGHT | NVG_ALIGN_MIDDLE, theme->elements[text_id].colour, "version: %s", e.tag.c_str()); y += h; if (!InYBounds(y)) { @@ -490,13 +500,23 @@ void Menu::LoadEntriesFromPath(const fs::FsPath& path) { const auto full_path = fs::AppendPath(path, d->d_name); from_json(full_path, entry); + // parse owner and author from url (if needed). + if (!entry.url.empty()) { + const auto s = entry.url.substr(std::strlen("https://github.com/")); + const auto it = s.find('/'); + if (it != s.npos) { + entry.owner = s.substr(0, it); + entry.repo = s.substr(it + 1); + } + } + // check that we have a owner and repo if (entry.owner.empty() || entry.repo.empty()) { continue; } - for (auto& p : entry.assets) { - + if (entry.tag.empty()) { + entry.tag = "latest"; } entry.json_path = full_path; diff --git a/sphaira/source/ui/menus/homebrew.cpp b/sphaira/source/ui/menus/homebrew.cpp index 1d555c4..5ec0f1e 100644 --- a/sphaira/source/ui/menus/homebrew.cpp +++ b/sphaira/source/ui/menus/homebrew.cpp @@ -273,7 +273,7 @@ void Menu::SetIndex(std::size_t index) { void Menu::InstallHomebrew() { const auto& nro = m_entries[m_index]; - InstallHomebrew(nro.path, nro.nacp, nro_get_icon(nro.path, nro.size, nro.icon_offset)); + InstallHomebrew(nro.path, nro.nacp, nro_get_icon(nro.path, nro.icon_size, nro.icon_offset)); } void Menu::ScanHomebrew() {