Skip to main content

upload_precreate/
upload_precreate.rs

1use baidu_netdisk_sdk::{BaiduNetDiskClient, PrecreateOptions};
2use log::info;
3use std::fs::File;
4use std::io::{BufReader, Read};
5use std::path::Path;
6
7fn calculate_md5<P: AsRef<Path>>(path: P) -> Result<String, Box<dyn std::error::Error>> {
8    let file = File::open(path)?;
9    let mut reader = BufReader::new(file);
10    let mut buffer = Vec::new();
11    reader.read_to_end(&mut buffer)?;
12    Ok(format!("{:x}", md5::compute(&buffer)))
13}
14
15fn get_file_md5blocks<P: AsRef<Path>>(
16    path: P,
17    chunk_size: usize,
18) -> Result<(u64, Vec<String>), Box<dyn std::error::Error>> {
19    let file = File::open(path)?;
20    let metadata = file.metadata()?;
21    let total_size = metadata.len() as u64;
22
23    let mut reader = BufReader::new(file);
24    let mut buffer = Vec::new();
25    let mut block_list = Vec::new();
26
27    loop {
28        buffer.clear();
29        let bytes_read = reader
30            .by_ref()
31            .take(chunk_size as u64)
32            .read_to_end(&mut buffer)?;
33        if bytes_read == 0 {
34            break;
35        }
36        block_list.push(format!("{:x}", md5::compute(&buffer)));
37    }
38
39    Ok((total_size, block_list))
40}
41
42#[tokio::main]
43async fn main() -> Result<(), Box<dyn std::error::Error>> {
44    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
45
46    let client = BaiduNetDiskClient::builder().build()?;
47    info!("Client created successfully");
48
49    client.load_token_from_env()?;
50    info!("Token loaded successfully");
51
52    let args: Vec<String> = std::env::args().collect();
53
54    if args.len() < 3 {
55        println!("Usage: {} <local_file> <remote_path>", args[0]);
56        println!("Example: {} test.txt /apps/test/test.txt", args[0]);
57        return Ok(());
58    }
59
60    let local_file = &args[1];
61    let remote_path = &args[2];
62
63    println!("=== Baidu NetDisk Preupload Test ===");
64    println!("Local file: {}", local_file);
65    println!("Remote path: {}", remote_path);
66    println!();
67
68    let (file_size, block_list) = get_file_md5blocks(local_file, 4 * 1024 * 1024)?;
69    let file_md5 = calculate_md5(local_file)?;
70
71    println!("File size: {} bytes", file_size);
72    println!("File MD5: {}", file_md5);
73    println!("Block count: {}", block_list.len());
74    println!("Block list: {:?}", block_list);
75    println!();
76
77    let options = PrecreateOptions::new(remote_path, file_size, block_list)
78        .content_md5(&file_md5)
79        .rtype(1);
80
81    println!("Sending precreate request...");
82    match client.upload().precreate(options).await {
83        Ok(response) => {
84            println!("Precreate success!");
85            println!("  Upload ID: {}", response.uploadid);
86            println!("  Path: {:?}", response.path);
87            println!("  Return type: {}", response.return_type);
88            println!("  Block list to upload: {:?}", response.block_list);
89        }
90        Err(e) => {
91            println!("Precreate failed: {}", e);
92        }
93    }
94
95    Ok(())
96}