feat!: playlists
This commit is contained in:
114
src/library.rs
114
src/library.rs
@@ -1,14 +1,22 @@
|
||||
use std::{collections::HashMap, path::PathBuf, sync::Arc, time::Instant};
|
||||
use deadpool_sqlite::Pool;
|
||||
use std::{collections::HashMap, path::PathBuf, sync::Arc, time::Instant};
|
||||
use tokio::{sync::Mutex, task::JoinSet};
|
||||
|
||||
use tonic::{Request, Response, Status};
|
||||
use walkdir::{DirEntry, WalkDir};
|
||||
|
||||
use crate::{
|
||||
checksum::generate_hash,
|
||||
database::tracks::{get_tracks, insert_tracks},
|
||||
database::tracks::{
|
||||
add_track_to_playlist, create_playlist, delete_playlist, get_playlists, get_tracks,
|
||||
insert_tracks, remove_track_from_playlist,
|
||||
},
|
||||
music::metadata::{extract_track_data, TrackMetadata},
|
||||
proto::library::{library_server::Library, Track, TrackList},
|
||||
proto::library::{
|
||||
library_server::Library, AddTrackToPlaylistRequest, CreatePlaylistRequest,
|
||||
CreatePlaylistResponse, DeletePlaylistRequest, ListPlaylistsResponse,
|
||||
RemoveTrackFromPlaylistRequest, Track, TrackList,
|
||||
},
|
||||
state::GrooveState,
|
||||
};
|
||||
|
||||
@@ -26,12 +34,9 @@ impl LibraryService {
|
||||
|
||||
#[tonic::async_trait]
|
||||
impl Library for LibraryService {
|
||||
async fn list_tracks(
|
||||
&self,
|
||||
_request: tonic::Request<()>,
|
||||
) -> Result<tonic::Response<TrackList>, tonic::Status> {
|
||||
async fn list_tracks(&self, _request: Request<()>) -> Result<Response<TrackList>, Status> {
|
||||
let Ok(tracks) = get_tracks(&self.pool).await else {
|
||||
return Err(tonic::Status::internal(""));
|
||||
return Err(Status::internal(""));
|
||||
};
|
||||
|
||||
let response = TrackList {
|
||||
@@ -47,15 +52,96 @@ impl Library for LibraryService {
|
||||
.collect::<Vec<Track>>(),
|
||||
};
|
||||
|
||||
Ok(tonic::Response::new(response))
|
||||
Ok(Response::new(response))
|
||||
}
|
||||
|
||||
async fn list_playlists(
|
||||
&self,
|
||||
_request: Request<()>,
|
||||
) -> Result<Response<ListPlaylistsResponse>, Status> {
|
||||
let Ok(playlists) = get_playlists(&self.pool).await else {
|
||||
return Err(Status::internal(""));
|
||||
};
|
||||
|
||||
let response = ListPlaylistsResponse { playlists };
|
||||
|
||||
Ok(Response::new(response))
|
||||
}
|
||||
|
||||
async fn create_playlist(
|
||||
&self,
|
||||
request: Request<CreatePlaylistRequest>,
|
||||
) -> Result<Response<CreatePlaylistResponse>, Status> {
|
||||
let input = request.get_ref();
|
||||
|
||||
let Ok(playlist) = create_playlist(&self.pool, &input.name).await else {
|
||||
return Err(Status::internal(""));
|
||||
};
|
||||
|
||||
let response = CreatePlaylistResponse {
|
||||
playlist: Some(playlist),
|
||||
};
|
||||
|
||||
Ok(Response::new(response))
|
||||
}
|
||||
|
||||
async fn delete_playlist(
|
||||
&self,
|
||||
request: Request<DeletePlaylistRequest>,
|
||||
) -> Result<Response<()>, Status> {
|
||||
let input = request.get_ref();
|
||||
|
||||
let Ok(success) = delete_playlist(&self.pool, input.id).await else {
|
||||
return Err(Status::internal(""));
|
||||
};
|
||||
|
||||
if !success {
|
||||
return Err(Status::internal(""));
|
||||
}
|
||||
|
||||
Ok(Response::new(()))
|
||||
}
|
||||
|
||||
async fn add_track_to_playlist(
|
||||
&self,
|
||||
request: Request<AddTrackToPlaylistRequest>,
|
||||
) -> Result<Response<()>, Status> {
|
||||
let input = request.get_ref();
|
||||
|
||||
let Ok(success) =
|
||||
add_track_to_playlist(&self.pool, input.playlist_id, &input.track_hash).await
|
||||
else {
|
||||
return Err(Status::internal(""));
|
||||
};
|
||||
|
||||
if !success {
|
||||
return Err(Status::internal(""));
|
||||
}
|
||||
|
||||
Ok(Response::new(()))
|
||||
}
|
||||
|
||||
async fn remove_track_from_playlist(
|
||||
&self,
|
||||
request: Request<RemoveTrackFromPlaylistRequest>,
|
||||
) -> Result<Response<()>, Status> {
|
||||
let input = request.get_ref();
|
||||
|
||||
let Ok(success) =
|
||||
remove_track_from_playlist(&self.pool, input.playlist_id, input.track_rank).await
|
||||
else {
|
||||
return Err(Status::internal(""));
|
||||
};
|
||||
|
||||
if !success {
|
||||
return Err(Status::internal(""));
|
||||
}
|
||||
|
||||
Ok(Response::new(()))
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn index_path(
|
||||
path: PathBuf,
|
||||
db: &Pool,
|
||||
path_id: u64,
|
||||
) -> Result<(), rusqlite::Error> {
|
||||
pub async fn index_path(path: PathBuf, db: &Pool, path_id: u64) -> Result<(), rusqlite::Error> {
|
||||
let home = home::home_dir().unwrap();
|
||||
|
||||
let correct_path = path.to_str().unwrap().replace("~", home.to_str().unwrap());
|
||||
|
||||
Reference in New Issue
Block a user