Remake filesystem listing to protobuf

This commit is contained in:
Niklas Jensen
2026-01-25 00:49:39 +01:00
committed by nikguin04
parent 6e7f7bb657
commit 9666baf858
6 changed files with 175 additions and 17 deletions
+84
View File
@@ -1,10 +1,94 @@
#include <filesystem.h>
#include <communication/webserver.h>
#include <vector>
#include <cstring>
static const char *TAG = "FileService";
namespace FileSystem {
// Storage for dynamically allocated FileEntry arrays
static std::vector<api_FileEntry*> allocatedEntries;
static void freeAllocatedEntries() {
for (auto ptr : allocatedEntries) {
delete[] ptr;
}
allocatedEntries.clear();
}
void listFilesProto(const std::string &directory, api_FileEntry *entry) {
File root = ESP_FS.open(directory.find("/") == 0 ? directory.c_str() : ("/" + directory).c_str());
if (!root.isDirectory()) {
entry->children_count = 0;
entry->children = nullptr;
return;
}
// First pass: count children
std::vector<File> files;
File file = root.openNextFile();
while (file) {
files.push_back(file);
file = root.openNextFile();
}
if (files.empty()) {
entry->children_count = 0;
entry->children = nullptr;
return;
}
// Allocate children array
entry->children_count = files.size();
entry->children = new api_FileEntry[files.size()];
allocatedEntries.push_back(entry->children);
// Fill children
for (size_t i = 0; i < files.size(); i++) {
api_FileEntry &child = entry->children[i];
memset(&child, 0, sizeof(child));
std::string name = std::string(files[i].name());
strncpy(child.name, name.c_str(), sizeof(child.name) - 1);
child.name[sizeof(child.name) - 1] = '\0';
child.is_directory = files[i].isDirectory();
if (child.is_directory) {
listFilesProto(name, &child);
} else {
child.size = files[i].size();
child.children_count = 0;
child.children = nullptr;
}
}
}
esp_err_t getFilesProto(httpd_req_t *request) {
freeAllocatedEntries(); // Clean up any previous allocations
api_Response res = api_Response_init_zero;
res.status_code = 200;
res.which_payload = api_Response_file_list_tag;
// Create root entry
api_FileEntry rootEntry = api_FileEntry_init_zero;
strncpy(rootEntry.name, "root", sizeof(rootEntry.name) - 1);
rootEntry.is_directory = true;
listFilesProto("/", &rootEntry);
// Allocate entries array for FileList
res.payload.file_list.entries_count = 1;
res.payload.file_list.entries = new api_FileEntry[1];
allocatedEntries.push_back(res.payload.file_list.entries);
res.payload.file_list.entries[0] = rootEntry;
esp_err_t result = WebServer::sendProto(request, 200, res, api_Response_fields);
freeAllocatedEntries(); // Clean up after sending
return result;
}
esp_err_t getFiles(httpd_req_t *request) {
std::string files = listFiles("/");
httpd_resp_set_type(request, "application/json");