Progress bar for uploading

This commit is contained in:
2025-08-08 21:38:43 +03:00
parent f126fb0252
commit af84517ce3
2 changed files with 93 additions and 44 deletions
+1
View File
@@ -1 +1,2 @@
/target /target
/.idea
+81 -33
View File
@@ -1,14 +1,16 @@
use std::cmp::Ordering;
use clap::{Args, Parser, Subcommand}; use clap::{Args, Parser, Subcommand};
use dirs_next::config_dir; use dirs_next::config_dir;
use reqwest::{Client, multipart};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fs; use std::cmp::Ordering;
use std::fs::File; 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::path::{Path, PathBuf};
use std::process::exit; use std::process::exit;
use std::str::FromStr; use std::str::FromStr;
use reqwest::{multipart, Client}; use std::string::ToString;
use std::time::Duration;
use std::{fs, thread};
/// Nuget packages manager /// Nuget packages manager
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
@@ -55,8 +57,7 @@ struct Packet {
version: Version, version: Version,
path: String, path: String,
} }
#[derive(Serialize, Deserialize, Debug, Eq)] #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
#[derive(PartialEq)]
struct Version { struct Version {
major: u32, major: u32,
minor: u32, minor: u32,
@@ -65,7 +66,11 @@ struct Version{
impl Version { impl Version {
fn new(major: u32, minor: u32, patch: u32) -> Version { fn new(major: u32, minor: u32, patch: u32) -> Version {
Version{ major, minor, patch } Version {
major,
minor,
patch,
}
} }
fn from_name(name: &str) -> Version { fn from_name(name: &str) -> Version {
@@ -90,9 +95,9 @@ impl Ord for Version {
if ord == Ordering::Equal { if ord == Ordering::Equal {
let ord = self.minor.cmp(&other.minor); let ord = self.minor.cmp(&other.minor);
if ord == Ordering::Equal { if ord == Ordering::Equal {
return self.patch.cmp(&other.patch) return self.patch.cmp(&other.patch);
} }
return ord return ord;
} }
ord ord
} }
@@ -112,7 +117,11 @@ impl Packet{
let dir = path.parent().unwrap().to_str().unwrap(); let dir = path.parent().unwrap().to_str().unwrap();
Packet { Packet {
key: name, key: name,
version: Version{major: a, minor: b, patch: c}, version: Version {
major: a,
minor: b,
patch: c,
},
path: dir.to_string(), path: dir.to_string(),
} }
} }
@@ -130,10 +139,11 @@ fn read_config() -> Configuration {
let reader = BufReader::new(file); let reader = BufReader::new(file);
let config: Configuration = serde_json::from_reader(reader).unwrap(); let config: Configuration = serde_json::from_reader(reader).unwrap();
config config
},
Err(_) => {
Configuration{key: None, packets: vec![]}
} }
Err(_) => Configuration {
key: None,
packets: vec![],
},
} }
} }
@@ -147,21 +157,28 @@ fn write_config(config: Configuration) {
} }
fn try_remember_packet(path: &Path, config: &mut Configuration) { 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) => { Some(packet) => {
let version = Version::from_name(&path.file_name().unwrap().to_str().unwrap()); let version = Version::from_name(&path.file_name().unwrap().to_str().unwrap());
if packet.version < version { if packet.version < version {
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] #[tokio::main]
async fn main() { async fn main() {
let args = CliArgs::parse(); let args = CliArgs::parse();
@@ -203,24 +220,12 @@ async fn main() {
exit(4) 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); 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); exit(0);
} }
@@ -252,10 +257,12 @@ async fn main() {
let mut reader = BufReader::new(f); let mut reader = BufReader::new(f);
reader.read_to_string(&mut ctg).unwrap(); reader.read_to_string(&mut ctg).unwrap();
} }
_ => { ctg = "Not configured yet".to_string(); } _ => {
ctg = "Not configured yet".to_string();
}
} }
println!("{}", ctg); println!("{}", ctg);
}, }
Some(Commands::Logout) => { Some(Commands::Logout) => {
let mut config = read_config(); let mut config = read_config();
config.key = None; config.key = None;
@@ -264,3 +271,44 @@ async fn main() {
None => {} 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
}
}
}