1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412
use std::{collections::HashMap, path::PathBuf};
use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
use serde_with::skip_serializing_none;
#[derive(Debug, Clone, serde::Deserialize, PartialEq, Eq)]
pub struct BuildInfo {
/// QT version
qt: String,
/// libtorrent version
libtorrent: String,
/// Boost version
boost: String,
/// OpenSSL version
openssl: String,
/// Application bitness (e.g. 64-bit)
bitness: i8,
}
#[cfg_attr(feature = "builder", derive(typed_builder::TypedBuilder))]
#[cfg_attr(
feature = "builder",
builder(field_defaults(default, setter(strip_option)))
)]
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, PartialEq)]
#[skip_serializing_none]
pub struct Preferences {
/// Currently selected language (e.g. en_GB for English)
pub locale: Option<String>,
/// True if a subfolder should be created when adding a torrent
pub create_subfolder_enabled: Option<bool>,
/// True if torrents should be added in a Paused state
pub start_paused_enabled: Option<bool>,
/// TODO
pub auto_delete_mode: Option<i64>,
/// True if disk space should be pre-allocated for all files
pub preallocate_all: Option<bool>,
/// True if ".!qB" should be appended to incomplete files
pub incomplete_files_ext: Option<bool>,
/// True if Automatic Torrent Management is enabled by default
pub auto_tmm_enabled: Option<bool>,
/// True if torrent should be relocated when its Category changes
pub torrent_changed_tmm_enabled: Option<bool>,
/// True if torrent should be relocated when the default save path changes
pub save_path_changed_tmm_enabled: Option<bool>,
/// True if torrent should be relocated when its Category's save path
/// changes
pub category_changed_tmm_enabled: Option<bool>,
/// Default save path for torrents, separated by slashes
pub save_path: Option<String>,
/// True if folder for incomplete torrents is enabled
pub temp_path_enabled: Option<bool>,
/// Path for incomplete torrents, separated by slashes
pub temp_path: Option<String>,
/// Property: directory to watch for torrent files, value: where torrents
/// loaded from this directory should be downloaded to (see list of possible
/// values below). Slashes are used as path separators; multiple key/value
/// pairs can be specified
pub scan_dirs: Option<HashMap<PathBuf, ScanDirValue>>,
/// Path to directory to copy .torrent files to. Slashes are used as path
/// separators
pub export_dir: Option<String>,
/// Path to directory to copy .torrent files of completed downloads to.
/// Slashes are used as path separators
pub export_dir_fin: Option<String>,
/// True if e-mail notification should be enabled
pub mail_notification_enabled: Option<bool>,
/// e-mail where notifications should originate from
pub mail_notification_sender: Option<String>,
/// e-mail to send notifications to
pub mail_notification_email: Option<String>,
/// smtp server for e-mail notifications
pub mail_notification_smtp: Option<String>,
/// True if smtp server requires SSL connection
pub mail_notification_ssl_enabled: Option<bool>,
/// True if smtp server requires authentication
pub mail_notification_auth_enabled: Option<bool>,
/// Username for smtp authentication
pub mail_notification_username: Option<String>,
/// Password for smtp authentication
pub mail_notification_password: Option<String>,
/// True if external program should be run after torrent has finished
/// downloading
pub autorun_enabled: Option<bool>,
/// Program path/name/arguments to run if `autorun_enabled` is enabled; path
/// is separated by slashes; you can use `%f` and `%n` arguments, which will
/// be expanded by qBittorent as path_to_torrent_file and torrent_name (from
/// the GUI; not the .torrent file name) respectively
pub autorun_program: Option<String>,
/// True if torrent queuing is enabled
pub queueing_enabled: Option<bool>,
/// Maximum number of active simultaneous downloads
pub max_active_downloads: Option<i64>,
/// Maximum number of active simultaneous downloads and uploads
pub max_active_torrents: Option<i64>,
/// Maximum number of active simultaneous uploads
pub max_active_uploads: Option<i64>,
/// If true torrents w/o any activity (stalled ones) will not be counted towards `max_active_*` limits; see [dont_count_slow_torrents](https://www.libtorrent.org/reference-Settings.html#dont_count_slow_torrents) for more information
pub dont_count_slow_torrents: Option<bool>,
/// Download rate in KiB/s for a torrent to be considered "slow"
pub slow_torrent_dl_rate_threshold: Option<i64>,
/// Upload rate in KiB/s for a torrent to be considered "slow"
pub slow_torrent_ul_rate_threshold: Option<i64>,
/// Seconds a torrent should be inactive before considered "slow"
pub slow_torrent_inactive_timer: Option<i64>,
/// True if share ratio limit is enabled
pub max_ratio_enabled: Option<bool>,
/// Get the global share ratio limit
pub max_ratio: Option<f64>,
/// Action performed when a torrent reaches the maximum share ratio. See
/// list of possible values here below.
pub max_ratio_act: Option<i64>,
/// Port for incoming connections
pub listen_port: Option<i64>,
/// True if UPnP/NAT-PMP is enabled
pub upnp: Option<bool>,
/// True if the port is randomly selected
pub random_port: Option<bool>,
/// Global download speed limit in KiB/s; `-1` means no limit is applied
pub dl_limit: Option<i64>,
/// Global upload speed limit in KiB/s; `-1` means no limit is applied
pub up_limit: Option<i64>,
/// Maximum global number of simultaneous connections
pub max_connec: Option<i64>,
/// Maximum number of simultaneous connections per torrent
pub max_connec_per_torrent: Option<i64>,
/// Maximum number of upload slots
pub max_uploads: Option<i64>,
/// Maximum number of upload slots per torrent
pub max_uploads_per_torrent: Option<i64>,
/// Timeout in seconds for a `stopped` announce request to trackers
pub stop_tracker_timeout: Option<i64>,
/// True if the advanced libtorrent option `piece_extent_affinity` is
/// enabled
pub enable_piece_extent_affinity: Option<bool>,
/// Bittorrent Protocol to use (see list of possible values below)
pub bittorrent_protocol: Option<i64>,
/// True if `[du]l_limit` should be applied to uTP connections; this option
/// is only available in qBittorent built against libtorrent version 0.16.X
/// and higher
pub limit_utp_rate: Option<bool>,
/// True if `[du]l_limit` should be applied to estimated TCP overhead
/// (service data: e.g. packet headers)
pub limit_tcp_overhead: Option<bool>,
/// True if `[du]l_limit` should be applied to peers on the LAN
pub limit_lan_peers: Option<bool>,
/// Alternative global download speed limit in KiB/s
pub alt_dl_limit: Option<i64>,
/// Alternative global upload speed limit in KiB/s
pub alt_up_limit: Option<i64>,
/// True if alternative limits should be applied according to schedule
pub scheduler_enabled: Option<bool>,
/// Scheduler starting hour
pub schedule_from_hour: Option<i64>,
/// Scheduler starting minute
pub schedule_from_min: Option<i64>,
/// Scheduler ending hour
pub schedule_to_hour: Option<i64>,
/// Scheduler ending minute
pub schedule_to_min: Option<i64>,
/// Scheduler days. See possible values here below
pub scheduler_days: Option<i64>,
/// True if DHT is enabled
pub dht: Option<bool>,
/// True if PeX is enabled
pub pex: Option<bool>,
/// True if LSD is enabled
pub lsd: Option<bool>,
/// See list of possible values here below
pub encryption: Option<i64>,
/// If true anonymous mode will be enabled; read more
/// [here](Anonymous-Mode); this option is only available in qBittorent
/// built against libtorrent version 0.16.X and higher
pub anonymous_mode: Option<bool>,
/// See list of possible values here below
pub proxy_type: Option<i64>,
/// Proxy IP address or domain name
pub proxy_ip: Option<String>,
/// Proxy port
pub proxy_port: Option<i64>,
/// True if peer and web seed connections should be proxified; this option
/// will have any effect only in qBittorent built against libtorrent version
/// 0.16.X and higher
pub proxy_peer_connections: Option<bool>,
/// True proxy requires authentication; doesn't apply to SOCKS4 proxies
pub proxy_auth_enabled: Option<bool>,
/// Username for proxy authentication
pub proxy_username: Option<String>,
/// Password for proxy authentication
pub proxy_password: Option<String>,
/// True if proxy is only used for torrents
pub proxy_torrents_only: Option<bool>,
/// True if external IP filter should be enabled
pub ip_filter_enabled: Option<bool>,
/// Path to IP filter file (.dat, .p2p, .p2b files are supported); path is
/// separated by slashes
pub ip_filter_path: Option<String>,
/// True if IP filters are applied to trackers
pub ip_filter_trackers: Option<bool>,
/// Comma-separated list of domains to accept when performing Host header
/// validation
pub web_ui_domain_list: Option<String>,
/// IP address to use for the WebUI
pub web_ui_address: Option<String>,
/// WebUI port
pub web_ui_port: Option<i64>,
/// True if UPnP is used for the WebUI port
pub web_ui_upnp: Option<bool>,
/// WebUI username
pub web_ui_username: Option<String>,
/// For API ≥ v2.3.0: Plaintext WebUI password, not readable, write-only.
/// For API < v2.3.0: MD5 hash of WebUI password, hash is generated from the
/// following string: `username:Web UI
/// Access:plain_text_web_ui_password`
pub web_ui_password: Option<String>,
/// True if WebUI CSRF protection is enabled
pub web_ui_csrf_protection_enabled: Option<bool>,
/// True if WebUI clickjacking protection is enabled
pub web_ui_clickjacking_protection_enabled: Option<bool>,
/// True if WebUI cookie `Secure` flag is enabled
pub web_ui_secure_cookie_enabled: Option<bool>,
/// Maximum number of authentication failures before WebUI access ban
pub web_ui_max_auth_fail_count: Option<i64>,
/// WebUI access ban duration in seconds
pub web_ui_ban_duration: Option<i64>,
/// Seconds until WebUI is automatically signed off
pub web_ui_session_timeout: Option<i64>,
/// True if WebUI host header validation is enabled
pub web_ui_host_header_validation_enabled: Option<bool>,
/// True if authentication challenge for loopback address (127.0.0.1) should
/// be disabled
pub bypass_local_auth: Option<bool>,
/// True if webui authentication should be bypassed for clients whose ip
/// resides within (at least) one of the subnets on the whitelist
pub bypass_auth_subnet_whitelist_enabled: Option<bool>,
/// (White)list of ipv4/ipv6 subnets for which webui authentication should
/// be bypassed; list entries are separated by commas
pub bypass_auth_subnet_whitelist: Option<String>,
/// True if an alternative WebUI should be used
pub alternative_webui_enabled: Option<bool>,
/// File path to the alternative WebUI
pub alternative_webui_path: Option<String>,
/// True if WebUI HTTPS access is enabled
pub use_https: Option<bool>,
/// For API < v2.0.1: SSL keyfile contents (this is a not a path)
pub ssl_key: Option<String>,
/// For API < v2.0.1: SSL certificate contents (this is a not a path)
pub ssl_cert: Option<String>,
/// For API ≥ v2.0.1: Path to SSL keyfile
pub web_ui_https_key_path: Option<String>,
/// For API ≥ v2.0.1: Path to SSL certificate
pub web_ui_https_cert_path: Option<String>,
/// True if server DNS should be updated dynamically
pub dyndns_enabled: Option<bool>,
/// See list of possible values here below
pub dyndns_service: Option<i64>,
/// Username for DDNS service
pub dyndns_username: Option<String>,
/// Password for DDNS service
pub dyndns_password: Option<String>,
/// Your DDNS domain name
pub dyndns_domain: Option<String>,
/// RSS refresh interval
pub rss_refresh_interval: Option<i64>,
/// Max stored articles per RSS feed
pub rss_max_articles_per_feed: Option<i64>,
/// Enable processing of RSS feeds
pub rss_processing_enabled: Option<bool>,
/// Enable auto-downloading of torrents from the RSS feeds
pub rss_auto_downloading_enabled: Option<bool>,
/// For API ≥ v2.5.1: Enable downloading of repack/proper Episodes
pub rss_download_repack_proper_episodes: Option<bool>,
/// For API ≥ v2.5.1: List of RSS Smart Episode Filters
pub rss_smart_episode_filters: Option<String>,
/// Enable automatic adding of trackers to new torrents
pub add_trackers_enabled: Option<bool>,
/// List of trackers to add to new torrent
pub add_trackers: Option<String>,
/// For API ≥ v2.5.1: Enable custom http headers
pub web_ui_use_custom_http_headers_enabled: Option<bool>,
/// For API ≥ v2.5.1: List of custom http headers
pub web_ui_custom_http_headers: Option<String>,
/// True enables max seeding time
pub max_seeding_time_enabled: Option<bool>,
/// Number of minutes to seed a torrent
pub max_seeding_time: Option<i64>,
/// TODO
pub announce_ip: Option<String>,
/// True always announce to all tiers
pub announce_to_all_tiers: Option<bool>,
/// True always announce to all trackers in a tier
pub announce_to_all_trackers: Option<bool>,
/// Number of asynchronous I/O threads
pub async_io_threads: Option<i64>,
/// List of banned IPs
#[serde(rename = "banned_IPs")]
pub banned_ips: Option<String>,
/// Outstanding memory when checking torrents in MiB
pub checking_memory_use: Option<i64>,
/// IP Address to bind to. Empty String means All addresses
pub current_interface_address: Option<String>,
/// Network Interface used
pub current_network_interface: Option<String>,
/// Disk cache used in MiB
pub disk_cache: Option<i64>,
/// Disk cache expiry interval in seconds
pub disk_cache_ttl: Option<i64>,
/// Port used for embedded tracker
pub embedded_tracker_port: Option<i64>,
/// True enables coalesce reads & writes
pub enable_coalesce_read_write: Option<bool>,
/// True enables embedded tracker
pub enable_embedded_tracker: Option<bool>,
/// True allows multiple connections from the same IP address
pub enable_multi_connections_from_same_ip: Option<bool>,
/// True enables os cache
pub enable_os_cache: Option<bool>,
/// True enables sending of upload piece suggestions
pub enable_upload_suggestions: Option<bool>,
/// File pool size
pub file_pool_size: Option<i64>,
/// Maximal outgoing port (0: Disabled)
pub outgoing_ports_max: Option<i64>,
/// Minimal outgoing port (0: Disabled)
pub outgoing_ports_min: Option<i64>,
/// True rechecks torrents on completion
pub recheck_completed_torrents: Option<bool>,
/// True resolves peer countries
pub resolve_peer_countries: Option<bool>,
/// Save resume data interval in min
pub save_resume_data_interval: Option<i64>,
/// Send buffer low watermark in KiB
pub send_buffer_low_watermark: Option<i64>,
/// Send buffer watermark in KiB
pub send_buffer_watermark: Option<i64>,
/// Send buffer watermark factor in percent
pub send_buffer_watermark_factor: Option<i64>,
/// Socket backlog size
pub socket_backlog_size: Option<i64>,
/// Upload choking algorithm used (see list of possible values below)
pub upload_choking_algorithm: Option<i64>,
/// Upload slots behavior used (see list of possible values below)
pub upload_slots_behavior: Option<i64>,
/// UPnP lease duration (0: Permanent lease)
pub upnp_lease_duration: Option<i64>,
/// μTP-TCP mixed mode algorithm (see list of possible values below)
pub utp_tcp_mixed_mode: Option<i64>,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum ScanDirValue {
MonitoredFolder,
DefaultSavingPath,
Path(PathBuf),
}
impl Serialize for ScanDirValue {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
ScanDirValue::MonitoredFolder => serializer.serialize_i64(0),
ScanDirValue::DefaultSavingPath => serializer.serialize_i64(1),
ScanDirValue::Path(path) => serializer.serialize_str(path.to_str().unwrap()),
}
}
}
impl<'de> Deserialize<'de> for ScanDirValue {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(ScanDirsVisitor)
}
}
struct ScanDirsVisitor;
/// Possible values of `scan_dirs`:
///
/// Value | Description
/// ----------------------------|------------
/// `0` | Download to the monitored folder
/// `1` | Download to the default save path
/// `"/path/to/download/to"` | Download to this path
impl Visitor<'_> for ScanDirsVisitor {
type Value = ScanDirValue;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("0, 1 or a path")
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
match v {
0 => Ok(ScanDirValue::MonitoredFolder),
1 => Ok(ScanDirValue::DefaultSavingPath),
_ => Err(E::custom(format!("Invalid value for ScanDirs: {}", v))),
}
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(ScanDirValue::Path(PathBuf::from(v)))
}
}