synthwave/src/route/album.rs
2024-07-24 11:07:24 +02:00

83 lines
No EOL
2.1 KiB
Rust

use std::cmp::Ordering;
use mongodb::bson::doc;
use rocket::*;
use serde_json::json;
use rocket::fs::NamedFile;
use mongod::Referencable;
use super::FallibleApiResponse;
use super::api_error;
use crate::library::Libary;
#[get("/artist/<artist_id>/albums")]
pub async fn albums_route(artist_id: &str, lib: &State<Libary>) -> FallibleApiResponse {
let albums = lib.get_albums_by_artist(artist_id).await;
Ok(json!({
"artist": artist_id,
"albums": &albums
}))
}
fn sort_by_tracknumber(a: &serde_json::Value, b: &serde_json::Value) -> Ordering {
a.get("tracknumber")
.unwrap()
.as_i64()
.unwrap()
.cmp(&b.get("tracknumber").unwrap().as_i64().unwrap())
}
#[get("/album/<album_id>/cover")]
pub async fn album_cover_route(album_id: &str, lib: &State<Libary>) -> Option<NamedFile> {
let album = lib.get_album_by_id(album_id).await?;
let track_path = lib
.get_tracks_of_album(&format!("album::{}", album._id))
.await
.first()?
.path
.clone();
let track_path = std::path::Path::new(&track_path);
for ext in ["png", "jpg", "jpeg", "avif"] {
let cover_file = track_path.parent()?.join(format!("cover.{ext}"));
if cover_file.exists() {
return NamedFile::open(cover_file).await.ok();
}
}
None
}
#[get("/album/<album_id>")]
pub async fn album_route(album_id: &str, lib: &State<Libary>) -> FallibleApiResponse {
let album = lib
.get_album_by_id(album_id)
.await
.ok_or_else(|| api_error("No album with that ID found"))?;
let mut tracks = lib
.get_tracks_of_album(&format!("album::{}", album._id))
.await
.into_iter()
.map(|x| {
json!({
"id": x.id(),
"title": x.title,
"tracknumber": x.meta.map(|x| x.track_number())
})
})
.collect::<Vec<_>>();
tracks.sort_by(sort_by_tracknumber);
let mut album = serde_json::to_value(album).unwrap();
album
.as_object_mut()
.unwrap()
.insert("tracks".into(), tracks.into());
Ok(album)
}