Implements get_album endpoint
This commit is contained in:
parent
b42c6d39e8
commit
332e39876e
6 changed files with 46 additions and 7 deletions
|
@ -65,6 +65,17 @@ impl IndexManager {
|
|||
Ok(true)
|
||||
}
|
||||
|
||||
pub async fn get_album(
|
||||
&self,
|
||||
album_key: &AlbumKey,
|
||||
) -> Result<collection::Album, collection::Error> {
|
||||
let index = self.index.read().await;
|
||||
let album_id = album_key.into();
|
||||
index
|
||||
.get_album(album_id)
|
||||
.ok_or_else(|| collection::Error::AlbumNotFound)
|
||||
}
|
||||
|
||||
pub async fn get_random_albums(
|
||||
&self,
|
||||
count: usize,
|
||||
|
@ -134,7 +145,7 @@ impl IndexBuilder {
|
|||
|
||||
if !song.album_artists.0.is_empty() {
|
||||
album.artists = song.album_artists.0.clone();
|
||||
} else if !song.album_artists.0.is_empty() {
|
||||
} else if !song.artists.0.is_empty() {
|
||||
album.artists = song.artists.0.clone();
|
||||
}
|
||||
|
||||
|
@ -166,15 +177,17 @@ pub(super) struct Index {
|
|||
}
|
||||
|
||||
impl Index {
|
||||
pub fn get_album(&self, album_id: AlbumID) -> Option<collection::Album> {
|
||||
pub(self) fn get_album(&self, album_id: AlbumID) -> Option<collection::Album> {
|
||||
self.albums.get(&album_id).map(|a| {
|
||||
let songs = a
|
||||
let mut songs = a
|
||||
.songs
|
||||
.iter()
|
||||
.filter_map(|s| self.songs.get(s))
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
songs.sort_by_key(|s| (s.disc_number.unwrap_or(-1), s.track_number.unwrap_or(-1)));
|
||||
|
||||
collection::Album {
|
||||
name: a.name.clone(),
|
||||
artwork: a.artwork.clone(),
|
||||
|
@ -188,7 +201,7 @@ impl Index {
|
|||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
pub struct SongID(u64);
|
||||
struct SongID(u64);
|
||||
|
||||
#[derive(Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
pub struct SongKey {
|
||||
|
@ -227,10 +240,10 @@ struct Album {
|
|||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
pub struct AlbumID(u64);
|
||||
struct AlbumID(u64);
|
||||
|
||||
#[derive(Clone, Eq, Hash, PartialEq)]
|
||||
struct AlbumKey {
|
||||
pub struct AlbumKey {
|
||||
pub artists: Vec<String>,
|
||||
pub name: Option<String>,
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ impl From<Option<String>> for MultiString {
|
|||
pub enum Error {
|
||||
#[error("Directory not found: {0}")]
|
||||
DirectoryNotFound(PathBuf),
|
||||
#[error("Album not found")]
|
||||
AlbumNotFound,
|
||||
#[error(transparent)]
|
||||
Database(#[from] sqlx::Error),
|
||||
#[error(transparent)]
|
||||
|
|
|
@ -25,6 +25,7 @@ impl TryFrom<i32> for APIMajorVersion {
|
|||
|
||||
pub const API_MAJOR_VERSION: i32 = 8;
|
||||
pub const API_MINOR_VERSION: i32 = 0;
|
||||
pub const API_ARRAY_SEPARATOR: &'static str = "\u{000C}";
|
||||
|
||||
mod axum;
|
||||
pub use axum::*;
|
||||
|
|
|
@ -12,7 +12,10 @@ use percent_encoding::percent_decode_str;
|
|||
|
||||
use crate::{
|
||||
app::{collection, config, ddns, lastfm, playlist, settings, thumbnail, user, vfs, App},
|
||||
server::{dto, error::APIError, APIMajorVersion, API_MAJOR_VERSION, API_MINOR_VERSION},
|
||||
server::{
|
||||
dto, error::APIError, APIMajorVersion, API_ARRAY_SEPARATOR, API_MAJOR_VERSION,
|
||||
API_MINOR_VERSION,
|
||||
},
|
||||
};
|
||||
|
||||
use super::auth::{AdminRights, Auth};
|
||||
|
@ -40,6 +43,7 @@ pub fn router() -> Router<App> {
|
|||
.route("/browse/*path", get(get_browse))
|
||||
.route("/flatten", get(get_flatten_root))
|
||||
.route("/flatten/*path", get(get_flatten))
|
||||
.route("/artists/:artists/albums/:name", get(get_album))
|
||||
.route("/random", get(get_random))
|
||||
.route("/recent", get(get_recent))
|
||||
.route("/search", get(get_search_root))
|
||||
|
@ -365,6 +369,21 @@ async fn get_flatten(
|
|||
songs_to_response(songs, api_version)
|
||||
}
|
||||
|
||||
async fn get_album(
|
||||
_auth: Auth,
|
||||
State(index_manager): State<collection::IndexManager>,
|
||||
Path((artists, name)): Path<(String, String)>,
|
||||
) -> Result<Json<dto::Album>, APIError> {
|
||||
let album_key = collection::AlbumKey {
|
||||
artists: artists
|
||||
.split(API_ARRAY_SEPARATOR)
|
||||
.map(str::to_owned)
|
||||
.collect::<Vec<_>>(),
|
||||
name: (!name.is_empty()).then_some(name),
|
||||
};
|
||||
Ok(Json(index_manager.get_album(&album_key).await?.into()))
|
||||
}
|
||||
|
||||
async fn get_random(
|
||||
_auth: Auth,
|
||||
api_version: APIMajorVersion,
|
||||
|
|
|
@ -21,6 +21,7 @@ impl IntoResponse for APIError {
|
|||
APIError::Database(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
APIError::DeletingOwnAccount => StatusCode::CONFLICT,
|
||||
APIError::DirectoryNotFound(_) => StatusCode::NOT_FOUND,
|
||||
APIError::AlbumNotFound => StatusCode::NOT_FOUND,
|
||||
APIError::EmbeddedArtworkNotFound => StatusCode::NOT_FOUND,
|
||||
APIError::EmptyPassword => StatusCode::BAD_REQUEST,
|
||||
APIError::EmptyUsername => StatusCode::BAD_REQUEST,
|
||||
|
|
|
@ -26,6 +26,8 @@ pub enum APIError {
|
|||
Database(sqlx::Error),
|
||||
#[error("Directory not found: {0}")]
|
||||
DirectoryNotFound(PathBuf),
|
||||
#[error("Album not found")]
|
||||
AlbumNotFound,
|
||||
#[error("DDNS update query failed with HTTP status {0}")]
|
||||
DdnsUpdateQueryFailed(u16),
|
||||
#[error("Cannot delete your own account")]
|
||||
|
@ -86,6 +88,7 @@ impl From<collection::Error> for APIError {
|
|||
fn from(error: collection::Error) -> APIError {
|
||||
match error {
|
||||
collection::Error::DirectoryNotFound(d) => APIError::DirectoryNotFound(d),
|
||||
collection::Error::AlbumNotFound => APIError::AlbumNotFound,
|
||||
collection::Error::Database(e) => APIError::Database(e),
|
||||
collection::Error::DatabaseConnection(e) => e.into(),
|
||||
collection::Error::Vfs(e) => e.into(),
|
||||
|
|
Loading…
Add table
Reference in a new issue