pub async fn cmd_clean<Q: crate::Qbt>(
global: &crate::Global<Q>,
dry_run: bool,
) -> anyhow::Result<()> {
let server_state = global.qbt.server_state().await?;
let Some(to_free) = global.config.target_free.checked_sub(server_state.free_space_on_disk)
else {
eprintln!(
"Have {} free which satisfies target_free of {}, nothing to do.",
crate::FmtBytes(server_state.free_space_on_disk),
crate::FmtBytes(global.config.target_free));
return Ok(())
};
eprintln!(
"Going to free {} to hit target of {} free space.",
crate::FmtBytes(to_free),
crate::FmtBytes(global.config.target_free));
let now = std::time::SystemTime::now();
let mut groups = global.group(None).await?
.filter(|g| g.pinned.is_none())
.collect::<Vec<_>>();
groups.sort_unstable_by_key(|g| {
std::cmp::Reverse(crate::F64Ord(g.rank(&global)))
});
let mut groups = groups.into_iter();
let mut removed_bytes = 0u64;
let mut removed_groups = 0u64;
let mut removed_torrents = 0u64;
let mut hashes = Vec::new();
for g in &mut groups {
removed_bytes += g.content_size();
removed_groups += 1;
eprintln!(
"--- group {}, torrents: {} ---",
crate::FmtBytes(g.group_id()),
g.torrents.len());
hashes.clear();
for t in g.torrents {
let last_active = now.duration_since(t.torrent.last_activity)
.unwrap_or(std::time::Duration::ZERO);
eprintln!(
"DELETE {} {:?} category: {}, tracker: {:?}, seeders: {}, active: {} ratio: {:.02}",
t.torrent.hash,
t.torrent.name,
t.torrent.category,
t.torrent.tracker_host().as_deref().unwrap_or(&t.torrent.tracker),
t.torrent.seeders,
crate::FmtDuration(last_active),
t.torrent.ratio);
hashes.push(t.torrent.hash);
removed_torrents += 1;
}
if !dry_run {
global.qbt.delete_torrents(&hashes).await?;
}
if removed_bytes >= to_free { break }
}
eprintln!(
"Deleted {} torrents in {} groups. Aprox {} freed.",
removed_torrents,
removed_groups,
crate::FmtBytes(removed_bytes));
if to_free > removed_bytes {
eprintln!("No more eligible torrents to reach free space target.");
} else {
let remaining = groups.map(|g| g.content_size()).sum();
eprintln!("Free space target met. {} still available to clean.", crate::FmtBytes(remaining));
}
Ok(())
}