From 93af34e09508f90ede396d269a89856795f5af72 Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Wed, 27 Aug 2025 17:25:53 -0400 Subject: [PATCH 1/4] Added code to queue song --- src/syncers/upload.rs | 46 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/syncers/upload.rs b/src/syncers/upload.rs index 473dd75..8344c3a 100644 --- a/src/syncers/upload.rs +++ b/src/syncers/upload.rs @@ -11,6 +11,16 @@ pub struct Upload { pub api: models::api::Api, } +mod response { + pub mod queue_song { + #[derive(Debug, serde::Deserialize)] + pub struct Response { + pub message: String, + pub data: Vec + } + } +} + impl Upload { pub async fn upload_song_with_metadata( &mut self, @@ -51,6 +61,42 @@ impl Upload { } } + pub async fn queue_song(&self, token: &icarus_models::token::AccessToken, song: &icarus_models::song::Song) -> Result { + let songpath = song.song_path().unwrap_or_default(); + + let mut song_filename = String::from("audio"); + song_filename += icarus_models::constants::file_extensions::audio::DEFAULTMUSICEXTENSION; + + let form = reqwest::multipart::Form::new() + .part( + "file", + reqwest::multipart::Part::bytes(std::fs::read(songpath).unwrap()) + .file_name(song_filename), + ); + + let endpoint = String::from("api/v2/song/queue"); + let url = format!("{}/{endpoint}", self.api.url); + let mut headers = reqwest::header::HeaderMap::new(); + headers.insert( + reqwest::header::AUTHORIZATION, + HeaderValue::from_str(&token.token.clone()).unwrap(), + ); + let client = reqwest::Client::builder().build().unwrap(); + match client.post(url).headers(headers).multipart(form).send().await { + Ok(response) => match response.json::().await { + Ok(resp) => { + Ok(resp.data[0]) + } + Err(err) => { + Err(err) + } + } + Err(err) => { + Err(err) + } + } + } + fn init_form( &self, song: &icarus_models::song::Song, -- 2.47.3 From c142fdc7fe4819b2a6d74777b812e25f6b19379d Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Wed, 27 Aug 2025 17:51:03 -0400 Subject: [PATCH 2/4] Making functions async --- src/main.rs | 5 +++-- src/managers/commit_manager.rs | 38 +++++++++++++++++----------------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/main.rs b/src/main.rs index ae68c95..98eb30d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,8 @@ mod utilities; use std::env; -fn main() { +#[tokio::main] +async fn main() { let args: Vec = env::args().collect(); let args_len = args.len() as i32; @@ -29,7 +30,7 @@ fn main() { ica_action: chosen_act, }; - cmt_mgr.commit_action(); + cmt_mgr.commit_action().await; } #[cfg(test)] diff --git a/src/managers/commit_manager.rs b/src/managers/commit_manager.rs index 3eb3709..1575143 100644 --- a/src/managers/commit_manager.rs +++ b/src/managers/commit_manager.rs @@ -79,7 +79,7 @@ pub fn retrieve_song( } impl CommitManager { - pub fn commit_action(&mut self) { + pub async fn commit_action(&mut self) { let action = &self.ica_action.action; println!("Committing {action} action"); @@ -91,11 +91,11 @@ impl CommitManager { // TODO: Move code to get token here and then pass it to the respective functions match mapped_action { - ActionValues::DeleteAct => self.delete_song(), - ActionValues::DownloadAct => self.download_song(), - ActionValues::RetrieveAct => self.retrieve_object(), + ActionValues::DeleteAct => self.delete_song().await, + ActionValues::DownloadAct => self.download_song().await, + ActionValues::RetrieveAct => self.retrieve_object().await, ActionValues::UploadAct => self.upload_song(), - ActionValues::UploadSongWithMetadata => self.upload_song_with_metadata(), + ActionValues::UploadSongWithMetadata => self.upload_song_with_metadata().await, _ => { println!("Nothing good here"); } @@ -132,7 +132,7 @@ impl CommitManager { actions } - fn delete_song(&self) { + async fn delete_song(&self) { let mut prsr = parsers::api_parser::APIParser { apis: vec![models::api::Api::default(), models::api::Api::default()], ica_act: self.ica_action.clone(), @@ -141,7 +141,7 @@ impl CommitManager { prsr.parse_api(parsers::api_parser::APIType::Auth); let auth_api = prsr.retrieve_api(parsers::api_parser::APIType::Auth); - let token = self.parse_token(&auth_api); + let token = self.parse_token(&auth_api).await; println!("Deleting song"); @@ -173,7 +173,7 @@ impl CommitManager { } } - fn download_song(&self) { + async fn download_song(&self) { println!("Deleting song"); let dwn = self.ica_action.retrieve_flag_value(&String::from("-b")); let song_id = uuid::Uuid::from_str(dwn.as_str()).unwrap(); @@ -186,7 +186,7 @@ impl CommitManager { prsr.parse_api(parsers::api_parser::APIType::Auth); let auth_api = prsr.retrieve_api(parsers::api_parser::APIType::Auth); - let token = self.parse_token(&auth_api); + let token = self.parse_token(&auth_api).await; println!("Message: {}", token.message); let api = prsr.retrieve_api(parsers::api_parser::APIType::Main); @@ -220,7 +220,7 @@ impl CommitManager { } } - fn retrieve_object(&self) { + async fn retrieve_object(&self) { println!("Retrieving song"); let rt = self.ica_action.retrieve_flag_value(&String::from("-rt")); @@ -236,7 +236,7 @@ impl CommitManager { prsr.parse_api(parsers::api_parser::APIType::Auth); let auth_api = prsr.retrieve_api(parsers::api_parser::APIType::Auth); - let token = self.parse_token(&auth_api); + let token = self.parse_token(&auth_api).await; println!("Token {token:?}"); let api = prsr.retrieve_api(parsers::api_parser::APIType::Main); @@ -265,7 +265,7 @@ impl CommitManager { panic!("Not supported"); } - fn parse_token(&self, api: &models::api::Api) -> icarus_models::token::AccessToken { + async fn parse_token(&self, api: &models::api::Api) -> icarus_models::token::AccessToken { println!("Fetching token"); let mut usr_mgr: managers::user_manager::UserManager = @@ -287,7 +287,7 @@ impl CommitManager { token.unwrap() } - fn upload_song_with_metadata(&mut self) { + async fn upload_song_with_metadata(&mut self) { println!("Uplodaring song with metadara"); let songpath = self.ica_action.retrieve_flag_value(&String::from("-s")); @@ -314,15 +314,15 @@ impl CommitManager { println!("metadata path: {metadata_path}"); println!("cover art path: {coverpath}"); - let _ = self.sing_target_upload(&songpath, &track_id, &metadata_path, &coverpath); + let _ = self.sing_target_upload(&songpath, &track_id, &metadata_path, &coverpath).await; } else if multitarget { - let _ = self.multi_target_upload(&uni); + let _ = self.multi_target_upload(&uni).await; } else { println!("Single or Multi target has not been chosen"); } } - fn sing_target_upload( + async fn sing_target_upload( &mut self, songpath: &String, track_id: &str, @@ -337,7 +337,7 @@ impl CommitManager { prsr.parse_api(parsers::api_parser::APIType::Auth); let auth_api = prsr.retrieve_api(parsers::api_parser::APIType::Auth); - let token = self.parse_token(&auth_api); + let token = self.parse_token(&auth_api).await; println!("Token: {:?}", token.token); @@ -455,7 +455,7 @@ impl CommitManager { } } - fn multi_target_upload(&mut self, sourcepath: &String) -> std::io::Result<()> { + async fn multi_target_upload(&mut self, sourcepath: &String) -> std::io::Result<()> { let mut prsr = parsers::api_parser::APIParser { apis: vec![models::api::Api::default(), models::api::Api::default()], ica_act: self.ica_action.clone(), @@ -463,7 +463,7 @@ impl CommitManager { prsr.parse_api(parsers::api_parser::APIType::Main); prsr.parse_api(parsers::api_parser::APIType::Auth); let auth_api = prsr.retrieve_api(parsers::api_parser::APIType::Auth); - let token = self.parse_token(&auth_api); + let token = self.parse_token(&auth_api).await; let directory_path = std::path::Path::new(&sourcepath); -- 2.47.3 From f208f511a550657b2fdc25b28f8c4fdd2f122bf5 Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Wed, 27 Aug 2025 18:42:58 -0400 Subject: [PATCH 3/4] Able to queue song --- src/managers/commit_manager.rs | 42 ++++++++++++++++++++++++++++++---- src/syncers/upload.rs | 28 +++++++++++++++++------ 2 files changed, 59 insertions(+), 11 deletions(-) diff --git a/src/managers/commit_manager.rs b/src/managers/commit_manager.rs index 1575143..755d854 100644 --- a/src/managers/commit_manager.rs +++ b/src/managers/commit_manager.rs @@ -282,7 +282,7 @@ impl CommitManager { }; tok_mgr.init(); - let token = Runtime::new().unwrap().block_on(tok_mgr.request_token()); + let token = tok_mgr.request_token().await; token.unwrap() } @@ -376,10 +376,11 @@ impl CommitManager { cover_art.data = cover_art.to_data().unwrap(); - let mut up = syncers::upload::Upload::default(); - let host = self.ica_action.retrieve_flag_value(&String::from("-h")); - up.set_api(&host); + // let mut up = syncers::upload::Upload::default(); + // let host = self.ica_action.retrieve_flag_value(&String::from("-h")); + // up.set_api(&host); + /* let res = up.upload_song_with_metadata(&token, &s, &cover_art); match Runtime::new().unwrap().block_on(res) { @@ -392,6 +393,16 @@ impl CommitManager { Err(std::io::Error::other(er.to_string())) } } + */ + let res = self.queue_song(&token, &s).await; + match res { + Ok(val) => { + Ok(()) + }, + Err(err) => { + Err(err) + } + } } Err(err) => { println!("Error: {err:?}"); @@ -408,6 +419,29 @@ impl CommitManager { } } + async fn queue_song(&self, token: &icarus_models::token::AccessToken, song: &icarus_models::song::Song) -> Result<()> { + let mut up = syncers::upload::Upload::default(); + let host = self.ica_action.retrieve_flag_value(&String::from("-h")); + up.set_api(&host); + + let mut queued_song_id = uuid::Uuid::nil(); + + println!("Queueing song"); + + match up.queue_song(token, song).await { + Ok(id) => { + queued_song_id = id; + } + Err(err) => { + eprintln!("Error: {err:?}"); + } + } + + println!("Queued song Id: {queued_song_id:?}"); + + Ok(()) + } + fn get_songs( &self, metadata_path: &String, diff --git a/src/syncers/upload.rs b/src/syncers/upload.rs index 8344c3a..a1c78e9 100644 --- a/src/syncers/upload.rs +++ b/src/syncers/upload.rs @@ -62,26 +62,40 @@ impl Upload { } pub async fn queue_song(&self, token: &icarus_models::token::AccessToken, song: &icarus_models::song::Song) -> Result { - let songpath = song.song_path().unwrap_or_default(); + let songpath = song.song_path().unwrap(); + let file = tokio::fs::File::open(&songpath).await.unwrap(); + let stream = tokio_util::codec::FramedRead::new(file, tokio_util::codec::BytesCodec::new()); + let file_body = reqwest::Body::wrap_stream(stream); + println!("Song path: {songpath:?}"); + println!("Token: {}", token.token); - let mut song_filename = String::from("audio"); - song_filename += icarus_models::constants::file_extensions::audio::DEFAULTMUSICEXTENSION; + // let mut song_filename = String::from("audio"); + // song_filename += icarus_models::constants::file_extensions::audio::DEFAULTMUSICEXTENSION; let form = reqwest::multipart::Form::new() .part( "file", - reqwest::multipart::Part::bytes(std::fs::read(songpath).unwrap()) - .file_name(song_filename), + reqwest::multipart::Part::stream(file_body) + .file_name(song.filename.clone()).mime_str("application/octet-stream").unwrap(), ); let endpoint = String::from("api/v2/song/queue"); let url = format!("{}/{endpoint}", self.api.url); + println!("Url: {url:?}"); + let mut headers = reqwest::header::HeaderMap::new(); headers.insert( reqwest::header::AUTHORIZATION, - HeaderValue::from_str(&token.token.clone()).unwrap(), + HeaderValue::from_str(&token.bearer_token()).unwrap(), ); - let client = reqwest::Client::builder().build().unwrap(); + headers.insert("Accept", HeaderValue::from_str("*/*").unwrap()); + headers.insert("Connection", HeaderValue::from_str("keep-alive").unwrap()); + headers.insert("Cache-Control", HeaderValue::from_str("no-cache").unwrap()); + + // let client = reqwest::Client::new(); + let client = reqwest::Client::builder().timeout(std::time::Duration::from_secs(300)) + .pool_idle_timeout(std::time::Duration::from_secs(30)) + .build().unwrap(); match client.post(url).headers(headers).multipart(form).send().await { Ok(response) => match response.json::().await { Ok(resp) => { -- 2.47.3 From 5a55396db0bf4d387b6548feb79ce8b577b9c075 Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Wed, 27 Aug 2025 18:47:32 -0400 Subject: [PATCH 4/4] Cleanup --- src/managers/commit_manager.rs | 39 +++++++------------------ src/syncers/upload.rs | 52 ++++++++++++++++++---------------- 2 files changed, 39 insertions(+), 52 deletions(-) diff --git a/src/managers/commit_manager.rs b/src/managers/commit_manager.rs index 755d854..1971d41 100644 --- a/src/managers/commit_manager.rs +++ b/src/managers/commit_manager.rs @@ -314,7 +314,9 @@ impl CommitManager { println!("metadata path: {metadata_path}"); println!("cover art path: {coverpath}"); - let _ = self.sing_target_upload(&songpath, &track_id, &metadata_path, &coverpath).await; + let _ = self + .sing_target_upload(&songpath, &track_id, &metadata_path, &coverpath) + .await; } else if multitarget { let _ = self.multi_target_upload(&uni).await; } else { @@ -376,32 +378,9 @@ impl CommitManager { cover_art.data = cover_art.to_data().unwrap(); - // let mut up = syncers::upload::Upload::default(); - // let host = self.ica_action.retrieve_flag_value(&String::from("-h")); - // up.set_api(&host); - - /* - let res = up.upload_song_with_metadata(&token, &s, &cover_art); - - match Runtime::new().unwrap().block_on(res) { - Ok(o) => { - println!("Successfully sent {o:?}"); - Ok(()) - } - Err(er) => { - println!("Some error {er:?}"); - Err(std::io::Error::other(er.to_string())) - } - } - */ - let res = self.queue_song(&token, &s).await; - match res { - Ok(val) => { - Ok(()) - }, - Err(err) => { - Err(err) - } + match self.queue_song(&token, &s).await { + Ok(_) => Ok(()), + Err(err) => Err(err), } } Err(err) => { @@ -419,7 +398,11 @@ impl CommitManager { } } - async fn queue_song(&self, token: &icarus_models::token::AccessToken, song: &icarus_models::song::Song) -> Result<()> { + async fn queue_song( + &self, + token: &icarus_models::token::AccessToken, + song: &icarus_models::song::Song, + ) -> Result<()> { let mut up = syncers::upload::Upload::default(); let host = self.ica_action.retrieve_flag_value(&String::from("-h")); up.set_api(&host); diff --git a/src/syncers/upload.rs b/src/syncers/upload.rs index a1c78e9..eedc762 100644 --- a/src/syncers/upload.rs +++ b/src/syncers/upload.rs @@ -16,7 +16,7 @@ mod response { #[derive(Debug, serde::Deserialize)] pub struct Response { pub message: String, - pub data: Vec + pub data: Vec, } } } @@ -61,23 +61,23 @@ impl Upload { } } - pub async fn queue_song(&self, token: &icarus_models::token::AccessToken, song: &icarus_models::song::Song) -> Result { + pub async fn queue_song( + &self, + token: &icarus_models::token::AccessToken, + song: &icarus_models::song::Song, + ) -> Result { let songpath = song.song_path().unwrap(); let file = tokio::fs::File::open(&songpath).await.unwrap(); let stream = tokio_util::codec::FramedRead::new(file, tokio_util::codec::BytesCodec::new()); let file_body = reqwest::Body::wrap_stream(stream); - println!("Song path: {songpath:?}"); - println!("Token: {}", token.token); - // let mut song_filename = String::from("audio"); - // song_filename += icarus_models::constants::file_extensions::audio::DEFAULTMUSICEXTENSION; - - let form = reqwest::multipart::Form::new() - .part( - "file", - reqwest::multipart::Part::stream(file_body) - .file_name(song.filename.clone()).mime_str("application/octet-stream").unwrap(), - ); + let form = reqwest::multipart::Form::new().part( + "file", + reqwest::multipart::Part::stream(file_body) + .file_name(song.filename.clone()) + .mime_str("application/octet-stream") + .unwrap(), + ); let endpoint = String::from("api/v2/song/queue"); let url = format!("{}/{endpoint}", self.api.url); @@ -92,22 +92,26 @@ impl Upload { headers.insert("Connection", HeaderValue::from_str("keep-alive").unwrap()); headers.insert("Cache-Control", HeaderValue::from_str("no-cache").unwrap()); - // let client = reqwest::Client::new(); - let client = reqwest::Client::builder().timeout(std::time::Duration::from_secs(300)) + let client = reqwest::Client::builder() + .timeout(std::time::Duration::from_secs(300)) .pool_idle_timeout(std::time::Duration::from_secs(30)) - .build().unwrap(); - match client.post(url).headers(headers).multipart(form).send().await { + .build() + .unwrap(); + match client + .post(url) + .headers(headers) + .multipart(form) + .send() + .await + { Ok(response) => match response.json::().await { Ok(resp) => { + println!("Message: {:?}", resp.message); Ok(resp.data[0]) } - Err(err) => { - Err(err) - } - } - Err(err) => { - Err(err) - } + Err(err) => Err(err), + }, + Err(err) => Err(err), } } -- 2.47.3