Adds playlist endpoints
This commit is contained in:
parent
274a1f2cf7
commit
d82563efc0
3 changed files with 63 additions and 5 deletions
|
@ -106,11 +106,11 @@ impl Manager {
|
||||||
.execute(connection.as_mut())
|
.execute(connection.as_mut())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if !new_songs.is_empty() {
|
for chunk in new_songs.chunks(10_000) {
|
||||||
QueryBuilder::<Sqlite>::new("INSERT INTO playlist_songs (playlist, path, ordering) ")
|
QueryBuilder::<Sqlite>::new("INSERT INTO playlist_songs (playlist, path, ordering) ")
|
||||||
.push_values(new_songs, |mut b, song| {
|
.push_values(chunk, |mut b, song| {
|
||||||
b.push_bind(playlist_id)
|
b.push_bind(playlist_id)
|
||||||
.push_bind(song.path)
|
.push_bind(&song.path)
|
||||||
.push_bind(song.ordering);
|
.push_bind(song.ordering);
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
|
|
|
@ -50,6 +50,12 @@ impl FromRef<App> for app::lastfm::Manager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromRef<App> for app::playlist::Manager {
|
||||||
|
fn from_ref(app: &App) -> Self {
|
||||||
|
app.playlist_manager.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromRef<App> for app::user::Manager {
|
impl FromRef<App> for app::user::Manager {
|
||||||
fn from_ref(app: &App) -> Self {
|
fn from_ref(app: &App) -> Self {
|
||||||
app.user_manager.clone()
|
app.user_manager.clone()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{Path, Query, State},
|
extract::{DefaultBodyLimit, Path, Query, State},
|
||||||
response::Html,
|
response::Html,
|
||||||
routing::{delete, get, post, put},
|
routing::{delete, get, post, put},
|
||||||
Json, Router,
|
Json, Router,
|
||||||
|
@ -8,7 +8,7 @@ use base64::{prelude::BASE64_STANDARD_NO_PAD, Engine};
|
||||||
use percent_encoding::percent_decode_str;
|
use percent_encoding::percent_decode_str;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::{config, ddns, index, lastfm, settings, user, vfs, App},
|
app::{config, ddns, index, lastfm, playlist, settings, user, vfs, App},
|
||||||
server::{dto, error::APIError},
|
server::{dto, error::APIError},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -41,6 +41,10 @@ pub fn router() -> Router<App> {
|
||||||
.route("/recent", get(get_recent))
|
.route("/recent", get(get_recent))
|
||||||
.route("/search", get(get_search_root))
|
.route("/search", get(get_search_root))
|
||||||
.route("/search/*query", get(get_search))
|
.route("/search/*query", get(get_search))
|
||||||
|
.route("/playlists", get(get_playlists))
|
||||||
|
.route("/playlist/:name", put(put_playlist))
|
||||||
|
.route("/playlist/:name", get(get_playlist))
|
||||||
|
.route("/playlist/:name", delete(delete_playlist))
|
||||||
.route("/lastfm/now_playing/*path", put(put_lastfm_now_playing))
|
.route("/lastfm/now_playing/*path", put(put_lastfm_now_playing))
|
||||||
.route("/lastfm/scrobble/*path", post(post_lastfm_scrobble))
|
.route("/lastfm/scrobble/*path", post(post_lastfm_scrobble))
|
||||||
.route("/lastfm/link_token", get(get_lastfm_link_token))
|
.route("/lastfm/link_token", get(get_lastfm_link_token))
|
||||||
|
@ -52,6 +56,7 @@ pub fn router() -> Router<App> {
|
||||||
.route("/random/", get(get_random))
|
.route("/random/", get(get_random))
|
||||||
.route("/recent/", get(get_recent))
|
.route("/recent/", get(get_recent))
|
||||||
.route("/search/", get(get_search_root))
|
.route("/search/", get(get_search_root))
|
||||||
|
.layer(DefaultBodyLimit::max(10 * 1024 * 1024)) // 10MB
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_version() -> Json<dto::Version> {
|
async fn get_version() -> Json<dto::Version> {
|
||||||
|
@ -311,6 +316,53 @@ async fn get_search(
|
||||||
Ok(Json(result))
|
Ok(Json(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_playlists(
|
||||||
|
auth: Auth,
|
||||||
|
State(playlist_manager): State<playlist::Manager>,
|
||||||
|
) -> Result<Json<Vec<dto::ListPlaylistsEntry>>, APIError> {
|
||||||
|
let playlist_names = playlist_manager.list_playlists(auth.get_username()).await?;
|
||||||
|
let playlists: Vec<dto::ListPlaylistsEntry> = playlist_names
|
||||||
|
.into_iter()
|
||||||
|
.map(|p| dto::ListPlaylistsEntry { name: p })
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(Json(playlists))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn put_playlist(
|
||||||
|
auth: Auth,
|
||||||
|
State(playlist_manager): State<playlist::Manager>,
|
||||||
|
Path(name): Path<String>,
|
||||||
|
playlist: Json<dto::SavePlaylistInput>,
|
||||||
|
) -> Result<(), APIError> {
|
||||||
|
playlist_manager
|
||||||
|
.save_playlist(&name, auth.get_username(), &playlist.tracks)
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_playlist(
|
||||||
|
auth: Auth,
|
||||||
|
State(playlist_manager): State<playlist::Manager>,
|
||||||
|
Path(name): Path<String>,
|
||||||
|
) -> Result<Json<Vec<index::Song>>, APIError> {
|
||||||
|
let songs = playlist_manager
|
||||||
|
.read_playlist(&name, auth.get_username())
|
||||||
|
.await?;
|
||||||
|
Ok(Json(songs))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn delete_playlist(
|
||||||
|
auth: Auth,
|
||||||
|
State(playlist_manager): State<playlist::Manager>,
|
||||||
|
Path(name): Path<String>,
|
||||||
|
) -> Result<(), APIError> {
|
||||||
|
playlist_manager
|
||||||
|
.delete_playlist(&name, auth.get_username())
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn put_lastfm_now_playing(
|
async fn put_lastfm_now_playing(
|
||||||
auth: Auth,
|
auth: Auth,
|
||||||
State(lastfm_manager): State<lastfm::Manager>,
|
State(lastfm_manager): State<lastfm::Manager>,
|
||||||
|
|
Loading…
Add table
Reference in a new issue