Utoipa media endpoints

This commit is contained in:
Antoine Gersant 2025-01-14 23:11:34 -08:00
parent b5a8aea1f8
commit df402ed7b8
2 changed files with 43 additions and 7 deletions

View file

@ -3,7 +3,7 @@ use std::path::PathBuf;
use axum::{ use axum::{
extract::{DefaultBodyLimit, Path, Query, State}, extract::{DefaultBodyLimit, Path, Query, State},
response::{IntoResponse, Response}, response::{IntoResponse, Response},
routing::{get, post}, routing::get,
Json, Json,
}; };
use axum_extra::headers::Range; use axum_extra::headers::Range;
@ -63,14 +63,14 @@ pub fn router() -> OpenApiRouter<App> {
.routes(routes!(get_playlists)) .routes(routes!(get_playlists))
.routes(routes!(put_playlist, get_playlist, delete_playlist)) .routes(routes!(put_playlist, get_playlist, delete_playlist))
// Media // Media
.route("/songs", post(get_songs)) // post because of https://github.com/whatwg/fetch/issues/551 .routes(routes!(get_songs))
.route("/peaks/{*path}", get(get_peaks)) .routes(routes!(get_peaks))
.route("/thumbnail/{*path}", get(get_thumbnail)) .routes(routes!(get_thumbnail))
// Layers // Layers
.layer(CompressionLayer::new().quality(CompressionLevel::Fastest)) .layer(CompressionLayer::new().quality(CompressionLevel::Fastest))
.layer(DefaultBodyLimit::max(10 * 1024 * 1024)) // 10MB .layer(DefaultBodyLimit::max(10 * 1024 * 1024)) // 10MB
// Uncompressed // Uncompressed
.route("/audio/{*path}", get(get_audio)) .routes(routes!(get_audio))
} }
#[utoipa::path( #[utoipa::path(
@ -573,6 +573,14 @@ async fn get_album(
Ok(Json(index_manager.get_album(artists, name).await?.into())) Ok(Json(index_manager.get_album(artists, name).await?.into()))
} }
#[utoipa::path(
post, // post because of https://github.com/whatwg/fetch/issues/551
path = "/songs",
request_body = dto::GetSongsBulkInput,
responses(
(status = 200, body = dto::GetSongsBulkOutput),
)
)]
async fn get_songs( async fn get_songs(
_auth: Auth, _auth: Auth,
State(index_manager): State<index::Manager>, State(index_manager): State<index::Manager>,
@ -595,6 +603,14 @@ async fn get_songs(
Ok(Json(output)) Ok(Json(output))
} }
#[utoipa::path(
get,
path = "/peaks/{*path}",
params(("path" = String, Path, allow_reserved)),
responses(
(status = 200, body = dto::Peaks),
)
)]
async fn get_peaks( async fn get_peaks(
_auth: Auth, _auth: Auth,
State(config_manager): State<config::Manager>, State(config_manager): State<config::Manager>,
@ -893,6 +909,15 @@ async fn delete_playlist(
Ok(()) Ok(())
} }
#[utoipa::path(
get,
path = "/audio/{*path}",
params(("path" = String, Path, allow_reserved)),
responses(
(status = 206, body = [u8]),
(status = 200, body = [u8]),
)
)]
async fn get_audio( async fn get_audio(
_auth: Auth, _auth: Auth,
State(config_manager): State<config::Manager>, State(config_manager): State<config::Manager>,
@ -913,6 +938,15 @@ async fn get_audio(
Ok(Ranged::new(range, body)) Ok(Ranged::new(range, body))
} }
#[utoipa::path(
get,
path = "/thumbnail/{*path}",
params(("path" = String, Path, allow_reserved)),
responses(
(status = 206, body = [u8]),
(status = 200, body = [u8]),
)
)]
async fn get_thumbnail( async fn get_thumbnail(
_auth: Auth, _auth: Auth,
State(config_manager): State<config::Manager>, State(config_manager): State<config::Manager>,

View file

@ -464,14 +464,16 @@ impl From<index::Album> for Album {
} }
} }
#[derive(Clone, Default, Serialize, Deserialize)] #[derive(Clone, Default, Serialize, Deserialize, ToSchema)]
pub struct GetSongsBulkInput { pub struct GetSongsBulkInput {
#[schema(value_type = Vec<String>)]
pub paths: Vec<PathBuf>, pub paths: Vec<PathBuf>,
} }
#[derive(Default, Serialize, Deserialize)] #[derive(Default, Serialize, Deserialize, ToSchema)]
pub struct GetSongsBulkOutput { pub struct GetSongsBulkOutput {
pub songs: Vec<Song>, pub songs: Vec<Song>,
#[schema(value_type = Vec<String>)]
pub not_found: Vec<PathBuf>, pub not_found: Vec<PathBuf>,
} }