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}