|
|
|
@ -13,6 +13,7 @@
@@ -13,6 +13,7 @@
|
|
|
|
|
#include <string_view> |
|
|
|
|
#include <type_traits> |
|
|
|
|
#include <ranges> |
|
|
|
|
#include <stack> |
|
|
|
|
|
|
|
|
|
#include <json.hpp> |
|
|
|
|
#include <date.h> |
|
|
|
@ -800,12 +801,9 @@ class feed_builder {
@@ -800,12 +801,9 @@ class feed_builder {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tinyxml2::XMLElement *add_article(std::string const &url, std::string const &title, time_t updated, time_t published, const std::string &full_content_html) { |
|
|
|
|
tinyxml2::XMLElement *add_article(std::string const &url, std::string const &title, time_t updated, time_t published) { |
|
|
|
|
auto article = add_article(url, title, updated); |
|
|
|
|
|
|
|
|
|
auto content = article->InsertNewChildElement("content"); |
|
|
|
|
content->SetText(full_content_html.c_str()); |
|
|
|
|
content->SetAttribute("type", "html"); |
|
|
|
|
|
|
|
|
|
auto timepoint = std::chrono::system_clock::from_time_t(published); |
|
|
|
|
std::ostringstream ss; |
|
|
|
@ -822,13 +820,25 @@ class feed_builder {
@@ -822,13 +820,25 @@ class feed_builder {
|
|
|
|
|
return std::string {p.CStr()}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
tinyxml2::XMLElement *add_article(std::string const &url, std::string const &title, const std::string &category, time_t updated, time_t published) { |
|
|
|
|
auto article = add_article(url, title, updated, published); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto e_category = article->InsertNewChildElement("category"); |
|
|
|
|
e_category->SetAttribute("term", category.c_str()); |
|
|
|
|
|
|
|
|
|
return article; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class rss_feed_plugin : public substitution_plugin { |
|
|
|
|
public: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline static const std::string hook_name = "feed"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int perform_substitution(int start, int end, const std::string &invocation, |
|
|
|
|
std::string &file_text,
|
|
|
|
|
const std::map<std::string, std::string> &properties) override { |
|
|
|
@ -837,21 +847,54 @@ class rss_feed_plugin : public substitution_plugin {
@@ -837,21 +847,54 @@ class rss_feed_plugin : public substitution_plugin {
|
|
|
|
|
auto args = get_arguments(invocation, 1); |
|
|
|
|
std::string relpath = args.at(1); |
|
|
|
|
|
|
|
|
|
fs::path path; |
|
|
|
|
if (relpath.at(0) == '/') { |
|
|
|
|
// path relative to site root
|
|
|
|
|
path = fs::path(properties.at("source_root")).append(relpath.substr(1)); |
|
|
|
|
} else { |
|
|
|
|
// path relative to current directory
|
|
|
|
|
path = fs::path(properties.at("current_directory")).append(relpath); |
|
|
|
|
std::vector<fs::path> paths; |
|
|
|
|
|
|
|
|
|
std::string::size_type first = 0; |
|
|
|
|
std::string::size_type next = relpath.find(","); |
|
|
|
|
if (next == std::string::npos)
|
|
|
|
|
next = relpath.length(); |
|
|
|
|
|
|
|
|
|
while (first != std::string::npos && next != std::string::npos) { |
|
|
|
|
|
|
|
|
|
std::string spath = relpath.substr(first, next - first); |
|
|
|
|
|
|
|
|
|
fs::path path; |
|
|
|
|
if (spath.at(0) == '/') { |
|
|
|
|
// path relative to site root
|
|
|
|
|
path = fs::path(properties.at("source_root")).append(spath.substr(1)); |
|
|
|
|
} else { |
|
|
|
|
// path relative to current directory
|
|
|
|
|
path = fs::path(properties.at("current_directory")).append(spath); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
paths.push_back(path); |
|
|
|
|
|
|
|
|
|
first = next + 1; |
|
|
|
|
next = relpath.find(",", first); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
file_index_plugin p {}; |
|
|
|
|
auto m = p.get_directory_list(path, properties); |
|
|
|
|
std::multimap<time_t, file_index_plugin::post_entry> entries; |
|
|
|
|
|
|
|
|
|
for (auto e : m) { |
|
|
|
|
entries.insert(e); |
|
|
|
|
for (auto path : paths) { |
|
|
|
|
spdlog::info("path {}", path.string()); |
|
|
|
|
auto m = p.get_directory_list(path, properties); |
|
|
|
|
|
|
|
|
|
std::stack<file_index_plugin::post_entry> s; |
|
|
|
|
|
|
|
|
|
for (auto e : m) { |
|
|
|
|
s.push(e.second); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
while (!s.empty()) { |
|
|
|
|
auto entry = s.top(); |
|
|
|
|
s.pop(); |
|
|
|
|
entries.insert({entry.date, entry}); |
|
|
|
|
|
|
|
|
|
for (auto sub_entry : entry.sub_directories) { |
|
|
|
|
s.push(sub_entry.second); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
feed_builder f {properties.at("url"), properties.at("name"), {properties.at("author")}}; |
|
|
|
@ -859,7 +902,8 @@ class rss_feed_plugin : public substitution_plugin {
@@ -859,7 +902,8 @@ class rss_feed_plugin : public substitution_plugin {
|
|
|
|
|
for (auto entry = entries.rbegin(); entry != entries.rend(); entry++) { |
|
|
|
|
// write into rss feed
|
|
|
|
|
if (!fs::is_directory(entry->second.path)) { |
|
|
|
|
f.add_article(compute_url(entry->second.path, properties), entry->second.title, entry->first); |
|
|
|
|
std::string category = entry->second.path.parent_path().filename().string(); |
|
|
|
|
f.add_article(compute_url(entry->second.path, properties), entry->second.title, category, entry->first, entry->first); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|