From 3cfbe3f2ff1895ea40661213522248f9babd76f8 Mon Sep 17 00:00:00 2001 From: ALEZ Date: Wed, 15 Nov 2023 19:53:50 +0100 Subject: [PATCH 1/3] edit readme for librqbit --- crates/librqbit/README.md | 129 +++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 1 deletion(-) diff --git a/crates/librqbit/README.md b/crates/librqbit/README.md index 32d46ee8..c10bca45 120000 --- a/crates/librqbit/README.md +++ b/crates/librqbit/README.md @@ -1 +1,128 @@ -../README.md \ No newline at end of file +# librqbit + +A torrent library 100% written in rust + +## Basic example +This is a simple on how to use this library +This program will just download a simple torrent file with a Magnet link + +```rust +use std::error::Error; +use std::path::PathBuf; +use std::sync::Arc; +use std::time::Duration; +use librqbit::{http_api_client, Magnet}; +use librqbit::session::{AddTorrentResponse, ListOnlyResponse, ManagedTorrentState, Session}; +use librqbit::spawn_utils::BlockingSpawner; +use size_format::SizeFormatterBinary as SF; +use tokio::spawn; + +const MAGNET_LINK: &str = "magnet:?..."; // Put your magnet link here + +#[tokio::main] +async fn main() -> Result<(), Box>{ + + let spawner = BlockingSpawner::new(false); + + // This function will print the torrent properties every 1s + let stats_printer = |session: Arc| async move { + loop { + session.with_torrents(|torrents| { + for (idx, torrent) in torrents.iter().enumerate() { + match &torrent.state { + ManagedTorrentState::Initializing => { + println!("[{}] initializing", idx); + }, + ManagedTorrentState::Running(handle) => { + let peer_stats = handle.torrent_state().peer_stats_snapshot(); + let stats = handle.torrent_state().stats_snapshot(); + let speed = handle.speed_estimator(); + let total = stats.total_bytes; + let progress = stats.total_bytes - stats.remaining_bytes; + let downloaded_pct = if stats.remaining_bytes == 0 { + 100f64 + } else { + (progress as f64 / total as f64) * 100f64 + }; + println!( + "[{}]: {:.2}% ({:.2}), down speed {:.2} MiB/s, fetched {}, remaining {:.2} of {:.2}, uploaded {:.2}, peers: {{live: {}, connecting: {}, queued: {}, seen: {}}}", + idx, + downloaded_pct, + SF::new(progress), + speed.download_mbps(), + SF::new(stats.fetched_bytes), + SF::new(stats.remaining_bytes), + SF::new(total), + SF::new(stats.uploaded_bytes), + peer_stats.live, + peer_stats.connecting, + peer_stats.queued, + peer_stats.seen, + ); + }, + } + } + }); + tokio::time::sleep(Duration::from_secs(1)).await; + } + }; + + // Create the torrent session, one session can have more than one torrent at the same time + let session = Arc::new( + Session::new(PathBuf::from("C:\\Anime"), spawner).await? + ); + + // Spawn the properties printer function + spawn(stats_printer(session.clone())); + + // Add the magnet link to the torrent session, you don't have to specify if it's an url or magnet, + // the library will recognize automatically for you + let handle = match session.add_torrent(MAGNET_LINK, None).await { + Ok(v) => match v { + AddTorrentResponse::AlreadyManaged(handle) => { + println!( + "torrent {:?} is already managed, downloaded to {:?}", + handle.info_hash, handle.output_folder + ); + Err(()) + } + AddTorrentResponse::ListOnly(ListOnlyResponse { + info_hash: _, + info, + only_files, + }) => { + for (idx, (filename, len)) in + info.iter_filenames_and_lengths()?.enumerate() + { + let included = match &only_files { + Some(files) => files.contains(&idx), + None => true, + }; + println!( + "File {}, size {}{}", + filename.to_string()?, + SF::new(len), + if included { "" } else { ", will skip" } + ) + } + Err(()) + } + AddTorrentResponse::Added(handle) => { + Ok(handle) + } + } + Err(err) => { + eprintln!("error adding {}: {:?}", MAGNET_LINK, err); + Err(()) + } + }; + + // Wait until the session complete the torrent download and terminate + let _ = match handle { + Ok(h) => h.wait_until_completed().await?, + _ => {}, + }; + + Ok(()) +} +``` From 11d7f8ffb2ba2c282b6c8a546bcbf2999a62c3cc Mon Sep 17 00:00:00 2001 From: ALEZ Date: Wed, 15 Nov 2023 20:21:30 +0100 Subject: [PATCH 2/3] readme correction --- crates/librqbit/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/librqbit/README.md b/crates/librqbit/README.md index c10bca45..b9fa6ca7 120000 --- a/crates/librqbit/README.md +++ b/crates/librqbit/README.md @@ -3,7 +3,7 @@ A torrent library 100% written in rust ## Basic example -This is a simple on how to use this library +This is a simple program on how to use this library This program will just download a simple torrent file with a Magnet link ```rust @@ -11,7 +11,7 @@ use std::error::Error; use std::path::PathBuf; use std::sync::Arc; use std::time::Duration; -use librqbit::{http_api_client, Magnet}; +use librqbit::Magnet; use librqbit::session::{AddTorrentResponse, ListOnlyResponse, ManagedTorrentState, Session}; use librqbit::spawn_utils::BlockingSpawner; use size_format::SizeFormatterBinary as SF; From 559bb3a194641c129b6dec167055351b8ef081d3 Mon Sep 17 00:00:00 2001 From: ALEZ Date: Wed, 15 Nov 2023 20:27:02 +0100 Subject: [PATCH 3/3] librqbit readme simplified --- crates/librqbit/README.md | 113 +++----------------------------------- 1 file changed, 7 insertions(+), 106 deletions(-) diff --git a/crates/librqbit/README.md b/crates/librqbit/README.md index b9fa6ca7..5eac475b 120000 --- a/crates/librqbit/README.md +++ b/crates/librqbit/README.md @@ -8,120 +8,21 @@ This program will just download a simple torrent file with a Magnet link ```rust use std::error::Error; -use std::path::PathBuf; -use std::sync::Arc; -use std::time::Duration; -use librqbit::Magnet; -use librqbit::session::{AddTorrentResponse, ListOnlyResponse, ManagedTorrentState, Session}; -use librqbit::spawn_utils::BlockingSpawner; -use size_format::SizeFormatterBinary as SF; -use tokio::spawn; +use librqbit::session::{AddTorrentResponse, Session}; const MAGNET_LINK: &str = "magnet:?..."; // Put your magnet link here #[tokio::main] async fn main() -> Result<(), Box>{ - let spawner = BlockingSpawner::new(false); - - // This function will print the torrent properties every 1s - let stats_printer = |session: Arc| async move { - loop { - session.with_torrents(|torrents| { - for (idx, torrent) in torrents.iter().enumerate() { - match &torrent.state { - ManagedTorrentState::Initializing => { - println!("[{}] initializing", idx); - }, - ManagedTorrentState::Running(handle) => { - let peer_stats = handle.torrent_state().peer_stats_snapshot(); - let stats = handle.torrent_state().stats_snapshot(); - let speed = handle.speed_estimator(); - let total = stats.total_bytes; - let progress = stats.total_bytes - stats.remaining_bytes; - let downloaded_pct = if stats.remaining_bytes == 0 { - 100f64 - } else { - (progress as f64 / total as f64) * 100f64 - }; - println!( - "[{}]: {:.2}% ({:.2}), down speed {:.2} MiB/s, fetched {}, remaining {:.2} of {:.2}, uploaded {:.2}, peers: {{live: {}, connecting: {}, queued: {}, seen: {}}}", - idx, - downloaded_pct, - SF::new(progress), - speed.download_mbps(), - SF::new(stats.fetched_bytes), - SF::new(stats.remaining_bytes), - SF::new(total), - SF::new(stats.uploaded_bytes), - peer_stats.live, - peer_stats.connecting, - peer_stats.queued, - peer_stats.seen, - ); - }, - } - } - }); - tokio::time::sleep(Duration::from_secs(1)).await; - } - }; - - // Create the torrent session, one session can have more than one torrent at the same time - let session = Arc::new( - Session::new(PathBuf::from("C:\\Anime"), spawner).await? - ); - - // Spawn the properties printer function - spawn(stats_printer(session.clone())); - - // Add the magnet link to the torrent session, you don't have to specify if it's an url or magnet, - // the library will recognize automatically for you + let session = Session::new("C:\\Anime", Default::default()); let handle = match session.add_torrent(MAGNET_LINK, None).await { - Ok(v) => match v { - AddTorrentResponse::AlreadyManaged(handle) => { - println!( - "torrent {:?} is already managed, downloaded to {:?}", - handle.info_hash, handle.output_folder - ); - Err(()) - } - AddTorrentResponse::ListOnly(ListOnlyResponse { - info_hash: _, - info, - only_files, - }) => { - for (idx, (filename, len)) in - info.iter_filenames_and_lengths()?.enumerate() - { - let included = match &only_files { - Some(files) => files.contains(&idx), - None => true, - }; - println!( - "File {}, size {}{}", - filename.to_string()?, - SF::new(len), - if included { "" } else { ", will skip" } - ) - } - Err(()) - } - AddTorrentResponse::Added(handle) => { - Ok(handle) - } - } - Err(err) => { - eprintln!("error adding {}: {:?}", MAGNET_LINK, err); - Err(()) - } - }; - - // Wait until the session complete the torrent download and terminate - let _ = match handle { - Ok(h) => h.wait_until_completed().await?, - _ => {}, + AddTorrentResponse::Added(handle) => { + handle + }, + resp => unimplemented!("{:?}", resp) }; + handle.wait_until_completed().await?; Ok(()) }