From f49ed0e11b5791b57499f090f5cd92ae5ccdf08c Mon Sep 17 00:00:00 2001 From: yggverse Date: Mon, 7 Jul 2025 15:48:36 +0300 Subject: [PATCH] show bytes as description, implement format bytes trait --- src/format.rs | 24 ++++++++++++++++++++++++ src/index.rs | 18 +++++++++++++++--- src/index/value.rs | 10 ++++++++-- src/main.rs | 23 +++++++++++++++++------ src/rss.rs | 4 ++-- 5 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 src/format.rs diff --git a/src/format.rs b/src/format.rs new file mode 100644 index 0000000..fa2d463 --- /dev/null +++ b/src/format.rs @@ -0,0 +1,24 @@ +pub trait Format { + /// Format bytes to KB/MB/GB presentation + fn bytes(self) -> String; +} + +impl Format for u64 { + fn bytes(self) -> String { + const KB: f32 = 1024.0; + const MB: f32 = KB * KB; + const GB: f32 = MB * KB; + + let f = self as f32; + + if f < KB { + format!("{self} B") + } else if f < MB { + format!("{:.2} KB", f / KB) + } else if f < GB { + format!("{:.2} MB", f / MB) + } else { + format!("{:.2} GB", f / GB) + } + } +} diff --git a/src/index.rs b/src/index.rs index b16f3ed..43d8b23 100644 --- a/src/index.rs +++ b/src/index.rs @@ -12,14 +12,16 @@ pub struct Index { is_changed: bool, /// Store the index value in memory only when it is in use by the init options has_name: bool, + has_length: bool, } impl Index { - pub fn init(capacity: usize, has_name: bool) -> Self { + pub fn init(capacity: usize, has_name: bool, has_length: bool) -> Self { Self { index: HashMap::with_capacity(capacity), is_changed: false, has_name, + has_length, } } @@ -43,12 +45,22 @@ impl Index { self.index.values().map(|i| i.node).sum::() } - pub fn insert(&mut self, infohash: String, node: u64, name: Option) { + pub fn insert( + &mut self, + infohash: String, + node: u64, + name: Option, + length: Option, + ) { if self .index .insert( infohash, - Value::new(node, if self.has_name { name } else { None }), + Value::new( + node, + if self.has_name { name } else { None }, + if self.has_length { length } else { None }, + ), ) .is_none() { diff --git a/src/index/value.rs b/src/index/value.rs index 4198cf8..c7286d6 100644 --- a/src/index/value.rs +++ b/src/index/value.rs @@ -6,16 +6,18 @@ const NAME_MAX_LEN: usize = 125; // + 3 bytes for `...` offset @TODO optional pub struct Value { pub time: DateTime, pub node: u64, - /// Isolate by applying internal filter on value set + // Isolate by applying internal filter on value set + length: Option, name: Option, } impl Value { /// Create new `Self` with current timestamp - pub fn new(node: u64, name: Option) -> Self { + pub fn new(node: u64, name: Option, length: Option) -> Self { Self { time: Utc::now(), node, + length, name: filter_name(name), } } @@ -23,6 +25,10 @@ impl Value { pub fn name(&self) -> Option<&String> { self.name.as_ref() } + /// Get reference to the safely constructed `length` member + pub fn length(&self) -> Option { + self.length + } } /// Prevent unexpected memory usage on store values from unknown source diff --git a/src/main.rs b/src/main.rs index deef53d..e94f8f1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ mod api; mod config; mod debug; +mod format; mod index; mod peers; mod preload; @@ -11,6 +12,7 @@ mod trackers; use anyhow::Result; use config::Config; use debug::Debug; +use format::Format; use index::Index; use peers::Peers; use rss::Rss; @@ -73,7 +75,11 @@ async fn main() -> Result<()> { // begin debug.info("Crawler started"); - let mut index = Index::init(config.index_capacity, config.export_rss.is_some()); + let mut index = Index::init( + config.index_capacity, + config.export_rss.is_some(), + config.export_rss.is_some(), + ); loop { debug.info("Index queue begin..."); index.refresh(); @@ -127,7 +133,7 @@ async fn main() -> Result<()> { config.preload_max_filecount.unwrap_or_default(), ); mt.wait_until_initialized().await?; - let name = mt.with_metadata(|m| { + let (name, length) = mt.with_metadata(|m| { // init preload files list if let Some(ref p) = preload { for (id, info) in m.file_infos.iter().enumerate() { @@ -160,7 +166,7 @@ async fn main() -> Result<()> { if let Some(ref t) = torrent { save_torrent_file(t, &debug, &i, &m.torrent_bytes) } - m.info.name.as_ref().map(|n|n.to_string()) + (m.info.name.as_ref().map(|n|n.to_string()), m.info.length) })?; session.update_only_files(&mt, &only_files).await?; session.unpause(&mt).await?; @@ -175,7 +181,7 @@ async fn main() -> Result<()> { p.cleanup(&i, Some(only_files_keep))? } - index.insert(i, only_files_size, name) + index.insert(i, only_files_size, name, length) } Ok(AddTorrentResponse::ListOnly(r)) => { if let Some(ref t) = torrent { @@ -186,7 +192,12 @@ async fn main() -> Result<()> { // use `r.info` for Memory, SQLite, // Manticore and other alternative storage type - index.insert(i, 0, r.info.name.map(|n| n.to_string())) + index.insert( + i, + 0, + r.info.name.map(|n| n.to_string()), + r.info.length, + ) } // unexpected as should be deleted Ok(AddTorrentResponse::AlreadyManaged(..)) => panic!(), @@ -213,7 +224,7 @@ async fn main() -> Result<()> { rss.push( k, v.name().unwrap_or(k), - None, // @TODO + v.length().map(|l| l.bytes()), Some(&v.time.to_rfc2822()), )? } diff --git a/src/rss.rs b/src/rss.rs index ef060ed..8483c2a 100644 --- a/src/rss.rs +++ b/src/rss.rs @@ -59,7 +59,7 @@ impl Rss { &mut self, infohash: &str, title: &str, - description: Option<&str>, + description: Option, pub_date: Option<&str>, ) -> Result<()> { self.file.write_all( @@ -72,7 +72,7 @@ impl Rss { )?; if let Some(s) = description { self.file.write_all(b"")?; - self.file.write_all(escape(s).as_bytes())?; + self.file.write_all(escape(&s).as_bytes())?; self.file.write_all(b"")? } if let Some(s) = pub_date {