qbt-clean 0.122.0

Automated rules-based cleaning of qBittorrent torrents.
#[serde_with::serde_as]
#[derive(Clone,Debug,serde::Deserialize)]
#[serde(default)]
#[serde(deny_unknown_fields)]
#[serde(rename_all="kebab-case")]
pub struct Config {
	#[serde_as(as="serde_with::FromInto<crate::SerdeBytes>")] pub target_free: u64,
	#[serde_as(as="serde_with::FromInto<crate::SerdeDuration>")] pub last_activity_min: std::time::Duration,
	#[serde_as(as="serde_with::FromInto<crate::SerdeDuration>")] pub seed_time_min: std::time::Duration,
	pub age_d_max_weight: f64,
	pub age_d_min_weight: f64,
	pub categories_allowed: std::collections::HashSet<String>,
	pub copies_weight: f64,
	pub last_activity_d_weight: f64,
	pub no_scored_torrents_weight: f64,
	pub parallelism: usize,
	pub qbt_headers: std::collections::HashMap<String, String>,
	pub qbt_url: url::Url,
	pub rules: Vec<crate::Rule>,
	pub seeder_count_min: u64,
	pub seeder_count_weight: f64,
	pub size_weight: f64,
	pub state_allowed: std::collections::HashSet<crate::TorrentState>,
}

impl Config {
	#[cfg(test)]
	pub fn empty() -> Self {
		Self {
			categories_allowed: std::collections::HashSet::new(),
			seeder_count_min: 0,
			seed_time_min: std::time::Duration::ZERO,
			last_activity_min: std::time::Duration::ZERO,
			state_allowed: std::collections::HashSet::new(),
			..Self::default()
		}
	}
}

impl Default for Config {
	fn default() -> Self {
		Config {
			age_d_max_weight: 0.0,
			age_d_min_weight: 0.0,
			categories_allowed: Default::default(),
			copies_weight: 0.0,
			last_activity_d_weight: 0.0,
			last_activity_min: std::time::Duration::from_secs(7 * 24 * 3600),
			no_scored_torrents_weight: 0.0,
			parallelism: 16,
			qbt_headers: Default::default(),
			qbt_url: "http://localhost:8080".parse().unwrap(),
			rules: Vec::new(),
			seed_time_min: std::time::Duration::from_secs(14 * 24 * 3600),
			seeder_count_min: 3,
			seeder_count_weight: 0.0,
			size_weight: 0.0,
			state_allowed: [
				crate::TorrentState::Error,
				crate::TorrentState::MissingFiles,
				crate::TorrentState::StoppedDownloading,
				crate::TorrentState::StoppedUploading,
				crate::TorrentState::UploadingForced,
				crate::TorrentState::UploadingQueued,
				crate::TorrentState::UploadingStalled,
			].into(),
			target_free: 10_000_000_000,
		}
	}
}