WebDav fixes and tweaks.

This commit is contained in:
J-D-K 2025-08-08 16:07:55 -04:00
parent 7d9a294745
commit 2f2191bc15
5 changed files with 45 additions and 23 deletions

View File

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

View File

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

View File

@ -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()

View File

@ -1,6 +1,9 @@
#include "remote/Storage.hpp"
#include "logger.hpp"
#include <algorithm>
#include <cstring>
// 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);
}

View File

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