refactor rust into separate files and add proper error handling
This commit is contained in:
		
							parent
							
								
									fce07d2749
								
							
						
					
					
						commit
						b8bbceb00b
					
				| 
						 | 
				
			
			@ -1 +1,2 @@
 | 
			
		|||
/target
 | 
			
		||||
*~
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
use rocket::Responder;
 | 
			
		||||
 | 
			
		||||
#[derive(Responder, Debug)]
 | 
			
		||||
pub enum BlossomError {
 | 
			
		||||
    #[response(status = 500)]
 | 
			
		||||
    Reqwest(&'static str, #[response(ignore)] reqwest::Error),
 | 
			
		||||
    #[response(status = 500)]
 | 
			
		||||
    ListenBrainz(&'static str, #[response(ignore)] listenbrainz::Error),
 | 
			
		||||
    #[response(status = 500)]
 | 
			
		||||
    Skinnyverse(&'static str, #[response(ignore)] mastodon_async::Error),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl From<reqwest::Error> for BlossomError {
 | 
			
		||||
    fn from(e: reqwest::Error) -> Self {
 | 
			
		||||
        BlossomError::Reqwest("reqwest error", e)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl From<listenbrainz::Error> for BlossomError {
 | 
			
		||||
    fn from(e: listenbrainz::Error) -> Self {
 | 
			
		||||
        BlossomError::ListenBrainz("listenbrainz error", e)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl From<mastodon_async::Error> for BlossomError {
 | 
			
		||||
    fn from(e: mastodon_async::Error) -> Self {
 | 
			
		||||
        BlossomError::Skinnyverse("skinnyverse error", e)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										115
									
								
								src/main.rs
								
								
								
								
							
							
						
						
									
										115
									
								
								src/main.rs
								
								
								
								
							| 
						 | 
				
			
			@ -1,82 +1,27 @@
 | 
			
		|||
use std::borrow::Cow;
 | 
			
		||||
 | 
			
		||||
use listenbrainz::raw::response::UserPlayingNowResponse;
 | 
			
		||||
use mastodon_async::{Data, Mastodon};
 | 
			
		||||
use rocket::fs::{relative, FileServer};
 | 
			
		||||
use rocket::http::Status;
 | 
			
		||||
use rocket::response::Responder;
 | 
			
		||||
use rocket::Request;
 | 
			
		||||
use rocket::State;
 | 
			
		||||
use rocket_dyn_templates::{context, Template};
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
use std::borrow::Cow;
 | 
			
		||||
 | 
			
		||||
mod scrobbles;
 | 
			
		||||
mod skweets;
 | 
			
		||||
 | 
			
		||||
struct Clients {
 | 
			
		||||
    listenbrainz: listenbrainz::raw::Client,
 | 
			
		||||
    skinnyverse: mastodon_async::Mastodon,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[macro_use]
 | 
			
		||||
extern crate rocket;
 | 
			
		||||
 | 
			
		||||
#[derive(Serialize, Deserialize)]
 | 
			
		||||
struct ScrobbleData {
 | 
			
		||||
    is_scrobbling: bool,
 | 
			
		||||
    song: Option<String>,
 | 
			
		||||
    artist: Option<String>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl ScrobbleData {
 | 
			
		||||
    fn new(playingnow: UserPlayingNowResponse) -> Self {
 | 
			
		||||
        let is_scrobbling = playingnow.payload.count > 0;
 | 
			
		||||
        if is_scrobbling {
 | 
			
		||||
            Self {
 | 
			
		||||
                is_scrobbling,
 | 
			
		||||
                song: Some(
 | 
			
		||||
                    playingnow
 | 
			
		||||
                        .payload
 | 
			
		||||
                        .listens
 | 
			
		||||
                        .first()
 | 
			
		||||
                        .unwrap()
 | 
			
		||||
                        .track_metadata
 | 
			
		||||
                        .track_name
 | 
			
		||||
                        .clone(),
 | 
			
		||||
                ),
 | 
			
		||||
                artist: Some(
 | 
			
		||||
                    playingnow
 | 
			
		||||
                        .payload
 | 
			
		||||
                        .listens
 | 
			
		||||
                        .first()
 | 
			
		||||
                        .unwrap()
 | 
			
		||||
                        .track_metadata
 | 
			
		||||
                        .artist_name
 | 
			
		||||
                        .clone(),
 | 
			
		||||
                ),
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            Self {
 | 
			
		||||
                is_scrobbling,
 | 
			
		||||
                song: None,
 | 
			
		||||
                artist: None,
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[get("/")]
 | 
			
		||||
async fn home() -> Template {
 | 
			
		||||
    let listenbrainz = listenbrainz::raw::Client::new();
 | 
			
		||||
    let playingnow = listenbrainz.user_playing_now("celblossom").unwrap();
 | 
			
		||||
    let listenbrainz_data = ScrobbleData::new(playingnow);
 | 
			
		||||
 | 
			
		||||
    let mut skinny_data = Data::default();
 | 
			
		||||
    skinny_data.base = Cow::from("https://skinnyver.se");
 | 
			
		||||
    let skinny_client = Mastodon::from(skinny_data);
 | 
			
		||||
    let mut skweets = skinny_client
 | 
			
		||||
        .statuses("cel", Default::default())
 | 
			
		||||
        .await
 | 
			
		||||
        .unwrap()
 | 
			
		||||
        .initial_items;
 | 
			
		||||
 | 
			
		||||
    skweets.truncate(6);
 | 
			
		||||
 | 
			
		||||
    Template::render(
 | 
			
		||||
async fn home(clients: &State<Clients>) -> Result<Template, BlossomError> {
 | 
			
		||||
    Ok(Template::render(
 | 
			
		||||
        "home",
 | 
			
		||||
        context! { is_live: false, listenbrainz: listenbrainz_data, skweets: skweets },
 | 
			
		||||
    )
 | 
			
		||||
        context! { is_live: false, listenbrainz: scrobbles::get_now_playing(&clients.listenbrainz).await?, skweets: skweets::get_recents(&clients.skinnyverse).await? },
 | 
			
		||||
    ))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[get("/contact")]
 | 
			
		||||
| 
						 | 
				
			
			@ -89,16 +34,8 @@ async fn plants() -> Result<Template, BlossomError> {
 | 
			
		|||
    todo!()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// #[get("/test")]
 | 
			
		||||
// async fn test() -> Result<Template, BlossomError> {
 | 
			
		||||
//     let posts = reqwest::get("https://skinnyver.se/api/v1/accounts/cel/statuses")
 | 
			
		||||
//         .await?
 | 
			
		||||
//         .json()
 | 
			
		||||
//         .await?;
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
#[catch(default)]
 | 
			
		||||
fn error(status: Status, req: &Request) -> Template {
 | 
			
		||||
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";
 | 
			
		||||
| 
						 | 
				
			
			@ -118,12 +55,19 @@ fn error(status: Status, req: &Request) -> Template {
 | 
			
		|||
 | 
			
		||||
#[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()
 | 
			
		||||
        .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])
 | 
			
		||||
        .register("/", catchers![error])
 | 
			
		||||
        .register("/", catchers![catcher])
 | 
			
		||||
        .mount("/", FileServer::from(relative!("static")))
 | 
			
		||||
        .launch()
 | 
			
		||||
        .await?;
 | 
			
		||||
| 
						 | 
				
			
			@ -131,14 +75,5 @@ async fn main() -> Result<(), rocket::Error> {
 | 
			
		|||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Responder)]
 | 
			
		||||
enum BlossomError {
 | 
			
		||||
    #[response(status = 500)]
 | 
			
		||||
    Reqwest(&'static str, #[response(ignore)] reqwest::Error),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl From<reqwest::Error> for BlossomError {
 | 
			
		||||
    fn from(e: reqwest::Error) -> Self {
 | 
			
		||||
        BlossomError::Reqwest("reqwest error", e)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
mod error;
 | 
			
		||||
use error::BlossomError;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,55 @@
 | 
			
		|||
use listenbrainz::raw::response::UserPlayingNowResponse;
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
 | 
			
		||||
use crate::error::BlossomError;
 | 
			
		||||
 | 
			
		||||
pub async fn get_now_playing(
 | 
			
		||||
    client: &listenbrainz::raw::Client,
 | 
			
		||||
) -> Result<NowPlayingData, BlossomError> {
 | 
			
		||||
    let playingnow = client.user_playing_now("celblossom")?;
 | 
			
		||||
    Ok(NowPlayingData::new(playingnow))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Serialize, Deserialize)]
 | 
			
		||||
pub struct NowPlayingData {
 | 
			
		||||
    pub is_scrobbling: bool,
 | 
			
		||||
    pub song: Option<String>,
 | 
			
		||||
    pub artist: Option<String>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl NowPlayingData {
 | 
			
		||||
    fn new(playingnow: UserPlayingNowResponse) -> Self {
 | 
			
		||||
        let is_scrobbling = playingnow.payload.count > 0;
 | 
			
		||||
        if is_scrobbling {
 | 
			
		||||
            Self {
 | 
			
		||||
                is_scrobbling,
 | 
			
		||||
                song: Some(
 | 
			
		||||
                    playingnow
 | 
			
		||||
                        .payload
 | 
			
		||||
                        .listens
 | 
			
		||||
                        .first()
 | 
			
		||||
                        .unwrap()
 | 
			
		||||
                        .track_metadata
 | 
			
		||||
                        .track_name
 | 
			
		||||
                        .clone(),
 | 
			
		||||
                ),
 | 
			
		||||
                artist: Some(
 | 
			
		||||
                    playingnow
 | 
			
		||||
                        .payload
 | 
			
		||||
                        .listens
 | 
			
		||||
                        .first()
 | 
			
		||||
                        .unwrap()
 | 
			
		||||
                        .track_metadata
 | 
			
		||||
                        .artist_name
 | 
			
		||||
                        .clone(),
 | 
			
		||||
                ),
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            Self {
 | 
			
		||||
                is_scrobbling,
 | 
			
		||||
                song: None,
 | 
			
		||||
                artist: None,
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,10 @@
 | 
			
		|||
use crate::error::BlossomError;
 | 
			
		||||
use mastodon_async::entities::status::Status;
 | 
			
		||||
use mastodon_async::prelude::*;
 | 
			
		||||
 | 
			
		||||
pub async fn get_recents(client: &Mastodon) -> Result<Vec<Status>, BlossomError> {
 | 
			
		||||
    Ok(client
 | 
			
		||||
        .statuses("cel", Default::default())
 | 
			
		||||
        .await?
 | 
			
		||||
        .initial_items)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -74,8 +74,7 @@
 | 
			
		|||
      <footer class="panel">
 | 
			
		||||
          <a class="badge" href="https://skinnyver.se"><img src="https://skinnyver.se/instance/skinnyversebadge.png"></a>
 | 
			
		||||
          <a class="badge" href="https://social.xenofem.me/"><img src="https://s3.eu-west-1.wasabisys.com/skinnyverse/4520d16b-565c-4956-b1f0-dd18afcdf906/xenofemme.png"></a>
 | 
			
		||||
          <a class="badge" href="https://asbestos.cafe"><img src="https://asbestos.cafe/instance/asbestoscafesisterinstance.png"></a>
 | 
			
		||||
          <a class="badge" href="https://worm.pink"><img src="https://worm.pink/instance/wormpinksistersite.png"></a>
 | 
			
		||||
          <a class="badge" href="https://arachnid.town"><img src="https://arachnid.town/media/e900cdf1adcd230b81fb7bb98c4279f5dfaa19ab18a54a0cbc8290a52bcd3ee7.png"></a>
 | 
			
		||||
      </footer>
 | 
			
		||||
      
 | 
			
		||||
    </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue