diff --git a/Cargo.lock b/Cargo.lock index cc1ff40..8daf43a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -355,6 +355,19 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ce4f10ea3abcd6617873bae9f91d1c5332b4a778bd9ce34d0cd517474c1de82" +[[package]] +name = "atom_syndication" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca96cb38e3d8236f1573a84bbc55e130bd1ae07df770e36d0cf221ea7a50e36c" +dependencies = [ + "chrono", + "derive_builder", + "diligent-date-parser", + "never", + "quick-xml", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -764,6 +777,37 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_builder" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder_macro" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" +dependencies = [ + "derive_builder_core", + "syn 1.0.109", +] + [[package]] name = "derive_more" version = "0.99.17" @@ -793,6 +837,15 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "diligent-date-parser" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6cf7fe294274a222363f84bcb63cdea762979a0443b4cf1f4f8fd17c86b1182" +dependencies = [ + "chrono", +] + [[package]] name = "dirs" version = "4.0.0" @@ -863,6 +916,7 @@ dependencies = [ "minify-js 0.5.6", "ramhorns", "reqwest", + "rss", "serde", "serde_yaml", "toml", @@ -1478,6 +1532,12 @@ dependencies = [ "tempfile", ] +[[package]] +name = "never" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96aba5aa877601bb3f6dd6a63a969e1f82e60646e81e71b14496995e9853c91" + [[package]] name = "nom" version = "7.1.3" @@ -1736,6 +1796,7 @@ version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce5e73202a820a31f8a0ee32ada5e21029c81fd9e3ebf668a40832e4219d9d1" dependencies = [ + "encoding_rs", "memchr", ] @@ -1894,6 +1955,18 @@ dependencies = [ "winreg", ] +[[package]] +name = "rss" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa1ec965a5f5ec71e16106b35df21861c4014ace848c6b75720816925552936d" +dependencies = [ + "atom_syndication", + "derive_builder", + "never", + "quick-xml", +] + [[package]] name = "rustc-hash" version = "1.1.0" diff --git a/Cargo.toml b/Cargo.toml index 877c0b1..9daef03 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,3 +23,4 @@ glob = "0.3.1" comrak = "0.18" reqwest = { version = "0.11", features = ["json"] } chrono = "0.4.24" +rss = "2.0.3" diff --git a/src/main.rs b/src/main.rs index f02c1e0..b20b71b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,6 +41,7 @@ async fn main() -> Result<()> { .service(portfolio::page) .service(contrib::page) .service(blog::index) + .service(blog::rss) .service(blog::page) .service(web3::page) .service(gaming::page) diff --git a/src/routes/blog.rs b/src/routes/blog.rs index 80b3c2b..c54f1f8 100644 --- a/src/routes/blog.rs +++ b/src/routes/blog.rs @@ -1,4 +1,5 @@ -use actix_web::{get, web, HttpResponse, Responder}; +use ::rss::{Category, Channel, Image}; +use actix_web::{dev::ConnectionInfo, get, web, HttpRequest, HttpResponse, Responder}; use cached::proc_macro::once; use chrono::{DateTime, Datelike, Utc}; use comrak::{parse_document, Arena}; @@ -152,3 +153,62 @@ fn get_post(post: &mut Option, filename: String) -> Infos { page_kw: Some(["blog", "blogging", "write", "writing"].join(", ")), } } + +#[get("/blog/rss")] +pub async fn rss(req: HttpRequest, config: web::Data) -> impl Responder { + HttpResponse::Ok().body(build_rss( + config.get_ref().to_owned(), + req.connection_info().to_owned(), + )) +} + +//#[once(time = 10800)] // 3h +fn build_rss(config: Config, info: ConnectionInfo) -> String { + let mut posts = get_posts("data/blog"); + + // Sort from newest to oldest + posts.sort_by_cached_key(|p| (p.date.year, p.date.month, p.date.day)); + posts.reverse(); + + // Only the 20 newest + let max = 20; + if posts.len() > max { + posts.drain(max..); + } + + let link_to_site = format!("{}://{}", info.scheme(), info.host()); + let channel = Channel { + title: "Blog d'Anri".into(), + link: link_to_site.to_owned(), + description: "Un fil qui parle d'infos".into(), + language: Some("fr".into()), + managing_editor: config.fc.mail.to_owned(), + webmaster: config.fc.mail, + pub_date: Some(chrono::Utc::now().to_rfc2822().replace("+0000", "GMT")), + categories: ["blog", "blogging", "write", "writing"] + .iter() + .map(|&c| Category { + name: c.into(), + ..Category::default() + }) + .collect(), + generator: Some("ewp with rss crate".into()), + docs: Some("https://www.rssboard.org/rss-specification".into()), + image: Some(Image { + url: format!( + "{}://{}/icons/favicon-32x32.png", + info.scheme(), + info.host() + ), + title: "Favicon".into(), + link: link_to_site, + ..Image::default() + }), + items: vec![], + ..Channel::default() + }; + + std::str::from_utf8(&channel.write_to(Vec::new()).unwrap()) + .unwrap() + .into() +}