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