diff --git a/Makefile b/Makefile index 50f0e2b..7ad2cf1 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ INCLUDES := include ./Libraries/FsLib/Switch/FsLib/include ./Libraries/SDLLib/SD EXEFS_SRC := exefs_src APP_TITLE := JKSV APP_AUTHOR := JK -APP_VERSION := 08.07.2025 +APP_VERSION := 08.08.2025 ROMFS := romfs ICON := icon.jpg diff --git a/source/JKSV.cpp b/source/JKSV.cpp index e7de399..99bc5e8 100644 --- a/source/JKSV.cpp +++ b/source/JKSV.cpp @@ -29,7 +29,7 @@ namespace /// @brief Build month. constexpr uint8_t BUILD_MON = 8; /// @brief Build day. - constexpr uint8_t BUILD_DAY = 7; + constexpr uint8_t BUILD_DAY = 8; /// @brief Year. constexpr uint16_t BUILD_YEAR = 2025; } // namespace diff --git a/source/appstates/BackupMenuState.cpp b/source/appstates/BackupMenuState.cpp index a956916..33e8703 100644 --- a/source/appstates/BackupMenuState.cpp +++ b/source/appstates/BackupMenuState.cpp @@ -179,10 +179,11 @@ void BackupMenuState::ensure_target_directory() const char *popFailed = strings::get_by_name(strings::names::BACKUPMENU_POPS, 12); // If this is enabled, don't bother. - const bool autoUpload = config::get_by_key(config::keys::AUTO_UPLOAD); - const bool directoryNeeded = !autoUpload && !fslib::directory_exists(m_directoryPath); - const bool directoryFailed = directoryNeeded && error::fslib(fslib::create_directory(m_directoryPath)); - if (!autoUpload && directoryFailed) { ui::PopMessageManager::push_message(popTicks, popFailed); } + const remote::Storage *remote = remote::get_remote_storage(); + const bool autoUpload = config::get_by_key(config::keys::AUTO_UPLOAD); + const bool directoryNeeded = (!remote || !autoUpload) && !fslib::directory_exists(m_directoryPath); + const bool directoryFailed = directoryNeeded && error::fslib(fslib::create_directory(m_directoryPath)); + if (directoryNeeded && directoryFailed) { ui::PopMessageManager::push_message(popTicks, popFailed); } } void BackupMenuState::initialize_task_data() diff --git a/source/remote/Storage.cpp b/source/remote/Storage.cpp index fbba859..ce336d0 100644 --- a/source/remote/Storage.cpp +++ b/source/remote/Storage.cpp @@ -1,6 +1,9 @@ #include "remote/Storage.hpp" +#include "logger.hpp" + #include +#include // Declarations here. Defined at bottom. remote::Storage::Storage(std::string_view prefix, bool supportsUtf8) @@ -66,7 +69,13 @@ std::string_view remote::Storage::get_prefix() const { return m_prefix; } remote::Storage::List::iterator remote::Storage::find_directory_by_name(std::string_view name) { auto is_match = [&](const Item &item) - { return item.is_directory() && item.get_parent_id() == m_parent && item.get_name() == name; }; + { + const bool isDir = item.is_directory(); + const bool parentMatch = isDir && item.get_parent_id() == m_parent; + const bool nameMatch = parentMatch && item.get_name() == name; + + return isDir && parentMatch && nameMatch; + }; return std::find_if(m_list.begin(), m_list.end(), is_match); } @@ -74,7 +83,13 @@ remote::Storage::List::iterator remote::Storage::find_directory_by_name(std::str remote::Storage::List::iterator remote::Storage::find_file_by_name(std::string_view name) { auto is_match = [&](const Item &item) - { return !item.is_directory() && item.get_parent_id() == m_parent && item.get_name() == name; }; + { + const bool notDir = !item.is_directory(); + const bool parentMatch = notDir && item.get_parent_id() == m_parent; + const bool nameMatch = parentMatch && item.get_name() == name; + + return notDir && parentMatch && nameMatch; + }; return std::find_if(m_list.begin(), m_list.end(), is_match); } diff --git a/source/remote/WebDav.cpp b/source/remote/WebDav.cpp index 38c2fb1..4f2b24c 100644 --- a/source/remote/WebDav.cpp +++ b/source/remote/WebDav.cpp @@ -21,6 +21,10 @@ static tinyxml2::XMLElement *get_element_by_name(tinyxml2::XMLElement *parent, s /// @param tag Tag to get the name of. static std::string_view get_tag_begin(std::string_view tag); +/// @brief Ensures the parent is a valid path. I guess some servers don't have trailing slashes for directories. +/// @param parent Parent string. +static std::string ensure_valid_dir_path(std::string_view parent); + /// @brief Slices and unescapes the directory or filename from the href. /// @param handle Curl handle to use to unescape. /// @param href HREF to slice. @@ -346,7 +350,7 @@ bool remote::WebDav::process_listing(std::string_view xml) return false; } - const char *parentLocationText = parentLocation->GetText(); // Possibly going to need this a lot. + const std::string parentID = ensure_valid_dir_path(parentLocation->GetText()); tinyxml2::XMLElement *current{}; for (current = parent->NextSiblingElement(); current; current = current->NextSiblingElement()) { @@ -363,7 +367,9 @@ bool remote::WebDav::process_listing(std::string_view xml) tinyxml2::XMLElement *collection = get_element_by_name(resourceType, tagCollection); if (collection) { - m_list.emplace_back(name, hrefText, parentLocationText, 0, true); + const std::string idString = ensure_valid_dir_path(hrefText); + + m_list.emplace_back(name, idString, parentID, 0, true); remote::URL nextUrl{m_origin}; nextUrl.append_path(hrefText); @@ -380,7 +386,7 @@ bool remote::WebDav::process_listing(std::string_view xml) const char *lengthString = getContentLength->GetText(); const int64_t contentLength = std::strtoll(lengthString, nullptr, 10); - m_list.emplace_back(name, hrefText, parentLocationText, contentLength, false); + m_list.emplace_back(name, hrefText, parentID, contentLength, false); } } return true; @@ -404,31 +410,31 @@ static std::string_view get_tag_begin(std::string_view tag) return tag.substr(colon + 1); } +static std::string ensure_valid_dir_path(std::string_view parent) +{ + std::string returnParent{parent}; + if (returnParent.back() != '/') { returnParent.append("/"); } + return returnParent; +} + static std::string slice_name_from_href(curl::Handle &handle, std::string_view href) { std::string name{}; - // This means we're working with a directory. if (href.back() == '/') { - size_t end = href.find_last_of('/'); - size_t begin = href.find_last_of('/', end - 1); - if (end == href.npos || begin == href.npos) - { - // To do: Maybe handle this better? - return std::string(href); - } - // To do: Inspect this behavior better. - name = href.substr(begin + 1, (end - begin) - 1); + // To do: This might not be the safest. + size_t end = href.find_last_of('/') - 1; + size_t begin = href.find_last_of('/', end); + if (begin == href.npos) { name = href; } + else { name = href.substr(begin + 1, (end - begin)); } } else { - // File size_t begin = href.find_last_of('/'); if (begin == href.npos) { name = href; } else { name = href.substr(begin + 1); } } - curl::unescape_string(handle, name, name); return name;