128 lines
3.4 KiB
Rust
128 lines
3.4 KiB
Rust
mod login;
|
|
mod update;
|
|
|
|
use clap::Parser;
|
|
use login::login_and_get_token;
|
|
use update::{upload_file_with_progress, UploadProgress};
|
|
use std::process;
|
|
|
|
#[derive(Parser)]
|
|
#[command(name = "upfs")]
|
|
#[command(about = "Upload file to UPFS server")]
|
|
struct Cli {
|
|
/// File path to upload
|
|
#[arg(short, long)]
|
|
file: String,
|
|
|
|
/// Remote file path on server
|
|
#[arg(short, long)]
|
|
remote_path: String,
|
|
|
|
/// Username for authentication
|
|
#[arg(short, long, default_value = "admin")]
|
|
username: String,
|
|
|
|
/// Password for authentication
|
|
#[arg(short, long)]
|
|
password: Option<String>,
|
|
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
let cli = Cli::parse();
|
|
|
|
// 检查文件是否存在
|
|
if !std::path::Path::new(&cli.file).exists() {
|
|
eprintln!("错误: 文件 '{}' 不存在", cli.file);
|
|
process::exit(1);
|
|
}
|
|
|
|
// 获取密码(如果没有提供则询问)
|
|
let password = match cli.password {
|
|
Some(pwd) => pwd,
|
|
None => {
|
|
println!("请输入密码:");
|
|
let mut input = String::new();
|
|
std::io::stdin().read_line(&mut input).expect("读取密码失败");
|
|
input.trim().to_string()
|
|
}
|
|
};
|
|
|
|
println!("正在登录服务器...");
|
|
|
|
// 登录获取token
|
|
let token = match login_and_get_token(cli.username, password).await {
|
|
Ok(token) => {
|
|
println!("登录成功!");
|
|
token
|
|
}
|
|
Err(e) => {
|
|
eprintln!("登录失败: {}", e);
|
|
process::exit(1);
|
|
}
|
|
};
|
|
|
|
println!("正在上传文件: {} 到远程路径: {}", cli.file, cli.remote_path);
|
|
println!("进度条说明: [进度百分比] | 上传速度 | 已用时间 | 剩余时间 | 已上传/总大小");
|
|
println!();
|
|
|
|
// 默认使用进度跟踪的上传
|
|
match upload_file_with_progress(token, &cli.file, &cli.remote_path, |progress| {
|
|
print_progress(&progress);
|
|
}).await {
|
|
Ok(response) => {
|
|
println!("\n✅ 文件上传成功!");
|
|
println!("服务器响应: {}", response.text);
|
|
}
|
|
Err(e) => {
|
|
eprintln!("\n上传过程中发生错误: {}", e);
|
|
process::exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 显示进度的函数
|
|
fn print_progress(progress: &UploadProgress) {
|
|
print!("\r\x1b[K"); // 清除从光标到行尾的内容
|
|
print!("[");
|
|
|
|
let bar_width = 30;
|
|
let filled = (progress.percentage / 100.0 * bar_width as f64) as usize;
|
|
for i in 0..bar_width {
|
|
if i < filled {
|
|
print!("=");
|
|
} else if i == filled {
|
|
print!(">");
|
|
} else {
|
|
print!(" ");
|
|
}
|
|
}
|
|
|
|
print!("] {:.1}% | {} | {} | {}",
|
|
progress.percentage,
|
|
progress.format_speed(),
|
|
progress.format_elapsed_time(),
|
|
progress.format_remaining_time()
|
|
);
|
|
|
|
print!(" | {}/{}",
|
|
format_bytes(progress.bytes_uploaded),
|
|
progress.format_bytes()
|
|
);
|
|
|
|
std::io::Write::flush(&mut std::io::stdout()).unwrap();
|
|
}
|
|
|
|
fn format_bytes(bytes: u64) -> String {
|
|
if bytes < 1024 {
|
|
format!("{} B", bytes)
|
|
} else if bytes < 1024 * 1024 {
|
|
format!("{:.2} KB", bytes as f64 / 1024.0)
|
|
} else if bytes < 1024 * 1024 * 1024 {
|
|
format!("{:.2} MB", bytes as f64 / (1024.0 * 1024.0))
|
|
} else {
|
|
format!("{:.2} GB", bytes as f64 / (1024.0 * 1024.0 * 1024.0))
|
|
}
|
|
}
|