aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
blob: 8ad4bf4efa79709b08ea77fb48a34cacd8dbcdd3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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::{self, database};
use rocket_db_pools::{Connection, Database};
use rocket_dyn_templates::{context, Template};
use std::borrow::Cow;

mod scrobbles;
mod skweets;

#[derive(Database)]
#[database("blossom")]
struct Blossom(sqlx::SqlitePool);

async fn run_migrations(rocket: Rocket<Build>) -> 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<Clients>) -> Result<Template, BlossomError> {
    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<Template, BlossomError> {
    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;