implement atom syndication
This commit is contained in:
		
							parent
							
								
									bc5ac494c6
								
							
						
					
					
						commit
						ab52991784
					
				| 
						 | 
					@ -94,6 +94,19 @@ dependencies = [
 | 
				
			||||||
 "syn 2.0.18",
 | 
					 "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]]
 | 
					[[package]]
 | 
				
			||||||
name = "atomic"
 | 
					name = "atomic"
 | 
				
			||||||
version = "0.5.1"
 | 
					version = "0.5.1"
 | 
				
			||||||
| 
						 | 
					@ -437,6 +450,72 @@ dependencies = [
 | 
				
			||||||
 "syn 1.0.107",
 | 
					 "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]]
 | 
					[[package]]
 | 
				
			||||||
name = "derive_deref"
 | 
					name = "derive_deref"
 | 
				
			||||||
version = "1.1.1"
 | 
					version = "1.1.1"
 | 
				
			||||||
| 
						 | 
					@ -498,6 +577,15 @@ dependencies = [
 | 
				
			||||||
 "subtle",
 | 
					 "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]]
 | 
					[[package]]
 | 
				
			||||||
name = "doc-comment"
 | 
					name = "doc-comment"
 | 
				
			||||||
version = "0.3.3"
 | 
					version = "0.3.3"
 | 
				
			||||||
| 
						 | 
					@ -972,6 +1060,12 @@ dependencies = [
 | 
				
			||||||
 "cxx-build",
 | 
					 "cxx-build",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "ident_case"
 | 
				
			||||||
 | 
					version = "1.0.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "idna"
 | 
					name = "idna"
 | 
				
			||||||
version = "0.3.0"
 | 
					version = "0.3.0"
 | 
				
			||||||
| 
						 | 
					@ -1377,6 +1471,12 @@ dependencies = [
 | 
				
			||||||
 "winapi 0.3.9",
 | 
					 "winapi 0.3.9",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "never"
 | 
				
			||||||
 | 
					version = "0.1.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "c96aba5aa877601bb3f6dd6a63a969e1f82e60646e81e71b14496995e9853c91"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "normpath"
 | 
					name = "normpath"
 | 
				
			||||||
version = "0.3.2"
 | 
					version = "0.3.2"
 | 
				
			||||||
| 
						 | 
					@ -1749,6 +1849,16 @@ dependencies = [
 | 
				
			||||||
 "unicase",
 | 
					 "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]]
 | 
					[[package]]
 | 
				
			||||||
name = "quote"
 | 
					name = "quote"
 | 
				
			||||||
version = "1.0.28"
 | 
					version = "1.0.28"
 | 
				
			||||||
| 
						 | 
					@ -2179,6 +2289,7 @@ name = "site"
 | 
				
			||||||
version = "0.1.0"
 | 
					version = "0.1.0"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "async-trait",
 | 
					 "async-trait",
 | 
				
			||||||
 | 
					 "atom_syndication",
 | 
				
			||||||
 "chrono",
 | 
					 "chrono",
 | 
				
			||||||
 "chrono-humanize",
 | 
					 "chrono-humanize",
 | 
				
			||||||
 "listenbrainz",
 | 
					 "listenbrainz",
 | 
				
			||||||
| 
						 | 
					@ -2274,6 +2385,12 @@ version = "1.1.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
 | 
					checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "strsim"
 | 
				
			||||||
 | 
					version = "0.10.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "subtle"
 | 
					name = "subtle"
 | 
				
			||||||
version = "2.4.1"
 | 
					version = "2.4.1"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,3 +23,4 @@ markdown = "1.0.0-alpha.10"
 | 
				
			||||||
async-trait = "0.1.68"
 | 
					async-trait = "0.1.68"
 | 
				
			||||||
toml = "0.7.4"
 | 
					toml = "0.7.4"
 | 
				
			||||||
tokio-stream = { version = "0.1.14", features = ["fs"] }
 | 
					tokio-stream = { version = "0.1.14", features = ["fs"] }
 | 
				
			||||||
 | 
					atom_syndication = "0.12.1"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										9
									
								
								TODO.md
								
								
								
								
							
							
						
						
									
										9
									
								
								TODO.md
								
								
								
								
							| 
						 | 
					@ -1,8 +1,17 @@
 | 
				
			||||||
 | 
					# TODO:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[x] make sure posts are organised in date order
 | 
					[x] make sure posts are organised in date order
 | 
				
			||||||
 | 
					[x] atom feed
 | 
				
			||||||
[x] tags
 | 
					[x] tags
 | 
				
			||||||
    [ ] multiple tag UI
 | 
					    [ ] multiple tag UI
 | 
				
			||||||
 | 
					[ ] more badges
 | 
				
			||||||
 | 
					[ ] site translations
 | 
				
			||||||
[ ] comments
 | 
					[ ] comments
 | 
				
			||||||
[ ] clean up spaghetti
 | 
					[ ] clean up spaghetti
 | 
				
			||||||
 | 
					[ ] brush font PLZ
 | 
				
			||||||
 | 
					[ ] deploy database yum
 | 
				
			||||||
 | 
					[ ] visitor counter
 | 
				
			||||||
 | 
					[ ] guestbook
 | 
				
			||||||
 | 
					
 | 
				
			||||||
badges to steal:
 | 
					badges to steal:
 | 
				
			||||||
[x] keith
 | 
					[x] keith
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										16
									
								
								src/error.rs
								
								
								
								
							
							
						
						
									
										16
									
								
								src/error.rs
								
								
								
								
							| 
						 | 
					@ -1,3 +1,5 @@
 | 
				
			||||||
 | 
					use std::string::FromUtf8Error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use rocket::{http::Status, Responder};
 | 
					use rocket::{http::Status, Responder};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Responder, Debug)]
 | 
					#[derive(Responder, Debug)]
 | 
				
			||||||
| 
						 | 
					@ -8,6 +10,8 @@ pub enum BlossomError {
 | 
				
			||||||
    Chrono(Status, #[response(ignore)] chrono::ParseError),
 | 
					    Chrono(Status, #[response(ignore)] chrono::ParseError),
 | 
				
			||||||
    Io(Status, #[response(ignore)] std::io::Error),
 | 
					    Io(Status, #[response(ignore)] std::io::Error),
 | 
				
			||||||
    Deserialization(Status, #[response(ignore)] toml::de::Error),
 | 
					    Deserialization(Status, #[response(ignore)] toml::de::Error),
 | 
				
			||||||
 | 
					    Syndicator(Status, #[response(ignore)] atom_syndication::Error),
 | 
				
			||||||
 | 
					    Utf8Conversion(Status, #[response(ignore)] FromUtf8Error),
 | 
				
			||||||
    NotFound(Status),
 | 
					    NotFound(Status),
 | 
				
			||||||
    NoMetadata(Status),
 | 
					    NoMetadata(Status),
 | 
				
			||||||
    Unimplemented(Status),
 | 
					    Unimplemented(Status),
 | 
				
			||||||
| 
						 | 
					@ -48,3 +52,15 @@ impl From<toml::de::Error> for BlossomError {
 | 
				
			||||||
        BlossomError::Deserialization(Status::new(500), e)
 | 
					        BlossomError::Deserialization(Status::new(500), e)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl From<atom_syndication::Error> for BlossomError {
 | 
				
			||||||
 | 
					    fn from(e: atom_syndication::Error) -> Self {
 | 
				
			||||||
 | 
					        BlossomError::Syndicator(Status::new(500), e)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl From<FromUtf8Error> for BlossomError {
 | 
				
			||||||
 | 
					    fn from(e: FromUtf8Error) -> Self {
 | 
				
			||||||
 | 
					        BlossomError::Utf8Conversion(Status::new(500), e)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										16
									
								
								src/main.rs
								
								
								
								
							
							
						
						
									
										16
									
								
								src/main.rs
								
								
								
								
							| 
						 | 
					@ -7,8 +7,9 @@ mod skweets;
 | 
				
			||||||
use std::borrow::Cow;
 | 
					use std::borrow::Cow;
 | 
				
			||||||
use std::collections::HashSet;
 | 
					use std::collections::HashSet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use atom_syndication::Feed;
 | 
				
			||||||
use rocket::fs::{relative, FileServer};
 | 
					use rocket::fs::{relative, FileServer};
 | 
				
			||||||
use rocket::http::Status;
 | 
					use rocket::http::{ContentType, Status};
 | 
				
			||||||
use rocket::{Request, State};
 | 
					use rocket::{Request, State};
 | 
				
			||||||
use rocket_dyn_templates::{context, Template};
 | 
					use rocket_dyn_templates::{context, Template};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,6 +88,17 @@ async fn blog(filter: Vec<String>) -> Result<Template> {
 | 
				
			||||||
    ))
 | 
					    ))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[get("/feed")]
 | 
				
			||||||
 | 
					async fn feed() -> Result<(Status, (ContentType, String))> {
 | 
				
			||||||
 | 
					    let posts = posts::get_blogposts().await?;
 | 
				
			||||||
 | 
					    let feed = posts::syndication::atom(posts).await;
 | 
				
			||||||
 | 
					    let feed: String = String::from_utf8(feed.write_to(Vec::new())?)?;
 | 
				
			||||||
 | 
					    Ok((
 | 
				
			||||||
 | 
					        Status::new(200),
 | 
				
			||||||
 | 
					        (ContentType::new("application", "atom+xml"), feed),
 | 
				
			||||||
 | 
					    ))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[get("/contact")]
 | 
					#[get("/contact")]
 | 
				
			||||||
async fn contact() -> Template {
 | 
					async fn contact() -> Template {
 | 
				
			||||||
    Template::render("contact", context! {})
 | 
					    Template::render("contact", context! {})
 | 
				
			||||||
| 
						 | 
					@ -130,7 +142,7 @@ async fn main() -> std::result::Result<(), rocket::Error> {
 | 
				
			||||||
        .attach(Template::custom(|engines| {
 | 
					        .attach(Template::custom(|engines| {
 | 
				
			||||||
            engines.tera.autoescape_on(vec![]);
 | 
					            engines.tera.autoescape_on(vec![]);
 | 
				
			||||||
        }))
 | 
					        }))
 | 
				
			||||||
        .mount("/", routes![home, contact, blog, blogpost, plants])
 | 
					        .mount("/", routes![home, contact, blog, blogpost, feed, plants])
 | 
				
			||||||
        .register("/", catchers![catcher])
 | 
					        .register("/", catchers![catcher])
 | 
				
			||||||
        .mount("/", FileServer::from(relative!("static")))
 | 
					        .mount("/", FileServer::from(relative!("static")))
 | 
				
			||||||
        .launch()
 | 
					        .launch()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
mod article;
 | 
					mod article;
 | 
				
			||||||
mod note;
 | 
					mod note;
 | 
				
			||||||
 | 
					pub mod syndication;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use std::collections::HashSet;
 | 
					use std::collections::HashSet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,96 @@
 | 
				
			||||||
 | 
					use atom_syndication::{Category, Content, Entry, Feed, Generator, Link, Person, Text, TextType};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use super::{Article, Post};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub async fn atom(posts: Vec<Post<Article>>) -> Feed {
 | 
				
			||||||
 | 
					    let me = Person {
 | 
				
			||||||
 | 
					        name: "cel".into(),
 | 
				
			||||||
 | 
					        email: Some("cel@blos.sm".into()),
 | 
				
			||||||
 | 
					        uri: Some("https://blos.sm".into()),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    let mut authors = Vec::new();
 | 
				
			||||||
 | 
					    authors.push(me);
 | 
				
			||||||
 | 
					    let link = Link {
 | 
				
			||||||
 | 
					        href: "https://blos.sm/feed".into(),
 | 
				
			||||||
 | 
					        rel: "self".into(),
 | 
				
			||||||
 | 
					        hreflang: Some("en".into()),
 | 
				
			||||||
 | 
					        mime_type: Some("application/atom+xml".into()),
 | 
				
			||||||
 | 
					        title: Some("atom feed".into()),
 | 
				
			||||||
 | 
					        length: None,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    let mut links = Vec::new();
 | 
				
			||||||
 | 
					    links.push(link);
 | 
				
			||||||
 | 
					    let mut feed = Feed {
 | 
				
			||||||
 | 
					        title: Text {
 | 
				
			||||||
 | 
					            value: "cel's site".into(),
 | 
				
			||||||
 | 
					            base: None,
 | 
				
			||||||
 | 
					            lang: Some("en".into()),
 | 
				
			||||||
 | 
					            r#type: TextType::Text,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        id: "https://blos.sm".into(),
 | 
				
			||||||
 | 
					        updated: posts[0].created_at.into(),
 | 
				
			||||||
 | 
					        authors: authors.clone(),
 | 
				
			||||||
 | 
					        categories: Vec::new(),
 | 
				
			||||||
 | 
					        contributors: authors.clone(),
 | 
				
			||||||
 | 
					        generator: Some(Generator {
 | 
				
			||||||
 | 
					            value: "blos.sm".into(),
 | 
				
			||||||
 | 
					            uri: Some("https://bunny.garden/cel/blos.sm".into()),
 | 
				
			||||||
 | 
					            version: None,
 | 
				
			||||||
 | 
					        }),
 | 
				
			||||||
 | 
					        icon: Some("/icon.png".into()),
 | 
				
			||||||
 | 
					        links: links.clone(),
 | 
				
			||||||
 | 
					        logo: Some("/logo.png".into()),
 | 
				
			||||||
 | 
					        rights: None,
 | 
				
			||||||
 | 
					        subtitle: None,
 | 
				
			||||||
 | 
					        entries: Vec::new(),
 | 
				
			||||||
 | 
					        base: Some("https://blos.sm".into()),
 | 
				
			||||||
 | 
					        lang: Some("en".into()),
 | 
				
			||||||
 | 
					        ..Default::default()
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    for mut post in posts {
 | 
				
			||||||
 | 
					        post.render().await.unwrap_or_default();
 | 
				
			||||||
 | 
					        let mut id = String::from("https://blos.sm/blog/");
 | 
				
			||||||
 | 
					        id.push_str(&post.data.name);
 | 
				
			||||||
 | 
					        let categories = post
 | 
				
			||||||
 | 
					            .tags
 | 
				
			||||||
 | 
					            .into_iter()
 | 
				
			||||||
 | 
					            .map(|tag| Category {
 | 
				
			||||||
 | 
					                term: tag.clone(),
 | 
				
			||||||
 | 
					                scheme: None,
 | 
				
			||||||
 | 
					                label: Some(tag.clone()),
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .collect();
 | 
				
			||||||
 | 
					        let entry = Entry {
 | 
				
			||||||
 | 
					            title: Text {
 | 
				
			||||||
 | 
					                value: post.subject.unwrap_or_default(),
 | 
				
			||||||
 | 
					                base: None,
 | 
				
			||||||
 | 
					                lang: Some("en".into()),
 | 
				
			||||||
 | 
					                r#type: TextType::Text,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            id: id.clone(),
 | 
				
			||||||
 | 
					            updated: if let Some(updated_at) = post.updated_at {
 | 
				
			||||||
 | 
					                updated_at.into()
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                post.created_at.into()
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            authors: authors.clone(),
 | 
				
			||||||
 | 
					            categories,
 | 
				
			||||||
 | 
					            contributors: authors.clone(),
 | 
				
			||||||
 | 
					            links: links.clone(),
 | 
				
			||||||
 | 
					            published: Some(post.created_at.into()),
 | 
				
			||||||
 | 
					            rights: None,
 | 
				
			||||||
 | 
					            source: None,
 | 
				
			||||||
 | 
					            summary: None,
 | 
				
			||||||
 | 
					            content: Some(Content {
 | 
				
			||||||
 | 
					                base: None,
 | 
				
			||||||
 | 
					                lang: Some("en".into()),
 | 
				
			||||||
 | 
					                value: post.render,
 | 
				
			||||||
 | 
					                src: Some(id),
 | 
				
			||||||
 | 
					                content_type: Some("html".to_string()),
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
 | 
					            ..Default::default()
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        feed.entries.push(entry);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    feed
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 4.7 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 199 B  | 
| 
						 | 
					@ -166,6 +166,14 @@ footer {
 | 
				
			||||||
  background-color: #0000;
 | 
					  background-color: #0000;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.small-badge,
 | 
				
			||||||
 | 
					.small-badge * {
 | 
				
			||||||
 | 
					  padding: 0;
 | 
				
			||||||
 | 
					  border: 0;
 | 
				
			||||||
 | 
					  margin: 0;
 | 
				
			||||||
 | 
					  font-size: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* homepage css */
 | 
					/* homepage css */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#title {
 | 
					#title {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,7 +40,7 @@
 | 
				
			||||||
          <li><a class="{% block nav_blog %}{% endblock %}" style="font-family: Sligoil" href="/blog">girlblog</a></li>
 | 
					          <li><a class="{% block nav_blog %}{% endblock %}" style="font-family: Sligoil" href="/blog">girlblog</a></li>
 | 
				
			||||||
          <li><a class="{% block nav_projects %}{% endblock %}" style="font-family: 'DeGerm LoCase';" href="/projects">projetos</a></li>
 | 
					          <li><a class="{% block nav_projects %}{% endblock %}" style="font-family: 'DeGerm LoCase';" href="/projects">projetos</a></li>
 | 
				
			||||||
          <li><a class="{% block nav_sound %}{% endblock %}" style="font-family: 'kirieji'" href="/sound">音</a></li>
 | 
					          <li><a class="{% block nav_sound %}{% endblock %}" style="font-family: 'kirieji'" href="/sound">音</a></li>
 | 
				
			||||||
          <li><a class="{% block nav_listens %}{% endblock %}" style="font-family: 'Almendra Display'; font-weight: 900;" href="https://listenbrainz.org/celblossom">écoute</a></li>
 | 
					          <li><a class="{% block nav_listens %}{% endblock %}" style="font-family: 'Almendra Display'; font-weight: 900;" href="https://listenbrainz.org/user/celblossom">écoute</a></li>
 | 
				
			||||||
          <li><a href="https://bimbo.video/a/cel" style="font-family: 'Mon Hugo In'">video</a></li>
 | 
					          <li><a href="https://bimbo.video/a/cel" style="font-family: 'Mon Hugo In'">video</a></li>
 | 
				
			||||||
          <li><a href="https://weirdstar.stream" style="font-family: id_kana018" >🔴ライブ</a></li>
 | 
					          <li><a href="https://weirdstar.stream" style="font-family: id_kana018" >🔴ライブ</a></li>
 | 
				
			||||||
          <li><a class="{% block nav_pix %}{% endblock %}" style="font-family: Minecraftia" href="/pix">pix</a></li>
 | 
					          <li><a class="{% block nav_pix %}{% endblock %}" style="font-family: Minecraftia" href="/pix">pix</a></li>
 | 
				
			||||||
| 
						 | 
					@ -70,6 +70,7 @@
 | 
				
			||||||
      </main>
 | 
					      </main>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      <footer class="panel">
 | 
					      <footer class="panel">
 | 
				
			||||||
 | 
					          <a class="badge" href="https://blos.sm"><img src="https://blos.sm/badges/cel.png"></a>
 | 
				
			||||||
          <a class="badge" href="https://skinnyver.se"><img src="https://skinnyver.se/instance/skinnyversebadge.png"></a>
 | 
					          <a class="badge" href="https://skinnyver.se"><img src="https://skinnyver.se/instance/skinnyversebadge.png"></a>
 | 
				
			||||||
          <img class="badge" src="/badges/mothracompat.gif">
 | 
					          <img class="badge" src="/badges/mothracompat.gif">
 | 
				
			||||||
          <img class="badge" src="/badges/flexbox.png">
 | 
					          <img class="badge" src="/badges/flexbox.png">
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,9 +15,8 @@
 | 
				
			||||||
<div class="content panel h-card" rel="author">
 | 
					<div class="content panel h-card" rel="author">
 | 
				
			||||||
  <h1 class="p-name">cel</h1>
 | 
					  <h1 class="p-name">cel</h1>
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
  <h3>pronouns: <a class="u-url" rel="me" href="https://en.pronouns.page/@celblossom"><span class="p-x-pronoun-nominative">she</span>/<span class="p-x-pronoun-accusative">her</span></a></h3>
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
  <ul>
 | 
					  <ul>
 | 
				
			||||||
 | 
					    <li><h3>pronouns: <span class="p-x-pronoun-nominative">she</span>/<span class="p-x-pronoun-accusative">her</span></h3></li>
 | 
				
			||||||
    <li>email: <a class="u-email" href="mailto:cel@blos.sm">cel@blos.sm</a> <a href="cel.asc" class="u-key" rel="pgpkey">pgp key</a></li>
 | 
					    <li>email: <a class="u-email" href="mailto:cel@blos.sm">cel@blos.sm</a> <a href="cel.asc" class="u-key" rel="pgpkey">pgp key</a></li>
 | 
				
			||||||
    <li>xmpp: <a class="u-impp" href="xmpp:cel@blos.sm?message">cel@blos.sm</a></li>
 | 
					    <li>xmpp: <a class="u-impp" href="xmpp:cel@blos.sm?message">cel@blos.sm</a></li>
 | 
				
			||||||
    <li>fedi: <a class="u-url" rel="me" href="https://skinnyver.se/cel">cel@skinnyver.se</a></li>
 | 
					    <li>fedi: <a class="u-url" rel="me" href="https://skinnyver.se/cel">cel@skinnyver.se</a></li>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,10 +30,10 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="panel content">
 | 
					<div class="panel content">
 | 
				
			||||||
  <h2>hallo i am celeste welcome 2 my site 🌟</h2>
 | 
					  <h2>hallo i am celeste welcome 2 my site 🌟</h2>
 | 
				
			||||||
  <p>this is where i dump everything</p>
 | 
					  <p>this is where i do the posting</p>
 | 
				
			||||||
  <p>i wish u a wonderful day</p>
 | 
					  <p>i wish u a wonderful day</p>
 | 
				
			||||||
  <br>
 | 
					  <br>
 | 
				
			||||||
  <img src="https://s3.eu-west-1.wasabisys.com/skinnyverse/f28c467a-0ee1-4d49-a638-08a010fd9927/quinntyping.png">
 | 
					  <img src="/quinntyping.png">
 | 
				
			||||||
  <p>perpetually under construction</p>
 | 
					  <p>perpetually under construction</p>
 | 
				
			||||||
  <img style="border: 0;" src="/barraconstruction.gif">
 | 
					  <img style="border: 0;" src="/barraconstruction.gif">
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
<div class="panel" id="posts">
 | 
					<div class="panel" id="posts">
 | 
				
			||||||
  <h2>latest posts <!--<a class="badge" href="/feed.xml"><img class="badge" src="/rssbadge.png" alt="rss newsfeed"></a>--></h2>
 | 
					  <h2>latest posts <a class="small-badge" href="/feed"><img class="small-badge" src="/atombadge.png" alt="atom newsfeed"></a></h2>
 | 
				
			||||||
  <table id="post-list">
 | 
					  <table id="post-list">
 | 
				
			||||||
    {% for blogpost in blogposts %}
 | 
					    {% for blogpost in blogposts %}
 | 
				
			||||||
    <tr>
 | 
					    <tr>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue