feat!: playlists

This commit is contained in:
2024-12-01 03:48:51 +01:00
parent 634c147ee9
commit a652ae330f
11 changed files with 456 additions and 57 deletions

View File

@@ -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());