diff options
author | cel 🌸 <cel@blos.sm> | 2024-01-30 16:16:05 +0000 |
---|---|---|
committer | cel 🌸 <cel@blos.sm> | 2024-01-30 16:16:05 +0000 |
commit | f00159f53b3774601500ec65345791311ff6efa1 (patch) | |
tree | cc65a487e71a056126e1935108a494c7851863f9 /src/main.rs | |
parent | 8c03d9a53f4bc2f70fb5c1e0487bc74fe0137fcb (diff) | |
download | blossom-f00159f53b3774601500ec65345791311ff6efa1.tar.gz blossom-f00159f53b3774601500ec65345791311ff6efa1.tar.bz2 blossom-f00159f53b3774601500ec65345791311ff6efa1.zip |
migrate to poem and askama
Diffstat (limited to '')
-rw-r--r-- | src/main.rs | 212 |
1 files changed, 98 insertions, 114 deletions
diff --git a/src/main.rs b/src/main.rs index ed768b4..c38b2eb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,155 +1,139 @@ +mod atom; +mod blog; mod error; mod live; mod posts; mod scrobbles; mod skweets; - -use std::borrow::Cow; -use std::collections::HashSet; -use std::time::Duration; - -use atom_syndication::Feed; -use rocket::fs::{relative, FileServer}; -use rocket::http::{ContentType, Status}; -use rocket::{Request, State}; -use rocket_dyn_templates::{context, Template}; +mod templates; +mod utils; + +use std::rc::Rc; +use std::{collections::HashSet, time::Duration}; + +use poem::http::StatusCode; +use poem::Response; +use poem::{ + endpoint::EmbeddedFilesEndpoint, + get, handler, + listener::TcpListener, + middleware::AddData, + web::{Data, Path, Query}, + EndpointExt, Route, Server, +}; +use rust_embed::RustEmbed; use error::BlossomError; +use serde::Deserialize; type Result<T> = std::result::Result<T, BlossomError>; -struct Clients { - listenbrainz: listenbrainz::raw::Client, - skinnyverse: mastodon_async::Mastodon, - reqwest: reqwest::Client, -} - -#[macro_use] -extern crate rocket; +#[derive(RustEmbed)] +#[folder = "static/"] +struct Static; -#[get("/")] -async fn home(clients: &State<Clients>) -> Template { +#[handler] +async fn home(Data(reqwest): Data<&reqwest::Client>) -> templates::Home { + let listenbrainz_client = listenbrainz::raw::Client::new(); let (live, listenbrainz, blogposts) = tokio::join!( - live::get_live_status(&clients.reqwest), - scrobbles::get_now_playing(&clients.listenbrainz), + live::get_live_status(reqwest), + scrobbles::get_now_playing(&listenbrainz_client), // skweets::get_recents(&clients.skinnyverse), - posts::get_blogposts() + blog::get_blogposts() ); let is_live = live.unwrap_or_default().online; let listenbrainz = listenbrainz.unwrap_or_default(); let blogposts = blogposts.unwrap_or_default(); - Template::render( - "home", - context! { - is_live, - listenbrainz, - // skweets, - blogposts, - }, - ) + templates::Home { + is_live, + listenbrainz, + blogposts, + } +} + +// #[get("/blog/<blogpost>")] +#[handler] +async fn blogpost(Path(blogpost): Path<String>) -> Result<templates::Blogpost> { + let blogpost = blog::get_blogpost(&blogpost).await?; + Ok(templates::Blogpost { + blogpost, + filter_tags: HashSet::new(), + }) } -#[get("/blog/<blogpost>")] -async fn blogpost(blogpost: &str) -> Result<Template> { - let mut blogpost = posts::get_blogpost(blogpost).await?; - blogpost.render().await?; - Ok(Template::render( - "blogpost", - context! { - blogpost, - }, - )) +#[derive(Deserialize)] +struct FilterTags { + filter: String, } -#[get("/blog?<filter>")] -async fn blog(filter: Vec<String>) -> Result<Template> { - let mut blogposts = posts::get_blogposts().await?; - let tags: Vec<String> = posts::get_tags(&blogposts) +// #[get("/blog?<filter>")] +#[handler] +async fn get_blog(filter_tags: Option<Query<FilterTags>>) -> Result<templates::Blog> { + let mut blogposts = blog::get_blogposts().await?; + let tags: Vec<String> = posts::Post::get_tags(&blogposts) .into_iter() .map(|tag| tag.to_owned()) .collect(); let mut filter_hashset: HashSet<String> = HashSet::new(); - if !filter.is_empty() { - filter_hashset.extend(filter.into_iter()); - blogposts = posts::filter_by_tags(blogposts, &filter_hashset); - } - for blogpost in &mut blogposts { - blogpost.render().await?; + if let Some(Query(FilterTags { filter })) = filter_tags { + filter_hashset.insert(filter); + blogposts = posts::Post::filter_by_tags(blogposts, &filter_hashset); } - let reverse = true; - Ok(Template::render( - "blog", - context! { - reverse, - tags, - filter_hashset, - blogposts, - }, - )) + Ok(templates::Blog { + blogposts, + tags, + filter_tags: filter_hashset, + }) } -#[get("/feed")] -async fn feed() -> Result<(Status, (ContentType, String))> { - let posts = posts::get_blogposts().await?; - let feed = posts::syndication::atom(posts).await; +#[handler] +async fn feed() -> Result<Response> { + let posts = blog::get_blogposts().await?; + // TODO: i18n + let context = atom::Context { + page_title: "celeste's hard drive".to_owned(), + page_url: "https://en.blos.sm".to_owned(), + self_url: "https://en.blos.sm/feed".to_owned(), + lang: "en".to_owned(), + }; + let feed = atom::atom(context, 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")] -async fn contact() -> Template { - Template::render("contact", context! {}) + Ok(Response::builder() + .status(StatusCode::OK) + .content_type("application/atom+xml") + .body(feed)) } -#[get("/plants")] -async fn plants() -> Result<Template> { - Err(BlossomError::Unimplemented(Status::NotImplemented)) +#[handler] +async fn contact() -> templates::Contact { + templates::Contact } -#[catch(default)] -fn catcher(status: Status, req: &Request) -> Template { - let message; - if status.code == 404 { - message = "i either haven't built this page yet or it looks like you're a little lost"; - } else if status.code == 500 { - message = "omg the server went kaputt!!"; - } else if status.code == 501 { - message = "it looks like this is not yet here!!!"; - } else { - message = "idk i got bored"; - } - let status = format!("{}", status); - Template::render( - "error", - context! { status: status, req: req.uri(), message: message }, - ) +#[handler] +async fn plants() -> Result<()> { + Err(BlossomError::Unimplemented) } #[tokio::main] -async fn main() -> std::result::Result<(), rocket::Error> { - let mut skinny_data = mastodon_async::Data::default(); - skinny_data.base = Cow::from("https://skinnyver.se"); - - let _rocket = rocket::build() - .manage(Clients { - listenbrainz: listenbrainz::raw::Client::new(), - skinnyverse: mastodon_async::Mastodon::from(skinny_data), - reqwest: reqwest::Client::builder() +async fn main() -> std::result::Result<(), std::io::Error> { + // let mut skinny_data = mastodon_async::Data::default(); + // skinny_data.base = Cow::from("https://skinnyver.se"); + let blossom = Route::new() + .at("/", get(home)) + .at("/blog", get(get_blog)) + .at("/blog/:blogpost", get(blogpost)) + .at("/feed", get(feed)) + .at("/contact", get(contact)) + .at("/plants", get(plants)) + .nest("/static/", EmbeddedFilesEndpoint::<Static>::new()) + .with(AddData::new( + reqwest::Client::builder() .connect_timeout(Duration::from_secs(1)) .build() .unwrap(), - }) - .attach(Template::custom(|engines| { - engines.tera.autoescape_on(vec![]); - })) - .mount("/", routes![home, contact, blog, blogpost, feed, plants]) - .register("/", catchers![catcher]) - .mount("/", FileServer::from("./static")) - .launch() - .await?; + )); - Ok(()) + Server::new(TcpListener::bind("0.0.0.0:3000")) + .run(blossom) + .await } |