~aleteoryx/lfm_embed

074c512ac422dbd86527b943b54e33200784b478 — alyx 5 months ago f548d2d
Fixed backend API, again.

Turns out track.getInfo just doesn't feel like serving image data anymore, even though the example response shows it. I love last.fm so much.
3 files changed, 25 insertions(+), 5 deletions(-)

M src/cache/user.rs
M src/ctx.rs
M src/deserialize.rs
M src/cache/user.rs => src/cache/user.rs +3 -0
@@ 35,6 35,7 @@ fn user_getter(username: &String) -> UserFuture {
    log::trace!("Got user.getUserInfo JSON for `{username}`: {userstr}");
    let userinfo = serde_json::from_str::<GetUserInfo>(&userstr)
      .map_err(|e| {log::error!("Couldn't parse user.getInfo for `{username}`: {e}"); (StatusCode::INTERNAL_SERVER_ERROR, "Couldn't parse user.getInfo!")})?.user;
    log::trace!("Parsed into: {userinfo:?}");

    let tracksreq = HTTP.get(format!("https://ws.audioscrobbler.com/2.0/?method=user.getRecentTracks&format=json&extended=1&limit=1&user={username}&api_key={}", CONFIG.lastfm_api_key))
      .send().await


@@ 47,6 48,7 @@ fn user_getter(username: &String) -> UserFuture {
    let trackstub = serde_json::from_str::<GetRecentTracks>(&tracksstr)
      .map_err(|e| {log::error!("Couldn't parse user.getRecentTracks for `{username}`: {e}"); (StatusCode::INTERNAL_SERVER_ERROR, "Couldn't parse user.getRecentTracks!")})?
      .recenttracks.track.into_iter().next().ok_or((StatusCode::UNPROCESSABLE_ENTITY, "You need to listen to some songs first!"))?;
    log::trace!("Parsed into: {trackstub:?}");

    let trackreq = HTTP.get(format!("https://ws.audioscrobbler.com/2.0/?method=track.getInfo&format=json&username={username}&api_key={}&track={}&artist={}", CONFIG.lastfm_api_key, trackstub.name, trackstub.artist.name))
      .send().await


@@ 57,6 59,7 @@ fn user_getter(username: &String) -> UserFuture {
    log::trace!("Got track.getInfo JSON for `{username}`: {trackstr}");
    let trackinfo = serde_json::from_str::<GetTrackInfo>(&trackstr)
      .map_err(|e| {log::error!("Couldn't parse track.getInfo for `{}` by `{}` on behalf of {username}: {e}", trackstub.name, trackstub.artist.name); (StatusCode::INTERNAL_SERVER_ERROR, "Couldn't parse track.getInfo!")})?.track;
    log::trace!("Parsed into: {trackinfo:?}");

    Ok(Arc::new((userinfo, trackinfo, trackstub)))
  })

M src/ctx.rs => src/ctx.rs +12 -1
@@ 132,7 132,18 @@ pub async fn get_ctx(api_result: Result<UserInfo, (StatusCode, &'static str)>, f
//            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()).filter(|s| !s.is_empty()).unwrap_or_else(|| "https://lastfm.freetls.fastly.net/i/u/128s/4128a6eb29f94943c9d206c08e625904.jpg".into()),
          image_url: {
            let image_url = track.images.iter()
              .chain(track.album.iter().flat_map(|x| &x.images))
              .chain(&trackstub.images)
              .chain(trackstub.album.iter().flat_map(|x| &x.images))
              .inspect(|i| log::trace!("got: {i:?}"))
              .max_by_key(|a| a.size)
              .map(|a| a.url.clone())
              .unwrap_or_else(|| "https://lastfm.freetls.fastly.net/i/u/128s/4128a6eb29f94943c9d206c08e625904.jpg".into());

              image_url
          },
          now_playing: trackstub.attr.nowplaying,
          url: track.url.clone(),
          loved: track.loved.unwrap_or(false)

M src/deserialize.rs => src/deserialize.rs +10 -4
@@ 70,7 70,7 @@ pub struct Artist {
  pub url: Option<Arc<str>>
}

#[derive(Deserialize, Debug, Ord, PartialOrd, Eq, PartialEq)]
#[derive(Deserialize, Debug, Ord, PartialOrd, Eq, PartialEq, Copy, Clone)]
#[serde(rename_all = "lowercase")]
#[repr(u8)]
pub enum ImageSize {


@@ 93,9 93,8 @@ pub struct Album {
  #[serde(alias = "#text")]
  pub title: Arc<str>,
  #[serde(default)]
  #[serde(rename = "image")]
  #[serde(alias = "image")]
  pub images: Vec<Image>,

}




@@ 151,7 150,14 @@ pub struct TrackStub {
  #[serde(rename = "@attr")]
  #[serde(default)]
  pub attr: TrackAttr,
  #[serde(default)]
  #[serde(alias = "image")]
  pub images: Vec<Image>,

  #[serde(default)]
  pub album: Option<Album>
}

#[derive(Deserialize, Debug)]
pub struct RecentTracks {
  pub track: Vec<TrackStub>


@@ 176,7 182,7 @@ pub struct User {
  #[serde(deserialize_with = "str_num")]
  pub album_count: u64,

  #[serde(rename = "image")]
  #[serde(alias = "image")]
  pub images: Vec<Image>,

  pub registered: TimeStamp,