From 8761b57f80432f53f820aece1260ede6e805e6ac Mon Sep 17 00:00:00 2001 From: Gabriel Simmer Date: Fri, 22 Sep 2023 11:31:49 +0100 Subject: [PATCH] Add /rss endpoint --- Cargo.lock | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 3 +- src/main.rs | 55 ++++++++++++++++++++++ 3 files changed, 189 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index b759296..4ed68a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -199,6 +199,19 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atom_syndication" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "571832dcff775e26562e8e6930cd483de5587301d40d3a3b85d532b6383e15a7" +dependencies = [ + "chrono", + "derive_builder", + "diligent-date-parser", + "never", + "quick-xml", +] + [[package]] name = "atty" version = "0.2.14" @@ -377,6 +390,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "num-traits", +] + [[package]] name = "clap" version = "2.34.0" @@ -543,6 +565,41 @@ dependencies = [ "typenum", ] +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + [[package]] name = "der" version = "0.7.8" @@ -554,6 +611,37 @@ dependencies = [ "zeroize", ] +[[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 = "dhall" version = "0.12.0" @@ -603,6 +691,15 @@ dependencies = [ "subtle", ] +[[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 = "doc-comment" version = "0.3.3" @@ -1086,6 +1183,12 @@ dependencies = [ "tokio-native-tls", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.4.0" @@ -1371,6 +1474,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" @@ -1749,6 +1858,7 @@ dependencies = [ "lazy_static 1.4.0", "maud", "orgize", + "rss", "serde", "serde_dhall", "sha2", @@ -1758,6 +1868,16 @@ dependencies = [ "tower-http", ] +[[package]] +name = "quick-xml" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" +dependencies = [ + "encoding_rs", + "memchr", +] + [[package]] name = "quote" version = "1.0.32" @@ -1902,6 +2022,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rss" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e6c0ea0e621c2a3aa34850ebd711526f0ac7385921f57d2430a47cecc7b9cbc" +dependencies = [ + "atom_syndication", + "derive_builder", + "never", + "quick-xml", +] + [[package]] name = "rustc-demangle" version = "0.1.23" diff --git a/Cargo.toml b/Cargo.toml index 4f93e41..c7e5010 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,4 +23,5 @@ orgize = { git = "https://git.gmem.ca/arch/orgize.git", branch = "org-images" } clap = { version = "4.0", features = ["derive"] } serde_dhall = "0.12.1" frontmatter = "0.4.0" -file-format = "0.18.0" \ No newline at end of file +file-format = "0.18.0" +rss = "2.0.6" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 22dca5e..03112f6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,6 +27,7 @@ use std::str::FromStr; use std::time::{SystemTime, UNIX_EPOCH}; use tokio::sync::Mutex; use tower_http::services::ServeDir; +use rss::ChannelBuilder; lazy_static! { static ref CACHE: Mutex> = Mutex::new(HashMap::new()); @@ -107,6 +108,7 @@ async fn main() -> Result<(), sqlx::Error> { let app = Router::new() .route("/", get(homepage)) + .route("/rss", get(rss)) .route("/blog", get(list_blog_posts)) .route("/blog/:post", get(blog_post)) .nest_service("/assets", ServeDir::new("assets")) @@ -123,6 +125,59 @@ async fn main() -> Result<(), sqlx::Error> { Ok(()) } +async fn rss() -> Result { + let mut posts: Vec = Vec::new(); + for entry in fs::read_dir("./posts").unwrap() { + let entry = entry.unwrap(); + let path = entry.path(); + let filename = path.file_name().unwrap().to_str().unwrap(); + let ext = path.extension().unwrap().to_str().unwrap(); + + // strip extension + let fname = filename.replace(&format!(".{}", ext), ""); + if ext == "md" || ext == "org" { + // We'll have the date at the beginning of the file + let mut content = File::open(&path).unwrap(); + let mut buffer = [0; 100]; + content.read(&mut buffer).unwrap(); + // Match date data of `date: YYYY-MM-DD` in the first 100 bytes + let metadata = String::from_utf8_lossy(&buffer); + let metadata_lines = metadata.split("\n").collect::>(); + // dbg!(&metadata); + // Split by --- and get the second element + let date = metadata_lines + .iter() + .find(|&x| x.contains("date:")) + .unwrap_or(&"") + .split(":") + .collect::>()[1]; + let title = metadata_lines + .iter() + .find(|&x| x.contains("title:")) + .unwrap_or(&"") + .split(":") + .collect::>()[1]; + let date = date.trim(); + dbg!(&date); + let item = rss::ItemBuilder::default() + .title(Some(title.to_owned())) + .link(Some(format!("https://gabrielsimmer.com/blog/{}", fname))) + .pub_date(Some(date.to_owned())) + .build(); + + posts.push(item); + } + } + let channel = ChannelBuilder::default() + .title("Gabriel Simmer's Blog".to_owned()) + .link("https://gabrielsimmer.com/blog".to_owned()) + .description("Gabriel Simmer's Blog Posts.".to_owned()) + .items(posts) + .build(); + + return Ok(channel.to_string()); +} + fn header(page_title: &str) -> Markup { html! { (DOCTYPE)