@ -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