diff options
author | alyx <alyx@aleteoryx.me> | 2023-08-10 03:10:54 -0400 |
---|---|---|
committer | alyx <alyx@aleteoryx.me> | 2023-08-10 03:10:54 -0400 |
commit | 4bec6679a8af2a2b5cb53610a80dece3b6d30bb4 (patch) | |
tree | 686297ae76fbc05b4e6af04eaf66b1545e055e4a /src/ctx.rs | |
parent | 60f8bc89d2fb182906fbedb4d4dc39d87af7d8e5 (diff) | |
download | lfm_embed-4bec6679a8af2a2b5cb53610a80dece3b6d30bb4.tar.gz lfm_embed-4bec6679a8af2a2b5cb53610a80dece3b6d30bb4.tar.bz2 lfm_embed-4bec6679a8af2a2b5cb53610a80dece3b6d30bb4.zip |
lots of stuff. theming basically done, added some logging, frontend basically done.
Diffstat (limited to 'src/ctx.rs')
-rw-r--r-- | src/ctx.rs | 122 |
1 files changed, 122 insertions, 0 deletions
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<str>, + /// Their "Display Name". + pub realname: Arc<str>, + + /// 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<str>, + + /// Link to user's profile. + pub url: Arc<str> + } + + /// The theme representation of an artist + #[derive(serde::Serialize, Debug)] + pub struct Artist { + /// The artist's name. + pub name: Arc<str>, + + /// A link to their current image. + pub image_url: Arc<str>, + /// A link to their last.fm page. + pub url: Arc<str> + } + + /// 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<str>, + /// The name of its album. + pub album: Arc<str>, + /// The artist who made it. + pub artist: Artist, + + /// A link to the track image. + pub image_url: Arc<str>, + /// 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<str>, + + /// 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<Result<Arc<(de::User, de::Track)>, (StatusCode, &'static str)>> for ResponseCtx { + fn from(v: Result<Arc<(de::User, de::Track)>, (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) + } + } + } +} |