From ab529917847641190f21129804bbda1784b4f998 Mon Sep 17 00:00:00 2001 From: cel 🌸 Date: Thu, 22 Jun 2023 21:37:10 +0100 Subject: implement atom syndication --- Cargo.lock | 117 ++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + TODO.md | 9 ++++ src/error.rs | 16 ++++++ src/main.rs | 16 +++++- src/posts/mod.rs | 1 + src/posts/syndication.rs | 96 +++++++++++++++++++++++++++++++++ static/atombadge.png | Bin 0 -> 4767 bytes static/atomfeed.gif | Bin 0 -> 199 bytes static/style.css | 8 +++ templates/base.html.tera | 3 +- templates/contact.html.tera | 3 +- templates/home.html.tera | 4 +- templates/latestposts.html.tera | 2 +- 14 files changed, 268 insertions(+), 8 deletions(-) create mode 100644 src/posts/syndication.rs create mode 100644 static/atombadge.png create mode 100644 static/atomfeed.gif diff --git a/Cargo.lock b/Cargo.lock index e65d4dd..bc79919 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -94,6 +94,19 @@ dependencies = [ "syn 2.0.18", ] +[[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 = "atomic" version = "0.5.1" @@ -437,6 +450,72 @@ dependencies = [ "syn 1.0.107", ] +[[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", + "syn 1.0.107", +] + +[[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.107", +] + +[[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.107", +] + +[[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.107", +] + [[package]] name = "derive_deref" version = "1.1.1" @@ -498,6 +577,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" @@ -972,6 +1060,12 @@ dependencies = [ "cxx-build", ] +[[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.3.0" @@ -1377,6 +1471,12 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "never" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96aba5aa877601bb3f6dd6a63a969e1f82e60646e81e71b14496995e9853c91" + [[package]] name = "normpath" version = "0.3.2" @@ -1749,6 +1849,16 @@ dependencies = [ "unicase", ] +[[package]] +name = "quick-xml" +version = "0.28.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce5e73202a820a31f8a0ee32ada5e21029c81fd9e3ebf668a40832e4219d9d1" +dependencies = [ + "encoding_rs", + "memchr", +] + [[package]] name = "quote" version = "1.0.28" @@ -2179,6 +2289,7 @@ name = "site" version = "0.1.0" dependencies = [ "async-trait", + "atom_syndication", "chrono", "chrono-humanize", "listenbrainz", @@ -2274,6 +2385,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "subtle" version = "2.4.1" diff --git a/Cargo.toml b/Cargo.toml index fbb29a8..edc28fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,3 +23,4 @@ markdown = "1.0.0-alpha.10" async-trait = "0.1.68" toml = "0.7.4" tokio-stream = { version = "0.1.14", features = ["fs"] } +atom_syndication = "0.12.1" diff --git a/TODO.md b/TODO.md index f0f2e32..2ad11d1 100644 --- a/TODO.md +++ b/TODO.md @@ -1,8 +1,17 @@ +# TODO: + [x] make sure posts are organised in date order +[x] atom feed [x] tags [ ] multiple tag UI +[ ] more badges +[ ] site translations [ ] comments [ ] clean up spaghetti +[ ] brush font PLZ +[ ] deploy database yum +[ ] visitor counter +[ ] guestbook badges to steal: [x] keith diff --git a/src/error.rs b/src/error.rs index eb6f6e6..42c01b1 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,3 +1,5 @@ +use std::string::FromUtf8Error; + use rocket::{http::Status, Responder}; #[derive(Responder, Debug)] @@ -8,6 +10,8 @@ pub enum BlossomError { Chrono(Status, #[response(ignore)] chrono::ParseError), Io(Status, #[response(ignore)] std::io::Error), Deserialization(Status, #[response(ignore)] toml::de::Error), + Syndicator(Status, #[response(ignore)] atom_syndication::Error), + Utf8Conversion(Status, #[response(ignore)] FromUtf8Error), NotFound(Status), NoMetadata(Status), Unimplemented(Status), @@ -48,3 +52,15 @@ impl From for BlossomError { BlossomError::Deserialization(Status::new(500), e) } } + +impl From for BlossomError { + fn from(e: atom_syndication::Error) -> Self { + BlossomError::Syndicator(Status::new(500), e) + } +} + +impl From for BlossomError { + fn from(e: FromUtf8Error) -> Self { + BlossomError::Utf8Conversion(Status::new(500), e) + } +} diff --git a/src/main.rs b/src/main.rs index 40f546d..844f3aa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,8 +7,9 @@ mod skweets; use std::borrow::Cow; use std::collections::HashSet; +use atom_syndication::Feed; use rocket::fs::{relative, FileServer}; -use rocket::http::Status; +use rocket::http::{ContentType, Status}; use rocket::{Request, State}; use rocket_dyn_templates::{context, Template}; @@ -87,6 +88,17 @@ async fn blog(filter: Vec) -> Result