From 4bec6679a8af2a2b5cb53610a80dece3b6d30bb4 Mon Sep 17 00:00:00 2001 From: alyx Date: Thu, 10 Aug 2023 03:10:54 -0400 Subject: lots of stuff. theming basically done, added some logging, frontend basically done. --- src/ctx.rs | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 src/ctx.rs (limited to 'src/ctx.rs') diff --git a/src/ctx.rs b/src/ctx.rs new file mode 100644 index 0000000..6beb634 --- /dev/null +++ b/src/ctx.rs @@ -0,0 +1,122 @@ +use reqwest::StatusCode; +use super::deserialize as de; +use std::sync::Arc; + +pub mod model { + use std::sync::Arc; + + /// The theme representation of a user. + #[derive(serde::Serialize, Debug)] + pub struct User { + /// Their username. + pub name: Arc, + /// Their "Display Name". + pub realname: Arc, + + /// True if user subscribes to last.fm pro. + pub pro_subscriber: bool, + /// Total scrobbles. + pub scrobble_count: u64, + /// Number of artists in library. + pub artist_count: u64, + /// Number of tracks in library. + pub track_count: u64, + /// Number of albums in library. + pub album_count: u64, + + /// Link to user's profile picture. + pub image_url: Arc, + + /// Link to user's profile. + pub url: Arc + } + + /// The theme representation of an artist + #[derive(serde::Serialize, Debug)] + pub struct Artist { + /// The artist's name. + pub name: Arc, + + /// A link to their current image. + pub image_url: Arc, + /// A link to their last.fm page. + pub url: Arc + } + + /// The theme representation of a user's most recently scrobbled track. + #[derive(serde::Serialize, Debug)] + pub struct Scrobble { + /// The name of the track. + pub name: Arc, + /// The name of its album. + pub album: Arc, + /// The artist who made it. + pub artist: Artist, + + /// A link to the track image. + pub image_url: Arc, + /// True if the user is currently scrobbling it, false if it's just the most recently played track. + pub now_playing: bool, + /// A link to the track's last.fm page. + pub url: Arc, + + /// True if the user has loved the track. + pub loved: bool + } + + /// The context passed in to all themes. + /// + /// Serialized as untagged, so themes should check if `error` is set and decide whether to show an error state or try rendering user info. + #[derive(serde::Serialize, Debug)] + #[serde(untagged)] + pub enum Data { + /// Contains text explaining a potential error. + Error { error: &'static str }, + /// Contains data about a user and what they're listening to. + Data { user: User, scrobble: Scrobble } + } +} +#[derive(Debug)] +pub struct ResponseCtx(pub model::Data, pub StatusCode); + +impl From, (StatusCode, &'static str)>> for ResponseCtx { + fn from(v: Result, (StatusCode, &'static str)>) -> ResponseCtx { + match v { + Ok(a) => { + let (user, track) = a.as_ref(); + ResponseCtx(model::Data::Data { + user: model::User { + name: user.name.clone(), + realname: user.realname.clone(), + + pro_subscriber: user.subscriber, + scrobble_count: user.playcount, + artist_count: user.artist_count, + track_count: user.track_count, + album_count: user.track_count, + + image_url: user.images.iter().max_by(|a, b| a.size.cmp(&b.size)).map(|a| a.url.clone()).unwrap_or_else(|| "".into()), + + url: user.url.clone() + }, + scrobble: model::Scrobble { + name: track.name.clone(), + album: track.album.name.clone(), + artist: model::Artist { + name: track.artist.name.clone(), + image_url: track.artist.images.iter().max_by(|a, b| a.size.cmp(&b.size)).map(|a| a.url.clone()).unwrap_or_else(|| "".into()), + url: track.artist.url.clone().unwrap_or_else(|| "".into()) + }, + image_url: track.images.iter().max_by(|a, b| a.size.cmp(&b.size)).map(|a| a.url.clone()).unwrap_or_else(|| "".into()), + now_playing: track.attr.nowplaying, + url: track.url.clone(), + loved: track.loved.unwrap_or(false) + } + }, StatusCode::OK) + }, + Err((status, error)) => { + ResponseCtx(model::Data::Error {error}, status) + } + } + } +} -- cgit v1.2.3-54-g00ecf