From 1560d0efec6876ef8e820c5ec72bea6098f99870 Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Wed, 22 Apr 2020 19:29:37 +0200 Subject: weblog (wip) --- plugins/weblog/weblog.cpp | 73 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 10 deletions(-) (limited to 'plugins') diff --git a/plugins/weblog/weblog.cpp b/plugins/weblog/weblog.cpp index 0c0ffcd..38d6dec 100644 --- a/plugins/weblog/weblog.cpp +++ b/plugins/weblog/weblog.cpp @@ -1,6 +1,8 @@ #include "weblog.h" #include +#include +#include #include #include @@ -10,6 +12,7 @@ using namespace std::string_literals; namespace fs = std::filesystem; +namespace pt = boost::property_tree; namespace { @@ -82,6 +85,12 @@ namespace { return (rel_target.size() == 0 || rel_target == "/"); } + bool is_index_file(std::string& rel_target, fs::path& path) + { + // must be top-level file, recognized as mime_type() + return rel_target.find("/") == rel_target.npos && mime_type(path) != "application/text"; + } + bool is_article_page(std::string& rel_target, fs::path& path) { return (rel_target.size() >= 2 && rel_target.back() == '/' && fs::is_directory(path)); @@ -146,9 +155,12 @@ namespace { std::vector result; for (auto& year_entry: fs::directory_iterator(path)) { - for (auto& entry: fs::directory_iterator(year_entry.path())) { - auto metaData{getMetaData(entry.path())}; - result.emplace_back(ArticleInfo{entry.path(), metaData.at("Subject"), metaData.at("Date")}); + std::string year_entry_filename{year_entry.path().filename().string()}; + if (fs::is_directory(year_entry)) { + for (auto& entry: fs::directory_iterator(year_entry.path())) { + auto metaData{getMetaData(entry.path())}; + result.emplace_back(ArticleInfo{entry.path(), metaData.at("Subject"), metaData.at("Date")}); + } } } @@ -159,19 +171,60 @@ namespace { return {result.begin(), result.begin() + size}; } + // returns plain text of string (xml elements removed) + std::string plainText(const std::string& text) + { + pt::ptree tree; + + std::istringstream ss{text}; + //pt::read_xml(ss, tree, pt::xml_parser::no_comments | pt::xml_parser::trim_whitespace); + + //std::cout << "DEBUG: " << tree.get("file") << std::endl; + + return text; + } + + // returns teaser of article in plain text + std::string shortVersion(const fs::path& path) + { + std::string article {getFile(path / article_filename)}; + size_t pos0 {article.find("\n\n")}; + if (pos0 == article.npos) + return ""; + + article = "" + article.substr(pos0 + 2) + ""; + + article = plainText(article); + + size_t pos1 {article.find(".")}; + + size_t num {std::min(static_cast(1000), pos1) + 1}; + + return article.substr(0, num); + } + std::string generateIndexPage(fs::path& path, std::function& GetRequestParam, std::function& SetResponseHeader) { try { - std::string result{"

"s + GetRequestParam("WEBLOG_NAME") + "

"s}; + std::string result{"

"s + GetRequestParam("WEBLOG_NAME") + "

"s}; fs::path link{ GetRequestParam("rel_target")}; auto list{getArticleList(path)}; for (const auto& article: list) { - result += "

"s + article.subject + "

"s + article.date + "
"s; + std::string linkstart{""}; + std::string linkend{""}; + result += "

"s + linkstart + article.subject + linkend + "

"s + article.date + "
"s; + + auto sv{shortVersion(article.path)}; + if (sv.size()) { + result += sv + " "s + linkstart + "more..." + linkend; + } } + result += "


"; + result += "Impressum"; result += ""; return result; } catch (const std::exception& ex) { @@ -191,7 +244,7 @@ namespace { if (pos == data.npos) throw std::runtime_error("Error parsing article"); - std::string result { "

"s + metaData.at("Subject") + "

"s + metaData.at("Date") + "

"s + data.substr(pos + 2) + ""s}; + std::string result { "

"s + metaData.at("Subject") + "

"s + metaData.at("Date") + "

"s + data.substr(pos + 2) + ""s}; return result; } catch (const std::exception& ex) { @@ -199,7 +252,7 @@ namespace { } } - std::string generateArticleFile(fs::path& path, std::function& SetResponseHeader) + std::string generateStaticFile(fs::path& path, std::function& SetResponseHeader) { try { SetResponseHeader("content_type", mime_type(path)); @@ -247,7 +300,7 @@ std::string weblog_plugin::generate_page( // Build the path to the requested file std::string doc_root{GetRequestParam("doc_root")}; - if (rel_target.size() >= 4 && std::for_each(rel_target.begin(), rel_target.begin() + 4, isdigit)) { + if (rel_target.size() >= 4 && std::all_of(rel_target.begin(), rel_target.begin() + 4, isdigit)) { rel_target = rel_target.substr(0, 4) + "/" + rel_target; } fs::path path {fs::path{doc_root} / rel_target}; @@ -265,8 +318,8 @@ std::string weblog_plugin::generate_page( if (is_article_page(rel_target, path)) return generateArticlePage(path, SetResponseHeader); - if (is_article_file(rel_target, path)) - return generateArticleFile(path, SetResponseHeader); + if (is_index_file(rel_target, path) || is_article_file(rel_target, path)) + return generateStaticFile(path, SetResponseHeader); return HttpStatus("404", "Bad path specification: "s + rel_target, SetResponseHeader); -- cgit v1.2.3