Added a new BrowsableFolderServeNode. It renders a simple directory / file browser for the given dir at the given uri.

This commit is contained in:
Relintai 2022-02-06 10:56:21 +01:00
parent 1d311af863
commit e86ce3df45
3 changed files with 154 additions and 1 deletions

View File

@ -0,0 +1,122 @@
#include "browsable_folder_serve_node.h"
#include "core/os/directory.h"
#include "web/file_cache.h"
#include "web/html/html_builder.h"
#include "web/http/request.h"
void BrowsableFolderServeNode::_handle_request_main(Request *request) {
String file_name = request->get_path(true, false);
file_name.print();
request->get_path().print();
String *s = _folder_indexes[file_name];
if (!s) {
request->send_error(HTTP_STATUS_CODE_404_NOT_FOUND);
return;
}
if (should_render_menu) {
render_menu(request);
}
request->body += (*s);
request->compile_and_send_body();
}
void BrowsableFolderServeNode::load() {
if (serve_folder == "") {
return;
}
FolderServeNode::load();
evaluate_dir(serve_folder, true);
}
void BrowsableFolderServeNode::evaluate_dir(const String &path, const bool top_level) {
Ref<Directory> dir;
dir.instance();
ERR_FAIL_COND_MSG(dir->open_dir(path) != OK, "Error opening folde!r: " + String(path));
String dir_uri;
if (!top_level) {
dir_uri = path.substr(serve_folder.size(), path.size() - serve_folder.size());
} else {
dir_uri = "/";
}
Vector<String> folders;
Vector<String> files;
while (dir->next()) {
String np = dir->current_get_path();
np = np.substr(serve_folder.size(), np.size() - serve_folder.size());
if (dir->current_is_file()) {
files.push_back(np);
} else {
folders.push_back(np);
evaluate_dir(dir->current_get_path());
}
}
dir->close_dir();
folders.sort_inc();
files.sort_inc();
render_dir_page(dir_uri, folders, files);
}
void BrowsableFolderServeNode::render_dir_page(const String &dir_uri, const Vector<String> &folders, const Vector<String> &files) {
HTMLBuilder b;
String uri = get_full_uri(false);
b.div("file_list");
{
for (int i = 0; i < folders.size(); ++i) {
b.div("file_list_entry");
{
b.a(uri + folders[i])->w("(Folder) ")->w(folders[i].path_get_basename())->ca();
}
b.cdiv();
}
for (int i = 0; i < files.size(); ++i) {
b.div("file_list_entry");
{
b.a(uri + files[i])->w("(File) ")->w(files[i].path_get_basename())->ca();
}
b.cdiv();
}
}
b.cdiv();
String *s = new String();
s->append_str(b.result);
_folder_indexes[dir_uri] = s;
}
BrowsableFolderServeNode::BrowsableFolderServeNode() :
FolderServeNode() {
should_render_menu = true;
}
BrowsableFolderServeNode::~BrowsableFolderServeNode() {
for (std::map<String, String*>::iterator E = _folder_indexes.begin(); E != _folder_indexes.end(); E++) {
if (E->second) {
delete E->second;
}
}
_folder_indexes.clear();
}

View File

@ -0,0 +1,29 @@
#ifndef BROWSABLE_FOLDER_SERVE_NODE_H
#define BROWSABLE_FOLDER_SERVE_NODE_H
#include "core/string.h"
#include <map>
#include "folder_serve_node.h"
class BrowsableFolderServeNode : public FolderServeNode {
RCPP_OBJECT(BrowsableFolderServeNode, FolderServeNode);
public:
void _handle_request_main(Request *request);
virtual void load();
void evaluate_dir(const String &path, const bool top_level = false);
virtual void render_dir_page(const String &dir_uri, const Vector<String> &folders, const Vector<String> &files);
bool should_render_menu;
BrowsableFolderServeNode();
~BrowsableFolderServeNode();
protected:
std::map<String, String*> _folder_indexes;
};
#endif

View File

@ -6,7 +6,9 @@ void FolderServeNode::handle_request_main(Request *request) {
const String &rp = request->get_current_path_segment();
if (rp == "") {
request->send_error(HTTP_STATUS_CODE_404_NOT_FOUND);
if (!try_route_request_to_children(request)) {
_handle_request_main(request);
}
return;
}