diff --git a/src/app.rs b/src/app.rs index 08653bb..8fea971 100644 --- a/src/app.rs +++ b/src/app.rs @@ -170,7 +170,7 @@ impl App { vfs_manager.clone(), ddns_manager.clone(), ); - let playlist_manager = playlist::Manager::new(db.clone(), vfs_manager.clone()); + let playlist_manager = playlist::Manager::new(db.clone()); let thumbnail_manager = thumbnail::Manager::new(thumbnails_dir_path); let lastfm_manager = lastfm::Manager::new(index_manager.clone(), user_manager.clone()); diff --git a/src/app/playlist.rs b/src/app/playlist.rs index 96810f3..23af628 100644 --- a/src/app/playlist.rs +++ b/src/app/playlist.rs @@ -2,18 +2,17 @@ use core::clone::Clone; use sqlx::{Acquire, QueryBuilder, Sqlite}; use std::path::PathBuf; -use crate::app::{vfs, Error}; +use crate::app::Error; use crate::db::DB; #[derive(Clone)] pub struct Manager { db: DB, - vfs_manager: vfs::Manager, } impl Manager { - pub fn new(db: DB, vfs_manager: vfs::Manager) -> Self { - Self { db, vfs_manager } + pub fn new(db: DB) -> Self { + Self { db } } pub async fn list_playlists(&self, owner: &str) -> Result, Error> { @@ -37,25 +36,17 @@ impl Manager { owner: &str, content: &[PathBuf], ) -> Result<(), Error> { - let vfs = self.vfs_manager.get_vfs().await?; - struct PlaylistSong { - path: String, + virtual_path: String, ordering: i64, } let mut new_songs: Vec = Vec::with_capacity(content.len()); - for (i, path) in content.iter().enumerate() { - if let Some(real_path) = vfs - .virtual_to_real(path) - .ok() - .and_then(|p| p.to_str().map(|s| s.to_owned())) - { - new_songs.push(PlaylistSong { - path: real_path, - ordering: i as i64, - }); - } + for (i, virtual_path) in content.iter().enumerate() { + new_songs.push(PlaylistSong { + virtual_path: virtual_path.to_string_lossy().to_string(), + ordering: i as i64, + }); } let mut connection = self.db.connect().await?; @@ -93,15 +84,17 @@ impl Manager { .await?; for chunk in new_songs.chunks(10_000) { - QueryBuilder::::new("INSERT INTO playlist_songs (playlist, path, ordering) ") - .push_values(chunk, |mut b, song| { - b.push_bind(playlist_id) - .push_bind(&song.path) - .push_bind(song.ordering); - }) - .build() - .execute(connection.as_mut()) - .await?; + QueryBuilder::::new( + "INSERT INTO playlist_songs (playlist, virtual_path, ordering) ", + ) + .push_values(chunk, |mut b, song| { + b.push_bind(playlist_id) + .push_bind(&song.virtual_path) + .push_bind(song.ordering); + }) + .build() + .execute(connection.as_mut()) + .await?; } Ok(()) @@ -132,20 +125,20 @@ impl Manager { .ok_or(Error::PlaylistNotFound)?; // List songs - todo!(); - // sqlx::query_as!( - // Song, - // r#" - // SELECT s.* - // FROM playlist_songs ps - // INNER JOIN songs s ON ps.virtual_path = s.virtual_path - // WHERE ps.playlist = $1 - // ORDER BY ps.ordering - // "#, - // playlist_id - // ) - // .fetch_all(connection.as_mut()) - // .await? + sqlx::query_scalar!( + r#" + SELECT virtual_path + FROM playlist_songs ps + WHERE ps.playlist = $1 + ORDER BY ps.ordering + "#, + playlist_id + ) + .fetch_all(connection.as_mut()) + .await? + .into_iter() + .map(PathBuf::from) + .collect() }; Ok(songs) diff --git a/src/app/test.rs b/src/app/test.rs index ba4fbbb..a0ada1b 100644 --- a/src/app/test.rs +++ b/src/app/test.rs @@ -73,7 +73,7 @@ impl ContextBuilder { ) .await .unwrap(); - let playlist_manager = playlist::Manager::new(db.clone(), vfs_manager.clone()); + let playlist_manager = playlist::Manager::new(db.clone()); config_manager.apply(&self.config).await.unwrap(); diff --git a/src/server/test/playlist.rs b/src/server/test/playlist.rs index 2b4f14c..214f008 100644 --- a/src/server/test/playlist.rs +++ b/src/server/test/playlist.rs @@ -2,8 +2,8 @@ use std::path::Path; use http::StatusCode; -use crate::server::dto; -use crate::server::test::protocol::V8; +use crate::server::dto::{self, SongList}; +use crate::server::test::protocol::{V7, V8}; use crate::server::test::{constants::*, protocol, ServiceType, TestService}; use crate::test_name; @@ -85,7 +85,25 @@ async fn get_playlist_golden_path() { } let request = protocol::read_playlist::(TEST_PLAYLIST_NAME); - let response = service.fetch_json::<_, Vec>(&request).await; + let response = service.fetch_json::<_, SongList>(&request).await; + assert_eq!(response.status(), StatusCode::OK); +} + +#[tokio::test] +async fn get_playlist_golden_path_api_v7() { + let mut service = ServiceType::new(&test_name!()).await; + service.complete_initial_setup().await; + service.login().await; + + { + let my_playlist = dto::SavePlaylistInput { tracks: Vec::new() }; + let request = protocol::save_playlist(TEST_PLAYLIST_NAME, my_playlist); + let response = service.fetch(&request).await; + assert_eq!(response.status(), StatusCode::OK); + } + + let request = protocol::read_playlist::(TEST_PLAYLIST_NAME); + let response = service.fetch_json::<_, Vec>(&request).await; assert_eq!(response.status(), StatusCode::OK); }