Last active
June 1, 2017 04:13
-
-
Save mmstick/b56ec00153daa1399bd166f041ac1dc1 to your computer and use it in GitHub Desktop.
RSS Rocket Handlebar Example (Sort of...)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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