summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-04-22 19:29:37 +0200
committerRoland Reichwein <mail@reichwein.it>2020-04-22 19:29:37 +0200
commit1560d0efec6876ef8e820c5ec72bea6098f99870 (patch)
tree0eff46f0e3ea201b087b34110cb21c10748a1105
parentef7ed9034bebe80a429112930ab0481c8aa66c95 (diff)
weblog (wip)
-rw-r--r--plugins/weblog/weblog.cpp73
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);