Repair playlists
This commit is contained in:
parent
6b5c291cb7
commit
3f645d1011
4 changed files with 57 additions and 46 deletions
|
@ -170,7 +170,7 @@ impl App {
|
||||||
vfs_manager.clone(),
|
vfs_manager.clone(),
|
||||||
ddns_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 thumbnail_manager = thumbnail::Manager::new(thumbnails_dir_path);
|
||||||
let lastfm_manager = lastfm::Manager::new(index_manager.clone(), user_manager.clone());
|
let lastfm_manager = lastfm::Manager::new(index_manager.clone(), user_manager.clone());
|
||||||
|
|
||||||
|
|
|
@ -2,18 +2,17 @@ use core::clone::Clone;
|
||||||
use sqlx::{Acquire, QueryBuilder, Sqlite};
|
use sqlx::{Acquire, QueryBuilder, Sqlite};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::app::{vfs, Error};
|
use crate::app::Error;
|
||||||
use crate::db::DB;
|
use crate::db::DB;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Manager {
|
pub struct Manager {
|
||||||
db: DB,
|
db: DB,
|
||||||
vfs_manager: vfs::Manager,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Manager {
|
impl Manager {
|
||||||
pub fn new(db: DB, vfs_manager: vfs::Manager) -> Self {
|
pub fn new(db: DB) -> Self {
|
||||||
Self { db, vfs_manager }
|
Self { db }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn list_playlists(&self, owner: &str) -> Result<Vec<String>, Error> {
|
pub async fn list_playlists(&self, owner: &str) -> Result<Vec<String>, Error> {
|
||||||
|
@ -37,26 +36,18 @@ impl Manager {
|
||||||
owner: &str,
|
owner: &str,
|
||||||
content: &[PathBuf],
|
content: &[PathBuf],
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let vfs = self.vfs_manager.get_vfs().await?;
|
|
||||||
|
|
||||||
struct PlaylistSong {
|
struct PlaylistSong {
|
||||||
path: String,
|
virtual_path: String,
|
||||||
ordering: i64,
|
ordering: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut new_songs: Vec<PlaylistSong> = Vec::with_capacity(content.len());
|
let mut new_songs: Vec<PlaylistSong> = Vec::with_capacity(content.len());
|
||||||
for (i, path) in content.iter().enumerate() {
|
for (i, virtual_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 {
|
new_songs.push(PlaylistSong {
|
||||||
path: real_path,
|
virtual_path: virtual_path.to_string_lossy().to_string(),
|
||||||
ordering: i as i64,
|
ordering: i as i64,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let mut connection = self.db.connect().await?;
|
let mut connection = self.db.connect().await?;
|
||||||
|
|
||||||
|
@ -93,10 +84,12 @@ impl Manager {
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
for chunk in new_songs.chunks(10_000) {
|
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, virtual_path, ordering) ",
|
||||||
|
)
|
||||||
.push_values(chunk, |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.virtual_path)
|
||||||
.push_bind(song.ordering);
|
.push_bind(song.ordering);
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
|
@ -132,20 +125,20 @@ impl Manager {
|
||||||
.ok_or(Error::PlaylistNotFound)?;
|
.ok_or(Error::PlaylistNotFound)?;
|
||||||
|
|
||||||
// List songs
|
// List songs
|
||||||
todo!();
|
sqlx::query_scalar!(
|
||||||
// sqlx::query_as!(
|
r#"
|
||||||
// Song,
|
SELECT virtual_path
|
||||||
// r#"
|
FROM playlist_songs ps
|
||||||
// SELECT s.*
|
WHERE ps.playlist = $1
|
||||||
// FROM playlist_songs ps
|
ORDER BY ps.ordering
|
||||||
// INNER JOIN songs s ON ps.virtual_path = s.virtual_path
|
"#,
|
||||||
// WHERE ps.playlist = $1
|
playlist_id
|
||||||
// ORDER BY ps.ordering
|
)
|
||||||
// "#,
|
.fetch_all(connection.as_mut())
|
||||||
// playlist_id
|
.await?
|
||||||
// )
|
.into_iter()
|
||||||
// .fetch_all(connection.as_mut())
|
.map(PathBuf::from)
|
||||||
// .await?
|
.collect()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(songs)
|
Ok(songs)
|
||||||
|
|
|
@ -73,7 +73,7 @@ impl ContextBuilder {
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.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();
|
config_manager.apply(&self.config).await.unwrap();
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@ use std::path::Path;
|
||||||
|
|
||||||
use http::StatusCode;
|
use http::StatusCode;
|
||||||
|
|
||||||
use crate::server::dto;
|
use crate::server::dto::{self, SongList};
|
||||||
use crate::server::test::protocol::V8;
|
use crate::server::test::protocol::{V7, V8};
|
||||||
use crate::server::test::{constants::*, protocol, ServiceType, TestService};
|
use crate::server::test::{constants::*, protocol, ServiceType, TestService};
|
||||||
use crate::test_name;
|
use crate::test_name;
|
||||||
|
|
||||||
|
@ -85,7 +85,25 @@ async fn get_playlist_golden_path() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let request = protocol::read_playlist::<V8>(TEST_PLAYLIST_NAME);
|
let request = protocol::read_playlist::<V8>(TEST_PLAYLIST_NAME);
|
||||||
let response = service.fetch_json::<_, Vec<dto::Song>>(&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::<V7>(TEST_PLAYLIST_NAME);
|
||||||
|
let response = service.fetch_json::<_, Vec<dto::v7::Song>>(&request).await;
|
||||||
assert_eq!(response.status(), StatusCode::OK);
|
assert_eq!(response.status(), StatusCode::OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue