cleanup irrelevant files on complete torrent download

This commit is contained in:
yggverse 2025-06-15 18:40:11 +03:00
parent 4cf5bbcb4e
commit 8e8b60fe31
3 changed files with 29 additions and 3 deletions

View file

@ -15,11 +15,13 @@ anyhow = "1.0"
clap = { version = "4.5", features = ["derive"] } clap = { version = "4.5", features = ["derive"] }
hyper-util = "0.1" hyper-util = "0.1"
librqbit = {version = "9.0.0-beta.0", features = ["disable-upload"]} librqbit = {version = "9.0.0-beta.0", features = ["disable-upload"]}
regex = "1.11"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
tokio = { version = "1.45", features = ["full"] } tokio = { version = "1.45", features = ["full"] }
tracing-subscriber = "0.3" tracing-subscriber = "0.3"
url = "2.5" url = "2.5"
walkdir = "2.5"
[patch.crates-io] [patch.crates-io]
librqbit = { git = "https://github.com/ikatson/rqbit.git", package = "librqbit" } librqbit = { git = "https://github.com/ikatson/rqbit.git", package = "librqbit" }
#librqbit = { version = "9.0.0-beta.0", path = "../../rqbit/crates/librqbit", package = "librqbit" } #librqbit = { version = "9.0.0-beta.0", path = "../../rqbit/crates/librqbit", package = "librqbit" }

View file

@ -83,7 +83,7 @@ async fn main() -> Result<()> {
list_only: arg.preload_regex.is_none(), list_only: arg.preload_regex.is_none(),
// the destination folder to preload files match `only_files_regex` // the destination folder to preload files match `only_files_regex`
// * e.g. images for audio albums // * e.g. images for audio albums
output_folder: storage.output_folder(&i).ok(), output_folder: storage.output_folder(&i, true).ok(),
only_files_regex: arg.preload_regex.clone(), only_files_regex: arg.preload_regex.clone(),
..Default::default() ..Default::default()
}), }),
@ -124,6 +124,10 @@ async fn main() -> Result<()> {
false, false,
) )
.await?; .await?;
// cleanup irrelevant files (see rqbit#408)
if let Some(ref r) = arg.preload_regex {
storage.purge_preload_regex(&i, r)?;
}
// ignore on the next crawl iterations for this session // ignore on the next crawl iterations for this session
index.insert(mt.info_hash().as_string()); index.insert(mt.info_hash().as_string());
} }

View file

@ -37,17 +37,37 @@ impl Storage {
Ok(p) Ok(p)
} }
pub fn output_folder(&self, infohash: &str) -> Result<String> { pub fn output_folder(&self, infohash: &str, create: bool) -> Result<String> {
let mut p = PathBuf::new(); let mut p = PathBuf::new();
p.push(&self.0); p.push(&self.0);
p.push(infohash); p.push(infohash);
if p.is_file() { if p.is_file() {
bail!("File destination is not directory!"); bail!("File destination is not directory!");
} }
if create {
fs::create_dir_all(&p)?; fs::create_dir_all(&p)?;
}
if !p.is_dir() {
bail!("Destination directory not exists!")
}
Ok(p.to_string_lossy().to_string()) Ok(p.to_string_lossy().to_string())
} }
/// Recursively remove all files match `pattern` under `infohash` location
pub fn purge_preload_regex(&self, infohash: &str, pattern: &str) -> Result<()> {
let r = regex::Regex::new(pattern)?;
for e in walkdir::WalkDir::new(self.output_folder(infohash, false)?)
.into_iter()
.filter_map(Result::ok)
{
let p = e.path();
if p.is_file() && !r.is_match(p.to_str().unwrap()) {
std::fs::remove_file(p)?;
}
}
Ok(())
}
pub fn path(&self) -> PathBuf { pub fn path(&self) -> PathBuf {
self.0.clone() self.0.clone()
} }