Adds seed support to get_random_albums

This commit is contained in:
Antoine Gersant 2024-09-18 21:19:59 -07:00
parent ae4200c6ce
commit 625f4bd006
4 changed files with 48 additions and 12 deletions

View file

@ -178,12 +178,19 @@ impl Manager {
.unwrap() .unwrap()
} }
pub async fn get_random_albums(&self, count: usize) -> Result<Vec<Album>, Error> { pub async fn get_random_albums(
&self,
seed: Option<u64>,
offset: usize,
count: usize,
) -> Result<Vec<Album>, Error> {
spawn_blocking({ spawn_blocking({
let index_manager = self.clone(); let index_manager = self.clone();
move || { move || {
let index = index_manager.index.read().unwrap(); let index = index_manager.index.read().unwrap();
Ok(index.collection.get_random_albums(&index.strings, count)) Ok(index
.collection
.get_random_albums(&index.strings, seed, offset, count))
} }
}) })
.await .await

View file

@ -5,7 +5,7 @@ use std::{
}; };
use lasso2::{Rodeo, RodeoReader, Spur}; use lasso2::{Rodeo, RodeoReader, Spur};
use rand::{rngs::ThreadRng, seq::IteratorRandom}; use rand::{rngs::StdRng, seq::SliceRandom, SeedableRng};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tinyvec::TinyVec; use tinyvec::TinyVec;
use unicase::UniCase; use unicase::UniCase;
@ -140,11 +140,27 @@ impl Collection {
}) })
} }
pub fn get_random_albums(&self, strings: &RodeoReader, count: usize) -> Vec<Album> { pub fn get_random_albums(
self.albums &self,
.keys() strings: &RodeoReader,
.choose_multiple(&mut ThreadRng::default(), count) seed: Option<u64>,
offset: usize,
count: usize,
) -> Vec<Album> {
let shuffled = {
let mut rng = match seed {
Some(seed) => StdRng::seed_from_u64(seed),
None => StdRng::from_entropy(),
};
let mut s = self.albums.keys().collect::<Vec<_>>();
s.shuffle(&mut rng);
s
};
shuffled
.into_iter() .into_iter()
.skip(offset)
.take(count)
.filter_map(|k| self.get_album(strings, k.clone())) .filter_map(|k| self.get_album(strings, k.clone()))
.collect() .collect()
} }
@ -545,7 +561,7 @@ mod test {
}, },
])); ]));
let albums = collection.get_random_albums(&strings, 10); let albums = collection.get_random_albums(&strings, None, 0, 10);
assert_eq!(albums.len(), 2); assert_eq!(albums.len(), 2);
assert_eq!( assert_eq!(

View file

@ -478,8 +478,14 @@ async fn get_random_albums(
_auth: Auth, _auth: Auth,
api_version: APIMajorVersion, api_version: APIMajorVersion,
State(index_manager): State<index::Manager>, State(index_manager): State<index::Manager>,
Query(options): Query<dto::GetRandomAlbumsParameters>,
) -> Response { ) -> Response {
let albums = match index_manager.get_random_albums(20).await { let offset = options.offset.unwrap_or(0);
let count = options.count.unwrap_or(20);
let albums = match index_manager
.get_random_albums(options.seed, offset, count)
.await
{
Ok(d) => d, Ok(d) => d,
Err(e) => return APIError::from(e).into_response(), Err(e) => return APIError::from(e).into_response(),
}; };
@ -490,10 +496,10 @@ async fn get_recent_albums(
_auth: Auth, _auth: Auth,
api_version: APIMajorVersion, api_version: APIMajorVersion,
State(index_manager): State<index::Manager>, State(index_manager): State<index::Manager>,
Query(option): Query<dto::GetRecentAlbumsParameters>, Query(options): Query<dto::GetRecentAlbumsParameters>,
) -> Response { ) -> Response {
let offset = option.offset.unwrap_or(0); let offset = options.offset.unwrap_or(0);
let count = option.count.unwrap_or(20); let count = options.count.unwrap_or(20);
let albums = match index_manager.get_recent_albums(offset, count).await { let albums = match index_manager.get_recent_albums(offset, count).await {
Ok(d) => d, Ok(d) => d,
Err(e) => return APIError::from(e).into_response(), Err(e) => return APIError::from(e).into_response(),

View file

@ -436,6 +436,13 @@ pub struct GetSongsBulkOutput {
pub not_found: Vec<PathBuf>, pub not_found: Vec<PathBuf>,
} }
#[derive(Clone, Serialize, Deserialize)]
pub struct GetRandomAlbumsParameters {
pub seed: Option<u64>,
pub offset: Option<usize>,
pub count: Option<usize>,
}
#[derive(Clone, Serialize, Deserialize)] #[derive(Clone, Serialize, Deserialize)]
pub struct GetRecentAlbumsParameters { pub struct GetRecentAlbumsParameters {
pub offset: Option<usize>, pub offset: Option<usize>,