diff --git a/.gitignore b/.gitignore index ea8c4bf..40d9aca 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +/.idea \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 9c2c076..b7257cb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,14 +1,16 @@ -use std::cmp::Ordering; use clap::{Args, Parser, Subcommand}; use dirs_next::config_dir; +use reqwest::{Client, multipart}; use serde::{Deserialize, Serialize}; -use std::fs; +use std::cmp::Ordering; use std::fs::File; -use std::io::{BufReader, BufWriter, Read}; +use std::io::{stdout, BufReader, BufWriter, Read, Write}; use std::path::{Path, PathBuf}; use std::process::exit; use std::str::FromStr; -use reqwest::{multipart, Client}; +use std::string::ToString; +use std::time::Duration; +use std::{fs, thread}; /// Nuget packages manager #[derive(Parser, Debug)] @@ -55,9 +57,8 @@ struct Packet { version: Version, path: String, } -#[derive(Serialize, Deserialize, Debug, Eq)] -#[derive(PartialEq)] -struct Version{ +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] +struct Version { major: u32, minor: u32, patch: u32, @@ -65,7 +66,11 @@ struct Version{ impl Version { fn new(major: u32, minor: u32, patch: u32) -> Version { - Version{ major, minor, patch } + Version { + major, + minor, + patch, + } } fn from_name(name: &str) -> Version { @@ -90,15 +95,15 @@ impl Ord for Version { if ord == Ordering::Equal { let ord = self.minor.cmp(&other.minor); if ord == Ordering::Equal { - return self.patch.cmp(&other.patch) + return self.patch.cmp(&other.patch); } - return ord + return ord; } ord } } -impl Packet{ +impl Packet { pub fn new(path: &Path) -> Packet { let name = path.file_name().unwrap().to_str().unwrap(); let mut parts = name.split(".").collect::>(); @@ -108,11 +113,15 @@ impl Packet{ let a = u32::from_str(parts.pop().unwrap()).unwrap(); let name = parts.join(".").to_string(); - println!("{}",name); + println!("{}", name); let dir = path.parent().unwrap().to_str().unwrap(); - Packet{ + Packet { key: name, - version: Version{major: a, minor: b, patch: c}, + version: Version { + major: a, + minor: b, + patch: c, + }, path: dir.to_string(), } } @@ -130,36 +139,44 @@ fn read_config() -> Configuration { let reader = BufReader::new(file); let config: Configuration = serde_json::from_reader(reader).unwrap(); config - }, - Err(_) => { - Configuration{key: None, packets: vec![]} } + Err(_) => Configuration { + key: None, + packets: vec![], + }, } } fn write_config(config: Configuration) { let path = config_path(); - let file= File::create(&path).unwrap(); + let file = File::create(&path).unwrap(); let mut writer = BufWriter::new(file); serde_json::to_writer_pretty(&mut writer, &config).unwrap(); } fn try_remember_packet(path: &Path, config: &mut Configuration) { - match config.packets.iter_mut().find(|p| p.path == path.parent().unwrap().to_str().unwrap()) { + match config + .packets + .iter_mut() + .find(|p| p.path == path.parent().unwrap().to_str().unwrap()) + { Some(packet) => { let version = Version::from_name(&path.file_name().unwrap().to_str().unwrap()); if packet.version < version { packet.version = version; } - }, - None => { - config.packets.push(Packet::new(path)) } + None => config.packets.push(Packet::new(path)), } - println!("{:?}",config) + println!("{:?}", config) +} + +fn conv(str: &mut String) { + let last = str.pop().unwrap(); + str.insert(0, last); } #[tokio::main] @@ -170,7 +187,7 @@ async fn main() { .expect("Could not determine config directory") .join("numan"); - if !Path::exists(&config_folder){ + if !Path::exists(&config_folder) { fs::create_dir_all(&config_folder).unwrap() } @@ -190,37 +207,25 @@ async fn main() { exit(3); } - let api_key : String; + let api_key: String; let mut config = read_config(); if let Some(key) = args.key { api_key = key; - }else if let Some(key) = &config.key { + } else if let Some(key) = &config.key { api_key = (*key).clone(); - }else{ + } else { println!("Api key is not defined! Use -k [key]"); exit(4) } - let client = Client::new(); - let form = multipart::Form::new() - .file("", path.clone()).await.unwrap(); + let success = send_packet(&path, api_key).await; - if !args.overlook { + if !args.overlook && success{ try_remember_packet(&Path::new(&path), &mut config); } - - let response = client.put("https://www.nuget.org/api/v2/package/").header("X-NuGet-ApiKey", api_key).header("X-NuGet-Client-Version", "4.1.0").multipart(form).send().await; - match response { - Ok(response) => { - println!("Response: [{}] {:?}",response.status() , response.text().await); - }, - Err(error) => { - println!("Error: {:?}", error.status().unwrap()); - } - } exit(0); } @@ -252,15 +257,58 @@ async fn main() { let mut reader = BufReader::new(f); reader.read_to_string(&mut ctg).unwrap(); } - _ => { ctg = "Not configured yet".to_string(); } + _ => { + ctg = "Not configured yet".to_string(); + } } println!("{}", ctg); - }, + } Some(Commands::Logout) => { - let mut config = read_config(); + let mut config = read_config(); config.key = None; write_config(config); } None => {} } } + +async fn send_packet(path: &String, api_key: String) -> bool { + let form = multipart::Form::new().file("", path.clone()).await.unwrap(); + let req_thread = tokio::spawn(async { + let client = Client::new(); + + let response_process = client + .put("https://www.nuget.org/api/v2/package/") + .header("X-NuGet-ApiKey", api_key) + .header("X-NuGet-Client-Version", "4.1.0") + .multipart(form) + .send(); + response_process.await + }); + let mut ind = "---->---->---->".to_string(); + + print!("{} [{}] https://www.nuget.org/api/v2/package/{}", path, ind, "\x08".repeat(54)); + while !req_thread.is_finished() { + print!("{}", ind); + stdout().flush().unwrap(); + print!("\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08"); + stdout().flush().unwrap(); + conv(&mut ind); + tokio::time::sleep(Duration::from_millis(100)).await; + } + let response = req_thread.await.unwrap(); + match response { + Ok(response) => { + let status = response.status(); + println!("Response: [{}] {:?}", status, response.text().await); + if !status.is_success() { + return false; + } + true + } + Err(error) => { + println!("Error: {:?}", error.status().unwrap()); + false + } + } +}