From eb2abf779de6d6183f44963fd994997c536d343c Mon Sep 17 00:00:00 2001 From: Relintai Date: Sun, 3 Jul 2022 15:27:14 +0200 Subject: [PATCH] Cleaned up PagedArticle and added it to the build. --- modules/web/SCsub | 2 + modules/web/config.py | 2 + .../web/nodes/paged_article/paged_article.cpp | 186 ++++++++++++------ .../web/nodes/paged_article/paged_article.h | 42 ++-- modules/web/register_types.cpp | 4 + 5 files changed, 169 insertions(+), 67 deletions(-) diff --git a/modules/web/SCsub b/modules/web/SCsub index 48c560ec2..6bc208e36 100644 --- a/modules/web/SCsub +++ b/modules/web/SCsub @@ -41,6 +41,8 @@ sources = [ "nodes/folder_serve_nodes/folder_serve_node.cpp", "nodes/list_page/list_page.cpp", + + "nodes/paged_article/paged_article.cpp", ] if ARGUMENTS.get('custom_modules_shared', 'no') == 'yes': diff --git a/modules/web/config.py b/modules/web/config.py index d948fbdef..b9c06d13e 100644 --- a/modules/web/config.py +++ b/modules/web/config.py @@ -44,6 +44,8 @@ def get_doc_classes(): "BrowsableFolderServeNode", "ListPage", + + "PagedArticle", ] diff --git a/modules/web/nodes/paged_article/paged_article.cpp b/modules/web/nodes/paged_article/paged_article.cpp index 22d7cc743..9fb594198 100644 --- a/modules/web/nodes/paged_article/paged_article.cpp +++ b/modules/web/nodes/paged_article/paged_article.cpp @@ -1,12 +1,37 @@ #include "paged_article.h" -#include "core/os/directory.h" -#include "web/html/utils.h" -#include "web/http/web_permission.h" +#include "core/os/dir_access.h" +#include "core/os/file_access.h" +#include "core/project_settings.h" -#include +#include "../../file_cache.h" +#include "../../html/paginator.h" +#include "../../http/http_server_enums.h" +#include "../../http/web_permission.h" +#include "../../http/web_server_request.h" -void PagedArticle::handle_request_main(Request *request) { +String PagedArticle::get_articles_folder() { + return articles_folder; +} +void PagedArticle::set_articles_folder(const String &val) { + articles_folder = val; +} + +bool PagedArticle::get_serve_folder_relative() { + return serve_folder_relative; +} +void PagedArticle::set_serve_folder_relative(const bool &val) { + serve_folder_relative = val; +} + +String PagedArticle::get_serve_folder() { + return serve_folder; +} +void PagedArticle::set_serve_folder(const String &val) { + serve_folder = val; +} + +void PagedArticle::_handle_request_main(Ref request) { if (_web_permission.is_valid()) { if (_web_permission->activate(request)) { return; @@ -18,8 +43,10 @@ void PagedArticle::handle_request_main(Request *request) { if (request->get_remaining_segment_count() > 1 && rp == "files") { String file_name = "/" + request->get_path_segment(request->get_current_segment_index() + 1); - if (file_cache->wwwroot_has_file(file_name)) { - String fp = file_cache->wwwroot + file_name; + int file_indx = file_cache->wwwroot_get_file_index(file_name); + + if (file_indx != -1) { + String fp = file_cache->wwwroot_get_file_orig_path_abs(file_indx); request->send_file(fp); return; @@ -28,69 +55,104 @@ void PagedArticle::handle_request_main(Request *request) { if (rp == "") { render_menu(request); - render_index(request); request->compile_and_send_body(); return; } - const String *page = pages[rp]; + for (int i = 0; i < pages.size(); ++i) { + const PAEntry &e = pages[i]; - if (page == nullptr) { - // bad url - request->send_error(404); - return; + if (e.url == rp) { + render_menu(request); + request->body += e.data; + request->compile_and_send_body(); + } } - render_menu(request); - request->body += (*page); - request->compile_and_send_body(); + request->send_error(HTTPServerEnums::HTTP_STATUS_CODE_404_NOT_FOUND); } -void PagedArticle::render_index(Request *request) { +void PagedArticle::_render_index(Ref request) { // summary page request->body += index_page; } -void PagedArticle::render_preview(Request *request) { +void PagedArticle::_render_preview(Ref request) { } void PagedArticle::load() { ERR_FAIL_COND_MSG(articles_folder == "", "Error: PagedArticle::load called, but a articles_folder is not set!"); - Ref dir; - dir.instance(); + String path = articles_folder; - ERR_FAIL_COND_MSG(dir->open_dir(articles_folder.c_str()) != OK, "Error opening PagedArticle::folder! folder: " + articles_folder); - - Vector files; - - while (dir->next()) { - if (dir->current_is_file()) { - files.push_back(dir->current_get_name()); + if (path.begins_with("res://")) { + if (ProjectSettings::get_singleton()) { + String resource_path = ProjectSettings::get_singleton()->get_resource_path(); + if (resource_path != "") { + path = path.replace_first("res:/", resource_path); + } else { + path = path.replace_first("res://", ""); + } + } + } else if (path.begins_with("user://")) { + String data_dir = OS::get_singleton()->get_user_data_dir(); + if (data_dir != "") { + path = path.replace_first("user:/", data_dir); + } else { + path = path.replace_first("user://", ""); } } - dir->close_dir(); + _articles_folder_abs = DirAccess::get_full_path(path, DirAccess::ACCESS_FILESYSTEM); + _articles_folder_abs = _articles_folder_abs.path_ensure_end_slash(); + + DirAccess *dir = DirAccess::open(_articles_folder_abs); + + ERR_FAIL_COND_MSG(!dir, "Error opening PagedArticle::folder! folder: " + _articles_folder_abs); + + Vector files; + + dir->list_dir_begin(); + + String file = dir->get_next(); + + while (file != "") { + if (!dir->current_is_dir()) { + files.push_back(file); + } + + file = dir->get_next(); + } + + dir->list_dir_end(); + memdelete(dir); + dir = nullptr; if (files.size() == 0) { return; } - files.sort_inc(); + files.sort(); - for (uint32_t i = 0; i < files.size(); ++i) { - String file_path = articles_folder; - file_path.append_path(files[i]); + for (int i = 0; i < files.size(); ++i) { + String file_path = _articles_folder_abs; + file_path += files[i]; String fd; - ERR_CONTINUE_MSG(dir->read_file_into(file_path, &fd) != OK, "PagedArticle::load_folder: Error opening file! " + file_path); + FileAccess *f = FileAccess::open(file_path, FileAccess::READ); - Utils::markdown_to_html(&fd); + ERR_CONTINUE_MSG(!f, "Error opening file! " + file_path); - if (files[i] == "summary.md") { + fd = f->get_as_utf8_string(); + f->close(); + memdelete(f); + + //Utils::markdown_to_html(&fd); + + if (files[i].get_file().get_basename() == "summary") { summary = fd; continue; @@ -98,18 +160,22 @@ void PagedArticle::load() { String pagination; - pagination = Utils::get_pagination_links(get_full_uri(), files, i); + pagination = HTMLPaginator::get_pagination_links_old(get_full_uri(false), files, i); - String *finals = new String(); + String finals; - (*finals) += pagination; - (*finals) += fd; - (*finals) += pagination; + finals += pagination; + finals += fd; + finals += pagination; - pages[files[i]] = finals; + PAEntry e; + e.url = files[i]; + e.data = finals; + + pages.push_back(e); if (i == 0) { - index_page = (*finals); + index_page = finals; } } @@ -117,10 +183,9 @@ void PagedArticle::load() { if (serve_folder != "") { if (serve_folder_relative) { - file_cache->wwwroot = articles_folder; - file_cache->wwwroot.append_path(serve_folder); + file_cache->set_wwwroot(_articles_folder_abs.append_path(serve_folder)); } else { - file_cache->wwwroot = serve_folder; + file_cache->set_wwwroot(serve_folder); } file_cache->wwwroot_refresh_cache(); @@ -153,21 +218,32 @@ void PagedArticle::_notification(const int what) { } } -PagedArticle::PagedArticle() : - WebNode() { - - file_cache = new FileCache(); +PagedArticle::PagedArticle() { + file_cache.instance(); serve_folder_relative = true; serve_folder = "files"; } PagedArticle::~PagedArticle() { - for (std::map::iterator it = pages.begin(); it != pages.end(); ++it) { - delete ((*it).second); - } - pages.clear(); +} - delete file_cache; -} \ No newline at end of file +void PagedArticle::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_articles_folder"), &PagedArticle::get_articles_folder); + ClassDB::bind_method(D_METHOD("set_articles_folder", "val"), &PagedArticle::set_articles_folder); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "articles_folder"), "set_articles_folder", "get_articles_folder"); + + ClassDB::bind_method(D_METHOD("get_serve_folder_relative"), &PagedArticle::get_serve_folder_relative); + ClassDB::bind_method(D_METHOD("set_serve_folder_relative", "val"), &PagedArticle::set_serve_folder_relative); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "serve_folder_relative"), "set_serve_folder_relative", "get_serve_folder_relative"); + + ClassDB::bind_method(D_METHOD("get_serve_folder"), &PagedArticle::get_serve_folder); + ClassDB::bind_method(D_METHOD("set_serve_folder", "val"), &PagedArticle::set_serve_folder); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "serve_folder"), "set_serve_folder", "get_serve_folder"); + + ClassDB::bind_method(D_METHOD("load"), &PagedArticle::load); + ClassDB::bind_method(D_METHOD("get_index_page"), &PagedArticle::get_index_page); + ClassDB::bind_method(D_METHOD("get_summary"), &PagedArticle::get_summary); + ClassDB::bind_method(D_METHOD("generate_summary"), &PagedArticle::generate_summary); +} diff --git a/modules/web/nodes/paged_article/paged_article.h b/modules/web/nodes/paged_article/paged_article.h index 6df21035c..5a5187e4b 100644 --- a/modules/web/nodes/paged_article/paged_article.h +++ b/modules/web/nodes/paged_article/paged_article.h @@ -1,13 +1,11 @@ #ifndef PAGED_ARTICLE_H #define PAGED_ARTICLE_H +#include "core/reference.h" #include "core/ustring.h" #include "core/vector.h" -#include "web/file_cache.h" -#include "web/http/web_node.h" - -#include "web/http/request.h" +#include "../../http/web_node.h" // This class will load and process all md files from the folder set to it's articles_folder property, // and serve every file from the directory set to it's serve_folder property. @@ -16,14 +14,26 @@ // THe links is generates currently look like: /01_test.md // files are served under /files/ +class WebServerRequest; +class FileCache; + class PagedArticle : public WebNode { GDCLASS(PagedArticle, WebNode); public: - void handle_request_main(Request *request); + String get_articles_folder(); + void set_articles_folder(const String &val); - void render_index(Request *request); - void render_preview(Request *request); + bool get_serve_folder_relative(); + void set_serve_folder_relative(const bool &val); + + String get_serve_folder(); + void set_serve_folder(const String &val); + + void _handle_request_main(Ref request); + + void _render_index(Ref request); + void _render_preview(Ref request); void load(); void load_folder(const String &folder, const String &path); @@ -32,20 +42,28 @@ public: virtual void generate_summary(); - void _notification(const int what); - PagedArticle(); ~PagedArticle(); +protected: + void _notification(const int what); + static void _bind_methods(); + String articles_folder; + String _articles_folder_abs; bool serve_folder_relative; String serve_folder; -protected: String index_page; String summary; - std::map pages; - FileCache *file_cache; + + struct PAEntry { + String url; + String data; + }; + + Vector pages; + Ref file_cache; }; #endif diff --git a/modules/web/register_types.cpp b/modules/web/register_types.cpp index 332354acf..641274ed5 100644 --- a/modules/web/register_types.cpp +++ b/modules/web/register_types.cpp @@ -52,6 +52,8 @@ SOFTWARE. #include "nodes/list_page/list_page.h" +#include "nodes/paged_article/paged_article.h" + void register_web_types() { ClassDB::register_class<_HTMLBuilder>(); ClassDB::register_class<_HTMLTag>(); @@ -84,6 +86,8 @@ void register_web_types() { ClassDB::register_class(); ClassDB::register_class(); + + ClassDB::register_class(); } void unregister_web_types() {