-
-
Save RandyMcMillan/d46b1117db6c8f9d580b00ab34b76878 to your computer and use it in GitHub Desktop.
archive.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::{ | |
io::{self, Write}, | |
path::Path, | |
}; | |
use tokio::io::AsyncWriteExt; // For async file writing | |
const DEST_DIR: &str = "torrents"; | |
#[derive(Debug, serde::Deserialize)] | |
struct Torrent { | |
url: String, | |
display_name: String, | |
torrent_size: f64, | |
} | |
#[tokio::main] // Marks the main function as an asynchronous entry point | |
async fn main() -> Result<(), Box<dyn std::error::Error>> { | |
let mut tb_input = String::new(); | |
print!( | |
"Please enter the number of terabytes worth of torrents\nwould you like to download (empty for no limit): " | |
); | |
io::stdout().flush()?; | |
io::stdin().read_line(&mut tb_input)?; | |
let tb_input = tb_input.trim(); | |
let tb: Option<f64> = if tb_input.is_empty() { | |
None | |
} else { | |
match tb_input.parse::<f64>() { | |
Ok(val) => Some((val * 100.0).round() / 100.0), // Round to 2 decimal places | |
Err(_) => { | |
eprintln!("Invalid input for terabytes. Exiting."); | |
std::process::exit(1); | |
} | |
} | |
}; | |
let mut confirm_download = String::new(); | |
println!("\nConfirm download with Y / N: "); | |
io::stdout().flush()?; | |
io::stdin().read_line(&mut confirm_download)?; | |
if confirm_download.trim().to_uppercase() != "Y" { | |
println!("Download cancelled."); | |
return Ok(()); | |
} | |
println!("Downloading torrent list..."); | |
let url = if let Some(t) = tb { | |
format!( | |
"https://annas-archive.org/dyn/generate_torrents?max_tb={}&format=json", | |
t | |
) | |
} else { | |
"https://annas-archive.org/dyn/generate_torrents?format=json".to_string() | |
}; | |
println!("{}", url); | |
// Make an asynchronous HTTP GET request | |
let client = reqwest::Client::new(); | |
let response = client.get(&url).send().await?.text().await?; | |
let torrents: Vec<Torrent> = serde_json::from_str(&response)?; | |
for torrent in &torrents { | |
println!("{:?}", torrent); | |
} | |
let length = torrents.len(); | |
let mut current = 1; | |
let dest_path = Path::new(DEST_DIR); | |
if !dest_path.exists() { | |
println!("Destination directory not found: creating now."); | |
tokio::fs::create_dir(dest_path).await?; | |
} else { | |
println!("Destination directory found! Proceeding."); | |
} | |
println!("Beginning to download torrents."); | |
for i in torrents { | |
let file_path = dest_path.join(&i.display_name); | |
// Asynchronously download the torrent file content | |
let torrent_file_response = client.get(&i.url).send().await?.bytes().await?; | |
// Asynchronously write the bytes to the file | |
let mut file = tokio::fs::File::create(&file_path).await?; | |
file.write_all(&torrent_file_response).await?; | |
println!( | |
"{}/{}: {} - {}kb ", | |
current, | |
length, | |
i.display_name, | |
(i.torrent_size / 1024.0).round() as u64 | |
); | |
current += 1; | |
} | |
println!("Torrents downloaded. Use a BitTorrent client to join the network and start seeding."); | |
Ok(()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment