~aleteoryx/lfm_embed

27bd2e5f5699fd9101aa298993c3a9045caf02f4 — alyx 5 months ago 5a97731
Remove ResponseCtx
3 files changed, 66 insertions(+), 69 deletions(-)

M src/ctx.rs
M src/lib.rs
M src/main.rs
M src/ctx.rs => src/ctx.rs +56 -61
@@ 107,69 107,64 @@ pub mod model {
}
pub use model::Root as Ctx;

#[derive(Debug)]
pub struct ResponseCtx(pub model::Root, pub StatusCode);

impl ResponseCtx {
  pub async fn create(api_result: Result<Arc<(de::User, de::Track, de::TrackStub)>, (StatusCode, &'static str)>, font_query: Option<FontQuery>, query: BTreeMap<String, String>) -> ResponseCtx {
    match api_result {
      Ok(a) => {
        let (user, track, trackstub) = a.as_ref();
        ResponseCtx((model::Data {
          user: model::User {
            name: user.name.clone(),
            realname: user.realname.clone(),

            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()
pub async fn get_ctx(api_result: Result<Arc<(de::User, de::Track, de::TrackStub)>, (StatusCode, &'static str)>, font_query: Option<FontQuery>, query: BTreeMap<String, String>) -> (Ctx, StatusCode) {
  match api_result {
    Ok(a) => {
      let (user, track, trackstub) = a.as_ref();
      ((model::Data {
        user: model::User {
          name: user.name.clone(),
          realname: user.realname.clone(),

          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.title.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())
          },
          scrobble: model::Scrobble {
            name: track.name.clone(),
            album: track.album.title.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()).filter(|s| !s.is_empty()).unwrap_or_else(|| "https://lastfm.freetls.fastly.net/i/u/128s/4128a6eb29f94943c9d206c08e625904.jpg".into()),
            now_playing: trackstub.attr.nowplaying,
            url: track.url.clone(),
            loved: track.loved.unwrap_or(false)
          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()),
          now_playing: trackstub.attr.nowplaying,
          url: track.url.clone(),
          loved: track.loved.unwrap_or(false)
        },
        font: match font_query {
          Some(FontQuery { google_font: Some(f), .. }) if CONFIG.has_google_api_key() => {
            let css = match crate::cache::font::get_fontinfo(&f.to_string()).await {
              Ok(css) => css,
              Err((status, error)) => { return (model::Root::Error {error}, status); }
            };
            Some(model::Font::External {
              css,
              name: f
            })
          },
          font: match font_query {
            Some(FontQuery { google_font: Some(f), .. }) if CONFIG.has_google_api_key() => {
              let css = match crate::cache::font::get_fontinfo(&f.to_string()).await {
                Ok(css) => css,
                Err((status, error)) => { return ResponseCtx(model::Root::Error {error}, status); }
              };
              Some(model::Font::External {
                css,
                name: f
              })
            },
            Some(FontQuery { include_font: Some(f), .. }) => Some(
              model::Font::External {
                css: format!(
                  "@font-face {{ font-family: 'included_font'; src: url('{}'); }}",
                  f.replace('\\', "\\\\")
                   .replace('\'', "\\'")).into(),
                name: "included_font".into()
            }),
            Some(FontQuery { font: Some(s), .. }) => Some(model::Font::Name { name: s }),
            _ => None,
          },
          query
        }).into(), StatusCode::OK)
      },
      Err((status, error)) => {
        ResponseCtx(model::Root::Error {error}, status)
      }
          Some(FontQuery { include_font: Some(f), .. }) => Some(
            model::Font::External {
              css: format!(
               "@font-face {{ font-family: 'included_font'; src: url('{}'); }}",
                f.replace('\\', "\\\\")
                 .replace('\'', "\\'")).into(),
              name: "included_font".into()
          }),
          Some(FontQuery { font: Some(s), .. }) => Some(model::Font::Name { name: s }),
          _ => None,
        },
        query
      }).into(), StatusCode::OK)
    },
    Err((status, error)) => {
      (model::Root::Error {error}, status)
    }
  }
}

M src/lib.rs => src/lib.rs +0 -1
@@ 10,4 10,3 @@ pub mod ctx;
pub mod theming;

pub use config::CONFIG;
pub use ctx::ResponseCtx;

M src/main.rs => src/main.rs +10 -7
@@ 5,8 5,11 @@ use std::collections::BTreeMap;
use std::fs::File;
use std::sync::Arc;

use lfm_embed::{CONFIG, ResponseCtx};
use lfm_embed::CONFIG;
use lfm_embed::ctx::get_ctx;
use lfm_embed::cache::user::get_userinfo;
use lfm_embed::cache::font::FontQuery;
use lfm_embed::theming::render_theme;

use log::LevelFilter;
use dotenv::var;


@@ 45,12 48,12 @@ async fn main() {
  let user = warp::path!("user" / String)
    .and(warp::query::<UserQuery>())
    .then(|s, q: UserQuery| async move {
      log::debug!(target: "lfm_embed::server::user", "Handling request for user `{s}` with {q:?}");
      let (ctx, dur) = lfm_embed::cache::user::get_userinfo(&s).await;
      let ResponseCtx(data, status) = ResponseCtx::create(ctx, q.font, q.rest).await;
      log::debug!(target: "lfm_embed::main::user", "Handling request for user `{s}` with {q:?}");
      let (userinfo, refresh) = get_userinfo(&s).await;
      let (ctx, status) = get_ctx(userinfo, q.font, q.rest).await;

      let (theme, res) = lfm_embed::theming::render_theme(q.theme.as_deref(), &data);
      log::debug!(target: "lfm_embed::server::user", "Using theme {theme}");
      let (theme, res) = render_theme(q.theme.as_deref(), &ctx);
      log::debug!(target: "lfm_embed::main::user", "Using theme {theme}");

      match res {
        Err(status) =>


@@ 63,7 66,7 @@ async fn main() {
        Ok(contents) =>
          http::Response::builder()
            .status(status)
            .header("Refresh", dur.as_secs())
            .header("Refresh", refresh.as_secs())
            .header("X-Selected-Theme", theme)
            .header("Content-Type", "text/html")
            .body(contents)