diff options
Diffstat (limited to 'src/handlers/blog.rs')
| -rw-r--r-- | src/handlers/blog.rs | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/src/handlers/blog.rs b/src/handlers/blog.rs new file mode 100644 index 0000000..e494e04 --- /dev/null +++ b/src/handlers/blog.rs @@ -0,0 +1,77 @@ +use super::{PostNotFound, SeriesNotFound}; +use crate::{ + app::State, + post::Post, + templates::{self, Html, RenderRucte}, +}; +use lazy_static::lazy_static; +use prometheus::{IntCounterVec, register_int_counter_vec, opts}; +use std::sync::Arc; +use warp::{http::Response, Rejection, Reply}; + +lazy_static! { + static ref HIT_COUNTER: IntCounterVec = + register_int_counter_vec!(opts!("blogpost_hits", "Number of hits to blogposts"), &["name"]) + .unwrap(); +} + +pub async fn index(state: Arc<State>) -> Result<impl Reply, Rejection> { + let state = state.clone(); + Response::builder().html(|o| templates::blogindex_html(o, state.blog.clone())) +} + +pub async fn series(state: Arc<State>) -> Result<impl Reply, Rejection> { + let state = state.clone(); + let mut series: Vec<String> = vec![]; + + for post in &state.blog { + if post.front_matter.series.is_some() { + series.push(post.front_matter.series.as_ref().unwrap().clone()); + } + } + + series.sort(); + series.dedup(); + + Response::builder().html(|o| templates::series_html(o, series)) +} + +pub async fn series_view(series: String, state: Arc<State>) -> Result<impl Reply, Rejection> { + let state = state.clone(); + let mut posts: Vec<Post> = vec![]; + + for post in &state.blog { + if post.front_matter.series.is_none() { + continue; + } + if post.front_matter.series.as_ref().unwrap() != &series { + continue; + } + posts.push(post.clone()); + } + + if posts.len() == 0 { + Err(SeriesNotFound(series).into()) + } else { + Response::builder().html(|o| templates::series_posts_html(o, series, &posts)) + } +} + +pub async fn post_view(name: String, state: Arc<State>) -> Result<impl Reply, Rejection> { + let mut want: Option<Post> = None; + + for post in &state.blog { + if post.link == format!("blog/{}", name) { + want = Some(post.clone()); + } + } + + match want { + None => Err(PostNotFound("blog".into(), name).into()), + Some(post) => { + HIT_COUNTER.with_label_values(&[name.clone().as_str()]).inc(); + let body = Html(post.body_html.clone()); + Response::builder().html(|o| templates::blogpost_html(o, post, body)) + } + } +} |
