Skip to content

Instantly share code, notes, and snippets.

@mmstick
Last active June 1, 2017 04:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mmstick/b56ec00153daa1399bd166f041ac1dc1 to your computer and use it in GitHub Desktop.
Save mmstick/b56ec00153daa1399bd166f041ac1dc1 to your computer and use it in GitHub Desktop.
RSS Rocket Handlebar Example (Sort of...)
<?xml version="1.0"?>
<rss version="2.0">
<channel>
<title>{{page_title}}</title>
<link>{{page_link}}</link>
<description>{{page_desc}}</description>
<language>en-us</language>
<pubDate>{{page_date}}</pubDate>
<generator>Custom Web Server Written in Rust (RIIR)</generator>
<webMaster>mmstickman@gmail.com</webMaster>
{{#each articles}}<item>
<title>{{title}}</title>
<link>{{link}}</link>
<description>{{description}}</description>
<pubDate>{{date}}</pubDate>
<guid>{{link}}</guid>
</item>{{/each}}
</channel>
</rss>
use accept_encoding::AcceptEncoding;
use cacher::{Page, PageCache, CachedContent};
use chrono::{DateTime, UTC};
use database::DBConnection;
use std::error::Error;
use posts::index::get_summary;
use rocket::State;
use rocket_contrib::Template;
macro_rules! request_content {
($cache:ident, $url:ident, $encoding:ident, $closure:expr) => {
match $cache.request_content($url.clone(), $encoding) {
Ok(content) => Ok(content),
Err(action) => $cache.update_cache($url, action, $encoding, $closure)
}
}
}
#[derive(Serialize)]
pub struct RssArticle {
title: String,
link: String,
description: String,
date: String,
}
#[derive(Serialize)]
struct RssFeed {
page_title: String,
page_link: String,
page_desc: String,
page_date: String,
articles: Vec<RssArticle>
}
impl RssFeed {
pub fn new <I: Iterator<Item = RssArticle>> (
title: String,
link: String,
description: String,
articles: I
) -> RssFeed {
RssFeed {
page_title: title,
page_link: link,
page_desc: description,
page_date: UTC::now().to_rfc2822(),
articles: articles.collect::<Vec<RssArticle>>()
}
}
}
const RSS_INDEX: &'static str = r#"SELECT
title, uuid, content, time_published
FROM posts ORDER BY time_published DESC LIMIT $1 OFFSET $2"#;
#[get("/rss")]
pub fn main_rss (
cache: State<PageCache>,
db: DBConnection,
encoding: AcceptEncoding
) -> Result<CachedContent, String> {
let url = String::from("/rss");
// Request for a cached compressed copy, and if it doesn't exist, or the cached copy is too
// old, generate a new copy.
request_content!(cache, url, encoding, || {
// Perform a DB query to get the latest N elements.
let query = db.get().query(RSS_INDEX, &[&15i64, &0i64])
.map_err(|why| why.description().to_owned())?;
// Generate the context elements needed for the RSS handlebar template.
let feed = RssFeed::new (
// The title of the supplied contents.
"Michael Murphy's Personal Blog".into(),
// The URL where the contents are stored.
"https://mmstick.tk/".into(),
// A description of the page's contents.
"The latest posts on Michael's personal blog.".into(),
// Creates an iterator that generates `RssArticle`s from the database queries.
query.iter().map(|article| RssArticle {
title: article.get(0),
link: {
let link: String = article.get(1);
["https://mmstick.tk/post/", &link].concat()
},
description: {
let description: String = article.get(2);
match get_summary(&description) {
Ok(summary) => summary.to_owned(),
Err(why) => why.to_owned()
}
},
date: {
let date: DateTime<UTC> = article.get(3);
date.to_rfc2822()
}
})
);
// Generate the RSS XML from the template and convert it into a compressed page.
Ok(Page::new(Template::render("rss", &feed), encoding).into())
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment