Return first 200 songs when returning a list of songs

This commit is contained in:
Antoine Gersant 2024-08-24 23:28:22 -07:00
parent 8141e565e0
commit 6837994433
4 changed files with 42 additions and 16 deletions

1
Cargo.lock generated
View file

@ -1628,6 +1628,7 @@ dependencies = [
"bytes", "bytes",
"daemonize", "daemonize",
"embed-resource", "embed-resource",
"futures-util",
"getopts", "getopts",
"headers", "headers",
"http 1.1.0", "http 1.1.0",

View file

@ -15,6 +15,7 @@ axum-range = "0.4.0"
base64 = "0.22.1" base64 = "0.22.1"
bitcode = { version = "0.6.3", features = ["serde"] } bitcode = { version = "0.6.3", features = ["serde"] }
branca = "0.10.1" branca = "0.10.1"
futures-util = { version = "0.3.30", default-features = false }
getopts = "0.2.21" getopts = "0.2.21"
headers = "0.4" headers = "0.4"
http = "1.1.0" http = "1.1.0"

View file

@ -10,6 +10,7 @@ use axum_extra::headers::Range;
use axum_extra::TypedHeader; use axum_extra::TypedHeader;
use axum_range::{KnownSize, Ranged}; use axum_range::{KnownSize, Ranged};
use base64::{prelude::BASE64_STANDARD_NO_PAD, Engine}; use base64::{prelude::BASE64_STANDARD_NO_PAD, Engine};
use futures_util::future::join_all;
use percent_encoding::percent_decode_str; use percent_encoding::percent_decode_str;
use tower_http::{compression::CompressionLayer, CompressionLevel}; use tower_http::{compression::CompressionLayer, CompressionLevel};
@ -282,19 +283,35 @@ fn index_files_to_response(files: Vec<index::File>, api_version: APIMajorVersion
} }
} }
fn songs_to_response(files: Vec<PathBuf>, api_version: APIMajorVersion) -> Response { async fn make_song_list(paths: Vec<PathBuf>, index_manager: &index::Manager) -> dto::SongList {
let songs: Vec<index::Song> = join_all(
paths
.iter()
.take(200)
.map(|f| index_manager.get_song(f.clone())),
)
.await
.into_iter()
.filter_map(|r| r.ok())
.collect();
dto::SongList {
paths,
first_songs: songs.into_iter().map(|s| s.into()).collect(),
}
}
fn song_list_to_response(song_list: dto::SongList, api_version: APIMajorVersion) -> Response {
match api_version { match api_version {
APIMajorVersion::V7 => Json( APIMajorVersion::V7 => Json(
files song_list
.paths
.into_iter() .into_iter()
.map(|p| (&p).into()) .map(|p| (&p).into())
.collect::<Vec<dto::v7::Song>>(), .collect::<Vec<dto::v7::Song>>(),
) )
.into_response(), .into_response(),
APIMajorVersion::V8 => Json(dto::SongList { APIMajorVersion::V8 => Json(song_list).into_response(),
paths: files.into_iter().collect(),
})
.into_response(),
} }
} }
@ -347,11 +364,12 @@ async fn get_flatten_root(
api_version: APIMajorVersion, api_version: APIMajorVersion,
State(index_manager): State<index::Manager>, State(index_manager): State<index::Manager>,
) -> Response { ) -> Response {
let songs = match index_manager.flatten(PathBuf::new()).await { let paths = match index_manager.flatten(PathBuf::new()).await {
Ok(s) => s, Ok(s) => s,
Err(e) => return APIError::from(e).into_response(), Err(e) => return APIError::from(e).into_response(),
}; };
songs_to_response(songs, api_version) let song_list = make_song_list(paths, &index_manager).await;
song_list_to_response(song_list, api_version)
} }
async fn get_flatten( async fn get_flatten(
@ -360,11 +378,12 @@ async fn get_flatten(
State(index_manager): State<index::Manager>, State(index_manager): State<index::Manager>,
Path(path): Path<PathBuf>, Path(path): Path<PathBuf>,
) -> Response { ) -> Response {
let songs = match index_manager.flatten(path).await { let paths = match index_manager.flatten(path).await {
Ok(s) => s, Ok(s) => s,
Err(e) => return APIError::from(e).into_response(), Err(e) => return APIError::from(e).into_response(),
}; };
songs_to_response(songs, api_version) let song_list = make_song_list(paths, &index_manager).await;
song_list_to_response(song_list, api_version)
} }
async fn get_artists( async fn get_artists(
@ -433,11 +452,12 @@ async fn get_search_root(
api_version: APIMajorVersion, api_version: APIMajorVersion,
State(index_manager): State<index::Manager>, State(index_manager): State<index::Manager>,
) -> Response { ) -> Response {
let files = match index_manager.search("").await { let paths = match index_manager.search("").await {
Ok(f) => f, Ok(f) => f,
Err(e) => return APIError::from(e).into_response(), Err(e) => return APIError::from(e).into_response(),
}; };
songs_to_response(files, api_version) let song_list = make_song_list(paths, &index_manager).await;
song_list_to_response(song_list, api_version)
} }
async fn get_search( async fn get_search(
@ -446,11 +466,12 @@ async fn get_search(
State(index_manager): State<index::Manager>, State(index_manager): State<index::Manager>,
Path(query): Path<String>, Path(query): Path<String>,
) -> Response { ) -> Response {
let files = match index_manager.search(&query).await { let paths = match index_manager.search(&query).await {
Ok(f) => f, Ok(f) => f,
Err(e) => return APIError::from(e).into_response(), Err(e) => return APIError::from(e).into_response(),
}; };
songs_to_response(files, api_version) let song_list = make_song_list(paths, &index_manager).await;
song_list_to_response(song_list, api_version)
} }
async fn get_playlists( async fn get_playlists(
@ -481,17 +502,19 @@ async fn put_playlist(
async fn get_playlist( async fn get_playlist(
auth: Auth, auth: Auth,
api_version: APIMajorVersion, api_version: APIMajorVersion,
State(index_manager): State<index::Manager>,
State(playlist_manager): State<playlist::Manager>, State(playlist_manager): State<playlist::Manager>,
Path(name): Path<String>, Path(name): Path<String>,
) -> Response { ) -> Response {
let songs = match playlist_manager let paths = match playlist_manager
.read_playlist(&name, auth.get_username()) .read_playlist(&name, auth.get_username())
.await .await
{ {
Ok(s) => s, Ok(s) => s,
Err(e) => return APIError::from(e).into_response(), Err(e) => return APIError::from(e).into_response(),
}; };
songs_to_response(songs, api_version) let song_list = make_song_list(paths, &index_manager).await;
song_list_to_response(song_list, api_version)
} }
async fn delete_playlist( async fn delete_playlist(

View file

@ -283,6 +283,7 @@ impl From<index::Song> for Song {
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct SongList { pub struct SongList {
pub paths: Vec<PathBuf>, pub paths: Vec<PathBuf>,
pub first_songs: Vec<Song>,
} }
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]