aboutsummaryrefslogtreecommitdiff
path: root/src/content/blog/Blog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/content/blog/Blog.cpp')
-rw-r--r--src/content/blog/Blog.cpp138
1 files changed, 131 insertions, 7 deletions
diff --git a/src/content/blog/Blog.cpp b/src/content/blog/Blog.cpp
index b473bf3..1893cc5 100644
--- a/src/content/blog/Blog.cpp
+++ b/src/content/blog/Blog.cpp
@@ -1,11 +1,13 @@
#include "Blog.hpp"
+#include <filesystem>
+
Blog::Blog(std::string uriBasePath, std::string mainTemplatePath, std::string blogPath)
: Content(),
m_UriBasePath(uriBasePath),
m_MainTemplatePath(mainTemplatePath),
m_BlogPath(blogPath),
- m_BlogEntries("", blogPath)
+ m_BlogContents("", blogPath)
{
m_Redirections.push_back(uriBasePath + "/");
m_Redirections.push_back(uriBasePath + "/index.html");
@@ -13,25 +15,48 @@ Blog::Blog(std::string uriBasePath, std::string mainTemplatePath, std::string bl
bool Blog::Init()
{
- std::cout << "Blog entries path: " << m_BlogPath << std::endl;
+ bool retval = true;
+ std::cout << "Blog entries path: " << m_BlogPath << std::endl;
std::vector<std::string> extensions = {"json"};
- if (m_BlogEntriesMetadata.Scan(m_BlogPath, extensions, false) == false)
+ Filesystem fs;
+ if (fs.Scan(m_BlogPath, extensions, false) == false)
{
return false;
}
- m_BlogEntries.Init();
+ for (auto const & jfile : fs.GetFiles())
+ {
+ auto const json_metadata = inja::json::parse(jfile.second.data);
+ BlogEntry be =
+ std::make_shared<struct blog_entry>(jfile.first,
+ std::string(std::filesystem::path(jfile.first).stem()) + ".md");
+ if (Blog::ValidateAndSetMetdadata(json_metadata, be) == false)
+ {
+ std::cerr << "Blog Metadata validation failed." << std::endl;
+ retval = false;
+ }
+ m_BlogEntriesSortedByDate.push_back(be);
- return true;
+ m_Redirections.push_back(std::filesystem::path(jfile.first).stem());
+ }
+
+ m_BlogContents.Init();
+
+ if (retval == false)
+ {
+ return false;
+ }
+
+ return ValidateEntries();
}
void Blog::Shutdown()
{
std::cout << "Blog module shutdown" << std::endl;
- m_BlogEntries.Shutdown();
+ m_BlogContents.Shutdown();
}
bool Blog::Render(RequestResponse & rr, RenderData & rd, std::string & out)
@@ -40,7 +65,15 @@ bool Blog::Render(RequestResponse & rr, RenderData & rd, std::string & out)
(void)rd;
(void)out;
- rd["blah"] = "Yooooh!";
+ if (rr.GetUriPath() == m_UriBasePath || rr.GetUriPath() == m_UriBasePath + "/" ||
+ rr.GetUriPath() == m_UriBasePath + "/index.html")
+ {
+ GenerateBlogListing(rd["blog_listing"]);
+ }
+ else
+ {
+ rd["blog_content"] = "bla";
+ }
return true;
}
@@ -59,3 +92,94 @@ Redirections const & Blog::GetRedirections() const
{
return m_Redirections;
}
+
+bool Blog::ValidateAndSetMetdadata(BlogMetadata const & blogMetadata, BlogEntry & blogEntry)
+{
+ bool retval = true;
+ std::function<bool(BlogMetadata const &, std::string const)> validateMetadata =
+ [blogEntry](BlogMetadata const & bm, std::string const tname) {
+ if (bm.find(tname) == bm.cend())
+ {
+ std::cerr << "Metadata validation: JSON key '" << tname << "' missing in "
+ << blogEntry->metadata_filename << std::endl;
+ return false;
+ }
+ return true;
+ };
+ std::function<bool(std::string const &, std::time_t &)> parseDateTime = [](std::string const & timeStr,
+ std::time_t & time) {
+ std::tm tm = {};
+ std::stringstream ss(timeStr);
+ ss >> std::get_time(&tm, "%d.%m.%y %H:%M");
+ time = std::mktime(&tm);
+ if (time <= 0)
+ {
+ std::cerr << "Metadata validation: Invalid time string '" << timeStr
+ << "', format required: '%d.%m.%y %H:%M'" << std::endl;
+ return false;
+ }
+ return true;
+ };
+
+ if (validateMetadata(blogMetadata, "createDate") == false ||
+ parseDateTime(blogMetadata["createDate"], blogEntry->createDate) == false)
+ {
+ retval = false;
+ }
+
+ if (validateMetadata(blogMetadata, "publishDate") == false ||
+ parseDateTime(blogMetadata["publishDate"], blogEntry->publishDate) == false)
+ {
+ retval = false;
+ }
+
+ if (validateMetadata(blogMetadata, "published") == false)
+ {
+ retval = false;
+ }
+ blogEntry->published = blogMetadata["published"];
+
+ return retval;
+}
+
+bool Blog::ValidateEntries() const
+{
+ bool retval = true;
+
+ for (auto const & e : m_BlogEntriesSortedByDate)
+ {
+ if (m_BlogContents.HasMarkdownFile(e->content_filename) == false)
+ {
+ std::cerr << "Blog entry metadata " << e->metadata_filename << " exists, but markdown file "
+ << e->content_filename << " not." << std::endl;
+ retval = false;
+ }
+ }
+ for (auto const & m : m_BlogContents.GetMarkdowns())
+ {
+ if (std::any_of(m_BlogEntriesSortedByDate.cbegin(),
+ m_BlogEntriesSortedByDate.cend(),
+ [m](BlogEntry const & be) { return m.first == be->content_filename; }) == false)
+ {
+ std::cerr << "Blog entry markdown " << m.first << " exists, but metadata not." << std::endl;
+ retval = false;
+ }
+ }
+
+ return retval;
+}
+
+void Blog::GenerateBlogListing(RenderData & rd) const
+{
+ for (auto const & e : m_BlogEntriesSortedByDate)
+ {
+ RenderData re;
+ re["metadata_filename"] = e->metadata_filename;
+ re["content_filename"] = e->content_filename;
+ re["createDate"] = e->createDate;
+ re["publishDate"] = e->publishDate;
+ re["published"] = e->published;
+
+ rd += re;
+ }
+}