From e16a6540bdbe09d54677caae65e16598c1da2538 Mon Sep 17 00:00:00 2001 From: Harishankar Date: Fri, 22 May 2020 17:07:12 +0530 Subject: [PATCH] Added RSS feed to each category Added RSS feed to each category in the document tree --- biawebdocumenttree.hpp | 35 +++++++++++- biawebrss.hpp | 115 ++++++++++++++++++++++++++++++++++++++ biawebstrings.hpp | 6 ++ biawebtemplate.hpp | 9 ++- templates/rss.tpl.xml | 11 ++++ templates/rssitem.tpl.xml | 9 +++ templates/stringbits.txt | 4 +- 7 files changed, 183 insertions(+), 6 deletions(-) create mode 100644 biawebrss.hpp create mode 100644 templates/rss.tpl.xml create mode 100644 templates/rssitem.tpl.xml diff --git a/biawebdocumenttree.hpp b/biawebdocumenttree.hpp index 70471f3..447a5c7 100644 --- a/biawebdocumenttree.hpp +++ b/biawebdocumenttree.hpp @@ -12,6 +12,7 @@ #include "biawebutil.hpp" #include "biawebdoclist.hpp" #include "biawebtemplate.hpp" +#include "biawebrss.hpp" // class to implement a document tree - both with or without subtrees namespace biaweb { @@ -196,8 +197,7 @@ namespace biaweb { item1.set_item_url (this->stub_hierarchy() + "index.html"); bar1.get()->add_sidebar_item (item1); } - index.get()->add_side_bar (*bar1.get()); - + // create a sidebar for the child levels if there are children std::unique_ptr bar2 (new SideBar ()); bar2.get()->set_title (tpl->get_stringbit (SUB_CAT) + this->title); @@ -209,7 +209,6 @@ namespace biaweb { tree.stub + "/" + "index.html"); bar2.get()->add_sidebar_item (item); } - index.get()->add_side_bar (*bar2.get()); // create the path and then the index file std::filesystem::create_directories (filepath); @@ -235,7 +234,20 @@ namespace biaweb { par1 = par1->parent; } + // rss feed + std::unique_ptr feed (new RSSFeed ()); + feed.get()->set_pub_date (index.get()->get_creation_date()); + + // iterate through the documents and generate the document for (Document doc : this->docs) { + // Add the document to RSS feed + RSSFeedItem fitem (doc.get_title(), doc.get_meta_desc (), + urlpath + doc.get_filename() + ".html", + doc.get_creation_date()); + // If the items don't exceed max size of RSS feed + if (feed.get()->get_num_items() <= MAX_RSS_FEED) + feed.get()->add_rss_item (fitem); + // Add the document to the document list DocListItem item (doc.get_title(), urlpath + doc.get_filename() + ".html", doc.get_creation_date(), doc.get_modified_date (), @@ -249,6 +261,23 @@ namespace biaweb { doc.output_to_html (tpl, filepath); } + // output the rss feed + feed.get()->output_to_html (tpl, filepath); + + // add the side bars + index.get()->add_side_bar (*bar1.get()); + index.get()->add_side_bar (*bar2.get()); + + // sidebar for RSS feed + // if there are are items in the feed add the link + if (feed.get()->get_num_items () > 0) { + std::unique_ptr bar3 (new SideBar ()); + bar3.get()->set_title (tpl->get_stringbit (SUBSCRIBE)); + bar3.get()->add_sidebar_item ( + GenericLinkItem (tpl->get_stringbit(RSS_FEED), urlpath + "/feed.xml")); + index.get()->add_side_bar (*bar3.get()); + } + // add the navigation bit index.get()->set_navigation_bit (*navbit.get()); // index should contain the summary followed by the article list diff --git a/biawebrss.hpp b/biawebrss.hpp new file mode 100644 index 0000000..eb4d0aa --- /dev/null +++ b/biawebrss.hpp @@ -0,0 +1,115 @@ +#ifndef __BIAWEBRSSFEED__ +#define __BIAWEBRSSFEED__ + +#include "biawebutil.hpp" +#include "biawebtemplate.hpp" +#include +#include +#include "fmt/format.h" + +namespace biaweb { + // class to define and implement an RSS feed item + class RSSFeedItem { + protected: + std::string title; + std::string description; + std::string url; + std::time_t pub_date; + public: + // Main Constructor + RSSFeedItem (std::string title, std::string desc, + std::string url, std::time_t pub) { + this->title = escape_html (title); + this->description = escape_html (desc); + this->url = url; + this->pub_date = pub; + } + + // generate HTML using specified template + std::string to_html (Template *t); + + std::string get_title() { + return this->title; + } + void set_title(std::string title) { + this->title = escape_html (title); + } + std::string get_description() { + return this->description; + } + void set_description(std::string description) { + this->description = escape_html (description); + } + std::string get_url() { + return this->url; + } + void set_url(std::string url) { + this->url = url; + } + std::time_t get_pub_date() { + return this->pub_date; + } + void set_pub_date(std::time_t pub_date) { + this->pub_date = pub_date; + } + }; + std::string RSSFeedItem::to_html (Template *t) { + std::string item_tpl = t->get_rss_item_tpl (); + + std::tm ct = *std::localtime (&this->pub_date); + + std::string output = fmt::format (item_tpl, + fmt::arg ("title", this->title), + fmt::arg ("description", this->description), + fmt::arg ("url", this->url), + fmt::arg ("pubdate", ct)); + return output; + } + + // class to implement an RSS feed + class RSSFeed { + protected: + std::time_t pub_date; + std::list items; + public: + // add a feed item + void add_rss_item (RSSFeedItem item) { + this->items.insert (items.cend(), item); + } + + // number of items + std::size_t get_num_items () { + return this->items.size (); + } + + std::time_t get_pub_date() { + return this->pub_date; + } + void set_pub_date(std::time_t pub_date) { + this->pub_date = pub_date; + } + + // output the RSS feed file as feed.xml + void output_to_html (Template *t, std::string path) { + std::string templ_str = t->get_rss_tpl (); + // only if there are feed items, output the feed.xml file + if (this->items.size () != 0) { + std::string items_str ; + // get the items + for (auto item : this->items) + items_str += item.to_html (t); + + std::tm ct = *std::localtime (&this->pub_date); + + std::string output = fmt::format (templ_str, + fmt::arg ("pubdate", ct), + fmt::arg ("items", items_str) ); + std::ofstream f (path + "/feed.xml"); + f << output; + f.close (); + } + } + }; +} + +#endif \ No newline at end of file diff --git a/biawebstrings.hpp b/biawebstrings.hpp index a421ee2..fb79a6a 100644 --- a/biawebstrings.hpp +++ b/biawebstrings.hpp @@ -17,6 +17,9 @@ namespace biaweb { \t - directory containing the templates\n \ NOTE: directory argument need not terminate with the separator (/)"; + // MAXIMUM SIZE OF RSS FEED + const unsigned int MAX_RSS_FEED = 10; + // NAMED INDEX FOR DOCUMENT STRING BITS (LOADED FROM TEMPLATE FILE stringbits.txt) const unsigned int HOME = 0; const unsigned int ARTICLES_LIST = 1; @@ -24,6 +27,9 @@ NOTE: directory argument need not terminate with the separator (/)"; const unsigned int NAVIGATION = 3; const unsigned int SUB_CAT = 4; const unsigned int GO_UP = 5; + const unsigned int SUBSCRIBE = 6; + const unsigned int RSS_FEED = 7; + } #endif diff --git a/biawebtemplate.hpp b/biawebtemplate.hpp index 604cb26..8dd39df 100644 --- a/biawebtemplate.hpp +++ b/biawebtemplate.hpp @@ -19,7 +19,9 @@ namespace biaweb { std::string navigationbit_tpl; std::string sidebar_tpl; std::string style_tpl; - std::array stringbits; + std::string rss_tpl; + std::string rss_item_tpl; + std::array stringbits; public: // constructor: generate the template bits from a template directory Template (std::string templatedir) ; @@ -34,6 +36,8 @@ namespace biaweb { std::string get_sidebar_tpl () { return this->sidebar_tpl; } std::string get_style_tpl () { return this->style_tpl; } std::string get_stringbit (unsigned int id) { return this->stringbits[id]; } + std::string get_rss_tpl () { return this->rss_tpl; } + std::string get_rss_item_tpl () { return this->rss_item_tpl; } }; // construct a template from a source directory @@ -48,7 +52,8 @@ namespace biaweb { this->navigationbit_tpl = load_from_file (templatedir + "/navigationbit.tpl.html"); this->sidebar_tpl = load_from_file (templatedir + "/sidebar.tpl.html"); this->style_tpl = load_from_file (templatedir + "/style.tpl.css"); - + this->rss_tpl = load_from_file (templatedir + "/rss.tpl.xml"); + this->rss_item_tpl = load_from_file (templatedir + "/rssitem.tpl.xml"); // read the stringbits into the array std::ifstream f (templatedir + "/stringbits.txt"); diff --git a/templates/rss.tpl.xml b/templates/rss.tpl.xml new file mode 100644 index 0000000..d3d49ed --- /dev/null +++ b/templates/rss.tpl.xml @@ -0,0 +1,11 @@ + + + + + My Site + Site Description + http://my.site + {pubdate:%a, %d %b %Y %H:%M:%S %z} + {items} + + \ No newline at end of file diff --git a/templates/rssitem.tpl.xml b/templates/rssitem.tpl.xml new file mode 100644 index 0000000..b7bdfa1 --- /dev/null +++ b/templates/rssitem.tpl.xml @@ -0,0 +1,9 @@ + + {title} + {description} + + + http://my.site/{url} + http://my.site/{url} + {pubdate:%a, %d %b %Y %H:%M:%S %z} + \ No newline at end of file diff --git a/templates/stringbits.txt b/templates/stringbits.txt index 70341af..774a7e0 100644 --- a/templates/stringbits.txt +++ b/templates/stringbits.txt @@ -3,4 +3,6 @@ List of Articles Index Page Navigation Sub categories: -Go up \ No newline at end of file +Go up +Subscribe +RSS Feed \ No newline at end of file -- 2.20.1