RSS feed
This commit is contained in:
parent
c9704a20f6
commit
2d548e83ba
@ -12,6 +12,7 @@ axum = "0.7.3"
|
|||||||
chrono = { version = "0.4.31", features = ["serde"] }
|
chrono = { version = "0.4.31", features = ["serde"] }
|
||||||
gray_matter = "0.2.6"
|
gray_matter = "0.2.6"
|
||||||
markdown = "1.0.0-alpha.16"
|
markdown = "1.0.0-alpha.16"
|
||||||
|
rss = "2.0.7"
|
||||||
serde = "1.0.195"
|
serde = "1.0.195"
|
||||||
serde_json = "1.0.111"
|
serde_json = "1.0.111"
|
||||||
tokio = { version = "1.35.1", features = ["full"] }
|
tokio = { version = "1.35.1", features = ["full"] }
|
||||||
|
50
axum_server/src/feed.rs
Normal file
50
axum_server/src/feed.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use axum::http::{header, StatusCode};
|
||||||
|
use axum::response::IntoResponse;
|
||||||
|
use chrono::Utc;
|
||||||
|
use rss::{ChannelBuilder, GuidBuilder, Item, ItemBuilder};
|
||||||
|
|
||||||
|
use crate::{pages::post::PostMetadata, post_list::get_post_list};
|
||||||
|
|
||||||
|
pub async fn render_rss_feed() -> Result<impl IntoResponse, StatusCode> {
|
||||||
|
let mut post_list = get_post_list::<PostMetadata>().await.unwrap_or(vec![]);
|
||||||
|
post_list.sort_by_key(|post| post.metadata.date);
|
||||||
|
post_list.reverse();
|
||||||
|
|
||||||
|
let last_build_date = Utc::now().to_rfc2822();
|
||||||
|
let publish_date = post_list.last().map_or_else(
|
||||||
|
|| last_build_date.clone(),
|
||||||
|
|post| post.metadata.date.to_rfc2822(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let post_items = post_list
|
||||||
|
.into_iter()
|
||||||
|
.map(|post| {
|
||||||
|
ItemBuilder::default()
|
||||||
|
.title(Some(post.metadata.title))
|
||||||
|
.link(Some(format!("https://michalvanko.dev/blog/{}", post.slug)))
|
||||||
|
// TODO Description should be just a preview
|
||||||
|
.description(None)
|
||||||
|
.guid(Some(
|
||||||
|
GuidBuilder::default()
|
||||||
|
.value(format!("https://michalvanko.dev/blog/{}", post.slug))
|
||||||
|
.build(),
|
||||||
|
))
|
||||||
|
.pub_date(Some(post.metadata.date.to_rfc2822()))
|
||||||
|
.build()
|
||||||
|
})
|
||||||
|
.collect::<Vec<Item>>();
|
||||||
|
|
||||||
|
let feed_builder = ChannelBuilder::default()
|
||||||
|
.title("michalvanko.dev latest posts".to_string())
|
||||||
|
.link("https://michalvanko.dev".to_string())
|
||||||
|
.description("Latest posts published on michalvanko.dev blog site".to_string())
|
||||||
|
.language(Some("en".to_string()))
|
||||||
|
.webmaster(Some("michalvankosk@gmail.com".to_string()))
|
||||||
|
.pub_date(Some(publish_date))
|
||||||
|
.last_build_date(Some(last_build_date))
|
||||||
|
.items(post_items)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let response = feed_builder.to_string();
|
||||||
|
return Ok(([(header::CONTENT_TYPE, "application/xml")], response));
|
||||||
|
}
|
@ -2,6 +2,7 @@ use axum;
|
|||||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||||
|
|
||||||
mod components;
|
mod components;
|
||||||
|
mod feed;
|
||||||
mod pages;
|
mod pages;
|
||||||
mod post_list;
|
mod post_list;
|
||||||
mod post_parser;
|
mod post_parser;
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
use crate::pages::{index::render_index, post::render_post, post_list::render_post_list};
|
use crate::{
|
||||||
|
feed::render_rss_feed,
|
||||||
|
pages::{index::render_index, post::render_post, post_list::render_post_list},
|
||||||
|
};
|
||||||
use axum::{extract::MatchedPath, http::Request, routing::get, Router};
|
use axum::{extract::MatchedPath, http::Request, routing::get, Router};
|
||||||
use tower_http::trace::TraceLayer;
|
use tower_http::trace::TraceLayer;
|
||||||
use tracing::info_span;
|
use tracing::info_span;
|
||||||
@ -9,6 +12,7 @@ pub fn get_router() -> Router {
|
|||||||
.route("/blog", get(render_post_list))
|
.route("/blog", get(render_post_list))
|
||||||
.route("/blog/tags/:tag", get(render_post_list))
|
.route("/blog/tags/:tag", get(render_post_list))
|
||||||
.route("/blog/:post_id", get(render_post))
|
.route("/blog/:post_id", get(render_post))
|
||||||
|
.route("/feed.xml", get(render_rss_feed))
|
||||||
.layer(
|
.layer(
|
||||||
TraceLayer::new_for_http().make_span_with(|request: &Request<_>| {
|
TraceLayer::new_for_http().make_span_with(|request: &Request<_>| {
|
||||||
// Log the matched route's path (with placeholders not filled in).
|
// Log the matched route's path (with placeholders not filled in).
|
||||||
|
Loading…
Reference in New Issue
Block a user