added file handling the calls

This commit is contained in:
hendrik 2024-10-12 04:32:54 +02:00
parent 43663f8d0e
commit 8829a7766f
4 changed files with 174 additions and 144 deletions

157
src/cmd.rs Normal file
View File

@ -0,0 +1,157 @@
use crate::utils::ouput_gen::*;
use crate::{
encode::bedecode::decode_bencoded_single_value,
magnet::{magnet_handler::*, parse::parse_magnet},
tcp::downloader::{download_and_save_file, download_and_save_sing_piece},
torrent::{file_parse::parse_file, meta::TorrentMeta},
tracker::exec::get_peers,
};
use std::fs;
use std::hash::Hash;
#[derive(Hash, PartialEq, Eq)]
pub enum Command {
Decode,
Info,
Peers,
Handshake,
DownloadPiece,
Download,
MagnetParse,
MagnetHandshake,
MagnetInfo,
MagnetDownloadPiece,
MagnetDownload,
}
fn get_file_contents(filename: &str) -> Vec<u8> {
fs::read(filename).unwrap_or_else(|_| {
eprintln!("Failed to read file {}", filename);
Vec::new()
})
}
pub fn parse_cmd(cmd: &str) -> Command {
match cmd {
"decode" => Command::Decode,
"info" => Command::Info,
"peers" => Command::Peers,
"handshake" => Command::Handshake,
"download_piece" => Command::DownloadPiece,
"download" => Command::Download,
"magnet_parse" => Command::MagnetParse,
"magnet_handshake" => Command::MagnetHandshake,
"magnet_info" => Command::MagnetInfo,
"magnet_download_piece" => Command::MagnetDownloadPiece,
"magnet_download" => Command::MagnetDownload,
_ => panic!("Unknown command"),
}
}
impl Command {
pub async fn call(self, obj: Vec<String>) -> String {
match self {
Command::Decode => decode(obj.as_slice()).await,
Command::Info => info(obj.as_slice()).await,
Command::Peers => peers(obj.as_slice()).await,
Command::Handshake => handshake(obj.as_slice()).await,
Command::DownloadPiece => download_piece(obj.as_slice()).await,
Command::Download => download(obj.as_slice()).await,
Command::MagnetParse => magnet_parse(obj.as_slice()).await,
Command::MagnetHandshake => magnet_handshake(obj.as_slice()).await,
Command::MagnetInfo => magnet_info(obj.as_slice()).await,
Command::MagnetDownloadPiece => magnet_download_piece(obj.as_slice()).await,
Command::MagnetDownload => magnet_download(obj.as_slice()).await,
}
}
}
async fn decode(obj: &[String]) -> String {
let encoded_value = &obj[0];
let decoded_value = decode_bencoded_single_value(encoded_value.as_bytes());
format!("{}", display(&decoded_value))
}
async fn info(obj: &[String]) -> String {
let file_content = get_file_contents(&obj[0]);
let parsed_file = parse_file(&file_content);
format!("{}", parsed_file)
}
async fn peers(obj: &[String]) -> String {
let file_content = get_file_contents(&obj[0]);
let parsed_file = parse_file(&file_content);
let ips = get_peers(&parsed_file).await.expect("Expected ips");
format!("{}", display_ips(ips))
}
async fn handshake(obj: &[String]) -> String {
let file_content = get_file_contents(&obj[0]);
let parsed_file: TorrentMeta = parse_file(&file_content);
let handshake_response = make_handshake(&parsed_file)
.await
.expect("handshake response not parseable");
format!("{}", display_peer(handshake_response))
}
async fn download_piece(obj: &[String]) -> String {
let file_content = get_file_contents(&obj[2]);
let parsed_file = parse_file(&file_content);
let ips = get_peers(&parsed_file).await.expect("Expected ips");
let _ = download_and_save_sing_piece(
parsed_file,
ips,
obj[3].clone().parse::<usize>().unwrap(),
obj[1].clone().to_owned(),
)
.await;
String::new()
}
async fn download(obj: &[String]) -> String {
let file_content = get_file_contents(&obj[2]);
let parsed_file = parse_file(&file_content);
let ips = get_peers(&parsed_file).await.expect("Expected ips");
let _ = download_and_save_file(parsed_file, ips, obj[1].to_owned()).await;
String::new()
}
async fn magnet_parse(obj: &[String]) -> String {
let magnet = &obj[0];
format!("{}", parse_magnet(magnet).unwrap())
}
async fn magnet_handshake(obj: &[String]) -> String {
let magnet_link = &obj[0];
let magnet = parse_magnet(magnet_link).expect("parse err");
let handshake_response = make_extended_handshake(magnet)
.await
.expect("handshake response not parseable");
print_magnet_handshake(&handshake_response)
}
async fn magnet_info(obj: &[String]) -> String {
let magnet_link = &obj[0];
let magnet = parse_magnet(magnet_link).expect("parse err");
let meta_data = extend_metadata(magnet).await.expect("some error");
format!("{}", meta_data)
}
async fn magnet_download_piece(obj: &[String]) -> String {
let magnet_link = &obj[2];
let magnet = parse_magnet(magnet_link).expect("parse err");
let meta_data = extend_metadata(magnet).await.expect("some error");
let ips = get_peers(&meta_data).await.expect("Expected ips");
let _ = download_and_save_sing_piece(
meta_data,
ips,
obj[3].clone().parse::<usize>().unwrap(),
obj[1].clone().to_owned(),
)
.await;
String::new()
}
async fn magnet_download(obj: &[String]) -> String {
let magnet_link = &obj[2];
let magnet = parse_magnet(magnet_link).expect("parse err");
let meta_data = extend_metadata(magnet).await.expect("some error");
let ips = get_peers(&meta_data).await.expect("Expected ips");
let _ = download_and_save_file(meta_data, ips, obj[1].clone().to_owned()).await;
String::new()
}

View File

@ -1,3 +1,4 @@
pub mod cmd;
pub mod encode;
pub mod magnet;
pub mod rand;

View File

@ -1,153 +1,25 @@
use bittorrent_starter_rust::{
encode::bedecode::decode_bencoded_single_value,
magnet::{magnet_handler::*, parse::parse_magnet},
tcp::downloader::{download_and_save_file, download_and_save_sing_piece},
torrent::{file_parse::parse_file, meta::TorrentMeta},
tracker::exec::get_peers,
cmd::parse_cmd,
utils::ouput_gen::*,
};
use std::{env, fs};
use std::env;
fn get_file_contents(filename: &str) -> Vec<u8> {
fs::read(filename).unwrap_or_else(|_| {
eprintln!("Failed to read file {}", filename);
Vec::new()
})
}
async fn run() {
let args: Vec<String> = env::args().collect();
let command = &args[1];
let cmd = parse_cmd(&command);
async fn run(command: &str, obj: &[String]) {
match command {
"decode" => {
let encoded_value = &obj[0];
let decoded_value = decode_bencoded_single_value(encoded_value.as_bytes());
println!("{}", display(&decoded_value));
}
"info" => {
let file_content = get_file_contents(&obj[0]);
let parsed_file = parse_file(&file_content);
println!("{}", parsed_file);
}
"peers" => {
let file_content = get_file_contents(&obj[0]);
let parsed_file = parse_file(&file_content);
let ips = get_peers(&parsed_file).await.expect("Expected ips");
println!("{}", display_ips(ips));
}
"handshake" => {
let file_content = get_file_contents(&obj[0]);
let parsed_file: TorrentMeta = parse_file(&file_content);
let handshake_response = make_handshake(&parsed_file)
.await
.expect("handshake response not parseable");
println!("{}", display_peer(handshake_response));
}
"download_piece" => {
let file_content = get_file_contents(&obj[2]);
let parsed_file = parse_file(&file_content);
let ips = get_peers(&parsed_file).await.expect("Expected ips");
let _ = download_and_save_sing_piece(
parsed_file,
ips,
obj[3].clone().parse::<usize>().unwrap(),
obj[1].clone(),
)
.await;
}
"download" => {
let file_content = get_file_contents(&obj[2]);
let parsed_file = parse_file(&file_content);
let ips = get_peers(&parsed_file).await.expect("Expected ips");
let _ = download_and_save_file(parsed_file, ips, obj[1].clone()).await;
}
"magnet_parse" => {
let magnet = &obj[0];
println!("{}", parse_magnet(magnet).unwrap());
}
"magnet_handshake" => {
let magnet_link = &obj[0];
//let magnet_link= "magnet:?xt=urn:btih:ad42ce8109f54c99613ce38f9b4d87e70f24a165&dn=magnet1.gif&tr=http%3A%2F%2Fbittorrent-test-tracker.codecrafters.io%2Fannounce";
let magnet = parse_magnet(magnet_link).expect("parse err");
let handshake_response = make_extended_handshake(magnet)
.await
.expect("handshake response not parseable");
print_magnet_handshake(&handshake_response);
}
"magnet_info" => {
let magnet_link = &obj[0];
//let magnet_link= "magnet3.gif.torrent: magnet:?xt=urn:btih:c5fb9894bdaba464811b088d806bdd611ba490af&dn=magnet3.gif&tr=http%3A%2F%2Fbittorrent-test-tracker.codecrafters.io%2Fannounce";
let magnet = parse_magnet(magnet_link).expect("parse err");
let meta_data = extend_metadata(magnet).await.expect("some error");
println!("{}", meta_data);
}
"magnet_download_piece" => {
let magnet_link = &obj[2];
let magnet = parse_magnet(magnet_link).expect("parse err");
let meta_data = extend_metadata(magnet).await.expect("some error");
let ips = get_peers(&meta_data).await.expect("Expected ips");
let _ = download_and_save_sing_piece(
meta_data,
ips,
obj[3].clone().parse::<usize>().unwrap(),
obj[1].clone(),
)
.await;
}
"magnet_download" => {
let magnet_link = &obj[2];
let magnet = parse_magnet(magnet_link).expect("parse err");
let meta_data = extend_metadata(magnet).await.expect("some error");
let ips = get_peers(&meta_data).await.expect("Expected ips");
let _ = download_and_save_file(meta_data, ips, obj[1].clone()).await;
}
_ => eprintln!("unknown command: {}", command),
}
println!(
"{}",
cmd.call(args[2..].into_iter().map(|s| s.to_string()).collect())
.await
);
}
#[tokio::main]
async fn main() {
set_logging_enabled(true);
let args: Vec<String> = env::args().collect();
let command = &args[1];
run(command, &args[2..]).await;
}
/*
#[tokio::main]
async fn main_test() {
set_logging_enabled(true);
let file_content: [u8; 420] = [
100, 56, 58, 97, 110, 110, 111, 117, 110, 99, 101, 53, 53, 58, 104, 116, 116, 112, 58, 47,
47, 98, 105, 116, 116, 111, 114, 114, 101, 110, 116, 45, 116, 101, 115, 116, 45, 116, 114,
97, 99, 107, 101, 114, 46, 99, 111, 100, 101, 99, 114, 97, 102, 116, 101, 114, 115, 46,
105, 111, 47, 97, 110, 110, 111, 117, 110, 99, 101, 49, 48, 58, 99, 114, 101, 97, 116, 101,
100, 32, 98, 121, 49, 51, 58, 109, 107, 116, 111, 114, 114, 101, 110, 116, 32, 49, 46, 49,
52, 58, 105, 110, 102, 111, 100, 54, 58, 108, 101, 110, 103, 116, 104, 105, 50, 57, 57, 52,
49, 50, 48, 101, 52, 58, 110, 97, 109, 101, 49, 50, 58, 99, 111, 100, 101, 114, 99, 97,
116, 46, 103, 105, 102, 49, 50, 58, 112, 105, 101, 99, 101, 32, 108, 101, 110, 103, 116,
104, 105, 50, 54, 50, 49, 52, 52, 101, 54, 58, 112, 105, 101, 99, 101, 115, 50, 52, 48, 58,
60, 52, 48, 159, 174, 191, 1, 228, 156, 15, 99, 201, 11, 126, 220, 194, 37, 155, 106, 208,
184, 81, 155, 46, 169, 187, 55, 63, 245, 103, 246, 68, 66, 129, 86, 201, 138, 29, 0, 252,
157, 200, 19, 102, 88, 117, 54, 244, 140, 32, 152, 161, 215, 150, 146, 242, 89, 15, 217,
166, 3, 60, 97, 231, 23, 248, 192, 209, 229, 88, 80, 104, 14, 180, 81, 227, 84, 59, 98, 3,
111, 84, 231, 70, 236, 54, 159, 101, 243, 45, 69, 247, 123, 31, 28, 55, 98, 31, 185, 101,
198, 86, 112, 75, 120, 16, 126, 213, 83, 189, 8, 19, 249, 47, 239, 120, 2, 103, 192, 123,
116, 49, 184, 104, 49, 55, 210, 15, 245, 148, 177, 241, 191, 63, 136, 53, 22, 93, 104, 251,
4, 50, 189, 142, 119, 150, 8, 210, 119, 130, 183, 121, 199, 115, 128, 98, 233, 181, 10,
181, 214, 188, 4, 9, 160, 243, 169, 80, 56, 87, 102, 157, 71, 254, 117, 45, 69, 119, 234,
0, 168, 110, 230, 171, 188, 48, 205, 219, 128, 10, 11, 98, 215, 162, 150, 17, 17, 102, 216,
57, 120, 63, 82, 183, 15, 12, 144, 45, 86, 25, 107, 211, 238, 127, 55, 155, 93, 181, 126,
59, 61, 141, 185, 227, 77, 182, 59, 75, 161, 190, 39, 147, 9, 17, 170, 55, 179, 249, 151,
221, 101, 101,
];
let parsed_file = parse_file(&file_content);
let ips = get_peers(&parsed_file).await.expect("Expected ips");
println!("{}", parsed_file);
let _ = download_and_save_file(parsed_file, ips, String::new()).await;
run().await;
}
*/

View File

@ -47,18 +47,18 @@ pub fn display(sel: &Value) -> String {
}
}
pub fn print_magnet_handshake(handshake: &Handshake) {
pub fn print_magnet_handshake(handshake: &Handshake) -> String {
if let Some(ext) = handshake.extension() {
let metadata = ext
.parm_disp(ExtensionHandshakeParm::Metadata)
.expect("un parseable metadata");
println!(
format!(
"Peer ID: {}\nPeer Metadata Extension ID: {}",
handshake.peer_id(),
metadata
);
)
} else {
println!("Peer ID: {}", handshake.peer_id());
format!("Peer ID: {}", handshake.peer_id())
}
}