implement files list

This commit is contained in:
yggverse 2025-09-08 16:29:52 +03:00
parent 1dd9631c8a
commit 09dba402cd
2 changed files with 64 additions and 24 deletions

View file

@ -7,31 +7,33 @@ pub fn files(meta: &TorrentMetaV1Owned) -> String {
format!("{total} {}", total.plurify(&["file", "files", "files"]))
}
pub fn size(meta: &TorrentMetaV1Owned) -> String {
fn s(value: u64) -> String {
const KB: f32 = 1024.0;
const MB: f32 = KB * KB;
const GB: f32 = MB * KB;
pub fn size(value: u64) -> String {
const KB: f32 = 1024.0;
const MB: f32 = KB * KB;
const GB: f32 = MB * KB;
let f = value as f32;
let f = value as f32;
if f < KB {
format!("{value} 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)
}
if f < KB {
format!("{value} 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)
}
s(meta
.info
.files
.as_ref()
.map(|files| files.iter().map(|file| file.length).sum::<u64>())
.unwrap_or_default()
+ meta.info.length.unwrap_or_default())
}
pub fn total(meta: &TorrentMetaV1Owned) -> String {
size(
meta.info
.files
.as_ref()
.map(|files| files.iter().map(|file| file.length).sum::<u64>())
.unwrap_or_default()
+ meta.info.length.unwrap_or_default(),
)
}
pub fn magnet(meta: &TorrentMetaV1Owned, trackers: Option<&Vec<Url>>) -> String {

View file

@ -16,6 +16,7 @@ use std::{
fs::File,
io::{Read, Write},
net::{SocketAddr, TcpListener, TcpStream},
path::PathBuf,
str::FromStr,
sync::Arc,
thread,
@ -301,7 +302,7 @@ fn index(config: &Config, public: &Public, page: Option<usize>) -> Result<String
b.push(format!(
"{} • {} • {}\n",
torrent.time.format(&config.date),
format::size(&i),
format::total(&i),
format::files(&i),
))
}
@ -335,6 +336,19 @@ fn index(config: &Config, public: &Public, page: Option<usize>) -> Result<String
}
fn info(config: &Config, torrent: Torrent) -> Result<String> {
struct File {
path: Option<PathBuf>,
length: u64,
}
impl File {
pub fn path(&self) -> String {
self.path
.as_ref()
.map(|p| p.to_string_lossy().into())
.unwrap_or("?".into())
}
}
let i: TorrentMetaV1Owned = torrent_from_bytes(&torrent.bytes)?;
let mut b = Vec::new();
@ -351,7 +365,7 @@ fn info(config: &Config, torrent: Torrent) -> Result<String> {
b.push(format!(
"{} • {} • {}\n",
torrent.time.format(&config.date),
format::size(&i),
format::total(&i),
format::files(&i),
));
@ -360,5 +374,29 @@ fn info(config: &Config, torrent: Torrent) -> Result<String> {
format::magnet(&i, config.tracker.as_ref())
));
if let Some(files) = i.info.files.map(|files| {
let mut b = Vec::with_capacity(files.len());
for f in files {
let mut p = std::path::PathBuf::new();
b.push(File {
length: f.length,
path: match f.full_path(&mut p) {
Ok(()) => Some(p),
Err(e) => {
warn!("Filename decode error: {e}");
None
}
},
})
}
b.sort_by(|a, b| a.path.cmp(&b.path)); // @TODO optional
b
}) {
b.push("## Files".into());
for file in files {
b.push(format!("* {} ({})", file.path(), format::size(file.length)));
}
}
Ok(b.join("\n"))
}