Fix WebDav basepath/root

This commit is contained in:
J-D-K
2025-07-04 15:04:13 -04:00
parent a7413c3e75
commit b1b9ce2959
5 changed files with 63 additions and 9 deletions

View File

@@ -84,6 +84,9 @@ namespace remote
/// @brief Returns whether or not the remote storage type supports UTF-8 for names or requires path safe titles.
bool supports_utf8() const;
/// @brief Returns the prefix for menus.
std::string_view get_prefix() const;
protected:
/// @brief This is the size of the buffers used for snprintf'ing URLs together.
static constexpr size_t SIZE_URL_BUFFER = 0x401;
@@ -109,6 +112,9 @@ namespace remote
/// @brief This is the main remote listing.
Storage::List m_list;
/// @brief This is the prefix used for menus.
std::string m_prefix;
/// @brief Searches the list for a directory matching name and the current parent.
/// @param name Name to search for.
Storage::List::iterator find_directory_by_name(std::string_view name);

View File

@@ -50,6 +50,9 @@ remote::GoogleDrive::GoogleDrive() : Storage()
// Google Drive doesn't really use directories, so UTF-8 is fine!
m_utf8Paths = true;
// Google Drive menu prefix.
m_prefix = "[GD] ";
// Load the json file.
json::Object clientJson = json::new_object(json_object_from_file, remote::PATH_GOOGLE_DRIVE_CONFIG.data());
if (!clientJson)

View File

@@ -1,5 +1,7 @@
#include "remote/Item.hpp"
#include "logger.hpp"
remote::Item::Item(std::string_view name, std::string_view id, std::string_view parent, size_t size, bool directory)
: m_name(name), m_id(id), m_parent(parent), m_size(size), m_isDirectory(directory) {};

View File

@@ -74,6 +74,11 @@ bool remote::Storage::supports_utf8() const
return m_utf8Paths;
}
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)
{
return std::find_if(m_list.begin(), m_list.end(), [name, this](const Item &item) {

View File

@@ -3,12 +3,13 @@
#include "curl/curl.hpp"
#include "logger.hpp"
#include "remote/remote.hpp"
#include "stringutil.hpp"
#include <tinyxml2.h>
namespace
{
const char *TAG_XML_HREF = "href";
}
} // namespace
// Declarations here. Definitions at bottom.
/// @brief Gets a XML element by name. This is namespace agnostic.
@@ -20,6 +21,12 @@ 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 Slices and unescapes the directory or filename from the href.
/// @param handle Curl handle to use to unescape.
/// @param href HREF to slice.
/// @note This seemed like a better alternative than relying on servers having displayname.
static std::string slice_name_from_href(curl::Handle &handle, std::string_view href);
remote::WebDav::WebDav() : Storage()
{
static const char *STRING_CONFIG_READ_ERROR = "Error initializing WebDav: %s";
@@ -27,6 +34,9 @@ remote::WebDav::WebDav() : Storage()
// WebDav has problems with these.
m_utf8Paths = false;
// WebDav prefix for menus.
m_prefix = "[WD] ";
json::Object config = json::new_object(json_object_from_file, remote::PATH_WEBDAV_CONFIG.data());
if (!config)
{
@@ -52,7 +62,7 @@ remote::WebDav::WebDav() : Storage()
{
// The root is both in the beginning. I want this to work as closely as the original just not as poorly written
// or thought out as the original JKSV dav code.
m_root = json_object_get_string(basepath);
m_root = stringutil::get_formatted_string("/%s/", json_object_get_string(basepath));
m_parent = m_root;
}
@@ -77,7 +87,6 @@ remote::WebDav::WebDav() : Storage()
logger::log(STRING_CONFIG_READ_ERROR, "Error retrieving listing from WebDav server!");
return;
}
m_isInitialized = true;
}
@@ -328,8 +337,11 @@ bool remote::WebDav::process_listing(std::string_view xml)
tinyxml2::XMLElement *collection = get_element_by_name(resourceType, "collection");
if (collection)
{
// JKSV doesn't expose folder names to the end user, so they are emplaced as-is.
m_list.emplace_back(href->GetText(), href->GetText(), parentLocation->GetText(), 0, true);
m_list.emplace_back(slice_name_from_href(m_curl, href->GetText()),
href->GetText(),
parentLocation->GetText(),
0,
true);
remote::URL nextUrl{m_origin};
nextUrl.append_path(href->GetText());
@@ -342,15 +354,14 @@ bool remote::WebDav::process_listing(std::string_view xml)
}
else
{
tinyxml2::XMLElement *displayName = get_element_by_name(prop, "displayname");
tinyxml2::XMLElement *getContentLength = get_element_by_name(prop, "getcontentlength");
if (!displayName || !getContentLength)
if (!getContentLength)
{
logger::log(STRING_ERROR_PROCESSING_XML, "Missing needed tags for file!");
logger::log(STRING_ERROR_PROCESSING_XML, "Missing needed data for file!");
continue;
}
m_list.emplace_back(displayName->GetText(),
m_list.emplace_back(slice_name_from_href(m_curl, href->GetText()),
href->GetText(),
parentLocation->GetText(),
std::strtoll(getContentLength->GetText(), NULL, 10),
@@ -388,3 +399,30 @@ static std::string_view get_tag_begin(std::string_view tag)
}
return tag.substr(colon + 1);
}
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);
// To do: Inspect this behavior better.
name = href.substr(begin + 1, (end - begin) - 1);
}
else
{
// File
size_t begin = href.find_last_of('/');
name = href.substr(begin + 1);
}
curl::unescape_string(handle, name, name);
logger::log(name.c_str());
return name;
}