diff options
| author | Roland Reichwein <mail@reichwein.it> | 2020-04-22 19:29:37 +0200 | 
|---|---|---|
| committer | Roland Reichwein <mail@reichwein.it> | 2020-04-22 19:29:37 +0200 | 
| commit | 1560d0efec6876ef8e820c5ec72bea6098f99870 (patch) | |
| tree | 0eff46f0e3ea201b087b34110cb21c10748a1105 /plugins | |
| parent | ef7ed9034bebe80a429112930ab0481c8aa66c95 (diff) | |
weblog (wip)
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/weblog/weblog.cpp | 73 | 
1 files changed, 63 insertions, 10 deletions
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 <boost/algorithm/string/predicate.hpp> +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/xml_parser.hpp>  #include <algorithm>  #include <filesystem> @@ -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<ArticleInfo> 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<std::string>("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 = "<file>" + article.substr(pos0 + 2) + "</file>"; + +  article = plainText(article); + +  size_t pos1 {article.find(".")}; +   +  size_t num {std::min(static_cast<size_t>(1000), pos1) + 1}; + +  return article.substr(0, num); + } +   std::string generateIndexPage(fs::path& path,                                 std::function<std::string(const std::string& key)>& GetRequestParam,                                 std::function<plugin_interface_setter_type>& SetResponseHeader)   {    try { -   std::string result{"<html><body><h1>"s + GetRequestParam("WEBLOG_NAME") + "</h1>"s}; +   std::string result{"<!DOCTYPE html><html><head><meta charset=\"utf-8\"/></head><body><h1>"s + GetRequestParam("WEBLOG_NAME") + "</h1>"s};     fs::path link{ GetRequestParam("rel_target")};     auto list{getArticleList(path)};     for (const auto& article: list) { -    result += "<h2><a href=\"" + (link / article.path.filename()).string() + "/\">"s + article.subject + "</a></h2>"s + article.date + "<br/>"s; +    std::string linkstart{"<a href=\"" + (link / article.path.filename()).string() + "/\">"}; +    std::string linkend{"</a>"}; +    result += "<h2>"s + linkstart + article.subject + linkend + "</h2>"s + article.date + "<br/>"s; +     +    auto sv{shortVersion(article.path)}; +    if (sv.size()) { +     result += sv + " "s + linkstart + "more..." + linkend; +    }     } +   result += "<br/><br/><br/>"; +   result += "<a href=\"impressum.html\">Impressum</a>";     result += "</body></html>";     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 { "<html><body><h1>"s + metaData.at("Subject") + "</h1>"s + metaData.at("Date") + "<br/><br/>"s + data.substr(pos + 2) + "</body></html>"s}; +   std::string result { "<!DOCTYPE html><html><head><meta charset=\"utf-8\"/></head><body><h1>"s + metaData.at("Subject") + "</h1>"s + metaData.at("Date") + "<br/><br/>"s + data.substr(pos + 2) + "</body></html>"s};     return result;    } catch (const std::exception& ex) { @@ -199,7 +252,7 @@ namespace {    }   } - std::string generateArticleFile(fs::path& path, std::function<plugin_interface_setter_type>& SetResponseHeader) + std::string generateStaticFile(fs::path& path, std::function<plugin_interface_setter_type>& 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);  | 
