Add thumbnails endpoint

This commit is contained in:
Antoine Gersant 2024-07-13 17:58:31 -07:00
parent d82563efc0
commit 153943a3ae
5 changed files with 35 additions and 4 deletions

1
Cargo.lock generated
View file

@ -1548,6 +1548,7 @@ dependencies = [
"sqlx",
"thiserror",
"tokio",
"tokio-util",
"toml 0.7.8",
"tower-http",
"ureq 2.7.1",

View file

@ -37,6 +37,7 @@ serde_json = "1.0.87"
simplelog = "0.12.0"
thiserror = "1.0.37"
tokio = { version = "1.38", features = ["macros", "rt-multi-thread"] }
tokio-util = { version = "0.7.11", features = ["io"] }
toml = "0.7"
tower-http = { version = "0.5.2", features = ["fs"] }
ureq = "2.7"

View file

@ -68,6 +68,12 @@ impl FromRef<App> for app::settings::Manager {
}
}
impl FromRef<App> for app::thumbnail::Manager {
fn from_ref(app: &App) -> Self {
app.thumbnail_manager.clone()
}
}
impl FromRef<App> for app::vfs::Manager {
fn from_ref(app: &App) -> Self {
app.vfs_manager.clone()

View file

@ -1,14 +1,16 @@
use axum::{
body::Body,
extract::{DefaultBodyLimit, Path, Query, State},
response::Html,
response::{Html, IntoResponse},
routing::{delete, get, post, put},
Json, Router,
};
use base64::{prelude::BASE64_STANDARD_NO_PAD, Engine};
use percent_encoding::percent_decode_str;
use tokio_util::io::ReaderStream;
use crate::{
app::{config, ddns, index, lastfm, playlist, settings, user, vfs, App},
app::{config, ddns, index, lastfm, playlist, settings, thumbnail, user, vfs, App},
server::{dto, error::APIError},
};
@ -45,6 +47,7 @@ pub fn router() -> Router<App> {
.route("/playlist/:name", put(put_playlist))
.route("/playlist/:name", get(get_playlist))
.route("/playlist/:name", delete(delete_playlist))
.route("/thumbnail/*path", get(get_thumbnail))
.route("/lastfm/now_playing/*path", put(put_lastfm_now_playing))
.route("/lastfm/scrobble/*path", post(post_lastfm_scrobble))
.route("/lastfm/link_token", get(get_lastfm_link_token))
@ -363,6 +366,26 @@ async fn delete_playlist(
Ok(())
}
async fn get_thumbnail(
_auth: Auth,
State(vfs_manager): State<vfs::Manager>,
State(thumbnails_manager): State<thumbnail::Manager>,
Path(path): Path<String>,
Query(options_input): Query<dto::ThumbnailOptions>,
) -> Result<impl IntoResponse, APIError> {
let options = thumbnail::Options::from(options_input);
let vfs = vfs_manager.get_vfs().await?;
let path = percent_decode_str(&path).decode_utf8_lossy();
let image_path = vfs.virtual_to_real(std::path::Path::new(path.as_ref()))?;
let thumbnail_path = thumbnails_manager.get_thumbnail(&image_path, &options)?;
let Ok(file) = tokio::fs::File::open(thumbnail_path).await else {
return Err(APIError::ThumbnailFileIOError);
};
Ok(Body::from_stream(ReaderStream::new(file)))
}
async fn put_lastfm_now_playing(
auth: Auth,
State(lastfm_manager): State<lastfm::Manager>,

View file

@ -125,7 +125,7 @@ pub trait TestService {
if !entries.is_empty() {
break;
}
tokio::time::sleep(Duration::from_secs(1)).await;
tokio::time::sleep(Duration::from_millis(100)).await;
}
loop {
@ -137,7 +137,7 @@ pub trait TestService {
if !entries.is_empty() {
break;
}
tokio::time::sleep(Duration::from_secs(1)).await;
tokio::time::sleep(Duration::from_millis(100)).await;
}
}
}