Browse Source

rss and atom

master
alistair 3 years ago
parent
commit
b122dd37cf
  1. 181
      main.cpp

181
main.cpp

@ -765,20 +765,37 @@ class file_index_plugin : public substitution_plugin { @@ -765,20 +765,37 @@ class file_index_plugin : public substitution_plugin {
class feed_builder {
public:
enum feed_format {
ATOM,
RSS
};
private:
feed_format type = ATOM;
tinyxml2::XMLDocument feed;
tinyxml2::XMLElement *e_feed;
public:
feed_builder(const std::string &url, const std::string &title,
const std::vector<std::string> &author_names) {
const std::vector<std::string> &author_names,
feed_format type) : type(type) {
using namespace tinyxml2;
auto decl = feed.NewDeclaration();
feed.InsertFirstChild(decl);
e_feed = feed.NewElement("feed");
e_feed->SetAttribute("xmlns", "http://www.w3.org/2005/Atom");
feed.InsertEndChild(e_feed);
if (ATOM == type) {
e_feed = feed.NewElement("feed");
e_feed->SetAttribute("xmlns", "http://www.w3.org/2005/Atom");
feed.InsertEndChild(e_feed);
} else if (RSS == type) {
auto i_feed = feed.NewElement("rss");
i_feed->SetAttribute("version", 2.0);
feed.InsertEndChild(i_feed);
e_feed = i_feed->InsertNewChildElement("channel");
}
auto e_title = e_feed->InsertNewChildElement("title");
e_title->SetText(title.c_str());
@ -789,47 +806,80 @@ class feed_builder { @@ -789,47 +806,80 @@ class feed_builder {
std::string uurl = url;
e_link->SetAttribute("href", uurl.c_str());
auto e_updated = e_feed->InsertNewChildElement("updated");
/* shouldn't really be generation time: should be last modification time
* - might be nice to check the diff against the old feed, or only
* update when the site has been changed.
*/
auto timepoint = std::chrono::system_clock::now();
std::ostringstream ss;
date::to_stream(ss, "%FT%TZ", timepoint);
e_updated->SetText(ss.str().c_str());
if (ATOM == type) {
auto e_updated = e_feed->InsertNewChildElement("updated");
/* shouldn't really be generation time: should be last modification time
* - might be nice to check the diff against the old feed, or only
* update when the site has been changed.
*/
auto timepoint = std::chrono::system_clock::now();
std::ostringstream ss;
date::to_stream(ss, "%FT%TZ", timepoint);
e_updated->SetText(ss.str().c_str());
auto e_author = e_feed->InsertNewChildElement("author");
for (auto author: author_names) {
auto e_author_name = e_author->InsertNewChildElement("name");
e_author_name->SetText(author.c_str());
}
auto e_author = e_feed->InsertNewChildElement("author");
for (auto author: author_names) {
auto e_author_name = e_author->InsertNewChildElement("name");
e_author_name->SetText(author.c_str());
auto e_feed_id = e_feed->InsertNewChildElement("id");
e_feed_id->SetText(uurl.c_str());
} else if (RSS == type) {
auto e_updated = e_feed->InsertNewChildElement("pubDate");
/* shouldn't really be generation time: should be last modification time
* - might be nice to check the diff against the old feed, or only
* update when the site has been changed.
*/
auto timepoint = std::chrono::system_clock::now();
std::ostringstream ss;
date::to_stream(ss, "%a, %d %b %Y %T %Z", timepoint);
e_updated->SetText(ss.str().c_str());
auto e_feed_id = e_feed->InsertNewChildElement("guid");
e_feed_id->SetText(uurl.c_str());
auto e_descr = e_feed->InsertNewChildElement("description");
e_descr->SetText(title.c_str());
}
auto e_feed_id = e_feed->InsertNewChildElement("id");
e_feed_id->SetText(uurl.c_str());
}
tinyxml2::XMLElement *add_article(std::string const &url, std::string const &title, time_t updated) {
auto article = e_feed->InsertNewChildElement("entry");
auto id = article->InsertNewChildElement("id");
id->SetText(url.c_str());
tinyxml2::XMLElement * article;
auto a_title = article->InsertNewChildElement("title");
a_title->SetText(title.c_str());
if (ATOM == type) {
article = e_feed->InsertNewChildElement("entry");
auto a_updated = article->InsertNewChildElement("updated");
auto id = article->InsertNewChildElement("id");
id->SetText(url.c_str());
auto timepoint = std::chrono::system_clock::from_time_t(updated);
std::ostringstream ss;
date::to_stream(ss, "%FT%TZ", timepoint);
auto a_title = article->InsertNewChildElement("title");
a_title->SetText(title.c_str());
auto a_updated = article->InsertNewChildElement("updated");
auto timepoint = std::chrono::system_clock::from_time_t(updated);
std::ostringstream ss;
date::to_stream(ss, "%FT%TZ", timepoint);
a_updated->SetText(ss.str().c_str());
auto link = article->InsertNewChildElement("link");
link->SetAttribute("rel", "alternate");
link->SetAttribute("href", url.c_str());
} else if (RSS == type) {
article = e_feed->InsertNewChildElement("item");
auto a_title = article->InsertNewChildElement("title");
a_title->SetText(title.c_str());
a_updated->SetText(ss.str().c_str());
auto link = article->InsertNewChildElement("link");
link->SetAttribute("rel", "alternate");
link->SetAttribute("href", url.c_str());
auto link = article->InsertNewChildElement("link");
link->SetAttribute("rel", "alternate");
link->SetAttribute("href", url.c_str());
}
return article;
}
@ -837,14 +887,25 @@ class feed_builder { @@ -837,14 +887,25 @@ class feed_builder {
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);
std::string key;
if (ATOM == type) {
key = "published";
auto timepoint = std::chrono::system_clock::from_time_t(published);
std::ostringstream ss;
date::to_stream(ss, "%FT%TZ", timepoint);
auto a_published = article->InsertNewChildElement(key.c_str());
a_published->SetText(ss.str().c_str());
} else if (RSS == type) {
key = "pubDate";
auto timepoint = std::chrono::system_clock::from_time_t(published);
std::ostringstream ss;
date::to_stream(ss, "%a, %d %b %Y %T %Z", timepoint);
auto a_published = article->InsertNewChildElement(key.c_str());
a_published->SetText(ss.str().c_str());
}
auto timepoint = std::chrono::system_clock::from_time_t(published);
std::ostringstream ss;
date::to_stream(ss, "%FT%TZ", timepoint);
auto a_published = article->InsertNewChildElement("published");
a_published->SetText(ss.str().c_str());
return article;
}
@ -857,20 +918,26 @@ class feed_builder { @@ -857,20 +918,26 @@ class feed_builder {
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());
if (ATOM == type) {
e_category->SetAttribute("term", category.c_str());
} else if (RSS == type) {
e_category->SetText(category.c_str());
}
return article;
}
tinyxml2::XMLElement *add_article(std::string const &url, std::string const &title, const std::string &category, time_t updated, time_t published, std::string content) {
auto article = add_article(url, title, updated, published);
auto e_category = article->InsertNewChildElement("category");
e_category->SetAttribute("term", category.c_str());
auto e_content = article->InsertNewChildElement("content");
e_content->SetText(content.c_str());
e_content->SetAttribute("type", "html");
auto article = add_article(url, title, category, updated, published);
if (ATOM == type) {
auto e_content = article->InsertNewChildElement("content");
e_content->SetText(content.c_str());
e_content->SetAttribute("type", "html");
} else if (RSS == type) {
auto e_content = article->InsertNewChildElement("description");
e_content->SetText(content.c_str());
e_content->SetAttribute("type", "html");
}
return article;
}
@ -945,12 +1012,20 @@ class rss_feed_plugin : public s2_substitution_plugin { @@ -945,12 +1012,20 @@ class rss_feed_plugin : public s2_substitution_plugin {
const std::map<std::string, std::string> &properties, const std::map<fs::path, blog_item> & pages) override {
auto args = get_arguments(invocation, 1);
std::string relpath = args.at(1);
auto args = get_arguments(invocation, 2);
std::string type = args.at(1);
std::string relpath = args.at(2);
feed_builder::feed_format format;
if (type == "rss") {
format = feed_builder::feed_format::RSS;
} else if (type == "atom") {
format = feed_builder::feed_format::ATOM;
}
auto feed_items = get_sorted_post_list(relpath, properties, pages);
feed_builder f {compute_url(properties.at("current_file"), properties), properties.at("name"), {properties.at("author")}};
feed_builder f {compute_url(properties.at("current_file"), properties), properties.at("name"), {properties.at("author")}, format};
for (auto entry = feed_items.rbegin(); entry != feed_items.rend(); entry++) {
@ -1001,7 +1076,7 @@ class microblog_plugin : public s2_substitution_plugin { @@ -1001,7 +1076,7 @@ class microblog_plugin : public s2_substitution_plugin {
std::string text = "";
feed_builder f {compute_url(properties.at("current_file"), properties), properties.at("name"), {properties.at("author")}};
// feed_builder f {compute_url(properties.at("current_file"), properties), properties.at("name"), {properties.at("author")}};
for (auto entry = feed_items.rbegin(); entry != feed_items.rend(); entry++) {
// write into rss feed

Loading…
Cancel
Save