use rocket::fairing::{self, AdHoc}; use rocket::fs::{relative, FileServer}; use rocket::http::Status; use rocket::State; use rocket::{Build, Request, Rocket}; use rocket_db_pools::sqlx; use rocket_db_pools::Database; use rocket_dyn_templates::{context, Template}; use std::borrow::Cow; mod posts; mod scrobbles; mod skweets; #[derive(Database)] #[database("blossom")] struct Blossom(sqlx::SqlitePool); async fn run_migrations(rocket: Rocket) -> fairing::Result { match Blossom::fetch(&rocket) { Some(db) => match sqlx::migrate!().run(&**db).await { Ok(_) => Ok(rocket), Err(e) => { error!("failed to init blossom database: {}", e); Err(rocket) } }, None => Err(rocket), } } fn stage() -> AdHoc { AdHoc::on_ignite("blossom database stage", |rocket| async { rocket .attach(Blossom::init()) .attach(AdHoc::try_on_ignite("database migrations", run_migrations)) }) } struct Clients { listenbrainz: listenbrainz::raw::Client, skinnyverse: mastodon_async::Mastodon, } #[macro_use] extern crate rocket; #[get("/")] async fn home(clients: &State) -> Result { Ok(Template::render( "home", context! { is_live: false, listenbrainz: scrobbles::get_now_playing(&clients.listenbrainz).await.unwrap_or_default(), skweets: skweets::get_recents(&clients.skinnyverse).await.unwrap_or_default() }, )) } #[get("/contact")] async fn contact() -> Template { Template::render("contact", context! {}) } #[get("/plants")] async fn plants() -> Result { Err(BlossomError::Unimplemented(Status::NotImplemented)) } #[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 }, ) } #[tokio::main] async fn main() -> Result<(), rocket::Error> { let mut skinny_data = mastodon_async::Data::default(); skinny_data.base = Cow::from("https://skinnyver.se"); let _rocket = rocket::build() .attach(stage()) .manage(Clients { listenbrainz: listenbrainz::raw::Client::new(), skinnyverse: mastodon_async::Mastodon::from(skinny_data), }) .attach(Template::custom(|engines| { engines.tera.autoescape_on(vec![]); })) .mount("/", routes![home, contact, plants]) .register("/", catchers![catcher]) .mount("/", FileServer::from(relative!("static"))) .launch() .await?; Ok(()) } mod error; use error::BlossomError;