mirror of
https://github.com/Waradu/to-streamshare.git
synced 2025-04-22 04:14:06 +02:00
Implementation of ProgressBar (#1)
Co-authored-by: Waradu <waradu@outlook.com>
This commit is contained in:
parent
c7e859badf
commit
7a101fde14
4 changed files with 202 additions and 68 deletions
125
src/main.rs
125
src/main.rs
|
@ -1,7 +1,11 @@
|
|||
use std::{io::Write, time::Instant};
|
||||
|
||||
use clap::{CommandFactory, Parser};
|
||||
use kdam::{tqdm, BarExt, Column, RichProgress, Spinner, term::Colorizer};
|
||||
use streamshare::{delete, upload};
|
||||
use std::io::{stderr, IsTerminal};
|
||||
use std::fs;
|
||||
use std::time::Duration;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(name = "toss", version, about, long_about = None)]
|
||||
|
@ -18,7 +22,7 @@ struct Args {
|
|||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
async fn main() -> std::io::Result<()> {
|
||||
let args = Args::parse();
|
||||
|
||||
if let Some(delete_param) = args.delete {
|
||||
|
@ -31,50 +35,83 @@ async fn main() {
|
|||
eprintln!("Invalid format for --delete. Use 'file_identifier/deletion_token' (e.g., 'abc123/def456')");
|
||||
}
|
||||
} else if let Some(file_path) = args.file {
|
||||
let start_time = Instant::now();
|
||||
let mut file_size: u64 = 0;
|
||||
|
||||
let show_progress = |uploaded_bytes, total_bytes| {
|
||||
let percentage = (uploaded_bytes as f64 / total_bytes as f64) * 100.0;
|
||||
let uploaded = readable(uploaded_bytes);
|
||||
let total = readable(total_bytes);
|
||||
let elapsed_secs = start_time.elapsed().as_secs_f64();
|
||||
let speed = readable((uploaded_bytes as f64 / elapsed_secs) as u64);
|
||||
file_size = total_bytes;
|
||||
kdam::term::init(stderr().is_terminal());
|
||||
kdam::term::hide_cursor()?;
|
||||
|
||||
print!(
|
||||
"\r\x1b[2K{:.2}% {}/{} ({}/s)",
|
||||
percentage, uploaded, total, speed
|
||||
);
|
||||
std::io::stdout().flush().unwrap();
|
||||
};
|
||||
let file_size = fs::metadata(&file_path)?.len();
|
||||
|
||||
match upload(&file_path, show_progress).await {
|
||||
let pb = RichProgress::new(
|
||||
tqdm!(
|
||||
total = file_size as usize,
|
||||
unit_scale = true,
|
||||
unit_divisor = 1024,
|
||||
unit = "B",
|
||||
mininterval = 0.01,
|
||||
dynamic_ncols = true,
|
||||
colour = "green"
|
||||
),
|
||||
vec![
|
||||
Column::Spinner(Spinner::new(&["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"], 80.0, 1.0)),
|
||||
Column::Percentage(1),
|
||||
Column::Text("•".to_owned()),
|
||||
Column::Animation,
|
||||
Column::Text("•".to_owned()),
|
||||
Column::CountTotal,
|
||||
Column::Text("•".to_owned()),
|
||||
Column::Rate,
|
||||
Column::Text("•".to_owned()),
|
||||
Column::RemainingTime,
|
||||
],
|
||||
);
|
||||
|
||||
let pb_arc = Arc::new(Mutex::new(pb));
|
||||
let current_progress = Arc::new(Mutex::new(0));
|
||||
|
||||
let pb_arc_clone = pb_arc.clone();
|
||||
let current_progress_clone = current_progress.clone();
|
||||
|
||||
let update_thread = thread::spawn(move || {
|
||||
loop {
|
||||
thread::sleep(Duration::from_millis(50));
|
||||
let progress = *current_progress_clone.lock().unwrap();
|
||||
if progress >= file_size {
|
||||
break;
|
||||
}
|
||||
pb_arc_clone.lock().unwrap().update_to(progress as usize).unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
match upload(&file_path, move |current, _total| {
|
||||
*current_progress.lock().unwrap() = current;
|
||||
}).await {
|
||||
Ok((file_identifier, deletion_token)) => {
|
||||
let mut pb = pb_arc.lock().unwrap();
|
||||
pb.update_to(file_size as usize).unwrap();
|
||||
|
||||
println!("\n{}", "┌".to_owned() + &"─".repeat(79) + "┐");
|
||||
println!("│{:^90}│", "Upload Complete!".colorize("bold green"));
|
||||
println!("├{}┤", "─".repeat(79));
|
||||
|
||||
let download_url = format!(
|
||||
"https://streamshare.wireway.ch/download/{}",
|
||||
file_identifier
|
||||
);
|
||||
|
||||
let elapsed_secs = start_time.elapsed().as_secs_f64();
|
||||
println!(
|
||||
"\r\x1b[2K100.00% {}/{} (Upload completed in {:.2}s)",
|
||||
readable(file_size),
|
||||
readable(file_size),
|
||||
elapsed_secs
|
||||
);
|
||||
println!();
|
||||
|
||||
println!("File uploaded successfully");
|
||||
println!("Download URL: {}", download_url);
|
||||
println!("File Identifier: {}", file_identifier);
|
||||
println!("Deletion Token: {}", deletion_token);
|
||||
println!("│ {:<15} {:<31} │", "URL:".colorize("bold yellow"), download_url);
|
||||
println!("│ {:<15} {:<68} │", "File ID:".colorize("bold yellow"), file_identifier);
|
||||
println!("│ {:<15} {:<61} │", "Deletion Token:".colorize("bold yellow"), deletion_token);
|
||||
|
||||
println!("{}", "└".to_owned() + &"─".repeat(79) + "┘");
|
||||
}
|
||||
Err(e) => eprintln!("Error: {}", e),
|
||||
Err(e) => eprintln!("{}", format!("Error: {}", e).colorize("bold red")),
|
||||
}
|
||||
|
||||
update_thread.join().unwrap();
|
||||
kdam::term::show_cursor()?;
|
||||
} else {
|
||||
Args::command().print_help().unwrap();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse_delete_param(param: &str) -> Option<(&str, &str)> {
|
||||
|
@ -84,20 +121,4 @@ fn parse_delete_param(param: &str) -> Option<(&str, &str)> {
|
|||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn readable(bytes: u64) -> String {
|
||||
const KB: f64 = 1024.0;
|
||||
const MB: f64 = KB * 1024.0;
|
||||
const GB: f64 = MB * 1024.0;
|
||||
|
||||
if bytes as f64 >= GB {
|
||||
format!("{:.2}gb", bytes as f64 / GB)
|
||||
} else if bytes as f64 >= MB {
|
||||
format!("{:.2}mb", bytes as f64 / MB)
|
||||
} else if bytes as f64 >= KB {
|
||||
format!("{:.2}kb", bytes as f64 / KB)
|
||||
} else {
|
||||
format!("{}b", bytes)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue