diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 57300f3..c641ae1 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -10,11 +10,6 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ USER vscode -# RUN rustup default nightly \ -# && cargo install cargo-expand \ -# && rustup component add rustfmt \ -# && rustup component add clippy - RUN cargo install cargo-expand \ && rustup component add rustfmt \ && rustup component add clippy diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 1c4a773..bd3c8b4 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -26,7 +26,8 @@ "tamasfe.even-better-toml", "serayuzgur.crates", "redhat.vscode-yaml", - "eamodio.gitlens" + "eamodio.gitlens", + "streetsidesoftware.code-spell-checker" ] } }, diff --git a/Cargo.lock b/Cargo.lock index f5b9100..57613ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + [[package]] name = "anyhow" version = "1.0.58" @@ -81,6 +90,22 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +[[package]] +name = "ctor" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + [[package]] name = "dissimilar" version = "1.0.4" @@ -487,6 +512,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "output_vt100" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66" +dependencies = [ + "winapi", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -534,6 +568,18 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +[[package]] +name = "pretty_assertions" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89f989ac94207d048d92db058e4f6ec7342b0971fc58d1271ca148b799b3563" +dependencies = [ + "ansi_term", + "ctor", + "diff", + "output_vt100", +] + [[package]] name = "proc-macro2" version = "1.0.40" @@ -561,6 +607,7 @@ version = "0.3.2" dependencies = [ "anyhow", "case", + "pretty_assertions", "proc-macro2", "quote", "regex", diff --git a/Cargo.toml b/Cargo.toml index 70ce1b3..fdc3024 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,4 @@ serde_json = "1.0.82" thiserror = "1.0.31" [workspace] -members = [ - "qbittorrent-web-api-gen", -] +members = ["qbittorrent-web-api-gen"] diff --git a/README.md b/README.md index 5bb548c..2eefd0a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # qBittorrent web api for Rust -This is an automatic async implementation of the qBittorrent 4.1 web api. The api generation is based on the wiki markdown file which can be found [here](https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)). +This is an automatic async implementation of the qBittorrent 4.1 web api. The api generation is based on a forked wiki markdown file describing the api which can be found [here](https://github.com/JoelWachsler/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)) and the original [here](https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)). ## Example diff --git a/qbittorrent-web-api-gen/Cargo.toml b/qbittorrent-web-api-gen/Cargo.toml index c0fd57f..d76b7b4 100644 --- a/qbittorrent-web-api-gen/Cargo.toml +++ b/qbittorrent-web-api-gen/Cargo.toml @@ -6,11 +6,17 @@ license = "MIT" keywords = ["qbittorrent"] repository = "https://github.com/JoelWachsler/qbittorrent-web-api" description = "Generated web api for qBittorrent" -exclude = ["*.txt", "tests"] +exclude = ["*.txt", "tests", "src/md_parser/token_tree_factory_tests"] +# we use trybuild instead +autotests = false [lib] proc-macro = true +[[test]] +name = "tests" +path = "tests/tests.rs" + [dependencies] syn = { version = "1.0.98", features = ["extra-traits"]} quote = "1.0.20" @@ -26,3 +32,4 @@ trybuild = { version = "1.0.63", features = ["diff"] } anyhow = "1.0.58" tokio = { version = "1.19.2", features = ["full"] } reqwest = { version = "0.11.11", features = ["json", "multipart"] } +pretty_assertions = "1.2.1" diff --git a/qbittorrent-web-api-gen/api-4_1.md b/qbittorrent-web-api-gen/api-4_1.md index cf94502..35e55f5 100644 --- a/qbittorrent-web-api-gen/api-4_1.md +++ b/qbittorrent-web-api-gen/api-4_1.md @@ -1002,17 +1002,17 @@ HTTP Status Code | Scenario The response is a JSON object with the following possible fields -Property | Type | Description -------------------------------|---------|------------ -`rid` | integer | Response ID -`full_update` | bool | Whether the response contains all the data or partial data -`torrents` | object | Property: torrent hash, value: same as [torrent list](#get-torrent-list) -`torrents_removed` | array | List of hashes of torrents removed since last request -`categories` | object | Info for categories added since last request -`categories_removed` | array | List of categories removed since last request -`tags` | array | List of tags added since last request -`tags_removed` | array | List of tags removed since last request -`server_state` | object | Global transfer info +Property | Type | Description +--------------------------------|-----------|------------ +`rid` | integer | Response ID +`full_update`_optional_ | bool | Whether the response contains all the data or partial data +`torrents`_optional_ | object | Property: torrent hash, value: same as [torrent list](#get-torrent-list), map from string to torrents object +`torrents_removed`_optional_ | array | List of hashes of torrents removed since last request +`categories`_optional_ | object | Info for categories added since last request, map from string to categories object +`categories_removed`_optional_ | array | List of categories removed since last request +`tags`_optional_ | array | List of tags added since last request +`tags_removed`_optional_ | array | List of tags removed since last request +`server_state`_optional_ | object | `server_state` object see table below Example: @@ -1029,6 +1029,74 @@ Example: } ``` +**ServerState object:** + +Property | Type | Description +------------------------------|---------|------------ +`average_time_queue` | integer | Average time queue +`dl_info_data` | number | Download info data +`dl_info_speed` | number | Download info speed +`queued_io_jobs` | integer | Queued io jobs +`total_buffers_size` | number | Total buffers size +`total_peer_connections` | integer | Total peer connections + +**Categories object:** + +Property | Type | Description +------------------------------|---------|------------ +`name` | string | Category name +`savePath` | string | Save path + +**Torrents object:** + +Property | Type | Description +--------------------------------|-----------|------------ +`added_on`_optional_ | integer | Time (Unix Epoch) when the torrent was added to the client +`amount_left`_optional_ | integer | Amount of data left to download (bytes) +`auto_tmm`_optional_ | bool | Whether this torrent is managed by Automatic Torrent Management +`availability`_optional_ | float | Percentage of file pieces currently available +`category`_optional_ | string | Category of the torrent +`completed`_optional_ | integer | Amount of transfer data completed (bytes) +`completion_on`_optional_ | integer | Time (Unix Epoch) when the torrent completed +`content_path`_optional_ | string | Absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents) +`dl_limit`_optional_ | integer | Torrent download speed limit (bytes/s). `-1` if ulimited. +`dlspeed`_optional_ | integer | Torrent download speed (bytes/s) +`downloaded`_optional_ | integer | Amount of data downloaded +`downloaded_session`_optional_ | integer | Amount of data downloaded this session +`eta`_optional_ | integer | Torrent ETA (seconds) +`f_l_piece_prio`_optional_ | bool | True if first last piece are prioritized +`force_start`_optional_ | bool | True if force start is enabled for this torrent +`hash`_optional_ | string | Torrent hash +`last_activity`_optional_ | integer | Last time (Unix Epoch) when a chunk was downloaded/uploaded +`magnet_uri`_optional_ | string | Magnet URI corresponding to this torrent +`max_ratio`_optional_ | float | Maximum share ratio until torrent is stopped from seeding/uploading +`max_seeding_time`_optional_ | integer | Maximum seeding time (seconds) until torrent is stopped from seeding +`name`_optional_ | string | Torrent name +`num_complete`_optional_ | integer | Number of seeds in the swarm +`num_incomplete`_optional_ | integer | Number of leechers in the swarm +`num_leechs`_optional_ | integer | Number of leechers connected to +`num_seeds`_optional_ | integer | Number of seeds connected to +`priority`_optional_ | integer | Torrent priority. Returns -1 if queuing is disabled or torrent is in seed mode +`progress`_optional_ | float | Torrent progress (percentage/100) +`ratio`_optional_ | float | Torrent share ratio. Max ratio value: 9999. +`ratio_limit`_optional_ | float | TODO (what is different from `max_ratio`?) +`save_path`_optional_ | string | Path where this torrent's data is stored +`seeding_time`_optional_ | integer | Torrent elapsed time while complete (seconds) +`seeding_time_limit`_optional_ | integer | TODO (what is different from `max_seeding_time`?) seeding_time_limit is a per torrent setting, when Automatic Torrent Management is disabled, furthermore then max_seeding_time is set to seeding_time_limit for this torrent. If Automatic Torrent Management is enabled, the value is -2. And if max_seeding_time is unset it have a default value -1. +`seen_complete`_optional_ | integer | Time (Unix Epoch) when this torrent was last seen complete +`seq_dl`_optional_ | bool | True if sequential download is enabled +`size`_optional_ | integer | Total size (bytes) of files selected for download +`state`_optional_ | string | Torrent state. See table here below for the possible values +`super_seeding`_optional_ | bool | True if super seeding is enabled +`tags`_optional_ | string | Comma-concatenated tag list of the torrent +`time_active`_optional_ | integer | Total active time (seconds) +`total_size`_optional_ | integer | Total size (bytes) of all file in this torrent (including unselected ones) +`tracker`_optional_ | string | The first tracker with working status. Returns empty string if no tracker is working. +`up_limit`_optional_ | integer | Torrent upload speed limit (bytes/s). `-1` if ulimited. +`uploaded`_optional_ | integer | Amount of data uploaded +`uploaded_session`_optional_ | integer | Amount of data uploaded this session +`upspeed`_optional_ | integer | Torrent upload speed (bytes/s) + ## Get torrent peers data ## Name: `torrentPeers` @@ -1756,7 +1824,7 @@ Name: `delete` Parameter | Type | Description ------------|----------|------------ `hashes` | string | The hashes of the torrents you want to delete. `hashes` can contain multiple hashes separated by `\|`, to delete multiple torrents, or set to `all`, to delete all torrents. -`deleteFiles` | If set to `true`, the downloaded data will also be deleted, otherwise has no effect. +`deleteFiles` | bool | If set to `true`, the downloaded data will also be deleted, otherwise has no effect. Example: @@ -3275,6 +3343,13 @@ Field | Type | Description ] ``` +**Category object:** + +Field | Type | Description +---------------------------|---------|------------ +`id` | string | Id +`name` | string | Name + ## Install search plugin ## Name: `installPlugin` diff --git a/qbittorrent-web-api-gen/groups.txt b/qbittorrent-web-api-gen/groups.txt index 96d8e85..e470003 100644 --- a/qbittorrent-web-api-gen/groups.txt +++ b/qbittorrent-web-api-gen/groups.txt @@ -5,43 +5,48 @@ ApiMethod { name: "login", description: Some( - "Example showing how to login and execute a command that requires authentication using `curl`:\n\n```sh\n$ curl -i --header 'Referer: http://localhost:8080' --data 'username=admin&password=adminadmin' http://localhost:8080/api/v2/auth/login\nHTTP/1.1 200 OK\nContent-Encoding:\nContent-Length: 3\nContent-Type: text/plain; charset=UTF-8\nSet-Cookie: SID=hBc7TxF76ERhvIw0jQQ4LZ7Z1jQUV0tQ; path=/\n$ curl http://localhost:8080/api/v2/torrents/info --cookie \"SID=hBc7TxF76ERhvIw0jQQ4LZ7Z1jQUV0tQ\"\n```\n\nNote: Set `Referer` or `Origin` header to the exact same domain and port as used in the HTTP query `Host` header.", + "Upon success, the response will contain a cookie with your SID. You must supply the cookie whenever you want to perform an operation that requires authentication.\n\nExample showing how to login and execute a command that requires authentication using `curl`:\n\n```sh\n$ curl -i --header 'Referer: http://localhost:8080' --data 'username=admin&password=adminadmin' http://localhost:8080/api/v2/auth/login\nHTTP/1.1 200 OK\nContent-Encoding:\nContent-Length: 3\nContent-Type: text/plain; charset=UTF-8\nSet-Cookie: SID=hBc7TxF76ERhvIw0jQQ4LZ7Z1jQUV0tQ; path=/\n$ curl http://localhost:8080/api/v2/torrents/info --cookie \"SID=hBc7TxF76ERhvIw0jQQ4LZ7Z1jQUV0tQ\"\n```\n\nNote: Set `Referer` or `Origin` header to the exact same domain and port as used in the HTTP query `Host` header.", ), - parameters: Some( - [ - String( - TypeInfo { - name: "username", - is_optional: false, + url: "login", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "username", + description: Some( + "Username used to access the WebUI", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "password", + description: Some( + "Password used to access the WebUI", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "Username used to access the WebUI", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "password", - is_optional: false, - is_list: false, - description: Some( - "Password used to access the WebUI", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "login", + }, }, ApiMethod { name: "logout", description: None, - parameters: None, - return_type: None, url: "logout", + types: CompositeTypes { + composite_types: [], + }, }, ], description: Some( @@ -54,2527 +59,452 @@ methods: [ ApiMethod { name: "version", - description: None, - parameters: None, - return_type: None, + description: Some( + "The response is a string with the application version, e.g. `v4.1.3`", + ), url: "version", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "webapiVersion", - description: None, - parameters: None, - return_type: None, + description: Some( + "The response is a string with the WebAPI version, e.g. `2.0`", + ), url: "webapiVersion", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "buildInfo", - description: None, - parameters: None, - return_type: Some( - ReturnType { - is_list: false, - parameters: [ - ReturnTypeParameter { - name: "qt", - description: "QT version", - return_type: String( - TypeInfo { - name: "qt", - is_optional: false, - is_list: false, - description: Some( - "QT version", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "libtorrent", - description: "libtorrent version", - return_type: String( - TypeInfo { - name: "libtorrent", - is_optional: false, - is_list: false, - description: Some( - "libtorrent version", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "boost", - description: "Boost version", - return_type: String( - TypeInfo { - name: "boost", - is_optional: false, - is_list: false, - description: Some( - "Boost version", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "openssl", - description: "OpenSSL version", - return_type: String( - TypeInfo { - name: "openssl", - is_optional: false, - is_list: false, - description: Some( - "OpenSSL version", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "bitness", - description: "Application bitness (e.g. 64-bit)", - return_type: Number( - TypeInfo { - name: "bitness", - is_optional: false, - is_list: false, - description: Some( - "Application bitness (e.g. 64-bit)", - ), - type_description: None, - }, - ), - }, - ], - }, + description: Some( + "The response is a JSON object containing the following fields", ), url: "buildInfo", + types: CompositeTypes { + composite_types: [ + Response( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "qt", + description: Some( + "QT version", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "libtorrent", + description: Some( + "libtorrent version", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "boost", + description: Some( + "Boost version", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "openssl", + description: Some( + "OpenSSL version", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "bitness", + description: Some( + "Application bitness (e.g. 64-bit)", + ), + is_optional: false, + is_list: false, + }, + ), + ], + is_list: false, + }, + ), + ], + }, }, ApiMethod { name: "shutdown", description: None, - parameters: None, - return_type: None, url: "shutdown", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "preferences", description: Some( - "Possible fields:\n\nPossible values of `scan_dirs`:\n\nPossible values of `scheduler_days`:\n\nPossible values of `encryption`:\n\nNB: the first options allows you to use both encrypted and unencrypted connections (this is the default); other options are mutually exclusive: e.g. by forcing encryption on you won't be able to use unencrypted connections and vice versa.\n\nPossible values of `proxy_type`:\n\nPossible values of `dyndns_service`:\n\nPossible values of `max_ratio_act`:\n\nPossible values of `bittorrent_protocol`:\n\nPossible values of `upload_choking_algorithm`:\n\nPossible values of `upload_slots_behavior`:\n\nPossible values of `utp_tcp_mixed_mode`:\n\nExample:\n\n```JSON\n{\n \"add_trackers\": \"\",\n \"add_trackers_enabled\": false,\n \"alt_dl_limit\": 10240,\n \"alt_up_limit\": 10240,\n \"alternative_webui_enabled\": false,\n \"alternative_webui_path\": \"/home/user/Documents/qbit-webui\",\n \"announce_ip\": \"\",\n \"announce_to_all_tiers\": true,\n \"announce_to_all_trackers\": false,\n \"anonymous_mode\": false,\n \"async_io_threads\": 4,\n \"auto_delete_mode\": 0,\n \"auto_tmm_enabled\": false,\n \"autorun_enabled\": false,\n \"autorun_program\": \"\",\n \"banned_IPs\": \"\",\n \"bittorrent_protocol\": 0,\n \"bypass_auth_subnet_whitelist\": \"\",\n \"bypass_auth_subnet_whitelist_enabled\": false,\n \"bypass_local_auth\": false,\n \"category_changed_tmm_enabled\": false,\n \"checking_memory_use\": 32,\n \"create_subfolder_enabled\": true,\n \"current_interface_address\": \"\",\n \"current_network_interface\": \"\",\n \"dht\": true,\n \"disk_cache\": -1,\n \"disk_cache_ttl\": 60,\n \"dl_limit\": 0,\n \"dont_count_slow_torrents\": false,\n \"dyndns_domain\": \"changeme.dyndns.org\",\n \"dyndns_enabled\": false,\n \"dyndns_password\": \"\",\n \"dyndns_service\": 0,\n \"dyndns_username\": \"\",\n \"embedded_tracker_port\": 9000,\n \"enable_coalesce_read_write\": false,\n \"enable_embedded_tracker\": false,\n \"enable_multi_connections_from_same_ip\": false,\n \"enable_os_cache\": true,\n \"enable_piece_extent_affinity\": false,\n \"enable_upload_suggestions\": false,\n \"encryption\": 0,\n \"export_dir\": \"/home/user/Downloads/all\",\n \"export_dir_fin\": \"/home/user/Downloads/completed\",\n \"file_pool_size\": 40,\n \"incomplete_files_ext\": false,\n \"ip_filter_enabled\": false,\n \"ip_filter_path\": \"\",\n \"ip_filter_trackers\": false,\n \"limit_lan_peers\": true,\n \"limit_tcp_overhead\": false,\n \"limit_utp_rate\": true,\n \"listen_port\": 58925,\n \"locale\": \"en\",\n \"lsd\": true,\n \"mail_notification_auth_enabled\": false,\n \"mail_notification_email\": \"\",\n \"mail_notification_enabled\": false,\n \"mail_notification_password\": \"\",\n \"mail_notification_sender\": \"qBittorrent_notification@example.com\",\n \"mail_notification_smtp\": \"smtp.changeme.com\",\n \"mail_notification_ssl_enabled\": false,\n \"mail_notification_username\": \"\",\n \"max_active_downloads\": 3,\n \"max_active_torrents\": 5,\n \"max_active_uploads\": 3,\n \"max_connec\": 500,\n \"max_connec_per_torrent\": 100,\n \"max_ratio\": -1,\n \"max_ratio_act\": 0,\n \"max_ratio_enabled\": false,\n \"max_seeding_time\": -1,\n \"max_seeding_time_enabled\": false,\n \"max_uploads\": -1,\n \"max_uploads_per_torrent\": -1,\n \"outgoing_ports_max\": 0,\n \"outgoing_ports_min\": 0,\n \"pex\": true,\n \"preallocate_all\": false,\n \"proxy_auth_enabled\": false,\n \"proxy_ip\": \"0.0.0.0\",\n \"proxy_password\": \"\",\n \"proxy_peer_connections\": false,\n \"proxy_port\": 8080,\n \"proxy_torrents_only\": false,\n \"proxy_type\": 0,\n \"proxy_username\": \"\",\n \"queueing_enabled\": false,\n \"random_port\": false,\n \"recheck_completed_torrents\": false,\n \"resolve_peer_countries\": true,\n \"rss_auto_downloading_enabled\":true,\n \"rss_download_repack_proper_episodes\":true,\n \"rss_max_articles_per_feed\":50,\n \"rss_processing_enabled\":true,\n \"rss_refresh_interval\":30,\n \"rss_smart_episode_filters\":\"s(\\\\d+)e(\\\\d+)\\n(\\\\d+)x(\\\\d+)\\n(\\\\d{4}[.\\\\-]\\\\d{1,2}[.\\\\-]\\\\d{1,2})\",\n \"save_path\": \"/home/user/Downloads/\",\n \"save_path_changed_tmm_enabled\": false,\n \"save_resume_data_interval\": 60,\n \"scan_dirs\":\n {\n \"/home/user/Downloads/incoming/games\": 0,\n \"/home/user/Downloads/incoming/movies\": 1,\n },\n \"schedule_from_hour\": 8,\n \"schedule_from_min\": 0,\n \"schedule_to_hour\": 20,\n \"schedule_to_min\": 0,\n \"scheduler_days\": 0,\n \"scheduler_enabled\": false,\n \"send_buffer_low_watermark\": 10,\n \"send_buffer_watermark\": 500,\n \"send_buffer_watermark_factor\": 50,\n \"slow_torrent_dl_rate_threshold\": 2,\n \"slow_torrent_inactive_timer\": 60,\n \"slow_torrent_ul_rate_threshold\": 2,\n \"socket_backlog_size\": 30,\n \"start_paused_enabled\": false,\n \"stop_tracker_timeout\": 1,\n \"temp_path\": \"/home/user/Downloads/temp\",\n \"temp_path_enabled\": false,\n \"torrent_changed_tmm_enabled\": true,\n \"up_limit\": 0,\n \"upload_choking_algorithm\": 1,\n \"upload_slots_behavior\": 0,\n \"upnp\": true,\n \"use_https\": false,\n \"utp_tcp_mixed_mode\": 0,\n \"web_ui_address\": \"*\",\n \"web_ui_ban_duration\": 3600,\n \"web_ui_clickjacking_protection_enabled\": true,\n \"web_ui_csrf_protection_enabled\": true,\n \"web_ui_custom_http_headers\": \"\",\n \"web_ui_domain_list\": \"*\",\n \"web_ui_host_header_validation_enabled\": true,\n \"web_ui_https_cert_path\": \"\",\n \"web_ui_https_key_path\": \"\",\n \"web_ui_max_auth_fail_count\": 5,\n \"web_ui_port\": 8080,\n \"web_ui_secure_cookie_enabled\": true,\n \"web_ui_session_timeout\": 3600,\n \"web_ui_upnp\": false,\n \"web_ui_use_custom_http_headers_enabled\": false,\n \"web_ui_username\": \"admin\"\n}\n```", - ), - parameters: None, - return_type: Some( - ReturnType { - is_list: false, - parameters: [ - ReturnTypeParameter { - name: "locale", - description: "Currently selected language (e.g. en_GB for English)", - return_type: String( - TypeInfo { - name: "locale", - is_optional: false, - is_list: false, - description: Some( - "Currently selected language (e.g. en_GB for English)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "create_subfolder_enabled", - description: "True if a subfolder should be created when adding a torrent", - return_type: Bool( - TypeInfo { - name: "create_subfolder_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if a subfolder should be created when adding a torrent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "start_paused_enabled", - description: "True if torrents should be added in a Paused state", - return_type: Bool( - TypeInfo { - name: "start_paused_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if torrents should be added in a Paused state", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "auto_delete_mode", - description: "TODO", - return_type: Number( - TypeInfo { - name: "auto_delete_mode", - is_optional: false, - is_list: false, - description: Some( - "TODO", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "preallocate_all", - description: "True if disk space should be pre-allocated for all files", - return_type: Bool( - TypeInfo { - name: "preallocate_all", - is_optional: false, - is_list: false, - description: Some( - "True if disk space should be pre-allocated for all files", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "incomplete_files_ext", - description: "True if \".!qB\" should be appended to incomplete files", - return_type: Bool( - TypeInfo { - name: "incomplete_files_ext", - is_optional: false, - is_list: false, - description: Some( - "True if \".!qB\" should be appended to incomplete files", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "auto_tmm_enabled", - description: "True if Automatic Torrent Management is enabled by default", - return_type: Bool( - TypeInfo { - name: "auto_tmm_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if Automatic Torrent Management is enabled by default", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "torrent_changed_tmm_enabled", - description: "True if torrent should be relocated when its Category changes", - return_type: Bool( - TypeInfo { - name: "torrent_changed_tmm_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if torrent should be relocated when its Category changes", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "save_path_changed_tmm_enabled", - description: "True if torrent should be relocated when the default save path changes", - return_type: Bool( - TypeInfo { - name: "save_path_changed_tmm_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if torrent should be relocated when the default save path changes", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "category_changed_tmm_enabled", - description: "True if torrent should be relocated when its Category's save path changes", - return_type: Bool( - TypeInfo { - name: "category_changed_tmm_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if torrent should be relocated when its Category's save path changes", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "save_path", - description: "Default save path for torrents, separated by slashes", - return_type: String( - TypeInfo { - name: "save_path", - is_optional: false, - is_list: false, - description: Some( - "Default save path for torrents, separated by slashes", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "temp_path_enabled", - description: "True if folder for incomplete torrents is enabled", - return_type: Bool( - TypeInfo { - name: "temp_path_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if folder for incomplete torrents is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "temp_path", - description: "Path for incomplete torrents, separated by slashes", - return_type: String( - TypeInfo { - name: "temp_path", - is_optional: false, - is_list: false, - description: Some( - "Path for incomplete torrents, separated by slashes", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "scan_dirs", - description: "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", - return_type: Object( - TypeInfo { - name: "scan_dirs", - is_optional: false, - is_list: false, - description: Some( - "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", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "Download to the monitored folder", - }, - TypeDescriptions { - value: "1", - description: "Download to the default save path", - }, - TypeDescriptions { - value: "\"/path/to/download/to\"", - description: "Download to this path", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "export_dir", - description: "Path to directory to copy .torrent files to. Slashes are used as path separators", - return_type: String( - TypeInfo { - name: "export_dir", - is_optional: false, - is_list: false, - description: Some( - "Path to directory to copy .torrent files to. Slashes are used as path separators", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "export_dir_fin", - description: "Path to directory to copy .torrent files of completed downloads to. Slashes are used as path separators", - return_type: String( - TypeInfo { - name: "export_dir_fin", - is_optional: false, - is_list: false, - description: Some( - "Path to directory to copy .torrent files of completed downloads to. Slashes are used as path separators", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "mail_notification_enabled", - description: "True if e-mail notification should be enabled", - return_type: Bool( - TypeInfo { - name: "mail_notification_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if e-mail notification should be enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "mail_notification_sender", - description: "e-mail where notifications should originate from", - return_type: String( - TypeInfo { - name: "mail_notification_sender", - is_optional: false, - is_list: false, - description: Some( - "e-mail where notifications should originate from", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "mail_notification_email", - description: "e-mail to send notifications to", - return_type: String( - TypeInfo { - name: "mail_notification_email", - is_optional: false, - is_list: false, - description: Some( - "e-mail to send notifications to", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "mail_notification_smtp", - description: "smtp server for e-mail notifications", - return_type: String( - TypeInfo { - name: "mail_notification_smtp", - is_optional: false, - is_list: false, - description: Some( - "smtp server for e-mail notifications", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "mail_notification_ssl_enabled", - description: "True if smtp server requires SSL connection", - return_type: Bool( - TypeInfo { - name: "mail_notification_ssl_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if smtp server requires SSL connection", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "mail_notification_auth_enabled", - description: "True if smtp server requires authentication", - return_type: Bool( - TypeInfo { - name: "mail_notification_auth_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if smtp server requires authentication", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "mail_notification_username", - description: "Username for smtp authentication", - return_type: String( - TypeInfo { - name: "mail_notification_username", - is_optional: false, - is_list: false, - description: Some( - "Username for smtp authentication", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "mail_notification_password", - description: "Password for smtp authentication", - return_type: String( - TypeInfo { - name: "mail_notification_password", - is_optional: false, - is_list: false, - description: Some( - "Password for smtp authentication", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "autorun_enabled", - description: "True if external program should be run after torrent has finished downloading", - return_type: Bool( - TypeInfo { - name: "autorun_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if external program should be run after torrent has finished downloading", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "autorun_program", - description: "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", - return_type: String( - TypeInfo { - name: "autorun_program", - is_optional: false, - is_list: false, - description: Some( - "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", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "queueing_enabled", - description: "True if torrent queuing is enabled", - return_type: Bool( - TypeInfo { - name: "queueing_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if torrent queuing is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_active_downloads", - description: "Maximum number of active simultaneous downloads", - return_type: Number( - TypeInfo { - name: "max_active_downloads", - is_optional: false, - is_list: false, - description: Some( - "Maximum number of active simultaneous downloads", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_active_torrents", - description: "Maximum number of active simultaneous downloads and uploads", - return_type: Number( - TypeInfo { - name: "max_active_torrents", - is_optional: false, - is_list: false, - description: Some( - "Maximum number of active simultaneous downloads and uploads", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_active_uploads", - description: "Maximum number of active simultaneous uploads", - return_type: Number( - TypeInfo { - name: "max_active_uploads", - is_optional: false, - is_list: false, - description: Some( - "Maximum number of active simultaneous uploads", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dont_count_slow_torrents", - description: "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", - return_type: Bool( - TypeInfo { - name: "dont_count_slow_torrents", - is_optional: false, - is_list: false, - description: Some( - "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", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "slow_torrent_dl_rate_threshold", - description: "Download rate in KiB/s for a torrent to be considered \"slow\"", - return_type: Number( - TypeInfo { - name: "slow_torrent_dl_rate_threshold", - is_optional: false, - is_list: false, - description: Some( - "Download rate in KiB/s for a torrent to be considered \"slow\"", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "slow_torrent_ul_rate_threshold", - description: "Upload rate in KiB/s for a torrent to be considered \"slow\"", - return_type: Number( - TypeInfo { - name: "slow_torrent_ul_rate_threshold", - is_optional: false, - is_list: false, - description: Some( - "Upload rate in KiB/s for a torrent to be considered \"slow\"", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "slow_torrent_inactive_timer", - description: "Seconds a torrent should be inactive before considered \"slow\"", - return_type: Number( - TypeInfo { - name: "slow_torrent_inactive_timer", - is_optional: false, - is_list: false, - description: Some( - "Seconds a torrent should be inactive before considered \"slow\"", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_ratio_enabled", - description: "True if share ratio limit is enabled", - return_type: Bool( - TypeInfo { - name: "max_ratio_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if share ratio limit is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_ratio", - description: "Get the global share ratio limit", - return_type: Float( - TypeInfo { - name: "max_ratio", - is_optional: false, - is_list: false, - description: Some( - "Get the global share ratio limit", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_ratio_act", - description: "Action performed when a torrent reaches the maximum share ratio. See list of possible values here below.", - return_type: Number( - TypeInfo { - name: "max_ratio_act", - is_optional: false, - is_list: false, - description: Some( - "Action performed when a torrent reaches the maximum share ratio. See list of possible values here below.", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "Pause torrent", - }, - TypeDescriptions { - value: "1", - description: "Remove torrent", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "listen_port", - description: "Port for incoming connections", - return_type: Number( - TypeInfo { - name: "listen_port", - is_optional: false, - is_list: false, - description: Some( - "Port for incoming connections", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "upnp", - description: "True if UPnP/NAT-PMP is enabled", - return_type: Bool( - TypeInfo { - name: "upnp", - is_optional: false, - is_list: false, - description: Some( - "True if UPnP/NAT-PMP is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "random_port", - description: "True if the port is randomly selected", - return_type: Bool( - TypeInfo { - name: "random_port", - is_optional: false, - is_list: false, - description: Some( - "True if the port is randomly selected", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dl_limit", - description: "Global download speed limit in KiB/s; -1 means no limit is applied", - return_type: Number( - TypeInfo { - name: "dl_limit", - is_optional: false, - is_list: false, - description: Some( - "Global download speed limit in KiB/s; -1 means no limit is applied", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "up_limit", - description: "Global upload speed limit in KiB/s; -1 means no limit is applied", - return_type: Number( - TypeInfo { - name: "up_limit", - is_optional: false, - is_list: false, - description: Some( - "Global upload speed limit in KiB/s; -1 means no limit is applied", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_connec", - description: "Maximum global number of simultaneous connections", - return_type: Number( - TypeInfo { - name: "max_connec", - is_optional: false, - is_list: false, - description: Some( - "Maximum global number of simultaneous connections", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_connec_per_torrent", - description: "Maximum number of simultaneous connections per torrent", - return_type: Number( - TypeInfo { - name: "max_connec_per_torrent", - is_optional: false, - is_list: false, - description: Some( - "Maximum number of simultaneous connections per torrent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_uploads", - description: "Maximum number of upload slots", - return_type: Number( - TypeInfo { - name: "max_uploads", - is_optional: false, - is_list: false, - description: Some( - "Maximum number of upload slots", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_uploads_per_torrent", - description: "Maximum number of upload slots per torrent", - return_type: Number( - TypeInfo { - name: "max_uploads_per_torrent", - is_optional: false, - is_list: false, - description: Some( - "Maximum number of upload slots per torrent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "stop_tracker_timeout", - description: "Timeout in seconds for a stopped announce request to trackers", - return_type: Number( - TypeInfo { - name: "stop_tracker_timeout", - is_optional: false, - is_list: false, - description: Some( - "Timeout in seconds for a stopped announce request to trackers", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "enable_piece_extent_affinity", - description: "True if the advanced libtorrent option piece_extent_affinity is enabled", - return_type: Bool( - TypeInfo { - name: "enable_piece_extent_affinity", - is_optional: false, - is_list: false, - description: Some( - "True if the advanced libtorrent option piece_extent_affinity is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "bittorrent_protocol", - description: "Bittorrent Protocol to use (see list of possible values below)", - return_type: Number( - TypeInfo { - name: "bittorrent_protocol", - is_optional: false, - is_list: false, - description: Some( - "Bittorrent Protocol to use (see list of possible values below)", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "TCP and μTP", - }, - TypeDescriptions { - value: "1", - description: "TCP", - }, - TypeDescriptions { - value: "2", - description: "μTP", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "limit_utp_rate", - description: "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", - return_type: Bool( - TypeInfo { - name: "limit_utp_rate", - is_optional: false, - is_list: false, - description: Some( - "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", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "limit_tcp_overhead", - description: "True if [du]l_limit should be applied to estimated TCP overhead (service data: e.g. packet headers)", - return_type: Bool( - TypeInfo { - name: "limit_tcp_overhead", - is_optional: false, - is_list: false, - description: Some( - "True if [du]l_limit should be applied to estimated TCP overhead (service data: e.g. packet headers)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "limit_lan_peers", - description: "True if [du]l_limit should be applied to peers on the LAN", - return_type: Bool( - TypeInfo { - name: "limit_lan_peers", - is_optional: false, - is_list: false, - description: Some( - "True if [du]l_limit should be applied to peers on the LAN", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "alt_dl_limit", - description: "Alternative global download speed limit in KiB/s", - return_type: Number( - TypeInfo { - name: "alt_dl_limit", - is_optional: false, - is_list: false, - description: Some( - "Alternative global download speed limit in KiB/s", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "alt_up_limit", - description: "Alternative global upload speed limit in KiB/s", - return_type: Number( - TypeInfo { - name: "alt_up_limit", - is_optional: false, - is_list: false, - description: Some( - "Alternative global upload speed limit in KiB/s", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "scheduler_enabled", - description: "True if alternative limits should be applied according to schedule", - return_type: Bool( - TypeInfo { - name: "scheduler_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if alternative limits should be applied according to schedule", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "schedule_from_hour", - description: "Scheduler starting hour", - return_type: Number( - TypeInfo { - name: "schedule_from_hour", - is_optional: false, - is_list: false, - description: Some( - "Scheduler starting hour", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "schedule_from_min", - description: "Scheduler starting minute", - return_type: Number( - TypeInfo { - name: "schedule_from_min", - is_optional: false, - is_list: false, - description: Some( - "Scheduler starting minute", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "schedule_to_hour", - description: "Scheduler ending hour", - return_type: Number( - TypeInfo { - name: "schedule_to_hour", - is_optional: false, - is_list: false, - description: Some( - "Scheduler ending hour", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "schedule_to_min", - description: "Scheduler ending minute", - return_type: Number( - TypeInfo { - name: "schedule_to_min", - is_optional: false, - is_list: false, - description: Some( - "Scheduler ending minute", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "scheduler_days", - description: "Scheduler days. See possible values here below", - return_type: Number( - TypeInfo { - name: "scheduler_days", - is_optional: false, - is_list: false, - description: Some( - "Scheduler days. See possible values here below", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "Every day", - }, - TypeDescriptions { - value: "1", - description: "Every weekday", - }, - TypeDescriptions { - value: "2", - description: "Every weekend", - }, - TypeDescriptions { - value: "3", - description: "Every Monday", - }, - TypeDescriptions { - value: "4", - description: "Every Tuesday", - }, - TypeDescriptions { - value: "5", - description: "Every Wednesday", - }, - TypeDescriptions { - value: "6", - description: "Every Thursday", - }, - TypeDescriptions { - value: "7", - description: "Every Friday", - }, - TypeDescriptions { - value: "8", - description: "Every Saturday", - }, - TypeDescriptions { - value: "9", - description: "Every Sunday", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "dht", - description: "True if DHT is enabled", - return_type: Bool( - TypeInfo { - name: "dht", - is_optional: false, - is_list: false, - description: Some( - "True if DHT is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "pex", - description: "True if PeX is enabled", - return_type: Bool( - TypeInfo { - name: "pex", - is_optional: false, - is_list: false, - description: Some( - "True if PeX is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "lsd", - description: "True if LSD is enabled", - return_type: Bool( - TypeInfo { - name: "lsd", - is_optional: false, - is_list: false, - description: Some( - "True if LSD is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "encryption", - description: "See list of possible values here below", - return_type: Number( - TypeInfo { - name: "encryption", - is_optional: false, - is_list: false, - description: Some( - "See list of possible values here below", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "Prefer encryption", - }, - TypeDescriptions { - value: "1", - description: "Force encryption on", - }, - TypeDescriptions { - value: "2", - description: "Force encryption off", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "anonymous_mode", - description: "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", - return_type: Bool( - TypeInfo { - name: "anonymous_mode", - is_optional: false, - is_list: false, - description: Some( - "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", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "proxy_type", - description: "See list of possible values here below", - return_type: Number( - TypeInfo { - name: "proxy_type", - is_optional: false, - is_list: false, - description: Some( - "See list of possible values here below", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "-1", - description: "Proxy is disabled", - }, - TypeDescriptions { - value: "1", - description: "HTTP proxy without authentication", - }, - TypeDescriptions { - value: "2", - description: "SOCKS5 proxy without authentication", - }, - TypeDescriptions { - value: "3", - description: "HTTP proxy with authentication", - }, - TypeDescriptions { - value: "4", - description: "SOCKS5 proxy with authentication", - }, - TypeDescriptions { - value: "5", - description: "SOCKS4 proxy without authentication", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "proxy_ip", - description: "Proxy IP address or domain name", - return_type: String( - TypeInfo { - name: "proxy_ip", - is_optional: false, - is_list: false, - description: Some( - "Proxy IP address or domain name", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "proxy_port", - description: "Proxy port", - return_type: Number( - TypeInfo { - name: "proxy_port", - is_optional: false, - is_list: false, - description: Some( - "Proxy port", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "proxy_peer_connections", - description: "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", - return_type: Bool( - TypeInfo { - name: "proxy_peer_connections", - is_optional: false, - is_list: false, - description: Some( - "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", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "proxy_auth_enabled", - description: "True proxy requires authentication; doesn't apply to SOCKS4 proxies", - return_type: Bool( - TypeInfo { - name: "proxy_auth_enabled", - is_optional: false, - is_list: false, - description: Some( - "True proxy requires authentication; doesn't apply to SOCKS4 proxies", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "proxy_username", - description: "Username for proxy authentication", - return_type: String( - TypeInfo { - name: "proxy_username", - is_optional: false, - is_list: false, - description: Some( - "Username for proxy authentication", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "proxy_password", - description: "Password for proxy authentication", - return_type: String( - TypeInfo { - name: "proxy_password", - is_optional: false, - is_list: false, - description: Some( - "Password for proxy authentication", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "proxy_torrents_only", - description: "True if proxy is only used for torrents", - return_type: Bool( - TypeInfo { - name: "proxy_torrents_only", - is_optional: false, - is_list: false, - description: Some( - "True if proxy is only used for torrents", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "ip_filter_enabled", - description: "True if external IP filter should be enabled", - return_type: Bool( - TypeInfo { - name: "ip_filter_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if external IP filter should be enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "ip_filter_path", - description: "Path to IP filter file (.dat, .p2p, .p2b files are supported); path is separated by slashes", - return_type: String( - TypeInfo { - name: "ip_filter_path", - is_optional: false, - is_list: false, - description: Some( - "Path to IP filter file (.dat, .p2p, .p2b files are supported); path is separated by slashes", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "ip_filter_trackers", - description: "True if IP filters are applied to trackers", - return_type: Bool( - TypeInfo { - name: "ip_filter_trackers", - is_optional: false, - is_list: false, - description: Some( - "True if IP filters are applied to trackers", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_domain_list", - description: "Comma-separated list of domains to accept when performing Host header validation", - return_type: String( - TypeInfo { - name: "web_ui_domain_list", - is_optional: false, - is_list: false, - description: Some( - "Comma-separated list of domains to accept when performing Host header validation", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_address", - description: "IP address to use for the WebUI", - return_type: String( - TypeInfo { - name: "web_ui_address", - is_optional: false, - is_list: false, - description: Some( - "IP address to use for the WebUI", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_port", - description: "WebUI port", - return_type: Number( - TypeInfo { - name: "web_ui_port", - is_optional: false, - is_list: false, - description: Some( - "WebUI port", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_upnp", - description: "True if UPnP is used for the WebUI port", - return_type: Bool( - TypeInfo { - name: "web_ui_upnp", - is_optional: false, - is_list: false, - description: Some( - "True if UPnP is used for the WebUI port", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_username", - description: "WebUI username", - return_type: String( - TypeInfo { - name: "web_ui_username", - is_optional: false, - is_list: false, - description: Some( - "WebUI username", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_password", - description: "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", - return_type: String( - TypeInfo { - name: "web_ui_password", - is_optional: false, - is_list: false, - description: Some( - "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", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_csrf_protection_enabled", - description: "True if WebUI CSRF protection is enabled", - return_type: Bool( - TypeInfo { - name: "web_ui_csrf_protection_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if WebUI CSRF protection is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_clickjacking_protection_enabled", - description: "True if WebUI clickjacking protection is enabled", - return_type: Bool( - TypeInfo { - name: "web_ui_clickjacking_protection_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if WebUI clickjacking protection is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_secure_cookie_enabled", - description: "True if WebUI cookie Secure flag is enabled", - return_type: Bool( - TypeInfo { - name: "web_ui_secure_cookie_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if WebUI cookie Secure flag is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_max_auth_fail_count", - description: "Maximum number of authentication failures before WebUI access ban", - return_type: Number( - TypeInfo { - name: "web_ui_max_auth_fail_count", - is_optional: false, - is_list: false, - description: Some( - "Maximum number of authentication failures before WebUI access ban", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_ban_duration", - description: "WebUI access ban duration in seconds", - return_type: Number( - TypeInfo { - name: "web_ui_ban_duration", - is_optional: false, - is_list: false, - description: Some( - "WebUI access ban duration in seconds", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_session_timeout", - description: "Seconds until WebUI is automatically signed off", - return_type: Number( - TypeInfo { - name: "web_ui_session_timeout", - is_optional: false, - is_list: false, - description: Some( - "Seconds until WebUI is automatically signed off", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_host_header_validation_enabled", - description: "True if WebUI host header validation is enabled", - return_type: Bool( - TypeInfo { - name: "web_ui_host_header_validation_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if WebUI host header validation is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "bypass_local_auth", - description: "True if authentication challenge for loopback address (127.0.0.1) should be disabled", - return_type: Bool( - TypeInfo { - name: "bypass_local_auth", - is_optional: false, - is_list: false, - description: Some( - "True if authentication challenge for loopback address (127.0.0.1) should be disabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "bypass_auth_subnet_whitelist_enabled", - description: "True if webui authentication should be bypassed for clients whose ip resides within (at least) one of the subnets on the whitelist", - return_type: Bool( - TypeInfo { - name: "bypass_auth_subnet_whitelist_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if webui authentication should be bypassed for clients whose ip resides within (at least) one of the subnets on the whitelist", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "bypass_auth_subnet_whitelist", - description: "(White)list of ipv4/ipv6 subnets for which webui authentication should be bypassed; list entries are separated by commas", - return_type: String( - TypeInfo { - name: "bypass_auth_subnet_whitelist", - is_optional: false, - is_list: false, - description: Some( - "(White)list of ipv4/ipv6 subnets for which webui authentication should be bypassed; list entries are separated by commas", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "alternative_webui_enabled", - description: "True if an alternative WebUI should be used", - return_type: Bool( - TypeInfo { - name: "alternative_webui_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if an alternative WebUI should be used", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "alternative_webui_path", - description: "File path to the alternative WebUI", - return_type: String( - TypeInfo { - name: "alternative_webui_path", - is_optional: false, - is_list: false, - description: Some( - "File path to the alternative WebUI", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "use_https", - description: "True if WebUI HTTPS access is enabled", - return_type: Bool( - TypeInfo { - name: "use_https", - is_optional: false, - is_list: false, - description: Some( - "True if WebUI HTTPS access is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "ssl_key", - description: "For API < v2.0.1: SSL keyfile contents (this is a not a path)", - return_type: String( - TypeInfo { - name: "ssl_key", - is_optional: false, - is_list: false, - description: Some( - "For API < v2.0.1: SSL keyfile contents (this is a not a path)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "ssl_cert", - description: "For API < v2.0.1: SSL certificate contents (this is a not a path)", - return_type: String( - TypeInfo { - name: "ssl_cert", - is_optional: false, - is_list: false, - description: Some( - "For API < v2.0.1: SSL certificate contents (this is a not a path)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_https_key_path", - description: "For API ≥ v2.0.1: Path to SSL keyfile", - return_type: String( - TypeInfo { - name: "web_ui_https_key_path", - is_optional: false, - is_list: false, - description: Some( - "For API ≥ v2.0.1: Path to SSL keyfile", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_https_cert_path", - description: "For API ≥ v2.0.1: Path to SSL certificate", - return_type: String( - TypeInfo { - name: "web_ui_https_cert_path", - is_optional: false, - is_list: false, - description: Some( - "For API ≥ v2.0.1: Path to SSL certificate", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dyndns_enabled", - description: "True if server DNS should be updated dynamically", - return_type: Bool( - TypeInfo { - name: "dyndns_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if server DNS should be updated dynamically", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dyndns_service", - description: "See list of possible values here below", - return_type: Number( - TypeInfo { - name: "dyndns_service", - is_optional: false, - is_list: false, - description: Some( - "See list of possible values here below", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "Use DyDNS", - }, - TypeDescriptions { - value: "1", - description: "Use NOIP", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "dyndns_username", - description: "Username for DDNS service", - return_type: String( - TypeInfo { - name: "dyndns_username", - is_optional: false, - is_list: false, - description: Some( - "Username for DDNS service", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dyndns_password", - description: "Password for DDNS service", - return_type: String( - TypeInfo { - name: "dyndns_password", - is_optional: false, - is_list: false, - description: Some( - "Password for DDNS service", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dyndns_domain", - description: "Your DDNS domain name", - return_type: String( - TypeInfo { - name: "dyndns_domain", - is_optional: false, - is_list: false, - description: Some( - "Your DDNS domain name", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "rss_refresh_interval", - description: "RSS refresh interval", - return_type: Number( - TypeInfo { - name: "rss_refresh_interval", - is_optional: false, - is_list: false, - description: Some( - "RSS refresh interval", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "rss_max_articles_per_feed", - description: "Max stored articles per RSS feed", - return_type: Number( - TypeInfo { - name: "rss_max_articles_per_feed", - is_optional: false, - is_list: false, - description: Some( - "Max stored articles per RSS feed", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "rss_processing_enabled", - description: "Enable processing of RSS feeds", - return_type: Bool( - TypeInfo { - name: "rss_processing_enabled", - is_optional: false, - is_list: false, - description: Some( - "Enable processing of RSS feeds", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "rss_auto_downloading_enabled", - description: "Enable auto-downloading of torrents from the RSS feeds", - return_type: Bool( - TypeInfo { - name: "rss_auto_downloading_enabled", - is_optional: false, - is_list: false, - description: Some( - "Enable auto-downloading of torrents from the RSS feeds", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "rss_download_repack_proper_episodes", - description: "For API ≥ v2.5.1: Enable downloading of repack/proper Episodes", - return_type: Bool( - TypeInfo { - name: "rss_download_repack_proper_episodes", - is_optional: false, - is_list: false, - description: Some( - "For API ≥ v2.5.1: Enable downloading of repack/proper Episodes", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "rss_smart_episode_filters", - description: "For API ≥ v2.5.1: List of RSS Smart Episode Filters", - return_type: String( - TypeInfo { - name: "rss_smart_episode_filters", - is_optional: false, - is_list: false, - description: Some( - "For API ≥ v2.5.1: List of RSS Smart Episode Filters", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "add_trackers_enabled", - description: "Enable automatic adding of trackers to new torrents", - return_type: Bool( - TypeInfo { - name: "add_trackers_enabled", - is_optional: false, - is_list: false, - description: Some( - "Enable automatic adding of trackers to new torrents", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "add_trackers", - description: "List of trackers to add to new torrent", - return_type: String( - TypeInfo { - name: "add_trackers", - is_optional: false, - is_list: false, - description: Some( - "List of trackers to add to new torrent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_use_custom_http_headers_enabled", - description: "For API ≥ v2.5.1: Enable custom http headers", - return_type: Bool( - TypeInfo { - name: "web_ui_use_custom_http_headers_enabled", - is_optional: false, - is_list: false, - description: Some( - "For API ≥ v2.5.1: Enable custom http headers", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_custom_http_headers", - description: "For API ≥ v2.5.1: List of custom http headers", - return_type: String( - TypeInfo { - name: "web_ui_custom_http_headers", - is_optional: false, - is_list: false, - description: Some( - "For API ≥ v2.5.1: List of custom http headers", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_seeding_time_enabled", - description: "True enables max seeding time", - return_type: Bool( - TypeInfo { - name: "max_seeding_time_enabled", - is_optional: false, - is_list: false, - description: Some( - "True enables max seeding time", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_seeding_time", - description: "Number of minutes to seed a torrent", - return_type: Number( - TypeInfo { - name: "max_seeding_time", - is_optional: false, - is_list: false, - description: Some( - "Number of minutes to seed a torrent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "announce_ip", - description: "TODO", - return_type: String( - TypeInfo { - name: "announce_ip", - is_optional: false, - is_list: false, - description: Some( - "TODO", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "announce_to_all_tiers", - description: "True always announce to all tiers", - return_type: Bool( - TypeInfo { - name: "announce_to_all_tiers", - is_optional: false, - is_list: false, - description: Some( - "True always announce to all tiers", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "announce_to_all_trackers", - description: "True always announce to all trackers in a tier", - return_type: Bool( - TypeInfo { - name: "announce_to_all_trackers", - is_optional: false, - is_list: false, - description: Some( - "True always announce to all trackers in a tier", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "async_io_threads", - description: "Number of asynchronous I/O threads", - return_type: Number( - TypeInfo { - name: "async_io_threads", - is_optional: false, - is_list: false, - description: Some( - "Number of asynchronous I/O threads", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "banned_IPs", - description: "List of banned IPs", - return_type: String( - TypeInfo { - name: "banned_IPs", - is_optional: false, - is_list: false, - description: Some( - "List of banned IPs", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "checking_memory_use", - description: "Outstanding memory when checking torrents in MiB", - return_type: Number( - TypeInfo { - name: "checking_memory_use", - is_optional: false, - is_list: false, - description: Some( - "Outstanding memory when checking torrents in MiB", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "current_interface_address", - description: "IP Address to bind to. Empty String means All addresses", - return_type: String( - TypeInfo { - name: "current_interface_address", - is_optional: false, - is_list: false, - description: Some( - "IP Address to bind to. Empty String means All addresses", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "current_network_interface", - description: "Network Interface used", - return_type: String( - TypeInfo { - name: "current_network_interface", - is_optional: false, - is_list: false, - description: Some( - "Network Interface used", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "disk_cache", - description: "Disk cache used in MiB", - return_type: Number( - TypeInfo { - name: "disk_cache", - is_optional: false, - is_list: false, - description: Some( - "Disk cache used in MiB", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "disk_cache_ttl", - description: "Disk cache expiry interval in seconds", - return_type: Number( - TypeInfo { - name: "disk_cache_ttl", - is_optional: false, - is_list: false, - description: Some( - "Disk cache expiry interval in seconds", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "embedded_tracker_port", - description: "Port used for embedded tracker", - return_type: Number( - TypeInfo { - name: "embedded_tracker_port", - is_optional: false, - is_list: false, - description: Some( - "Port used for embedded tracker", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "enable_coalesce_read_write", - description: "True enables coalesce reads & writes", - return_type: Bool( - TypeInfo { - name: "enable_coalesce_read_write", - is_optional: false, - is_list: false, - description: Some( - "True enables coalesce reads & writes", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "enable_embedded_tracker", - description: "True enables embedded tracker", - return_type: Bool( - TypeInfo { - name: "enable_embedded_tracker", - is_optional: false, - is_list: false, - description: Some( - "True enables embedded tracker", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "enable_multi_connections_from_same_ip", - description: "True allows multiple connections from the same IP address", - return_type: Bool( - TypeInfo { - name: "enable_multi_connections_from_same_ip", - is_optional: false, - is_list: false, - description: Some( - "True allows multiple connections from the same IP address", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "enable_os_cache", - description: "True enables os cache", - return_type: Bool( - TypeInfo { - name: "enable_os_cache", - is_optional: false, - is_list: false, - description: Some( - "True enables os cache", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "enable_upload_suggestions", - description: "True enables sending of upload piece suggestions", - return_type: Bool( - TypeInfo { - name: "enable_upload_suggestions", - is_optional: false, - is_list: false, - description: Some( - "True enables sending of upload piece suggestions", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "file_pool_size", - description: "File pool size", - return_type: Number( - TypeInfo { - name: "file_pool_size", - is_optional: false, - is_list: false, - description: Some( - "File pool size", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "outgoing_ports_max", - description: "Maximal outgoing port (0: Disabled)", - return_type: Number( - TypeInfo { - name: "outgoing_ports_max", - is_optional: false, - is_list: false, - description: Some( - "Maximal outgoing port (0: Disabled)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "outgoing_ports_min", - description: "Minimal outgoing port (0: Disabled)", - return_type: Number( - TypeInfo { - name: "outgoing_ports_min", - is_optional: false, - is_list: false, - description: Some( - "Minimal outgoing port (0: Disabled)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "recheck_completed_torrents", - description: "True rechecks torrents on completion", - return_type: Bool( - TypeInfo { - name: "recheck_completed_torrents", - is_optional: false, - is_list: false, - description: Some( - "True rechecks torrents on completion", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "resolve_peer_countries", - description: "True resolves peer countries", - return_type: Bool( - TypeInfo { - name: "resolve_peer_countries", - is_optional: false, - is_list: false, - description: Some( - "True resolves peer countries", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "save_resume_data_interval", - description: "Save resume data interval in min", - return_type: Number( - TypeInfo { - name: "save_resume_data_interval", - is_optional: false, - is_list: false, - description: Some( - "Save resume data interval in min", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "send_buffer_low_watermark", - description: "Send buffer low watermark in KiB", - return_type: Number( - TypeInfo { - name: "send_buffer_low_watermark", - is_optional: false, - is_list: false, - description: Some( - "Send buffer low watermark in KiB", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "send_buffer_watermark", - description: "Send buffer watermark in KiB", - return_type: Number( - TypeInfo { - name: "send_buffer_watermark", - is_optional: false, - is_list: false, - description: Some( - "Send buffer watermark in KiB", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "send_buffer_watermark_factor", - description: "Send buffer watermark factor in percent", - return_type: Number( - TypeInfo { - name: "send_buffer_watermark_factor", - is_optional: false, - is_list: false, - description: Some( - "Send buffer watermark factor in percent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "socket_backlog_size", - description: "Socket backlog size", - return_type: Number( - TypeInfo { - name: "socket_backlog_size", - is_optional: false, - is_list: false, - description: Some( - "Socket backlog size", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "upload_choking_algorithm", - description: "Upload choking algorithm used (see list of possible values below)", - return_type: Number( - TypeInfo { - name: "upload_choking_algorithm", - is_optional: false, - is_list: false, - description: Some( - "Upload choking algorithm used (see list of possible values below)", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "Round-robin", - }, - TypeDescriptions { - value: "1", - description: "Fastest upload", - }, - TypeDescriptions { - value: "2", - description: "Anti-leech", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "upload_slots_behavior", - description: "Upload slots behavior used (see list of possible values below)", - return_type: Number( - TypeInfo { - name: "upload_slots_behavior", - is_optional: false, - is_list: false, - description: Some( - "Upload slots behavior used (see list of possible values below)", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "Fixed slots", - }, - TypeDescriptions { - value: "1", - description: "Upload rate based", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "upnp_lease_duration", - description: "UPnP lease duration (0: Permanent lease)", - return_type: Number( - TypeInfo { - name: "upnp_lease_duration", - is_optional: false, - is_list: false, - description: Some( - "UPnP lease duration (0: Permanent lease)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "utp_tcp_mixed_mode", - description: "μTP-TCP mixed mode algorithm (see list of possible values below)", - return_type: Number( - TypeInfo { - name: "utp_tcp_mixed_mode", - is_optional: false, - is_list: false, - description: Some( - "μTP-TCP mixed mode algorithm (see list of possible values below)", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "Prefer TCP", - }, - TypeDescriptions { - value: "1", - description: "Peer proportional", - }, - ], - }, - ), - }, - ), - }, - ], - }, + "The response is a JSON object with several fields (key-value) pairs representing the application's settings. The contents may vary depending on which settings are present in qBittorrent.ini.\n\nPossible fields:\n\n\nPossible values of `scan_dirs`:\n\n\nPossible values of `scheduler_days`:\n\n\nPossible values of `encryption`:\n\n\nNB: the first options allows you to use both encrypted and unencrypted connections (this is the default); other options are mutually exclusive: e.g. by forcing encryption on you won't be able to use unencrypted connections and vice versa.\n\nPossible values of `proxy_type`:\n\n\nPossible values of `dyndns_service`:\n\n\nPossible values of `max_ratio_act`:\n\n\nPossible values of `bittorrent_protocol`:\n\n\nPossible values of `upload_choking_algorithm`:\n\n\nPossible values of `upload_slots_behavior`:\n\n\nPossible values of `utp_tcp_mixed_mode`:\n\n\nExample:\n\n```JSON\n{\n \"add_trackers\": \"\",\n \"add_trackers_enabled\": false,\n \"alt_dl_limit\": 10240,\n \"alt_up_limit\": 10240,\n \"alternative_webui_enabled\": false,\n \"alternative_webui_path\": \"/home/user/Documents/qbit-webui\",\n \"announce_ip\": \"\",\n \"announce_to_all_tiers\": true,\n \"announce_to_all_trackers\": false,\n \"anonymous_mode\": false,\n \"async_io_threads\": 4,\n \"auto_delete_mode\": 0,\n \"auto_tmm_enabled\": false,\n \"autorun_enabled\": false,\n \"autorun_program\": \"\",\n \"banned_IPs\": \"\",\n \"bittorrent_protocol\": 0,\n \"bypass_auth_subnet_whitelist\": \"\",\n \"bypass_auth_subnet_whitelist_enabled\": false,\n \"bypass_local_auth\": false,\n \"category_changed_tmm_enabled\": false,\n \"checking_memory_use\": 32,\n \"create_subfolder_enabled\": true,\n \"current_interface_address\": \"\",\n \"current_network_interface\": \"\",\n \"dht\": true,\n \"disk_cache\": -1,\n \"disk_cache_ttl\": 60,\n \"dl_limit\": 0,\n \"dont_count_slow_torrents\": false,\n \"dyndns_domain\": \"changeme.dyndns.org\",\n \"dyndns_enabled\": false,\n \"dyndns_password\": \"\",\n \"dyndns_service\": 0,\n \"dyndns_username\": \"\",\n \"embedded_tracker_port\": 9000,\n \"enable_coalesce_read_write\": false,\n \"enable_embedded_tracker\": false,\n \"enable_multi_connections_from_same_ip\": false,\n \"enable_os_cache\": true,\n \"enable_piece_extent_affinity\": false,\n \"enable_upload_suggestions\": false,\n \"encryption\": 0,\n \"export_dir\": \"/home/user/Downloads/all\",\n \"export_dir_fin\": \"/home/user/Downloads/completed\",\n \"file_pool_size\": 40,\n \"incomplete_files_ext\": false,\n \"ip_filter_enabled\": false,\n \"ip_filter_path\": \"\",\n \"ip_filter_trackers\": false,\n \"limit_lan_peers\": true,\n \"limit_tcp_overhead\": false,\n \"limit_utp_rate\": true,\n \"listen_port\": 58925,\n \"locale\": \"en\",\n \"lsd\": true,\n \"mail_notification_auth_enabled\": false,\n \"mail_notification_email\": \"\",\n \"mail_notification_enabled\": false,\n \"mail_notification_password\": \"\",\n \"mail_notification_sender\": \"qBittorrent_notification@example.com\",\n \"mail_notification_smtp\": \"smtp.changeme.com\",\n \"mail_notification_ssl_enabled\": false,\n \"mail_notification_username\": \"\",\n \"max_active_downloads\": 3,\n \"max_active_torrents\": 5,\n \"max_active_uploads\": 3,\n \"max_connec\": 500,\n \"max_connec_per_torrent\": 100,\n \"max_ratio\": -1,\n \"max_ratio_act\": 0,\n \"max_ratio_enabled\": false,\n \"max_seeding_time\": -1,\n \"max_seeding_time_enabled\": false,\n \"max_uploads\": -1,\n \"max_uploads_per_torrent\": -1,\n \"outgoing_ports_max\": 0,\n \"outgoing_ports_min\": 0,\n \"pex\": true,\n \"preallocate_all\": false,\n \"proxy_auth_enabled\": false,\n \"proxy_ip\": \"0.0.0.0\",\n \"proxy_password\": \"\",\n \"proxy_peer_connections\": false,\n \"proxy_port\": 8080,\n \"proxy_torrents_only\": false,\n \"proxy_type\": 0,\n \"proxy_username\": \"\",\n \"queueing_enabled\": false,\n \"random_port\": false,\n \"recheck_completed_torrents\": false,\n \"resolve_peer_countries\": true,\n \"rss_auto_downloading_enabled\":true,\n \"rss_download_repack_proper_episodes\":true,\n \"rss_max_articles_per_feed\":50,\n \"rss_processing_enabled\":true,\n \"rss_refresh_interval\":30,\n \"rss_smart_episode_filters\":\"s(\\\\d+)e(\\\\d+)\\n(\\\\d+)x(\\\\d+)\\n(\\\\d{4}[.\\\\-]\\\\d{1,2}[.\\\\-]\\\\d{1,2})\",\n \"save_path\": \"/home/user/Downloads/\",\n \"save_path_changed_tmm_enabled\": false,\n \"save_resume_data_interval\": 60,\n \"scan_dirs\":\n {\n \"/home/user/Downloads/incoming/games\": 0,\n \"/home/user/Downloads/incoming/movies\": 1,\n },\n \"schedule_from_hour\": 8,\n \"schedule_from_min\": 0,\n \"schedule_to_hour\": 20,\n \"schedule_to_min\": 0,\n \"scheduler_days\": 0,\n \"scheduler_enabled\": false,\n \"send_buffer_low_watermark\": 10,\n \"send_buffer_watermark\": 500,\n \"send_buffer_watermark_factor\": 50,\n \"slow_torrent_dl_rate_threshold\": 2,\n \"slow_torrent_inactive_timer\": 60,\n \"slow_torrent_ul_rate_threshold\": 2,\n \"socket_backlog_size\": 30,\n \"start_paused_enabled\": false,\n \"stop_tracker_timeout\": 1,\n \"temp_path\": \"/home/user/Downloads/temp\",\n \"temp_path_enabled\": false,\n \"torrent_changed_tmm_enabled\": true,\n \"up_limit\": 0,\n \"upload_choking_algorithm\": 1,\n \"upload_slots_behavior\": 0,\n \"upnp\": true,\n \"use_https\": false,\n \"utp_tcp_mixed_mode\": 0,\n \"web_ui_address\": \"*\",\n \"web_ui_ban_duration\": 3600,\n \"web_ui_clickjacking_protection_enabled\": true,\n \"web_ui_csrf_protection_enabled\": true,\n \"web_ui_custom_http_headers\": \"\",\n \"web_ui_domain_list\": \"*\",\n \"web_ui_host_header_validation_enabled\": true,\n \"web_ui_https_cert_path\": \"\",\n \"web_ui_https_key_path\": \"\",\n \"web_ui_max_auth_fail_count\": 5,\n \"web_ui_port\": 8080,\n \"web_ui_secure_cookie_enabled\": true,\n \"web_ui_session_timeout\": 3600,\n \"web_ui_upnp\": false,\n \"web_ui_use_custom_http_headers_enabled\": false,\n \"web_ui_username\": \"admin\"\n}\n```", ), url: "preferences", + types: CompositeTypes { + composite_types: [ + Enum( + Enum { + name: "BittorrentProtocol", + values: [ + EnumValue { + description: Some( + "TCP and μTP", + ), + value: "TCPAndμTP", + original_value: "0", + }, + EnumValue { + description: Some( + "TCP", + ), + value: "TCP", + original_value: "1", + }, + EnumValue { + description: Some( + "μTP", + ), + value: "μTP", + original_value: "2", + }, + ], + }, + ), + Enum( + Enum { + name: "DyndnsService", + values: [ + EnumValue { + description: Some( + "Use DyDNS", + ), + value: "UseDyDNS", + original_value: "0", + }, + EnumValue { + description: Some( + "Use NOIP", + ), + value: "UseNOIP", + original_value: "1", + }, + ], + }, + ), + Enum( + Enum { + name: "Encryption", + values: [ + EnumValue { + description: Some( + "Prefer encryption", + ), + value: "PreferEncryption", + original_value: "0", + }, + EnumValue { + description: Some( + "Force encryption on", + ), + value: "ForceEncryptionOn", + original_value: "1", + }, + EnumValue { + description: Some( + "Force encryption off", + ), + value: "ForceEncryptionOff", + original_value: "2", + }, + ], + }, + ), + Enum( + Enum { + name: "MaxRatioAct", + values: [ + EnumValue { + description: Some( + "Pause torrent", + ), + value: "PauseTorrent", + original_value: "0", + }, + EnumValue { + description: Some( + "Remove torrent", + ), + value: "RemoveTorrent", + original_value: "1", + }, + ], + }, + ), + Enum( + Enum { + name: "ProxyType", + values: [ + EnumValue { + description: Some( + "Proxy is disabled", + ), + value: "ProxyIsDisabled", + original_value: "-1", + }, + EnumValue { + description: Some( + "HTTP proxy without authentication", + ), + value: "HTTPProxyWithoutAuthentication", + original_value: "1", + }, + EnumValue { + description: Some( + "SOCKS5 proxy without authentication", + ), + value: "SOCKS5ProxyWithoutAuthentication", + original_value: "2", + }, + EnumValue { + description: Some( + "HTTP proxy with authentication", + ), + value: "HTTPProxyWithAuthentication", + original_value: "3", + }, + EnumValue { + description: Some( + "SOCKS5 proxy with authentication", + ), + value: "SOCKS5ProxyWithAuthentication", + original_value: "4", + }, + EnumValue { + description: Some( + "SOCKS4 proxy without authentication", + ), + value: "SOCKS4ProxyWithoutAuthentication", + original_value: "5", + }, + ], + }, + ), + Enum( + Enum { + name: "ScanDirs", + values: [ + EnumValue { + description: Some( + "Download to the monitored folder", + ), + value: "DownloadToTheMonitoredFolder", + original_value: "0", + }, + EnumValue { + description: Some( + "Download to the default save path", + ), + value: "DownloadToTheDefaultSavePath", + original_value: "1", + }, + EnumValue { + description: Some( + "Download to this path", + ), + value: "\"/path/to/download/to\"", + original_value: "\"/path/to/download/to\"", + }, + ], + }, + ), + Enum( + Enum { + name: "SchedulerDays", + values: [ + EnumValue { + description: Some( + "Every day", + ), + value: "EveryDay", + original_value: "0", + }, + EnumValue { + description: Some( + "Every weekday", + ), + value: "EveryWeekday", + original_value: "1", + }, + EnumValue { + description: Some( + "Every weekend", + ), + value: "EveryWeekend", + original_value: "2", + }, + EnumValue { + description: Some( + "Every Monday", + ), + value: "EveryMonday", + original_value: "3", + }, + EnumValue { + description: Some( + "Every Tuesday", + ), + value: "EveryTuesday", + original_value: "4", + }, + EnumValue { + description: Some( + "Every Wednesday", + ), + value: "EveryWednesday", + original_value: "5", + }, + EnumValue { + description: Some( + "Every Thursday", + ), + value: "EveryThursday", + original_value: "6", + }, + EnumValue { + description: Some( + "Every Friday", + ), + value: "EveryFriday", + original_value: "7", + }, + EnumValue { + description: Some( + "Every Saturday", + ), + value: "EverySaturday", + original_value: "8", + }, + EnumValue { + description: Some( + "Every Sunday", + ), + value: "EverySunday", + original_value: "9", + }, + ], + }, + ), + Enum( + Enum { + name: "UploadChokingAlgorithm", + values: [ + EnumValue { + description: Some( + "Round-robin", + ), + value: "RoundRobin", + original_value: "0", + }, + EnumValue { + description: Some( + "Fastest upload", + ), + value: "FastestUpload", + original_value: "1", + }, + EnumValue { + description: Some( + "Anti-leech", + ), + value: "AntiLeech", + original_value: "2", + }, + ], + }, + ), + Enum( + Enum { + name: "UploadSlotsBehavior", + values: [ + EnumValue { + description: Some( + "Fixed slots", + ), + value: "FixedSlots", + original_value: "0", + }, + EnumValue { + description: Some( + "Upload rate based", + ), + value: "UploadRateBased", + original_value: "1", + }, + ], + }, + ), + Enum( + Enum { + name: "UtpTcpMixedMode", + values: [ + EnumValue { + description: Some( + "Prefer TCP", + ), + value: "PreferTCP", + original_value: "0", + }, + EnumValue { + description: Some( + "Peer proportional", + ), + value: "PeerProportional", + original_value: "1", + }, + ], + }, + ), + ], + }, }, ApiMethod { name: "setPreferences", description: Some( "1. There is no need to pass all possible preferences' `token:value` pairs if you only want to change one option\n 1. Paths in `scan_dirs` must exist, otherwise this option will have no effect\n 1. String values must be quoted; integer and boolean values must never be quoted\n\nFor a list of possible preference options see [Get application preferences](#get-application-preferences)", ), - parameters: None, - return_type: None, url: "setPreferences", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "defaultSavePath", - description: None, - parameters: None, - return_type: None, + description: Some( + "The response is a string with the default save path, e.g. `C:/Users/Dayman/Downloads`.", + ), url: "defaultSavePath", + types: CompositeTypes { + composite_types: [], + }, }, ], description: Some( @@ -2588,156 +518,98 @@ ApiMethod { name: "main", description: Some( - "Each element of the array has the following properties:\n\nExample:\n\n```JSON\n[\n {\n \"id\":0,\n \"message\":\"qBittorrent v3.4.0 started\",\n \"timestamp\":1507969127860,\n \"type\":1\n },\n {\n \"id\":1,\n \"message\":\"qBittorrent is trying to listen on any interface port: 19036\",\n \"timestamp\":1507969127869,\n \"type\":2\n },\n {\n \"id\":2,\n \"message\":\"Peer ID: -qB3400-\",\n \"timestamp\":1507969127870,\n \"type\":1\n },\n {\n \"id\":3,\n \"message\":\"HTTP User-Agent is 'qBittorrent/3.4.0'\",\n \"timestamp\":1507969127870,\n \"type\":1\n },\n {\n \"id\":4,\n \"message\":\"DHT support [ON]\",\n \"timestamp\":1507969127871,\n \"type\":2\n },\n {\n \"id\":5,\n \"message\":\"Local Peer Discovery support [ON]\",\n \"timestamp\":1507969127871,\n \"type\":2\n },\n {\n \"id\":6,\n \"message\":\"PeX support [ON]\",\n \"timestamp\":1507969127871,\n \"type\":2\n },\n {\n \"id\":7,\n \"message\":\"Anonymous mode [OFF]\",\n \"timestamp\":1507969127871,\n \"type\":2\n },\n {\n \"id\":8,\n \"message\":\"Encryption support [ON]\",\n \"timestamp\":1507969127871,\n \"type\":2\n },\n {\n \"id\":9,\n \"message\":\"Embedded Tracker [OFF]\",\n \"timestamp\":1507969127871,\n \"type\":2\n },\n {\n \"id\":10,\n \"message\":\"UPnP / NAT-PMP support [ON]\",\n \"timestamp\":1507969127873,\n \"type\":2\n },\n {\n \"id\":11,\n \"message\":\"Web UI: Now listening on port 8080\",\n \"timestamp\":1507969127883,\n \"type\":1\n },\n {\n \"id\":12,\n \"message\":\"Options were saved successfully.\",\n \"timestamp\":1507969128055,\n \"type\":1\n },\n {\n \"id\":13,\n \"message\":\"qBittorrent is successfully listening on interface :: port: TCP/19036\",\n \"timestamp\":1507969128270,\n \"type\":2\n },\n {\n \"id\":14,\n \"message\":\"qBittorrent is successfully listening on interface 0.0.0.0 port: TCP/19036\",\n \"timestamp\":1507969128271,\n \"type\":2\n },\n {\n \"id\":15,\n \"message\":\"qBittorrent is successfully listening on interface 0.0.0.0 port: UDP/19036\",\n \"timestamp\":1507969128272,\n \"type\":2\n }\n]\n```", + "The response is a JSON array in which each element is an entry of the log.\n\nEach element of the array has the following properties:\n\n\nExample:\n\n```JSON\n[\n {\n \"id\":0,\n \"message\":\"qBittorrent v3.4.0 started\",\n \"timestamp\":1507969127860,\n \"type\":1\n },\n {\n \"id\":1,\n \"message\":\"qBittorrent is trying to listen on any interface port: 19036\",\n \"timestamp\":1507969127869,\n \"type\":2\n },\n {\n \"id\":2,\n \"message\":\"Peer ID: -qB3400-\",\n \"timestamp\":1507969127870,\n \"type\":1\n },\n {\n \"id\":3,\n \"message\":\"HTTP User-Agent is 'qBittorrent/3.4.0'\",\n \"timestamp\":1507969127870,\n \"type\":1\n },\n {\n \"id\":4,\n \"message\":\"DHT support [ON]\",\n \"timestamp\":1507969127871,\n \"type\":2\n },\n {\n \"id\":5,\n \"message\":\"Local Peer Discovery support [ON]\",\n \"timestamp\":1507969127871,\n \"type\":2\n },\n {\n \"id\":6,\n \"message\":\"PeX support [ON]\",\n \"timestamp\":1507969127871,\n \"type\":2\n },\n {\n \"id\":7,\n \"message\":\"Anonymous mode [OFF]\",\n \"timestamp\":1507969127871,\n \"type\":2\n },\n {\n \"id\":8,\n \"message\":\"Encryption support [ON]\",\n \"timestamp\":1507969127871,\n \"type\":2\n },\n {\n \"id\":9,\n \"message\":\"Embedded Tracker [OFF]\",\n \"timestamp\":1507969127871,\n \"type\":2\n },\n {\n \"id\":10,\n \"message\":\"UPnP / NAT-PMP support [ON]\",\n \"timestamp\":1507969127873,\n \"type\":2\n },\n {\n \"id\":11,\n \"message\":\"Web UI: Now listening on port 8080\",\n \"timestamp\":1507969127883,\n \"type\":1\n },\n {\n \"id\":12,\n \"message\":\"Options were saved successfully.\",\n \"timestamp\":1507969128055,\n \"type\":1\n },\n {\n \"id\":13,\n \"message\":\"qBittorrent is successfully listening on interface :: port: TCP/19036\",\n \"timestamp\":1507969128270,\n \"type\":2\n },\n {\n \"id\":14,\n \"message\":\"qBittorrent is successfully listening on interface 0.0.0.0 port: TCP/19036\",\n \"timestamp\":1507969128271,\n \"type\":2\n },\n {\n \"id\":15,\n \"message\":\"qBittorrent is successfully listening on interface 0.0.0.0 port: UDP/19036\",\n \"timestamp\":1507969128272,\n \"type\":2\n }\n]\n```", ), - parameters: Some( - [ - Bool( - TypeInfo { - name: "normal", - is_optional: true, + url: "main", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + Bool( + TypeInfo { + name: "normal", + description: Some( + "Include normal messages (default: true)", + ), + is_optional: true, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "info", + description: Some( + "Include info messages (default: true)", + ), + is_optional: true, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "warning", + description: Some( + "Include warning messages (default: true)", + ), + is_optional: true, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "critical", + description: Some( + "Include critical messages (default: true)", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "last_known_id", + description: Some( + "Exclude messages with \"message id\" <= last_known_id (default: -1)", + ), + is_optional: true, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "Include normal messages (default: true)", - ), - type_description: None, - }, - ), - Bool( - TypeInfo { - name: "info", - is_optional: true, - is_list: false, - description: Some( - "Include info messages (default: true)", - ), - type_description: None, - }, - ), - Bool( - TypeInfo { - name: "warning", - is_optional: true, - is_list: false, - description: Some( - "Include warning messages (default: true)", - ), - type_description: None, - }, - ), - Bool( - TypeInfo { - name: "critical", - is_optional: true, - is_list: false, - description: Some( - "Include critical messages (default: true)", - ), - type_description: None, - }, - ), - Number( - TypeInfo { - name: "last_known_id", - is_optional: true, - is_list: false, - description: Some( - "Exclude messages with \"message id\" <= last_known_id (default: -1)", - ), - type_description: None, }, ), ], - ), - return_type: Some( - ReturnType { - is_list: true, - parameters: [ - ReturnTypeParameter { - name: "id", - description: "ID of the message", - return_type: Number( - TypeInfo { - name: "id", - is_optional: false, - is_list: false, - description: Some( - "ID of the message", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "message", - description: "Text of the message", - return_type: String( - TypeInfo { - name: "message", - is_optional: false, - is_list: false, - description: Some( - "Text of the message", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "timestamp", - description: "Milliseconds since epoch", - return_type: Number( - TypeInfo { - name: "timestamp", - is_optional: false, - is_list: false, - description: Some( - "Milliseconds since epoch", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "type", - description: "Type of the message: Log::NORMAL: 1, Log::INFO: 2, Log::WARNING: 4, Log::CRITICAL: 8", - return_type: Number( - TypeInfo { - name: "type", - is_optional: false, - is_list: false, - description: Some( - "Type of the message: Log::NORMAL: 1, Log::INFO: 2, Log::WARNING: 4, Log::CRITICAL: 8", - ), - type_description: None, - }, - ), - }, - ], - }, - ), - url: "main", + }, }, ApiMethod { name: "peers", - description: None, - parameters: Some( - [ - Number( - TypeInfo { - name: "last_known_id", - is_optional: true, + description: Some( + "The response a JSON array. Each element of the array of objects (each object is the information relative to a peer) containing the following fields", + ), + url: "peers", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + Number( + TypeInfo { + name: "last_known_id", + description: Some( + "Exclude messages with \"message id\" <= last_known_id (default: -1)", + ), + is_optional: true, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "Exclude messages with \"message id\" <= last_known_id (default: -1)", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "peers", + }, }, ], description: Some( @@ -2751,198 +623,753 @@ ApiMethod { name: "maindata", description: Some( - "Example:\n\n```JSON\n{\n \"rid\":15,\n \"torrents\":\n {\n \"8c212779b4abde7c6bc608063a0d008b7e40ce32\":\n {\n \"state\":\"pausedUP\"\n }\n }\n}\n```", + "The response is a JSON object with the following possible fields\n\n\nExample:\n\n```JSON\n{\n \"rid\":15,\n \"torrents\":\n {\n \"8c212779b4abde7c6bc608063a0d008b7e40ce32\":\n {\n \"state\":\"pausedUP\"\n }\n }\n}\n```", ), - parameters: Some( - [ - Number( - TypeInfo { - name: "rid", - is_optional: false, + url: "maindata", + types: CompositeTypes { + composite_types: [ + Object( + TypeWithName { + name: "Categories", + types: [ + String( + TypeInfo { + name: "name", + description: Some( + "Category name", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "savePath", + description: Some( + "Save path", + ), + is_optional: false, + is_list: false, + }, + ), + ], + }, + ), + Parameters( + TypeWithoutName { + types: [ + Number( + TypeInfo { + name: "rid", + description: Some( + "Response ID. If not provided, rid=0 will be assumed. If the given rid is different from the one of last server reply, full_update will be true (see the server reply details for more info)", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "Response ID. If not provided, rid=0 will be assumed. If the given rid is different from the one of last server reply, full_update will be true (see the server reply details for more info)", - ), - type_description: None, + }, + ), + Object( + TypeWithName { + name: "ServerState", + types: [ + Number( + TypeInfo { + name: "average_time_queue", + description: Some( + "Average time queue", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "dl_info_data", + description: Some( + "Download info data", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "dl_info_speed", + description: Some( + "Download info speed", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "queued_io_jobs", + description: Some( + "Queued io jobs", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "total_buffers_size", + description: Some( + "Total buffers size", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "total_peer_connections", + description: Some( + "Total peer connections", + ), + is_optional: false, + is_list: false, + }, + ), + ], + }, + ), + Response( + TypeWithoutName { + types: [ + Number( + TypeInfo { + name: "rid", + description: Some( + "Response ID", + ), + is_optional: false, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "full_update", + description: Some( + "Whether the response contains all the data or partial data", + ), + is_optional: true, + is_list: false, + }, + ), + Object( + Object { + type_info: TypeInfo { + name: "torrents", + description: Some( + "Property: torrent hash, value: same as [torrent list](#get-torrent-list), map from string to torrents object", + ), + is_optional: true, + is_list: false, + }, + ref_type: Map( + "String", + "Torrents", + ), + }, + ), + Object( + Object { + type_info: TypeInfo { + name: "torrents_removed", + description: Some( + "List of hashes of torrents removed since last request", + ), + is_optional: true, + is_list: true, + }, + ref_type: String( + "String", + ), + }, + ), + Object( + Object { + type_info: TypeInfo { + name: "categories", + description: Some( + "Info for categories added since last request, map from string to categories object", + ), + is_optional: true, + is_list: false, + }, + ref_type: Map( + "String", + "Categories", + ), + }, + ), + Object( + Object { + type_info: TypeInfo { + name: "categories_removed", + description: Some( + "List of categories removed since last request", + ), + is_optional: true, + is_list: true, + }, + ref_type: String( + "String", + ), + }, + ), + Object( + Object { + type_info: TypeInfo { + name: "tags", + description: Some( + "List of tags added since last request", + ), + is_optional: true, + is_list: true, + }, + ref_type: String( + "String", + ), + }, + ), + Object( + Object { + type_info: TypeInfo { + name: "tags_removed", + description: Some( + "List of tags removed since last request", + ), + is_optional: true, + is_list: true, + }, + ref_type: String( + "String", + ), + }, + ), + Object( + Object { + type_info: TypeInfo { + name: "server_state", + description: Some( + "server_state object see table below", + ), + is_optional: true, + is_list: false, + }, + ref_type: String( + "ServerState", + ), + }, + ), + ], + is_list: false, + }, + ), + Object( + TypeWithName { + name: "Torrents", + types: [ + Number( + TypeInfo { + name: "added_on", + description: Some( + "Time (Unix Epoch) when the torrent was added to the client", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "amount_left", + description: Some( + "Amount of data left to download (bytes)", + ), + is_optional: true, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "auto_tmm", + description: Some( + "Whether this torrent is managed by Automatic Torrent Management", + ), + is_optional: true, + is_list: false, + }, + ), + Float( + TypeInfo { + name: "availability", + description: Some( + "Percentage of file pieces currently available", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "category", + description: Some( + "Category of the torrent", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "completed", + description: Some( + "Amount of transfer data completed (bytes)", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "completion_on", + description: Some( + "Time (Unix Epoch) when the torrent completed", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "content_path", + description: Some( + "Absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents)", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "dl_limit", + description: Some( + "Torrent download speed limit (bytes/s). -1 if ulimited.", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "dlspeed", + description: Some( + "Torrent download speed (bytes/s)", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "downloaded", + description: Some( + "Amount of data downloaded", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "downloaded_session", + description: Some( + "Amount of data downloaded this session", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "eta", + description: Some( + "Torrent ETA (seconds)", + ), + is_optional: true, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "f_l_piece_prio", + description: Some( + "True if first last piece are prioritized", + ), + is_optional: true, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "force_start", + description: Some( + "True if force start is enabled for this torrent", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "hash", + description: Some( + "Torrent hash", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "last_activity", + description: Some( + "Last time (Unix Epoch) when a chunk was downloaded/uploaded", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "magnet_uri", + description: Some( + "Magnet URI corresponding to this torrent", + ), + is_optional: true, + is_list: false, + }, + ), + Float( + TypeInfo { + name: "max_ratio", + description: Some( + "Maximum share ratio until torrent is stopped from seeding/uploading", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "max_seeding_time", + description: Some( + "Maximum seeding time (seconds) until torrent is stopped from seeding", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "name", + description: Some( + "Torrent name", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "num_complete", + description: Some( + "Number of seeds in the swarm", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "num_incomplete", + description: Some( + "Number of leechers in the swarm", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "num_leechs", + description: Some( + "Number of leechers connected to", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "num_seeds", + description: Some( + "Number of seeds connected to", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "priority", + description: Some( + "Torrent priority. Returns -1 if queuing is disabled or torrent is in seed mode", + ), + is_optional: true, + is_list: false, + }, + ), + Float( + TypeInfo { + name: "progress", + description: Some( + "Torrent progress (percentage/100)", + ), + is_optional: true, + is_list: false, + }, + ), + Float( + TypeInfo { + name: "ratio", + description: Some( + "Torrent share ratio. Max ratio value: 9999.", + ), + is_optional: true, + is_list: false, + }, + ), + Float( + TypeInfo { + name: "ratio_limit", + description: Some( + "TODO (what is different from max_ratio?)", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "save_path", + description: Some( + "Path where this torrent's data is stored", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "seeding_time", + description: Some( + "Torrent elapsed time while complete (seconds)", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "seeding_time_limit", + description: Some( + "TODO (what is different from max_seeding_time?) seeding_time_limit is a per torrent setting, when Automatic Torrent Management is disabled, furthermore then max_seeding_time is set to seeding_time_limit for this torrent. If Automatic Torrent Management is enabled, the value is -2. And if max_seeding_time is unset it have a default value -1.", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "seen_complete", + description: Some( + "Time (Unix Epoch) when this torrent was last seen complete", + ), + is_optional: true, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "seq_dl", + description: Some( + "True if sequential download is enabled", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "size", + description: Some( + "Total size (bytes) of files selected for download", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "state", + description: Some( + "Torrent state. See table here below for the possible values", + ), + is_optional: true, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "super_seeding", + description: Some( + "True if super seeding is enabled", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "tags", + description: Some( + "Comma-concatenated tag list of the torrent", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "time_active", + description: Some( + "Total active time (seconds)", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "total_size", + description: Some( + "Total size (bytes) of all file in this torrent (including unselected ones)", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "tracker", + description: Some( + "The first tracker with working status. Returns empty string if no tracker is working.", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "up_limit", + description: Some( + "Torrent upload speed limit (bytes/s). -1 if ulimited.", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "uploaded", + description: Some( + "Amount of data uploaded", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "uploaded_session", + description: Some( + "Amount of data uploaded this session", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "upspeed", + description: Some( + "Torrent upload speed (bytes/s)", + ), + is_optional: true, + is_list: false, + }, + ), + ], }, ), ], - ), - return_type: Some( - ReturnType { - is_list: false, - parameters: [ - ReturnTypeParameter { - name: "rid", - description: "Response ID", - return_type: Number( - TypeInfo { - name: "rid", - is_optional: false, - is_list: false, - description: Some( - "Response ID", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "full_update", - description: "Whether the response contains all the data or partial data", - return_type: Bool( - TypeInfo { - name: "full_update", - is_optional: false, - is_list: false, - description: Some( - "Whether the response contains all the data or partial data", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "torrents", - description: "Property: torrent hash, value: same as [torrent list](#get-torrent-list)", - return_type: Object( - TypeInfo { - name: "torrents", - is_optional: false, - is_list: false, - description: Some( - "Property: torrent hash, value: same as [torrent list](#get-torrent-list)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "torrents_removed", - description: "List of hashes of torrents removed since last request", - return_type: StringArray( - TypeInfo { - name: "torrents_removed", - is_optional: false, - is_list: false, - description: Some( - "List of hashes of torrents removed since last request", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "categories", - description: "Info for categories added since last request", - return_type: Object( - TypeInfo { - name: "categories", - is_optional: false, - is_list: false, - description: Some( - "Info for categories added since last request", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "categories_removed", - description: "List of categories removed since last request", - return_type: StringArray( - TypeInfo { - name: "categories_removed", - is_optional: false, - is_list: false, - description: Some( - "List of categories removed since last request", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "tags", - description: "List of tags added since last request", - return_type: StringArray( - TypeInfo { - name: "tags", - is_optional: false, - is_list: false, - description: Some( - "List of tags added since last request", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "tags_removed", - description: "List of tags removed since last request", - return_type: StringArray( - TypeInfo { - name: "tags_removed", - is_optional: false, - is_list: false, - description: Some( - "List of tags removed since last request", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "server_state", - description: "Global transfer info", - return_type: Object( - TypeInfo { - name: "server_state", - is_optional: false, - is_list: false, - description: Some( - "Global transfer info", - ), - type_description: None, - }, - ), - }, - ], - }, - ), - url: "maindata", + }, }, ApiMethod { name: "torrentPeers", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, + description: Some( + "The response is TODO", + ), + url: "torrentPeers", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hash", + description: Some( + "Torrent hash", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "rid", + description: Some( + "Response ID. If not provided, rid=0 will be assumed. If the given rid is different from the one of last server reply, full_update will be true (see the server reply details for more info)", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "Torrent hash", - ), - type_description: None, - }, - ), - Number( - TypeInfo { - name: "rid", - is_optional: false, - is_list: false, - description: Some( - "Response ID. If not provided, rid=0 will be assumed. If the given rid is different from the one of last server reply, full_update will be true (see the server reply details for more info)", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "torrentPeers", + }, }, ], description: Some( @@ -2956,245 +1383,216 @@ ApiMethod { name: "info", description: Some( - "In addition to the above in partial data requests (see [Get partial data](#get-partial-data) for more info):\n\nPossible values of `connection_status`:\n\nExample:\n\n```JSON\n{\n \"connection_status\":\"connected\",\n \"dht_nodes\":386,\n \"dl_info_data\":681521119,\n \"dl_info_speed\":0,\n \"dl_rate_limit\":0,\n \"up_info_data\":10747904,\n \"up_info_speed\":0,\n \"up_rate_limit\":1048576\n}\n```", - ), - parameters: None, - return_type: Some( - ReturnType { - is_list: false, - parameters: [ - ReturnTypeParameter { - name: "dl_info_speed", - description: "Global download rate (bytes/s)", - return_type: Number( - TypeInfo { - name: "dl_info_speed", - is_optional: false, - is_list: false, - description: Some( - "Global download rate (bytes/s)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dl_info_data", - description: "Data downloaded this session (bytes)", - return_type: Number( - TypeInfo { - name: "dl_info_data", - is_optional: false, - is_list: false, - description: Some( - "Data downloaded this session (bytes)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "up_info_speed", - description: "Global upload rate (bytes/s)", - return_type: Number( - TypeInfo { - name: "up_info_speed", - is_optional: false, - is_list: false, - description: Some( - "Global upload rate (bytes/s)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "up_info_data", - description: "Data uploaded this session (bytes)", - return_type: Number( - TypeInfo { - name: "up_info_data", - is_optional: false, - is_list: false, - description: Some( - "Data uploaded this session (bytes)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dl_rate_limit", - description: "Download rate limit (bytes/s)", - return_type: Number( - TypeInfo { - name: "dl_rate_limit", - is_optional: false, - is_list: false, - description: Some( - "Download rate limit (bytes/s)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "up_rate_limit", - description: "Upload rate limit (bytes/s)", - return_type: Number( - TypeInfo { - name: "up_rate_limit", - is_optional: false, - is_list: false, - description: Some( - "Upload rate limit (bytes/s)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dht_nodes", - description: "DHT nodes connected to", - return_type: Number( - TypeInfo { - name: "dht_nodes", - is_optional: false, - is_list: false, - description: Some( - "DHT nodes connected to", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "connection_status", - description: "Connection status. See possible values here below", - return_type: String( - TypeInfo { - name: "connection_status", - is_optional: false, - is_list: false, - description: Some( - "Connection status. See possible values here below", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "connected", - description: "", - }, - TypeDescriptions { - value: "firewalled", - description: "", - }, - TypeDescriptions { - value: "disconnected", - description: "", - }, - ], - }, - ), - }, - ), - }, - ], - }, + "The response is a JSON object with the following fields\n\n\nIn addition to the above in partial data requests (see [Get partial data](#get-partial-data) for more info):\n\n\nPossible values of `connection_status`:\n\nValue |\n\nExample:\n\n```JSON\n{\n \"connection_status\":\"connected\",\n \"dht_nodes\":386,\n \"dl_info_data\":681521119,\n \"dl_info_speed\":0,\n \"dl_rate_limit\":0,\n \"up_info_data\":10747904,\n \"up_info_speed\":0,\n \"up_rate_limit\":1048576\n}\n```", ), url: "info", + types: CompositeTypes { + composite_types: [ + Response( + TypeWithoutName { + types: [ + Number( + TypeInfo { + name: "dl_info_speed", + description: Some( + "Global download rate (bytes/s)", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "dl_info_data", + description: Some( + "Data downloaded this session (bytes)", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "up_info_speed", + description: Some( + "Global upload rate (bytes/s)", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "up_info_data", + description: Some( + "Data uploaded this session (bytes)", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "dl_rate_limit", + description: Some( + "Download rate limit (bytes/s)", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "up_rate_limit", + description: Some( + "Upload rate limit (bytes/s)", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "dht_nodes", + description: Some( + "DHT nodes connected to", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "connection_status", + description: Some( + "Connection status. See possible values here below", + ), + is_optional: false, + is_list: false, + }, + ), + ], + is_list: false, + }, + ), + ], + }, }, ApiMethod { name: "speedLimitsMode", - description: None, - parameters: None, - return_type: None, + description: Some( + "The response is `1` if alternative speed limits are enabled, `0` otherwise.", + ), url: "speedLimitsMode", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "toggleSpeedLimitsMode", description: None, - parameters: None, - return_type: None, url: "toggleSpeedLimitsMode", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "downloadLimit", - description: None, - parameters: None, - return_type: None, + description: Some( + "The response is the value of current global download speed limit in bytes/second; this value will be zero if no limit is applied.", + ), url: "downloadLimit", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "setDownloadLimit", description: None, - parameters: Some( - [ - Number( - TypeInfo { - name: "limit", - is_optional: false, + url: "setDownloadLimit", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + Number( + TypeInfo { + name: "limit", + description: Some( + "The global download speed limit to set in bytes/second", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The global download speed limit to set in bytes/second", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "setDownloadLimit", + }, }, ApiMethod { name: "uploadLimit", - description: None, - parameters: None, - return_type: None, + description: Some( + "The response is the value of current global upload speed limit in bytes/second; this value will be zero if no limit is applied.", + ), url: "uploadLimit", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "setUploadLimit", description: None, - parameters: Some( - [ - Number( - TypeInfo { - name: "limit", - is_optional: false, + url: "setUploadLimit", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + Number( + TypeInfo { + name: "limit", + description: Some( + "The global upload speed limit to set in bytes/second", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The global upload speed limit to set in bytes/second", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "setUploadLimit", + }, }, ApiMethod { name: "banPeers", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "peers", - is_optional: false, + url: "banPeers", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "peers", + description: Some( + "The peer to ban, or multiple peers separated by a pipe \\", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The peer to ban, or multiple peers separated by a pipe \\", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "banPeers", + }, }, ], description: Some( @@ -3208,1978 +1606,1944 @@ ApiMethod { name: "info", description: Some( - "Possible values of `state`:\n\nExample:\n\n```JSON\n[\n {\n \"dlspeed\":9681262,\n \"eta\":87,\n \"f_l_piece_prio\":false,\n \"force_start\":false,\n \"hash\":\"8c212779b4abde7c6bc608063a0d008b7e40ce32\",\n \"category\":\"\",\n \"tags\": \"\",\n \"name\":\"debian-8.1.0-amd64-CD-1.iso\",\n \"num_complete\":-1,\n \"num_incomplete\":-1,\n \"num_leechs\":2,\n \"num_seeds\":54,\n \"priority\":1,\n \"progress\":0.16108787059783936,\n \"ratio\":0,\n \"seq_dl\":false,\n \"size\":657457152,\n \"state\":\"downloading\",\n \"super_seeding\":false,\n \"upspeed\":0\n },\n {\n another_torrent_info\n }\n]\n```", + "The response is a JSON array with the following fields\n\n\nPossible values of `state`:\n\n\nExample:\n\n```JSON\n[\n {\n \"dlspeed\":9681262,\n \"eta\":87,\n \"f_l_piece_prio\":false,\n \"force_start\":false,\n \"hash\":\"8c212779b4abde7c6bc608063a0d008b7e40ce32\",\n \"category\":\"\",\n \"tags\": \"\",\n \"name\":\"debian-8.1.0-amd64-CD-1.iso\",\n \"num_complete\":-1,\n \"num_incomplete\":-1,\n \"num_leechs\":2,\n \"num_seeds\":54,\n \"priority\":1,\n \"progress\":0.16108787059783936,\n \"ratio\":0,\n \"seq_dl\":false,\n \"size\":657457152,\n \"state\":\"downloading\",\n \"super_seeding\":false,\n \"upspeed\":0\n },\n {\n another_torrent_info\n }\n]\n```", ), - parameters: Some( - [ - String( - TypeInfo { - name: "filter", - is_optional: true, + url: "info", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "filter", + description: Some( + "Filter torrent list by state. Allowed state filters: all, downloading, seeding, completed, paused, active, inactive, resumed, stalled, stalled_uploading, stalled_downloading, errored", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "category", + description: Some( + "Get torrents with the given category (empty string means \"without category\"; no \"category\" parameter means \"any category\" <- broken until [#11748](https://github.com/qbittorrent/qBittorrent/issues/11748) is resolved). Remember to URL-encode the category name. For example, My category becomes My%20category", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "tag", + description: Some( + "Get torrents with the given tag (empty string means \"without tag\"; no \"tag\" parameter means \"any tag\". Remember to URL-encode the category name. For example, My tag becomes My%20tag", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "sort", + description: Some( + "Sort torrents by given key. They can be sorted using any field of the response's JSON array (which are documented below) as the sort key.", + ), + is_optional: true, + is_list: true, + }, + ), + Bool( + TypeInfo { + name: "reverse", + description: Some( + "Enable reverse sorting. Defaults to false", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "limit", + description: Some( + "Limit the number of torrents returned", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "offset", + description: Some( + "Set offset (if less than 0, offset from end)", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "hashes", + description: Some( + "Filter by hashes. Can contain multiple hashes separated by \\", + ), + is_optional: true, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "Filter torrent list by state. Allowed state filters: all, downloading, seeding, completed, paused, active, inactive, resumed, stalled, stalled_uploading, stalled_downloading, errored", - ), - type_description: None, }, ), - String( - TypeInfo { - name: "category", - is_optional: true, - is_list: false, - description: Some( - "Get torrents with the given category (empty string means \"without category\"; no \"category\" parameter means \"any category\" <- broken until [#11748](https://github.com/qbittorrent/qBittorrent/issues/11748) is resolved). Remember to URL-encode the category name. For example, My category becomes My%20category", - ), - type_description: None, + Enum( + Enum { + name: "State", + values: [ + EnumValue { + description: Some( + "Some error occurred, applies to paused torrents", + ), + value: "Error", + original_value: "error", + }, + EnumValue { + description: Some( + "Torrent data files is missing", + ), + value: "MissingFiles", + original_value: "missingFiles", + }, + EnumValue { + description: Some( + "Torrent is being seeded and data is being transferred", + ), + value: "Uploading", + original_value: "uploading", + }, + EnumValue { + description: Some( + "Torrent is paused and has finished downloading", + ), + value: "PausedUP", + original_value: "pausedUP", + }, + EnumValue { + description: Some( + "Queuing is enabled and torrent is queued for upload", + ), + value: "QueuedUP", + original_value: "queuedUP", + }, + EnumValue { + description: Some( + "Torrent is being seeded, but no connection were made", + ), + value: "StalledUP", + original_value: "stalledUP", + }, + EnumValue { + description: Some( + "Torrent has finished downloading and is being checked", + ), + value: "CheckingUP", + original_value: "checkingUP", + }, + EnumValue { + description: Some( + "Torrent is forced to uploading and ignore queue limit", + ), + value: "ForcedUP", + original_value: "forcedUP", + }, + EnumValue { + description: Some( + "Torrent is allocating disk space for download", + ), + value: "Allocating", + original_value: "allocating", + }, + EnumValue { + description: Some( + "Torrent is being downloaded and data is being transferred", + ), + value: "Downloading", + original_value: "downloading", + }, + EnumValue { + description: Some( + "Torrent has just started downloading and is fetching metadata", + ), + value: "MetaDL", + original_value: "metaDL", + }, + EnumValue { + description: Some( + "Torrent is paused and has NOT finished downloading", + ), + value: "PausedDL", + original_value: "pausedDL", + }, + EnumValue { + description: Some( + "Queuing is enabled and torrent is queued for download", + ), + value: "QueuedDL", + original_value: "queuedDL", + }, + EnumValue { + description: Some( + "Torrent is being downloaded, but no connection were made", + ), + value: "StalledDL", + original_value: "stalledDL", + }, + EnumValue { + description: Some( + "Same as checkingUP, but torrent has NOT finished downloading", + ), + value: "CheckingDL", + original_value: "checkingDL", + }, + EnumValue { + description: Some( + "Torrent is forced to downloading to ignore queue limit", + ), + value: "ForcedDL", + original_value: "forcedDL", + }, + EnumValue { + description: Some( + "Checking resume data on qBt startup", + ), + value: "CheckingResumeData", + original_value: "checkingResumeData", + }, + EnumValue { + description: Some( + "Torrent is moving to another location", + ), + value: "Moving", + original_value: "moving", + }, + EnumValue { + description: Some( + "Unknown status", + ), + value: "Unknown", + original_value: "unknown", + }, + ], }, ), - String( - TypeInfo { - name: "tag", - is_optional: true, - is_list: false, - description: Some( - "Get torrents with the given tag (empty string means \"without tag\"; no \"tag\" parameter means \"any tag\". Remember to URL-encode the category name. For example, My tag becomes My%20tag", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "sort", - is_optional: true, - is_list: false, - description: Some( - "Sort torrents by given key. They can be sorted using any field of the response's JSON array (which are documented below) as the sort key.", - ), - type_description: None, - }, - ), - Bool( - TypeInfo { - name: "reverse", - is_optional: true, - is_list: false, - description: Some( - "Enable reverse sorting. Defaults to false", - ), - type_description: None, - }, - ), - Number( - TypeInfo { - name: "limit", - is_optional: true, - is_list: false, - description: Some( - "Limit the number of torrents returned", - ), - type_description: None, - }, - ), - Number( - TypeInfo { - name: "offset", - is_optional: true, - is_list: false, - description: Some( - "Set offset (if less than 0, offset from end)", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "hashes", - is_optional: true, - is_list: false, - description: Some( - "Filter by hashes. Can contain multiple hashes separated by \\", - ), - type_description: None, + Response( + TypeWithoutName { + types: [ + Number( + TypeInfo { + name: "added_on", + description: Some( + "Time (Unix Epoch) when the torrent was added to the client", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "amount_left", + description: Some( + "Amount of data left to download (bytes)", + ), + is_optional: false, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "auto_tmm", + description: Some( + "Whether this torrent is managed by Automatic Torrent Management", + ), + is_optional: false, + is_list: false, + }, + ), + Float( + TypeInfo { + name: "availability", + description: Some( + "Percentage of file pieces currently available", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "category", + description: Some( + "Category of the torrent", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "completed", + description: Some( + "Amount of transfer data completed (bytes)", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "completion_on", + description: Some( + "Time (Unix Epoch) when the torrent completed", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "content_path", + description: Some( + "Absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents)", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "dl_limit", + description: Some( + "Torrent download speed limit (bytes/s). -1 if ulimited.", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "dlspeed", + description: Some( + "Torrent download speed (bytes/s)", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "downloaded", + description: Some( + "Amount of data downloaded", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "downloaded_session", + description: Some( + "Amount of data downloaded this session", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "eta", + description: Some( + "Torrent ETA (seconds)", + ), + is_optional: false, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "f_l_piece_prio", + description: Some( + "True if first last piece are prioritized", + ), + is_optional: false, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "force_start", + description: Some( + "True if force start is enabled for this torrent", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "hash", + description: Some( + "Torrent hash", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "last_activity", + description: Some( + "Last time (Unix Epoch) when a chunk was downloaded/uploaded", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "magnet_uri", + description: Some( + "Magnet URI corresponding to this torrent", + ), + is_optional: false, + is_list: false, + }, + ), + Float( + TypeInfo { + name: "max_ratio", + description: Some( + "Maximum share ratio until torrent is stopped from seeding/uploading", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "max_seeding_time", + description: Some( + "Maximum seeding time (seconds) until torrent is stopped from seeding", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "name", + description: Some( + "Torrent name", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "num_complete", + description: Some( + "Number of seeds in the swarm", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "num_incomplete", + description: Some( + "Number of leechers in the swarm", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "num_leechs", + description: Some( + "Number of leechers connected to", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "num_seeds", + description: Some( + "Number of seeds connected to", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "priority", + description: Some( + "Torrent priority. Returns -1 if queuing is disabled or torrent is in seed mode", + ), + is_optional: false, + is_list: false, + }, + ), + Float( + TypeInfo { + name: "progress", + description: Some( + "Torrent progress (percentage/100)", + ), + is_optional: false, + is_list: false, + }, + ), + Float( + TypeInfo { + name: "ratio", + description: Some( + "Torrent share ratio. Max ratio value: 9999.", + ), + is_optional: false, + is_list: false, + }, + ), + Float( + TypeInfo { + name: "ratio_limit", + description: Some( + "TODO (what is different from max_ratio?)", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "save_path", + description: Some( + "Path where this torrent's data is stored", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "seeding_time", + description: Some( + "Torrent elapsed time while complete (seconds)", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "seeding_time_limit", + description: Some( + "TODO (what is different from max_seeding_time?) seeding_time_limit is a per torrent setting, when Automatic Torrent Management is disabled, furthermore then max_seeding_time is set to seeding_time_limit for this torrent. If Automatic Torrent Management is enabled, the value is -2. And if max_seeding_time is unset it have a default value -1.", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "seen_complete", + description: Some( + "Time (Unix Epoch) when this torrent was last seen complete", + ), + is_optional: false, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "seq_dl", + description: Some( + "True if sequential download is enabled", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "size", + description: Some( + "Total size (bytes) of files selected for download", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "state", + description: Some( + "Torrent state. See table here below for the possible values", + ), + is_optional: false, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "super_seeding", + description: Some( + "True if super seeding is enabled", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "tags", + description: Some( + "Comma-concatenated tag list of the torrent", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "time_active", + description: Some( + "Total active time (seconds)", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "total_size", + description: Some( + "Total size (bytes) of all file in this torrent (including unselected ones)", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "tracker", + description: Some( + "The first tracker with working status. Returns empty string if no tracker is working.", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "up_limit", + description: Some( + "Torrent upload speed limit (bytes/s). -1 if ulimited.", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "uploaded", + description: Some( + "Amount of data uploaded", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "uploaded_session", + description: Some( + "Amount of data uploaded this session", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "upspeed", + description: Some( + "Torrent upload speed (bytes/s)", + ), + is_optional: false, + is_list: false, + }, + ), + ], + is_list: true, }, ), ], - ), - return_type: Some( - ReturnType { - is_list: true, - parameters: [ - ReturnTypeParameter { - name: "added_on", - description: "Time (Unix Epoch) when the torrent was added to the client", - return_type: Number( - TypeInfo { - name: "added_on", - is_optional: false, - is_list: false, - description: Some( - "Time (Unix Epoch) when the torrent was added to the client", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "amount_left", - description: "Amount of data left to download (bytes)", - return_type: Number( - TypeInfo { - name: "amount_left", - is_optional: false, - is_list: false, - description: Some( - "Amount of data left to download (bytes)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "auto_tmm", - description: "Whether this torrent is managed by Automatic Torrent Management", - return_type: Bool( - TypeInfo { - name: "auto_tmm", - is_optional: false, - is_list: false, - description: Some( - "Whether this torrent is managed by Automatic Torrent Management", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "availability", - description: "Percentage of file pieces currently available", - return_type: Float( - TypeInfo { - name: "availability", - is_optional: false, - is_list: false, - description: Some( - "Percentage of file pieces currently available", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "category", - description: "Category of the torrent", - return_type: String( - TypeInfo { - name: "category", - is_optional: false, - is_list: false, - description: Some( - "Category of the torrent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "completed", - description: "Amount of transfer data completed (bytes)", - return_type: Number( - TypeInfo { - name: "completed", - is_optional: false, - is_list: false, - description: Some( - "Amount of transfer data completed (bytes)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "completion_on", - description: "Time (Unix Epoch) when the torrent completed", - return_type: Number( - TypeInfo { - name: "completion_on", - is_optional: false, - is_list: false, - description: Some( - "Time (Unix Epoch) when the torrent completed", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "content_path", - description: "Absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents)", - return_type: String( - TypeInfo { - name: "content_path", - is_optional: false, - is_list: false, - description: Some( - "Absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dl_limit", - description: "Torrent download speed limit (bytes/s). -1 if ulimited.", - return_type: Number( - TypeInfo { - name: "dl_limit", - is_optional: false, - is_list: false, - description: Some( - "Torrent download speed limit (bytes/s). -1 if ulimited.", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dlspeed", - description: "Torrent download speed (bytes/s)", - return_type: Number( - TypeInfo { - name: "dlspeed", - is_optional: false, - is_list: false, - description: Some( - "Torrent download speed (bytes/s)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "downloaded", - description: "Amount of data downloaded", - return_type: Number( - TypeInfo { - name: "downloaded", - is_optional: false, - is_list: false, - description: Some( - "Amount of data downloaded", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "downloaded_session", - description: "Amount of data downloaded this session", - return_type: Number( - TypeInfo { - name: "downloaded_session", - is_optional: false, - is_list: false, - description: Some( - "Amount of data downloaded this session", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "eta", - description: "Torrent ETA (seconds)", - return_type: Number( - TypeInfo { - name: "eta", - is_optional: false, - is_list: false, - description: Some( - "Torrent ETA (seconds)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "f_l_piece_prio", - description: "True if first last piece are prioritized", - return_type: Bool( - TypeInfo { - name: "f_l_piece_prio", - is_optional: false, - is_list: false, - description: Some( - "True if first last piece are prioritized", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "force_start", - description: "True if force start is enabled for this torrent", - return_type: Bool( - TypeInfo { - name: "force_start", - is_optional: false, - is_list: false, - description: Some( - "True if force start is enabled for this torrent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "hash", - description: "Torrent hash", - return_type: String( - TypeInfo { - name: "hash", - is_optional: false, - is_list: false, - description: Some( - "Torrent hash", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "last_activity", - description: "Last time (Unix Epoch) when a chunk was downloaded/uploaded", - return_type: Number( - TypeInfo { - name: "last_activity", - is_optional: false, - is_list: false, - description: Some( - "Last time (Unix Epoch) when a chunk was downloaded/uploaded", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "magnet_uri", - description: "Magnet URI corresponding to this torrent", - return_type: String( - TypeInfo { - name: "magnet_uri", - is_optional: false, - is_list: false, - description: Some( - "Magnet URI corresponding to this torrent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_ratio", - description: "Maximum share ratio until torrent is stopped from seeding/uploading", - return_type: Float( - TypeInfo { - name: "max_ratio", - is_optional: false, - is_list: false, - description: Some( - "Maximum share ratio until torrent is stopped from seeding/uploading", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_seeding_time", - description: "Maximum seeding time (seconds) until torrent is stopped from seeding", - return_type: Number( - TypeInfo { - name: "max_seeding_time", - is_optional: false, - is_list: false, - description: Some( - "Maximum seeding time (seconds) until torrent is stopped from seeding", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "name", - description: "Torrent name", - return_type: String( - TypeInfo { - name: "name", - is_optional: false, - is_list: false, - description: Some( - "Torrent name", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "num_complete", - description: "Number of seeds in the swarm", - return_type: Number( - TypeInfo { - name: "num_complete", - is_optional: false, - is_list: false, - description: Some( - "Number of seeds in the swarm", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "num_incomplete", - description: "Number of leechers in the swarm", - return_type: Number( - TypeInfo { - name: "num_incomplete", - is_optional: false, - is_list: false, - description: Some( - "Number of leechers in the swarm", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "num_leechs", - description: "Number of leechers connected to", - return_type: Number( - TypeInfo { - name: "num_leechs", - is_optional: false, - is_list: false, - description: Some( - "Number of leechers connected to", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "num_seeds", - description: "Number of seeds connected to", - return_type: Number( - TypeInfo { - name: "num_seeds", - is_optional: false, - is_list: false, - description: Some( - "Number of seeds connected to", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "priority", - description: "Torrent priority. Returns -1 if queuing is disabled or torrent is in seed mode", - return_type: Number( - TypeInfo { - name: "priority", - is_optional: false, - is_list: false, - description: Some( - "Torrent priority. Returns -1 if queuing is disabled or torrent is in seed mode", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "progress", - description: "Torrent progress (percentage/100)", - return_type: Float( - TypeInfo { - name: "progress", - is_optional: false, - is_list: false, - description: Some( - "Torrent progress (percentage/100)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "ratio", - description: "Torrent share ratio. Max ratio value: 9999.", - return_type: Float( - TypeInfo { - name: "ratio", - is_optional: false, - is_list: false, - description: Some( - "Torrent share ratio. Max ratio value: 9999.", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "ratio_limit", - description: "TODO (what is different from max_ratio?)", - return_type: Float( - TypeInfo { - name: "ratio_limit", - is_optional: false, - is_list: false, - description: Some( - "TODO (what is different from max_ratio?)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "save_path", - description: "Path where this torrent's data is stored", - return_type: String( - TypeInfo { - name: "save_path", - is_optional: false, - is_list: false, - description: Some( - "Path where this torrent's data is stored", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "seeding_time", - description: "Torrent elapsed time while complete (seconds)", - return_type: Number( - TypeInfo { - name: "seeding_time", - is_optional: false, - is_list: false, - description: Some( - "Torrent elapsed time while complete (seconds)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "seeding_time_limit", - description: "TODO (what is different from max_seeding_time?) seeding_time_limit is a per torrent setting, when Automatic Torrent Management is disabled, furthermore then max_seeding_time is set to seeding_time_limit for this torrent. If Automatic Torrent Management is enabled, the value is -2. And if max_seeding_time is unset it have a default value -1.", - return_type: Number( - TypeInfo { - name: "seeding_time_limit", - is_optional: false, - is_list: false, - description: Some( - "TODO (what is different from max_seeding_time?) seeding_time_limit is a per torrent setting, when Automatic Torrent Management is disabled, furthermore then max_seeding_time is set to seeding_time_limit for this torrent. If Automatic Torrent Management is enabled, the value is -2. And if max_seeding_time is unset it have a default value -1.", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "seen_complete", - description: "Time (Unix Epoch) when this torrent was last seen complete", - return_type: Number( - TypeInfo { - name: "seen_complete", - is_optional: false, - is_list: false, - description: Some( - "Time (Unix Epoch) when this torrent was last seen complete", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "seq_dl", - description: "True if sequential download is enabled", - return_type: Bool( - TypeInfo { - name: "seq_dl", - is_optional: false, - is_list: false, - description: Some( - "True if sequential download is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "size", - description: "Total size (bytes) of files selected for download", - return_type: Number( - TypeInfo { - name: "size", - is_optional: false, - is_list: false, - description: Some( - "Total size (bytes) of files selected for download", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "state", - description: "Torrent state. See table here below for the possible values", - return_type: String( - TypeInfo { - name: "state", - is_optional: false, - is_list: false, - description: Some( - "Torrent state. See table here below for the possible values", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "error", - description: "Some error occurred, applies to paused torrents", - }, - TypeDescriptions { - value: "missingFiles", - description: "Torrent data files is missing", - }, - TypeDescriptions { - value: "uploading", - description: "Torrent is being seeded and data is being transferred", - }, - TypeDescriptions { - value: "pausedUP", - description: "Torrent is paused and has finished downloading", - }, - TypeDescriptions { - value: "queuedUP", - description: "Queuing is enabled and torrent is queued for upload", - }, - TypeDescriptions { - value: "stalledUP", - description: "Torrent is being seeded, but no connection were made", - }, - TypeDescriptions { - value: "checkingUP", - description: "Torrent has finished downloading and is being checked", - }, - TypeDescriptions { - value: "forcedUP", - description: "Torrent is forced to uploading and ignore queue limit", - }, - TypeDescriptions { - value: "allocating", - description: "Torrent is allocating disk space for download", - }, - TypeDescriptions { - value: "downloading", - description: "Torrent is being downloaded and data is being transferred", - }, - TypeDescriptions { - value: "metaDL", - description: "Torrent has just started downloading and is fetching metadata", - }, - TypeDescriptions { - value: "pausedDL", - description: "Torrent is paused and has NOT finished downloading", - }, - TypeDescriptions { - value: "queuedDL", - description: "Queuing is enabled and torrent is queued for download", - }, - TypeDescriptions { - value: "stalledDL", - description: "Torrent is being downloaded, but no connection were made", - }, - TypeDescriptions { - value: "checkingDL", - description: "Same as checkingUP, but torrent has NOT finished downloading", - }, - TypeDescriptions { - value: "forcedDL", - description: "Torrent is forced to downloading to ignore queue limit", - }, - TypeDescriptions { - value: "checkingResumeData", - description: "Checking resume data on qBt startup", - }, - TypeDescriptions { - value: "moving", - description: "Torrent is moving to another location", - }, - TypeDescriptions { - value: "unknown", - description: "Unknown status", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "super_seeding", - description: "True if super seeding is enabled", - return_type: Bool( - TypeInfo { - name: "super_seeding", - is_optional: false, - is_list: false, - description: Some( - "True if super seeding is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "tags", - description: "Comma-concatenated tag list of the torrent", - return_type: String( - TypeInfo { - name: "tags", - is_optional: false, - is_list: false, - description: Some( - "Comma-concatenated tag list of the torrent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "time_active", - description: "Total active time (seconds)", - return_type: Number( - TypeInfo { - name: "time_active", - is_optional: false, - is_list: false, - description: Some( - "Total active time (seconds)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "total_size", - description: "Total size (bytes) of all file in this torrent (including unselected ones)", - return_type: Number( - TypeInfo { - name: "total_size", - is_optional: false, - is_list: false, - description: Some( - "Total size (bytes) of all file in this torrent (including unselected ones)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "tracker", - description: "The first tracker with working status. Returns empty string if no tracker is working.", - return_type: String( - TypeInfo { - name: "tracker", - is_optional: false, - is_list: false, - description: Some( - "The first tracker with working status. Returns empty string if no tracker is working.", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "up_limit", - description: "Torrent upload speed limit (bytes/s). -1 if ulimited.", - return_type: Number( - TypeInfo { - name: "up_limit", - is_optional: false, - is_list: false, - description: Some( - "Torrent upload speed limit (bytes/s). -1 if ulimited.", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "uploaded", - description: "Amount of data uploaded", - return_type: Number( - TypeInfo { - name: "uploaded", - is_optional: false, - is_list: false, - description: Some( - "Amount of data uploaded", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "uploaded_session", - description: "Amount of data uploaded this session", - return_type: Number( - TypeInfo { - name: "uploaded_session", - is_optional: false, - is_list: false, - description: Some( - "Amount of data uploaded this session", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "upspeed", - description: "Torrent upload speed (bytes/s)", - return_type: Number( - TypeInfo { - name: "upspeed", - is_optional: false, - is_list: false, - description: Some( - "Torrent upload speed (bytes/s)", - ), - type_description: None, - }, - ), - }, - ], - }, - ), - url: "info", + }, }, ApiMethod { name: "properties", description: Some( - "- empty, if the torrent hash is invalid\n- otherwise, a JSON object with the following fields\n\nNB: `-1` is returned if the type of the property is integer but its value is not known.\n\nExample:\n\n```JSON\n{\n \"addition_date\":1438429165,\n \"comment\":\"\\\"Debian CD from cdimage.debian.org\\\"\",\n \"completion_date\":1438429234,\n \"created_by\":\"\",\n \"creation_date\":1433605214,\n \"dl_limit\":-1,\n \"dl_speed\":0,\n \"dl_speed_avg\":9736015,\n \"eta\":8640000,\n \"last_seen\":1438430354,\n \"nb_connections\":3,\n \"nb_connections_limit\":250,\n \"peers\":1,\n \"peers_total\":89,\n \"piece_size\":524288,\n \"pieces_have\":1254,\n \"pieces_num\":1254,\n \"reannounce\":672,\n \"save_path\":\"/Downloads/debian-8.1.0-amd64-CD-1.iso\",\n \"seeding_time\":1128,\n \"seeds\":1,\n \"seeds_total\":254,\n \"share_ratio\":0.00072121022562178299,\n \"time_elapsed\":1197,\n \"total_downloaded\":681521119,\n \"total_downloaded_session\":681521119,\n \"total_size\":657457152,\n \"total_uploaded\":491520,\n \"total_uploaded_session\":491520,\n \"total_wasted\":23481724,\n \"up_limit\":-1,\n \"up_speed\":0,\n \"up_speed_avg\":410\n}\n```", + "The response is:\n\n- empty, if the torrent hash is invalid\n- otherwise, a JSON object with the following fields\n\n\nNB: `-1` is returned if the type of the property is integer but its value is not known.\n\nExample:\n\n```JSON\n{\n \"addition_date\":1438429165,\n \"comment\":\"\\\"Debian CD from cdimage.debian.org\\\"\",\n \"completion_date\":1438429234,\n \"created_by\":\"\",\n \"creation_date\":1433605214,\n \"dl_limit\":-1,\n \"dl_speed\":0,\n \"dl_speed_avg\":9736015,\n \"eta\":8640000,\n \"last_seen\":1438430354,\n \"nb_connections\":3,\n \"nb_connections_limit\":250,\n \"peers\":1,\n \"peers_total\":89,\n \"piece_size\":524288,\n \"pieces_have\":1254,\n \"pieces_num\":1254,\n \"reannounce\":672,\n \"save_path\":\"/Downloads/debian-8.1.0-amd64-CD-1.iso\",\n \"seeding_time\":1128,\n \"seeds\":1,\n \"seeds_total\":254,\n \"share_ratio\":0.00072121022562178299,\n \"time_elapsed\":1197,\n \"total_downloaded\":681521119,\n \"total_downloaded_session\":681521119,\n \"total_size\":657457152,\n \"total_uploaded\":491520,\n \"total_uploaded_session\":491520,\n \"total_wasted\":23481724,\n \"up_limit\":-1,\n \"up_speed\":0,\n \"up_speed_avg\":410\n}\n```", ), - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, + url: "properties", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hash", + description: Some( + "The hash of the torrent you want to get the generic properties of", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hash of the torrent you want to get the generic properties of", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "properties", + }, }, ApiMethod { name: "trackers", description: Some( - "Possible values of `status`:\n\nExample:\n\n```JSON\n[\n {\n \"msg\":\"\",\n \"num_peers\":100,\n \"status\":2,\n \"url\":\"http://bttracker.debian.org:6969/announce\"\n },\n {\n another_tracker_info\n }\n]\n```", + "The response is a JSON array, where each element contains info about one tracker, with the following fields\n\n\nPossible values of `status`:\n\n\nExample:\n\n```JSON\n[\n {\n \"msg\":\"\",\n \"num_peers\":100,\n \"status\":2,\n \"url\":\"http://bttracker.debian.org:6969/announce\"\n },\n {\n another_tracker_info\n }\n]\n```", ), - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, + url: "trackers", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hash", + description: Some( + "The hash of the torrent you want to get the trackers of", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hash of the torrent you want to get the trackers of", - ), - type_description: None, + }, + ), + Enum( + Enum { + name: "Status", + values: [ + EnumValue { + description: Some( + "Tracker is disabled (used for DHT, PeX, and LSD)", + ), + value: "TrackerIsDisabled", + original_value: "0", + }, + EnumValue { + description: Some( + "Tracker has not been contacted yet", + ), + value: "TrackerHasNotBeenContactedYet", + original_value: "1", + }, + EnumValue { + description: Some( + "Tracker has been contacted and is working", + ), + value: "TrackerHasBeenContactedAndIsWorking", + original_value: "2", + }, + EnumValue { + description: Some( + "Tracker is updating", + ), + value: "TrackerIsUpdating", + original_value: "3", + }, + EnumValue { + description: Some( + "Tracker has been contacted, but it is not working (or doesn't send proper replies)", + ), + value: "TrackerHasBeenContactedButItIsNotWorking", + original_value: "4", + }, + ], + }, + ), + Response( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "url", + description: Some( + "Tracker url", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "status", + description: Some( + "Tracker status. See the table below for possible values", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "tier", + description: Some( + "Tracker priority tier. Lower tier trackers are tried before higher tiers. Tier numbers are valid when >= 0, < 0 is used as placeholder when tier does not exist for special entries (such as DHT).", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "num_peers", + description: Some( + "Number of peers for current torrent, as reported by the tracker", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "num_seeds", + description: Some( + "Number of seeds for current torrent, asreported by the tracker", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "num_leeches", + description: Some( + "Number of leeches for current torrent, as reported by the tracker", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "num_downloaded", + description: Some( + "Number of completed downlods for current torrent, as reported by the tracker", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "msg", + description: Some( + "Tracker message (there is no way of knowing what this message is - it's up to tracker admins)", + ), + is_optional: false, + is_list: false, + }, + ), + ], + is_list: true, }, ), ], - ), - return_type: Some( - ReturnType { - is_list: true, - parameters: [ - ReturnTypeParameter { - name: "url", - description: "Tracker url", - return_type: String( - TypeInfo { - name: "url", - is_optional: false, - is_list: false, - description: Some( - "Tracker url", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "status", - description: "Tracker status. See the table below for possible values", - return_type: Number( - TypeInfo { - name: "status", - is_optional: false, - is_list: false, - description: Some( - "Tracker status. See the table below for possible values", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "Tracker is disabled (used for DHT, PeX, and LSD)", - }, - TypeDescriptions { - value: "1", - description: "Tracker has not been contacted yet", - }, - TypeDescriptions { - value: "2", - description: "Tracker has been contacted and is working", - }, - TypeDescriptions { - value: "3", - description: "Tracker is updating", - }, - TypeDescriptions { - value: "4", - description: "Tracker has been contacted, but it is not working (or doesn't send proper replies)", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "tier", - description: "Tracker priority tier. Lower tier trackers are tried before higher tiers. Tier numbers are valid when >= 0, < 0 is used as placeholder when tier does not exist for special entries (such as DHT).", - return_type: Number( - TypeInfo { - name: "tier", - is_optional: false, - is_list: false, - description: Some( - "Tracker priority tier. Lower tier trackers are tried before higher tiers. Tier numbers are valid when >= 0, < 0 is used as placeholder when tier does not exist for special entries (such as DHT).", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "num_peers", - description: "Number of peers for current torrent, as reported by the tracker", - return_type: Number( - TypeInfo { - name: "num_peers", - is_optional: false, - is_list: false, - description: Some( - "Number of peers for current torrent, as reported by the tracker", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "num_seeds", - description: "Number of seeds for current torrent, asreported by the tracker", - return_type: Number( - TypeInfo { - name: "num_seeds", - is_optional: false, - is_list: false, - description: Some( - "Number of seeds for current torrent, asreported by the tracker", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "num_leeches", - description: "Number of leeches for current torrent, as reported by the tracker", - return_type: Number( - TypeInfo { - name: "num_leeches", - is_optional: false, - is_list: false, - description: Some( - "Number of leeches for current torrent, as reported by the tracker", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "num_downloaded", - description: "Number of completed downlods for current torrent, as reported by the tracker", - return_type: Number( - TypeInfo { - name: "num_downloaded", - is_optional: false, - is_list: false, - description: Some( - "Number of completed downlods for current torrent, as reported by the tracker", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "msg", - description: "Tracker message (there is no way of knowing what this message is - it's up to tracker admins)", - return_type: String( - TypeInfo { - name: "msg", - is_optional: false, - is_list: false, - description: Some( - "Tracker message (there is no way of knowing what this message is - it's up to tracker admins)", - ), - type_description: None, - }, - ), - }, - ], - }, - ), - url: "trackers", + }, }, ApiMethod { name: "webseeds", description: Some( - "Example:\n\n```JSON\n[\n {\n \"url\":\"http://some_url/\"\n },\n {\n \"url\":\"http://some_other_url/\"\n }\n]\n```", + "The response is a JSON array, where each element is information about one webseed, with the following fields\n\n\nExample:\n\n```JSON\n[\n {\n \"url\":\"http://some_url/\"\n },\n {\n \"url\":\"http://some_other_url/\"\n }\n]\n```", ), - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, + url: "webseeds", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hash", + description: Some( + "The hash of the torrent you want to get the webseeds of", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hash of the torrent you want to get the webseeds of", - ), - type_description: None, + }, + ), + Response( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "url", + description: Some( + "URL of the web seed", + ), + is_optional: false, + is_list: false, + }, + ), + ], + is_list: true, }, ), ], - ), - return_type: Some( - ReturnType { - is_list: true, - parameters: [ - ReturnTypeParameter { - name: "url", - description: "URL of the web seed", - return_type: String( - TypeInfo { - name: "url", - is_optional: false, - is_list: false, - description: Some( - "URL of the web seed", - ), - type_description: None, - }, - ), - }, - ], - }, - ), - url: "webseeds", + }, }, ApiMethod { name: "files", description: Some( - "- empty, if the torrent hash is invalid\n- otherwise, a JSON array, where each element contains info about one file, with the following fields\n\nPossible values of `priority`:\n\nExample:\n\n```JSON\n\n[\n {\n \"index\":0,\n \"is_seed\":false,\n \"name\":\"debian-8.1.0-amd64-CD-1.iso\",\n \"piece_range\":[0,1253],\n \"priority\":1,\n \"progress\":0,\n \"size\":657457152,\n \"availability\":0.5,\n }\n]\n```", + "The response is:\n\n- empty, if the torrent hash is invalid\n- otherwise, a JSON array, where each element contains info about one file, with the following fields\n\n\nPossible values of `priority`:\n\n\nExample:\n\n```JSON\n\n[\n {\n \"index\":0,\n \"is_seed\":false,\n \"name\":\"debian-8.1.0-amd64-CD-1.iso\",\n \"piece_range\":[0,1253],\n \"priority\":1,\n \"progress\":0,\n \"size\":657457152,\n \"availability\":0.5,\n }\n]\n```", ), - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, + url: "files", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hash", + description: Some( + "The hash of the torrent you want to get the contents of", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "indexes", + description: Some( + "The indexes of the files you want to retrieve. indexes can contain multiple values separated by \\", + ), + is_optional: true, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hash of the torrent you want to get the contents of", - ), - type_description: None, }, ), - String( - TypeInfo { - name: "indexes", - is_optional: true, - is_list: false, - description: Some( - "The indexes of the files you want to retrieve. indexes can contain multiple values separated by \\", - ), - type_description: None, + Enum( + Enum { + name: "Priority", + values: [ + EnumValue { + description: Some( + "Do not download", + ), + value: "DoNotDownload", + original_value: "0", + }, + EnumValue { + description: Some( + "Normal priority", + ), + value: "NormalPriority", + original_value: "1", + }, + EnumValue { + description: Some( + "High priority", + ), + value: "HighPriority", + original_value: "6", + }, + EnumValue { + description: Some( + "Maximal priority", + ), + value: "MaximalPriority", + original_value: "7", + }, + ], }, ), ], - ), - return_type: None, - url: "files", + }, }, ApiMethod { name: "pieceStates", description: Some( - "- empty, if the torrent hash is invalid\n- otherwise, an array of states (integers) of all pieces (in order) of a specific torrent.\n\nValue meanings are defined as below:\n\nExample:\n\n```JSON\n[0,0,2,1,0,0,2,1]\n```", + "The response is:\n\n- empty, if the torrent hash is invalid\n- otherwise, an array of states (integers) of all pieces (in order) of a specific torrent.\n\nValue meanings are defined as below:\n\n\nExample:\n\n```JSON\n[0,0,2,1,0,0,2,1]\n```", ), - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, + url: "pieceStates", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hash", + description: Some( + "The hash of the torrent you want to get the pieces' states of", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hash of the torrent you want to get the pieces' states of", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "pieceStates", + }, }, ApiMethod { name: "pieceHashes", description: Some( - "- empty, if the torrent hash is invalid\n- otherwise, an array of hashes (strings) of all pieces (in order) of a specific torrent.\n\nExample:\n\n```JSON\n[\"54eddd830a5b58480a6143d616a97e3a6c23c439\",\"f8a99d225aa4241db100f88407fc3bdaead583ab\",\"928fb615b9bd4dd8f9e9022552c8f8f37ef76f58\"]\n```", + "The response is:\n\n- empty, if the torrent hash is invalid\n- otherwise, an array of hashes (strings) of all pieces (in order) of a specific torrent.\n\nExample:\n\n```JSON\n[\"54eddd830a5b58480a6143d616a97e3a6c23c439\",\"f8a99d225aa4241db100f88407fc3bdaead583ab\",\"928fb615b9bd4dd8f9e9022552c8f8f37ef76f58\"]\n```", ), - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, + url: "pieceHashes", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hash", + description: Some( + "The hash of the torrent you want to get the pieces' hashes of", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hash of the torrent you want to get the pieces' hashes of", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "pieceHashes", + }, }, ApiMethod { name: "pause", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, + url: "pause", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hashes", + description: Some( + "The hashes of the torrents you want to pause. hashes can contain multiple hashes separated by \\", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hashes of the torrents you want to pause. hashes can contain multiple hashes separated by \\", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "pause", + }, }, ApiMethod { name: "resume", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, + url: "resume", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hashes", + description: Some( + "The hashes of the torrents you want to resume. hashes can contain multiple hashes separated by \\", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hashes of the torrents you want to resume. hashes can contain multiple hashes separated by \\", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "resume", + }, }, ApiMethod { name: "delete", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, + url: "delete", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hashes", + description: Some( + "The hashes of the torrents you want to delete. hashes can contain multiple hashes separated by \\", + ), + is_optional: false, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "deleteFiles", + description: Some( + "If set to true, the downloaded data will also be deleted, otherwise has no effect.", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hashes of the torrents you want to delete. hashes can contain multiple hashes separated by \\", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "delete", + }, }, ApiMethod { name: "recheck", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, + url: "recheck", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hashes", + description: Some( + "The hashes of the torrents you want to recheck. hashes can contain multiple hashes separated by \\", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hashes of the torrents you want to recheck. hashes can contain multiple hashes separated by \\", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "recheck", + }, }, ApiMethod { name: "reannounce", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, + url: "reannounce", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hashes", + description: Some( + "The hashes of the torrents you want to reannounce. hashes can contain multiple hashes separated by \\", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hashes of the torrents you want to reannounce. hashes can contain multiple hashes separated by \\", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "reannounce", + }, }, ApiMethod { name: "add", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "urls", - is_optional: false, + url: "add", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "urls", + description: Some( + "URLs separated with newlines", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "savepath", + description: Some( + "Download folder", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "cookie", + description: Some( + "Cookie sent to download the .torrent file", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "category", + description: Some( + "Category for the torrent", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "tags", + description: Some( + "Tags for the torrent, split by ','", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "skip_checking", + description: Some( + "Skip hash checking. Possible values are true, false (default)", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "paused", + description: Some( + "Add torrents in the paused state. Possible values are true, false (default)", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "root_folder", + description: Some( + "Create the root folder. Possible values are true, false, unset (default)", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "rename", + description: Some( + "Rename torrent", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "upLimit", + description: Some( + "Set torrent upload speed limit. Unit in bytes/second", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "dlLimit", + description: Some( + "Set torrent download speed limit. Unit in bytes/second", + ), + is_optional: true, + is_list: false, + }, + ), + Float( + TypeInfo { + name: "ratioLimit", + description: Some( + "Set torrent share ratio limit", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "seedingTimeLimit", + description: Some( + "Set torrent seeding time limit. Unit in seconds", + ), + is_optional: true, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "autoTMM", + description: Some( + "Whether Automatic Torrent Management should be used", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "sequentialDownload", + description: Some( + "Enable sequential download. Possible values are true, false (default)", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "firstLastPiecePrio", + description: Some( + "Prioritize download first last piece. Possible values are true, false (default)", + ), + is_optional: true, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "URLs separated with newlines", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "savepath", - is_optional: true, - is_list: false, - description: Some( - "Download folder", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "cookie", - is_optional: true, - is_list: false, - description: Some( - "Cookie sent to download the .torrent file", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "category", - is_optional: true, - is_list: false, - description: Some( - "Category for the torrent", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "tags", - is_optional: true, - is_list: false, - description: Some( - "Tags for the torrent, split by ','", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "skip_checking", - is_optional: true, - is_list: false, - description: Some( - "Skip hash checking. Possible values are true, false (default)", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "paused", - is_optional: true, - is_list: false, - description: Some( - "Add torrents in the paused state. Possible values are true, false (default)", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "root_folder", - is_optional: true, - is_list: false, - description: Some( - "Create the root folder. Possible values are true, false, unset (default)", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "rename", - is_optional: true, - is_list: false, - description: Some( - "Rename torrent", - ), - type_description: None, - }, - ), - Number( - TypeInfo { - name: "upLimit", - is_optional: true, - is_list: false, - description: Some( - "Set torrent upload speed limit. Unit in bytes/second", - ), - type_description: None, - }, - ), - Number( - TypeInfo { - name: "dlLimit", - is_optional: true, - is_list: false, - description: Some( - "Set torrent download speed limit. Unit in bytes/second", - ), - type_description: None, - }, - ), - Float( - TypeInfo { - name: "ratioLimit", - is_optional: true, - is_list: false, - description: Some( - "Set torrent share ratio limit", - ), - type_description: None, - }, - ), - Number( - TypeInfo { - name: "seedingTimeLimit", - is_optional: true, - is_list: false, - description: Some( - "Set torrent seeding time limit. Unit in seconds", - ), - type_description: None, - }, - ), - Bool( - TypeInfo { - name: "autoTMM", - is_optional: true, - is_list: false, - description: Some( - "Whether Automatic Torrent Management should be used", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "sequentialDownload", - is_optional: true, - is_list: false, - description: Some( - "Enable sequential download. Possible values are true, false (default)", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "firstLastPiecePrio", - is_optional: true, - is_list: false, - description: Some( - "Prioritize download first last piece. Possible values are true, false (default)", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "add", + }, }, ApiMethod { name: "addTrackers", description: None, - parameters: None, - return_type: None, url: "addTrackers", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "editTracker", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, + url: "editTracker", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hash", + description: Some( + "The hash of the torrent", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "origUrl", + description: Some( + "The tracker URL you want to edit", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "newUrl", + description: Some( + "The new URL to replace the origUrl", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hash of the torrent", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "origUrl", - is_optional: false, - is_list: false, - description: Some( - "The tracker URL you want to edit", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "newUrl", - is_optional: false, - is_list: false, - description: Some( - "The new URL to replace the origUrl", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "editTracker", + }, }, ApiMethod { name: "removeTrackers", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, + url: "removeTrackers", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hash", + description: Some( + "The hash of the torrent", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "urls", + description: Some( + "URLs to remove, separated by \\", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hash of the torrent", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "urls", - is_optional: false, - is_list: false, - description: Some( - "URLs to remove, separated by \\", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "removeTrackers", + }, }, ApiMethod { name: "addPeers", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, + url: "addPeers", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hashes", + description: Some( + "The hash of the torrent, or multiple hashes separated by a pipe \\", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "peers", + description: Some( + "The peer to add, or multiple peers separated by a pipe \\", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hash of the torrent, or multiple hashes separated by a pipe \\", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "peers", - is_optional: false, - is_list: false, - description: Some( - "The peer to add, or multiple peers separated by a pipe \\", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "addPeers", + }, }, ApiMethod { name: "increasePrio", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, + url: "increasePrio", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hashes", + description: Some( + "The hashes of the torrents you want to increase the priority of. hashes can contain multiple hashes separated by \\", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hashes of the torrents you want to increase the priority of. hashes can contain multiple hashes separated by \\", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "increasePrio", + }, }, ApiMethod { name: "decreasePrio", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, + url: "decreasePrio", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hashes", + description: Some( + "The hashes of the torrents you want to decrease the priority of. hashes can contain multiple hashes separated by \\", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hashes of the torrents you want to decrease the priority of. hashes can contain multiple hashes separated by \\", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "decreasePrio", + }, }, ApiMethod { name: "topPrio", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, + url: "topPrio", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hashes", + description: Some( + "The hashes of the torrents you want to set to the maximum priority. hashes can contain multiple hashes separated by \\", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hashes of the torrents you want to set to the maximum priority. hashes can contain multiple hashes separated by \\", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "topPrio", + }, }, ApiMethod { name: "bottomPrio", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, + url: "bottomPrio", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hashes", + description: Some( + "The hashes of the torrents you want to set to the minimum priority. hashes can contain multiple hashes separated by \\", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hashes of the torrents you want to set to the minimum priority. hashes can contain multiple hashes separated by \\", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "bottomPrio", + }, }, ApiMethod { name: "filePrio", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, + url: "filePrio", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hash", + description: Some( + "The hash of the torrent", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "id", + description: Some( + "File ids, separated by \\", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "priority", + description: Some( + "File priority to set (consult [torrent contents API](#get-torrent-contents) for possible values)", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hash of the torrent", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "id", - is_optional: false, - is_list: false, - description: Some( - "File ids, separated by \\", - ), - type_description: None, - }, - ), - Number( - TypeInfo { - name: "priority", - is_optional: false, - is_list: false, - description: Some( - "File priority to set (consult [torrent contents API](#get-torrent-contents) for possible values)", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "filePrio", + }, }, ApiMethod { name: "downloadLimit", description: None, - parameters: None, - return_type: None, url: "downloadLimit", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "setShareLimits", description: None, - parameters: None, - return_type: None, url: "setShareLimits", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "uploadLimit", description: None, - parameters: None, - return_type: None, url: "uploadLimit", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "setUploadLimit", description: None, - parameters: None, - return_type: None, url: "setUploadLimit", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "setLocation", description: None, - parameters: None, - return_type: None, url: "setLocation", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "rename", description: None, - parameters: None, - return_type: None, url: "rename", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "setCategory", description: None, - parameters: None, - return_type: None, url: "setCategory", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "categories", description: None, - parameters: None, - return_type: None, url: "categories", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "createCategory", description: None, - parameters: None, - return_type: None, url: "createCategory", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "editCategory", description: None, - parameters: None, - return_type: None, url: "editCategory", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "removeCategories", description: None, - parameters: None, - return_type: None, url: "removeCategories", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "addTags", description: None, - parameters: None, - return_type: None, url: "addTags", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "removeTags", description: None, - parameters: None, - return_type: None, url: "removeTags", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "tags", description: None, - parameters: None, - return_type: None, url: "tags", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "createTags", description: None, - parameters: None, - return_type: None, url: "createTags", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "deleteTags", description: None, - parameters: None, - return_type: None, url: "deleteTags", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "setAutoManagement", description: None, - parameters: None, - return_type: None, url: "setAutoManagement", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "toggleSequentialDownload", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, + url: "toggleSequentialDownload", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hashes", + description: Some( + "The hashes of the torrents you want to toggle sequential download for. hashes can contain multiple hashes separated by \\", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hashes of the torrents you want to toggle sequential download for. hashes can contain multiple hashes separated by \\", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "toggleSequentialDownload", + }, }, ApiMethod { name: "toggleFirstLastPiecePrio", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, + url: "toggleFirstLastPiecePrio", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hashes", + description: Some( + "The hashes of the torrents you want to toggle the first/last piece priority for. hashes can contain multiple hashes separated by \\", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hashes of the torrents you want to toggle the first/last piece priority for. hashes can contain multiple hashes separated by \\", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "toggleFirstLastPiecePrio", + }, }, ApiMethod { name: "setForceStart", description: None, - parameters: None, - return_type: None, url: "setForceStart", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "setSuperSeeding", description: None, - parameters: None, - return_type: None, url: "setSuperSeeding", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "renameFile", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, + url: "renameFile", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hash", + description: Some( + "The hash of the torrent", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "oldPath", + description: Some( + "The old path of the torrent", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "newPath", + description: Some( + "The new path to use for the file", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hash of the torrent", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "oldPath", - is_optional: false, - is_list: false, - description: Some( - "The old path of the torrent", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "newPath", - is_optional: false, - is_list: false, - description: Some( - "The new path to use for the file", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "renameFile", + }, }, ApiMethod { name: "renameFolder", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, + url: "renameFolder", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "hash", + description: Some( + "The hash of the torrent", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "oldPath", + description: Some( + "The old path of the torrent", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "newPath", + description: Some( + "The new path to use for the file", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "The hash of the torrent", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "oldPath", - is_optional: false, - is_list: false, - description: Some( - "The old path of the torrent", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "newPath", - is_optional: false, - is_list: false, - description: Some( - "The new path to use for the file", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "renameFolder", + }, }, ], description: Some( @@ -5193,281 +3557,328 @@ ApiMethod { name: "addFolder", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "path", - is_optional: false, + url: "addFolder", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "path", + description: Some( + "Full path of added folder (e.g. \"The Pirate Bay\\Top100\")", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "Full path of added folder (e.g. \"The Pirate Bay\\Top100\")", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "addFolder", + }, }, ApiMethod { name: "addFeed", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "url", - is_optional: false, + url: "addFeed", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "url", + description: Some( + "URL of RSS feed (e.g. \"[http://thepiratebay.org/rss//top100/200](http://thepiratebay.org/rss//top100/200)\")", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "path", + description: Some( + "Full path of added folder (e.g. \"The Pirate Bay\\Top100\\Video\")", + ), + is_optional: true, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "URL of RSS feed (e.g. \"[http://thepiratebay.org/rss//top100/200](http://thepiratebay.org/rss//top100/200)\")", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "path", - is_optional: true, - is_list: false, - description: Some( - "Full path of added folder (e.g. \"The Pirate Bay\\Top100\\Video\")", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "addFeed", + }, }, ApiMethod { name: "removeItem", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "path", - is_optional: false, + url: "removeItem", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "path", + description: Some( + "Full path of removed item (e.g. \"The Pirate Bay\\Top100\")", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "Full path of removed item (e.g. \"The Pirate Bay\\Top100\")", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "removeItem", + }, }, ApiMethod { name: "moveItem", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "itemPath", - is_optional: false, + url: "moveItem", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "itemPath", + description: Some( + "Current full path of item (e.g. \"The Pirate Bay\\Top100\")", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "destPath", + description: Some( + "New full path of item (e.g. \"The Pirate Bay\")", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "Current full path of item (e.g. \"The Pirate Bay\\Top100\")", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "destPath", - is_optional: false, - is_list: false, - description: Some( - "New full path of item (e.g. \"The Pirate Bay\")", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "moveItem", + }, }, ApiMethod { name: "items", description: None, - parameters: Some( - [ - Bool( - TypeInfo { - name: "withData", - is_optional: true, + url: "items", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + Bool( + TypeInfo { + name: "withData", + description: Some( + "True if you need current feed articles", + ), + is_optional: true, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "True if you need current feed articles", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "items", + }, }, ApiMethod { name: "markAsRead", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "itemPath", - is_optional: false, + url: "markAsRead", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "itemPath", + description: Some( + "Current full path of item (e.g. \"The Pirate Bay\\Top100\")", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "articleId", + description: Some( + "ID of article", + ), + is_optional: true, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "Current full path of item (e.g. \"The Pirate Bay\\Top100\")", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "articleId", - is_optional: true, - is_list: false, - description: Some( - "ID of article", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "markAsRead", + }, }, ApiMethod { name: "refreshItem", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "itemPath", - is_optional: false, + url: "refreshItem", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "itemPath", + description: Some( + "Current full path of item (e.g. \"The Pirate Bay\\Top100\")", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "Current full path of item (e.g. \"The Pirate Bay\\Top100\")", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "refreshItem", + }, }, ApiMethod { name: "setRule", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "ruleName", - is_optional: false, + url: "setRule", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "ruleName", + description: Some( + "Rule name (e.g. \"Punisher\")", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "ruleDef", + description: Some( + "JSON encoded rule definition", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "Rule name (e.g. \"Punisher\")", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "ruleDef", - is_optional: false, - is_list: false, - description: Some( - "JSON encoded rule definition", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "setRule", + }, }, ApiMethod { name: "renameRule", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "ruleName", - is_optional: false, + url: "renameRule", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "ruleName", + description: Some( + "Rule name (e.g. \"Punisher\")", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "newRuleName", + description: Some( + "New rule name (e.g. \"The Punisher\")", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "Rule name (e.g. \"Punisher\")", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "newRuleName", - is_optional: false, - is_list: false, - description: Some( - "New rule name (e.g. \"The Punisher\")", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "renameRule", + }, }, ApiMethod { name: "removeRule", description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "ruleName", - is_optional: false, + url: "removeRule", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "ruleName", + description: Some( + "Rule name (e.g. \"Punisher\")", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "Rule name (e.g. \"Punisher\")", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "removeRule", + }, }, ApiMethod { name: "rules", description: None, - parameters: None, - return_type: None, url: "rules", + types: CompositeTypes { + composite_types: [], + }, }, ApiMethod { name: "matchingArticles", description: None, - parameters: None, - return_type: None, url: "matchingArticles", + types: CompositeTypes { + composite_types: [], + }, }, ], description: Some( @@ -5481,211 +3892,557 @@ ApiMethod { name: "start", description: Some( - "Example:\n\n```JSON\n{\n \"id\": 12345\n}\n```", + "The response is a JSON object with the following fields\n\n\nExample:\n\n```JSON\n{\n \"id\": 12345\n}\n```", ), - parameters: Some( - [ - String( - TypeInfo { - name: "pattern", - is_optional: false, + url: "start", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "pattern", + description: Some( + "Pattern to search for (e.g. \"Ubuntu 18.04\")", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "plugins", + description: Some( + "Plugins to use for searching (e.g. \"legittorrents\"). Supports multiple plugins separated by \\", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "category", + description: Some( + "Categories to limit your search to (e.g. \"legittorrents\"). Available categories depend on the specified plugins. Also supports all", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "Pattern to search for (e.g. \"Ubuntu 18.04\")", - ), - type_description: None, }, ), - String( - TypeInfo { - name: "plugins", - is_optional: false, + Response( + TypeWithoutName { + types: [ + Number( + TypeInfo { + name: "id", + description: Some( + "ID of the search job", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "Plugins to use for searching (e.g. \"legittorrents\"). Supports multiple plugins separated by \\", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "category", - is_optional: false, - is_list: false, - description: Some( - "Categories to limit your search to (e.g. \"legittorrents\"). Available categories depend on the specified plugins. Also supports all", - ), - type_description: None, }, ), ], - ), - return_type: Some( - ReturnType { - is_list: false, - parameters: [ - ReturnTypeParameter { - name: "id", - description: "ID of the search job", - return_type: Number( - TypeInfo { - name: "id", - is_optional: false, - is_list: false, - description: Some( - "ID of the search job", - ), - type_description: None, - }, - ), - }, - ], - }, - ), - url: "start", + }, }, ApiMethod { name: "stop", description: None, - parameters: Some( - [ - Number( - TypeInfo { - name: "id", - is_optional: false, + url: "stop", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + Number( + TypeInfo { + name: "id", + description: Some( + "ID of the search job", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "ID of the search job", - ), - type_description: None, }, ), ], - ), - return_type: None, - url: "stop", + }, }, ApiMethod { name: "status", description: Some( - "Example:\n\n```JSON\n[\n {\n \"id\": 12345,\n \"status\": \"Running\",\n \"total\": 170\n }\n]\n```", + "The response is a JSON array of objects containing the following fields\n\n\nExample:\n\n```JSON\n[\n {\n \"id\": 12345,\n \"status\": \"Running\",\n \"total\": 170\n }\n]\n```", ), - parameters: Some( - [ - Number( - TypeInfo { - name: "id", - is_optional: true, + url: "status", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + Number( + TypeInfo { + name: "id", + description: Some( + "ID of the search job. If not specified, all search jobs are returned", + ), + is_optional: true, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "ID of the search job. If not specified, all search jobs are returned", - ), - type_description: None, + }, + ), + Response( + TypeWithoutName { + types: [ + Number( + TypeInfo { + name: "id", + description: Some( + "ID of the search job", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "status", + description: Some( + "Current status of the search job (either Running or Stopped)", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "total", + description: Some( + "Total number of results. If the status is Running this number may contineu to increase", + ), + is_optional: false, + is_list: false, + }, + ), + ], + is_list: true, }, ), ], - ), - return_type: Some( - ReturnType { - is_list: true, - parameters: [ - ReturnTypeParameter { - name: "id", - description: "ID of the search job", - return_type: Number( - TypeInfo { - name: "id", - is_optional: false, - is_list: false, - description: Some( - "ID of the search job", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "status", - description: "Current status of the search job (either Running or Stopped)", - return_type: String( - TypeInfo { - name: "status", - is_optional: false, - is_list: false, - description: Some( - "Current status of the search job (either Running or Stopped)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "total", - description: "Total number of results. If the status is Running this number may contineu to increase", - return_type: Number( - TypeInfo { - name: "total", - is_optional: false, - is_list: false, - description: Some( - "Total number of results. If the status is Running this number may contineu to increase", - ), - type_description: None, - }, - ), - }, - ], - }, - ), - url: "status", + }, }, ApiMethod { name: "results", - description: None, - parameters: Some( - [ - Number( - TypeInfo { - name: "id", - is_optional: false, + description: Some( + "The response is a JSON object with the following fields\n\n\n\n\nExample:\n\n```JSON\n{\n \"results\": [\n {\n \"descrLink\": \"http://www.legittorrents.info/index.php?page=torrent-details&id=8d5f512e1acb687029b8d7cc6c5a84dce51d7a41\",\n \"fileName\": \"Ubuntu-10.04-32bit-NeTV.ova\",\n \"fileSize\": -1,\n \"fileUrl\": \"http://www.legittorrents.info/download.php?id=8d5f512e1acb687029b8d7cc6c5a84dce51d7a41&f=Ubuntu-10.04-32bit-NeTV.ova.torrent\",\n \"nbLeechers\": 1,\n \"nbSeeders\": 0,\n \"siteUrl\": \"http://www.legittorrents.info\"\n },\n {\n \"descrLink\": \"http://www.legittorrents.info/index.php?page=torrent-details&id=d5179f53e105dc2c2401bcfaa0c2c4936a6aa475\",\n \"fileName\": \"mangOH-Legato-17_06-Ubuntu-16_04.ova\",\n \"fileSize\": -1,\n \"fileUrl\": \"http://www.legittorrents.info/download.php?id=d5179f53e105dc2c2401bcfaa0c2c4936a6aa475&f=mangOH-Legato-17_06-Ubuntu-16_04.ova.torrent\",\n \"nbLeechers\": 0,\n \"nbSeeders\": 59,\n \"siteUrl\": \"http://www.legittorrents.info\"\n }\n ],\n \"status\": \"Running\",\n \"total\": 2\n}\n```", + ), + url: "results", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + Number( + TypeInfo { + name: "id", + description: Some( + "ID of the search job", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "limit", + description: Some( + "max number of results to return. 0 or negative means no limit", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "offset", + description: Some( + "result to start at. A negative number means count backwards (e.g. -2 returns the 2 most recent results)", + ), + is_optional: true, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "ID of the search job", - ), - type_description: None, }, ), - Number( - TypeInfo { - name: "limit", - is_optional: true, - is_list: false, - description: Some( - "max number of results to return. 0 or negative means no limit", - ), - type_description: None, + Object( + TypeWithName { + name: "Result", + types: [ + String( + TypeInfo { + name: "descrLink", + description: Some( + "URL of the torrent's description page", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "fileName", + description: Some( + "Name of the file", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "fileSize", + description: Some( + "Size of the file in Bytes", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "fileUrl", + description: Some( + "Torrent download link (usually either .torrent file or magnet link)", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "nbLeechers", + description: Some( + "Number of leechers", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "nbSeeders", + description: Some( + "Number of seeders", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "siteUrl", + description: Some( + "URL of the torrent site", + ), + is_optional: false, + is_list: false, + }, + ), + ], }, ), - Number( - TypeInfo { - name: "offset", - is_optional: true, + Response( + TypeWithoutName { + types: [ + Object( + Object { + type_info: TypeInfo { + name: "results", + description: Some( + "Array of result objects- see table below", + ), + is_optional: false, + is_list: true, + }, + ref_type: String( + "Result", + ), + }, + ), + String( + TypeInfo { + name: "status", + description: Some( + "Current status of the search job (either Running or Stopped)", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "total", + description: Some( + "Total number of results. If the status is Running this number may continue to increase", + ), + is_optional: false, + is_list: false, + }, + ), + ], is_list: false, - description: Some( - "result to start at. A negative number means count backwards (e.g. -2 returns the 2 most recent results)", - ), - type_description: None, }, ), ], + }, + }, + ApiMethod { + name: "delete", + description: None, + url: "delete", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + Number( + TypeInfo { + name: "id", + description: Some( + "ID of the search job", + ), + is_optional: false, + is_list: false, + }, + ), + ], + is_list: false, + }, + ), + ], + }, + }, + ApiMethod { + name: "plugins", + description: Some( + "The response is a JSON array of objects containing the following fields\n\n\n```JSON\n[\n {\n \"enabled\": true,\n \"fullName\": \"Legit Torrents\",\n \"name\": \"legittorrents\",\n \"supportedCategories\": [{\n \"id\": \"all\",\n \"name\": \"All categories\"\n }, {\n \"id\": \"anime\",\n \"name\": \"Anime\"\n }, {\n \"id\": \"books\",\n \"name\": \"Books\"\n }, {\n \"id\": \"games\",\n \"name\": \"Games\"\n }, {\n \"id\": \"movies\",\n \"name\": \"Movies\"\n }, {\n \"id\": \"music\",\n \"name\": \"Music\"\n }, {\n \"id\": \"tv\",\n \"name\": \"TV shows\"\n }],\n \"url\": \"http://www.legittorrents.info\",\n \"version\": \"2.3\"\n }\n]\n```", ), - return_type: Some( - ReturnType { - is_list: false, - parameters: [], - }, - ), - url: "results", + url: "plugins", + types: CompositeTypes { + composite_types: [ + Object( + TypeWithName { + name: "Category", + types: [ + String( + TypeInfo { + name: "id", + description: Some( + "Id", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "name", + description: Some( + "Name", + ), + is_optional: false, + is_list: false, + }, + ), + ], + }, + ), + Response( + TypeWithoutName { + types: [ + Bool( + TypeInfo { + name: "enabled", + description: Some( + "Whether the plugin is enabled", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "fullName", + description: Some( + "Full name of the plugin", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "name", + description: Some( + "Short name of the plugin", + ), + is_optional: false, + is_list: false, + }, + ), + Object( + Object { + type_info: TypeInfo { + name: "supportedCategories", + description: Some( + "List of category objects", + ), + is_optional: false, + is_list: true, + }, + ref_type: String( + "Category", + ), + }, + ), + String( + TypeInfo { + name: "url", + description: Some( + "URL of the torrent site", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "version", + description: Some( + "Installed version of the plugin", + ), + is_optional: false, + is_list: false, + }, + ), + ], + is_list: true, + }, + ), + ], + }, + }, + ApiMethod { + name: "installPlugin", + description: None, + url: "installPlugin", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "sources", + description: Some( + "Url or file path of the plugin to install (e.g. \"[https://raw.githubusercontent.com/qbittorrent/search-plugins/master/nova3/engines/legittorrents.py](https://raw.githubusercontent.com/qbittorrent/search-plugins/master/nova3/engines/legittorrents.py)\"). Supports multiple sources separated by \\", + ), + is_optional: false, + is_list: false, + }, + ), + ], + is_list: false, + }, + ), + ], + }, + }, + ApiMethod { + name: "uninstallPlugin", + description: None, + url: "uninstallPlugin", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "names", + description: Some( + "Name of the plugin to uninstall (e.g. \"legittorrents\"). Supports multiple names separated by \\", + ), + is_optional: false, + is_list: false, + }, + ), + ], + is_list: false, + }, + ), + ], + }, + }, + ApiMethod { + name: "enablePlugin", + description: None, + url: "enablePlugin", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + String( + TypeInfo { + name: "names", + description: Some( + "Name of the plugin to enable/disable (e.g. \"legittorrents\"). Supports multiple names separated by \\", + ), + is_optional: false, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "enable", + description: Some( + "Whether the plugins should be enabled", + ), + is_optional: false, + is_list: false, + }, + ), + ], + is_list: false, + }, + ), + ], + }, + }, + ApiMethod { + name: "updatePlugins", + description: None, + url: "updatePlugins", + types: CompositeTypes { + composite_types: [], + }, }, ], description: Some( diff --git a/qbittorrent-web-api-gen/src/generate/api_group.rs b/qbittorrent-web-api-gen/src/generate/api_group.rs new file mode 100644 index 0000000..26abae1 --- /dev/null +++ b/qbittorrent-web-api-gen/src/generate/api_group.rs @@ -0,0 +1,89 @@ +use crate::parser; +use case::CaseExt; +use proc_macro2::{Ident, TokenStream}; +use quote::quote; + +use super::{group_method::GroupMethod, skeleton::auth_ident, util}; + +impl parser::ApiGroup { + pub fn generate(&self) -> TokenStream { + let struct_name = self.struct_name(); + let group_name_snake = self.name_snake(); + let group_methods = self.generate_group_methods(); + + let group_struct = self.group_struct(); + let group_factory = self.group_factory(); + let auth = auth_ident(); + + quote! { + pub mod #group_name_snake { + impl <'a> #struct_name<'a> { + pub fn new(auth: &'a super::#auth) -> Self { + Self { auth } + } + } + + #group_struct + #group_factory + + #(#group_methods)* + } + } + } + + fn generate_group_methods(&self) -> Vec { + let group_methods = self.group_methods(); + group_methods + .iter() + .map(|group_method| group_method.generate_method()) + .collect() + } + + fn group_factory(&self) -> TokenStream { + let struct_name = self.struct_name(); + let name_snake = self.name_snake(); + let auth = auth_ident(); + + util::add_docs( + &self.description, + quote! { + impl super::#auth { + pub fn #name_snake(&self) -> #struct_name { + #struct_name::new(self) + } + } + }, + ) + } + + fn group_struct(&self) -> TokenStream { + let struct_name = self.struct_name(); + let auth = auth_ident(); + + quote! { + #[derive(Debug)] + pub struct #struct_name<'a> { + auth: &'a super::#auth, + } + } + } + + fn group_methods(&self) -> Vec { + self.methods + .iter() + .map(|method| GroupMethod::new(self, method)) + .collect() + } + + pub fn struct_name(&self) -> Ident { + self.name_camel() + } + + fn name_camel(&self) -> Ident { + util::to_ident(&self.name.to_camel()) + } + + fn name_snake(&self) -> Ident { + util::to_ident(&self.name.to_snake()) + } +} diff --git a/qbittorrent-web-api-gen/src/generate/api_method.rs b/qbittorrent-web-api-gen/src/generate/api_method.rs new file mode 100644 index 0000000..abdb8cf --- /dev/null +++ b/qbittorrent-web-api-gen/src/generate/api_method.rs @@ -0,0 +1,31 @@ +use case::CaseExt; +use proc_macro2::{Ident, TokenStream}; +use quote::quote; + +use crate::parser; + +use super::util; + +impl parser::ApiMethod { + pub fn structs(&self) -> TokenStream { + let objects = self.types.objects(); + let structs = objects.iter().map(|obj| obj.generate_struct()); + + quote! { + #(#structs)* + } + } + + pub fn enums(&self) -> TokenStream { + let enums = self.types.enums(); + let generated_enums = enums.iter().map(|e| e.generate()); + + quote! { + #(#generated_enums)* + } + } + + pub fn name_snake(&self) -> Ident { + util::to_ident(&self.name.to_snake()) + } +} diff --git a/qbittorrent-web-api-gen/src/generate/group.rs b/qbittorrent-web-api-gen/src/generate/group.rs new file mode 100644 index 0000000..f2988bf --- /dev/null +++ b/qbittorrent-web-api-gen/src/generate/group.rs @@ -0,0 +1,184 @@ +use crate::{parser, types}; +use case::CaseExt; +use proc_macro2::{Ident, TokenStream}; +use quote::quote; + +use super::util; + +pub fn generate_groups(groups: Vec) -> TokenStream { + let gr = groups + .iter() + // implemented manually + .filter(|group| group.name != "authentication") + .map(generate_group); + + quote! { + #(#gr)* + } +} + +fn generate_group(group: &parser::ApiGroup) -> TokenStream { + let group = group.generate(); + + quote! { + #group + } +} + +impl parser::TypeWithName { + pub fn generate_struct(&self) -> TokenStream { + let fields = self.types.iter().map(|obj| obj.generate_struct_field()); + let name = util::to_ident(&self.name); + + quote! { + #[derive(Debug, serde::Deserialize)] + pub struct #name { + #(#fields,)* + } + } + } +} + +impl types::Type { + pub fn generate_struct_field(&self) -> TokenStream { + let name_snake = self.name_snake(); + let type_ = self.owned_type_ident(); + let orig_name = self.name(); + + util::add_docs( + &self.get_type_info().description, + quote! { + #[serde(rename = #orig_name)] + pub #name_snake: #type_ + }, + ) + } + + fn owned_type_ident(&self) -> TokenStream { + let owned_type = match self { + types::Type::Number(_) => quote! { i128 }, + types::Type::Float(_) => quote! { f32 }, + types::Type::Bool(_) => quote! { bool }, + types::Type::String(_) => quote! { String }, + types::Type::StringArray(_) => quote! { String }, + types::Type::Object(obj) => match &obj.ref_type { + types::RefType::String(str) => { + let str_ident = &util::to_ident(str); + quote! { #str_ident } + } + types::RefType::Map(key, value) => { + let key_ident = util::to_ident(key); + let value_ident = util::to_ident(value); + quote! { std::collections::HashMap<#key_ident, #value_ident> } + } + }, + }; + + if self.is_list() { + quote! { std::vec::Vec<#owned_type> } + } else { + owned_type + } + } + + fn name(&self) -> String { + self.get_type_info().name.clone() + } + + fn name_snake(&self) -> Ident { + util::to_ident(&self.name().to_snake()) + } +} + +impl parser::Enum { + pub fn generate(&self) -> TokenStream { + let values = self.values.iter().map(|enum_value| enum_value.generate()); + let name = util::to_ident(&self.name); + + quote! { + #[allow(clippy::enum_variant_names)] + #[derive(Debug, serde::Deserialize, PartialEq, Eq)] + pub enum #name { + #(#values,)* + } + } + } +} + +impl parser::EnumValue { + fn generate(&self) -> TokenStream { + util::add_docs(&self.description, self.generate_field()) + } + + fn generate_field(&self) -> TokenStream { + let orig_name = self.original_value.clone(); + + // special enum value which does not follow conventions + if orig_name == "\"/path/to/download/to\"" { + quote! { + PathToDownloadTo(String) + } + } else { + let name_camel = self.name_camel(); + quote! { + #[serde(rename = #orig_name)] + #name_camel + } + } + } + + fn name_camel(&self) -> Ident { + util::to_ident(&self.value.to_camel()) + } +} + +impl types::Type { + pub fn generate_optional_builder_method_with_docs(&self) -> TokenStream { + util::add_docs( + &self.get_type_info().description, + self.generate_optional_builder_method(), + ) + } + + fn borrowed_type_ident(&self) -> Ident { + util::to_ident(&self.to_borrowed_type()) + } + + pub fn to_parameter(&self) -> TokenStream { + let name_snake = self.name_snake(); + let borrowed_type = self.borrowed_type(); + + quote! { #name_snake: #borrowed_type } + } + + pub fn generate_form_builder(&self, add_to: TokenStream) -> TokenStream { + let name_str = self.name(); + let name_snake = self.name_snake(); + + quote! { + #add_to = #add_to.text(#name_str, #name_snake.to_string()); + } + } + + fn generate_optional_builder_method(&self) -> TokenStream { + let name_snake = self.name_snake(); + let borrowed_type = self.borrowed_type(); + let form_builder = self.generate_form_builder(quote! { self.form }); + + quote! { + pub fn #name_snake(mut self, #name_snake: #borrowed_type) -> Self { + #form_builder; + self + } + } + } + + fn borrowed_type(&self) -> TokenStream { + let type_ = self.borrowed_type_ident(); + if self.should_borrow() { + quote! { &#type_ } + } else { + quote! { #type_ } + } + } +} diff --git a/qbittorrent-web-api-gen/src/generate/group/method/method_with_params.rs b/qbittorrent-web-api-gen/src/generate/group/method/method_with_params.rs deleted file mode 100644 index 5af6ef0..0000000 --- a/qbittorrent-web-api-gen/src/generate/group/method/method_with_params.rs +++ /dev/null @@ -1,156 +0,0 @@ -use case::CaseExt; -use quote::quote; - -use crate::{generate::util, parser, types}; - -use super::{return_type::create_return_type, send_method_builder::SendMethodBuilder}; - -pub fn create_method_with_params( - group: &parser::ApiGroup, - method: &parser::ApiMethod, - params: &[types::Type], - method_name: &proc_macro2::Ident, - url: &str, -) -> (proc_macro2::TokenStream, Option) { - let param_type = util::to_ident(&format!( - "{}{}Parameters", - group.name.to_camel(), - method.name.to_camel() - )); - - let mandatory_params = mandatory_params(params); - let mandatory_param_args = generate_mandatory_params(&mandatory_params); - - let mandatory_param_names = mandatory_params.iter().map(|param| { - let (name, ..) = param_name(param); - quote! { #name } - }); - - let group_name = util::to_ident(&group.name.to_camel()); - let send_builder = - SendMethodBuilder::new(&util::to_ident("send"), url, quote! { self.group.auth }) - .with_form(); - - let generate_send_impl = |send_method: proc_macro2::TokenStream| { - let optional_params = generate_optional_params(params); - let mandatory_param_form_build = generate_mandatory_param_builder(&mandatory_params); - - quote! { - impl<'a> #param_type<'a> { - fn new(group: &'a #group_name, #(#mandatory_param_args),*) -> Self { - let form = reqwest::multipart::Form::new(); - #(#mandatory_param_form_build)* - Self { group, form } - } - - #(#optional_params)* - #send_method - } - } - }; - - let send = match create_return_type(group, method) { - Some((return_type_name, return_type)) => { - let send_impl = generate_send_impl(send_builder.return_type(&return_type_name).build()); - - quote! { - #send_impl - #return_type - } - } - None => generate_send_impl(send_builder.build()), - }; - - let builder = util::add_docs( - &method.description, - quote! { - pub fn #method_name(&self, #(#mandatory_param_args),*) -> #param_type { - #param_type::new(self, #(#mandatory_param_names),*) - } - }, - ); - - let group_impl = quote! { - pub struct #param_type<'a> { - group: &'a #group_name<'a>, - form: reqwest::multipart::Form, - } - - #send - }; - - (builder, Some(group_impl)) -} - -fn generate_mandatory_params(mandatory_params: &[&types::Type]) -> Vec { - mandatory_params - .iter() - .map(|param| param_with_name(param)) - .collect() -} - -fn generate_mandatory_param_builder( - mandatory_params: &[&types::Type], -) -> Vec { - mandatory_params - .iter() - .map(|param| { - let (name, name_as_str) = param_name(param); - quote! { let form = form.text(#name_as_str, #name.to_string()); } - }) - .collect() -} - -fn generate_optional_params(params: &[types::Type]) -> Vec { - params - .iter() - .filter(|param| param.get_type_info().is_optional) - .map(generate_optional_param) - .collect() -} - -fn mandatory_params(params: &[types::Type]) -> Vec<&types::Type> { - params - .iter() - .filter(|param| !param.get_type_info().is_optional) - .collect() -} - -fn generate_optional_param(param: &types::Type) -> proc_macro2::TokenStream { - let n = ¶m.get_type_info().name; - let name = util::to_ident(&n.to_snake()); - let t = util::to_ident(¶m.to_borrowed_type()); - let builder_param = if param.should_borrow() { - quote! { &#t } - } else { - quote! { #t } - }; - - util::add_docs( - ¶m.get_type_info().description, - quote! { - pub fn #name(mut self, value: #builder_param) -> Self { - self.form = self.form.text(#n, value.to_string()); - self - } - }, - ) -} - -fn param_name(param: &types::Type) -> (proc_macro2::Ident, String) { - let name_as_str = param.get_type_info().name.to_snake(); - (util::to_ident(&name_as_str), name_as_str) -} - -fn param_with_name(param: &types::Type) -> proc_macro2::TokenStream { - let t = util::to_ident(¶m.to_borrowed_type()); - - let (name, ..) = param_name(param); - let t = if param.should_borrow() { - quote! { &#t } - } else { - quote! { #t } - }; - - quote! { #name: #t } -} diff --git a/qbittorrent-web-api-gen/src/generate/group/method/method_without_params.rs b/qbittorrent-web-api-gen/src/generate/group/method/method_without_params.rs deleted file mode 100644 index b705257..0000000 --- a/qbittorrent-web-api-gen/src/generate/group/method/method_without_params.rs +++ /dev/null @@ -1,26 +0,0 @@ -use quote::quote; - -use super::{return_type::create_return_type, send_method_builder::SendMethodBuilder}; -use crate::parser; - -pub fn create_method_without_params( - group: &parser::ApiGroup, - method: &parser::ApiMethod, - method_name: proc_macro2::Ident, - url: &str, -) -> (proc_macro2::TokenStream, Option) { - let builder = SendMethodBuilder::new(&method_name, url, quote! { self.auth }) - .description(&method.description); - - match create_return_type(group, method) { - Some((return_type_name, return_type)) => ( - builder.return_type(&return_type_name).build(), - Some(return_type), - ), - None => ( - builder.build(), - // assume that all methods without a return type returns a string - None, - ), - } -} diff --git a/qbittorrent-web-api-gen/src/generate/group/method/mod.rs b/qbittorrent-web-api-gen/src/generate/group/method/mod.rs deleted file mode 100644 index 3c2ea73..0000000 --- a/qbittorrent-web-api-gen/src/generate/group/method/mod.rs +++ /dev/null @@ -1,52 +0,0 @@ -mod method_with_params; -mod method_without_params; -mod return_type; -mod send_method_builder; - -use crate::{generate::util, parser}; -use case::CaseExt; -use quote::quote; - -use self::{ - method_with_params::create_method_with_params, - method_without_params::create_method_without_params, -}; - -pub fn generate_methods( - group: &parser::ApiGroup, - auth: &syn::Ident, - group_name_camel: &syn::Ident, -) -> proc_macro2::TokenStream { - let methods_and_param_structs = group - .methods - .iter() - .map(|method| generate_method(group, method)); - - let methods = methods_and_param_structs.clone().map(|(method, ..)| method); - let structs = methods_and_param_structs.flat_map(|(_, s)| s); - - quote! { - impl <'a> #group_name_camel<'a> { - pub fn new(auth: &'a #auth) -> Self { - Self { auth } - } - - #(#methods)* - } - - #(#structs)* - } -} - -fn generate_method( - group: &parser::ApiGroup, - method: &parser::ApiMethod, -) -> (proc_macro2::TokenStream, Option) { - let method_name = util::to_ident(&method.name.to_snake()); - let url = format!("/api/v2/{}/{}", group.url, method.url); - - match &method.parameters { - Some(params) => create_method_with_params(group, method, params, &method_name, &url), - None => create_method_without_params(group, method, method_name, &url), - } -} diff --git a/qbittorrent-web-api-gen/src/generate/group/method/return_type.rs b/qbittorrent-web-api-gen/src/generate/group/method/return_type.rs deleted file mode 100644 index 4fc68f5..0000000 --- a/qbittorrent-web-api-gen/src/generate/group/method/return_type.rs +++ /dev/null @@ -1,203 +0,0 @@ -use std::collections::HashMap; - -use case::CaseExt; -use quote::{format_ident, quote}; -use regex::Regex; - -use crate::{generate::util, parser, types}; - -pub fn create_return_type( - group: &parser::ApiGroup, - method: &parser::ApiMethod, -) -> Option<(proc_macro2::TokenStream, proc_macro2::TokenStream)> { - let return_type = match &method.return_type { - Some(t) => t, - None => return None, - }; - - let to_enum_name = |name: &str| to_enum_name(&group.name, &method.name, name); - - let enum_types_with_names: Vec<(String, proc_macro2::TokenStream)> = - create_enum_with_names(return_type, &group.name, &method.name); - - let enum_names: HashMap = enum_types_with_names - .iter() - .map(|(enum_name, _)| (enum_name.clone(), to_enum_name(enum_name))) - .collect(); - - let enum_types = enum_types_with_names.iter().map(|(_, enum_type)| enum_type); - - let builder_fields = return_type - .parameters - .iter() - .map(|parameter| generate_builder_field(parameter, &enum_names)); - - let return_type_name = util::to_ident(&format!( - "{}{}Result", - &group.name.to_camel(), - &method.name.to_camel() - )); - - let result_type = if return_type.is_list { - quote! { std::vec::Vec<#return_type_name> } - } else { - quote! { #return_type_name } - }; - - Some(( - result_type, - quote! { - #[derive(Debug, Deserialize)] - pub struct #return_type_name { - #(#builder_fields,)* - } - - #(#enum_types)* - }, - )) -} - -fn create_enum_with_names( - return_type: &parser::ReturnType, - group_name: &str, - method_name: &str, -) -> Vec<(String, proc_macro2::TokenStream)> { - return_type - .parameters - .iter() - .flat_map(create_enum_fields) - .map(|(name, enum_fields)| create_enum(enum_fields, group_name, method_name, name)) - .collect() -} - -fn create_enum( - enum_fields: Vec, - group_name: &str, - method_name: &str, - name: String, -) -> (String, proc_macro2::TokenStream) { - let enum_name = util::to_ident(&to_enum_name(group_name, method_name, &name)); - ( - name, - quote! { - #[allow(clippy::enum_variant_names)] - #[derive(Debug, Deserialize, PartialEq, Eq)] - pub enum #enum_name { - #(#enum_fields,)* - } - }, - ) -} - -fn create_enum_fields( - parameter: &parser::ReturnTypeParameter, -) -> Option<(String, Vec)> { - match ¶meter.return_type { - types::Type::Number(types::TypeInfo { - ref name, - type_description: Some(type_description), - .. - }) => create_enum_field_value(type_description, name, create_number_enum_value), - types::Type::String(types::TypeInfo { - ref name, - type_description: Some(type_description), - .. - }) => create_enum_field_value(type_description, name, create_string_enum_value), - _ => None, - } -} - -fn generate_builder_field( - parameter: &parser::ReturnTypeParameter, - enum_names: &HashMap, -) -> proc_macro2::TokenStream { - let namestr = ¶meter.name; - let name = util::to_ident(&namestr.to_snake().replace("__", "_")); - let enum_name = match enum_names.get(namestr) { - Some(enum_type) => enum_type.to_owned(), - None => parameter.return_type.to_owned_type(), - }; - let rtype = util::to_ident(&enum_name); - let rtype_as_quote = if parameter.return_type.get_type_info().is_list { - quote! { std::vec::Vec<#rtype> } - } else { - quote! { #rtype } - }; - let generate_field = |field_name| { - quote! { - #[serde(rename = #namestr)] - pub #field_name: #rtype_as_quote - } - }; - - // "type" is a reserved keyword in Rust, so we just add "t_" to it. - if namestr == "type" { - generate_field(format_ident!("t_{}", name)) - } else { - generate_field(name) - } -} - -fn create_enum_field_value( - type_description: &types::TypeDescription, - name: &str, - f: F, -) -> Option<(String, Vec)> -where - F: Fn(&types::TypeDescriptions) -> proc_macro2::TokenStream, -{ - let enum_fields: Vec = type_description - .values - .iter() - .map(f) - .collect::>(); - - let nn = name.to_string(); - - Some((nn, enum_fields)) -} - -fn create_string_enum_value( - type_description: &types::TypeDescriptions, -) -> proc_macro2::TokenStream { - let value = &type_description.value; - let value_as_ident = util::to_ident(&value.to_camel()); - create_enum_field(&value_as_ident, value, &type_description.description) -} - -fn create_number_enum_value(value: &types::TypeDescriptions) -> proc_macro2::TokenStream { - let v = &value.value; - let re = Regex::new(r#"\(.*\)"#).unwrap(); - let desc = &value - .description - .replace(' ', "_") - .replace('-', "_") - .replace(',', "_"); - let desc_without_parentheses = re.replace_all(desc, ""); - let ident = util::to_ident(&desc_without_parentheses.to_camel()); - - create_enum_field(&ident, v, &value.description) -} - -fn create_enum_field( - ident: &syn::Ident, - rename: &str, - description: &str, -) -> proc_macro2::TokenStream { - util::add_docs( - &Some(description.to_string()), - quote! { - #[serde(rename = #rename)] - #ident - }, - ) -} - -fn to_enum_name(group_name: &str, method_name: &str, name: &str) -> String { - format!( - "{}{}{}", - group_name.to_camel(), - method_name.to_camel(), - name.to_camel() - ) -} diff --git a/qbittorrent-web-api-gen/src/generate/group/method/send_method_builder.rs b/qbittorrent-web-api-gen/src/generate/group/method/send_method_builder.rs deleted file mode 100644 index da0c44a..0000000 --- a/qbittorrent-web-api-gen/src/generate/group/method/send_method_builder.rs +++ /dev/null @@ -1,76 +0,0 @@ -use quote::quote; - -use crate::generate::util; - -pub struct SendMethodBuilder { - method_name: syn::Ident, - url: String, - auth_module_path: proc_macro2::TokenStream, - return_type: Option, - description: Option, - form: bool, -} - -impl SendMethodBuilder { - pub fn new( - method_name: &syn::Ident, - url: &str, - auth_module_path: proc_macro2::TokenStream, - ) -> Self { - Self { - method_name: method_name.clone(), - url: url.to_string(), - auth_module_path, - return_type: None, - description: None, - form: false, - } - } - - pub fn return_type(mut self, value: &proc_macro2::TokenStream) -> Self { - self.return_type = Some(value.clone()); - self - } - - pub fn description(mut self, value: &Option) -> Self { - self.description = value.clone(); - self - } - - pub fn with_form(mut self) -> Self { - self.form = true; - self - } - - pub fn build(&self) -> proc_macro2::TokenStream { - let method_name = &self.method_name; - let (return_type, parse_type) = match &self.return_type { - Some(t) => (t.clone(), quote! { .json::<#t>() }), - None => (quote! { String }, quote! { .text() }), - }; - let url = &self.url; - let auth_module_path = &self.auth_module_path; - let form = if self.form { - quote! { .multipart(self.form) } - } else { - quote! {} - }; - - util::add_docs( - &self.description, - quote! { - pub async fn #method_name(self) -> Result<#return_type> { - let res = #auth_module_path - .authenticated_client(#url) - #form - .send() - .await? - #parse_type - .await?; - - Ok(res) - } - }, - ) - } -} diff --git a/qbittorrent-web-api-gen/src/generate/group/mod.rs b/qbittorrent-web-api-gen/src/generate/group/mod.rs deleted file mode 100644 index bf4c911..0000000 --- a/qbittorrent-web-api-gen/src/generate/group/mod.rs +++ /dev/null @@ -1,49 +0,0 @@ -mod method; - -use crate::parser; -use case::CaseExt; -use quote::quote; - -use self::method::generate_methods; - -use super::{skeleton::auth_ident, util}; - -pub fn generate_groups(groups: Vec) -> proc_macro2::TokenStream { - let gr = groups - .iter() - // implemented manually - .filter(|group| group.name != "authentication") - .map(generate_group); - - quote! { - #(#gr)* - } -} - -fn generate_group(group: &parser::ApiGroup) -> proc_macro2::TokenStream { - let group_name_camel = util::to_ident(&group.name.to_camel()); - let group_name_snake = util::to_ident(&group.name.to_snake()); - let auth = auth_ident(); - let methods = generate_methods(group, &auth, &group_name_camel); - - let group_method = util::add_docs( - &group.description, - quote! { - pub fn #group_name_snake(&self) -> #group_name_camel { - #group_name_camel::new(self) - } - }, - ); - - quote! { - pub struct #group_name_camel<'a> { - auth: &'a #auth, - } - - #methods - - impl #auth { - #group_method - } - } -} diff --git a/qbittorrent-web-api-gen/src/generate/group_method.rs b/qbittorrent-web-api-gen/src/generate/group_method.rs new file mode 100644 index 0000000..e8fb818 --- /dev/null +++ b/qbittorrent-web-api-gen/src/generate/group_method.rs @@ -0,0 +1,186 @@ +use crate::parser; +use proc_macro2::{Ident, TokenStream}; +use quote::quote; + +use super::util; + +#[derive(Debug)] +pub struct GroupMethod<'a> { + group: &'a parser::ApiGroup, + method: &'a parser::ApiMethod, +} + +impl<'a> GroupMethod<'a> { + pub fn new(group: &'a parser::ApiGroup, method: &'a parser::ApiMethod) -> Self { + Self { group, method } + } + + pub fn generate_method(&self) -> TokenStream { + let method_name = self.method.name_snake(); + let structs = self.method.structs(); + let enums = self.method.enums(); + let builder = self.generate_request_builder(); + let response_struct = self.generate_response_struct(); + let request_method = self.generate_request_method(); + + quote! { + pub mod #method_name { + #structs + #enums + #builder + #response_struct + #request_method + } + } + } + + fn generate_request_method(&self) -> TokenStream { + let method_name = self.method.name_snake(); + + let parameters = self + .method + .types + .mandatory_params() + .iter() + .map(|param| param.to_parameter()) + .collect(); + + let form_builder = self.mandatory_parameters_as_form_builder(); + + let method_impl = if self.method.types.optional_parameters().is_empty() { + self.generate_send_method( + &method_name, + parameters, + quote! { self.auth }, + quote! { form }, + quote! { + let form = reqwest::multipart::Form::new(); + #form_builder + }, + ) + } else { + quote! { + pub fn #method_name(&self, #(#parameters),*) -> Builder<'_> { + let form = reqwest::multipart::Form::new(); + #form_builder + Builder { group: self, form } + } + } + }; + + let group_struct_name = self.group.struct_name(); + let method_impl_with_docs = util::add_docs(&self.method.description, method_impl); + + quote! { + impl<'a> super::#group_struct_name<'a> { + #method_impl_with_docs + } + } + } + + fn generate_response_struct(&self) -> TokenStream { + let response = match self.method.types.response() { + Some(res) => res, + None => return quote! {}, + }; + + let struct_fields = response + .types + .iter() + .map(|field| field.generate_struct_field()); + + quote! { + #[derive(Debug, serde::Deserialize)] + pub struct Response { + #(#struct_fields,)* + } + } + } + + /// Returns a TokenStream containing a request builder if there are optional + /// parameters, otherwise an empty TokenStream is returned. + fn generate_request_builder(&self) -> TokenStream { + let optional_params = self.method.types.optional_parameters(); + if optional_params.is_empty() { + return quote! {}; + } + + let builder_methods = optional_params + .iter() + .map(|param| param.generate_optional_builder_method_with_docs()); + + let group_name = self.group.struct_name(); + let send_method = self.generate_send_method( + &util::to_ident("send"), + vec![], + quote! { self.group.auth }, + quote! { self.form }, + quote! {}, + ); + + quote! { + pub struct Builder<'a> { + group: &'a super::#group_name<'a>, + form: reqwest::multipart::Form, + } + + impl<'a> Builder<'a> { + #send_method + #(#builder_methods)* + } + } + } + + fn generate_send_method( + &self, + method_name: &Ident, + parameters: Vec, + auth_access: TokenStream, + form_access: TokenStream, + form_factory: TokenStream, + ) -> TokenStream { + let method_url = format!("/api/v2/{}/{}", self.group.url, self.method.url); + + let (response_type, response_parse) = match self.method.types.response() { + Some(resp) => { + if resp.is_list { + ( + quote! { std::vec::Vec }, + quote! { .json::>() }, + ) + } else { + (quote! { Response }, quote! { .json::() }) + } + } + None => (quote! { String }, quote! { .text() }), + }; + + quote! { + pub async fn #method_name(self, #(#parameters),*) -> super::super::Result<#response_type> { + #form_factory + let res = #auth_access + .authenticated_client(#method_url) + .multipart(#form_access) + .send() + .await? + #response_parse + .await?; + + Ok(res) + } + } + } + + fn mandatory_parameters_as_form_builder(&self) -> TokenStream { + let builder = self + .method + .types + .mandatory_params() + .into_iter() + .map(|param| param.generate_form_builder(quote! { form })); + + quote! { + #(let #builder)* + } + } +} diff --git a/qbittorrent-web-api-gen/src/generate/mod.rs b/qbittorrent-web-api-gen/src/generate/mod.rs index 9e68fa9..7292d8a 100644 --- a/qbittorrent-web-api-gen/src/generate/mod.rs +++ b/qbittorrent-web-api-gen/src/generate/mod.rs @@ -1,4 +1,7 @@ +mod api_group; +mod api_method; mod group; +mod group_method; mod skeleton; mod util; diff --git a/qbittorrent-web-api-gen/src/generate/skeleton.rs b/qbittorrent-web-api-gen/src/generate/skeleton.rs index fb74c23..e09f91b 100644 --- a/qbittorrent-web-api-gen/src/generate/skeleton.rs +++ b/qbittorrent-web-api-gen/src/generate/skeleton.rs @@ -10,13 +10,7 @@ pub fn generate_skeleton(ident: &syn::Ident) -> proc_macro2::TokenStream { let auth = auth_ident(); quote! { - use reqwest::RequestBuilder; - use serde::Deserialize; - use thiserror::Error; - - use super::#ident; - - impl #ident { + impl super::#ident { /// Creates an authenticated client. /// base_url is the url to the qbittorrent instance, i.e. http://localhost:8080 pub async fn login( @@ -61,7 +55,7 @@ pub fn generate_skeleton(ident: &syn::Ident) -> proc_macro2::TokenStream { } #[allow(clippy::enum_variant_names)] - #[derive(Debug, Error)] + #[derive(Debug, thiserror::Error)] pub enum Error { #[error("failed to parse auth cookie")] AuthCookieParseError, @@ -81,7 +75,7 @@ pub fn generate_skeleton(ident: &syn::Ident) -> proc_macro2::TokenStream { } impl #auth { - fn authenticated_client(&self, url: &str) -> RequestBuilder { + fn authenticated_client(&self, url: &str) -> reqwest::RequestBuilder { let url = format!("{}{}", self.base_url, url); let cookie = self.auth_cookie.clone(); diff --git a/qbittorrent-web-api-gen/src/md_parser.rs b/qbittorrent-web-api-gen/src/md_parser.rs deleted file mode 100644 index 184e994..0000000 --- a/qbittorrent-web-api-gen/src/md_parser.rs +++ /dev/null @@ -1,316 +0,0 @@ -use std::{cell::RefCell, rc::Rc}; - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum MdContent { - Text(String), - Asterix(String), - Table(Table), -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Table { - pub header: TableRow, - pub split: String, - pub rows: Vec, -} - -impl Table { - fn raw(&self) -> String { - let mut output = vec![self.header.raw.clone(), self.split.clone()]; - for row in self.rows.clone() { - output.push(row.raw); - } - - output.join("\n") - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct TableRow { - raw: String, - pub columns: Vec, -} - -impl MdContent { - pub fn inner_value_as_string(&self) -> String { - match self { - MdContent::Text(text) => text.into(), - MdContent::Asterix(text) => text.into(), - MdContent::Table(table) => table.raw(), - } - } -} - -#[derive(Debug, Clone)] -pub struct Header { - level: i32, - content: String, -} - -/// These are the only relevant tokens we need for the api generation. -#[derive(Debug)] -pub enum MdToken { - Header(Header), - Content(MdContent), -} - -impl MdToken { - fn parse_token(line: &str) -> MdToken { - if line.starts_with('#') { - let mut level = 0; - for char in line.chars() { - if char != '#' { - break; - } - - level += 1; - } - - MdToken::Header(Header { - level, - content: line.trim_matches('#').trim().to_string(), - }) - } else if line.starts_with('*') { - MdToken::Content(MdContent::Asterix( - line.trim_matches('*').trim().to_string(), - )) - } else { - MdToken::Content(MdContent::Text(line.to_string())) - } - } - - fn from(content: &str) -> Vec { - let mut output = Vec::new(); - - let mut iter = content.lines(); - while let Some(line) = iter.next() { - // assume this is a table - if line.contains('|') { - let to_columns = |column_line: &str| { - column_line - .replace('`', "") - .split('|') - .map(|s| s.trim().to_string()) - .collect() - }; - - let table_header = TableRow { - raw: line.into(), - columns: to_columns(line), - }; - let table_split = iter.next().unwrap(); - let mut table_rows = Vec::new(); - while let Some(row_line) = iter.next() { - if !row_line.contains('|') { - // we've reached the end of the table, let's go back one step - iter.next_back(); - break; - } - - let table_row = TableRow { - raw: row_line.into(), - columns: to_columns(row_line), - }; - - table_rows.push(table_row); - } - - output.push(MdToken::Content(MdContent::Table(Table { - header: table_header, - split: table_split.to_string(), - rows: table_rows, - }))); - } else { - output.push(MdToken::parse_token(line)); - } - } - - output - } -} - -#[derive(Debug)] -pub struct TokenTree { - pub title: Option, - pub content: Vec, - pub children: Vec, -} - -impl From> for TokenTree { - fn from(builder: Rc) -> Self { - let children = builder - .children - .clone() - .into_inner() - .into_iter() - .map(|child| child.into()) - .collect::>(); - - let content = builder.content.clone().into_inner(); - - TokenTree { - title: builder.title.clone(), - content, - children, - } - } -} - -#[derive(Debug, Default)] -pub struct TokenTreeFactory { - title: Option, - content: RefCell>, - children: RefCell>>, - level: i32, -} - -impl TokenTreeFactory { - fn new(title: &str, level: i32) -> Self { - Self { - title: if title.is_empty() { - None - } else { - Some(title.to_string()) - }, - level, - ..Default::default() - } - } - - fn add_content(&self, content: MdContent) { - self.content.borrow_mut().push(content); - } - - fn append(&self, child: &Rc) { - self.children.borrow_mut().push(child.clone()); - } - - pub fn create(content: &str) -> TokenTree { - let tokens = MdToken::from(content); - - let mut stack = Vec::new(); - let root = Rc::new(TokenTreeFactory::default()); - stack.push(root.clone()); - - for token in tokens { - match token { - MdToken::Header(Header { level, content }) => { - let new_header = Rc::new(TokenTreeFactory::new(&content, level)); - - // go back until we're at the same or lower level. - while let Some(current) = stack.pop() { - if current.level < level { - current.append(&new_header); - stack.push(current); - break; - } - } - - stack.push(new_header.clone()); - } - MdToken::Content(content) => { - let current = stack.pop().unwrap(); - current.add_content(content); - stack.push(current); - } - } - } - - root.into() - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn should_remove_surrounding_asterix() { - // given - let input = r#" -# A -**B** - "# - .trim_matches('\n') - .trim(); - - // when - let tree = TokenTreeFactory::create(input); - - // then - println!("{:#?}", tree); - let first = tree.children.first().unwrap(); - let content = first.content.first().unwrap(); - assert_eq!(*content, MdContent::Asterix("B".into())); - } - - #[test] - fn should_remove_surrounding_hash() { - // given - let input = r#" -# A # - "# - .trim_matches('\n') - .trim(); - - // when - let tree = TokenTreeFactory::create(input); - - // then - println!("{:#?}", tree); - assert_eq!(tree.children.first().unwrap().title, Some("A".into())); - } - - #[test] - fn single_level() { - // given - let input = r#" -# A -Foo - "# - .trim_matches('\n') - .trim(); - - // when - let tree = TokenTreeFactory::create(input); - - // then - println!("{:#?}", tree); - assert_eq!(tree.title, None); - let first_child = tree.children.first().unwrap(); - assert_eq!(first_child.title, Some("A".into())); - } - - #[test] - fn complex() { - // given - let input = r#" -# A -Foo -## B -# C -## D -Bar - "# - .trim_matches('\n') - .trim(); - - // when - let tree = TokenTreeFactory::create(input); - - // then - println!("{:#?}", tree); - assert_eq!(tree.title, None); - assert_eq!(tree.children.len(), 2); - - let first = tree.children.get(0).unwrap(); - assert_eq!(first.title, Some("A".into())); - assert_eq!(first.children.len(), 1); - assert_eq!(first.children.first().unwrap().title, Some("B".into())); - - let second = tree.children.get(1).unwrap(); - assert_eq!(second.title, Some("C".into())); - assert_eq!(second.children.len(), 1); - assert_eq!(second.children.first().unwrap().title, Some("D".into())); - } -} diff --git a/qbittorrent-web-api-gen/src/md_parser/md_token.rs b/qbittorrent-web-api-gen/src/md_parser/md_token.rs new file mode 100644 index 0000000..3b1d181 --- /dev/null +++ b/qbittorrent-web-api-gen/src/md_parser/md_token.rs @@ -0,0 +1,179 @@ +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum MdContent { + Text(String), + Asterisk(String), + Table(Table), +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Table { + pub header: TableRow, + pub split: String, + pub rows: Vec, +} + +impl Table { + fn raw(&self) -> String { + let mut output = vec![self.header.raw.clone(), self.split.clone()]; + for row in self.rows.clone() { + output.push(row.raw); + } + + output.join("\n") + } +} + +#[derive(Debug, Clone)] +pub struct Header { + pub level: i32, + pub content: String, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TableRow { + raw: String, + pub columns: Vec, +} + +impl MdContent { + pub fn inner_value_as_string(&self) -> String { + match self { + MdContent::Text(text) => text.into(), + MdContent::Asterisk(text) => text.into(), + MdContent::Table(table) => table.raw(), + } + } +} + +#[derive(Debug)] +pub enum MdToken { + Header(Header), + Content(MdContent), +} + +impl MdToken { + pub fn from(content: &str) -> Vec { + // to prevent infinite loops + let mut max_iterator_checker = MaxIteratorChecker::default(); + + let mut output = Vec::new(); + let mut iter = content.lines().peekable(); + + while let Some(line) = iter.next() { + max_iterator_checker.decrease(); + + if line.contains(" | ") || line.contains("-|") || line.contains("|-") { + let table = TableParser::new(&mut max_iterator_checker, &mut iter).parse(line); + output.push(MdToken::Content(table)); + } else if line.starts_with('#') { + output.push(parse_header(line)); + } else if line.starts_with('*') { + let asterisk = MdContent::Asterisk(line.trim_matches('*').trim().to_string()); + output.push(MdToken::Content(asterisk)); + } else { + output.push(MdToken::Content(MdContent::Text(line.to_string()))); + } + } + + output + } +} + +fn parse_header(line: &str) -> MdToken { + let mut level = 0; + for char in line.chars() { + if char != '#' { + break; + } + + level += 1; + } + MdToken::Header(Header { + level, + content: line.trim_matches('#').trim().to_string(), + }) +} + +struct TableParser<'a, 'b> { + max_iterator_checker: &'a mut MaxIteratorChecker, + iter: &'a mut std::iter::Peekable>, +} + +impl<'a, 'b> TableParser<'a, 'b> { + fn new( + max_iterator_checker: &'a mut MaxIteratorChecker, + iter: &'a mut std::iter::Peekable>, + ) -> Self { + Self { + max_iterator_checker, + iter, + } + } + + fn parse(&mut self, line: &str) -> MdContent { + let table_header = TableRow { + raw: line.into(), + columns: Self::to_columns(line), + }; + + let table_split = self.iter.next().unwrap(); + let table_rows = self.table_rows(); + + MdContent::Table(Table { + header: table_header, + split: table_split.to_string(), + rows: table_rows, + }) + } + + fn table_rows(&mut self) -> Vec { + let mut table_rows = Vec::new(); + + while let Some(peeked_row_line) = self.iter.peek() { + self.max_iterator_checker.decrease(); + + if !peeked_row_line.contains('|') { + // we've reached the end of the table, let's go back one step + break; + } + + let next_row_line = self.iter.next().unwrap(); + table_rows.push(TableRow { + raw: next_row_line.to_string(), + columns: Self::to_columns(next_row_line), + }); + } + + table_rows + } + + fn to_columns(column_line: &str) -> Vec { + column_line + .replace('`', "") + .split('|') + .map(|s| s.trim().to_string()) + .collect() + } +} + +#[derive(Debug)] +struct MaxIteratorChecker { + max_iterations: i32, +} + +impl MaxIteratorChecker { + fn decrease(&mut self) { + self.max_iterations -= 1; + if self.max_iterations <= 0 { + panic!("Max iterations reached, missing termination?"); + } + } +} + +impl Default for MaxIteratorChecker { + fn default() -> Self { + MaxIteratorChecker { + max_iterations: 10000, + } + } +} diff --git a/qbittorrent-web-api-gen/src/md_parser/mod.rs b/qbittorrent-web-api-gen/src/md_parser/mod.rs new file mode 100644 index 0000000..08d4769 --- /dev/null +++ b/qbittorrent-web-api-gen/src/md_parser/mod.rs @@ -0,0 +1,7 @@ +mod md_token; +mod token_tree; +mod token_tree_factory; + +pub use md_token::*; +pub use token_tree::TokenTree; +pub use token_tree_factory::TokenTreeFactory; diff --git a/qbittorrent-web-api-gen/src/md_parser/token_tree.rs b/qbittorrent-web-api-gen/src/md_parser/token_tree.rs new file mode 100644 index 0000000..473193b --- /dev/null +++ b/qbittorrent-web-api-gen/src/md_parser/token_tree.rs @@ -0,0 +1,30 @@ +use std::rc::Rc; + +use super::{md_token::MdContent, token_tree_factory::TokenTreeFactory}; + +#[derive(Debug)] +pub struct TokenTree { + pub title: Option, + pub content: Vec, + pub children: Vec, +} + +impl From> for TokenTree { + fn from(builder: Rc) -> Self { + let children = builder + .children + .clone() + .into_inner() + .into_iter() + .map(|child| child.into()) + .collect::>(); + + let content = builder.content.clone().into_inner(); + + TokenTree { + title: builder.title.clone(), + content, + children, + } + } +} diff --git a/qbittorrent-web-api-gen/src/md_parser/token_tree_factory.rs b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory.rs new file mode 100644 index 0000000..acff043 --- /dev/null +++ b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory.rs @@ -0,0 +1,154 @@ +use std::{cell::RefCell, rc::Rc}; + +use super::{ + md_token::{Header, MdContent, MdToken}, + token_tree::TokenTree, +}; + +#[derive(Debug, Default)] +pub struct TokenTreeFactory { + pub title: Option, + pub content: RefCell>, + pub children: RefCell>>, + pub level: i32, +} + +impl TokenTreeFactory { + fn new(title: &str, level: i32) -> Self { + Self { + title: if title.is_empty() { + None + } else { + Some(title.to_string()) + }, + level, + ..Default::default() + } + } + + fn add_content(&self, content: MdContent) { + self.content.borrow_mut().push(content); + } + + fn append(&self, child: &Rc) { + self.children.borrow_mut().push(child.clone()); + } + + pub fn create(content: &str) -> TokenTree { + let tokens = MdToken::from(content); + + let mut stack = Vec::new(); + let root = Rc::new(TokenTreeFactory::default()); + stack.push(root.clone()); + + for token in tokens { + match token { + MdToken::Header(Header { level, content }) => { + let new_header = Rc::new(TokenTreeFactory::new(&content, level)); + + // go back until we're at the same or lower level. + while let Some(current) = stack.pop() { + if current.level < level { + current.append(&new_header); + stack.push(current); + break; + } + } + + stack.push(new_header.clone()); + } + MdToken::Content(content) => { + let current = stack.pop().unwrap(); + current.add_content(content); + stack.push(current); + } + } + } + + root.into() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + macro_rules! TEST_DIR { + () => { + "token_tree_factory_tests" + }; + } + + macro_rules! run_test { + ($test_file:expr) => { + use pretty_assertions::assert_eq; + + // given + let input = include_str!(concat!(TEST_DIR!(), "/", $test_file, ".md")); + + // when + let tree = TokenTreeFactory::create(input); + + // then + let tree_as_str = format!("{tree:#?}"); + let should_be = include_str!(concat!(TEST_DIR!(), "/", $test_file, ".check")); + assert_eq!(tree_as_str, should_be); + }; + } + + // use this macro when creating/updating as test + #[allow(unused_macros)] + macro_rules! update_test { + ($test_file:expr) => { + use std::fs; + use std::path::Path; + + let input = include_str!(concat!(TEST_DIR!(), "/", $test_file, ".md")); + let tree = TokenTreeFactory::create(input); + let tree_as_str = format!("{tree:#?}"); + let file = concat!("src/md_parser/", TEST_DIR!(), "/", $test_file, ".check"); + + // prevent user from accidentally leaving the current macro in a test + if Path::new(file).exists() { + panic!("Test case already exists: {file}"); + } + + fs::write(file, tree_as_str).unwrap(); + }; + } + + #[test] + fn should_remove_surrounding_asterisk() { + run_test!("should_remove_surrounding_asterisk"); + } + + #[test] + fn should_remove_surrounding_hash() { + run_test!("should_remove_surrounding_hash"); + } + + #[test] + fn single_level() { + run_test!("single_level"); + } + + #[test] + fn complex() { + run_test!("complex"); + } + + #[test] + fn log() { + run_test!("log"); + } + + #[test] + fn multi_table() { + run_test!("multi_table"); + } + + #[test] + fn non_table_with_pipe() { + run_test!("non_table_with_pipe"); + } +} diff --git a/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/complex.check b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/complex.check new file mode 100644 index 0000000..16be004 --- /dev/null +++ b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/complex.check @@ -0,0 +1,44 @@ +TokenTree { + title: None, + content: [], + children: [ + TokenTree { + title: Some( + "A", + ), + content: [ + Text( + "Foo", + ), + ], + children: [ + TokenTree { + title: Some( + "B", + ), + content: [], + children: [], + }, + ], + }, + TokenTree { + title: Some( + "C", + ), + content: [], + children: [ + TokenTree { + title: Some( + "D", + ), + content: [ + Text( + "Bar", + ), + ], + children: [], + }, + ], + }, + ], +} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/complex.md b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/complex.md new file mode 100644 index 0000000..cfaa8fb --- /dev/null +++ b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/complex.md @@ -0,0 +1,6 @@ +# A +Foo +## B +# C +## D +Bar \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/log.check b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/log.check new file mode 100644 index 0000000..41a4da1 --- /dev/null +++ b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/log.check @@ -0,0 +1,521 @@ +TokenTree { + title: None, + content: [], + children: [ + TokenTree { + title: Some( + "Log", + ), + content: [ + Text( + "", + ), + Text( + "All Log API methods are under \"log\", e.g.: `/api/v2/log/methodName`.", + ), + Text( + "", + ), + ], + children: [ + TokenTree { + title: Some( + "Get log", + ), + content: [ + Text( + "", + ), + Text( + "Name: `main`", + ), + Text( + "", + ), + Asterisk( + "Parameters:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Parameter | Type | Description", + columns: [ + "Parameter", + "Type", + "Description", + ], + }, + split: "----------------|---------|------------", + rows: [ + TableRow { + raw: "`normal` | bool | Include normal messages (default: `true`)", + columns: [ + "normal", + "bool", + "Include normal messages (default: true)", + ], + }, + TableRow { + raw: "`info` | bool | Include info messages (default: `true`)", + columns: [ + "info", + "bool", + "Include info messages (default: true)", + ], + }, + TableRow { + raw: "`warning` | bool | Include warning messages (default: `true`)", + columns: [ + "warning", + "bool", + "Include warning messages (default: true)", + ], + }, + TableRow { + raw: "`critical` | bool | Include critical messages (default: `true`)", + columns: [ + "critical", + "bool", + "Include critical messages (default: true)", + ], + }, + TableRow { + raw: "`last_known_id` | integer | Exclude messages with \"message id\" <= `last_known_id` (default: `-1`)", + columns: [ + "last_known_id", + "integer", + "Exclude messages with \"message id\" <= last_known_id (default: -1)", + ], + }, + ], + }, + ), + Text( + "", + ), + Text( + "Example:", + ), + Text( + "", + ), + Text( + "```http", + ), + Text( + "/api/v2/log/main?normal=true&info=true&warning=true&critical=true&last_known_id=-1", + ), + Text( + "```", + ), + Text( + "", + ), + Asterisk( + "Returns:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "HTTP Status Code | Scenario", + columns: [ + "HTTP Status Code", + "Scenario", + ], + }, + split: "----------------------------------|---------------------", + rows: [ + TableRow { + raw: "200 | All scenarios- see JSON below", + columns: [ + "200", + "All scenarios- see JSON below", + ], + }, + ], + }, + ), + Text( + "", + ), + Text( + "The response is a JSON array in which each element is an entry of the log.", + ), + Text( + "", + ), + Text( + "Each element of the array has the following properties:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Property | Type | Description", + columns: [ + "Property", + "Type", + "Description", + ], + }, + split: "------------|---------|------------", + rows: [ + TableRow { + raw: "`id` | integer | ID of the message", + columns: [ + "id", + "integer", + "ID of the message", + ], + }, + TableRow { + raw: "`message` | string | Text of the message", + columns: [ + "message", + "string", + "Text of the message", + ], + }, + TableRow { + raw: "`timestamp` | integer | Milliseconds since epoch", + columns: [ + "timestamp", + "integer", + "Milliseconds since epoch", + ], + }, + TableRow { + raw: "`type` | integer | Type of the message: Log::NORMAL: `1`, Log::INFO: `2`, Log::WARNING: `4`, Log::CRITICAL: `8`", + columns: [ + "type", + "integer", + "Type of the message: Log::NORMAL: 1, Log::INFO: 2, Log::WARNING: 4, Log::CRITICAL: 8", + ], + }, + ], + }, + ), + Text( + "", + ), + Text( + "Example:", + ), + Text( + "", + ), + Text( + "```JSON", + ), + Text( + "[", + ), + Text( + " {", + ), + Text( + " \"id\":0,", + ), + Text( + " \"message\":\"qBittorrent v3.4.0 started\",", + ), + Text( + " \"timestamp\":1507969127860,", + ), + Text( + " \"type\":1", + ), + Text( + " },", + ), + Text( + " {", + ), + Text( + " \"id\":1,", + ), + Text( + " \"message\":\"qBittorrent is trying to listen on any interface port: 19036\",", + ), + Text( + " \"timestamp\":1507969127869,", + ), + Text( + " \"type\":2", + ), + Text( + " },", + ), + Text( + " {", + ), + Text( + " \"id\":2,", + ), + Text( + " \"message\":\"Peer ID: -qB3400-\",", + ), + Text( + " \"timestamp\":1507969127870,", + ), + Text( + " \"type\":1", + ), + Text( + " },", + ), + Text( + " {", + ), + Text( + " \"id\":3,", + ), + Text( + " \"message\":\"HTTP User-Agent is 'qBittorrent/3.4.0'\",", + ), + Text( + " \"timestamp\":1507969127870,", + ), + Text( + " \"type\":1", + ), + Text( + " },", + ), + Text( + " {", + ), + Text( + " \"id\":4,", + ), + Text( + " \"message\":\"DHT support [ON]\",", + ), + Text( + " \"timestamp\":1507969127871,", + ), + Text( + " \"type\":2", + ), + Text( + " },", + ), + Text( + " {", + ), + Text( + " \"id\":5,", + ), + Text( + " \"message\":\"Local Peer Discovery support [ON]\",", + ), + Text( + " \"timestamp\":1507969127871,", + ), + Text( + " \"type\":2", + ), + Text( + " },", + ), + Text( + " {", + ), + Text( + " \"id\":6,", + ), + Text( + " \"message\":\"PeX support [ON]\",", + ), + Text( + " \"timestamp\":1507969127871,", + ), + Text( + " \"type\":2", + ), + Text( + " },", + ), + Text( + " {", + ), + Text( + " \"id\":7,", + ), + Text( + " \"message\":\"Anonymous mode [OFF]\",", + ), + Text( + " \"timestamp\":1507969127871,", + ), + Text( + " \"type\":2", + ), + Text( + " },", + ), + Text( + " {", + ), + Text( + " \"id\":8,", + ), + Text( + " \"message\":\"Encryption support [ON]\",", + ), + Text( + " \"timestamp\":1507969127871,", + ), + Text( + " \"type\":2", + ), + Text( + " },", + ), + Text( + " {", + ), + Text( + " \"id\":9,", + ), + Text( + " \"message\":\"Embedded Tracker [OFF]\",", + ), + Text( + " \"timestamp\":1507969127871,", + ), + Text( + " \"type\":2", + ), + Text( + " },", + ), + Text( + " {", + ), + Text( + " \"id\":10,", + ), + Text( + " \"message\":\"UPnP / NAT-PMP support [ON]\",", + ), + Text( + " \"timestamp\":1507969127873,", + ), + Text( + " \"type\":2", + ), + Text( + " },", + ), + Text( + " {", + ), + Text( + " \"id\":11,", + ), + Text( + " \"message\":\"Web UI: Now listening on port 8080\",", + ), + Text( + " \"timestamp\":1507969127883,", + ), + Text( + " \"type\":1", + ), + Text( + " },", + ), + Text( + " {", + ), + Text( + " \"id\":12,", + ), + Text( + " \"message\":\"Options were saved successfully.\",", + ), + Text( + " \"timestamp\":1507969128055,", + ), + Text( + " \"type\":1", + ), + Text( + " },", + ), + Text( + " {", + ), + Text( + " \"id\":13,", + ), + Text( + " \"message\":\"qBittorrent is successfully listening on interface :: port: TCP/19036\",", + ), + Text( + " \"timestamp\":1507969128270,", + ), + Text( + " \"type\":2", + ), + Text( + " },", + ), + Text( + " {", + ), + Text( + " \"id\":14,", + ), + Text( + " \"message\":\"qBittorrent is successfully listening on interface 0.0.0.0 port: TCP/19036\",", + ), + Text( + " \"timestamp\":1507969128271,", + ), + Text( + " \"type\":2", + ), + Text( + " },", + ), + Text( + " {", + ), + Text( + " \"id\":15,", + ), + Text( + " \"message\":\"qBittorrent is successfully listening on interface 0.0.0.0 port: UDP/19036\",", + ), + Text( + " \"timestamp\":1507969128272,", + ), + Text( + " \"type\":2", + ), + Text( + " }", + ), + Text( + "]", + ), + Text( + "```", + ), + ], + children: [], + }, + ], + }, + ], +} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/log.md b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/log.md new file mode 100644 index 0000000..52df39e --- /dev/null +++ b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/log.md @@ -0,0 +1,143 @@ +# Log # + +All Log API methods are under "log", e.g.: `/api/v2/log/methodName`. + +## Get log ## + +Name: `main` + +**Parameters:** + +Parameter | Type | Description +----------------|---------|------------ +`normal` | bool | Include normal messages (default: `true`) +`info` | bool | Include info messages (default: `true`) +`warning` | bool | Include warning messages (default: `true`) +`critical` | bool | Include critical messages (default: `true`) +`last_known_id` | integer | Exclude messages with "message id" <= `last_known_id` (default: `-1`) + +Example: + +```http +/api/v2/log/main?normal=true&info=true&warning=true&critical=true&last_known_id=-1 +``` + +**Returns:** + +HTTP Status Code | Scenario +----------------------------------|--------------------- +200 | All scenarios- see JSON below + +The response is a JSON array in which each element is an entry of the log. + +Each element of the array has the following properties: + +Property | Type | Description +------------|---------|------------ +`id` | integer | ID of the message +`message` | string | Text of the message +`timestamp` | integer | Milliseconds since epoch +`type` | integer | Type of the message: Log::NORMAL: `1`, Log::INFO: `2`, Log::WARNING: `4`, Log::CRITICAL: `8` + +Example: + +```JSON +[ + { + "id":0, + "message":"qBittorrent v3.4.0 started", + "timestamp":1507969127860, + "type":1 + }, + { + "id":1, + "message":"qBittorrent is trying to listen on any interface port: 19036", + "timestamp":1507969127869, + "type":2 + }, + { + "id":2, + "message":"Peer ID: -qB3400-", + "timestamp":1507969127870, + "type":1 + }, + { + "id":3, + "message":"HTTP User-Agent is 'qBittorrent/3.4.0'", + "timestamp":1507969127870, + "type":1 + }, + { + "id":4, + "message":"DHT support [ON]", + "timestamp":1507969127871, + "type":2 + }, + { + "id":5, + "message":"Local Peer Discovery support [ON]", + "timestamp":1507969127871, + "type":2 + }, + { + "id":6, + "message":"PeX support [ON]", + "timestamp":1507969127871, + "type":2 + }, + { + "id":7, + "message":"Anonymous mode [OFF]", + "timestamp":1507969127871, + "type":2 + }, + { + "id":8, + "message":"Encryption support [ON]", + "timestamp":1507969127871, + "type":2 + }, + { + "id":9, + "message":"Embedded Tracker [OFF]", + "timestamp":1507969127871, + "type":2 + }, + { + "id":10, + "message":"UPnP / NAT-PMP support [ON]", + "timestamp":1507969127873, + "type":2 + }, + { + "id":11, + "message":"Web UI: Now listening on port 8080", + "timestamp":1507969127883, + "type":1 + }, + { + "id":12, + "message":"Options were saved successfully.", + "timestamp":1507969128055, + "type":1 + }, + { + "id":13, + "message":"qBittorrent is successfully listening on interface :: port: TCP/19036", + "timestamp":1507969128270, + "type":2 + }, + { + "id":14, + "message":"qBittorrent is successfully listening on interface 0.0.0.0 port: TCP/19036", + "timestamp":1507969128271, + "type":2 + }, + { + "id":15, + "message":"qBittorrent is successfully listening on interface 0.0.0.0 port: UDP/19036", + "timestamp":1507969128272, + "type":2 + } +] +``` diff --git a/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/multi_table.check b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/multi_table.check new file mode 100644 index 0000000..7efc49d --- /dev/null +++ b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/multi_table.check @@ -0,0 +1,86 @@ +TokenTree { + title: None, + content: [], + children: [ + TokenTree { + title: Some( + "Foo", + ), + content: [ + Text( + "", + ), + ], + children: [ + TokenTree { + title: Some( + "Bar", + ), + content: [ + Table( + Table { + header: TableRow { + raw: "Parameter | Type | Description", + columns: [ + "Parameter", + "Type", + "Description", + ], + }, + split: "----------------|---------|------------", + rows: [ + TableRow { + raw: "`normal` | bool | Include normal messages (default: `true`)", + columns: [ + "normal", + "bool", + "Include normal messages (default: true)", + ], + }, + ], + }, + ), + Text( + "", + ), + ], + children: [], + }, + TokenTree { + title: Some( + "Baz", + ), + content: [ + Table( + Table { + header: TableRow { + raw: "Parameter | Type | Description", + columns: [ + "Parameter", + "Type", + "Description", + ], + }, + split: "----------------|---------|------------", + rows: [ + TableRow { + raw: "`last_known_id` | integer | Exclude messages with \"message id\" <= `last_known_id` (default: `-1`)", + columns: [ + "last_known_id", + "integer", + "Exclude messages with \"message id\" <= last_known_id (default: -1)", + ], + }, + ], + }, + ), + Text( + "", + ), + ], + children: [], + }, + ], + }, + ], +} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/multi_table.md b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/multi_table.md new file mode 100644 index 0000000..c5a3510 --- /dev/null +++ b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/multi_table.md @@ -0,0 +1,12 @@ +# Foo + +## Bar +Parameter | Type | Description +----------------|---------|------------ +`normal` | bool | Include normal messages (default: `true`) + +## Baz +Parameter | Type | Description +----------------|---------|------------ +`last_known_id` | integer | Exclude messages with "message id" <= `last_known_id` (default: `-1`) + diff --git a/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/non_table_with_pipe.check b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/non_table_with_pipe.check new file mode 100644 index 0000000..502d25d --- /dev/null +++ b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/non_table_with_pipe.check @@ -0,0 +1,17 @@ +TokenTree { + title: None, + content: [], + children: [ + TokenTree { + title: Some( + "A", + ), + content: [ + Text( + "a|b", + ), + ], + children: [], + }, + ], +} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/non_table_with_pipe.md b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/non_table_with_pipe.md new file mode 100644 index 0000000..7087e40 --- /dev/null +++ b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/non_table_with_pipe.md @@ -0,0 +1,2 @@ +# A +a|b \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/should_remove_surrounding_asterisk.check b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/should_remove_surrounding_asterisk.check new file mode 100644 index 0000000..2255cf5 --- /dev/null +++ b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/should_remove_surrounding_asterisk.check @@ -0,0 +1,17 @@ +TokenTree { + title: None, + content: [], + children: [ + TokenTree { + title: Some( + "A", + ), + content: [ + Asterisk( + "B", + ), + ], + children: [], + }, + ], +} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/should_remove_surrounding_asterisk.md b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/should_remove_surrounding_asterisk.md new file mode 100644 index 0000000..318a664 --- /dev/null +++ b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/should_remove_surrounding_asterisk.md @@ -0,0 +1,2 @@ +# A +**B** \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/should_remove_surrounding_hash.check b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/should_remove_surrounding_hash.check new file mode 100644 index 0000000..bb00231 --- /dev/null +++ b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/should_remove_surrounding_hash.check @@ -0,0 +1,13 @@ +TokenTree { + title: None, + content: [], + children: [ + TokenTree { + title: Some( + "A", + ), + content: [], + children: [], + }, + ], +} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/should_remove_surrounding_hash.md b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/should_remove_surrounding_hash.md new file mode 100644 index 0000000..c3fd722 --- /dev/null +++ b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/should_remove_surrounding_hash.md @@ -0,0 +1 @@ +# A # \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/single_level.check b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/single_level.check new file mode 100644 index 0000000..34e9f2c --- /dev/null +++ b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/single_level.check @@ -0,0 +1,17 @@ +TokenTree { + title: None, + content: [], + children: [ + TokenTree { + title: Some( + "A", + ), + content: [ + Text( + "Foo", + ), + ], + children: [], + }, + ], +} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/single_level.md b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/single_level.md new file mode 100644 index 0000000..f5e1cf8 --- /dev/null +++ b/qbittorrent-web-api-gen/src/md_parser/token_tree_factory_tests/single_level.md @@ -0,0 +1,2 @@ +# A +Foo \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/parser/group/description.rs b/qbittorrent-web-api-gen/src/parser/group/description.rs index c47d531..395973b 100644 --- a/qbittorrent-web-api-gen/src/parser/group/description.rs +++ b/qbittorrent-web-api-gen/src/parser/group/description.rs @@ -1,17 +1,20 @@ use crate::md_parser; -pub fn parse_group_description(content: &[md_parser::MdContent]) -> Option { - let return_desc = content - .iter() - .map(|row| row.inner_value_as_string()) - .collect::>() - .join("\n") - .trim() - .to_string(); +impl md_parser::TokenTree { + pub fn parse_group_description(&self) -> Option { + let return_desc = self + .content + .iter() + .map(|row| row.inner_value_as_string()) + .collect::>() + .join("\n") + .trim() + .to_string(); - if return_desc.is_empty() { - None - } else { - Some(return_desc) + if return_desc.is_empty() { + None + } else { + Some(return_desc) + } } } diff --git a/qbittorrent-web-api-gen/src/parser/group/method/description.rs b/qbittorrent-web-api-gen/src/parser/group/method/description.rs index 73f3fce..fb892b8 100644 --- a/qbittorrent-web-api-gen/src/parser/group/method/description.rs +++ b/qbittorrent-web-api-gen/src/parser/group/method/description.rs @@ -1,35 +1,38 @@ -use crate::md_parser::MdContent; +use crate::md_parser::{self, MdContent}; -pub fn parse_method_description(content: &[MdContent]) -> Option { - let return_desc = content - .iter() - // skip until we get to the "Returns:" text - .skip_while(|row| match row { - MdContent::Asterix(text) => !text.starts_with("Returns:"), - _ => true, - }) - // there is one space before the table - .skip(2) - .skip_while(|row| match row { - MdContent::Text(text) => !text.is_empty(), - _ => true, - }) - // and there is one space after the table - .skip(1) - // then what is left should be the description - .flat_map(|row| match row { - MdContent::Text(text) => Some(text), - _ => None, - }) - .cloned() - .collect::>() - .join("\n") - .trim() - .to_string(); +impl md_parser::TokenTree { + pub fn parse_method_description(&self) -> Option { + let return_desc = self + .content + .iter() + // skip until we get to the "Returns:" text + .skip_while(|row| match row { + MdContent::Asterisk(text) => !text.starts_with("Returns:"), + _ => true, + }) + // there is one space before the table + .skip(2) + .skip_while(|row| match row { + MdContent::Text(text) => !text.is_empty(), + _ => true, + }) + // and there is one space after the table + .skip(1) + // then what is left should be the description + .flat_map(|row| match row { + MdContent::Text(text) => Some(text), + _ => None, + }) + .cloned() + .collect::>() + .join("\n") + .trim() + .to_string(); - if return_desc.is_empty() { - None - } else { - Some(return_desc) + if return_desc.is_empty() { + None + } else { + Some(return_desc) + } } } diff --git a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/array_field.check b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/array_field.check new file mode 100644 index 0000000..cb6792d --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/array_field.check @@ -0,0 +1,26 @@ +ApiMethod { + name: "foo", + description: None, + url: "foo", + types: CompositeTypes { + composite_types: [ + Response( + TypeWithoutName { + types: [ + Number( + TypeInfo { + name: "amount_left", + description: Some( + "Amount of data left to download (bytes)", + ), + is_optional: false, + is_list: true, + }, + ), + ], + is_list: false, + }, + ), + ], + }, +} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/array_field.md b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/array_field.md new file mode 100644 index 0000000..dc34aa3 --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/array_field.md @@ -0,0 +1,9 @@ +## Testing + +Name: `foo` + +The response is a JSON object with the following fields + +Property | Type | Description +---------------------|---------|------------ +`amount_left` | integer array | Amount of data left to download (bytes) diff --git a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/array_field.tree b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/array_field.tree new file mode 100644 index 0000000..687e642 --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/array_field.tree @@ -0,0 +1,52 @@ +TokenTree { + title: None, + content: [], + children: [ + TokenTree { + title: Some( + "Testing", + ), + content: [ + Text( + "", + ), + Text( + "Name: `foo`", + ), + Text( + "", + ), + Text( + "The response is a JSON object with the following fields", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Property | Type | Description", + columns: [ + "Property", + "Type", + "Description", + ], + }, + split: "---------------------|---------|------------", + rows: [ + TableRow { + raw: "`amount_left` | integer array | Amount of data left to download (bytes)", + columns: [ + "amount_left", + "integer array", + "Amount of data left to download (bytes)", + ], + }, + ], + }, + ), + ], + children: [], + }, + ], +} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/array_result.check b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/array_result.check new file mode 100644 index 0000000..674cd63 --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/array_result.check @@ -0,0 +1,26 @@ +ApiMethod { + name: "foo", + description: None, + url: "foo", + types: CompositeTypes { + composite_types: [ + Response( + TypeWithoutName { + types: [ + Number( + TypeInfo { + name: "added_on", + description: Some( + "Time (Unix Epoch) when the torrent was added to the client", + ), + is_optional: false, + is_list: false, + }, + ), + ], + is_list: true, + }, + ), + ], + }, +} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/array_result.md b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/array_result.md new file mode 100644 index 0000000..3e8a748 --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/array_result.md @@ -0,0 +1,9 @@ +## Testing + +Name: `foo` + +The response is a JSON array with the following fields + +Property | Type | Description +---------------------|---------|------------ +`added_on` | integer | Time (Unix Epoch) when the torrent was added to the client diff --git a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/array_result.tree b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/array_result.tree new file mode 100644 index 0000000..7589f7a --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/array_result.tree @@ -0,0 +1,52 @@ +TokenTree { + title: None, + content: [], + children: [ + TokenTree { + title: Some( + "Testing", + ), + content: [ + Text( + "", + ), + Text( + "Name: `foo`", + ), + Text( + "", + ), + Text( + "The response is a JSON array with the following fields", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Property | Type | Description", + columns: [ + "Property", + "Type", + "Description", + ], + }, + split: "---------------------|---------|------------", + rows: [ + TableRow { + raw: "`added_on` | integer | Time (Unix Epoch) when the torrent was added to the client", + columns: [ + "added_on", + "integer", + "Time (Unix Epoch) when the torrent was added to the client", + ], + }, + ], + }, + ), + ], + children: [], + }, + ], +} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/enum.check b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/enum.check new file mode 100644 index 0000000..165730d --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/enum.check @@ -0,0 +1,37 @@ +ApiMethod { + name: "foo", + description: None, + url: "foo", + types: CompositeTypes { + composite_types: [ + Enum( + Enum { + name: "ScanDirs", + values: [ + EnumValue { + description: Some( + "Download to the monitored folder", + ), + value: "DownloadToTheMonitoredFolder", + original_value: "0", + }, + EnumValue { + description: Some( + "Download to the default save path", + ), + value: "DownloadToTheDefaultSavePath", + original_value: "1", + }, + EnumValue { + description: Some( + "Download to this path", + ), + value: "\"/path/to/download/to\"", + original_value: "\"/path/to/download/to\"", + }, + ], + }, + ), + ], + }, +} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/enum.md b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/enum.md new file mode 100644 index 0000000..75f74c6 --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/enum.md @@ -0,0 +1,12 @@ +## Testing + +Name: `foo` + +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 + diff --git a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/enum.tree b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/enum.tree new file mode 100644 index 0000000..6a8f814 --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/enum.tree @@ -0,0 +1,67 @@ +TokenTree { + title: None, + content: [], + children: [ + TokenTree { + title: Some( + "Testing", + ), + content: [ + Text( + "", + ), + Text( + "Name: `foo`", + ), + Text( + "", + ), + Text( + "Possible values of `scan_dirs`:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Value | Description", + columns: [ + "Value", + "Description", + ], + }, + split: "----------------------------|------------", + rows: [ + TableRow { + raw: "`0` | Download to the monitored folder", + columns: [ + "0", + "Download to the monitored folder", + ], + }, + TableRow { + raw: "`1` | Download to the default save path", + columns: [ + "1", + "Download to the default save path", + ], + }, + TableRow { + raw: "`\"/path/to/download/to\"` | Download to this path", + columns: [ + "\"/path/to/download/to\"", + "Download to this path", + ], + }, + ], + }, + ), + Text( + "", + ), + ], + children: [], + }, + ], +} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.check b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.check new file mode 100644 index 0000000..7a7dec4 --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.check @@ -0,0 +1,110 @@ +ApiMethod { + name: "plugins", + description: Some( + "The response is a JSON array of objects containing the following fields\n\n\n```JSON\n[\n {\n \"enabled\": true,\n \"fullName\": \"Legit Torrents\",\n \"name\": \"legittorrents\",\n \"supportedCategories\": [{\n \"id\": \"all\",\n \"name\": \"All categories\"\n }, {\n \"id\": \"anime\",\n \"name\": \"Anime\"\n }, {\n \"id\": \"books\",\n \"name\": \"Books\"\n }, {\n \"id\": \"games\",\n \"name\": \"Games\"\n }, {\n \"id\": \"movies\",\n \"name\": \"Movies\"\n }, {\n \"id\": \"music\",\n \"name\": \"Music\"\n }, {\n \"id\": \"tv\",\n \"name\": \"TV shows\"\n }],\n \"url\": \"http://www.legittorrents.info\",\n \"version\": \"2.3\"\n }\n]\n```", + ), + url: "plugins", + types: CompositeTypes { + composite_types: [ + Object( + TypeWithName { + name: "Category", + types: [ + String( + TypeInfo { + name: "id", + description: Some( + "Id", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "name", + description: Some( + "Name", + ), + is_optional: false, + is_list: false, + }, + ), + ], + }, + ), + Response( + TypeWithoutName { + types: [ + Bool( + TypeInfo { + name: "enabled", + description: Some( + "Whether the plugin is enabled", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "fullName", + description: Some( + "Full name of the plugin", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "name", + description: Some( + "Short name of the plugin", + ), + is_optional: false, + is_list: false, + }, + ), + Object( + Object { + type_info: TypeInfo { + name: "supportedCategories", + description: Some( + "List of category objects", + ), + is_optional: false, + is_list: true, + }, + ref_type: String( + "Category", + ), + }, + ), + String( + TypeInfo { + name: "url", + description: Some( + "URL of the torrent site", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "version", + description: Some( + "Installed version of the plugin", + ), + is_optional: false, + is_list: false, + }, + ), + ], + is_list: true, + }, + ), + ], + }, +} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.md b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.md new file mode 100644 index 0000000..07dd1aa --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.md @@ -0,0 +1,65 @@ +## Get search plugins ## + +Name: `plugins` + +**Parameters:** + +None + +**Returns:** + +HTTP Status Code | Scenario +----------------------------------|--------------------- +200 | All scenarios- see JSON below + +The response is a JSON array of objects containing the following fields + +Field | Type | Description +----------------------------------|---------|------------ +`enabled` | bool | Whether the plugin is enabled +`fullName` | string | Full name of the plugin +`name` | string | Short name of the plugin +`supportedCategories` | array | List of category objects +`url` | string | URL of the torrent site +`version` | string | Installed version of the plugin + +```JSON +[ + { + "enabled": true, + "fullName": "Legit Torrents", + "name": "legittorrents", + "supportedCategories": [{ + "id": "all", + "name": "All categories" + }, { + "id": "anime", + "name": "Anime" + }, { + "id": "books", + "name": "Books" + }, { + "id": "games", + "name": "Games" + }, { + "id": "movies", + "name": "Movies" + }, { + "id": "music", + "name": "Music" + }, { + "id": "tv", + "name": "TV shows" + }], + "url": "http://www.legittorrents.info", + "version": "2.3" + } +] +``` + +**Category object:** + +Field | Type | Description +---------------------------|---------|------------ +`id` | string | Id +`name` | string | Name diff --git a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.tree b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.tree new file mode 100644 index 0000000..2e3f921 --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.tree @@ -0,0 +1,276 @@ +TokenTree { + title: None, + content: [], + children: [ + TokenTree { + title: Some( + "Get search plugins", + ), + content: [ + Text( + "", + ), + Text( + "Name: `plugins`", + ), + Text( + "", + ), + Asterisk( + "Parameters:", + ), + Text( + "", + ), + Text( + "None", + ), + Text( + "", + ), + Asterisk( + "Returns:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "HTTP Status Code | Scenario", + columns: [ + "HTTP Status Code", + "Scenario", + ], + }, + split: "----------------------------------|---------------------", + rows: [ + TableRow { + raw: "200 | All scenarios- see JSON below", + columns: [ + "200", + "All scenarios- see JSON below", + ], + }, + ], + }, + ), + Text( + "", + ), + Text( + "The response is a JSON array of objects containing the following fields", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Field | Type | Description", + columns: [ + "Field", + "Type", + "Description", + ], + }, + split: "----------------------------------|---------|------------", + rows: [ + TableRow { + raw: "`enabled` | bool | Whether the plugin is enabled", + columns: [ + "enabled", + "bool", + "Whether the plugin is enabled", + ], + }, + TableRow { + raw: "`fullName` | string | Full name of the plugin", + columns: [ + "fullName", + "string", + "Full name of the plugin", + ], + }, + TableRow { + raw: "`name` | string | Short name of the plugin", + columns: [ + "name", + "string", + "Short name of the plugin", + ], + }, + TableRow { + raw: "`supportedCategories` | array | List of category objects", + columns: [ + "supportedCategories", + "array", + "List of category objects", + ], + }, + TableRow { + raw: "`url` | string | URL of the torrent site", + columns: [ + "url", + "string", + "URL of the torrent site", + ], + }, + TableRow { + raw: "`version` | string | Installed version of the plugin", + columns: [ + "version", + "string", + "Installed version of the plugin", + ], + }, + ], + }, + ), + Text( + "", + ), + Text( + "```JSON", + ), + Text( + "[", + ), + Text( + " {", + ), + Text( + " \"enabled\": true,", + ), + Text( + " \"fullName\": \"Legit Torrents\",", + ), + Text( + " \"name\": \"legittorrents\",", + ), + Text( + " \"supportedCategories\": [{", + ), + Text( + " \"id\": \"all\",", + ), + Text( + " \"name\": \"All categories\"", + ), + Text( + " }, {", + ), + Text( + " \"id\": \"anime\",", + ), + Text( + " \"name\": \"Anime\"", + ), + Text( + " }, {", + ), + Text( + " \"id\": \"books\",", + ), + Text( + " \"name\": \"Books\"", + ), + Text( + " }, {", + ), + Text( + " \"id\": \"games\",", + ), + Text( + " \"name\": \"Games\"", + ), + Text( + " }, {", + ), + Text( + " \"id\": \"movies\",", + ), + Text( + " \"name\": \"Movies\"", + ), + Text( + " }, {", + ), + Text( + " \"id\": \"music\",", + ), + Text( + " \"name\": \"Music\"", + ), + Text( + " }, {", + ), + Text( + " \"id\": \"tv\",", + ), + Text( + " \"name\": \"TV shows\"", + ), + Text( + " }],", + ), + Text( + " \"url\": \"http://www.legittorrents.info\",", + ), + Text( + " \"version\": \"2.3\"", + ), + Text( + " }", + ), + Text( + "]", + ), + Text( + "```", + ), + Text( + "", + ), + Asterisk( + "Category object:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Field | Type | Description", + columns: [ + "Field", + "Type", + "Description", + ], + }, + split: "---------------------------|---------|------------", + rows: [ + TableRow { + raw: "`id` | string | Id", + columns: [ + "id", + "string", + "Id", + ], + }, + TableRow { + raw: "`name` | string | Name", + columns: [ + "name", + "string", + "Name", + ], + }, + ], + }, + ), + ], + children: [], + }, + ], +} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/search_result.check b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/search_result.check new file mode 100644 index 0000000..fc24550 --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/search_result.check @@ -0,0 +1,167 @@ +ApiMethod { + name: "results", + description: Some( + "The response is a JSON object with the following fields\n\n\n\n\nExample:\n\n```JSON\n{\n \"results\": [\n {\n \"descrLink\": \"http://www.legittorrents.info/index.php?page=torrent-details&id=8d5f512e1acb687029b8d7cc6c5a84dce51d7a41\",\n \"fileName\": \"Ubuntu-10.04-32bit-NeTV.ova\",\n \"fileSize\": -1,\n \"fileUrl\": \"http://www.legittorrents.info/download.php?id=8d5f512e1acb687029b8d7cc6c5a84dce51d7a41&f=Ubuntu-10.04-32bit-NeTV.ova.torrent\",\n \"nbLeechers\": 1,\n \"nbSeeders\": 0,\n \"siteUrl\": \"http://www.legittorrents.info\"\n },\n {\n \"descrLink\": \"http://www.legittorrents.info/index.php?page=torrent-details&id=d5179f53e105dc2c2401bcfaa0c2c4936a6aa475\",\n \"fileName\": \"mangOH-Legato-17_06-Ubuntu-16_04.ova\",\n \"fileSize\": -1,\n \"fileUrl\": \"http://www.legittorrents.info/download.php?id=d5179f53e105dc2c2401bcfaa0c2c4936a6aa475&f=mangOH-Legato-17_06-Ubuntu-16_04.ova.torrent\",\n \"nbLeechers\": 0,\n \"nbSeeders\": 59,\n \"siteUrl\": \"http://www.legittorrents.info\"\n }\n ],\n \"status\": \"Running\",\n \"total\": 2\n}\n```", + ), + url: "results", + types: CompositeTypes { + composite_types: [ + Parameters( + TypeWithoutName { + types: [ + Number( + TypeInfo { + name: "id", + description: Some( + "ID of the search job", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "limit", + description: Some( + "max number of results to return. 0 or negative means no limit", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "offset", + description: Some( + "result to start at. A negative number means count backwards (e.g. -2 returns the 2 most recent results)", + ), + is_optional: true, + is_list: false, + }, + ), + ], + is_list: false, + }, + ), + Object( + TypeWithName { + name: "Result", + types: [ + String( + TypeInfo { + name: "descrLink", + description: Some( + "URL of the torrent's description page", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "fileName", + description: Some( + "Name of the file", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "fileSize", + description: Some( + "Size of the file in Bytes", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "fileUrl", + description: Some( + "Torrent download link (usually either .torrent file or magnet link)", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "nbLeechers", + description: Some( + "Number of leechers", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "nbSeeders", + description: Some( + "Number of seeders", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "siteUrl", + description: Some( + "URL of the torrent site", + ), + is_optional: false, + is_list: false, + }, + ), + ], + }, + ), + Response( + TypeWithoutName { + types: [ + Object( + Object { + type_info: TypeInfo { + name: "results", + description: Some( + "Array of result objects- see table below", + ), + is_optional: false, + is_list: true, + }, + ref_type: String( + "Result", + ), + }, + ), + String( + TypeInfo { + name: "status", + description: Some( + "Current status of the search job (either Running or Stopped)", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "total", + description: Some( + "Total number of results. If the status is Running this number may continue to increase", + ), + is_optional: false, + is_list: false, + }, + ), + ], + is_list: false, + }, + ), + ], + }, +} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/search_result.md b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/search_result.md new file mode 100644 index 0000000..6ef3347 --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/search_result.md @@ -0,0 +1,68 @@ +## Get search results ## + +Name: `results` + +**Parameters:** + +Parameter | Type | Description +----------------------------------|---------|------------ +`id` | number | ID of the search job +`limit` _optional_ | number | max number of results to return. 0 or negative means no limit +`offset` _optional_ | number | result to start at. A negative number means count backwards (e.g. `-2` returns the 2 most recent results) + +**Returns:** + +HTTP Status Code | Scenario +----------------------------------|--------------------- +404 | Search job was not found +409 | Offset is too large, or too small (e.g. absolute value of negative number is greater than # results) +200 | All other scenarios- see JSON below + +The response is a JSON object with the following fields + +Field | Type | Description +----------------------------------|---------|------------ +`results` | array | Array of `result` objects- see table below +`status` | string | Current status of the search job (either `Running` or `Stopped`) +`total` | number | Total number of results. If the status is `Running` this number may continue to increase + +**Result object:** + +Field | Type | Description +----------------------------------|---------|------------ +`descrLink` | string | URL of the torrent's description page +`fileName` | string | Name of the file +`fileSize` | number | Size of the file in Bytes +`fileUrl` | string | Torrent download link (usually either .torrent file or magnet link) +`nbLeechers` | number | Number of leechers +`nbSeeders` | number | Number of seeders +`siteUrl` | string | URL of the torrent site + +Example: + +```JSON +{ + "results": [ + { + "descrLink": "http://www.legittorrents.info/index.php?page=torrent-details&id=8d5f512e1acb687029b8d7cc6c5a84dce51d7a41", + "fileName": "Ubuntu-10.04-32bit-NeTV.ova", + "fileSize": -1, + "fileUrl": "http://www.legittorrents.info/download.php?id=8d5f512e1acb687029b8d7cc6c5a84dce51d7a41&f=Ubuntu-10.04-32bit-NeTV.ova.torrent", + "nbLeechers": 1, + "nbSeeders": 0, + "siteUrl": "http://www.legittorrents.info" + }, + { + "descrLink": "http://www.legittorrents.info/index.php?page=torrent-details&id=d5179f53e105dc2c2401bcfaa0c2c4936a6aa475", + "fileName": "mangOH-Legato-17_06-Ubuntu-16_04.ova", + "fileSize": -1, + "fileUrl": "http://www.legittorrents.info/download.php?id=d5179f53e105dc2c2401bcfaa0c2c4936a6aa475&f=mangOH-Legato-17_06-Ubuntu-16_04.ova.torrent", + "nbLeechers": 0, + "nbSeeders": 59, + "siteUrl": "http://www.legittorrents.info" + } + ], + "status": "Running", + "total": 2 +} +``` \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/search_result.tree b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/search_result.tree new file mode 100644 index 0000000..6e9c73c --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/search_result.tree @@ -0,0 +1,327 @@ +TokenTree { + title: None, + content: [], + children: [ + TokenTree { + title: Some( + "Get search results", + ), + content: [ + Text( + "", + ), + Text( + "Name: `results`", + ), + Text( + "", + ), + Asterisk( + "Parameters:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Parameter | Type | Description", + columns: [ + "Parameter", + "Type", + "Description", + ], + }, + split: "----------------------------------|---------|------------", + rows: [ + TableRow { + raw: "`id` | number | ID of the search job", + columns: [ + "id", + "number", + "ID of the search job", + ], + }, + TableRow { + raw: "`limit` _optional_ | number | max number of results to return. 0 or negative means no limit", + columns: [ + "limit _optional_", + "number", + "max number of results to return. 0 or negative means no limit", + ], + }, + TableRow { + raw: "`offset` _optional_ | number | result to start at. A negative number means count backwards (e.g. `-2` returns the 2 most recent results)", + columns: [ + "offset _optional_", + "number", + "result to start at. A negative number means count backwards (e.g. -2 returns the 2 most recent results)", + ], + }, + ], + }, + ), + Text( + "", + ), + Asterisk( + "Returns:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "HTTP Status Code | Scenario", + columns: [ + "HTTP Status Code", + "Scenario", + ], + }, + split: "----------------------------------|---------------------", + rows: [ + TableRow { + raw: "404 | Search job was not found", + columns: [ + "404", + "Search job was not found", + ], + }, + TableRow { + raw: "409 | Offset is too large, or too small (e.g. absolute value of negative number is greater than # results)", + columns: [ + "409", + "Offset is too large, or too small (e.g. absolute value of negative number is greater than # results)", + ], + }, + TableRow { + raw: "200 | All other scenarios- see JSON below", + columns: [ + "200", + "All other scenarios- see JSON below", + ], + }, + ], + }, + ), + Text( + "", + ), + Text( + "The response is a JSON object with the following fields", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Field | Type | Description", + columns: [ + "Field", + "Type", + "Description", + ], + }, + split: "----------------------------------|---------|------------", + rows: [ + TableRow { + raw: "`results` | array | Array of `result` objects- see table below", + columns: [ + "results", + "array", + "Array of result objects- see table below", + ], + }, + TableRow { + raw: "`status` | string | Current status of the search job (either `Running` or `Stopped`)", + columns: [ + "status", + "string", + "Current status of the search job (either Running or Stopped)", + ], + }, + TableRow { + raw: "`total` | number | Total number of results. If the status is `Running` this number may continue to increase", + columns: [ + "total", + "number", + "Total number of results. If the status is Running this number may continue to increase", + ], + }, + ], + }, + ), + Text( + "", + ), + Asterisk( + "Result object:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Field | Type | Description", + columns: [ + "Field", + "Type", + "Description", + ], + }, + split: "----------------------------------|---------|------------", + rows: [ + TableRow { + raw: "`descrLink` | string | URL of the torrent's description page", + columns: [ + "descrLink", + "string", + "URL of the torrent's description page", + ], + }, + TableRow { + raw: "`fileName` | string | Name of the file", + columns: [ + "fileName", + "string", + "Name of the file", + ], + }, + TableRow { + raw: "`fileSize` | number | Size of the file in Bytes", + columns: [ + "fileSize", + "number", + "Size of the file in Bytes", + ], + }, + TableRow { + raw: "`fileUrl` | string | Torrent download link (usually either .torrent file or magnet link)", + columns: [ + "fileUrl", + "string", + "Torrent download link (usually either .torrent file or magnet link)", + ], + }, + TableRow { + raw: "`nbLeechers` | number | Number of leechers", + columns: [ + "nbLeechers", + "number", + "Number of leechers", + ], + }, + TableRow { + raw: "`nbSeeders` | number | Number of seeders", + columns: [ + "nbSeeders", + "number", + "Number of seeders", + ], + }, + TableRow { + raw: "`siteUrl` | string | URL of the torrent site", + columns: [ + "siteUrl", + "string", + "URL of the torrent site", + ], + }, + ], + }, + ), + Text( + "", + ), + Text( + "Example:", + ), + Text( + "", + ), + Text( + "```JSON", + ), + Text( + "{", + ), + Text( + " \"results\": [", + ), + Text( + " {", + ), + Text( + " \"descrLink\": \"http://www.legittorrents.info/index.php?page=torrent-details&id=8d5f512e1acb687029b8d7cc6c5a84dce51d7a41\",", + ), + Text( + " \"fileName\": \"Ubuntu-10.04-32bit-NeTV.ova\",", + ), + Text( + " \"fileSize\": -1,", + ), + Text( + " \"fileUrl\": \"http://www.legittorrents.info/download.php?id=8d5f512e1acb687029b8d7cc6c5a84dce51d7a41&f=Ubuntu-10.04-32bit-NeTV.ova.torrent\",", + ), + Text( + " \"nbLeechers\": 1,", + ), + Text( + " \"nbSeeders\": 0,", + ), + Text( + " \"siteUrl\": \"http://www.legittorrents.info\"", + ), + Text( + " },", + ), + Text( + " {", + ), + Text( + " \"descrLink\": \"http://www.legittorrents.info/index.php?page=torrent-details&id=d5179f53e105dc2c2401bcfaa0c2c4936a6aa475\",", + ), + Text( + " \"fileName\": \"mangOH-Legato-17_06-Ubuntu-16_04.ova\",", + ), + Text( + " \"fileSize\": -1,", + ), + Text( + " \"fileUrl\": \"http://www.legittorrents.info/download.php?id=d5179f53e105dc2c2401bcfaa0c2c4936a6aa475&f=mangOH-Legato-17_06-Ubuntu-16_04.ova.torrent\",", + ), + Text( + " \"nbLeechers\": 0,", + ), + Text( + " \"nbSeeders\": 59,", + ), + Text( + " \"siteUrl\": \"http://www.legittorrents.info\"", + ), + Text( + " }", + ), + Text( + " ],", + ), + Text( + " \"status\": \"Running\",", + ), + Text( + " \"total\": 2", + ), + Text( + "}", + ), + Text( + "```", + ), + ], + children: [], + }, + ], +} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/parser/group/method/mod.rs b/qbittorrent-web-api-gen/src/parser/group/method/mod.rs index 3d374f8..7d53d47 100644 --- a/qbittorrent-web-api-gen/src/parser/group/method/mod.rs +++ b/qbittorrent-web-api-gen/src/parser/group/method/mod.rs @@ -1,47 +1,430 @@ mod description; -mod parameters; -mod return_type; +// mod return_type; mod url; -use crate::{md_parser, parser::util, types}; - -pub use return_type::ReturnType; - -use self::{ - description::parse_method_description, parameters::parse_parameters, - return_type::parse_return_type, url::get_method_url, -}; +use crate::{md_parser, types}; +use case::CaseExt; +use regex::Regex; +use std::collections::BTreeMap; #[derive(Debug)] pub struct ApiMethod { pub name: String, pub description: Option, - pub parameters: Option>, - pub return_type: Option, pub url: String, + pub types: CompositeTypes, } -pub fn parse_api_method(child: &md_parser::TokenTree) -> Option { - util::find_content_starts_with(&child.content, "Name: ") - .map(|name| { - name.trim_start_matches("Name: ") - .trim_matches('`') - .to_string() +#[derive(Debug)] +pub struct CompositeTypes { + pub composite_types: Vec, +} + +impl CompositeTypes { + pub fn new(tables: &Tables) -> Self { + Self { + composite_types: tables.get_all_tables_as_types(), + } + } + + pub fn parameters(&self) -> Vec<&types::Type> { + self.composite_types + .iter() + .find_map(|type_| match type_ { + CompositeType::Parameters(p) => Some(p.types.iter().collect()), + _ => None, + }) + .unwrap_or_default() + } + + pub fn optional_parameters(&self) -> Vec<&types::Type> { + self.parameters() + .iter() + .filter(|param| param.is_optional()) + .copied() + .collect() + } + + pub fn mandatory_params(&self) -> Vec<&types::Type> { + self.parameters() + .iter() + .filter(|param| !param.is_optional()) + .copied() + .collect() + } + + pub fn response(&self) -> Option<&TypeWithoutName> { + self.composite_types.iter().find_map(|type_| match type_ { + CompositeType::Response(p) => Some(p), + _ => None, }) - .map(|name| to_api_method(child, &name)) -} + } -fn to_api_method(child: &md_parser::TokenTree, name: &str) -> ApiMethod { - let method_description = parse_method_description(&child.content); - let return_type = parse_return_type(&child.content); - let parameters = parse_parameters(&child.content); - let method_url = get_method_url(&child.content); + pub fn objects(&self) -> Vec<&TypeWithName> { + self.composite_types + .iter() + .filter_map(|type_| match type_ { + CompositeType::Object(p) => Some(p), + _ => None, + }) + .collect() + } - ApiMethod { - name: name.to_string(), - description: method_description, - parameters, - return_type, - url: method_url, + pub fn enums(&self) -> Vec<&Enum> { + self.composite_types + .iter() + .filter_map(|type_| match type_ { + CompositeType::Enum(p) => Some(p), + _ => None, + }) + .collect() + } +} + +#[derive(Debug)] +pub struct ApiParameters { + pub mandatory: Vec, + pub optional: Vec, +} + +#[derive(Debug)] +pub enum CompositeType { + Enum(Enum), + Object(TypeWithName), + Response(TypeWithoutName), + Parameters(TypeWithoutName), +} + +#[derive(Debug)] +pub struct TypeWithName { + pub name: String, + pub types: Vec, +} + +#[derive(Debug)] +pub struct TypeWithoutName { + pub types: Vec, + pub is_list: bool, +} + +impl TypeWithoutName { + pub fn new(types: Vec, is_list: bool) -> Self { + Self { types, is_list } + } +} + +impl TypeWithName { + pub fn new(name: &str, types: Vec) -> Self { + Self { + name: name.to_string(), + types, + } + } +} + +#[derive(Debug)] +pub struct Enum { + pub name: String, + pub values: Vec, +} + +#[derive(Debug)] +pub struct EnumValue { + pub description: Option, + pub value: String, + pub original_value: String, +} + +impl Enum { + fn new(name: &str, table: &md_parser::Table) -> Self { + let values = table.rows.iter().map(EnumValue::from).collect(); + + Enum { + name: name.to_string(), + values, + } + } +} + +impl From<&md_parser::TableRow> for EnumValue { + fn from(row: &md_parser::TableRow) -> Self { + let description = row.columns.get(1).cloned(); + let original_value = row.columns[0].clone(); + let value = if original_value.parse::().is_ok() { + let name = description + .clone() + .unwrap() + .replace(' ', "_") + .replace('-', "_") + .replace(',', "_"); + + let re = Regex::new(r#"\(.*\)"#).unwrap(); + re.replace_all(&name, "").to_camel() + } else { + original_value.to_camel() + }; + + EnumValue { + description, + value, + original_value, + } + } +} + +impl ApiMethod { + pub fn try_new(child: &md_parser::TokenTree) -> Option { + const NAME: &str = "Name: "; + + child + .find_content_starts_with(NAME) + .map(|name| name.trim_start_matches(NAME).trim_matches('`').to_string()) + .map(|name| ApiMethod::new(child, &name)) + } + + fn new(child: &md_parser::TokenTree, name: &str) -> Self { + let tables = Tables::from(child); + let method_description = child.parse_method_description(); + let method_url = child.get_method_url(); + + ApiMethod { + name: name.to_string(), + description: method_description, + url: method_url, + types: CompositeTypes::new(&tables), + } + } +} + +impl md_parser::TokenTree { + fn find_content_starts_with(&self, starts_with: &str) -> Option { + self.content.iter().find_map(|row| match row { + md_parser::MdContent::Text(content) if content.starts_with(starts_with) => { + Some(content.into()) + } + _ => None, + }) + } +} + +impl<'a> From<&'a md_parser::TokenTree> for Tables<'a> { + fn from(token_tree: &'a md_parser::TokenTree) -> Self { + let mut tables = BTreeMap::new(); + let mut prev_prev: Option<&md_parser::MdContent> = None; + let mut prev: Option<&md_parser::MdContent> = None; + + for content in &token_tree.content { + if let md_parser::MdContent::Table(table) = content { + let title = match prev_prev { + Some(md_parser::MdContent::Text(text)) => text.clone(), + Some(md_parser::MdContent::Asterisk(text)) => text.clone(), + _ => panic!("Expected table title, found: {:?}", prev_prev), + }; + + tables.insert(title.replace(':', ""), table); + } + + prev_prev = prev; + prev = Some(content); + } + + Tables { tables } + } +} + +#[derive(Debug)] +pub struct Tables<'a> { + tables: BTreeMap, +} + +impl md_parser::Table { + fn to_enum(&self, input_name: &str) -> Option { + let re = Regex::new(r"^Possible values of `(\w+)`$").unwrap(); + + if !re.is_match(input_name) { + return None; + } + + Some(CompositeType::Enum(Enum::new( + &Self::regex_to_name(&re, input_name), + self, + ))) + } + + fn to_object(&self, input_name: &str) -> Option { + let re = Regex::new(r"^(\w+) object$").unwrap(); + + if !re.is_match(input_name) { + return None; + } + + Some(CompositeType::Object(TypeWithName::new( + &Self::regex_to_name(&re, input_name), + self.to_types(), + ))) + } + + fn to_response(&self, input_name: &str) -> Option { + if !input_name.starts_with("The response is a") { + return None; + } + + Some(CompositeType::Response(TypeWithoutName::new( + self.to_types(), + input_name.to_lowercase().contains("array"), + ))) + } + + fn to_parameters(&self, input_name: &str) -> Option { + if !input_name.starts_with("Parameters") { + return None; + } + + Some(CompositeType::Parameters(TypeWithoutName::new( + self.to_types(), + input_name.to_lowercase().contains("array"), + ))) + } + + fn to_composite_type(&self, input_name: &str) -> Option { + self.to_enum(input_name) + .or_else(|| self.to_response(input_name)) + .or_else(|| self.to_object(input_name)) + .or_else(|| self.to_parameters(input_name)) + } + + fn regex_to_name(re: &Regex, input_name: &str) -> String { + re.captures(input_name) + .unwrap() + .get(1) + .unwrap() + .as_str() + .to_string() + .to_camel() + } +} + +impl<'a> Tables<'a> { + fn get_all_tables_as_types(&self) -> Vec { + self.tables + .iter() + .flat_map(|(k, v)| v.to_composite_type(k)) + .collect() + } +} + +impl md_parser::Table { + fn to_types(&self) -> Vec { + self.rows + .iter() + .flat_map(|table_row| table_row.to_type()) + .collect() + } +} + +impl md_parser::TableRow { + fn to_type(&self) -> Option { + let columns = &self.columns; + let description = columns.get(2).cloned(); + + match &columns.get(2) { + // If the description contains a default value it means that the parameter is optional. + Some(desc) if desc.contains("default: ") => { + // type defines a variable as default if it contains: _optional_ + let name_with_optional = format!("{} {}", columns[0], types::OPTIONAL); + types::Type::from(&columns[1], &name_with_optional, description) + } + _ => types::Type::from(&columns[1], &columns[0], description), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use md_parser::TokenTreeFactory; + + macro_rules! TEST_DIR { + () => { + "method_tests" + }; + } + + #[allow(unused_macros)] + macro_rules! run_test { + ($test_file:expr) => { + use pretty_assertions::assert_eq; + + // given + let input = include_str!(concat!(TEST_DIR!(), "/", $test_file, ".md")); + + // when + let tree = TokenTreeFactory::create(input); + let api_method = ApiMethod::try_new(&tree.children[0]).unwrap(); + + // then + let api_method_as_str = format!("{api_method:#?}"); + let should_be = include_str!(concat!(TEST_DIR!(), "/", $test_file, ".check")); + assert_eq!(api_method_as_str, should_be); + }; + } + + // use this macro when creating/updating as test + #[allow(unused_macros)] + macro_rules! update_test { + ($test_file:expr) => { + use std::fs; + use std::path::Path; + + let input = include_str!(concat!(TEST_DIR!(), "/", $test_file, ".md")); + let tree = TokenTreeFactory::create(input); + let api_method = ApiMethod::try_new(&tree.children[0]).unwrap(); + + let tree_as_str = format!("{tree:#?}"); + let api_method_as_str = format!("{api_method:#?}"); + + let tree_file = concat!( + "src/parser/group/method/", + TEST_DIR!(), + "/", + $test_file, + ".tree" + ); + let file = concat!( + "src/parser/group/method/", + TEST_DIR!(), + "/", + $test_file, + ".check" + ); + + fs::write(file, api_method_as_str).unwrap(); + fs::write(tree_file, tree_as_str).unwrap(); + }; + } + + #[test] + fn search_result() { + run_test!("search_result"); + } + + #[test] + fn enum_test() { + run_test!("enum"); + } + + #[test] + fn array_result() { + run_test!("array_result"); + } + + #[test] + fn array_field() { + run_test!("array_field"); + } + + #[test] + fn ref_type() { + run_test!("ref_type"); } } diff --git a/qbittorrent-web-api-gen/src/parser/group/method/parameters.rs b/qbittorrent-web-api-gen/src/parser/group/method/parameters.rs deleted file mode 100644 index ebbfb07..0000000 --- a/qbittorrent-web-api-gen/src/parser/group/method/parameters.rs +++ /dev/null @@ -1,51 +0,0 @@ -use std::collections::HashMap; - -use crate::{md_parser, parser::types}; - -pub fn parse_parameters(content: &[md_parser::MdContent]) -> Option> { - let mut it = content - .iter() - .skip_while(|row| match row { - md_parser::MdContent::Asterix(content) | md_parser::MdContent::Text(content) => { - !content.starts_with("Parameters:") - } - _ => true, - }) - // Parameters: <-- skip - // <-- skip - // table with parameters <-- take - .skip(2); - - let parameter_table = match it.next() { - Some(md_parser::MdContent::Table(table)) => table, - _ => return None, - }; - - // empty for now - let type_map = HashMap::default(); - - let table = parameter_table - .rows - .iter() - .flat_map(|row| parse_parameter(row, &type_map)) - .collect(); - - Some(table) -} - -fn parse_parameter( - row: &md_parser::TableRow, - type_map: &HashMap, -) -> Option { - let description = row.columns.get(2).cloned(); - - match &row.columns.get(2) { - // If the description contains a default value it means that the parameter is optional. - Some(desc) if desc.contains("default: ") => { - // type defines a variable as default if it contains: _optional_ - let name_with_optional = format!("{} {}", row.columns[0], types::OPTIONAL); - types::Type::from(&row.columns[1], &name_with_optional, description, type_map) - } - _ => types::Type::from(&row.columns[1], &row.columns[0], description, type_map), - } -} diff --git a/qbittorrent-web-api-gen/src/parser/group/method/return_type.rs b/qbittorrent-web-api-gen/src/parser/group/method/return_type.rs index 6ff8342..f7a4c45 100644 --- a/qbittorrent-web-api-gen/src/parser/group/method/return_type.rs +++ b/qbittorrent-web-api-gen/src/parser/group/method/return_type.rs @@ -1,100 +1,107 @@ use std::collections::HashMap; use crate::{ - md_parser::{self, MdContent}, + md_parser, parser::{types, ReturnTypeParameter}, }; +use super::Tables; + #[derive(Debug)] pub struct ReturnType { pub is_list: bool, pub parameters: Vec, } -pub fn parse_return_type(content: &[MdContent]) -> Option { - let table = content - .iter() - // The response is a ... <-- Trying to find this line - // <-- The next line is empty - // Table with the return type <-- And then extract the following type table - .skip_while(|row| match row { - MdContent::Text(text) => !text.starts_with("The response is a"), - _ => true, - }) - .find_map(|row| match row { - MdContent::Table(table) => Some(table), - _ => None, - })?; - - let types = parse_object_types(content); - - let parameters = table - .rows - .iter() - .map(|parameter| ReturnTypeParameter { - name: parameter.columns[0].clone(), - description: parameter.columns[2].clone(), - return_type: types::Type::from( - ¶meter.columns[1], - ¶meter.columns[0], - Some(parameter.columns[2].clone()), - &types, - ) - .unwrap_or_else(|| panic!("Failed to parse type {}", ¶meter.columns[1])), - }) - .collect(); - - let is_list = content - .iter() - .find_map(|row| match row { - MdContent::Text(text) if text.starts_with("The response is a") => Some(text), - _ => None, - }) - .map(|found| found.contains("array")) - .unwrap_or_else(|| false); - - Some(ReturnType { - parameters, - is_list, - }) +impl md_parser::Table { + fn to_return_type_parameters( + &self, + types: &HashMap, + ) -> Vec { + self.rows + .iter() + .map(|parameter| parameter.to_return_type_parameter(types)) + .collect() + } } -pub fn parse_object_types( - content: &[md_parser::MdContent], -) -> HashMap { - let mut output = HashMap::new(); - let mut content_it = content.iter(); +impl md_parser::TokenTree { + pub fn parse_return_type(&self) -> Option { + let tables: Tables = self.into(); + let table = tables + .get_type_containing_as_table("The response is a") + // these two are special cases not following a pattern + .or_else(|| tables.get_type_containing_as_table("Possible fields")) + .or_else(|| { + tables.get_type_containing_as_table( + "Each element of the array has the following properties", + ) + })?; - while let Some(entry) = content_it.next() { - if let md_parser::MdContent::Text(content) = entry { - const POSSIBLE_VALUES_OF: &str = "Possible values of "; - if content.contains(POSSIBLE_VALUES_OF) { - // is empty - content_it.next(); - if let Some(md_parser::MdContent::Table(table)) = content_it.next() { - let enum_types = to_type_descriptions(table); + let types = self.parse_object_types(); - let name = content - .trim_start_matches(POSSIBLE_VALUES_OF) - .replace('`', "") - .replace(':', ""); + Some(ReturnType { + parameters: table.to_return_type_parameters(&types), + is_list: self.is_list(), + }) + } - output.insert(name, types::TypeDescription { values: enum_types }); - } - } + fn is_list(&self) -> bool { + self.find_content_starts_with("The response is a") + .map(|found| found.contains("array")) + .unwrap_or_else(|| false) + } + + pub fn parse_object_types(&self) -> HashMap { + let tables: Tables = self.into(); + const POSSIBLE_VALUES_OF: &str = "Possible values of "; + + tables + .get_all_type_containing_as_table(POSSIBLE_VALUES_OF) + .iter() + .map(|(k, table)| { + let name = k + .trim_start_matches(POSSIBLE_VALUES_OF) + .replace('`', "") + .replace(':', ""); + + (name, table.to_type_description()) + }) + .collect() + } +} + +impl md_parser::Table { + pub fn to_type_description(&self) -> types::TypeDescription { + types::TypeDescription { + values: self.to_type_descriptions(), } } - output + pub fn to_type_descriptions(&self) -> Vec { + self.rows + .iter() + .map(|row| types::TypeDescriptions { + value: row.columns[0].to_string(), + description: row.columns[1].to_string(), + }) + .collect() + } } -fn to_type_descriptions(table: &md_parser::Table) -> Vec { - table - .rows - .iter() - .map(|row| types::TypeDescriptions { - value: row.columns[0].to_string(), - description: row.columns[1].to_string(), - }) - .collect() +impl md_parser::TableRow { + fn to_return_type_parameter( + &self, + type_map: &HashMap, + ) -> ReturnTypeParameter { + let columns = &self.columns; + + ReturnTypeParameter { + name: columns[0].clone(), + description: columns[2].clone(), + return_type: self + .to_types_with_types(type_map) + .unwrap_or_else(|| panic!("Failed to parse type {}", &columns[1])), + } + } } diff --git a/qbittorrent-web-api-gen/src/parser/group/method/url.rs b/qbittorrent-web-api-gen/src/parser/group/method/url.rs index 5358362..ff35a32 100644 --- a/qbittorrent-web-api-gen/src/parser/group/method/url.rs +++ b/qbittorrent-web-api-gen/src/parser/group/method/url.rs @@ -1,9 +1,11 @@ -use crate::{md_parser, parser::util}; +use crate::md_parser; -pub fn get_method_url(content: &[md_parser::MdContent]) -> String { - const START: &str = "Name: "; +impl md_parser::TokenTree { + pub fn get_method_url(&self) -> String { + const START: &str = "Name: "; - util::find_content_starts_with(content, START) - .map(|text| text.trim_start_matches(START).trim_matches('`').to_string()) - .expect("Could find method url") + self.find_content_starts_with(START) + .map(|text| text.trim_start_matches(START).trim_matches('`').to_string()) + .expect("Could find method url") + } } diff --git a/qbittorrent-web-api-gen/src/parser/group/mod.rs b/qbittorrent-web-api-gen/src/parser/group/mod.rs index b7b4036..df6730d 100644 --- a/qbittorrent-web-api-gen/src/parser/group/mod.rs +++ b/qbittorrent-web-api-gen/src/parser/group/mod.rs @@ -4,8 +4,7 @@ mod url; use crate::md_parser; -use self::{description::parse_group_description, method::parse_api_method, url::get_group_url}; -pub use method::{ApiMethod, ReturnType}; +pub use method::*; #[derive(Debug)] pub struct ApiGroup { @@ -15,25 +14,29 @@ pub struct ApiGroup { pub url: String, } -pub fn parse_api_group(tree: &md_parser::TokenTree) -> ApiGroup { - let methods = tree.children.iter().flat_map(parse_api_method).collect(); - - let group_description = parse_group_description(&tree.content); - let group_url = get_group_url(&tree.content); - - let name = tree - .title - .clone() - .unwrap() - .to_lowercase() - .trim_end_matches("(experimental)") - .trim() - .replace(' ', "_"); - - ApiGroup { - name, - methods, - description: group_description, - url: group_url, +impl ApiGroup { + pub fn new(tree: &md_parser::TokenTree) -> ApiGroup { + ApiGroup { + name: tree.name(), + methods: tree.methods(), + description: tree.parse_group_description(), + url: tree.get_group_url(), + } + } +} + +impl md_parser::TokenTree { + fn name(&self) -> String { + self.title + .clone() + .unwrap() + .to_lowercase() + .trim_end_matches("(experimental)") + .trim() + .replace(' ', "_") + } + + fn methods(&self) -> Vec { + self.children.iter().flat_map(ApiMethod::try_new).collect() } } diff --git a/qbittorrent-web-api-gen/src/parser/group/url.rs b/qbittorrent-web-api-gen/src/parser/group/url.rs index 993c9b8..4f67c6f 100644 --- a/qbittorrent-web-api-gen/src/parser/group/url.rs +++ b/qbittorrent-web-api-gen/src/parser/group/url.rs @@ -1,14 +1,26 @@ use regex::Regex; -use crate::{md_parser, parser::util}; +use crate::md_parser; -pub fn get_group_url(content: &[md_parser::MdContent]) -> String { - let row = util::find_content_contains(content, "API methods are under") - .expect("Could not find api method"); +impl md_parser::TokenTree { + pub fn get_group_url(&self) -> String { + let row = self + .find_content_contains("API methods are under") + .expect("Could not find api method"); - let re = Regex::new(r#"All (?:\w+\s?)+ API methods are under "(\w+)", e.g."#) - .expect("Failed to create regex"); + let re = Regex::new(r#"All (?:\w+\s?)+ API methods are under "(\w+)", e.g."#) + .expect("Failed to create regex"); - let res = re.captures(&row).expect("Failed find capture"); - res[1].to_string() + let res = re.captures(&row).expect("Failed find capture"); + res[1].to_string() + } + + fn find_content_contains(&self, contains: &str) -> Option { + self.content.iter().find_map(|row| match row { + md_parser::MdContent::Text(content) if content.contains(contains) => { + Some(content.into()) + } + _ => None, + }) + } } diff --git a/qbittorrent-web-api-gen/src/parser/groups.txt b/qbittorrent-web-api-gen/src/parser/groups.txt deleted file mode 100644 index 96d8e85..0000000 --- a/qbittorrent-web-api-gen/src/parser/groups.txt +++ /dev/null @@ -1,5696 +0,0 @@ -[ - ApiGroup { - name: "authentication", - methods: [ - ApiMethod { - name: "login", - description: Some( - "Example showing how to login and execute a command that requires authentication using `curl`:\n\n```sh\n$ curl -i --header 'Referer: http://localhost:8080' --data 'username=admin&password=adminadmin' http://localhost:8080/api/v2/auth/login\nHTTP/1.1 200 OK\nContent-Encoding:\nContent-Length: 3\nContent-Type: text/plain; charset=UTF-8\nSet-Cookie: SID=hBc7TxF76ERhvIw0jQQ4LZ7Z1jQUV0tQ; path=/\n$ curl http://localhost:8080/api/v2/torrents/info --cookie \"SID=hBc7TxF76ERhvIw0jQQ4LZ7Z1jQUV0tQ\"\n```\n\nNote: Set `Referer` or `Origin` header to the exact same domain and port as used in the HTTP query `Host` header.", - ), - parameters: Some( - [ - String( - TypeInfo { - name: "username", - is_optional: false, - is_list: false, - description: Some( - "Username used to access the WebUI", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "password", - is_optional: false, - is_list: false, - description: Some( - "Password used to access the WebUI", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "login", - }, - ApiMethod { - name: "logout", - description: None, - parameters: None, - return_type: None, - url: "logout", - }, - ], - description: Some( - "All Authentication API methods are under \"auth\", e.g.: `/api/v2/auth/methodName`.\n\nqBittorrent uses cookie-based authentication.", - ), - url: "auth", - }, - ApiGroup { - name: "application", - methods: [ - ApiMethod { - name: "version", - description: None, - parameters: None, - return_type: None, - url: "version", - }, - ApiMethod { - name: "webapiVersion", - description: None, - parameters: None, - return_type: None, - url: "webapiVersion", - }, - ApiMethod { - name: "buildInfo", - description: None, - parameters: None, - return_type: Some( - ReturnType { - is_list: false, - parameters: [ - ReturnTypeParameter { - name: "qt", - description: "QT version", - return_type: String( - TypeInfo { - name: "qt", - is_optional: false, - is_list: false, - description: Some( - "QT version", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "libtorrent", - description: "libtorrent version", - return_type: String( - TypeInfo { - name: "libtorrent", - is_optional: false, - is_list: false, - description: Some( - "libtorrent version", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "boost", - description: "Boost version", - return_type: String( - TypeInfo { - name: "boost", - is_optional: false, - is_list: false, - description: Some( - "Boost version", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "openssl", - description: "OpenSSL version", - return_type: String( - TypeInfo { - name: "openssl", - is_optional: false, - is_list: false, - description: Some( - "OpenSSL version", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "bitness", - description: "Application bitness (e.g. 64-bit)", - return_type: Number( - TypeInfo { - name: "bitness", - is_optional: false, - is_list: false, - description: Some( - "Application bitness (e.g. 64-bit)", - ), - type_description: None, - }, - ), - }, - ], - }, - ), - url: "buildInfo", - }, - ApiMethod { - name: "shutdown", - description: None, - parameters: None, - return_type: None, - url: "shutdown", - }, - ApiMethod { - name: "preferences", - description: Some( - "Possible fields:\n\nPossible values of `scan_dirs`:\n\nPossible values of `scheduler_days`:\n\nPossible values of `encryption`:\n\nNB: the first options allows you to use both encrypted and unencrypted connections (this is the default); other options are mutually exclusive: e.g. by forcing encryption on you won't be able to use unencrypted connections and vice versa.\n\nPossible values of `proxy_type`:\n\nPossible values of `dyndns_service`:\n\nPossible values of `max_ratio_act`:\n\nPossible values of `bittorrent_protocol`:\n\nPossible values of `upload_choking_algorithm`:\n\nPossible values of `upload_slots_behavior`:\n\nPossible values of `utp_tcp_mixed_mode`:\n\nExample:\n\n```JSON\n{\n \"add_trackers\": \"\",\n \"add_trackers_enabled\": false,\n \"alt_dl_limit\": 10240,\n \"alt_up_limit\": 10240,\n \"alternative_webui_enabled\": false,\n \"alternative_webui_path\": \"/home/user/Documents/qbit-webui\",\n \"announce_ip\": \"\",\n \"announce_to_all_tiers\": true,\n \"announce_to_all_trackers\": false,\n \"anonymous_mode\": false,\n \"async_io_threads\": 4,\n \"auto_delete_mode\": 0,\n \"auto_tmm_enabled\": false,\n \"autorun_enabled\": false,\n \"autorun_program\": \"\",\n \"banned_IPs\": \"\",\n \"bittorrent_protocol\": 0,\n \"bypass_auth_subnet_whitelist\": \"\",\n \"bypass_auth_subnet_whitelist_enabled\": false,\n \"bypass_local_auth\": false,\n \"category_changed_tmm_enabled\": false,\n \"checking_memory_use\": 32,\n \"create_subfolder_enabled\": true,\n \"current_interface_address\": \"\",\n \"current_network_interface\": \"\",\n \"dht\": true,\n \"disk_cache\": -1,\n \"disk_cache_ttl\": 60,\n \"dl_limit\": 0,\n \"dont_count_slow_torrents\": false,\n \"dyndns_domain\": \"changeme.dyndns.org\",\n \"dyndns_enabled\": false,\n \"dyndns_password\": \"\",\n \"dyndns_service\": 0,\n \"dyndns_username\": \"\",\n \"embedded_tracker_port\": 9000,\n \"enable_coalesce_read_write\": false,\n \"enable_embedded_tracker\": false,\n \"enable_multi_connections_from_same_ip\": false,\n \"enable_os_cache\": true,\n \"enable_piece_extent_affinity\": false,\n \"enable_upload_suggestions\": false,\n \"encryption\": 0,\n \"export_dir\": \"/home/user/Downloads/all\",\n \"export_dir_fin\": \"/home/user/Downloads/completed\",\n \"file_pool_size\": 40,\n \"incomplete_files_ext\": false,\n \"ip_filter_enabled\": false,\n \"ip_filter_path\": \"\",\n \"ip_filter_trackers\": false,\n \"limit_lan_peers\": true,\n \"limit_tcp_overhead\": false,\n \"limit_utp_rate\": true,\n \"listen_port\": 58925,\n \"locale\": \"en\",\n \"lsd\": true,\n \"mail_notification_auth_enabled\": false,\n \"mail_notification_email\": \"\",\n \"mail_notification_enabled\": false,\n \"mail_notification_password\": \"\",\n \"mail_notification_sender\": \"qBittorrent_notification@example.com\",\n \"mail_notification_smtp\": \"smtp.changeme.com\",\n \"mail_notification_ssl_enabled\": false,\n \"mail_notification_username\": \"\",\n \"max_active_downloads\": 3,\n \"max_active_torrents\": 5,\n \"max_active_uploads\": 3,\n \"max_connec\": 500,\n \"max_connec_per_torrent\": 100,\n \"max_ratio\": -1,\n \"max_ratio_act\": 0,\n \"max_ratio_enabled\": false,\n \"max_seeding_time\": -1,\n \"max_seeding_time_enabled\": false,\n \"max_uploads\": -1,\n \"max_uploads_per_torrent\": -1,\n \"outgoing_ports_max\": 0,\n \"outgoing_ports_min\": 0,\n \"pex\": true,\n \"preallocate_all\": false,\n \"proxy_auth_enabled\": false,\n \"proxy_ip\": \"0.0.0.0\",\n \"proxy_password\": \"\",\n \"proxy_peer_connections\": false,\n \"proxy_port\": 8080,\n \"proxy_torrents_only\": false,\n \"proxy_type\": 0,\n \"proxy_username\": \"\",\n \"queueing_enabled\": false,\n \"random_port\": false,\n \"recheck_completed_torrents\": false,\n \"resolve_peer_countries\": true,\n \"rss_auto_downloading_enabled\":true,\n \"rss_download_repack_proper_episodes\":true,\n \"rss_max_articles_per_feed\":50,\n \"rss_processing_enabled\":true,\n \"rss_refresh_interval\":30,\n \"rss_smart_episode_filters\":\"s(\\\\d+)e(\\\\d+)\\n(\\\\d+)x(\\\\d+)\\n(\\\\d{4}[.\\\\-]\\\\d{1,2}[.\\\\-]\\\\d{1,2})\",\n \"save_path\": \"/home/user/Downloads/\",\n \"save_path_changed_tmm_enabled\": false,\n \"save_resume_data_interval\": 60,\n \"scan_dirs\":\n {\n \"/home/user/Downloads/incoming/games\": 0,\n \"/home/user/Downloads/incoming/movies\": 1,\n },\n \"schedule_from_hour\": 8,\n \"schedule_from_min\": 0,\n \"schedule_to_hour\": 20,\n \"schedule_to_min\": 0,\n \"scheduler_days\": 0,\n \"scheduler_enabled\": false,\n \"send_buffer_low_watermark\": 10,\n \"send_buffer_watermark\": 500,\n \"send_buffer_watermark_factor\": 50,\n \"slow_torrent_dl_rate_threshold\": 2,\n \"slow_torrent_inactive_timer\": 60,\n \"slow_torrent_ul_rate_threshold\": 2,\n \"socket_backlog_size\": 30,\n \"start_paused_enabled\": false,\n \"stop_tracker_timeout\": 1,\n \"temp_path\": \"/home/user/Downloads/temp\",\n \"temp_path_enabled\": false,\n \"torrent_changed_tmm_enabled\": true,\n \"up_limit\": 0,\n \"upload_choking_algorithm\": 1,\n \"upload_slots_behavior\": 0,\n \"upnp\": true,\n \"use_https\": false,\n \"utp_tcp_mixed_mode\": 0,\n \"web_ui_address\": \"*\",\n \"web_ui_ban_duration\": 3600,\n \"web_ui_clickjacking_protection_enabled\": true,\n \"web_ui_csrf_protection_enabled\": true,\n \"web_ui_custom_http_headers\": \"\",\n \"web_ui_domain_list\": \"*\",\n \"web_ui_host_header_validation_enabled\": true,\n \"web_ui_https_cert_path\": \"\",\n \"web_ui_https_key_path\": \"\",\n \"web_ui_max_auth_fail_count\": 5,\n \"web_ui_port\": 8080,\n \"web_ui_secure_cookie_enabled\": true,\n \"web_ui_session_timeout\": 3600,\n \"web_ui_upnp\": false,\n \"web_ui_use_custom_http_headers_enabled\": false,\n \"web_ui_username\": \"admin\"\n}\n```", - ), - parameters: None, - return_type: Some( - ReturnType { - is_list: false, - parameters: [ - ReturnTypeParameter { - name: "locale", - description: "Currently selected language (e.g. en_GB for English)", - return_type: String( - TypeInfo { - name: "locale", - is_optional: false, - is_list: false, - description: Some( - "Currently selected language (e.g. en_GB for English)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "create_subfolder_enabled", - description: "True if a subfolder should be created when adding a torrent", - return_type: Bool( - TypeInfo { - name: "create_subfolder_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if a subfolder should be created when adding a torrent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "start_paused_enabled", - description: "True if torrents should be added in a Paused state", - return_type: Bool( - TypeInfo { - name: "start_paused_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if torrents should be added in a Paused state", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "auto_delete_mode", - description: "TODO", - return_type: Number( - TypeInfo { - name: "auto_delete_mode", - is_optional: false, - is_list: false, - description: Some( - "TODO", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "preallocate_all", - description: "True if disk space should be pre-allocated for all files", - return_type: Bool( - TypeInfo { - name: "preallocate_all", - is_optional: false, - is_list: false, - description: Some( - "True if disk space should be pre-allocated for all files", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "incomplete_files_ext", - description: "True if \".!qB\" should be appended to incomplete files", - return_type: Bool( - TypeInfo { - name: "incomplete_files_ext", - is_optional: false, - is_list: false, - description: Some( - "True if \".!qB\" should be appended to incomplete files", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "auto_tmm_enabled", - description: "True if Automatic Torrent Management is enabled by default", - return_type: Bool( - TypeInfo { - name: "auto_tmm_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if Automatic Torrent Management is enabled by default", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "torrent_changed_tmm_enabled", - description: "True if torrent should be relocated when its Category changes", - return_type: Bool( - TypeInfo { - name: "torrent_changed_tmm_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if torrent should be relocated when its Category changes", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "save_path_changed_tmm_enabled", - description: "True if torrent should be relocated when the default save path changes", - return_type: Bool( - TypeInfo { - name: "save_path_changed_tmm_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if torrent should be relocated when the default save path changes", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "category_changed_tmm_enabled", - description: "True if torrent should be relocated when its Category's save path changes", - return_type: Bool( - TypeInfo { - name: "category_changed_tmm_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if torrent should be relocated when its Category's save path changes", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "save_path", - description: "Default save path for torrents, separated by slashes", - return_type: String( - TypeInfo { - name: "save_path", - is_optional: false, - is_list: false, - description: Some( - "Default save path for torrents, separated by slashes", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "temp_path_enabled", - description: "True if folder for incomplete torrents is enabled", - return_type: Bool( - TypeInfo { - name: "temp_path_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if folder for incomplete torrents is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "temp_path", - description: "Path for incomplete torrents, separated by slashes", - return_type: String( - TypeInfo { - name: "temp_path", - is_optional: false, - is_list: false, - description: Some( - "Path for incomplete torrents, separated by slashes", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "scan_dirs", - description: "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", - return_type: Object( - TypeInfo { - name: "scan_dirs", - is_optional: false, - is_list: false, - description: Some( - "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", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "Download to the monitored folder", - }, - TypeDescriptions { - value: "1", - description: "Download to the default save path", - }, - TypeDescriptions { - value: "\"/path/to/download/to\"", - description: "Download to this path", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "export_dir", - description: "Path to directory to copy .torrent files to. Slashes are used as path separators", - return_type: String( - TypeInfo { - name: "export_dir", - is_optional: false, - is_list: false, - description: Some( - "Path to directory to copy .torrent files to. Slashes are used as path separators", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "export_dir_fin", - description: "Path to directory to copy .torrent files of completed downloads to. Slashes are used as path separators", - return_type: String( - TypeInfo { - name: "export_dir_fin", - is_optional: false, - is_list: false, - description: Some( - "Path to directory to copy .torrent files of completed downloads to. Slashes are used as path separators", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "mail_notification_enabled", - description: "True if e-mail notification should be enabled", - return_type: Bool( - TypeInfo { - name: "mail_notification_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if e-mail notification should be enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "mail_notification_sender", - description: "e-mail where notifications should originate from", - return_type: String( - TypeInfo { - name: "mail_notification_sender", - is_optional: false, - is_list: false, - description: Some( - "e-mail where notifications should originate from", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "mail_notification_email", - description: "e-mail to send notifications to", - return_type: String( - TypeInfo { - name: "mail_notification_email", - is_optional: false, - is_list: false, - description: Some( - "e-mail to send notifications to", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "mail_notification_smtp", - description: "smtp server for e-mail notifications", - return_type: String( - TypeInfo { - name: "mail_notification_smtp", - is_optional: false, - is_list: false, - description: Some( - "smtp server for e-mail notifications", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "mail_notification_ssl_enabled", - description: "True if smtp server requires SSL connection", - return_type: Bool( - TypeInfo { - name: "mail_notification_ssl_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if smtp server requires SSL connection", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "mail_notification_auth_enabled", - description: "True if smtp server requires authentication", - return_type: Bool( - TypeInfo { - name: "mail_notification_auth_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if smtp server requires authentication", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "mail_notification_username", - description: "Username for smtp authentication", - return_type: String( - TypeInfo { - name: "mail_notification_username", - is_optional: false, - is_list: false, - description: Some( - "Username for smtp authentication", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "mail_notification_password", - description: "Password for smtp authentication", - return_type: String( - TypeInfo { - name: "mail_notification_password", - is_optional: false, - is_list: false, - description: Some( - "Password for smtp authentication", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "autorun_enabled", - description: "True if external program should be run after torrent has finished downloading", - return_type: Bool( - TypeInfo { - name: "autorun_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if external program should be run after torrent has finished downloading", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "autorun_program", - description: "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", - return_type: String( - TypeInfo { - name: "autorun_program", - is_optional: false, - is_list: false, - description: Some( - "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", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "queueing_enabled", - description: "True if torrent queuing is enabled", - return_type: Bool( - TypeInfo { - name: "queueing_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if torrent queuing is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_active_downloads", - description: "Maximum number of active simultaneous downloads", - return_type: Number( - TypeInfo { - name: "max_active_downloads", - is_optional: false, - is_list: false, - description: Some( - "Maximum number of active simultaneous downloads", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_active_torrents", - description: "Maximum number of active simultaneous downloads and uploads", - return_type: Number( - TypeInfo { - name: "max_active_torrents", - is_optional: false, - is_list: false, - description: Some( - "Maximum number of active simultaneous downloads and uploads", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_active_uploads", - description: "Maximum number of active simultaneous uploads", - return_type: Number( - TypeInfo { - name: "max_active_uploads", - is_optional: false, - is_list: false, - description: Some( - "Maximum number of active simultaneous uploads", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dont_count_slow_torrents", - description: "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", - return_type: Bool( - TypeInfo { - name: "dont_count_slow_torrents", - is_optional: false, - is_list: false, - description: Some( - "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", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "slow_torrent_dl_rate_threshold", - description: "Download rate in KiB/s for a torrent to be considered \"slow\"", - return_type: Number( - TypeInfo { - name: "slow_torrent_dl_rate_threshold", - is_optional: false, - is_list: false, - description: Some( - "Download rate in KiB/s for a torrent to be considered \"slow\"", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "slow_torrent_ul_rate_threshold", - description: "Upload rate in KiB/s for a torrent to be considered \"slow\"", - return_type: Number( - TypeInfo { - name: "slow_torrent_ul_rate_threshold", - is_optional: false, - is_list: false, - description: Some( - "Upload rate in KiB/s for a torrent to be considered \"slow\"", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "slow_torrent_inactive_timer", - description: "Seconds a torrent should be inactive before considered \"slow\"", - return_type: Number( - TypeInfo { - name: "slow_torrent_inactive_timer", - is_optional: false, - is_list: false, - description: Some( - "Seconds a torrent should be inactive before considered \"slow\"", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_ratio_enabled", - description: "True if share ratio limit is enabled", - return_type: Bool( - TypeInfo { - name: "max_ratio_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if share ratio limit is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_ratio", - description: "Get the global share ratio limit", - return_type: Float( - TypeInfo { - name: "max_ratio", - is_optional: false, - is_list: false, - description: Some( - "Get the global share ratio limit", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_ratio_act", - description: "Action performed when a torrent reaches the maximum share ratio. See list of possible values here below.", - return_type: Number( - TypeInfo { - name: "max_ratio_act", - is_optional: false, - is_list: false, - description: Some( - "Action performed when a torrent reaches the maximum share ratio. See list of possible values here below.", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "Pause torrent", - }, - TypeDescriptions { - value: "1", - description: "Remove torrent", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "listen_port", - description: "Port for incoming connections", - return_type: Number( - TypeInfo { - name: "listen_port", - is_optional: false, - is_list: false, - description: Some( - "Port for incoming connections", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "upnp", - description: "True if UPnP/NAT-PMP is enabled", - return_type: Bool( - TypeInfo { - name: "upnp", - is_optional: false, - is_list: false, - description: Some( - "True if UPnP/NAT-PMP is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "random_port", - description: "True if the port is randomly selected", - return_type: Bool( - TypeInfo { - name: "random_port", - is_optional: false, - is_list: false, - description: Some( - "True if the port is randomly selected", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dl_limit", - description: "Global download speed limit in KiB/s; -1 means no limit is applied", - return_type: Number( - TypeInfo { - name: "dl_limit", - is_optional: false, - is_list: false, - description: Some( - "Global download speed limit in KiB/s; -1 means no limit is applied", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "up_limit", - description: "Global upload speed limit in KiB/s; -1 means no limit is applied", - return_type: Number( - TypeInfo { - name: "up_limit", - is_optional: false, - is_list: false, - description: Some( - "Global upload speed limit in KiB/s; -1 means no limit is applied", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_connec", - description: "Maximum global number of simultaneous connections", - return_type: Number( - TypeInfo { - name: "max_connec", - is_optional: false, - is_list: false, - description: Some( - "Maximum global number of simultaneous connections", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_connec_per_torrent", - description: "Maximum number of simultaneous connections per torrent", - return_type: Number( - TypeInfo { - name: "max_connec_per_torrent", - is_optional: false, - is_list: false, - description: Some( - "Maximum number of simultaneous connections per torrent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_uploads", - description: "Maximum number of upload slots", - return_type: Number( - TypeInfo { - name: "max_uploads", - is_optional: false, - is_list: false, - description: Some( - "Maximum number of upload slots", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_uploads_per_torrent", - description: "Maximum number of upload slots per torrent", - return_type: Number( - TypeInfo { - name: "max_uploads_per_torrent", - is_optional: false, - is_list: false, - description: Some( - "Maximum number of upload slots per torrent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "stop_tracker_timeout", - description: "Timeout in seconds for a stopped announce request to trackers", - return_type: Number( - TypeInfo { - name: "stop_tracker_timeout", - is_optional: false, - is_list: false, - description: Some( - "Timeout in seconds for a stopped announce request to trackers", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "enable_piece_extent_affinity", - description: "True if the advanced libtorrent option piece_extent_affinity is enabled", - return_type: Bool( - TypeInfo { - name: "enable_piece_extent_affinity", - is_optional: false, - is_list: false, - description: Some( - "True if the advanced libtorrent option piece_extent_affinity is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "bittorrent_protocol", - description: "Bittorrent Protocol to use (see list of possible values below)", - return_type: Number( - TypeInfo { - name: "bittorrent_protocol", - is_optional: false, - is_list: false, - description: Some( - "Bittorrent Protocol to use (see list of possible values below)", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "TCP and μTP", - }, - TypeDescriptions { - value: "1", - description: "TCP", - }, - TypeDescriptions { - value: "2", - description: "μTP", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "limit_utp_rate", - description: "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", - return_type: Bool( - TypeInfo { - name: "limit_utp_rate", - is_optional: false, - is_list: false, - description: Some( - "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", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "limit_tcp_overhead", - description: "True if [du]l_limit should be applied to estimated TCP overhead (service data: e.g. packet headers)", - return_type: Bool( - TypeInfo { - name: "limit_tcp_overhead", - is_optional: false, - is_list: false, - description: Some( - "True if [du]l_limit should be applied to estimated TCP overhead (service data: e.g. packet headers)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "limit_lan_peers", - description: "True if [du]l_limit should be applied to peers on the LAN", - return_type: Bool( - TypeInfo { - name: "limit_lan_peers", - is_optional: false, - is_list: false, - description: Some( - "True if [du]l_limit should be applied to peers on the LAN", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "alt_dl_limit", - description: "Alternative global download speed limit in KiB/s", - return_type: Number( - TypeInfo { - name: "alt_dl_limit", - is_optional: false, - is_list: false, - description: Some( - "Alternative global download speed limit in KiB/s", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "alt_up_limit", - description: "Alternative global upload speed limit in KiB/s", - return_type: Number( - TypeInfo { - name: "alt_up_limit", - is_optional: false, - is_list: false, - description: Some( - "Alternative global upload speed limit in KiB/s", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "scheduler_enabled", - description: "True if alternative limits should be applied according to schedule", - return_type: Bool( - TypeInfo { - name: "scheduler_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if alternative limits should be applied according to schedule", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "schedule_from_hour", - description: "Scheduler starting hour", - return_type: Number( - TypeInfo { - name: "schedule_from_hour", - is_optional: false, - is_list: false, - description: Some( - "Scheduler starting hour", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "schedule_from_min", - description: "Scheduler starting minute", - return_type: Number( - TypeInfo { - name: "schedule_from_min", - is_optional: false, - is_list: false, - description: Some( - "Scheduler starting minute", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "schedule_to_hour", - description: "Scheduler ending hour", - return_type: Number( - TypeInfo { - name: "schedule_to_hour", - is_optional: false, - is_list: false, - description: Some( - "Scheduler ending hour", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "schedule_to_min", - description: "Scheduler ending minute", - return_type: Number( - TypeInfo { - name: "schedule_to_min", - is_optional: false, - is_list: false, - description: Some( - "Scheduler ending minute", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "scheduler_days", - description: "Scheduler days. See possible values here below", - return_type: Number( - TypeInfo { - name: "scheduler_days", - is_optional: false, - is_list: false, - description: Some( - "Scheduler days. See possible values here below", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "Every day", - }, - TypeDescriptions { - value: "1", - description: "Every weekday", - }, - TypeDescriptions { - value: "2", - description: "Every weekend", - }, - TypeDescriptions { - value: "3", - description: "Every Monday", - }, - TypeDescriptions { - value: "4", - description: "Every Tuesday", - }, - TypeDescriptions { - value: "5", - description: "Every Wednesday", - }, - TypeDescriptions { - value: "6", - description: "Every Thursday", - }, - TypeDescriptions { - value: "7", - description: "Every Friday", - }, - TypeDescriptions { - value: "8", - description: "Every Saturday", - }, - TypeDescriptions { - value: "9", - description: "Every Sunday", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "dht", - description: "True if DHT is enabled", - return_type: Bool( - TypeInfo { - name: "dht", - is_optional: false, - is_list: false, - description: Some( - "True if DHT is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "pex", - description: "True if PeX is enabled", - return_type: Bool( - TypeInfo { - name: "pex", - is_optional: false, - is_list: false, - description: Some( - "True if PeX is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "lsd", - description: "True if LSD is enabled", - return_type: Bool( - TypeInfo { - name: "lsd", - is_optional: false, - is_list: false, - description: Some( - "True if LSD is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "encryption", - description: "See list of possible values here below", - return_type: Number( - TypeInfo { - name: "encryption", - is_optional: false, - is_list: false, - description: Some( - "See list of possible values here below", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "Prefer encryption", - }, - TypeDescriptions { - value: "1", - description: "Force encryption on", - }, - TypeDescriptions { - value: "2", - description: "Force encryption off", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "anonymous_mode", - description: "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", - return_type: Bool( - TypeInfo { - name: "anonymous_mode", - is_optional: false, - is_list: false, - description: Some( - "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", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "proxy_type", - description: "See list of possible values here below", - return_type: Number( - TypeInfo { - name: "proxy_type", - is_optional: false, - is_list: false, - description: Some( - "See list of possible values here below", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "-1", - description: "Proxy is disabled", - }, - TypeDescriptions { - value: "1", - description: "HTTP proxy without authentication", - }, - TypeDescriptions { - value: "2", - description: "SOCKS5 proxy without authentication", - }, - TypeDescriptions { - value: "3", - description: "HTTP proxy with authentication", - }, - TypeDescriptions { - value: "4", - description: "SOCKS5 proxy with authentication", - }, - TypeDescriptions { - value: "5", - description: "SOCKS4 proxy without authentication", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "proxy_ip", - description: "Proxy IP address or domain name", - return_type: String( - TypeInfo { - name: "proxy_ip", - is_optional: false, - is_list: false, - description: Some( - "Proxy IP address or domain name", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "proxy_port", - description: "Proxy port", - return_type: Number( - TypeInfo { - name: "proxy_port", - is_optional: false, - is_list: false, - description: Some( - "Proxy port", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "proxy_peer_connections", - description: "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", - return_type: Bool( - TypeInfo { - name: "proxy_peer_connections", - is_optional: false, - is_list: false, - description: Some( - "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", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "proxy_auth_enabled", - description: "True proxy requires authentication; doesn't apply to SOCKS4 proxies", - return_type: Bool( - TypeInfo { - name: "proxy_auth_enabled", - is_optional: false, - is_list: false, - description: Some( - "True proxy requires authentication; doesn't apply to SOCKS4 proxies", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "proxy_username", - description: "Username for proxy authentication", - return_type: String( - TypeInfo { - name: "proxy_username", - is_optional: false, - is_list: false, - description: Some( - "Username for proxy authentication", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "proxy_password", - description: "Password for proxy authentication", - return_type: String( - TypeInfo { - name: "proxy_password", - is_optional: false, - is_list: false, - description: Some( - "Password for proxy authentication", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "proxy_torrents_only", - description: "True if proxy is only used for torrents", - return_type: Bool( - TypeInfo { - name: "proxy_torrents_only", - is_optional: false, - is_list: false, - description: Some( - "True if proxy is only used for torrents", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "ip_filter_enabled", - description: "True if external IP filter should be enabled", - return_type: Bool( - TypeInfo { - name: "ip_filter_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if external IP filter should be enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "ip_filter_path", - description: "Path to IP filter file (.dat, .p2p, .p2b files are supported); path is separated by slashes", - return_type: String( - TypeInfo { - name: "ip_filter_path", - is_optional: false, - is_list: false, - description: Some( - "Path to IP filter file (.dat, .p2p, .p2b files are supported); path is separated by slashes", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "ip_filter_trackers", - description: "True if IP filters are applied to trackers", - return_type: Bool( - TypeInfo { - name: "ip_filter_trackers", - is_optional: false, - is_list: false, - description: Some( - "True if IP filters are applied to trackers", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_domain_list", - description: "Comma-separated list of domains to accept when performing Host header validation", - return_type: String( - TypeInfo { - name: "web_ui_domain_list", - is_optional: false, - is_list: false, - description: Some( - "Comma-separated list of domains to accept when performing Host header validation", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_address", - description: "IP address to use for the WebUI", - return_type: String( - TypeInfo { - name: "web_ui_address", - is_optional: false, - is_list: false, - description: Some( - "IP address to use for the WebUI", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_port", - description: "WebUI port", - return_type: Number( - TypeInfo { - name: "web_ui_port", - is_optional: false, - is_list: false, - description: Some( - "WebUI port", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_upnp", - description: "True if UPnP is used for the WebUI port", - return_type: Bool( - TypeInfo { - name: "web_ui_upnp", - is_optional: false, - is_list: false, - description: Some( - "True if UPnP is used for the WebUI port", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_username", - description: "WebUI username", - return_type: String( - TypeInfo { - name: "web_ui_username", - is_optional: false, - is_list: false, - description: Some( - "WebUI username", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_password", - description: "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", - return_type: String( - TypeInfo { - name: "web_ui_password", - is_optional: false, - is_list: false, - description: Some( - "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", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_csrf_protection_enabled", - description: "True if WebUI CSRF protection is enabled", - return_type: Bool( - TypeInfo { - name: "web_ui_csrf_protection_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if WebUI CSRF protection is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_clickjacking_protection_enabled", - description: "True if WebUI clickjacking protection is enabled", - return_type: Bool( - TypeInfo { - name: "web_ui_clickjacking_protection_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if WebUI clickjacking protection is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_secure_cookie_enabled", - description: "True if WebUI cookie Secure flag is enabled", - return_type: Bool( - TypeInfo { - name: "web_ui_secure_cookie_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if WebUI cookie Secure flag is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_max_auth_fail_count", - description: "Maximum number of authentication failures before WebUI access ban", - return_type: Number( - TypeInfo { - name: "web_ui_max_auth_fail_count", - is_optional: false, - is_list: false, - description: Some( - "Maximum number of authentication failures before WebUI access ban", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_ban_duration", - description: "WebUI access ban duration in seconds", - return_type: Number( - TypeInfo { - name: "web_ui_ban_duration", - is_optional: false, - is_list: false, - description: Some( - "WebUI access ban duration in seconds", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_session_timeout", - description: "Seconds until WebUI is automatically signed off", - return_type: Number( - TypeInfo { - name: "web_ui_session_timeout", - is_optional: false, - is_list: false, - description: Some( - "Seconds until WebUI is automatically signed off", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_host_header_validation_enabled", - description: "True if WebUI host header validation is enabled", - return_type: Bool( - TypeInfo { - name: "web_ui_host_header_validation_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if WebUI host header validation is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "bypass_local_auth", - description: "True if authentication challenge for loopback address (127.0.0.1) should be disabled", - return_type: Bool( - TypeInfo { - name: "bypass_local_auth", - is_optional: false, - is_list: false, - description: Some( - "True if authentication challenge for loopback address (127.0.0.1) should be disabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "bypass_auth_subnet_whitelist_enabled", - description: "True if webui authentication should be bypassed for clients whose ip resides within (at least) one of the subnets on the whitelist", - return_type: Bool( - TypeInfo { - name: "bypass_auth_subnet_whitelist_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if webui authentication should be bypassed for clients whose ip resides within (at least) one of the subnets on the whitelist", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "bypass_auth_subnet_whitelist", - description: "(White)list of ipv4/ipv6 subnets for which webui authentication should be bypassed; list entries are separated by commas", - return_type: String( - TypeInfo { - name: "bypass_auth_subnet_whitelist", - is_optional: false, - is_list: false, - description: Some( - "(White)list of ipv4/ipv6 subnets for which webui authentication should be bypassed; list entries are separated by commas", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "alternative_webui_enabled", - description: "True if an alternative WebUI should be used", - return_type: Bool( - TypeInfo { - name: "alternative_webui_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if an alternative WebUI should be used", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "alternative_webui_path", - description: "File path to the alternative WebUI", - return_type: String( - TypeInfo { - name: "alternative_webui_path", - is_optional: false, - is_list: false, - description: Some( - "File path to the alternative WebUI", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "use_https", - description: "True if WebUI HTTPS access is enabled", - return_type: Bool( - TypeInfo { - name: "use_https", - is_optional: false, - is_list: false, - description: Some( - "True if WebUI HTTPS access is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "ssl_key", - description: "For API < v2.0.1: SSL keyfile contents (this is a not a path)", - return_type: String( - TypeInfo { - name: "ssl_key", - is_optional: false, - is_list: false, - description: Some( - "For API < v2.0.1: SSL keyfile contents (this is a not a path)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "ssl_cert", - description: "For API < v2.0.1: SSL certificate contents (this is a not a path)", - return_type: String( - TypeInfo { - name: "ssl_cert", - is_optional: false, - is_list: false, - description: Some( - "For API < v2.0.1: SSL certificate contents (this is a not a path)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_https_key_path", - description: "For API ≥ v2.0.1: Path to SSL keyfile", - return_type: String( - TypeInfo { - name: "web_ui_https_key_path", - is_optional: false, - is_list: false, - description: Some( - "For API ≥ v2.0.1: Path to SSL keyfile", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_https_cert_path", - description: "For API ≥ v2.0.1: Path to SSL certificate", - return_type: String( - TypeInfo { - name: "web_ui_https_cert_path", - is_optional: false, - is_list: false, - description: Some( - "For API ≥ v2.0.1: Path to SSL certificate", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dyndns_enabled", - description: "True if server DNS should be updated dynamically", - return_type: Bool( - TypeInfo { - name: "dyndns_enabled", - is_optional: false, - is_list: false, - description: Some( - "True if server DNS should be updated dynamically", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dyndns_service", - description: "See list of possible values here below", - return_type: Number( - TypeInfo { - name: "dyndns_service", - is_optional: false, - is_list: false, - description: Some( - "See list of possible values here below", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "Use DyDNS", - }, - TypeDescriptions { - value: "1", - description: "Use NOIP", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "dyndns_username", - description: "Username for DDNS service", - return_type: String( - TypeInfo { - name: "dyndns_username", - is_optional: false, - is_list: false, - description: Some( - "Username for DDNS service", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dyndns_password", - description: "Password for DDNS service", - return_type: String( - TypeInfo { - name: "dyndns_password", - is_optional: false, - is_list: false, - description: Some( - "Password for DDNS service", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dyndns_domain", - description: "Your DDNS domain name", - return_type: String( - TypeInfo { - name: "dyndns_domain", - is_optional: false, - is_list: false, - description: Some( - "Your DDNS domain name", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "rss_refresh_interval", - description: "RSS refresh interval", - return_type: Number( - TypeInfo { - name: "rss_refresh_interval", - is_optional: false, - is_list: false, - description: Some( - "RSS refresh interval", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "rss_max_articles_per_feed", - description: "Max stored articles per RSS feed", - return_type: Number( - TypeInfo { - name: "rss_max_articles_per_feed", - is_optional: false, - is_list: false, - description: Some( - "Max stored articles per RSS feed", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "rss_processing_enabled", - description: "Enable processing of RSS feeds", - return_type: Bool( - TypeInfo { - name: "rss_processing_enabled", - is_optional: false, - is_list: false, - description: Some( - "Enable processing of RSS feeds", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "rss_auto_downloading_enabled", - description: "Enable auto-downloading of torrents from the RSS feeds", - return_type: Bool( - TypeInfo { - name: "rss_auto_downloading_enabled", - is_optional: false, - is_list: false, - description: Some( - "Enable auto-downloading of torrents from the RSS feeds", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "rss_download_repack_proper_episodes", - description: "For API ≥ v2.5.1: Enable downloading of repack/proper Episodes", - return_type: Bool( - TypeInfo { - name: "rss_download_repack_proper_episodes", - is_optional: false, - is_list: false, - description: Some( - "For API ≥ v2.5.1: Enable downloading of repack/proper Episodes", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "rss_smart_episode_filters", - description: "For API ≥ v2.5.1: List of RSS Smart Episode Filters", - return_type: String( - TypeInfo { - name: "rss_smart_episode_filters", - is_optional: false, - is_list: false, - description: Some( - "For API ≥ v2.5.1: List of RSS Smart Episode Filters", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "add_trackers_enabled", - description: "Enable automatic adding of trackers to new torrents", - return_type: Bool( - TypeInfo { - name: "add_trackers_enabled", - is_optional: false, - is_list: false, - description: Some( - "Enable automatic adding of trackers to new torrents", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "add_trackers", - description: "List of trackers to add to new torrent", - return_type: String( - TypeInfo { - name: "add_trackers", - is_optional: false, - is_list: false, - description: Some( - "List of trackers to add to new torrent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_use_custom_http_headers_enabled", - description: "For API ≥ v2.5.1: Enable custom http headers", - return_type: Bool( - TypeInfo { - name: "web_ui_use_custom_http_headers_enabled", - is_optional: false, - is_list: false, - description: Some( - "For API ≥ v2.5.1: Enable custom http headers", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "web_ui_custom_http_headers", - description: "For API ≥ v2.5.1: List of custom http headers", - return_type: String( - TypeInfo { - name: "web_ui_custom_http_headers", - is_optional: false, - is_list: false, - description: Some( - "For API ≥ v2.5.1: List of custom http headers", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_seeding_time_enabled", - description: "True enables max seeding time", - return_type: Bool( - TypeInfo { - name: "max_seeding_time_enabled", - is_optional: false, - is_list: false, - description: Some( - "True enables max seeding time", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_seeding_time", - description: "Number of minutes to seed a torrent", - return_type: Number( - TypeInfo { - name: "max_seeding_time", - is_optional: false, - is_list: false, - description: Some( - "Number of minutes to seed a torrent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "announce_ip", - description: "TODO", - return_type: String( - TypeInfo { - name: "announce_ip", - is_optional: false, - is_list: false, - description: Some( - "TODO", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "announce_to_all_tiers", - description: "True always announce to all tiers", - return_type: Bool( - TypeInfo { - name: "announce_to_all_tiers", - is_optional: false, - is_list: false, - description: Some( - "True always announce to all tiers", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "announce_to_all_trackers", - description: "True always announce to all trackers in a tier", - return_type: Bool( - TypeInfo { - name: "announce_to_all_trackers", - is_optional: false, - is_list: false, - description: Some( - "True always announce to all trackers in a tier", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "async_io_threads", - description: "Number of asynchronous I/O threads", - return_type: Number( - TypeInfo { - name: "async_io_threads", - is_optional: false, - is_list: false, - description: Some( - "Number of asynchronous I/O threads", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "banned_IPs", - description: "List of banned IPs", - return_type: String( - TypeInfo { - name: "banned_IPs", - is_optional: false, - is_list: false, - description: Some( - "List of banned IPs", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "checking_memory_use", - description: "Outstanding memory when checking torrents in MiB", - return_type: Number( - TypeInfo { - name: "checking_memory_use", - is_optional: false, - is_list: false, - description: Some( - "Outstanding memory when checking torrents in MiB", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "current_interface_address", - description: "IP Address to bind to. Empty String means All addresses", - return_type: String( - TypeInfo { - name: "current_interface_address", - is_optional: false, - is_list: false, - description: Some( - "IP Address to bind to. Empty String means All addresses", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "current_network_interface", - description: "Network Interface used", - return_type: String( - TypeInfo { - name: "current_network_interface", - is_optional: false, - is_list: false, - description: Some( - "Network Interface used", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "disk_cache", - description: "Disk cache used in MiB", - return_type: Number( - TypeInfo { - name: "disk_cache", - is_optional: false, - is_list: false, - description: Some( - "Disk cache used in MiB", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "disk_cache_ttl", - description: "Disk cache expiry interval in seconds", - return_type: Number( - TypeInfo { - name: "disk_cache_ttl", - is_optional: false, - is_list: false, - description: Some( - "Disk cache expiry interval in seconds", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "embedded_tracker_port", - description: "Port used for embedded tracker", - return_type: Number( - TypeInfo { - name: "embedded_tracker_port", - is_optional: false, - is_list: false, - description: Some( - "Port used for embedded tracker", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "enable_coalesce_read_write", - description: "True enables coalesce reads & writes", - return_type: Bool( - TypeInfo { - name: "enable_coalesce_read_write", - is_optional: false, - is_list: false, - description: Some( - "True enables coalesce reads & writes", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "enable_embedded_tracker", - description: "True enables embedded tracker", - return_type: Bool( - TypeInfo { - name: "enable_embedded_tracker", - is_optional: false, - is_list: false, - description: Some( - "True enables embedded tracker", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "enable_multi_connections_from_same_ip", - description: "True allows multiple connections from the same IP address", - return_type: Bool( - TypeInfo { - name: "enable_multi_connections_from_same_ip", - is_optional: false, - is_list: false, - description: Some( - "True allows multiple connections from the same IP address", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "enable_os_cache", - description: "True enables os cache", - return_type: Bool( - TypeInfo { - name: "enable_os_cache", - is_optional: false, - is_list: false, - description: Some( - "True enables os cache", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "enable_upload_suggestions", - description: "True enables sending of upload piece suggestions", - return_type: Bool( - TypeInfo { - name: "enable_upload_suggestions", - is_optional: false, - is_list: false, - description: Some( - "True enables sending of upload piece suggestions", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "file_pool_size", - description: "File pool size", - return_type: Number( - TypeInfo { - name: "file_pool_size", - is_optional: false, - is_list: false, - description: Some( - "File pool size", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "outgoing_ports_max", - description: "Maximal outgoing port (0: Disabled)", - return_type: Number( - TypeInfo { - name: "outgoing_ports_max", - is_optional: false, - is_list: false, - description: Some( - "Maximal outgoing port (0: Disabled)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "outgoing_ports_min", - description: "Minimal outgoing port (0: Disabled)", - return_type: Number( - TypeInfo { - name: "outgoing_ports_min", - is_optional: false, - is_list: false, - description: Some( - "Minimal outgoing port (0: Disabled)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "recheck_completed_torrents", - description: "True rechecks torrents on completion", - return_type: Bool( - TypeInfo { - name: "recheck_completed_torrents", - is_optional: false, - is_list: false, - description: Some( - "True rechecks torrents on completion", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "resolve_peer_countries", - description: "True resolves peer countries", - return_type: Bool( - TypeInfo { - name: "resolve_peer_countries", - is_optional: false, - is_list: false, - description: Some( - "True resolves peer countries", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "save_resume_data_interval", - description: "Save resume data interval in min", - return_type: Number( - TypeInfo { - name: "save_resume_data_interval", - is_optional: false, - is_list: false, - description: Some( - "Save resume data interval in min", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "send_buffer_low_watermark", - description: "Send buffer low watermark in KiB", - return_type: Number( - TypeInfo { - name: "send_buffer_low_watermark", - is_optional: false, - is_list: false, - description: Some( - "Send buffer low watermark in KiB", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "send_buffer_watermark", - description: "Send buffer watermark in KiB", - return_type: Number( - TypeInfo { - name: "send_buffer_watermark", - is_optional: false, - is_list: false, - description: Some( - "Send buffer watermark in KiB", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "send_buffer_watermark_factor", - description: "Send buffer watermark factor in percent", - return_type: Number( - TypeInfo { - name: "send_buffer_watermark_factor", - is_optional: false, - is_list: false, - description: Some( - "Send buffer watermark factor in percent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "socket_backlog_size", - description: "Socket backlog size", - return_type: Number( - TypeInfo { - name: "socket_backlog_size", - is_optional: false, - is_list: false, - description: Some( - "Socket backlog size", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "upload_choking_algorithm", - description: "Upload choking algorithm used (see list of possible values below)", - return_type: Number( - TypeInfo { - name: "upload_choking_algorithm", - is_optional: false, - is_list: false, - description: Some( - "Upload choking algorithm used (see list of possible values below)", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "Round-robin", - }, - TypeDescriptions { - value: "1", - description: "Fastest upload", - }, - TypeDescriptions { - value: "2", - description: "Anti-leech", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "upload_slots_behavior", - description: "Upload slots behavior used (see list of possible values below)", - return_type: Number( - TypeInfo { - name: "upload_slots_behavior", - is_optional: false, - is_list: false, - description: Some( - "Upload slots behavior used (see list of possible values below)", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "Fixed slots", - }, - TypeDescriptions { - value: "1", - description: "Upload rate based", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "upnp_lease_duration", - description: "UPnP lease duration (0: Permanent lease)", - return_type: Number( - TypeInfo { - name: "upnp_lease_duration", - is_optional: false, - is_list: false, - description: Some( - "UPnP lease duration (0: Permanent lease)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "utp_tcp_mixed_mode", - description: "μTP-TCP mixed mode algorithm (see list of possible values below)", - return_type: Number( - TypeInfo { - name: "utp_tcp_mixed_mode", - is_optional: false, - is_list: false, - description: Some( - "μTP-TCP mixed mode algorithm (see list of possible values below)", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "Prefer TCP", - }, - TypeDescriptions { - value: "1", - description: "Peer proportional", - }, - ], - }, - ), - }, - ), - }, - ], - }, - ), - url: "preferences", - }, - ApiMethod { - name: "setPreferences", - description: Some( - "1. There is no need to pass all possible preferences' `token:value` pairs if you only want to change one option\n 1. Paths in `scan_dirs` must exist, otherwise this option will have no effect\n 1. String values must be quoted; integer and boolean values must never be quoted\n\nFor a list of possible preference options see [Get application preferences](#get-application-preferences)", - ), - parameters: None, - return_type: None, - url: "setPreferences", - }, - ApiMethod { - name: "defaultSavePath", - description: None, - parameters: None, - return_type: None, - url: "defaultSavePath", - }, - ], - description: Some( - "All Application API methods are under \"app\", e.g.: `/api/v2/app/methodName`.", - ), - url: "app", - }, - ApiGroup { - name: "log", - methods: [ - ApiMethod { - name: "main", - description: Some( - "Each element of the array has the following properties:\n\nExample:\n\n```JSON\n[\n {\n \"id\":0,\n \"message\":\"qBittorrent v3.4.0 started\",\n \"timestamp\":1507969127860,\n \"type\":1\n },\n {\n \"id\":1,\n \"message\":\"qBittorrent is trying to listen on any interface port: 19036\",\n \"timestamp\":1507969127869,\n \"type\":2\n },\n {\n \"id\":2,\n \"message\":\"Peer ID: -qB3400-\",\n \"timestamp\":1507969127870,\n \"type\":1\n },\n {\n \"id\":3,\n \"message\":\"HTTP User-Agent is 'qBittorrent/3.4.0'\",\n \"timestamp\":1507969127870,\n \"type\":1\n },\n {\n \"id\":4,\n \"message\":\"DHT support [ON]\",\n \"timestamp\":1507969127871,\n \"type\":2\n },\n {\n \"id\":5,\n \"message\":\"Local Peer Discovery support [ON]\",\n \"timestamp\":1507969127871,\n \"type\":2\n },\n {\n \"id\":6,\n \"message\":\"PeX support [ON]\",\n \"timestamp\":1507969127871,\n \"type\":2\n },\n {\n \"id\":7,\n \"message\":\"Anonymous mode [OFF]\",\n \"timestamp\":1507969127871,\n \"type\":2\n },\n {\n \"id\":8,\n \"message\":\"Encryption support [ON]\",\n \"timestamp\":1507969127871,\n \"type\":2\n },\n {\n \"id\":9,\n \"message\":\"Embedded Tracker [OFF]\",\n \"timestamp\":1507969127871,\n \"type\":2\n },\n {\n \"id\":10,\n \"message\":\"UPnP / NAT-PMP support [ON]\",\n \"timestamp\":1507969127873,\n \"type\":2\n },\n {\n \"id\":11,\n \"message\":\"Web UI: Now listening on port 8080\",\n \"timestamp\":1507969127883,\n \"type\":1\n },\n {\n \"id\":12,\n \"message\":\"Options were saved successfully.\",\n \"timestamp\":1507969128055,\n \"type\":1\n },\n {\n \"id\":13,\n \"message\":\"qBittorrent is successfully listening on interface :: port: TCP/19036\",\n \"timestamp\":1507969128270,\n \"type\":2\n },\n {\n \"id\":14,\n \"message\":\"qBittorrent is successfully listening on interface 0.0.0.0 port: TCP/19036\",\n \"timestamp\":1507969128271,\n \"type\":2\n },\n {\n \"id\":15,\n \"message\":\"qBittorrent is successfully listening on interface 0.0.0.0 port: UDP/19036\",\n \"timestamp\":1507969128272,\n \"type\":2\n }\n]\n```", - ), - parameters: Some( - [ - Bool( - TypeInfo { - name: "normal", - is_optional: true, - is_list: false, - description: Some( - "Include normal messages (default: true)", - ), - type_description: None, - }, - ), - Bool( - TypeInfo { - name: "info", - is_optional: true, - is_list: false, - description: Some( - "Include info messages (default: true)", - ), - type_description: None, - }, - ), - Bool( - TypeInfo { - name: "warning", - is_optional: true, - is_list: false, - description: Some( - "Include warning messages (default: true)", - ), - type_description: None, - }, - ), - Bool( - TypeInfo { - name: "critical", - is_optional: true, - is_list: false, - description: Some( - "Include critical messages (default: true)", - ), - type_description: None, - }, - ), - Number( - TypeInfo { - name: "last_known_id", - is_optional: true, - is_list: false, - description: Some( - "Exclude messages with \"message id\" <= last_known_id (default: -1)", - ), - type_description: None, - }, - ), - ], - ), - return_type: Some( - ReturnType { - is_list: true, - parameters: [ - ReturnTypeParameter { - name: "id", - description: "ID of the message", - return_type: Number( - TypeInfo { - name: "id", - is_optional: false, - is_list: false, - description: Some( - "ID of the message", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "message", - description: "Text of the message", - return_type: String( - TypeInfo { - name: "message", - is_optional: false, - is_list: false, - description: Some( - "Text of the message", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "timestamp", - description: "Milliseconds since epoch", - return_type: Number( - TypeInfo { - name: "timestamp", - is_optional: false, - is_list: false, - description: Some( - "Milliseconds since epoch", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "type", - description: "Type of the message: Log::NORMAL: 1, Log::INFO: 2, Log::WARNING: 4, Log::CRITICAL: 8", - return_type: Number( - TypeInfo { - name: "type", - is_optional: false, - is_list: false, - description: Some( - "Type of the message: Log::NORMAL: 1, Log::INFO: 2, Log::WARNING: 4, Log::CRITICAL: 8", - ), - type_description: None, - }, - ), - }, - ], - }, - ), - url: "main", - }, - ApiMethod { - name: "peers", - description: None, - parameters: Some( - [ - Number( - TypeInfo { - name: "last_known_id", - is_optional: true, - is_list: false, - description: Some( - "Exclude messages with \"message id\" <= last_known_id (default: -1)", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "peers", - }, - ], - description: Some( - "All Log API methods are under \"log\", e.g.: `/api/v2/log/methodName`.", - ), - url: "log", - }, - ApiGroup { - name: "sync", - methods: [ - ApiMethod { - name: "maindata", - description: Some( - "Example:\n\n```JSON\n{\n \"rid\":15,\n \"torrents\":\n {\n \"8c212779b4abde7c6bc608063a0d008b7e40ce32\":\n {\n \"state\":\"pausedUP\"\n }\n }\n}\n```", - ), - parameters: Some( - [ - Number( - TypeInfo { - name: "rid", - is_optional: false, - is_list: false, - description: Some( - "Response ID. If not provided, rid=0 will be assumed. If the given rid is different from the one of last server reply, full_update will be true (see the server reply details for more info)", - ), - type_description: None, - }, - ), - ], - ), - return_type: Some( - ReturnType { - is_list: false, - parameters: [ - ReturnTypeParameter { - name: "rid", - description: "Response ID", - return_type: Number( - TypeInfo { - name: "rid", - is_optional: false, - is_list: false, - description: Some( - "Response ID", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "full_update", - description: "Whether the response contains all the data or partial data", - return_type: Bool( - TypeInfo { - name: "full_update", - is_optional: false, - is_list: false, - description: Some( - "Whether the response contains all the data or partial data", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "torrents", - description: "Property: torrent hash, value: same as [torrent list](#get-torrent-list)", - return_type: Object( - TypeInfo { - name: "torrents", - is_optional: false, - is_list: false, - description: Some( - "Property: torrent hash, value: same as [torrent list](#get-torrent-list)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "torrents_removed", - description: "List of hashes of torrents removed since last request", - return_type: StringArray( - TypeInfo { - name: "torrents_removed", - is_optional: false, - is_list: false, - description: Some( - "List of hashes of torrents removed since last request", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "categories", - description: "Info for categories added since last request", - return_type: Object( - TypeInfo { - name: "categories", - is_optional: false, - is_list: false, - description: Some( - "Info for categories added since last request", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "categories_removed", - description: "List of categories removed since last request", - return_type: StringArray( - TypeInfo { - name: "categories_removed", - is_optional: false, - is_list: false, - description: Some( - "List of categories removed since last request", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "tags", - description: "List of tags added since last request", - return_type: StringArray( - TypeInfo { - name: "tags", - is_optional: false, - is_list: false, - description: Some( - "List of tags added since last request", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "tags_removed", - description: "List of tags removed since last request", - return_type: StringArray( - TypeInfo { - name: "tags_removed", - is_optional: false, - is_list: false, - description: Some( - "List of tags removed since last request", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "server_state", - description: "Global transfer info", - return_type: Object( - TypeInfo { - name: "server_state", - is_optional: false, - is_list: false, - description: Some( - "Global transfer info", - ), - type_description: None, - }, - ), - }, - ], - }, - ), - url: "maindata", - }, - ApiMethod { - name: "torrentPeers", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, - is_list: false, - description: Some( - "Torrent hash", - ), - type_description: None, - }, - ), - Number( - TypeInfo { - name: "rid", - is_optional: false, - is_list: false, - description: Some( - "Response ID. If not provided, rid=0 will be assumed. If the given rid is different from the one of last server reply, full_update will be true (see the server reply details for more info)", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "torrentPeers", - }, - ], - description: Some( - "Sync API implements requests for obtaining changes since the last request.\nAll Sync API methods are under \"sync\", e.g.: `/api/v2/sync/methodName`.", - ), - url: "sync", - }, - ApiGroup { - name: "transfer_info", - methods: [ - ApiMethod { - name: "info", - description: Some( - "In addition to the above in partial data requests (see [Get partial data](#get-partial-data) for more info):\n\nPossible values of `connection_status`:\n\nExample:\n\n```JSON\n{\n \"connection_status\":\"connected\",\n \"dht_nodes\":386,\n \"dl_info_data\":681521119,\n \"dl_info_speed\":0,\n \"dl_rate_limit\":0,\n \"up_info_data\":10747904,\n \"up_info_speed\":0,\n \"up_rate_limit\":1048576\n}\n```", - ), - parameters: None, - return_type: Some( - ReturnType { - is_list: false, - parameters: [ - ReturnTypeParameter { - name: "dl_info_speed", - description: "Global download rate (bytes/s)", - return_type: Number( - TypeInfo { - name: "dl_info_speed", - is_optional: false, - is_list: false, - description: Some( - "Global download rate (bytes/s)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dl_info_data", - description: "Data downloaded this session (bytes)", - return_type: Number( - TypeInfo { - name: "dl_info_data", - is_optional: false, - is_list: false, - description: Some( - "Data downloaded this session (bytes)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "up_info_speed", - description: "Global upload rate (bytes/s)", - return_type: Number( - TypeInfo { - name: "up_info_speed", - is_optional: false, - is_list: false, - description: Some( - "Global upload rate (bytes/s)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "up_info_data", - description: "Data uploaded this session (bytes)", - return_type: Number( - TypeInfo { - name: "up_info_data", - is_optional: false, - is_list: false, - description: Some( - "Data uploaded this session (bytes)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dl_rate_limit", - description: "Download rate limit (bytes/s)", - return_type: Number( - TypeInfo { - name: "dl_rate_limit", - is_optional: false, - is_list: false, - description: Some( - "Download rate limit (bytes/s)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "up_rate_limit", - description: "Upload rate limit (bytes/s)", - return_type: Number( - TypeInfo { - name: "up_rate_limit", - is_optional: false, - is_list: false, - description: Some( - "Upload rate limit (bytes/s)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dht_nodes", - description: "DHT nodes connected to", - return_type: Number( - TypeInfo { - name: "dht_nodes", - is_optional: false, - is_list: false, - description: Some( - "DHT nodes connected to", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "connection_status", - description: "Connection status. See possible values here below", - return_type: String( - TypeInfo { - name: "connection_status", - is_optional: false, - is_list: false, - description: Some( - "Connection status. See possible values here below", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "connected", - description: "", - }, - TypeDescriptions { - value: "firewalled", - description: "", - }, - TypeDescriptions { - value: "disconnected", - description: "", - }, - ], - }, - ), - }, - ), - }, - ], - }, - ), - url: "info", - }, - ApiMethod { - name: "speedLimitsMode", - description: None, - parameters: None, - return_type: None, - url: "speedLimitsMode", - }, - ApiMethod { - name: "toggleSpeedLimitsMode", - description: None, - parameters: None, - return_type: None, - url: "toggleSpeedLimitsMode", - }, - ApiMethod { - name: "downloadLimit", - description: None, - parameters: None, - return_type: None, - url: "downloadLimit", - }, - ApiMethod { - name: "setDownloadLimit", - description: None, - parameters: Some( - [ - Number( - TypeInfo { - name: "limit", - is_optional: false, - is_list: false, - description: Some( - "The global download speed limit to set in bytes/second", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "setDownloadLimit", - }, - ApiMethod { - name: "uploadLimit", - description: None, - parameters: None, - return_type: None, - url: "uploadLimit", - }, - ApiMethod { - name: "setUploadLimit", - description: None, - parameters: Some( - [ - Number( - TypeInfo { - name: "limit", - is_optional: false, - is_list: false, - description: Some( - "The global upload speed limit to set in bytes/second", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "setUploadLimit", - }, - ApiMethod { - name: "banPeers", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "peers", - is_optional: false, - is_list: false, - description: Some( - "The peer to ban, or multiple peers separated by a pipe \\", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "banPeers", - }, - ], - description: Some( - "All Transfer info API methods are under \"transfer\", e.g.: `/api/v2/transfer/methodName`.", - ), - url: "transfer", - }, - ApiGroup { - name: "torrent_management", - methods: [ - ApiMethod { - name: "info", - description: Some( - "Possible values of `state`:\n\nExample:\n\n```JSON\n[\n {\n \"dlspeed\":9681262,\n \"eta\":87,\n \"f_l_piece_prio\":false,\n \"force_start\":false,\n \"hash\":\"8c212779b4abde7c6bc608063a0d008b7e40ce32\",\n \"category\":\"\",\n \"tags\": \"\",\n \"name\":\"debian-8.1.0-amd64-CD-1.iso\",\n \"num_complete\":-1,\n \"num_incomplete\":-1,\n \"num_leechs\":2,\n \"num_seeds\":54,\n \"priority\":1,\n \"progress\":0.16108787059783936,\n \"ratio\":0,\n \"seq_dl\":false,\n \"size\":657457152,\n \"state\":\"downloading\",\n \"super_seeding\":false,\n \"upspeed\":0\n },\n {\n another_torrent_info\n }\n]\n```", - ), - parameters: Some( - [ - String( - TypeInfo { - name: "filter", - is_optional: true, - is_list: false, - description: Some( - "Filter torrent list by state. Allowed state filters: all, downloading, seeding, completed, paused, active, inactive, resumed, stalled, stalled_uploading, stalled_downloading, errored", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "category", - is_optional: true, - is_list: false, - description: Some( - "Get torrents with the given category (empty string means \"without category\"; no \"category\" parameter means \"any category\" <- broken until [#11748](https://github.com/qbittorrent/qBittorrent/issues/11748) is resolved). Remember to URL-encode the category name. For example, My category becomes My%20category", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "tag", - is_optional: true, - is_list: false, - description: Some( - "Get torrents with the given tag (empty string means \"without tag\"; no \"tag\" parameter means \"any tag\". Remember to URL-encode the category name. For example, My tag becomes My%20tag", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "sort", - is_optional: true, - is_list: false, - description: Some( - "Sort torrents by given key. They can be sorted using any field of the response's JSON array (which are documented below) as the sort key.", - ), - type_description: None, - }, - ), - Bool( - TypeInfo { - name: "reverse", - is_optional: true, - is_list: false, - description: Some( - "Enable reverse sorting. Defaults to false", - ), - type_description: None, - }, - ), - Number( - TypeInfo { - name: "limit", - is_optional: true, - is_list: false, - description: Some( - "Limit the number of torrents returned", - ), - type_description: None, - }, - ), - Number( - TypeInfo { - name: "offset", - is_optional: true, - is_list: false, - description: Some( - "Set offset (if less than 0, offset from end)", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "hashes", - is_optional: true, - is_list: false, - description: Some( - "Filter by hashes. Can contain multiple hashes separated by \\", - ), - type_description: None, - }, - ), - ], - ), - return_type: Some( - ReturnType { - is_list: true, - parameters: [ - ReturnTypeParameter { - name: "added_on", - description: "Time (Unix Epoch) when the torrent was added to the client", - return_type: Number( - TypeInfo { - name: "added_on", - is_optional: false, - is_list: false, - description: Some( - "Time (Unix Epoch) when the torrent was added to the client", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "amount_left", - description: "Amount of data left to download (bytes)", - return_type: Number( - TypeInfo { - name: "amount_left", - is_optional: false, - is_list: false, - description: Some( - "Amount of data left to download (bytes)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "auto_tmm", - description: "Whether this torrent is managed by Automatic Torrent Management", - return_type: Bool( - TypeInfo { - name: "auto_tmm", - is_optional: false, - is_list: false, - description: Some( - "Whether this torrent is managed by Automatic Torrent Management", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "availability", - description: "Percentage of file pieces currently available", - return_type: Float( - TypeInfo { - name: "availability", - is_optional: false, - is_list: false, - description: Some( - "Percentage of file pieces currently available", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "category", - description: "Category of the torrent", - return_type: String( - TypeInfo { - name: "category", - is_optional: false, - is_list: false, - description: Some( - "Category of the torrent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "completed", - description: "Amount of transfer data completed (bytes)", - return_type: Number( - TypeInfo { - name: "completed", - is_optional: false, - is_list: false, - description: Some( - "Amount of transfer data completed (bytes)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "completion_on", - description: "Time (Unix Epoch) when the torrent completed", - return_type: Number( - TypeInfo { - name: "completion_on", - is_optional: false, - is_list: false, - description: Some( - "Time (Unix Epoch) when the torrent completed", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "content_path", - description: "Absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents)", - return_type: String( - TypeInfo { - name: "content_path", - is_optional: false, - is_list: false, - description: Some( - "Absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dl_limit", - description: "Torrent download speed limit (bytes/s). -1 if ulimited.", - return_type: Number( - TypeInfo { - name: "dl_limit", - is_optional: false, - is_list: false, - description: Some( - "Torrent download speed limit (bytes/s). -1 if ulimited.", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "dlspeed", - description: "Torrent download speed (bytes/s)", - return_type: Number( - TypeInfo { - name: "dlspeed", - is_optional: false, - is_list: false, - description: Some( - "Torrent download speed (bytes/s)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "downloaded", - description: "Amount of data downloaded", - return_type: Number( - TypeInfo { - name: "downloaded", - is_optional: false, - is_list: false, - description: Some( - "Amount of data downloaded", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "downloaded_session", - description: "Amount of data downloaded this session", - return_type: Number( - TypeInfo { - name: "downloaded_session", - is_optional: false, - is_list: false, - description: Some( - "Amount of data downloaded this session", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "eta", - description: "Torrent ETA (seconds)", - return_type: Number( - TypeInfo { - name: "eta", - is_optional: false, - is_list: false, - description: Some( - "Torrent ETA (seconds)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "f_l_piece_prio", - description: "True if first last piece are prioritized", - return_type: Bool( - TypeInfo { - name: "f_l_piece_prio", - is_optional: false, - is_list: false, - description: Some( - "True if first last piece are prioritized", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "force_start", - description: "True if force start is enabled for this torrent", - return_type: Bool( - TypeInfo { - name: "force_start", - is_optional: false, - is_list: false, - description: Some( - "True if force start is enabled for this torrent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "hash", - description: "Torrent hash", - return_type: String( - TypeInfo { - name: "hash", - is_optional: false, - is_list: false, - description: Some( - "Torrent hash", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "last_activity", - description: "Last time (Unix Epoch) when a chunk was downloaded/uploaded", - return_type: Number( - TypeInfo { - name: "last_activity", - is_optional: false, - is_list: false, - description: Some( - "Last time (Unix Epoch) when a chunk was downloaded/uploaded", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "magnet_uri", - description: "Magnet URI corresponding to this torrent", - return_type: String( - TypeInfo { - name: "magnet_uri", - is_optional: false, - is_list: false, - description: Some( - "Magnet URI corresponding to this torrent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_ratio", - description: "Maximum share ratio until torrent is stopped from seeding/uploading", - return_type: Float( - TypeInfo { - name: "max_ratio", - is_optional: false, - is_list: false, - description: Some( - "Maximum share ratio until torrent is stopped from seeding/uploading", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "max_seeding_time", - description: "Maximum seeding time (seconds) until torrent is stopped from seeding", - return_type: Number( - TypeInfo { - name: "max_seeding_time", - is_optional: false, - is_list: false, - description: Some( - "Maximum seeding time (seconds) until torrent is stopped from seeding", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "name", - description: "Torrent name", - return_type: String( - TypeInfo { - name: "name", - is_optional: false, - is_list: false, - description: Some( - "Torrent name", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "num_complete", - description: "Number of seeds in the swarm", - return_type: Number( - TypeInfo { - name: "num_complete", - is_optional: false, - is_list: false, - description: Some( - "Number of seeds in the swarm", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "num_incomplete", - description: "Number of leechers in the swarm", - return_type: Number( - TypeInfo { - name: "num_incomplete", - is_optional: false, - is_list: false, - description: Some( - "Number of leechers in the swarm", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "num_leechs", - description: "Number of leechers connected to", - return_type: Number( - TypeInfo { - name: "num_leechs", - is_optional: false, - is_list: false, - description: Some( - "Number of leechers connected to", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "num_seeds", - description: "Number of seeds connected to", - return_type: Number( - TypeInfo { - name: "num_seeds", - is_optional: false, - is_list: false, - description: Some( - "Number of seeds connected to", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "priority", - description: "Torrent priority. Returns -1 if queuing is disabled or torrent is in seed mode", - return_type: Number( - TypeInfo { - name: "priority", - is_optional: false, - is_list: false, - description: Some( - "Torrent priority. Returns -1 if queuing is disabled or torrent is in seed mode", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "progress", - description: "Torrent progress (percentage/100)", - return_type: Float( - TypeInfo { - name: "progress", - is_optional: false, - is_list: false, - description: Some( - "Torrent progress (percentage/100)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "ratio", - description: "Torrent share ratio. Max ratio value: 9999.", - return_type: Float( - TypeInfo { - name: "ratio", - is_optional: false, - is_list: false, - description: Some( - "Torrent share ratio. Max ratio value: 9999.", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "ratio_limit", - description: "TODO (what is different from max_ratio?)", - return_type: Float( - TypeInfo { - name: "ratio_limit", - is_optional: false, - is_list: false, - description: Some( - "TODO (what is different from max_ratio?)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "save_path", - description: "Path where this torrent's data is stored", - return_type: String( - TypeInfo { - name: "save_path", - is_optional: false, - is_list: false, - description: Some( - "Path where this torrent's data is stored", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "seeding_time", - description: "Torrent elapsed time while complete (seconds)", - return_type: Number( - TypeInfo { - name: "seeding_time", - is_optional: false, - is_list: false, - description: Some( - "Torrent elapsed time while complete (seconds)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "seeding_time_limit", - description: "TODO (what is different from max_seeding_time?) seeding_time_limit is a per torrent setting, when Automatic Torrent Management is disabled, furthermore then max_seeding_time is set to seeding_time_limit for this torrent. If Automatic Torrent Management is enabled, the value is -2. And if max_seeding_time is unset it have a default value -1.", - return_type: Number( - TypeInfo { - name: "seeding_time_limit", - is_optional: false, - is_list: false, - description: Some( - "TODO (what is different from max_seeding_time?) seeding_time_limit is a per torrent setting, when Automatic Torrent Management is disabled, furthermore then max_seeding_time is set to seeding_time_limit for this torrent. If Automatic Torrent Management is enabled, the value is -2. And if max_seeding_time is unset it have a default value -1.", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "seen_complete", - description: "Time (Unix Epoch) when this torrent was last seen complete", - return_type: Number( - TypeInfo { - name: "seen_complete", - is_optional: false, - is_list: false, - description: Some( - "Time (Unix Epoch) when this torrent was last seen complete", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "seq_dl", - description: "True if sequential download is enabled", - return_type: Bool( - TypeInfo { - name: "seq_dl", - is_optional: false, - is_list: false, - description: Some( - "True if sequential download is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "size", - description: "Total size (bytes) of files selected for download", - return_type: Number( - TypeInfo { - name: "size", - is_optional: false, - is_list: false, - description: Some( - "Total size (bytes) of files selected for download", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "state", - description: "Torrent state. See table here below for the possible values", - return_type: String( - TypeInfo { - name: "state", - is_optional: false, - is_list: false, - description: Some( - "Torrent state. See table here below for the possible values", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "error", - description: "Some error occurred, applies to paused torrents", - }, - TypeDescriptions { - value: "missingFiles", - description: "Torrent data files is missing", - }, - TypeDescriptions { - value: "uploading", - description: "Torrent is being seeded and data is being transferred", - }, - TypeDescriptions { - value: "pausedUP", - description: "Torrent is paused and has finished downloading", - }, - TypeDescriptions { - value: "queuedUP", - description: "Queuing is enabled and torrent is queued for upload", - }, - TypeDescriptions { - value: "stalledUP", - description: "Torrent is being seeded, but no connection were made", - }, - TypeDescriptions { - value: "checkingUP", - description: "Torrent has finished downloading and is being checked", - }, - TypeDescriptions { - value: "forcedUP", - description: "Torrent is forced to uploading and ignore queue limit", - }, - TypeDescriptions { - value: "allocating", - description: "Torrent is allocating disk space for download", - }, - TypeDescriptions { - value: "downloading", - description: "Torrent is being downloaded and data is being transferred", - }, - TypeDescriptions { - value: "metaDL", - description: "Torrent has just started downloading and is fetching metadata", - }, - TypeDescriptions { - value: "pausedDL", - description: "Torrent is paused and has NOT finished downloading", - }, - TypeDescriptions { - value: "queuedDL", - description: "Queuing is enabled and torrent is queued for download", - }, - TypeDescriptions { - value: "stalledDL", - description: "Torrent is being downloaded, but no connection were made", - }, - TypeDescriptions { - value: "checkingDL", - description: "Same as checkingUP, but torrent has NOT finished downloading", - }, - TypeDescriptions { - value: "forcedDL", - description: "Torrent is forced to downloading to ignore queue limit", - }, - TypeDescriptions { - value: "checkingResumeData", - description: "Checking resume data on qBt startup", - }, - TypeDescriptions { - value: "moving", - description: "Torrent is moving to another location", - }, - TypeDescriptions { - value: "unknown", - description: "Unknown status", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "super_seeding", - description: "True if super seeding is enabled", - return_type: Bool( - TypeInfo { - name: "super_seeding", - is_optional: false, - is_list: false, - description: Some( - "True if super seeding is enabled", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "tags", - description: "Comma-concatenated tag list of the torrent", - return_type: String( - TypeInfo { - name: "tags", - is_optional: false, - is_list: false, - description: Some( - "Comma-concatenated tag list of the torrent", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "time_active", - description: "Total active time (seconds)", - return_type: Number( - TypeInfo { - name: "time_active", - is_optional: false, - is_list: false, - description: Some( - "Total active time (seconds)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "total_size", - description: "Total size (bytes) of all file in this torrent (including unselected ones)", - return_type: Number( - TypeInfo { - name: "total_size", - is_optional: false, - is_list: false, - description: Some( - "Total size (bytes) of all file in this torrent (including unselected ones)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "tracker", - description: "The first tracker with working status. Returns empty string if no tracker is working.", - return_type: String( - TypeInfo { - name: "tracker", - is_optional: false, - is_list: false, - description: Some( - "The first tracker with working status. Returns empty string if no tracker is working.", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "up_limit", - description: "Torrent upload speed limit (bytes/s). -1 if ulimited.", - return_type: Number( - TypeInfo { - name: "up_limit", - is_optional: false, - is_list: false, - description: Some( - "Torrent upload speed limit (bytes/s). -1 if ulimited.", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "uploaded", - description: "Amount of data uploaded", - return_type: Number( - TypeInfo { - name: "uploaded", - is_optional: false, - is_list: false, - description: Some( - "Amount of data uploaded", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "uploaded_session", - description: "Amount of data uploaded this session", - return_type: Number( - TypeInfo { - name: "uploaded_session", - is_optional: false, - is_list: false, - description: Some( - "Amount of data uploaded this session", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "upspeed", - description: "Torrent upload speed (bytes/s)", - return_type: Number( - TypeInfo { - name: "upspeed", - is_optional: false, - is_list: false, - description: Some( - "Torrent upload speed (bytes/s)", - ), - type_description: None, - }, - ), - }, - ], - }, - ), - url: "info", - }, - ApiMethod { - name: "properties", - description: Some( - "- empty, if the torrent hash is invalid\n- otherwise, a JSON object with the following fields\n\nNB: `-1` is returned if the type of the property is integer but its value is not known.\n\nExample:\n\n```JSON\n{\n \"addition_date\":1438429165,\n \"comment\":\"\\\"Debian CD from cdimage.debian.org\\\"\",\n \"completion_date\":1438429234,\n \"created_by\":\"\",\n \"creation_date\":1433605214,\n \"dl_limit\":-1,\n \"dl_speed\":0,\n \"dl_speed_avg\":9736015,\n \"eta\":8640000,\n \"last_seen\":1438430354,\n \"nb_connections\":3,\n \"nb_connections_limit\":250,\n \"peers\":1,\n \"peers_total\":89,\n \"piece_size\":524288,\n \"pieces_have\":1254,\n \"pieces_num\":1254,\n \"reannounce\":672,\n \"save_path\":\"/Downloads/debian-8.1.0-amd64-CD-1.iso\",\n \"seeding_time\":1128,\n \"seeds\":1,\n \"seeds_total\":254,\n \"share_ratio\":0.00072121022562178299,\n \"time_elapsed\":1197,\n \"total_downloaded\":681521119,\n \"total_downloaded_session\":681521119,\n \"total_size\":657457152,\n \"total_uploaded\":491520,\n \"total_uploaded_session\":491520,\n \"total_wasted\":23481724,\n \"up_limit\":-1,\n \"up_speed\":0,\n \"up_speed_avg\":410\n}\n```", - ), - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, - is_list: false, - description: Some( - "The hash of the torrent you want to get the generic properties of", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "properties", - }, - ApiMethod { - name: "trackers", - description: Some( - "Possible values of `status`:\n\nExample:\n\n```JSON\n[\n {\n \"msg\":\"\",\n \"num_peers\":100,\n \"status\":2,\n \"url\":\"http://bttracker.debian.org:6969/announce\"\n },\n {\n another_tracker_info\n }\n]\n```", - ), - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, - is_list: false, - description: Some( - "The hash of the torrent you want to get the trackers of", - ), - type_description: None, - }, - ), - ], - ), - return_type: Some( - ReturnType { - is_list: true, - parameters: [ - ReturnTypeParameter { - name: "url", - description: "Tracker url", - return_type: String( - TypeInfo { - name: "url", - is_optional: false, - is_list: false, - description: Some( - "Tracker url", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "status", - description: "Tracker status. See the table below for possible values", - return_type: Number( - TypeInfo { - name: "status", - is_optional: false, - is_list: false, - description: Some( - "Tracker status. See the table below for possible values", - ), - type_description: Some( - TypeDescription { - values: [ - TypeDescriptions { - value: "0", - description: "Tracker is disabled (used for DHT, PeX, and LSD)", - }, - TypeDescriptions { - value: "1", - description: "Tracker has not been contacted yet", - }, - TypeDescriptions { - value: "2", - description: "Tracker has been contacted and is working", - }, - TypeDescriptions { - value: "3", - description: "Tracker is updating", - }, - TypeDescriptions { - value: "4", - description: "Tracker has been contacted, but it is not working (or doesn't send proper replies)", - }, - ], - }, - ), - }, - ), - }, - ReturnTypeParameter { - name: "tier", - description: "Tracker priority tier. Lower tier trackers are tried before higher tiers. Tier numbers are valid when >= 0, < 0 is used as placeholder when tier does not exist for special entries (such as DHT).", - return_type: Number( - TypeInfo { - name: "tier", - is_optional: false, - is_list: false, - description: Some( - "Tracker priority tier. Lower tier trackers are tried before higher tiers. Tier numbers are valid when >= 0, < 0 is used as placeholder when tier does not exist for special entries (such as DHT).", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "num_peers", - description: "Number of peers for current torrent, as reported by the tracker", - return_type: Number( - TypeInfo { - name: "num_peers", - is_optional: false, - is_list: false, - description: Some( - "Number of peers for current torrent, as reported by the tracker", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "num_seeds", - description: "Number of seeds for current torrent, asreported by the tracker", - return_type: Number( - TypeInfo { - name: "num_seeds", - is_optional: false, - is_list: false, - description: Some( - "Number of seeds for current torrent, asreported by the tracker", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "num_leeches", - description: "Number of leeches for current torrent, as reported by the tracker", - return_type: Number( - TypeInfo { - name: "num_leeches", - is_optional: false, - is_list: false, - description: Some( - "Number of leeches for current torrent, as reported by the tracker", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "num_downloaded", - description: "Number of completed downlods for current torrent, as reported by the tracker", - return_type: Number( - TypeInfo { - name: "num_downloaded", - is_optional: false, - is_list: false, - description: Some( - "Number of completed downlods for current torrent, as reported by the tracker", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "msg", - description: "Tracker message (there is no way of knowing what this message is - it's up to tracker admins)", - return_type: String( - TypeInfo { - name: "msg", - is_optional: false, - is_list: false, - description: Some( - "Tracker message (there is no way of knowing what this message is - it's up to tracker admins)", - ), - type_description: None, - }, - ), - }, - ], - }, - ), - url: "trackers", - }, - ApiMethod { - name: "webseeds", - description: Some( - "Example:\n\n```JSON\n[\n {\n \"url\":\"http://some_url/\"\n },\n {\n \"url\":\"http://some_other_url/\"\n }\n]\n```", - ), - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, - is_list: false, - description: Some( - "The hash of the torrent you want to get the webseeds of", - ), - type_description: None, - }, - ), - ], - ), - return_type: Some( - ReturnType { - is_list: true, - parameters: [ - ReturnTypeParameter { - name: "url", - description: "URL of the web seed", - return_type: String( - TypeInfo { - name: "url", - is_optional: false, - is_list: false, - description: Some( - "URL of the web seed", - ), - type_description: None, - }, - ), - }, - ], - }, - ), - url: "webseeds", - }, - ApiMethod { - name: "files", - description: Some( - "- empty, if the torrent hash is invalid\n- otherwise, a JSON array, where each element contains info about one file, with the following fields\n\nPossible values of `priority`:\n\nExample:\n\n```JSON\n\n[\n {\n \"index\":0,\n \"is_seed\":false,\n \"name\":\"debian-8.1.0-amd64-CD-1.iso\",\n \"piece_range\":[0,1253],\n \"priority\":1,\n \"progress\":0,\n \"size\":657457152,\n \"availability\":0.5,\n }\n]\n```", - ), - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, - is_list: false, - description: Some( - "The hash of the torrent you want to get the contents of", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "indexes", - is_optional: true, - is_list: false, - description: Some( - "The indexes of the files you want to retrieve. indexes can contain multiple values separated by \\", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "files", - }, - ApiMethod { - name: "pieceStates", - description: Some( - "- empty, if the torrent hash is invalid\n- otherwise, an array of states (integers) of all pieces (in order) of a specific torrent.\n\nValue meanings are defined as below:\n\nExample:\n\n```JSON\n[0,0,2,1,0,0,2,1]\n```", - ), - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, - is_list: false, - description: Some( - "The hash of the torrent you want to get the pieces' states of", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "pieceStates", - }, - ApiMethod { - name: "pieceHashes", - description: Some( - "- empty, if the torrent hash is invalid\n- otherwise, an array of hashes (strings) of all pieces (in order) of a specific torrent.\n\nExample:\n\n```JSON\n[\"54eddd830a5b58480a6143d616a97e3a6c23c439\",\"f8a99d225aa4241db100f88407fc3bdaead583ab\",\"928fb615b9bd4dd8f9e9022552c8f8f37ef76f58\"]\n```", - ), - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, - is_list: false, - description: Some( - "The hash of the torrent you want to get the pieces' hashes of", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "pieceHashes", - }, - ApiMethod { - name: "pause", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, - is_list: false, - description: Some( - "The hashes of the torrents you want to pause. hashes can contain multiple hashes separated by \\", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "pause", - }, - ApiMethod { - name: "resume", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, - is_list: false, - description: Some( - "The hashes of the torrents you want to resume. hashes can contain multiple hashes separated by \\", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "resume", - }, - ApiMethod { - name: "delete", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, - is_list: false, - description: Some( - "The hashes of the torrents you want to delete. hashes can contain multiple hashes separated by \\", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "delete", - }, - ApiMethod { - name: "recheck", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, - is_list: false, - description: Some( - "The hashes of the torrents you want to recheck. hashes can contain multiple hashes separated by \\", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "recheck", - }, - ApiMethod { - name: "reannounce", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, - is_list: false, - description: Some( - "The hashes of the torrents you want to reannounce. hashes can contain multiple hashes separated by \\", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "reannounce", - }, - ApiMethod { - name: "add", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "urls", - is_optional: false, - is_list: false, - description: Some( - "URLs separated with newlines", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "savepath", - is_optional: true, - is_list: false, - description: Some( - "Download folder", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "cookie", - is_optional: true, - is_list: false, - description: Some( - "Cookie sent to download the .torrent file", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "category", - is_optional: true, - is_list: false, - description: Some( - "Category for the torrent", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "tags", - is_optional: true, - is_list: false, - description: Some( - "Tags for the torrent, split by ','", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "skip_checking", - is_optional: true, - is_list: false, - description: Some( - "Skip hash checking. Possible values are true, false (default)", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "paused", - is_optional: true, - is_list: false, - description: Some( - "Add torrents in the paused state. Possible values are true, false (default)", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "root_folder", - is_optional: true, - is_list: false, - description: Some( - "Create the root folder. Possible values are true, false, unset (default)", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "rename", - is_optional: true, - is_list: false, - description: Some( - "Rename torrent", - ), - type_description: None, - }, - ), - Number( - TypeInfo { - name: "upLimit", - is_optional: true, - is_list: false, - description: Some( - "Set torrent upload speed limit. Unit in bytes/second", - ), - type_description: None, - }, - ), - Number( - TypeInfo { - name: "dlLimit", - is_optional: true, - is_list: false, - description: Some( - "Set torrent download speed limit. Unit in bytes/second", - ), - type_description: None, - }, - ), - Float( - TypeInfo { - name: "ratioLimit", - is_optional: true, - is_list: false, - description: Some( - "Set torrent share ratio limit", - ), - type_description: None, - }, - ), - Number( - TypeInfo { - name: "seedingTimeLimit", - is_optional: true, - is_list: false, - description: Some( - "Set torrent seeding time limit. Unit in seconds", - ), - type_description: None, - }, - ), - Bool( - TypeInfo { - name: "autoTMM", - is_optional: true, - is_list: false, - description: Some( - "Whether Automatic Torrent Management should be used", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "sequentialDownload", - is_optional: true, - is_list: false, - description: Some( - "Enable sequential download. Possible values are true, false (default)", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "firstLastPiecePrio", - is_optional: true, - is_list: false, - description: Some( - "Prioritize download first last piece. Possible values are true, false (default)", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "add", - }, - ApiMethod { - name: "addTrackers", - description: None, - parameters: None, - return_type: None, - url: "addTrackers", - }, - ApiMethod { - name: "editTracker", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, - is_list: false, - description: Some( - "The hash of the torrent", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "origUrl", - is_optional: false, - is_list: false, - description: Some( - "The tracker URL you want to edit", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "newUrl", - is_optional: false, - is_list: false, - description: Some( - "The new URL to replace the origUrl", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "editTracker", - }, - ApiMethod { - name: "removeTrackers", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, - is_list: false, - description: Some( - "The hash of the torrent", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "urls", - is_optional: false, - is_list: false, - description: Some( - "URLs to remove, separated by \\", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "removeTrackers", - }, - ApiMethod { - name: "addPeers", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, - is_list: false, - description: Some( - "The hash of the torrent, or multiple hashes separated by a pipe \\", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "peers", - is_optional: false, - is_list: false, - description: Some( - "The peer to add, or multiple peers separated by a pipe \\", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "addPeers", - }, - ApiMethod { - name: "increasePrio", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, - is_list: false, - description: Some( - "The hashes of the torrents you want to increase the priority of. hashes can contain multiple hashes separated by \\", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "increasePrio", - }, - ApiMethod { - name: "decreasePrio", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, - is_list: false, - description: Some( - "The hashes of the torrents you want to decrease the priority of. hashes can contain multiple hashes separated by \\", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "decreasePrio", - }, - ApiMethod { - name: "topPrio", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, - is_list: false, - description: Some( - "The hashes of the torrents you want to set to the maximum priority. hashes can contain multiple hashes separated by \\", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "topPrio", - }, - ApiMethod { - name: "bottomPrio", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, - is_list: false, - description: Some( - "The hashes of the torrents you want to set to the minimum priority. hashes can contain multiple hashes separated by \\", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "bottomPrio", - }, - ApiMethod { - name: "filePrio", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, - is_list: false, - description: Some( - "The hash of the torrent", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "id", - is_optional: false, - is_list: false, - description: Some( - "File ids, separated by \\", - ), - type_description: None, - }, - ), - Number( - TypeInfo { - name: "priority", - is_optional: false, - is_list: false, - description: Some( - "File priority to set (consult [torrent contents API](#get-torrent-contents) for possible values)", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "filePrio", - }, - ApiMethod { - name: "downloadLimit", - description: None, - parameters: None, - return_type: None, - url: "downloadLimit", - }, - ApiMethod { - name: "setShareLimits", - description: None, - parameters: None, - return_type: None, - url: "setShareLimits", - }, - ApiMethod { - name: "uploadLimit", - description: None, - parameters: None, - return_type: None, - url: "uploadLimit", - }, - ApiMethod { - name: "setUploadLimit", - description: None, - parameters: None, - return_type: None, - url: "setUploadLimit", - }, - ApiMethod { - name: "setLocation", - description: None, - parameters: None, - return_type: None, - url: "setLocation", - }, - ApiMethod { - name: "rename", - description: None, - parameters: None, - return_type: None, - url: "rename", - }, - ApiMethod { - name: "setCategory", - description: None, - parameters: None, - return_type: None, - url: "setCategory", - }, - ApiMethod { - name: "categories", - description: None, - parameters: None, - return_type: None, - url: "categories", - }, - ApiMethod { - name: "createCategory", - description: None, - parameters: None, - return_type: None, - url: "createCategory", - }, - ApiMethod { - name: "editCategory", - description: None, - parameters: None, - return_type: None, - url: "editCategory", - }, - ApiMethod { - name: "removeCategories", - description: None, - parameters: None, - return_type: None, - url: "removeCategories", - }, - ApiMethod { - name: "addTags", - description: None, - parameters: None, - return_type: None, - url: "addTags", - }, - ApiMethod { - name: "removeTags", - description: None, - parameters: None, - return_type: None, - url: "removeTags", - }, - ApiMethod { - name: "tags", - description: None, - parameters: None, - return_type: None, - url: "tags", - }, - ApiMethod { - name: "createTags", - description: None, - parameters: None, - return_type: None, - url: "createTags", - }, - ApiMethod { - name: "deleteTags", - description: None, - parameters: None, - return_type: None, - url: "deleteTags", - }, - ApiMethod { - name: "setAutoManagement", - description: None, - parameters: None, - return_type: None, - url: "setAutoManagement", - }, - ApiMethod { - name: "toggleSequentialDownload", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, - is_list: false, - description: Some( - "The hashes of the torrents you want to toggle sequential download for. hashes can contain multiple hashes separated by \\", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "toggleSequentialDownload", - }, - ApiMethod { - name: "toggleFirstLastPiecePrio", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hashes", - is_optional: false, - is_list: false, - description: Some( - "The hashes of the torrents you want to toggle the first/last piece priority for. hashes can contain multiple hashes separated by \\", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "toggleFirstLastPiecePrio", - }, - ApiMethod { - name: "setForceStart", - description: None, - parameters: None, - return_type: None, - url: "setForceStart", - }, - ApiMethod { - name: "setSuperSeeding", - description: None, - parameters: None, - return_type: None, - url: "setSuperSeeding", - }, - ApiMethod { - name: "renameFile", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, - is_list: false, - description: Some( - "The hash of the torrent", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "oldPath", - is_optional: false, - is_list: false, - description: Some( - "The old path of the torrent", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "newPath", - is_optional: false, - is_list: false, - description: Some( - "The new path to use for the file", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "renameFile", - }, - ApiMethod { - name: "renameFolder", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "hash", - is_optional: false, - is_list: false, - description: Some( - "The hash of the torrent", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "oldPath", - is_optional: false, - is_list: false, - description: Some( - "The old path of the torrent", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "newPath", - is_optional: false, - is_list: false, - description: Some( - "The new path to use for the file", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "renameFolder", - }, - ], - description: Some( - "All Torrent management API methods are under \"torrents\", e.g.: `/api/v2/torrents/methodName`.", - ), - url: "torrents", - }, - ApiGroup { - name: "rss", - methods: [ - ApiMethod { - name: "addFolder", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "path", - is_optional: false, - is_list: false, - description: Some( - "Full path of added folder (e.g. \"The Pirate Bay\\Top100\")", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "addFolder", - }, - ApiMethod { - name: "addFeed", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "url", - is_optional: false, - is_list: false, - description: Some( - "URL of RSS feed (e.g. \"[http://thepiratebay.org/rss//top100/200](http://thepiratebay.org/rss//top100/200)\")", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "path", - is_optional: true, - is_list: false, - description: Some( - "Full path of added folder (e.g. \"The Pirate Bay\\Top100\\Video\")", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "addFeed", - }, - ApiMethod { - name: "removeItem", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "path", - is_optional: false, - is_list: false, - description: Some( - "Full path of removed item (e.g. \"The Pirate Bay\\Top100\")", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "removeItem", - }, - ApiMethod { - name: "moveItem", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "itemPath", - is_optional: false, - is_list: false, - description: Some( - "Current full path of item (e.g. \"The Pirate Bay\\Top100\")", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "destPath", - is_optional: false, - is_list: false, - description: Some( - "New full path of item (e.g. \"The Pirate Bay\")", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "moveItem", - }, - ApiMethod { - name: "items", - description: None, - parameters: Some( - [ - Bool( - TypeInfo { - name: "withData", - is_optional: true, - is_list: false, - description: Some( - "True if you need current feed articles", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "items", - }, - ApiMethod { - name: "markAsRead", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "itemPath", - is_optional: false, - is_list: false, - description: Some( - "Current full path of item (e.g. \"The Pirate Bay\\Top100\")", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "articleId", - is_optional: true, - is_list: false, - description: Some( - "ID of article", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "markAsRead", - }, - ApiMethod { - name: "refreshItem", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "itemPath", - is_optional: false, - is_list: false, - description: Some( - "Current full path of item (e.g. \"The Pirate Bay\\Top100\")", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "refreshItem", - }, - ApiMethod { - name: "setRule", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "ruleName", - is_optional: false, - is_list: false, - description: Some( - "Rule name (e.g. \"Punisher\")", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "ruleDef", - is_optional: false, - is_list: false, - description: Some( - "JSON encoded rule definition", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "setRule", - }, - ApiMethod { - name: "renameRule", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "ruleName", - is_optional: false, - is_list: false, - description: Some( - "Rule name (e.g. \"Punisher\")", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "newRuleName", - is_optional: false, - is_list: false, - description: Some( - "New rule name (e.g. \"The Punisher\")", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "renameRule", - }, - ApiMethod { - name: "removeRule", - description: None, - parameters: Some( - [ - String( - TypeInfo { - name: "ruleName", - is_optional: false, - is_list: false, - description: Some( - "Rule name (e.g. \"Punisher\")", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "removeRule", - }, - ApiMethod { - name: "rules", - description: None, - parameters: None, - return_type: None, - url: "rules", - }, - ApiMethod { - name: "matchingArticles", - description: None, - parameters: None, - return_type: None, - url: "matchingArticles", - }, - ], - description: Some( - "All RSS API methods are under \"rss\", e.g.: `/api/v2/rss/methodName`.", - ), - url: "rss", - }, - ApiGroup { - name: "search", - methods: [ - ApiMethod { - name: "start", - description: Some( - "Example:\n\n```JSON\n{\n \"id\": 12345\n}\n```", - ), - parameters: Some( - [ - String( - TypeInfo { - name: "pattern", - is_optional: false, - is_list: false, - description: Some( - "Pattern to search for (e.g. \"Ubuntu 18.04\")", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "plugins", - is_optional: false, - is_list: false, - description: Some( - "Plugins to use for searching (e.g. \"legittorrents\"). Supports multiple plugins separated by \\", - ), - type_description: None, - }, - ), - String( - TypeInfo { - name: "category", - is_optional: false, - is_list: false, - description: Some( - "Categories to limit your search to (e.g. \"legittorrents\"). Available categories depend on the specified plugins. Also supports all", - ), - type_description: None, - }, - ), - ], - ), - return_type: Some( - ReturnType { - is_list: false, - parameters: [ - ReturnTypeParameter { - name: "id", - description: "ID of the search job", - return_type: Number( - TypeInfo { - name: "id", - is_optional: false, - is_list: false, - description: Some( - "ID of the search job", - ), - type_description: None, - }, - ), - }, - ], - }, - ), - url: "start", - }, - ApiMethod { - name: "stop", - description: None, - parameters: Some( - [ - Number( - TypeInfo { - name: "id", - is_optional: false, - is_list: false, - description: Some( - "ID of the search job", - ), - type_description: None, - }, - ), - ], - ), - return_type: None, - url: "stop", - }, - ApiMethod { - name: "status", - description: Some( - "Example:\n\n```JSON\n[\n {\n \"id\": 12345,\n \"status\": \"Running\",\n \"total\": 170\n }\n]\n```", - ), - parameters: Some( - [ - Number( - TypeInfo { - name: "id", - is_optional: true, - is_list: false, - description: Some( - "ID of the search job. If not specified, all search jobs are returned", - ), - type_description: None, - }, - ), - ], - ), - return_type: Some( - ReturnType { - is_list: true, - parameters: [ - ReturnTypeParameter { - name: "id", - description: "ID of the search job", - return_type: Number( - TypeInfo { - name: "id", - is_optional: false, - is_list: false, - description: Some( - "ID of the search job", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "status", - description: "Current status of the search job (either Running or Stopped)", - return_type: String( - TypeInfo { - name: "status", - is_optional: false, - is_list: false, - description: Some( - "Current status of the search job (either Running or Stopped)", - ), - type_description: None, - }, - ), - }, - ReturnTypeParameter { - name: "total", - description: "Total number of results. If the status is Running this number may contineu to increase", - return_type: Number( - TypeInfo { - name: "total", - is_optional: false, - is_list: false, - description: Some( - "Total number of results. If the status is Running this number may contineu to increase", - ), - type_description: None, - }, - ), - }, - ], - }, - ), - url: "status", - }, - ApiMethod { - name: "results", - description: None, - parameters: Some( - [ - Number( - TypeInfo { - name: "id", - is_optional: false, - is_list: false, - description: Some( - "ID of the search job", - ), - type_description: None, - }, - ), - Number( - TypeInfo { - name: "limit", - is_optional: true, - is_list: false, - description: Some( - "max number of results to return. 0 or negative means no limit", - ), - type_description: None, - }, - ), - Number( - TypeInfo { - name: "offset", - is_optional: true, - is_list: false, - description: Some( - "result to start at. A negative number means count backwards (e.g. -2 returns the 2 most recent results)", - ), - type_description: None, - }, - ), - ], - ), - return_type: Some( - ReturnType { - is_list: false, - parameters: [], - }, - ), - url: "results", - }, - ], - description: Some( - "All Search API methods are under \"search\", e.g.: `/api/v2/search/methodName`.", - ), - url: "search", - }, -] \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/parser/mod.rs b/qbittorrent-web-api-gen/src/parser/mod.rs index 8974168..e5d8968 100644 --- a/qbittorrent-web-api-gen/src/parser/mod.rs +++ b/qbittorrent-web-api-gen/src/parser/mod.rs @@ -1,9 +1,6 @@ use crate::{md_parser, types}; -use self::group::parse_api_group; - mod group; -mod util; #[derive(Debug)] pub struct ReturnTypeParameter { @@ -12,17 +9,14 @@ pub struct ReturnTypeParameter { pub return_type: types::Type, } -pub use group::{ApiGroup, ApiMethod, ReturnType}; +pub use group::*; pub fn parse_api_groups(token_tree: md_parser::TokenTree) -> Vec { parse_groups(extract_relevant_parts(token_tree)) } pub fn parse_groups(trees: Vec) -> Vec { - trees - .into_iter() - .map(|tree| parse_api_group(&tree)) - .collect() + trees.iter().map(ApiGroup::new).collect() } fn extract_relevant_parts(tree: md_parser::TokenTree) -> Vec { diff --git a/qbittorrent-web-api-gen/src/parser/token_tree.txt b/qbittorrent-web-api-gen/src/parser/token_tree.txt deleted file mode 100644 index 52bd36c..0000000 --- a/qbittorrent-web-api-gen/src/parser/token_tree.txt +++ /dev/null @@ -1,13793 +0,0 @@ -TokenTree { - title: None, - content: [ - Text( - "This WebUI API documentation applies to qBittorrent v4.1+. For other WebUI API versions, visit [WebUI API](https://github.com/qbittorrent/qBittorrent/wiki#WebUI-API).", - ), - Text( - "", - ), - ], - children: [ - TokenTree { - title: Some( - "Table of Contents", - ), - content: [ - Text( - "", - ), - Text( - "1. [Changes](#changes)", - ), - Text( - " 1. [API v2.0](#api-v20)", - ), - Text( - " 1. [API v2.0.1](#api-v201)", - ), - Text( - " 1. [API v2.0.2](#api-v202)", - ), - Text( - " 1. [API v2.1.0](#api-v210)", - ), - Text( - " 1. [API v2.1.1](#api-v211)", - ), - Text( - " 1. [API v2.2.0](#api-v220)", - ), - Text( - " 1. [API v2.2.1](#api-v221)", - ), - Text( - " 1. [API v2.3.0](#api-v230)", - ), - Text( - " 1. [API v2.4.0](#api-v240)", - ), - Text( - " 1. [API v2.4.1](#api-v241)", - ), - Text( - " 1. [API v2.5.0](#api-v250)", - ), - Text( - " 1. [API v2.5.1](#api-v251)", - ), - Text( - " 1. [API v2.6.0](#api-v260)", - ), - Text( - " 1. [API v2.6.1](#api-v261)", - ), - Text( - " 1. [API v2.6.2](#api-v262)", - ), - Text( - " 1. [API v2.7.0](#api-v270)", - ), - Text( - " 1. [API v2.8.0](#api-v280)", - ), - Text( - " 1. [API v2.8.1](#api-v281)", - ), - Text( - " 1. [API v2.8.2](#api-v282)", - ), - Text( - " 1. [API v2.8.3](#api-v283)", - ), - Text( - "1. [General information](#general-information)", - ), - Text( - "1. [Authentication](#authentication)", - ), - Text( - " 1. [Login](#login)", - ), - Text( - " 1. [Logout](#logout)", - ), - Text( - "1. [Application](#application)", - ), - Text( - " 1. [Get application version](#get-application-version)", - ), - Text( - " 1. [Get API version](#get-api-version)", - ), - Text( - " 1. [Get build info](#get-build-info)", - ), - Text( - " 1. [Shutdown application](#shutdown-application)", - ), - Text( - " 1. [Get application preferences](#get-application-preferences)", - ), - Text( - " 1. [Set application preferences](#set-application-preferences)", - ), - Text( - " 1. [Get default save path](#get-default-save-path)", - ), - Text( - "1. [Log](#log)", - ), - Text( - " 1. [Get log](#get-log)", - ), - Text( - " 1. [Get peer log](#get-peer-log)", - ), - Text( - "1. [Sync](#sync)", - ), - Text( - " 1. [Get main data](#get-main-data)", - ), - Text( - " 1. [Get torrent peers data](#get-torrent-peers-data)", - ), - Text( - "1. [Transfer info](#transfer-info)", - ), - Text( - " 1. [Get global transfer info](#get-global-transfer-info)", - ), - Text( - " 1. [Get alternative speed limits state](#get-alternative-speed-limits-state)", - ), - Text( - " 1. [Toggle alternative speed limits](#toggle-alternative-speed-limits)", - ), - Text( - " 1. [Get global download limit](#get-global-download-limit)", - ), - Text( - " 1. [Set global download limit](#set-global-download-limit)", - ), - Text( - " 1. [Get global upload limit](#get-global-upload-limit)", - ), - Text( - " 1. [Set global upload limit](#set-global-upload-limit)", - ), - Text( - " 1. [Ban peers](#ban-peers)", - ), - Text( - "1. [Torrent management](#torrent-management)", - ), - Text( - " 1. [Get torrent list](#get-torrent-list)", - ), - Text( - " 1. [Get torrent generic properties](#get-torrent-generic-properties)", - ), - Text( - " 1. [Get torrent trackers](#get-torrent-trackers)", - ), - Text( - " 1. [Get torrent web seeds](#get-torrent-web-seeds)", - ), - Text( - " 1. [Get torrent contents](#get-torrent-contents)", - ), - Text( - " 1. [Get torrent pieces' states](#get-torrent-pieces-states)", - ), - Text( - " 1. [Get torrent pieces' hashes](#get-torrent-pieces-hashes)", - ), - Text( - " 1. [Pause torrents](#pause-torrents)", - ), - Text( - " 1. [Resume torrents](#resume-torrents)", - ), - Text( - " 1. [Delete torrents](#delete-torrents)", - ), - Text( - " 1. [Recheck torrents](#recheck-torrents)", - ), - Text( - " 1. [Reannounce torrents](#reannounce-torrents)", - ), - Text( - " 1. [Edit trackers](#edit-trackers)", - ), - Text( - " 1. [Remove trackers](#remove-trackers)", - ), - Text( - " 1. [Add peers](#add-peers)", - ), - Text( - " 1. [Add new torrent](#add-new-torrent)", - ), - Text( - " 1. [Add trackers to torrent](#add-trackers-to-torrent)", - ), - Text( - " 1. [Increase torrent priority](#increase-torrent-priority)", - ), - Text( - " 1. [Decrease torrent priority](#decrease-torrent-priority)", - ), - Text( - " 1. [Maximal torrent priority](#maximal-torrent-priority)", - ), - Text( - " 1. [Minimal torrent priority](#minimal-torrent-priority)", - ), - Text( - " 1. [Set file priority](#set-file-priority)", - ), - Text( - " 1. [Get torrent download limit](#get-torrent-download-limit)", - ), - Text( - " 1. [Set torrent download limit](#set-torrent-download-limit)", - ), - Text( - " 1. [Set torrent share limit](#set-torrent-share-limit)", - ), - Text( - " 1. [Get torrent upload limit](#get-torrent-upload-limit)", - ), - Text( - " 1. [Set torrent upload limit](#set-torrent-upload-limit)", - ), - Text( - " 1. [Set torrent location](#set-torrent-location)", - ), - Text( - " 1. [Set torrent name](#set-torrent-name)", - ), - Text( - " 1. [Set torrent category](#set-torrent-category)", - ), - Text( - " 1. [Get all categories](#get-all-categories)", - ), - Text( - " 1. [Add new category](#add-new-category)", - ), - Text( - " 1. [Edit category](#edit-category)", - ), - Text( - " 1. [Remove categories](#remove-categories)", - ), - Text( - " 1. [Add torrent tags](#add-torrent-tags)", - ), - Text( - " 1. [Remove torrent tags](#remove-torrent-tags)", - ), - Text( - " 1. [Get all tags](#get-all-tags)", - ), - Text( - " 1. [Create tags](#create-tags)", - ), - Text( - " 1. [Delete tags](#delete-tags)", - ), - Text( - " 1. [Set automatic torrent management](#set-automatic-torrent-management)", - ), - Text( - " 1. [Toggle sequential download](#toggle-sequential-download)", - ), - Text( - " 1. [Set first/last piece priority](#set-firstlast-piece-priority)", - ), - Text( - " 1. [Set force start](#set-force-start)", - ), - Text( - " 1. [Set super seeding](#set-super-seeding)", - ), - Text( - " 1. [Rename file](#rename-file)", - ), - Text( - " 1. [Rename folder](#rename-folder)", - ), - Text( - "1. [RSS (experimental)](#rss-experimental)", - ), - Text( - " 1. [Add folder](#add-folder)", - ), - Text( - " 1. [Add feed](#add-feed)", - ), - Text( - " 1. [Remove item](#remove-item)", - ), - Text( - " 1. [Move item](#move-item)", - ), - Text( - " 1. [Get all items](#get-all-items)", - ), - Text( - " 1. [Mark as read](#mark-as-read)", - ), - Text( - " 1. [Refresh item](#refresh-item)", - ), - Text( - " 1. [Set auto-downloading rule](#set-auto-downloading-rule)", - ), - Text( - " 1. [Rename auto-downloading rule](#rename-auto-downloading-rule)", - ), - Text( - " 1. [Remove auto-downloading rule](#remove-auto-downloading-rule)", - ), - Text( - " 1. [Get all auto-downloading rules](#get-all-auto-downloading-rules)", - ), - Text( - " 1. [Get all articles matching a rule](#get-all-articles-matching-a-rule)", - ), - Text( - "1. [Search](#search)", - ), - Text( - " 1. [Start search](#start-search)", - ), - Text( - " 1. [Stop search](#stop-search)", - ), - Text( - " 1. [Get search status](#get-search-status)", - ), - Text( - " 1. [Get search results](#get-search-results)", - ), - Text( - " 1. [Delete search](#delete-search)", - ), - Text( - " 1. [Get search plugins](#get-search-plugins)", - ), - Text( - " 1. [Install search plugin](#install-search-plugin)", - ), - Text( - " 1. [Uninstall search plugin](#uninstall-search-plugin)", - ), - Text( - " 1. [Enable search plugin](#enable-search-plugin)", - ), - Text( - " 1. [Update search plugins](#update-search-plugins)", - ), - Text( - "1. [WebAPI versioning](#webapi-versioning)", - ), - Text( - "", - ), - Asterix( - "", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Changes", - ), - content: [ - Text( - "", - ), - ], - children: [ - TokenTree { - title: Some( - "API v2.0", - ), - content: [ - Text( - "", - ), - Text( - "- New version naming scheme: X.Y.Z (where X - major version, Y - minor version, Z - release version)", - ), - Text( - "- New API paths. All API methods are under `api/vX/` (where X is API major version)", - ), - Text( - "- API methods are under new scopes", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "API v2.0.1", - ), - content: [ - Text( - "", - ), - Text( - "- Add `hashes` field to `/torrents/info` ([#8782](https://github.com/qbittorrent/qBittorrent/pull/8782))", - ), - Text( - "- Add `/torrents/setShareLimits/` method ([#8598](https://github.com/qbittorrent/qBittorrent/pull/8598))", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "API v2.0.2", - ), - content: [ - Text( - "", - ), - Text( - "- Add `/torrents/reannounce` method ([#9229](https://github.com/qbittorrent/qBittorrent/pull/9229))", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "API v2.1.0", - ), - content: [ - Text( - "", - ), - Text( - "- Change `/sync/maindata` `categories` field from `array` to `object` ([#9228](https://github.com/qbittorrent/qBittorrent/pull/9228))", - ), - Text( - "- Add `savePath` field to `/torrents/createCategory` ([#9228](https://github.com/qbittorrent/qBittorrent/pull/9228)). This method now requires the category to already exist and will not create new categories.", - ), - Text( - "- Add `/torrents/editCategory` method ([#9228](https://github.com/qbittorrent/qBittorrent/pull/9228))", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "API v2.1.1", - ), - content: [ - Text( - "", - ), - Text( - "- Add `/torrents/categories` method ([#9586](https://github.com/qbittorrent/qBittorrent/pull/9586))", - ), - Text( - "- Add `/search/` methods ([#8584](https://github.com/qbittorrent/qBittorrent/pull/8584))", - ), - Text( - "- Add `free_space_on_disk` field to `/sync/maindata` ([#8217](https://github.com/qbittorrent/qBittorrent/pull/8217))", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "API v2.2.0", - ), - content: [ - Text( - "", - ), - Text( - "- Add `/torrents/editTracker` and `/torrents/removeTracker` methods ([#9375](https://github.com/qbittorrent/qBittorrent/pull/9375))", - ), - Text( - "- Add `tier`, `num_seeds`, `num_leeches`, and `num_downloaded` fields to `/torrents/trackers` ([#9375](https://github.com/qbittorrent/qBittorrent/pull/9375))", - ), - Text( - "- Change `status` field from translated string to an integer for `/torrents/trackers` ([#9375](https://github.com/qbittorrent/qBittorrent/pull/9375))", - ), - Text( - "- Change `/torrents/filePrio` `id` field to accept multiple ids ([#9541](https://github.com/qbittorrent/qBittorrent/pull/9541))", - ), - Text( - "- Throw additional errors for failed requests to `/torrents/filePrio` ([#9541](https://github.com/qbittorrent/qBittorrent/pull/9541))", - ), - Text( - "- Add `autoTMM` field to `/torrents/add` ([#9752](https://github.com/qbittorrent/qBittorrent/pull/9752))", - ), - Text( - "- Add various fields to `/app/getPreferences` and `/app/setPreferences` (`create_subfolder_enabled`, `start_paused_enabled`, `auto_delete_mode`, `preallocate_all`, `incomplete_files_ext`, `auto_tmm_enabled`, `torrent_changed_tmm_enabled`, `save_path_changed_tmm_enabled`, `category_changed_tmm_enabled`, `mail_notification_sender`, `limit_lan_peers`, `slow_torrent_dl_rate_threshold`, `slow_torrent_ul_rate_threshold`, `slow_torrent_inactive_timer`, `alternative_webui_enabled`, `alternative_webui_path`) ([#9752](https://github.com/qbittorrent/qBittorrent/pull/9752))", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "API v2.2.1", - ), - content: [ - Text( - "", - ), - Text( - "- Add `rss/refreshItem` ([#11067](https://github.com/qbittorrent/qBittorrent/pull/11067))", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "API v2.3.0", - ), - content: [ - Text( - "", - ), - Text( - "- Remove `web_ui_password` field from `/app/preferences`, this field is still writable in `/app/setPreferences` method ([#9942](https://github.com/qbittorrent/qBittorrent/pull/9942))", - ), - Text( - "- Add `/app/buildInfo` method ([#10096](https://github.com/qbittorrent/qBittorrent/pull/10096))", - ), - Text( - "- Always use `/` as path separator in `/torrents/files` response ([#10153](https://github.com/qbittorrent/qBittorrent/pull/10153/))", - ), - Text( - "- Add `/torrents/addPeers` and `/transfer/banPeers` methods ([#10158](https://github.com/qbittorrent/qBittorrent/pull/10158))", - ), - Text( - "- Add `/torrents/addTags`, `/torrents/removeTags`, `/torrents/tags`, `/torrents/createTags`, `/torrents/deleteTags` methods ([#10527](https://github.com/qbittorrent/qBittorrent/pull/10527))", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "API v2.4.0", - ), - content: [ - Text( - "", - ), - Text( - "- Add `/torrents/renameFile` method ([#11029](https://github.com/qbittorrent/qBittorrent/pull/11029))", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "API v2.4.1", - ), - content: [ - Text( - "", - ), - Text( - "- Add `stalled`, `stalled_uploading` and `stalled_downloading` as possible values for the `filter` parameter in `/torrents/info` ([#11825](https://github.com/qbittorrent/qBittorrent/pull/11825))", - ), - Text( - "- Add various fields to `/app/preferences` and `/app/setPreferences` (`piece_extent_affinity`, `web_ui_secure_cookie_enabled`, `web_ui_max_auth_fail_count`, `web_ui_ban_duration`, `stop_tracker_timeout`) ([#11781](https://github.com/qbittorrent/qBittorrent/pull/11781), [#11726](https://github.com/qbittorrent/qBittorrent/pull/11726), [#12004](https://github.com/qbittorrent/qBittorrent/pull/12004), [#11834](https://github.com/qbittorrent/qBittorrent/pull/11834))", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "API v2.5.0", - ), - content: [ - Text( - "- Removes `enable_super_seeding` as fields from `/app/preferences` and `/app/setPreferences` ([#12423](https://github.com/qbittorrent/qBittorrent/pull/12423))", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "API v2.5.1", - ), - content: [ - Text( - "- Add `web_ui_use_custom_http_headers_enabled`, `web_ui_custom_http_headers`, `rss_download_repack_proper_episodes` and `rss_smart_episode_filters` as fields to `/app/preferences` and `/app/setPreferences` ([#12579](https://github.com/qbittorrent/qBittorrent/pull/12579), [#12549](https://github.com/qbittorrent/qBittorrent/pull/12549))", - ), - Text( - "- Add `/rss/markAsRead` and `/rss/matchingArticles` methods ([#12549](https://github.com/qbittorrent/qBittorrent/pull/12549))", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "API v2.6.0", - ), - content: [ - Text( - "- Removed `/search/categories` method and modified `/search/plugins` method's response ([#12705](https://github.com/qbittorrent/qBittorrent/pull/12705))", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "API v2.6.1", - ), - content: [ - Text( - "- Exposed `contentPath` via the `content_path` field in the response to `/torrents/info` ([#13625](https://github.com/qbittorrent/qBittorrent/pull/13625))", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "API v2.6.2", - ), - content: [ - Text( - "- Added `tags` optional field to `/torrents/add` ([#13882](https://github.com/qbittorrent/qBittorrent/pull/13882))", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "API v2.8.0", - ), - content: [ - Text( - "- Added `/torrents/renameFolder` method and modified `/torrents/renameFile` method's parameters ([#13995](https://github.com/qbittorrent/qBittorrent/pull/13995))", - ), - Text( - "", - ), - Text( - "Note that this change was released in qBittorrent v4.3.3, but the WebAPI version was incorrectly set to v2.7.0 (see [#14275](https://github.com/qbittorrent/qBittorrent/pull/14275#issuecomment-766310862) for details)", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "API v2.8.1", - ), - content: [ - Text( - "- Added `ratioLimit` and `seedingTimeLimit` optional fields to `/torrents/add` ([#14519](https://github.com/qbittorrent/qBittorrent/pull/14519))", - ), - Text( - "- Added `seeding_time` field to `/torrents/info` ([#14554](https://github.com/qbittorrent/qBittorrent/pull/14554))", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "API v2.8.2", - ), - content: [ - Text( - "- Added `indexes` optional parameter to `/torrents/files` ([#14795](https://github.com/qbittorrent/qBittorrent/pull/14795))", - ), - Text( - "- Added `index` field to `/torrents/files` response ([#14795](https://github.com/qbittorrent/qBittorrent/pull/14795))", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "API v2.8.3", - ), - content: [ - Text( - "- Added `tag` optional parameter to `/torrents/info` ([#15152](https://github.com/qbittorrent/qBittorrent/pull/15152))", - ), - Text( - "", - ), - ], - children: [], - }, - ], - }, - TokenTree { - title: Some( - "General Information", - ), - content: [ - Text( - "", - ), - Text( - "- All API methods are under `/api/v2/APIName/methodName`, where `APIName` is a certain subgroup of API methods whose functionality is related.", - ), - Text( - "- Either `GET` or `POST` can be used as the request type for all API methods.", - ), - Text( - "- All API methods require [authentication](#authentication) (except the `/api/v2/auth/login` method itself, obviously).", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Authentication", - ), - content: [ - Text( - "", - ), - Text( - "All Authentication API methods are under \"auth\", e.g.: `/api/v2/auth/methodName`.", - ), - Text( - "", - ), - Text( - "qBittorrent uses cookie-based authentication.", - ), - Text( - "", - ), - ], - children: [ - TokenTree { - title: Some( - "Login", - ), - content: [ - Text( - "", - ), - Text( - "Name: `login`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`username` | string | Username used to access the WebUI", - columns: [ - "username", - "string", - "Username used to access the WebUI", - ], - }, - TableRow { - raw: "`password` | string | Password used to access the WebUI", - columns: [ - "password", - "string", - "Password used to access the WebUI", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "403 | User's IP is banned for too many failed login attempts", - columns: [ - "403", - "User's IP is banned for too many failed login attempts", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - Text( - "Upon success, the response will contain a cookie with your SID. You must supply the cookie whenever you want to perform an operation that requires authentication.", - ), - Text( - "", - ), - Text( - "Example showing how to login and execute a command that requires authentication using `curl`:", - ), - Text( - "", - ), - Text( - "```sh", - ), - Text( - "$ curl -i --header 'Referer: http://localhost:8080' --data 'username=admin&password=adminadmin' http://localhost:8080/api/v2/auth/login", - ), - Text( - "HTTP/1.1 200 OK", - ), - Text( - "Content-Encoding:", - ), - Text( - "Content-Length: 3", - ), - Text( - "Content-Type: text/plain; charset=UTF-8", - ), - Text( - "Set-Cookie: SID=hBc7TxF76ERhvIw0jQQ4LZ7Z1jQUV0tQ; path=/", - ), - Text( - "$ curl http://localhost:8080/api/v2/torrents/info --cookie \"SID=hBc7TxF76ERhvIw0jQQ4LZ7Z1jQUV0tQ\"", - ), - Text( - "```", - ), - Text( - "", - ), - Text( - "Note: Set `Referer` or `Origin` header to the exact same domain and port as used in the HTTP query `Host` header.", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Logout", - ), - content: [ - Text( - "", - ), - Text( - "Name: `logout`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Text( - "None", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - ], - }, - TokenTree { - title: Some( - "Application", - ), - content: [ - Text( - "", - ), - Text( - "All Application API methods are under \"app\", e.g.: `/api/v2/app/methodName`.", - ), - Text( - "", - ), - ], - children: [ - TokenTree { - title: Some( - "Get application version", - ), - content: [ - Text( - "", - ), - Text( - "Name: `version`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Text( - "None", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - Text( - "The response is a string with the application version, e.g. `v4.1.3`", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get API version", - ), - content: [ - Text( - "", - ), - Text( - "Name: `webapiVersion`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Text( - "None", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - Text( - "The response is a string with the WebAPI version, e.g. `2.0`", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get build info", - ), - content: [ - Text( - "", - ), - Text( - "Name: `buildInfo`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Text( - "None", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios- see JSON below", - columns: [ - "200", - "All scenarios- see JSON below", - ], - }, - ], - }, - ), - Text( - "The response is a JSON object containing the following fields", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Property | Type | Description", - columns: [ - "Property", - "Type", - "Description", - ], - }, - split: "-------------|---------|------------", - rows: [ - TableRow { - raw: "`qt` | string | QT version", - columns: [ - "qt", - "string", - "QT version", - ], - }, - TableRow { - raw: "`libtorrent` | string | libtorrent version", - columns: [ - "libtorrent", - "string", - "libtorrent version", - ], - }, - TableRow { - raw: "`boost` | string | Boost version", - columns: [ - "boost", - "string", - "Boost version", - ], - }, - TableRow { - raw: "`openssl` | string | OpenSSL version", - columns: [ - "openssl", - "string", - "OpenSSL version", - ], - }, - TableRow { - raw: "`bitness` | int | Application bitness (e.g. 64-bit)", - columns: [ - "bitness", - "int", - "Application bitness (e.g. 64-bit)", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Shutdown application", - ), - content: [ - Text( - "", - ), - Text( - "Name: `shutdown`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Text( - "None", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get application preferences", - ), - content: [ - Text( - "", - ), - Text( - "Name: `preferences`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Text( - "None", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios- see JSON below", - columns: [ - "200", - "All scenarios- see JSON below", - ], - }, - ], - }, - ), - Text( - "The response is a JSON object with several fields (key-value) pairs representing the application's settings. The contents may vary depending on which settings are present in qBittorrent.ini.", - ), - Text( - "", - ), - Text( - "Possible fields:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Property | Type | Description", - columns: [ - "Property", - "Type", - "Description", - ], - }, - split: "-----------------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`locale` | string | Currently selected language (e.g. en_GB for English)", - columns: [ - "locale", - "string", - "Currently selected language (e.g. en_GB for English)", - ], - }, - TableRow { - raw: "`create_subfolder_enabled` | bool | True if a subfolder should be created when adding a torrent", - columns: [ - "create_subfolder_enabled", - "bool", - "True if a subfolder should be created when adding a torrent", - ], - }, - TableRow { - raw: "`start_paused_enabled` | bool | True if torrents should be added in a Paused state", - columns: [ - "start_paused_enabled", - "bool", - "True if torrents should be added in a Paused state", - ], - }, - TableRow { - raw: "`auto_delete_mode` | integer | TODO", - columns: [ - "auto_delete_mode", - "integer", - "TODO", - ], - }, - TableRow { - raw: "`preallocate_all` | bool | True if disk space should be pre-allocated for all files", - columns: [ - "preallocate_all", - "bool", - "True if disk space should be pre-allocated for all files", - ], - }, - TableRow { - raw: "`incomplete_files_ext` | bool | True if \".!qB\" should be appended to incomplete files", - columns: [ - "incomplete_files_ext", - "bool", - "True if \".!qB\" should be appended to incomplete files", - ], - }, - TableRow { - raw: "`auto_tmm_enabled` | bool | True if Automatic Torrent Management is enabled by default", - columns: [ - "auto_tmm_enabled", - "bool", - "True if Automatic Torrent Management is enabled by default", - ], - }, - TableRow { - raw: "`torrent_changed_tmm_enabled` | bool | True if torrent should be relocated when its Category changes", - columns: [ - "torrent_changed_tmm_enabled", - "bool", - "True if torrent should be relocated when its Category changes", - ], - }, - TableRow { - raw: "`save_path_changed_tmm_enabled` | bool | True if torrent should be relocated when the default save path changes", - columns: [ - "save_path_changed_tmm_enabled", - "bool", - "True if torrent should be relocated when the default save path changes", - ], - }, - TableRow { - raw: "`category_changed_tmm_enabled` | bool | True if torrent should be relocated when its Category's save path changes", - columns: [ - "category_changed_tmm_enabled", - "bool", - "True if torrent should be relocated when its Category's save path changes", - ], - }, - TableRow { - raw: "`save_path` | string | Default save path for torrents, separated by slashes", - columns: [ - "save_path", - "string", - "Default save path for torrents, separated by slashes", - ], - }, - TableRow { - raw: "`temp_path_enabled` | bool | True if folder for incomplete torrents is enabled", - columns: [ - "temp_path_enabled", - "bool", - "True if folder for incomplete torrents is enabled", - ], - }, - TableRow { - raw: "`temp_path` | string | Path for incomplete torrents, separated by slashes", - columns: [ - "temp_path", - "string", - "Path for incomplete torrents, separated by slashes", - ], - }, - TableRow { - raw: "`scan_dirs` | object | 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", - columns: [ - "scan_dirs", - "object", - "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", - ], - }, - TableRow { - raw: "`export_dir` | string | Path to directory to copy .torrent files to. Slashes are used as path separators", - columns: [ - "export_dir", - "string", - "Path to directory to copy .torrent files to. Slashes are used as path separators", - ], - }, - TableRow { - raw: "`export_dir_fin` | string | Path to directory to copy .torrent files of completed downloads to. Slashes are used as path separators", - columns: [ - "export_dir_fin", - "string", - "Path to directory to copy .torrent files of completed downloads to. Slashes are used as path separators", - ], - }, - TableRow { - raw: "`mail_notification_enabled` | bool | True if e-mail notification should be enabled", - columns: [ - "mail_notification_enabled", - "bool", - "True if e-mail notification should be enabled", - ], - }, - TableRow { - raw: "`mail_notification_sender` | string | e-mail where notifications should originate from", - columns: [ - "mail_notification_sender", - "string", - "e-mail where notifications should originate from", - ], - }, - TableRow { - raw: "`mail_notification_email` | string | e-mail to send notifications to", - columns: [ - "mail_notification_email", - "string", - "e-mail to send notifications to", - ], - }, - TableRow { - raw: "`mail_notification_smtp` | string | smtp server for e-mail notifications", - columns: [ - "mail_notification_smtp", - "string", - "smtp server for e-mail notifications", - ], - }, - TableRow { - raw: "`mail_notification_ssl_enabled` | bool | True if smtp server requires SSL connection", - columns: [ - "mail_notification_ssl_enabled", - "bool", - "True if smtp server requires SSL connection", - ], - }, - TableRow { - raw: "`mail_notification_auth_enabled` | bool | True if smtp server requires authentication", - columns: [ - "mail_notification_auth_enabled", - "bool", - "True if smtp server requires authentication", - ], - }, - TableRow { - raw: "`mail_notification_username` | string | Username for smtp authentication", - columns: [ - "mail_notification_username", - "string", - "Username for smtp authentication", - ], - }, - TableRow { - raw: "`mail_notification_password` | string | Password for smtp authentication", - columns: [ - "mail_notification_password", - "string", - "Password for smtp authentication", - ], - }, - TableRow { - raw: "`autorun_enabled` | bool | True if external program should be run after torrent has finished downloading", - columns: [ - "autorun_enabled", - "bool", - "True if external program should be run after torrent has finished downloading", - ], - }, - TableRow { - raw: "`autorun_program` | string | 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", - columns: [ - "autorun_program", - "string", - "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", - ], - }, - TableRow { - raw: "`queueing_enabled` | bool | True if torrent queuing is enabled", - columns: [ - "queueing_enabled", - "bool", - "True if torrent queuing is enabled", - ], - }, - TableRow { - raw: "`max_active_downloads` | integer | Maximum number of active simultaneous downloads", - columns: [ - "max_active_downloads", - "integer", - "Maximum number of active simultaneous downloads", - ], - }, - TableRow { - raw: "`max_active_torrents` | integer | Maximum number of active simultaneous downloads and uploads", - columns: [ - "max_active_torrents", - "integer", - "Maximum number of active simultaneous downloads and uploads", - ], - }, - TableRow { - raw: "`max_active_uploads` | integer | Maximum number of active simultaneous uploads", - columns: [ - "max_active_uploads", - "integer", - "Maximum number of active simultaneous uploads", - ], - }, - TableRow { - raw: "`dont_count_slow_torrents` | bool | 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", - columns: [ - "dont_count_slow_torrents", - "bool", - "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", - ], - }, - TableRow { - raw: "`slow_torrent_dl_rate_threshold` | integer | Download rate in KiB/s for a torrent to be considered \"slow\"", - columns: [ - "slow_torrent_dl_rate_threshold", - "integer", - "Download rate in KiB/s for a torrent to be considered \"slow\"", - ], - }, - TableRow { - raw: "`slow_torrent_ul_rate_threshold` | integer | Upload rate in KiB/s for a torrent to be considered \"slow\"", - columns: [ - "slow_torrent_ul_rate_threshold", - "integer", - "Upload rate in KiB/s for a torrent to be considered \"slow\"", - ], - }, - TableRow { - raw: "`slow_torrent_inactive_timer` | integer | Seconds a torrent should be inactive before considered \"slow\"", - columns: [ - "slow_torrent_inactive_timer", - "integer", - "Seconds a torrent should be inactive before considered \"slow\"", - ], - }, - TableRow { - raw: "`max_ratio_enabled` | bool | True if share ratio limit is enabled", - columns: [ - "max_ratio_enabled", - "bool", - "True if share ratio limit is enabled", - ], - }, - TableRow { - raw: "`max_ratio` | float | Get the global share ratio limit", - columns: [ - "max_ratio", - "float", - "Get the global share ratio limit", - ], - }, - TableRow { - raw: "`max_ratio_act` | integer | Action performed when a torrent reaches the maximum share ratio. See list of possible values here below.", - columns: [ - "max_ratio_act", - "integer", - "Action performed when a torrent reaches the maximum share ratio. See list of possible values here below.", - ], - }, - TableRow { - raw: "`listen_port` | integer | Port for incoming connections", - columns: [ - "listen_port", - "integer", - "Port for incoming connections", - ], - }, - TableRow { - raw: "`upnp` | bool | True if UPnP/NAT-PMP is enabled", - columns: [ - "upnp", - "bool", - "True if UPnP/NAT-PMP is enabled", - ], - }, - TableRow { - raw: "`random_port` | bool | True if the port is randomly selected", - columns: [ - "random_port", - "bool", - "True if the port is randomly selected", - ], - }, - TableRow { - raw: "`dl_limit` | integer | Global download speed limit in KiB/s; `-1` means no limit is applied", - columns: [ - "dl_limit", - "integer", - "Global download speed limit in KiB/s; -1 means no limit is applied", - ], - }, - TableRow { - raw: "`up_limit` | integer | Global upload speed limit in KiB/s; `-1` means no limit is applied", - columns: [ - "up_limit", - "integer", - "Global upload speed limit in KiB/s; -1 means no limit is applied", - ], - }, - TableRow { - raw: "`max_connec` | integer | Maximum global number of simultaneous connections", - columns: [ - "max_connec", - "integer", - "Maximum global number of simultaneous connections", - ], - }, - TableRow { - raw: "`max_connec_per_torrent` | integer | Maximum number of simultaneous connections per torrent", - columns: [ - "max_connec_per_torrent", - "integer", - "Maximum number of simultaneous connections per torrent", - ], - }, - TableRow { - raw: "`max_uploads` | integer | Maximum number of upload slots", - columns: [ - "max_uploads", - "integer", - "Maximum number of upload slots", - ], - }, - TableRow { - raw: "`max_uploads_per_torrent` | integer | Maximum number of upload slots per torrent", - columns: [ - "max_uploads_per_torrent", - "integer", - "Maximum number of upload slots per torrent", - ], - }, - TableRow { - raw: "`stop_tracker_timeout` | integer | Timeout in seconds for a `stopped` announce request to trackers", - columns: [ - "stop_tracker_timeout", - "integer", - "Timeout in seconds for a stopped announce request to trackers", - ], - }, - TableRow { - raw: "`enable_piece_extent_affinity` | bool | True if the advanced libtorrent option `piece_extent_affinity` is enabled", - columns: [ - "enable_piece_extent_affinity", - "bool", - "True if the advanced libtorrent option piece_extent_affinity is enabled", - ], - }, - TableRow { - raw: "`bittorrent_protocol` | integer | Bittorrent Protocol to use (see list of possible values below)", - columns: [ - "bittorrent_protocol", - "integer", - "Bittorrent Protocol to use (see list of possible values below)", - ], - }, - TableRow { - raw: "`limit_utp_rate` | bool | 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", - columns: [ - "limit_utp_rate", - "bool", - "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", - ], - }, - TableRow { - raw: "`limit_tcp_overhead` | bool | True if `[du]l_limit` should be applied to estimated TCP overhead (service data: e.g. packet headers)", - columns: [ - "limit_tcp_overhead", - "bool", - "True if [du]l_limit should be applied to estimated TCP overhead (service data: e.g. packet headers)", - ], - }, - TableRow { - raw: "`limit_lan_peers` | bool | True if `[du]l_limit` should be applied to peers on the LAN", - columns: [ - "limit_lan_peers", - "bool", - "True if [du]l_limit should be applied to peers on the LAN", - ], - }, - TableRow { - raw: "`alt_dl_limit` | integer | Alternative global download speed limit in KiB/s", - columns: [ - "alt_dl_limit", - "integer", - "Alternative global download speed limit in KiB/s", - ], - }, - TableRow { - raw: "`alt_up_limit` | integer | Alternative global upload speed limit in KiB/s", - columns: [ - "alt_up_limit", - "integer", - "Alternative global upload speed limit in KiB/s", - ], - }, - TableRow { - raw: "`scheduler_enabled` | bool | True if alternative limits should be applied according to schedule", - columns: [ - "scheduler_enabled", - "bool", - "True if alternative limits should be applied according to schedule", - ], - }, - TableRow { - raw: "`schedule_from_hour` | integer | Scheduler starting hour", - columns: [ - "schedule_from_hour", - "integer", - "Scheduler starting hour", - ], - }, - TableRow { - raw: "`schedule_from_min` | integer | Scheduler starting minute", - columns: [ - "schedule_from_min", - "integer", - "Scheduler starting minute", - ], - }, - TableRow { - raw: "`schedule_to_hour` | integer | Scheduler ending hour", - columns: [ - "schedule_to_hour", - "integer", - "Scheduler ending hour", - ], - }, - TableRow { - raw: "`schedule_to_min` | integer | Scheduler ending minute", - columns: [ - "schedule_to_min", - "integer", - "Scheduler ending minute", - ], - }, - TableRow { - raw: "`scheduler_days` | integer | Scheduler days. See possible values here below", - columns: [ - "scheduler_days", - "integer", - "Scheduler days. See possible values here below", - ], - }, - TableRow { - raw: "`dht` | bool | True if DHT is enabled", - columns: [ - "dht", - "bool", - "True if DHT is enabled", - ], - }, - TableRow { - raw: "`pex` | bool | True if PeX is enabled", - columns: [ - "pex", - "bool", - "True if PeX is enabled", - ], - }, - TableRow { - raw: "`lsd` | bool | True if LSD is enabled", - columns: [ - "lsd", - "bool", - "True if LSD is enabled", - ], - }, - TableRow { - raw: "`encryption` | integer | See list of possible values here below", - columns: [ - "encryption", - "integer", - "See list of possible values here below", - ], - }, - TableRow { - raw: "`anonymous_mode` | bool | 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", - columns: [ - "anonymous_mode", - "bool", - "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", - ], - }, - TableRow { - raw: "`proxy_type` | integer | See list of possible values here below", - columns: [ - "proxy_type", - "integer", - "See list of possible values here below", - ], - }, - TableRow { - raw: "`proxy_ip` | string | Proxy IP address or domain name", - columns: [ - "proxy_ip", - "string", - "Proxy IP address or domain name", - ], - }, - TableRow { - raw: "`proxy_port` | integer | Proxy port", - columns: [ - "proxy_port", - "integer", - "Proxy port", - ], - }, - TableRow { - raw: "`proxy_peer_connections` | bool | 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", - columns: [ - "proxy_peer_connections", - "bool", - "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", - ], - }, - TableRow { - raw: "`proxy_auth_enabled` | bool | True proxy requires authentication; doesn't apply to SOCKS4 proxies", - columns: [ - "proxy_auth_enabled", - "bool", - "True proxy requires authentication; doesn't apply to SOCKS4 proxies", - ], - }, - TableRow { - raw: "`proxy_username` | string | Username for proxy authentication", - columns: [ - "proxy_username", - "string", - "Username for proxy authentication", - ], - }, - TableRow { - raw: "`proxy_password` | string | Password for proxy authentication", - columns: [ - "proxy_password", - "string", - "Password for proxy authentication", - ], - }, - TableRow { - raw: "`proxy_torrents_only` | bool | True if proxy is only used for torrents", - columns: [ - "proxy_torrents_only", - "bool", - "True if proxy is only used for torrents", - ], - }, - TableRow { - raw: "`ip_filter_enabled` | bool | True if external IP filter should be enabled", - columns: [ - "ip_filter_enabled", - "bool", - "True if external IP filter should be enabled", - ], - }, - TableRow { - raw: "`ip_filter_path` | string | Path to IP filter file (.dat, .p2p, .p2b files are supported); path is separated by slashes", - columns: [ - "ip_filter_path", - "string", - "Path to IP filter file (.dat, .p2p, .p2b files are supported); path is separated by slashes", - ], - }, - TableRow { - raw: "`ip_filter_trackers` | bool | True if IP filters are applied to trackers", - columns: [ - "ip_filter_trackers", - "bool", - "True if IP filters are applied to trackers", - ], - }, - TableRow { - raw: "`web_ui_domain_list` | string | Comma-separated list of domains to accept when performing Host header validation", - columns: [ - "web_ui_domain_list", - "string", - "Comma-separated list of domains to accept when performing Host header validation", - ], - }, - TableRow { - raw: "`web_ui_address` | string | IP address to use for the WebUI", - columns: [ - "web_ui_address", - "string", - "IP address to use for the WebUI", - ], - }, - TableRow { - raw: "`web_ui_port` | integer | WebUI port", - columns: [ - "web_ui_port", - "integer", - "WebUI port", - ], - }, - TableRow { - raw: "`web_ui_upnp` | bool | True if UPnP is used for the WebUI port", - columns: [ - "web_ui_upnp", - "bool", - "True if UPnP is used for the WebUI port", - ], - }, - TableRow { - raw: "`web_ui_username` | string | WebUI username", - columns: [ - "web_ui_username", - "string", - "WebUI username", - ], - }, - TableRow { - raw: "`web_ui_password` | 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`", - columns: [ - "web_ui_password", - "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", - ], - }, - TableRow { - raw: "`web_ui_csrf_protection_enabled` | bool | True if WebUI CSRF protection is enabled", - columns: [ - "web_ui_csrf_protection_enabled", - "bool", - "True if WebUI CSRF protection is enabled", - ], - }, - TableRow { - raw: "`web_ui_clickjacking_protection_enabled` | bool | True if WebUI clickjacking protection is enabled", - columns: [ - "web_ui_clickjacking_protection_enabled", - "bool", - "True if WebUI clickjacking protection is enabled", - ], - }, - TableRow { - raw: "`web_ui_secure_cookie_enabled` | bool | True if WebUI cookie `Secure` flag is enabled", - columns: [ - "web_ui_secure_cookie_enabled", - "bool", - "True if WebUI cookie Secure flag is enabled", - ], - }, - TableRow { - raw: "`web_ui_max_auth_fail_count` | integer | Maximum number of authentication failures before WebUI access ban", - columns: [ - "web_ui_max_auth_fail_count", - "integer", - "Maximum number of authentication failures before WebUI access ban", - ], - }, - TableRow { - raw: "`web_ui_ban_duration` | integer | WebUI access ban duration in seconds", - columns: [ - "web_ui_ban_duration", - "integer", - "WebUI access ban duration in seconds", - ], - }, - TableRow { - raw: "`web_ui_session_timeout` | integer | Seconds until WebUI is automatically signed off", - columns: [ - "web_ui_session_timeout", - "integer", - "Seconds until WebUI is automatically signed off", - ], - }, - TableRow { - raw: "`web_ui_host_header_validation_enabled` | bool | True if WebUI host header validation is enabled", - columns: [ - "web_ui_host_header_validation_enabled", - "bool", - "True if WebUI host header validation is enabled", - ], - }, - TableRow { - raw: "`bypass_local_auth` | bool | True if authentication challenge for loopback address (127.0.0.1) should be disabled", - columns: [ - "bypass_local_auth", - "bool", - "True if authentication challenge for loopback address (127.0.0.1) should be disabled", - ], - }, - TableRow { - raw: "`bypass_auth_subnet_whitelist_enabled` | bool | True if webui authentication should be bypassed for clients whose ip resides within (at least) one of the subnets on the whitelist", - columns: [ - "bypass_auth_subnet_whitelist_enabled", - "bool", - "True if webui authentication should be bypassed for clients whose ip resides within (at least) one of the subnets on the whitelist", - ], - }, - TableRow { - raw: "`bypass_auth_subnet_whitelist` | string | (White)list of ipv4/ipv6 subnets for which webui authentication should be bypassed; list entries are separated by commas", - columns: [ - "bypass_auth_subnet_whitelist", - "string", - "(White)list of ipv4/ipv6 subnets for which webui authentication should be bypassed; list entries are separated by commas", - ], - }, - TableRow { - raw: "`alternative_webui_enabled` | bool | True if an alternative WebUI should be used", - columns: [ - "alternative_webui_enabled", - "bool", - "True if an alternative WebUI should be used", - ], - }, - TableRow { - raw: "`alternative_webui_path` | string | File path to the alternative WebUI", - columns: [ - "alternative_webui_path", - "string", - "File path to the alternative WebUI", - ], - }, - TableRow { - raw: "`use_https` | bool | True if WebUI HTTPS access is enabled", - columns: [ - "use_https", - "bool", - "True if WebUI HTTPS access is enabled", - ], - }, - TableRow { - raw: "`ssl_key` | string | For API < v2.0.1: SSL keyfile contents (this is a not a path)", - columns: [ - "ssl_key", - "string", - "For API < v2.0.1: SSL keyfile contents (this is a not a path)", - ], - }, - TableRow { - raw: "`ssl_cert` | string | For API < v2.0.1: SSL certificate contents (this is a not a path)", - columns: [ - "ssl_cert", - "string", - "For API < v2.0.1: SSL certificate contents (this is a not a path)", - ], - }, - TableRow { - raw: "`web_ui_https_key_path` | string | For API ≥ v2.0.1: Path to SSL keyfile", - columns: [ - "web_ui_https_key_path", - "string", - "For API ≥ v2.0.1: Path to SSL keyfile", - ], - }, - TableRow { - raw: "`web_ui_https_cert_path` | string | For API ≥ v2.0.1: Path to SSL certificate", - columns: [ - "web_ui_https_cert_path", - "string", - "For API ≥ v2.0.1: Path to SSL certificate", - ], - }, - TableRow { - raw: "`dyndns_enabled` | bool | True if server DNS should be updated dynamically", - columns: [ - "dyndns_enabled", - "bool", - "True if server DNS should be updated dynamically", - ], - }, - TableRow { - raw: "`dyndns_service` | integer | See list of possible values here below", - columns: [ - "dyndns_service", - "integer", - "See list of possible values here below", - ], - }, - TableRow { - raw: "`dyndns_username` | string | Username for DDNS service", - columns: [ - "dyndns_username", - "string", - "Username for DDNS service", - ], - }, - TableRow { - raw: "`dyndns_password` | string | Password for DDNS service", - columns: [ - "dyndns_password", - "string", - "Password for DDNS service", - ], - }, - TableRow { - raw: "`dyndns_domain` | string | Your DDNS domain name", - columns: [ - "dyndns_domain", - "string", - "Your DDNS domain name", - ], - }, - TableRow { - raw: "`rss_refresh_interval` | integer | RSS refresh interval", - columns: [ - "rss_refresh_interval", - "integer", - "RSS refresh interval", - ], - }, - TableRow { - raw: "`rss_max_articles_per_feed` | integer | Max stored articles per RSS feed", - columns: [ - "rss_max_articles_per_feed", - "integer", - "Max stored articles per RSS feed", - ], - }, - TableRow { - raw: "`rss_processing_enabled` | bool | Enable processing of RSS feeds", - columns: [ - "rss_processing_enabled", - "bool", - "Enable processing of RSS feeds", - ], - }, - TableRow { - raw: "`rss_auto_downloading_enabled` | bool | Enable auto-downloading of torrents from the RSS feeds", - columns: [ - "rss_auto_downloading_enabled", - "bool", - "Enable auto-downloading of torrents from the RSS feeds", - ], - }, - TableRow { - raw: "`rss_download_repack_proper_episodes` | bool | For API ≥ v2.5.1: Enable downloading of repack/proper Episodes", - columns: [ - "rss_download_repack_proper_episodes", - "bool", - "For API ≥ v2.5.1: Enable downloading of repack/proper Episodes", - ], - }, - TableRow { - raw: "`rss_smart_episode_filters` | string | For API ≥ v2.5.1: List of RSS Smart Episode Filters", - columns: [ - "rss_smart_episode_filters", - "string", - "For API ≥ v2.5.1: List of RSS Smart Episode Filters", - ], - }, - TableRow { - raw: "`add_trackers_enabled` | bool | Enable automatic adding of trackers to new torrents", - columns: [ - "add_trackers_enabled", - "bool", - "Enable automatic adding of trackers to new torrents", - ], - }, - TableRow { - raw: "`add_trackers` | string | List of trackers to add to new torrent", - columns: [ - "add_trackers", - "string", - "List of trackers to add to new torrent", - ], - }, - TableRow { - raw: "`web_ui_use_custom_http_headers_enabled` | bool | For API ≥ v2.5.1: Enable custom http headers", - columns: [ - "web_ui_use_custom_http_headers_enabled", - "bool", - "For API ≥ v2.5.1: Enable custom http headers", - ], - }, - TableRow { - raw: "`web_ui_custom_http_headers` | string | For API ≥ v2.5.1: List of custom http headers", - columns: [ - "web_ui_custom_http_headers", - "string", - "For API ≥ v2.5.1: List of custom http headers", - ], - }, - TableRow { - raw: "`max_seeding_time_enabled` | bool | True enables max seeding time ", - columns: [ - "max_seeding_time_enabled", - "bool", - "True enables max seeding time", - ], - }, - TableRow { - raw: "`max_seeding_time` | integer | Number of minutes to seed a torrent", - columns: [ - "max_seeding_time", - "integer", - "Number of minutes to seed a torrent", - ], - }, - TableRow { - raw: "`announce_ip` | string | TODO", - columns: [ - "announce_ip", - "string", - "TODO", - ], - }, - TableRow { - raw: "`announce_to_all_tiers` | bool | True always announce to all tiers", - columns: [ - "announce_to_all_tiers", - "bool", - "True always announce to all tiers", - ], - }, - TableRow { - raw: "`announce_to_all_trackers` | bool | True always announce to all trackers in a tier", - columns: [ - "announce_to_all_trackers", - "bool", - "True always announce to all trackers in a tier", - ], - }, - TableRow { - raw: "`async_io_threads` | integer | Number of asynchronous I/O threads", - columns: [ - "async_io_threads", - "integer", - "Number of asynchronous I/O threads", - ], - }, - TableRow { - raw: "`banned_IPs` | string | List of banned IPs", - columns: [ - "banned_IPs", - "string", - "List of banned IPs", - ], - }, - TableRow { - raw: "`checking_memory_use` | integer | Outstanding memory when checking torrents in MiB", - columns: [ - "checking_memory_use", - "integer", - "Outstanding memory when checking torrents in MiB", - ], - }, - TableRow { - raw: "`current_interface_address` | string | IP Address to bind to. Empty String means All addresses", - columns: [ - "current_interface_address", - "string", - "IP Address to bind to. Empty String means All addresses", - ], - }, - TableRow { - raw: "`current_network_interface` | string | Network Interface used", - columns: [ - "current_network_interface", - "string", - "Network Interface used", - ], - }, - TableRow { - raw: "`disk_cache` | integer | Disk cache used in MiB", - columns: [ - "disk_cache", - "integer", - "Disk cache used in MiB", - ], - }, - TableRow { - raw: "`disk_cache_ttl` | integer | Disk cache expiry interval in seconds", - columns: [ - "disk_cache_ttl", - "integer", - "Disk cache expiry interval in seconds", - ], - }, - TableRow { - raw: "`embedded_tracker_port` | integer | Port used for embedded tracker", - columns: [ - "embedded_tracker_port", - "integer", - "Port used for embedded tracker", - ], - }, - TableRow { - raw: "`enable_coalesce_read_write` | bool | True enables coalesce reads & writes", - columns: [ - "enable_coalesce_read_write", - "bool", - "True enables coalesce reads & writes", - ], - }, - TableRow { - raw: "`enable_embedded_tracker` | bool | True enables embedded tracker", - columns: [ - "enable_embedded_tracker", - "bool", - "True enables embedded tracker", - ], - }, - TableRow { - raw: "`enable_multi_connections_from_same_ip` | bool | True allows multiple connections from the same IP address", - columns: [ - "enable_multi_connections_from_same_ip", - "bool", - "True allows multiple connections from the same IP address", - ], - }, - TableRow { - raw: "`enable_os_cache` | bool | True enables os cache", - columns: [ - "enable_os_cache", - "bool", - "True enables os cache", - ], - }, - TableRow { - raw: "`enable_upload_suggestions` | bool | True enables sending of upload piece suggestions", - columns: [ - "enable_upload_suggestions", - "bool", - "True enables sending of upload piece suggestions", - ], - }, - TableRow { - raw: "`file_pool_size` | integer | File pool size", - columns: [ - "file_pool_size", - "integer", - "File pool size", - ], - }, - TableRow { - raw: "`outgoing_ports_max` | integer | Maximal outgoing port (0: Disabled)", - columns: [ - "outgoing_ports_max", - "integer", - "Maximal outgoing port (0: Disabled)", - ], - }, - TableRow { - raw: "`outgoing_ports_min` | integer | Minimal outgoing port (0: Disabled)", - columns: [ - "outgoing_ports_min", - "integer", - "Minimal outgoing port (0: Disabled)", - ], - }, - TableRow { - raw: "`recheck_completed_torrents` | bool | True rechecks torrents on completion", - columns: [ - "recheck_completed_torrents", - "bool", - "True rechecks torrents on completion", - ], - }, - TableRow { - raw: "`resolve_peer_countries` | bool | True resolves peer countries", - columns: [ - "resolve_peer_countries", - "bool", - "True resolves peer countries", - ], - }, - TableRow { - raw: "`save_resume_data_interval` | integer | Save resume data interval in min", - columns: [ - "save_resume_data_interval", - "integer", - "Save resume data interval in min", - ], - }, - TableRow { - raw: "`send_buffer_low_watermark` | integer | Send buffer low watermark in KiB", - columns: [ - "send_buffer_low_watermark", - "integer", - "Send buffer low watermark in KiB", - ], - }, - TableRow { - raw: "`send_buffer_watermark` | integer | Send buffer watermark in KiB", - columns: [ - "send_buffer_watermark", - "integer", - "Send buffer watermark in KiB", - ], - }, - TableRow { - raw: "`send_buffer_watermark_factor` | integer | Send buffer watermark factor in percent", - columns: [ - "send_buffer_watermark_factor", - "integer", - "Send buffer watermark factor in percent", - ], - }, - TableRow { - raw: "`socket_backlog_size` | integer | Socket backlog size", - columns: [ - "socket_backlog_size", - "integer", - "Socket backlog size", - ], - }, - TableRow { - raw: "`upload_choking_algorithm` | integer | Upload choking algorithm used (see list of possible values below)", - columns: [ - "upload_choking_algorithm", - "integer", - "Upload choking algorithm used (see list of possible values below)", - ], - }, - TableRow { - raw: "`upload_slots_behavior` | integer | Upload slots behavior used (see list of possible values below)", - columns: [ - "upload_slots_behavior", - "integer", - "Upload slots behavior used (see list of possible values below)", - ], - }, - TableRow { - raw: "`upnp_lease_duration` | integer | UPnP lease duration (0: Permanent lease)", - columns: [ - "upnp_lease_duration", - "integer", - "UPnP lease duration (0: Permanent lease)", - ], - }, - TableRow { - raw: "`utp_tcp_mixed_mode` | integer | μTP-TCP mixed mode algorithm (see list of possible values below)", - columns: [ - "utp_tcp_mixed_mode", - "integer", - "μTP-TCP mixed mode algorithm (see list of possible values below)", - ], - }, - ], - }, - ), - Text( - "Possible values of `scan_dirs`:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Value | Description", - columns: [ - "Value", - "Description", - ], - }, - split: "----------------------------|------------", - rows: [ - TableRow { - raw: "`0` | Download to the monitored folder", - columns: [ - "0", - "Download to the monitored folder", - ], - }, - TableRow { - raw: "`1` | Download to the default save path", - columns: [ - "1", - "Download to the default save path", - ], - }, - TableRow { - raw: "`\"/path/to/download/to\"` | Download to this path", - columns: [ - "\"/path/to/download/to\"", - "Download to this path", - ], - }, - ], - }, - ), - Text( - "Possible values of `scheduler_days`:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Value | Description", - columns: [ - "Value", - "Description", - ], - }, - split: "-------|------------", - rows: [ - TableRow { - raw: "`0` | Every day", - columns: [ - "0", - "Every day", - ], - }, - TableRow { - raw: "`1` | Every weekday", - columns: [ - "1", - "Every weekday", - ], - }, - TableRow { - raw: "`2` | Every weekend", - columns: [ - "2", - "Every weekend", - ], - }, - TableRow { - raw: "`3` | Every Monday", - columns: [ - "3", - "Every Monday", - ], - }, - TableRow { - raw: "`4` | Every Tuesday", - columns: [ - "4", - "Every Tuesday", - ], - }, - TableRow { - raw: "`5` | Every Wednesday", - columns: [ - "5", - "Every Wednesday", - ], - }, - TableRow { - raw: "`6` | Every Thursday", - columns: [ - "6", - "Every Thursday", - ], - }, - TableRow { - raw: "`7` | Every Friday", - columns: [ - "7", - "Every Friday", - ], - }, - TableRow { - raw: "`8` | Every Saturday", - columns: [ - "8", - "Every Saturday", - ], - }, - TableRow { - raw: "`9` | Every Sunday", - columns: [ - "9", - "Every Sunday", - ], - }, - ], - }, - ), - Text( - "Possible values of `encryption`:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Value | Description", - columns: [ - "Value", - "Description", - ], - }, - split: "-------|------------", - rows: [ - TableRow { - raw: "`0` | Prefer encryption", - columns: [ - "0", - "Prefer encryption", - ], - }, - TableRow { - raw: "`1` | Force encryption on", - columns: [ - "1", - "Force encryption on", - ], - }, - TableRow { - raw: "`2` | Force encryption off", - columns: [ - "2", - "Force encryption off", - ], - }, - ], - }, - ), - Text( - "NB: the first options allows you to use both encrypted and unencrypted connections (this is the default); other options are mutually exclusive: e.g. by forcing encryption on you won't be able to use unencrypted connections and vice versa.", - ), - Text( - "", - ), - Text( - "Possible values of `proxy_type`:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Value | Description", - columns: [ - "Value", - "Description", - ], - }, - split: "------|------------", - rows: [ - TableRow { - raw: "`-1` | Proxy is disabled", - columns: [ - "-1", - "Proxy is disabled", - ], - }, - TableRow { - raw: "`1` | HTTP proxy without authentication", - columns: [ - "1", - "HTTP proxy without authentication", - ], - }, - TableRow { - raw: "`2` | SOCKS5 proxy without authentication", - columns: [ - "2", - "SOCKS5 proxy without authentication", - ], - }, - TableRow { - raw: "`3` | HTTP proxy with authentication", - columns: [ - "3", - "HTTP proxy with authentication", - ], - }, - TableRow { - raw: "`4` | SOCKS5 proxy with authentication", - columns: [ - "4", - "SOCKS5 proxy with authentication", - ], - }, - TableRow { - raw: "`5` | SOCKS4 proxy without authentication", - columns: [ - "5", - "SOCKS4 proxy without authentication", - ], - }, - ], - }, - ), - Text( - "Possible values of `dyndns_service`:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Value | Description", - columns: [ - "Value", - "Description", - ], - }, - split: "-------|------------", - rows: [ - TableRow { - raw: "`0` | Use DyDNS", - columns: [ - "0", - "Use DyDNS", - ], - }, - TableRow { - raw: "`1` | Use NOIP", - columns: [ - "1", - "Use NOIP", - ], - }, - ], - }, - ), - Text( - "Possible values of `max_ratio_act`:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Value | Description", - columns: [ - "Value", - "Description", - ], - }, - split: "------|------------", - rows: [ - TableRow { - raw: "`0` | Pause torrent", - columns: [ - "0", - "Pause torrent", - ], - }, - TableRow { - raw: "`1` | Remove torrent", - columns: [ - "1", - "Remove torrent", - ], - }, - ], - }, - ), - Text( - "Possible values of `bittorrent_protocol`:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Value | Description", - columns: [ - "Value", - "Description", - ], - }, - split: "-------|------------", - rows: [ - TableRow { - raw: "`0` | TCP and μTP", - columns: [ - "0", - "TCP and μTP", - ], - }, - TableRow { - raw: "`1` | TCP", - columns: [ - "1", - "TCP", - ], - }, - TableRow { - raw: "`2` | μTP", - columns: [ - "2", - "μTP", - ], - }, - ], - }, - ), - Text( - "Possible values of `upload_choking_algorithm`:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Value | Description", - columns: [ - "Value", - "Description", - ], - }, - split: "-------|------------", - rows: [ - TableRow { - raw: "`0` | Round-robin", - columns: [ - "0", - "Round-robin", - ], - }, - TableRow { - raw: "`1` | Fastest upload", - columns: [ - "1", - "Fastest upload", - ], - }, - TableRow { - raw: "`2` | Anti-leech", - columns: [ - "2", - "Anti-leech", - ], - }, - ], - }, - ), - Text( - "Possible values of `upload_slots_behavior`:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Value | Description", - columns: [ - "Value", - "Description", - ], - }, - split: "-------|------------", - rows: [ - TableRow { - raw: "`0` | Fixed slots", - columns: [ - "0", - "Fixed slots", - ], - }, - TableRow { - raw: "`1` | Upload rate based", - columns: [ - "1", - "Upload rate based", - ], - }, - ], - }, - ), - Text( - "Possible values of `utp_tcp_mixed_mode`:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Value | Description", - columns: [ - "Value", - "Description", - ], - }, - split: "-------|------------", - rows: [ - TableRow { - raw: "`0` | Prefer TCP", - columns: [ - "0", - "Prefer TCP", - ], - }, - TableRow { - raw: "`1` | Peer proportional", - columns: [ - "1", - "Peer proportional", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "{", - ), - Text( - " \"add_trackers\": \"\",", - ), - Text( - " \"add_trackers_enabled\": false,", - ), - Text( - " \"alt_dl_limit\": 10240,", - ), - Text( - " \"alt_up_limit\": 10240,", - ), - Text( - " \"alternative_webui_enabled\": false,", - ), - Text( - " \"alternative_webui_path\": \"/home/user/Documents/qbit-webui\",", - ), - Text( - " \"announce_ip\": \"\",", - ), - Text( - " \"announce_to_all_tiers\": true,", - ), - Text( - " \"announce_to_all_trackers\": false,", - ), - Text( - " \"anonymous_mode\": false,", - ), - Text( - " \"async_io_threads\": 4,", - ), - Text( - " \"auto_delete_mode\": 0,", - ), - Text( - " \"auto_tmm_enabled\": false,", - ), - Text( - " \"autorun_enabled\": false,", - ), - Text( - " \"autorun_program\": \"\",", - ), - Text( - " \"banned_IPs\": \"\",", - ), - Text( - " \"bittorrent_protocol\": 0,", - ), - Text( - " \"bypass_auth_subnet_whitelist\": \"\",", - ), - Text( - " \"bypass_auth_subnet_whitelist_enabled\": false,", - ), - Text( - " \"bypass_local_auth\": false,", - ), - Text( - " \"category_changed_tmm_enabled\": false,", - ), - Text( - " \"checking_memory_use\": 32,", - ), - Text( - " \"create_subfolder_enabled\": true,", - ), - Text( - " \"current_interface_address\": \"\",", - ), - Text( - " \"current_network_interface\": \"\",", - ), - Text( - " \"dht\": true,", - ), - Text( - " \"disk_cache\": -1,", - ), - Text( - " \"disk_cache_ttl\": 60,", - ), - Text( - " \"dl_limit\": 0,", - ), - Text( - " \"dont_count_slow_torrents\": false,", - ), - Text( - " \"dyndns_domain\": \"changeme.dyndns.org\",", - ), - Text( - " \"dyndns_enabled\": false,", - ), - Text( - " \"dyndns_password\": \"\",", - ), - Text( - " \"dyndns_service\": 0,", - ), - Text( - " \"dyndns_username\": \"\",", - ), - Text( - " \"embedded_tracker_port\": 9000,", - ), - Text( - " \"enable_coalesce_read_write\": false,", - ), - Text( - " \"enable_embedded_tracker\": false,", - ), - Text( - " \"enable_multi_connections_from_same_ip\": false,", - ), - Text( - " \"enable_os_cache\": true,", - ), - Text( - " \"enable_piece_extent_affinity\": false,", - ), - Text( - " \"enable_upload_suggestions\": false,", - ), - Text( - " \"encryption\": 0,", - ), - Text( - " \"export_dir\": \"/home/user/Downloads/all\",", - ), - Text( - " \"export_dir_fin\": \"/home/user/Downloads/completed\",", - ), - Text( - " \"file_pool_size\": 40,", - ), - Text( - " \"incomplete_files_ext\": false,", - ), - Text( - " \"ip_filter_enabled\": false,", - ), - Text( - " \"ip_filter_path\": \"\",", - ), - Text( - " \"ip_filter_trackers\": false,", - ), - Text( - " \"limit_lan_peers\": true,", - ), - Text( - " \"limit_tcp_overhead\": false,", - ), - Text( - " \"limit_utp_rate\": true,", - ), - Text( - " \"listen_port\": 58925,", - ), - Text( - " \"locale\": \"en\",", - ), - Text( - " \"lsd\": true,", - ), - Text( - " \"mail_notification_auth_enabled\": false,", - ), - Text( - " \"mail_notification_email\": \"\",", - ), - Text( - " \"mail_notification_enabled\": false,", - ), - Text( - " \"mail_notification_password\": \"\",", - ), - Text( - " \"mail_notification_sender\": \"qBittorrent_notification@example.com\",", - ), - Text( - " \"mail_notification_smtp\": \"smtp.changeme.com\",", - ), - Text( - " \"mail_notification_ssl_enabled\": false,", - ), - Text( - " \"mail_notification_username\": \"\",", - ), - Text( - " \"max_active_downloads\": 3,", - ), - Text( - " \"max_active_torrents\": 5,", - ), - Text( - " \"max_active_uploads\": 3,", - ), - Text( - " \"max_connec\": 500,", - ), - Text( - " \"max_connec_per_torrent\": 100,", - ), - Text( - " \"max_ratio\": -1,", - ), - Text( - " \"max_ratio_act\": 0,", - ), - Text( - " \"max_ratio_enabled\": false,", - ), - Text( - " \"max_seeding_time\": -1,", - ), - Text( - " \"max_seeding_time_enabled\": false,", - ), - Text( - " \"max_uploads\": -1,", - ), - Text( - " \"max_uploads_per_torrent\": -1,", - ), - Text( - " \"outgoing_ports_max\": 0,", - ), - Text( - " \"outgoing_ports_min\": 0,", - ), - Text( - " \"pex\": true,", - ), - Text( - " \"preallocate_all\": false,", - ), - Text( - " \"proxy_auth_enabled\": false,", - ), - Text( - " \"proxy_ip\": \"0.0.0.0\",", - ), - Text( - " \"proxy_password\": \"\",", - ), - Text( - " \"proxy_peer_connections\": false,", - ), - Text( - " \"proxy_port\": 8080,", - ), - Text( - " \"proxy_torrents_only\": false,", - ), - Text( - " \"proxy_type\": 0,", - ), - Text( - " \"proxy_username\": \"\",", - ), - Text( - " \"queueing_enabled\": false,", - ), - Text( - " \"random_port\": false,", - ), - Text( - " \"recheck_completed_torrents\": false,", - ), - Text( - " \"resolve_peer_countries\": true,", - ), - Text( - " \"rss_auto_downloading_enabled\":true,", - ), - Text( - " \"rss_download_repack_proper_episodes\":true,", - ), - Text( - " \"rss_max_articles_per_feed\":50,", - ), - Text( - " \"rss_processing_enabled\":true,", - ), - Text( - " \"rss_refresh_interval\":30,", - ), - Text( - " \"rss_smart_episode_filters\":\"s(\\\\d+)e(\\\\d+)\\n(\\\\d+)x(\\\\d+)\\n(\\\\d{4}[.\\\\-]\\\\d{1,2}[.\\\\-]\\\\d{1,2})\",", - ), - Text( - " \"save_path\": \"/home/user/Downloads/\",", - ), - Text( - " \"save_path_changed_tmm_enabled\": false,", - ), - Text( - " \"save_resume_data_interval\": 60,", - ), - Text( - " \"scan_dirs\":", - ), - Text( - " {", - ), - Text( - " \"/home/user/Downloads/incoming/games\": 0,", - ), - Text( - " \"/home/user/Downloads/incoming/movies\": 1,", - ), - Text( - " },", - ), - Text( - " \"schedule_from_hour\": 8,", - ), - Text( - " \"schedule_from_min\": 0,", - ), - Text( - " \"schedule_to_hour\": 20,", - ), - Text( - " \"schedule_to_min\": 0,", - ), - Text( - " \"scheduler_days\": 0,", - ), - Text( - " \"scheduler_enabled\": false,", - ), - Text( - " \"send_buffer_low_watermark\": 10,", - ), - Text( - " \"send_buffer_watermark\": 500,", - ), - Text( - " \"send_buffer_watermark_factor\": 50,", - ), - Text( - " \"slow_torrent_dl_rate_threshold\": 2,", - ), - Text( - " \"slow_torrent_inactive_timer\": 60,", - ), - Text( - " \"slow_torrent_ul_rate_threshold\": 2,", - ), - Text( - " \"socket_backlog_size\": 30,", - ), - Text( - " \"start_paused_enabled\": false,", - ), - Text( - " \"stop_tracker_timeout\": 1,", - ), - Text( - " \"temp_path\": \"/home/user/Downloads/temp\",", - ), - Text( - " \"temp_path_enabled\": false,", - ), - Text( - " \"torrent_changed_tmm_enabled\": true,", - ), - Text( - " \"up_limit\": 0,", - ), - Text( - " \"upload_choking_algorithm\": 1,", - ), - Text( - " \"upload_slots_behavior\": 0,", - ), - Text( - " \"upnp\": true,", - ), - Text( - " \"use_https\": false,", - ), - Text( - " \"utp_tcp_mixed_mode\": 0,", - ), - Text( - " \"web_ui_address\": \"*\",", - ), - Text( - " \"web_ui_ban_duration\": 3600,", - ), - Text( - " \"web_ui_clickjacking_protection_enabled\": true,", - ), - Text( - " \"web_ui_csrf_protection_enabled\": true,", - ), - Text( - " \"web_ui_custom_http_headers\": \"\",", - ), - Text( - " \"web_ui_domain_list\": \"*\",", - ), - Text( - " \"web_ui_host_header_validation_enabled\": true,", - ), - Text( - " \"web_ui_https_cert_path\": \"\",", - ), - Text( - " \"web_ui_https_key_path\": \"\",", - ), - Text( - " \"web_ui_max_auth_fail_count\": 5,", - ), - Text( - " \"web_ui_port\": 8080,", - ), - Text( - " \"web_ui_secure_cookie_enabled\": true,", - ), - Text( - " \"web_ui_session_timeout\": 3600,", - ), - Text( - " \"web_ui_upnp\": false,", - ), - Text( - " \"web_ui_use_custom_http_headers_enabled\": false,", - ), - Text( - " \"web_ui_username\": \"admin\"", - ), - Text( - "}", - ), - Text( - "```", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Set application preferences", - ), - content: [ - Text( - "", - ), - Text( - "Name: `setPreferences`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Text( - "A json object with key-value pairs of the settings you want to change and their new values.", - ), - Text( - "", - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "json={\"save_path\":\"C:/Users/Dayman/Downloads\",\"queueing_enabled\":false,\"scan_dirs\":{\"C:/Games\": 0,\"D:/Downloads\": 1}}", - ), - Text( - "```", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - Asterix( - "Notes**:", - ), - Text( - "", - ), - Text( - " 1. There is no need to pass all possible preferences' `token:value` pairs if you only want to change one option", - ), - Text( - " 1. Paths in `scan_dirs` must exist, otherwise this option will have no effect", - ), - Text( - " 1. String values must be quoted; integer and boolean values must never be quoted", - ), - Text( - "", - ), - Text( - "For a list of possible preference options see [Get application preferences](#get-application-preferences)", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get default save path", - ), - content: [ - Text( - "", - ), - Text( - "Name: `defaultSavePath`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Text( - "None", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - Text( - "The response is a string with the default save path, e.g. `C:/Users/Dayman/Downloads`.", - ), - Text( - "", - ), - ], - children: [], - }, - ], - }, - TokenTree { - title: Some( - "Log", - ), - content: [ - Text( - "", - ), - Text( - "All Log API methods are under \"log\", e.g.: `/api/v2/log/methodName`.", - ), - Text( - "", - ), - ], - children: [ - TokenTree { - title: Some( - "Get log", - ), - content: [ - Text( - "", - ), - Text( - "Name: `main`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------|---------|------------", - rows: [ - TableRow { - raw: "`normal` | bool | Include normal messages (default: `true`)", - columns: [ - "normal", - "bool", - "Include normal messages (default: true)", - ], - }, - TableRow { - raw: "`info` | bool | Include info messages (default: `true`)", - columns: [ - "info", - "bool", - "Include info messages (default: true)", - ], - }, - TableRow { - raw: "`warning` | bool | Include warning messages (default: `true`)", - columns: [ - "warning", - "bool", - "Include warning messages (default: true)", - ], - }, - TableRow { - raw: "`critical` | bool | Include critical messages (default: `true`)", - columns: [ - "critical", - "bool", - "Include critical messages (default: true)", - ], - }, - TableRow { - raw: "`last_known_id` | integer | Exclude messages with \"message id\" <= `last_known_id` (default: `-1`)", - columns: [ - "last_known_id", - "integer", - "Exclude messages with \"message id\" <= last_known_id (default: -1)", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "/api/v2/log/main?normal=true&info=true&warning=true&critical=true&last_known_id=-1", - ), - Text( - "```", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios- see JSON below", - columns: [ - "200", - "All scenarios- see JSON below", - ], - }, - ], - }, - ), - Text( - "The response is a JSON array in which each element is an entry of the log.", - ), - Text( - "", - ), - Text( - "Each element of the array has the following properties:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Property | Type | Description", - columns: [ - "Property", - "Type", - "Description", - ], - }, - split: "------------|---------|------------", - rows: [ - TableRow { - raw: "`id` | integer | ID of the message", - columns: [ - "id", - "integer", - "ID of the message", - ], - }, - TableRow { - raw: "`message` | string | Text of the message", - columns: [ - "message", - "string", - "Text of the message", - ], - }, - TableRow { - raw: "`timestamp` | integer | Milliseconds since epoch", - columns: [ - "timestamp", - "integer", - "Milliseconds since epoch", - ], - }, - TableRow { - raw: "`type` | integer | Type of the message: Log::NORMAL: `1`, Log::INFO: `2`, Log::WARNING: `4`, Log::CRITICAL: `8`", - columns: [ - "type", - "integer", - "Type of the message: Log::NORMAL: 1, Log::INFO: 2, Log::WARNING: 4, Log::CRITICAL: 8", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "[", - ), - Text( - " {", - ), - Text( - " \"id\":0,", - ), - Text( - " \"message\":\"qBittorrent v3.4.0 started\",", - ), - Text( - " \"timestamp\":1507969127860,", - ), - Text( - " \"type\":1", - ), - Text( - " },", - ), - Text( - " {", - ), - Text( - " \"id\":1,", - ), - Text( - " \"message\":\"qBittorrent is trying to listen on any interface port: 19036\",", - ), - Text( - " \"timestamp\":1507969127869,", - ), - Text( - " \"type\":2", - ), - Text( - " },", - ), - Text( - " {", - ), - Text( - " \"id\":2,", - ), - Text( - " \"message\":\"Peer ID: -qB3400-\",", - ), - Text( - " \"timestamp\":1507969127870,", - ), - Text( - " \"type\":1", - ), - Text( - " },", - ), - Text( - " {", - ), - Text( - " \"id\":3,", - ), - Text( - " \"message\":\"HTTP User-Agent is 'qBittorrent/3.4.0'\",", - ), - Text( - " \"timestamp\":1507969127870,", - ), - Text( - " \"type\":1", - ), - Text( - " },", - ), - Text( - " {", - ), - Text( - " \"id\":4,", - ), - Text( - " \"message\":\"DHT support [ON]\",", - ), - Text( - " \"timestamp\":1507969127871,", - ), - Text( - " \"type\":2", - ), - Text( - " },", - ), - Text( - " {", - ), - Text( - " \"id\":5,", - ), - Text( - " \"message\":\"Local Peer Discovery support [ON]\",", - ), - Text( - " \"timestamp\":1507969127871,", - ), - Text( - " \"type\":2", - ), - Text( - " },", - ), - Text( - " {", - ), - Text( - " \"id\":6,", - ), - Text( - " \"message\":\"PeX support [ON]\",", - ), - Text( - " \"timestamp\":1507969127871,", - ), - Text( - " \"type\":2", - ), - Text( - " },", - ), - Text( - " {", - ), - Text( - " \"id\":7,", - ), - Text( - " \"message\":\"Anonymous mode [OFF]\",", - ), - Text( - " \"timestamp\":1507969127871,", - ), - Text( - " \"type\":2", - ), - Text( - " },", - ), - Text( - " {", - ), - Text( - " \"id\":8,", - ), - Text( - " \"message\":\"Encryption support [ON]\",", - ), - Text( - " \"timestamp\":1507969127871,", - ), - Text( - " \"type\":2", - ), - Text( - " },", - ), - Text( - " {", - ), - Text( - " \"id\":9,", - ), - Text( - " \"message\":\"Embedded Tracker [OFF]\",", - ), - Text( - " \"timestamp\":1507969127871,", - ), - Text( - " \"type\":2", - ), - Text( - " },", - ), - Text( - " {", - ), - Text( - " \"id\":10,", - ), - Text( - " \"message\":\"UPnP / NAT-PMP support [ON]\",", - ), - Text( - " \"timestamp\":1507969127873,", - ), - Text( - " \"type\":2", - ), - Text( - " },", - ), - Text( - " {", - ), - Text( - " \"id\":11,", - ), - Text( - " \"message\":\"Web UI: Now listening on port 8080\",", - ), - Text( - " \"timestamp\":1507969127883,", - ), - Text( - " \"type\":1", - ), - Text( - " },", - ), - Text( - " {", - ), - Text( - " \"id\":12,", - ), - Text( - " \"message\":\"Options were saved successfully.\",", - ), - Text( - " \"timestamp\":1507969128055,", - ), - Text( - " \"type\":1", - ), - Text( - " },", - ), - Text( - " {", - ), - Text( - " \"id\":13,", - ), - Text( - " \"message\":\"qBittorrent is successfully listening on interface :: port: TCP/19036\",", - ), - Text( - " \"timestamp\":1507969128270,", - ), - Text( - " \"type\":2", - ), - Text( - " },", - ), - Text( - " {", - ), - Text( - " \"id\":14,", - ), - Text( - " \"message\":\"qBittorrent is successfully listening on interface 0.0.0.0 port: TCP/19036\",", - ), - Text( - " \"timestamp\":1507969128271,", - ), - Text( - " \"type\":2", - ), - Text( - " },", - ), - Text( - " {", - ), - Text( - " \"id\":15,", - ), - Text( - " \"message\":\"qBittorrent is successfully listening on interface 0.0.0.0 port: UDP/19036\",", - ), - Text( - " \"timestamp\":1507969128272,", - ), - Text( - " \"type\":2", - ), - Text( - " }", - ), - Text( - "]", - ), - Text( - "```", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get peer log", - ), - content: [ - Text( - "", - ), - Text( - "Name: `peers`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------|---------|------------", - rows: [ - TableRow { - raw: "`last_known_id` | integer | Exclude messages with \"message id\" <= `last_known_id` (default: `-1`)", - columns: [ - "last_known_id", - "integer", - "Exclude messages with \"message id\" <= last_known_id (default: -1)", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios- see JSON below", - columns: [ - "200", - "All scenarios- see JSON below", - ], - }, - ], - }, - ), - Text( - "The response a JSON array. Each element of the array of objects (each object is the information relative to a peer) containing the following fields", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Property | Type | Description", - columns: [ - "Property", - "Type", - "Description", - ], - }, - split: "------------|---------|------------", - rows: [ - TableRow { - raw: "`id` | integer | ID of the peer", - columns: [ - "id", - "integer", - "ID of the peer", - ], - }, - TableRow { - raw: "`ip` | string | IP of the peer", - columns: [ - "ip", - "string", - "IP of the peer", - ], - }, - TableRow { - raw: "`timestamp` | integer | Milliseconds since epoch", - columns: [ - "timestamp", - "integer", - "Milliseconds since epoch", - ], - }, - TableRow { - raw: "`blocked` | boolean | Whether or not the peer was blocked", - columns: [ - "blocked", - "boolean", - "Whether or not the peer was blocked", - ], - }, - TableRow { - raw: "`reason` | string | Reason of the block", - columns: [ - "reason", - "string", - "Reason of the block", - ], - }, - ], - }, - ), - ], - children: [], - }, - ], - }, - TokenTree { - title: Some( - "Sync", - ), - content: [ - Text( - "", - ), - Text( - "Sync API implements requests for obtaining changes since the last request.", - ), - Text( - "All Sync API methods are under \"sync\", e.g.: `/api/v2/sync/methodName`.", - ), - Text( - "", - ), - ], - children: [ - TokenTree { - title: Some( - "Get main data", - ), - content: [ - Text( - "", - ), - Text( - "Name: `maindata`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------|---------|------------", - rows: [ - TableRow { - raw: "`rid` | integer | Response ID. If not provided, `rid=0` will be assumed. If the given `rid` is different from the one of last server reply, `full_update` will be `true` (see the server reply details for more info)", - columns: [ - "rid", - "integer", - "Response ID. If not provided, rid=0 will be assumed. If the given rid is different from the one of last server reply, full_update will be true (see the server reply details for more info)", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "/api/v2/sync/maindata?rid=14", - ), - Text( - "```", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios- see JSON below", - columns: [ - "200", - "All scenarios- see JSON below", - ], - }, - ], - }, - ), - Text( - "The response is a JSON object with the following possible fields", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Property | Type | Description", - columns: [ - "Property", - "Type", - "Description", - ], - }, - split: "------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`rid` | integer | Response ID", - columns: [ - "rid", - "integer", - "Response ID", - ], - }, - TableRow { - raw: "`full_update` | bool | Whether the response contains all the data or partial data", - columns: [ - "full_update", - "bool", - "Whether the response contains all the data or partial data", - ], - }, - TableRow { - raw: "`torrents` | object | Property: torrent hash, value: same as [torrent list](#get-torrent-list)", - columns: [ - "torrents", - "object", - "Property: torrent hash, value: same as [torrent list](#get-torrent-list)", - ], - }, - TableRow { - raw: "`torrents_removed` | array | List of hashes of torrents removed since last request", - columns: [ - "torrents_removed", - "array", - "List of hashes of torrents removed since last request", - ], - }, - TableRow { - raw: "`categories` | object | Info for categories added since last request", - columns: [ - "categories", - "object", - "Info for categories added since last request", - ], - }, - TableRow { - raw: "`categories_removed` | array | List of categories removed since last request", - columns: [ - "categories_removed", - "array", - "List of categories removed since last request", - ], - }, - TableRow { - raw: "`tags` | array | List of tags added since last request", - columns: [ - "tags", - "array", - "List of tags added since last request", - ], - }, - TableRow { - raw: "`tags_removed` | array | List of tags removed since last request", - columns: [ - "tags_removed", - "array", - "List of tags removed since last request", - ], - }, - TableRow { - raw: "`server_state` | object | Global transfer info", - columns: [ - "server_state", - "object", - "Global transfer info", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "{", - ), - Text( - " \"rid\":15,", - ), - Text( - " \"torrents\":", - ), - Text( - " {", - ), - Text( - " \"8c212779b4abde7c6bc608063a0d008b7e40ce32\":", - ), - Text( - " {", - ), - Text( - " \"state\":\"pausedUP\"", - ), - Text( - " }", - ), - Text( - " }", - ), - Text( - "}", - ), - Text( - "```", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get torrent peers data", - ), - content: [ - Text( - "", - ), - Text( - "Name: `torrentPeers`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------|---------|------------", - rows: [ - TableRow { - raw: "`hash` | string | Torrent hash", - columns: [ - "hash", - "string", - "Torrent hash", - ], - }, - TableRow { - raw: "`rid` | integer | Response ID. If not provided, `rid=0` will be assumed. If the given `rid` is different from the one of last server reply, `full_update` will be `true` (see the server reply details for more info)", - columns: [ - "rid", - "integer", - "Response ID. If not provided, rid=0 will be assumed. If the given rid is different from the one of last server reply, full_update will be true (see the server reply details for more info)", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "/api/v2/sync/torrentPeers?hash=8c212779b4abde7c6bc608063a0d008b7e40ce32?rid=14", - ), - Text( - "```", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "404 | Torrent hash was not found", - columns: [ - "404", - "Torrent hash was not found", - ], - }, - TableRow { - raw: "200 | All other scenarios- see JSON below", - columns: [ - "200", - "All other scenarios- see JSON below", - ], - }, - ], - }, - ), - Text( - "The response is TODO", - ), - Text( - "", - ), - ], - children: [], - }, - ], - }, - TokenTree { - title: Some( - "Transfer info", - ), - content: [ - Text( - "", - ), - Text( - "All Transfer info API methods are under \"transfer\", e.g.: `/api/v2/transfer/methodName`.", - ), - Text( - "", - ), - ], - children: [ - TokenTree { - title: Some( - "Get global transfer info", - ), - content: [ - Text( - "", - ), - Text( - "This method returns info you usually see in qBt status bar.", - ), - Text( - "", - ), - Text( - "Name: `info`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Text( - "None", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios- see JSON below", - columns: [ - "200", - "All scenarios- see JSON below", - ], - }, - ], - }, - ), - Text( - "The response is a JSON object with the following fields", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Property | Type | Description", - columns: [ - "Property", - "Type", - "Description", - ], - }, - split: "--------------------|---------|------------", - rows: [ - TableRow { - raw: "`dl_info_speed` | integer | Global download rate (bytes/s)", - columns: [ - "dl_info_speed", - "integer", - "Global download rate (bytes/s)", - ], - }, - TableRow { - raw: "`dl_info_data` | integer | Data downloaded this session (bytes)", - columns: [ - "dl_info_data", - "integer", - "Data downloaded this session (bytes)", - ], - }, - TableRow { - raw: "`up_info_speed` | integer | Global upload rate (bytes/s)", - columns: [ - "up_info_speed", - "integer", - "Global upload rate (bytes/s)", - ], - }, - TableRow { - raw: "`up_info_data` | integer | Data uploaded this session (bytes)", - columns: [ - "up_info_data", - "integer", - "Data uploaded this session (bytes)", - ], - }, - TableRow { - raw: "`dl_rate_limit` | integer | Download rate limit (bytes/s)", - columns: [ - "dl_rate_limit", - "integer", - "Download rate limit (bytes/s)", - ], - }, - TableRow { - raw: "`up_rate_limit` | integer | Upload rate limit (bytes/s)", - columns: [ - "up_rate_limit", - "integer", - "Upload rate limit (bytes/s)", - ], - }, - TableRow { - raw: "`dht_nodes` | integer | DHT nodes connected to", - columns: [ - "dht_nodes", - "integer", - "DHT nodes connected to", - ], - }, - TableRow { - raw: "`connection_status` | string | Connection status. See possible values here below", - columns: [ - "connection_status", - "string", - "Connection status. See possible values here below", - ], - }, - ], - }, - ), - Text( - "In addition to the above in partial data requests (see [Get partial data](#get-partial-data) for more info):", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Property | Type | Description", - columns: [ - "Property", - "Type", - "Description", - ], - }, - split: "-----------------------|---------|------------", - rows: [ - TableRow { - raw: "`queueing` | bool | True if torrent queueing is enabled", - columns: [ - "queueing", - "bool", - "True if torrent queueing is enabled", - ], - }, - TableRow { - raw: "`use_alt_speed_limits` | bool | True if alternative speed limits are enabled", - columns: [ - "use_alt_speed_limits", - "bool", - "True if alternative speed limits are enabled", - ], - }, - TableRow { - raw: "`refresh_interval` | integer | Transfer list refresh interval (milliseconds)", - columns: [ - "refresh_interval", - "integer", - "Transfer list refresh interval (milliseconds)", - ], - }, - ], - }, - ), - Text( - "Possible values of `connection_status`:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Value |", - columns: [ - "Value", - "", - ], - }, - split: "--------------------|", - rows: [ - TableRow { - raw: "`connected` |", - columns: [ - "connected", - "", - ], - }, - TableRow { - raw: "`firewalled` |", - columns: [ - "firewalled", - "", - ], - }, - TableRow { - raw: "`disconnected` |", - columns: [ - "disconnected", - "", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "{", - ), - Text( - " \"connection_status\":\"connected\",", - ), - Text( - " \"dht_nodes\":386,", - ), - Text( - " \"dl_info_data\":681521119,", - ), - Text( - " \"dl_info_speed\":0,", - ), - Text( - " \"dl_rate_limit\":0,", - ), - Text( - " \"up_info_data\":10747904,", - ), - Text( - " \"up_info_speed\":0,", - ), - Text( - " \"up_rate_limit\":1048576", - ), - Text( - "}", - ), - Text( - "```", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get alternative speed limits state", - ), - content: [ - Text( - "", - ), - Text( - "Name: `speedLimitsMode`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Text( - "None", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - Text( - "The response is `1` if alternative speed limits are enabled, `0` otherwise.", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Toggle alternative speed limits", - ), - content: [ - Text( - "", - ), - Text( - "Name: `toggleSpeedLimitsMode`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Text( - "None", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get global download limit", - ), - content: [ - Text( - "", - ), - Text( - "Name: `downloadLimit`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Text( - "None", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - Text( - "The response is the value of current global download speed limit in bytes/second; this value will be zero if no limit is applied.", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Set global download limit", - ), - content: [ - Text( - "", - ), - Text( - "Name: `setDownloadLimit`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`limit` | integer | The global download speed limit to set in bytes/second", - columns: [ - "limit", - "integer", - "The global download speed limit to set in bytes/second", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get global upload limit", - ), - content: [ - Text( - "", - ), - Text( - "Name: `uploadLimit`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Text( - "None", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - Text( - "The response is the value of current global upload speed limit in bytes/second; this value will be zero if no limit is applied.", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Set global upload limit", - ), - content: [ - Text( - "", - ), - Text( - "Name: `setUploadLimit`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`limit` | integer | The global upload speed limit to set in bytes/second", - columns: [ - "limit", - "integer", - "The global upload speed limit to set in bytes/second", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Ban peers", - ), - content: [ - Text( - "", - ), - Text( - "Name: `banPeers`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`peers` | string | The peer to ban, or multiple peers separated by a pipe `\\|`. Each peer is a colon-separated `host:port`", - columns: [ - "peers", - "string", - "The peer to ban, or multiple peers separated by a pipe \\", - ". Each peer is a colon-separated host:port", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - ], - }, - TokenTree { - title: Some( - "Torrent management", - ), - content: [ - Text( - "", - ), - Text( - "All Torrent management API methods are under \"torrents\", e.g.: `/api/v2/torrents/methodName`.", - ), - Text( - "", - ), - ], - children: [ - TokenTree { - title: Some( - "Get torrent list", - ), - content: [ - Text( - "", - ), - Text( - "Name: `info`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------|---------|------------", - rows: [ - TableRow { - raw: "`filter` _optional_ | string | Filter torrent list by state. Allowed state filters: `all`, `downloading`, `seeding`, `completed`, `paused`, `active`, `inactive`, `resumed`, `stalled`, `stalled_uploading`, `stalled_downloading`, `errored`", - columns: [ - "filter _optional_", - "string", - "Filter torrent list by state. Allowed state filters: all, downloading, seeding, completed, paused, active, inactive, resumed, stalled, stalled_uploading, stalled_downloading, errored", - ], - }, - TableRow { - raw: "`category` _optional_ | string | Get torrents with the given category (empty string means \"without category\"; no \"category\" parameter means \"any category\" <- broken until [#11748](https://github.com/qbittorrent/qBittorrent/issues/11748) is resolved). Remember to URL-encode the category name. For example, `My category` becomes `My%20category`", - columns: [ - "category _optional_", - "string", - "Get torrents with the given category (empty string means \"without category\"; no \"category\" parameter means \"any category\" <- broken until [#11748](https://github.com/qbittorrent/qBittorrent/issues/11748) is resolved). Remember to URL-encode the category name. For example, My category becomes My%20category", - ], - }, - TableRow { - raw: "`tag` _optional_ since 2.8.3 | string | Get torrents with the given tag (empty string means \"without tag\"; no \"tag\" parameter means \"any tag\". Remember to URL-encode the category name. For example, `My tag` becomes `My%20tag`", - columns: [ - "tag _optional_ since 2.8.3", - "string", - "Get torrents with the given tag (empty string means \"without tag\"; no \"tag\" parameter means \"any tag\". Remember to URL-encode the category name. For example, My tag becomes My%20tag", - ], - }, - TableRow { - raw: "`sort` _optional_ | string | Sort torrents by given key. They can be sorted using any field of the response's JSON array (which are documented below) as the sort key.", - columns: [ - "sort _optional_", - "string", - "Sort torrents by given key. They can be sorted using any field of the response's JSON array (which are documented below) as the sort key.", - ], - }, - TableRow { - raw: "`reverse` _optional_ | bool | Enable reverse sorting. Defaults to `false`", - columns: [ - "reverse _optional_", - "bool", - "Enable reverse sorting. Defaults to false", - ], - }, - TableRow { - raw: "`limit` _optional_ | integer | Limit the number of torrents returned", - columns: [ - "limit _optional_", - "integer", - "Limit the number of torrents returned", - ], - }, - TableRow { - raw: "`offset` _optional_ | integer | Set offset (if less than 0, offset from end)", - columns: [ - "offset _optional_", - "integer", - "Set offset (if less than 0, offset from end)", - ], - }, - TableRow { - raw: "`hashes` _optional_ | string | Filter by hashes. Can contain multiple hashes separated by `\\|`", - columns: [ - "hashes _optional_", - "string", - "Filter by hashes. Can contain multiple hashes separated by \\", - "", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "/api/v2/torrents/info?filter=downloading&category=sample%20category&sort=ratio", - ), - Text( - "```", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios- see JSON below", - columns: [ - "200", - "All scenarios- see JSON below", - ], - }, - ], - }, - ), - Text( - "The response is a JSON array with the following fields", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Property | Type | Description", - columns: [ - "Property", - "Type", - "Description", - ], - }, - split: "---------------------|---------|------------", - rows: [ - TableRow { - raw: "`added_on` | integer | Time (Unix Epoch) when the torrent was added to the client", - columns: [ - "added_on", - "integer", - "Time (Unix Epoch) when the torrent was added to the client", - ], - }, - TableRow { - raw: "`amount_left` | integer | Amount of data left to download (bytes)", - columns: [ - "amount_left", - "integer", - "Amount of data left to download (bytes)", - ], - }, - TableRow { - raw: "`auto_tmm` | bool | Whether this torrent is managed by Automatic Torrent Management", - columns: [ - "auto_tmm", - "bool", - "Whether this torrent is managed by Automatic Torrent Management", - ], - }, - TableRow { - raw: "`availability` | float | Percentage of file pieces currently available", - columns: [ - "availability", - "float", - "Percentage of file pieces currently available", - ], - }, - TableRow { - raw: "`category` | string | Category of the torrent", - columns: [ - "category", - "string", - "Category of the torrent", - ], - }, - TableRow { - raw: "`completed` | integer | Amount of transfer data completed (bytes)", - columns: [ - "completed", - "integer", - "Amount of transfer data completed (bytes)", - ], - }, - TableRow { - raw: "`completion_on` | integer | Time (Unix Epoch) when the torrent completed", - columns: [ - "completion_on", - "integer", - "Time (Unix Epoch) when the torrent completed", - ], - }, - TableRow { - raw: "`content_path` | string | Absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents)", - columns: [ - "content_path", - "string", - "Absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents)", - ], - }, - TableRow { - raw: "`dl_limit` | integer | Torrent download speed limit (bytes/s). `-1` if ulimited.", - columns: [ - "dl_limit", - "integer", - "Torrent download speed limit (bytes/s). -1 if ulimited.", - ], - }, - TableRow { - raw: "`dlspeed` | integer | Torrent download speed (bytes/s)", - columns: [ - "dlspeed", - "integer", - "Torrent download speed (bytes/s)", - ], - }, - TableRow { - raw: "`downloaded` | integer | Amount of data downloaded", - columns: [ - "downloaded", - "integer", - "Amount of data downloaded", - ], - }, - TableRow { - raw: "`downloaded_session` | integer | Amount of data downloaded this session", - columns: [ - "downloaded_session", - "integer", - "Amount of data downloaded this session", - ], - }, - TableRow { - raw: "`eta` | integer | Torrent ETA (seconds)", - columns: [ - "eta", - "integer", - "Torrent ETA (seconds)", - ], - }, - TableRow { - raw: "`f_l_piece_prio` | bool | True if first last piece are prioritized", - columns: [ - "f_l_piece_prio", - "bool", - "True if first last piece are prioritized", - ], - }, - TableRow { - raw: "`force_start` | bool | True if force start is enabled for this torrent", - columns: [ - "force_start", - "bool", - "True if force start is enabled for this torrent", - ], - }, - TableRow { - raw: "`hash` | string | Torrent hash", - columns: [ - "hash", - "string", - "Torrent hash", - ], - }, - TableRow { - raw: "`last_activity` | integer | Last time (Unix Epoch) when a chunk was downloaded/uploaded", - columns: [ - "last_activity", - "integer", - "Last time (Unix Epoch) when a chunk was downloaded/uploaded", - ], - }, - TableRow { - raw: "`magnet_uri` | string | Magnet URI corresponding to this torrent", - columns: [ - "magnet_uri", - "string", - "Magnet URI corresponding to this torrent", - ], - }, - TableRow { - raw: "`max_ratio` | float | Maximum share ratio until torrent is stopped from seeding/uploading", - columns: [ - "max_ratio", - "float", - "Maximum share ratio until torrent is stopped from seeding/uploading", - ], - }, - TableRow { - raw: "`max_seeding_time` | integer | Maximum seeding time (seconds) until torrent is stopped from seeding", - columns: [ - "max_seeding_time", - "integer", - "Maximum seeding time (seconds) until torrent is stopped from seeding", - ], - }, - TableRow { - raw: "`name` | string | Torrent name", - columns: [ - "name", - "string", - "Torrent name", - ], - }, - TableRow { - raw: "`num_complete` | integer | Number of seeds in the swarm", - columns: [ - "num_complete", - "integer", - "Number of seeds in the swarm", - ], - }, - TableRow { - raw: "`num_incomplete` | integer | Number of leechers in the swarm", - columns: [ - "num_incomplete", - "integer", - "Number of leechers in the swarm", - ], - }, - TableRow { - raw: "`num_leechs` | integer | Number of leechers connected to", - columns: [ - "num_leechs", - "integer", - "Number of leechers connected to", - ], - }, - TableRow { - raw: "`num_seeds` | integer | Number of seeds connected to", - columns: [ - "num_seeds", - "integer", - "Number of seeds connected to", - ], - }, - TableRow { - raw: "`priority` | integer | Torrent priority. Returns -1 if queuing is disabled or torrent is in seed mode", - columns: [ - "priority", - "integer", - "Torrent priority. Returns -1 if queuing is disabled or torrent is in seed mode", - ], - }, - TableRow { - raw: "`progress` | float | Torrent progress (percentage/100)", - columns: [ - "progress", - "float", - "Torrent progress (percentage/100)", - ], - }, - TableRow { - raw: "`ratio` | float | Torrent share ratio. Max ratio value: 9999.", - columns: [ - "ratio", - "float", - "Torrent share ratio. Max ratio value: 9999.", - ], - }, - TableRow { - raw: "`ratio_limit` | float | TODO (what is different from `max_ratio`?)", - columns: [ - "ratio_limit", - "float", - "TODO (what is different from max_ratio?)", - ], - }, - TableRow { - raw: "`save_path` | string | Path where this torrent's data is stored", - columns: [ - "save_path", - "string", - "Path where this torrent's data is stored", - ], - }, - TableRow { - raw: "`seeding_time` | integer | Torrent elapsed time while complete (seconds)", - columns: [ - "seeding_time", - "integer", - "Torrent elapsed time while complete (seconds)", - ], - }, - TableRow { - raw: "`seeding_time_limit` | integer | TODO (what is different from `max_seeding_time`?) seeding_time_limit is a per torrent setting, when Automatic Torrent Management is disabled, furthermore then max_seeding_time is set to seeding_time_limit for this torrent. If Automatic Torrent Management is enabled, the value is -2. And if max_seeding_time is unset it have a default value -1.", - columns: [ - "seeding_time_limit", - "integer", - "TODO (what is different from max_seeding_time?) seeding_time_limit is a per torrent setting, when Automatic Torrent Management is disabled, furthermore then max_seeding_time is set to seeding_time_limit for this torrent. If Automatic Torrent Management is enabled, the value is -2. And if max_seeding_time is unset it have a default value -1.", - ], - }, - TableRow { - raw: "`seen_complete` | integer | Time (Unix Epoch) when this torrent was last seen complete", - columns: [ - "seen_complete", - "integer", - "Time (Unix Epoch) when this torrent was last seen complete", - ], - }, - TableRow { - raw: "`seq_dl` | bool | True if sequential download is enabled", - columns: [ - "seq_dl", - "bool", - "True if sequential download is enabled", - ], - }, - TableRow { - raw: "`size` | integer | Total size (bytes) of files selected for download", - columns: [ - "size", - "integer", - "Total size (bytes) of files selected for download", - ], - }, - TableRow { - raw: "`state` | string | Torrent state. See table here below for the possible values", - columns: [ - "state", - "string", - "Torrent state. See table here below for the possible values", - ], - }, - TableRow { - raw: "`super_seeding` | bool | True if super seeding is enabled", - columns: [ - "super_seeding", - "bool", - "True if super seeding is enabled", - ], - }, - TableRow { - raw: "`tags` | string | Comma-concatenated tag list of the torrent", - columns: [ - "tags", - "string", - "Comma-concatenated tag list of the torrent", - ], - }, - TableRow { - raw: "`time_active` | integer | Total active time (seconds)", - columns: [ - "time_active", - "integer", - "Total active time (seconds)", - ], - }, - TableRow { - raw: "`total_size` | integer | Total size (bytes) of all file in this torrent (including unselected ones)", - columns: [ - "total_size", - "integer", - "Total size (bytes) of all file in this torrent (including unselected ones)", - ], - }, - TableRow { - raw: "`tracker` | string | The first tracker with working status. Returns empty string if no tracker is working.", - columns: [ - "tracker", - "string", - "The first tracker with working status. Returns empty string if no tracker is working.", - ], - }, - TableRow { - raw: "`up_limit` | integer | Torrent upload speed limit (bytes/s). `-1` if ulimited.", - columns: [ - "up_limit", - "integer", - "Torrent upload speed limit (bytes/s). -1 if ulimited.", - ], - }, - TableRow { - raw: "`uploaded` | integer | Amount of data uploaded", - columns: [ - "uploaded", - "integer", - "Amount of data uploaded", - ], - }, - TableRow { - raw: "`uploaded_session` | integer | Amount of data uploaded this session", - columns: [ - "uploaded_session", - "integer", - "Amount of data uploaded this session", - ], - }, - TableRow { - raw: "`upspeed` | integer | Torrent upload speed (bytes/s)", - columns: [ - "upspeed", - "integer", - "Torrent upload speed (bytes/s)", - ], - }, - ], - }, - ), - Text( - "Possible values of `state`:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Value | Description", - columns: [ - "Value", - "Description", - ], - }, - split: "--------------|------------", - rows: [ - TableRow { - raw: "`error` | Some error occurred, applies to paused torrents", - columns: [ - "error", - "Some error occurred, applies to paused torrents", - ], - }, - TableRow { - raw: "`missingFiles`| Torrent data files is missing", - columns: [ - "missingFiles", - "Torrent data files is missing", - ], - }, - TableRow { - raw: "`uploading` | Torrent is being seeded and data is being transferred", - columns: [ - "uploading", - "Torrent is being seeded and data is being transferred", - ], - }, - TableRow { - raw: "`pausedUP` | Torrent is paused and has finished downloading", - columns: [ - "pausedUP", - "Torrent is paused and has finished downloading", - ], - }, - TableRow { - raw: "`queuedUP` | Queuing is enabled and torrent is queued for upload", - columns: [ - "queuedUP", - "Queuing is enabled and torrent is queued for upload", - ], - }, - TableRow { - raw: "`stalledUP` | Torrent is being seeded, but no connection were made", - columns: [ - "stalledUP", - "Torrent is being seeded, but no connection were made", - ], - }, - TableRow { - raw: "`checkingUP` | Torrent has finished downloading and is being checked", - columns: [ - "checkingUP", - "Torrent has finished downloading and is being checked", - ], - }, - TableRow { - raw: "`forcedUP` | Torrent is forced to uploading and ignore queue limit", - columns: [ - "forcedUP", - "Torrent is forced to uploading and ignore queue limit", - ], - }, - TableRow { - raw: "`allocating` | Torrent is allocating disk space for download", - columns: [ - "allocating", - "Torrent is allocating disk space for download", - ], - }, - TableRow { - raw: "`downloading` | Torrent is being downloaded and data is being transferred", - columns: [ - "downloading", - "Torrent is being downloaded and data is being transferred", - ], - }, - TableRow { - raw: "`metaDL` | Torrent has just started downloading and is fetching metadata", - columns: [ - "metaDL", - "Torrent has just started downloading and is fetching metadata", - ], - }, - TableRow { - raw: "`pausedDL` | Torrent is paused and has NOT finished downloading", - columns: [ - "pausedDL", - "Torrent is paused and has NOT finished downloading", - ], - }, - TableRow { - raw: "`queuedDL` | Queuing is enabled and torrent is queued for download", - columns: [ - "queuedDL", - "Queuing is enabled and torrent is queued for download", - ], - }, - TableRow { - raw: "`stalledDL` | Torrent is being downloaded, but no connection were made", - columns: [ - "stalledDL", - "Torrent is being downloaded, but no connection were made", - ], - }, - TableRow { - raw: "`checkingDL` | Same as checkingUP, but torrent has NOT finished downloading", - columns: [ - "checkingDL", - "Same as checkingUP, but torrent has NOT finished downloading", - ], - }, - TableRow { - raw: "`forcedDL` | Torrent is forced to downloading to ignore queue limit", - columns: [ - "forcedDL", - "Torrent is forced to downloading to ignore queue limit", - ], - }, - TableRow { - raw: "`checkingResumeData`| Checking resume data on qBt startup", - columns: [ - "checkingResumeData", - "Checking resume data on qBt startup", - ], - }, - TableRow { - raw: "`moving` | Torrent is moving to another location", - columns: [ - "moving", - "Torrent is moving to another location", - ], - }, - TableRow { - raw: "`unknown` | Unknown status", - columns: [ - "unknown", - "Unknown status", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "[", - ), - Text( - " {", - ), - Text( - " \"dlspeed\":9681262,", - ), - Text( - " \"eta\":87,", - ), - Text( - " \"f_l_piece_prio\":false,", - ), - Text( - " \"force_start\":false,", - ), - Text( - " \"hash\":\"8c212779b4abde7c6bc608063a0d008b7e40ce32\",", - ), - Text( - " \"category\":\"\",", - ), - Text( - " \"tags\": \"\",", - ), - Text( - " \"name\":\"debian-8.1.0-amd64-CD-1.iso\",", - ), - Text( - " \"num_complete\":-1,", - ), - Text( - " \"num_incomplete\":-1,", - ), - Text( - " \"num_leechs\":2,", - ), - Text( - " \"num_seeds\":54,", - ), - Text( - " \"priority\":1,", - ), - Text( - " \"progress\":0.16108787059783936,", - ), - Text( - " \"ratio\":0,", - ), - Text( - " \"seq_dl\":false,", - ), - Text( - " \"size\":657457152,", - ), - Text( - " \"state\":\"downloading\",", - ), - Text( - " \"super_seeding\":false,", - ), - Text( - " \"upspeed\":0", - ), - Text( - " },", - ), - Text( - " {", - ), - Text( - " another_torrent_info", - ), - Text( - " }", - ), - Text( - "]", - ), - Text( - "```", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get torrent generic properties", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `properties`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------|--------|------------", - rows: [ - TableRow { - raw: "`hash` | string | The hash of the torrent you want to get the generic properties of", - columns: [ - "hash", - "string", - "The hash of the torrent you want to get the generic properties of", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "404 | Torrent hash was not found", - columns: [ - "404", - "Torrent hash was not found", - ], - }, - TableRow { - raw: "200 | All other scenarios- see JSON below", - columns: [ - "200", - "All other scenarios- see JSON below", - ], - }, - ], - }, - ), - Text( - "The response is:", - ), - Text( - "", - ), - Text( - "- empty, if the torrent hash is invalid", - ), - Text( - "- otherwise, a JSON object with the following fields", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Property | Type | Description", - columns: [ - "Property", - "Type", - "Description", - ], - }, - split: "--------------------------|---------|------------", - rows: [ - TableRow { - raw: "`save_path` | string | Torrent save path", - columns: [ - "save_path", - "string", - "Torrent save path", - ], - }, - TableRow { - raw: "`creation_date` | integer | Torrent creation date (Unix timestamp)", - columns: [ - "creation_date", - "integer", - "Torrent creation date (Unix timestamp)", - ], - }, - TableRow { - raw: "`piece_size` | integer | Torrent piece size (bytes)", - columns: [ - "piece_size", - "integer", - "Torrent piece size (bytes)", - ], - }, - TableRow { - raw: "`comment` | string | Torrent comment", - columns: [ - "comment", - "string", - "Torrent comment", - ], - }, - TableRow { - raw: "`total_wasted` | integer | Total data wasted for torrent (bytes)", - columns: [ - "total_wasted", - "integer", - "Total data wasted for torrent (bytes)", - ], - }, - TableRow { - raw: "`total_uploaded` | integer | Total data uploaded for torrent (bytes)", - columns: [ - "total_uploaded", - "integer", - "Total data uploaded for torrent (bytes)", - ], - }, - TableRow { - raw: "`total_uploaded_session` | integer | Total data uploaded this session (bytes)", - columns: [ - "total_uploaded_session", - "integer", - "Total data uploaded this session (bytes)", - ], - }, - TableRow { - raw: "`total_downloaded` | integer | Total data downloaded for torrent (bytes)", - columns: [ - "total_downloaded", - "integer", - "Total data downloaded for torrent (bytes)", - ], - }, - TableRow { - raw: "`total_downloaded_session`| integer | Total data downloaded this session (bytes)", - columns: [ - "total_downloaded_session", - "integer", - "Total data downloaded this session (bytes)", - ], - }, - TableRow { - raw: "`up_limit` | integer | Torrent upload limit (bytes/s)", - columns: [ - "up_limit", - "integer", - "Torrent upload limit (bytes/s)", - ], - }, - TableRow { - raw: "`dl_limit` | integer | Torrent download limit (bytes/s)", - columns: [ - "dl_limit", - "integer", - "Torrent download limit (bytes/s)", - ], - }, - TableRow { - raw: "`time_elapsed` | integer | Torrent elapsed time (seconds)", - columns: [ - "time_elapsed", - "integer", - "Torrent elapsed time (seconds)", - ], - }, - TableRow { - raw: "`seeding_time` | integer | Torrent elapsed time while complete (seconds)", - columns: [ - "seeding_time", - "integer", - "Torrent elapsed time while complete (seconds)", - ], - }, - TableRow { - raw: "`nb_connections` | integer | Torrent connection count", - columns: [ - "nb_connections", - "integer", - "Torrent connection count", - ], - }, - TableRow { - raw: "`nb_connections_limit` | integer | Torrent connection count limit", - columns: [ - "nb_connections_limit", - "integer", - "Torrent connection count limit", - ], - }, - TableRow { - raw: "`share_ratio` | float | Torrent share ratio", - columns: [ - "share_ratio", - "float", - "Torrent share ratio", - ], - }, - TableRow { - raw: "`addition_date` | integer | When this torrent was added (unix timestamp)", - columns: [ - "addition_date", - "integer", - "When this torrent was added (unix timestamp)", - ], - }, - TableRow { - raw: "`completion_date` | integer | Torrent completion date (unix timestamp)", - columns: [ - "completion_date", - "integer", - "Torrent completion date (unix timestamp)", - ], - }, - TableRow { - raw: "`created_by` | string | Torrent creator", - columns: [ - "created_by", - "string", - "Torrent creator", - ], - }, - TableRow { - raw: "`dl_speed_avg` | integer | Torrent average download speed (bytes/second)", - columns: [ - "dl_speed_avg", - "integer", - "Torrent average download speed (bytes/second)", - ], - }, - TableRow { - raw: "`dl_speed` | integer | Torrent download speed (bytes/second)", - columns: [ - "dl_speed", - "integer", - "Torrent download speed (bytes/second)", - ], - }, - TableRow { - raw: "`eta` | integer | Torrent ETA (seconds)", - columns: [ - "eta", - "integer", - "Torrent ETA (seconds)", - ], - }, - TableRow { - raw: "`last_seen` | integer | Last seen complete date (unix timestamp)", - columns: [ - "last_seen", - "integer", - "Last seen complete date (unix timestamp)", - ], - }, - TableRow { - raw: "`peers` | integer | Number of peers connected to", - columns: [ - "peers", - "integer", - "Number of peers connected to", - ], - }, - TableRow { - raw: "`peers_total` | integer | Number of peers in the swarm", - columns: [ - "peers_total", - "integer", - "Number of peers in the swarm", - ], - }, - TableRow { - raw: "`pieces_have` | integer | Number of pieces owned", - columns: [ - "pieces_have", - "integer", - "Number of pieces owned", - ], - }, - TableRow { - raw: "`pieces_num` | integer | Number of pieces of the torrent", - columns: [ - "pieces_num", - "integer", - "Number of pieces of the torrent", - ], - }, - TableRow { - raw: "`reannounce` | integer | Number of seconds until the next announce", - columns: [ - "reannounce", - "integer", - "Number of seconds until the next announce", - ], - }, - TableRow { - raw: "`seeds` | integer | Number of seeds connected to", - columns: [ - "seeds", - "integer", - "Number of seeds connected to", - ], - }, - TableRow { - raw: "`seeds_total` | integer | Number of seeds in the swarm", - columns: [ - "seeds_total", - "integer", - "Number of seeds in the swarm", - ], - }, - TableRow { - raw: "`total_size` | integer | Torrent total size (bytes)", - columns: [ - "total_size", - "integer", - "Torrent total size (bytes)", - ], - }, - TableRow { - raw: "`up_speed_avg` | integer | Torrent average upload speed (bytes/second)", - columns: [ - "up_speed_avg", - "integer", - "Torrent average upload speed (bytes/second)", - ], - }, - TableRow { - raw: "`up_speed` | integer | Torrent upload speed (bytes/second)", - columns: [ - "up_speed", - "integer", - "Torrent upload speed (bytes/second)", - ], - }, - ], - }, - ), - Text( - "NB: `-1` is returned if the type of the property is integer but its value is not known.", - ), - Text( - "", - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "{", - ), - Text( - " \"addition_date\":1438429165,", - ), - Text( - " \"comment\":\"\\\"Debian CD from cdimage.debian.org\\\"\",", - ), - Text( - " \"completion_date\":1438429234,", - ), - Text( - " \"created_by\":\"\",", - ), - Text( - " \"creation_date\":1433605214,", - ), - Text( - " \"dl_limit\":-1,", - ), - Text( - " \"dl_speed\":0,", - ), - Text( - " \"dl_speed_avg\":9736015,", - ), - Text( - " \"eta\":8640000,", - ), - Text( - " \"last_seen\":1438430354,", - ), - Text( - " \"nb_connections\":3,", - ), - Text( - " \"nb_connections_limit\":250,", - ), - Text( - " \"peers\":1,", - ), - Text( - " \"peers_total\":89,", - ), - Text( - " \"piece_size\":524288,", - ), - Text( - " \"pieces_have\":1254,", - ), - Text( - " \"pieces_num\":1254,", - ), - Text( - " \"reannounce\":672,", - ), - Text( - " \"save_path\":\"/Downloads/debian-8.1.0-amd64-CD-1.iso\",", - ), - Text( - " \"seeding_time\":1128,", - ), - Text( - " \"seeds\":1,", - ), - Text( - " \"seeds_total\":254,", - ), - Text( - " \"share_ratio\":0.00072121022562178299,", - ), - Text( - " \"time_elapsed\":1197,", - ), - Text( - " \"total_downloaded\":681521119,", - ), - Text( - " \"total_downloaded_session\":681521119,", - ), - Text( - " \"total_size\":657457152,", - ), - Text( - " \"total_uploaded\":491520,", - ), - Text( - " \"total_uploaded_session\":491520,", - ), - Text( - " \"total_wasted\":23481724,", - ), - Text( - " \"up_limit\":-1,", - ), - Text( - " \"up_speed\":0,", - ), - Text( - " \"up_speed_avg\":410", - ), - Text( - "}", - ), - Text( - "```", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get torrent trackers", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `trackers`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------|--------|------------", - rows: [ - TableRow { - raw: "`hash` | string | The hash of the torrent you want to get the trackers of", - columns: [ - "hash", - "string", - "The hash of the torrent you want to get the trackers of", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "404 | Torrent hash was not found", - columns: [ - "404", - "Torrent hash was not found", - ], - }, - TableRow { - raw: "200 | All other scenarios- see JSON below", - columns: [ - "200", - "All other scenarios- see JSON below", - ], - }, - ], - }, - ), - Text( - "The response is a JSON array, where each element contains info about one tracker, with the following fields", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Property | Type | Description", - columns: [ - "Property", - "Type", - "Description", - ], - }, - split: "-----------------|----------|-------------", - rows: [ - TableRow { - raw: "`url` | string | Tracker url", - columns: [ - "url", - "string", - "Tracker url", - ], - }, - TableRow { - raw: "`status` | integer | Tracker status. See the table below for possible values", - columns: [ - "status", - "integer", - "Tracker status. See the table below for possible values", - ], - }, - TableRow { - raw: "`tier` | integer | Tracker priority tier. Lower tier trackers are tried before higher tiers. Tier numbers are valid when `>= 0`, `< 0` is used as placeholder when `tier` does not exist for special entries (such as DHT).", - columns: [ - "tier", - "integer", - "Tracker priority tier. Lower tier trackers are tried before higher tiers. Tier numbers are valid when >= 0, < 0 is used as placeholder when tier does not exist for special entries (such as DHT).", - ], - }, - TableRow { - raw: "`num_peers` | integer | Number of peers for current torrent, as reported by the tracker", - columns: [ - "num_peers", - "integer", - "Number of peers for current torrent, as reported by the tracker", - ], - }, - TableRow { - raw: "`num_seeds` | integer | Number of seeds for current torrent, asreported by the tracker", - columns: [ - "num_seeds", - "integer", - "Number of seeds for current torrent, asreported by the tracker", - ], - }, - TableRow { - raw: "`num_leeches` | integer | Number of leeches for current torrent, as reported by the tracker", - columns: [ - "num_leeches", - "integer", - "Number of leeches for current torrent, as reported by the tracker", - ], - }, - TableRow { - raw: "`num_downloaded` | integer | Number of completed downlods for current torrent, as reported by the tracker", - columns: [ - "num_downloaded", - "integer", - "Number of completed downlods for current torrent, as reported by the tracker", - ], - }, - TableRow { - raw: "`msg` | string | Tracker message (there is no way of knowing what this message is - it's up to tracker admins)", - columns: [ - "msg", - "string", - "Tracker message (there is no way of knowing what this message is - it's up to tracker admins)", - ], - }, - ], - }, - ), - Text( - "Possible values of `status`:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Value | Description", - columns: [ - "Value", - "Description", - ], - }, - split: "-------|------------", - rows: [ - TableRow { - raw: "0 | Tracker is disabled (used for DHT, PeX, and LSD)", - columns: [ - "0", - "Tracker is disabled (used for DHT, PeX, and LSD)", - ], - }, - TableRow { - raw: "1 | Tracker has not been contacted yet", - columns: [ - "1", - "Tracker has not been contacted yet", - ], - }, - TableRow { - raw: "2 | Tracker has been contacted and is working", - columns: [ - "2", - "Tracker has been contacted and is working", - ], - }, - TableRow { - raw: "3 | Tracker is updating", - columns: [ - "3", - "Tracker is updating", - ], - }, - TableRow { - raw: "4 | Tracker has been contacted, but it is not working (or doesn't send proper replies)", - columns: [ - "4", - "Tracker has been contacted, but it is not working (or doesn't send proper replies)", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "[", - ), - Text( - " {", - ), - Text( - " \"msg\":\"\",", - ), - Text( - " \"num_peers\":100,", - ), - Text( - " \"status\":2,", - ), - Text( - " \"url\":\"http://bttracker.debian.org:6969/announce\"", - ), - Text( - " },", - ), - Text( - " {", - ), - Text( - " another_tracker_info", - ), - Text( - " }", - ), - Text( - "]", - ), - Text( - "```", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get torrent web seeds", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `webseeds`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------|--------|------------", - rows: [ - TableRow { - raw: "`hash` | string | The hash of the torrent you want to get the webseeds of", - columns: [ - "hash", - "string", - "The hash of the torrent you want to get the webseeds of", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "404 | Torrent hash was not found", - columns: [ - "404", - "Torrent hash was not found", - ], - }, - TableRow { - raw: "200 | All other scenarios- see JSON below", - columns: [ - "200", - "All other scenarios- see JSON below", - ], - }, - ], - }, - ), - Text( - "The response is a JSON array, where each element is information about one webseed, with the following fields", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Property | Type | Description", - columns: [ - "Property", - "Type", - "Description", - ], - }, - split: "--------------|----------|------------", - rows: [ - TableRow { - raw: "`url` | string | URL of the web seed", - columns: [ - "url", - "string", - "URL of the web seed", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "[", - ), - Text( - " {", - ), - Text( - " \"url\":\"http://some_url/\"", - ), - Text( - " },", - ), - Text( - " {", - ), - Text( - " \"url\":\"http://some_other_url/\"", - ), - Text( - " }", - ), - Text( - "]", - ), - Text( - "```", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get torrent contents", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `files`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------|--------|------------", - rows: [ - TableRow { - raw: "`hash` | string | The hash of the torrent you want to get the contents of", - columns: [ - "hash", - "string", - "The hash of the torrent you want to get the contents of", - ], - }, - TableRow { - raw: "`indexes` _optional_ since 2.8.2 | string | The indexes of the files you want to retrieve. `indexes` can contain multiple values separated by `\\|`.", - columns: [ - "indexes _optional_ since 2.8.2", - "string", - "The indexes of the files you want to retrieve. indexes can contain multiple values separated by \\", - ".", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "404 | Torrent hash was not found", - columns: [ - "404", - "Torrent hash was not found", - ], - }, - TableRow { - raw: "200 | All other scenarios- see JSON below", - columns: [ - "200", - "All other scenarios- see JSON below", - ], - }, - ], - }, - ), - Text( - "The response is:", - ), - Text( - "", - ), - Text( - "- empty, if the torrent hash is invalid", - ), - Text( - "- otherwise, a JSON array, where each element contains info about one file, with the following fields", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Property | Type | Description", - columns: [ - "Property", - "Type", - "Description", - ], - }, - split: "---------------|---------------|-------------", - rows: [ - TableRow { - raw: "`index` since 2.8.2 | integer | File index", - columns: [ - "index since 2.8.2", - "integer", - "File index", - ], - }, - TableRow { - raw: "`name` | string | File name (including relative path)", - columns: [ - "name", - "string", - "File name (including relative path)", - ], - }, - TableRow { - raw: "`size` | integer | File size (bytes)", - columns: [ - "size", - "integer", - "File size (bytes)", - ], - }, - TableRow { - raw: "`progress` | float | File progress (percentage/100)", - columns: [ - "progress", - "float", - "File progress (percentage/100)", - ], - }, - TableRow { - raw: "`priority` | integer | File priority. See possible values here below", - columns: [ - "priority", - "integer", - "File priority. See possible values here below", - ], - }, - TableRow { - raw: "`is_seed` | bool | True if file is seeding/complete", - columns: [ - "is_seed", - "bool", - "True if file is seeding/complete", - ], - }, - TableRow { - raw: "`piece_range` | integer array | The first number is the starting piece index and the second number is the ending piece index (inclusive)", - columns: [ - "piece_range", - "integer array", - "The first number is the starting piece index and the second number is the ending piece index (inclusive)", - ], - }, - TableRow { - raw: "`availability` | float | Percentage of file pieces currently available (percentage/100)", - columns: [ - "availability", - "float", - "Percentage of file pieces currently available (percentage/100)", - ], - }, - ], - }, - ), - Text( - "Possible values of `priority`:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Value | Description", - columns: [ - "Value", - "Description", - ], - }, - split: "-----------|------------", - rows: [ - TableRow { - raw: "`0` | Do not download", - columns: [ - "0", - "Do not download", - ], - }, - TableRow { - raw: "`1` | Normal priority", - columns: [ - "1", - "Normal priority", - ], - }, - TableRow { - raw: "`6` | High priority", - columns: [ - "6", - "High priority", - ], - }, - TableRow { - raw: "`7` | Maximal priority", - columns: [ - "7", - "Maximal priority", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "", - ), - Text( - "[", - ), - Text( - " {", - ), - Text( - " \"index\":0,", - ), - Text( - " \"is_seed\":false,", - ), - Text( - " \"name\":\"debian-8.1.0-amd64-CD-1.iso\",", - ), - Text( - " \"piece_range\":[0,1253],", - ), - Text( - " \"priority\":1,", - ), - Text( - " \"progress\":0,", - ), - Text( - " \"size\":657457152,", - ), - Text( - " \"availability\":0.5,", - ), - Text( - " }", - ), - Text( - "]", - ), - Text( - "```", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get torrent pieces' states", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `pieceStates`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------|--------|------------", - rows: [ - TableRow { - raw: "`hash` | string | The hash of the torrent you want to get the pieces' states of", - columns: [ - "hash", - "string", - "The hash of the torrent you want to get the pieces' states of", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "404 | Torrent hash was not found", - columns: [ - "404", - "Torrent hash was not found", - ], - }, - TableRow { - raw: "200 | All other scenarios- see JSON below", - columns: [ - "200", - "All other scenarios- see JSON below", - ], - }, - ], - }, - ), - Text( - "The response is:", - ), - Text( - "", - ), - Text( - "- empty, if the torrent hash is invalid", - ), - Text( - "- otherwise, an array of states (integers) of all pieces (in order) of a specific torrent.", - ), - Text( - "", - ), - Text( - "Value meanings are defined as below:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Value | Description", - columns: [ - "Value", - "Description", - ], - }, - split: "-----------|------------", - rows: [ - TableRow { - raw: "`0` | Not downloaded yet", - columns: [ - "0", - "Not downloaded yet", - ], - }, - TableRow { - raw: "`1` | Now downloading", - columns: [ - "1", - "Now downloading", - ], - }, - TableRow { - raw: "`2` | Already downloaded", - columns: [ - "2", - "Already downloaded", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "[0,0,2,1,0,0,2,1]", - ), - Text( - "```", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get torrent pieces' hashes", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `pieceHashes`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------|--------|------------", - rows: [ - TableRow { - raw: "`hash` | string | The hash of the torrent you want to get the pieces' hashes of", - columns: [ - "hash", - "string", - "The hash of the torrent you want to get the pieces' hashes of", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "404 | Torrent hash was not found", - columns: [ - "404", - "Torrent hash was not found", - ], - }, - TableRow { - raw: "200 | All other scenarios- see JSON below", - columns: [ - "200", - "All other scenarios- see JSON below", - ], - }, - ], - }, - ), - Text( - "The response is:", - ), - Text( - "", - ), - Text( - "- empty, if the torrent hash is invalid", - ), - Text( - "- otherwise, an array of hashes (strings) of all pieces (in order) of a specific torrent.", - ), - Text( - "", - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "[\"54eddd830a5b58480a6143d616a97e3a6c23c439\",\"f8a99d225aa4241db100f88407fc3bdaead583ab\",\"928fb615b9bd4dd8f9e9022552c8f8f37ef76f58\"]", - ), - Text( - "```", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Pause torrents", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hashes. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `pause`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "------------|----------|------------", - rows: [ - TableRow { - raw: "`hashes` | string | The hashes of the torrents you want to pause. `hashes` can contain multiple hashes separated by `\\|`, to pause multiple torrents, or set to `all`, to pause all torrents.", - columns: [ - "hashes", - "string", - "The hashes of the torrents you want to pause. hashes can contain multiple hashes separated by \\", - ", to pause multiple torrents, or set to all, to pause all torrents.", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```http", - ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/pause?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/pause?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Resume torrents", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hashes. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `resume`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "------------|----------|------------", - rows: [ - TableRow { - raw: "`hashes` | string | The hashes of the torrents you want to resume. `hashes` can contain multiple hashes separated by `\\|`, to resume multiple torrents, or set to `all`, to resume all torrents.", - columns: [ - "hashes", - "string", - "The hashes of the torrents you want to resume. hashes can contain multiple hashes separated by \\", - ", to resume multiple torrents, or set to all, to resume all torrents.", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```http", - ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/resume?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/resume?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Delete torrents", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hashes. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `delete`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "------------|----------|------------", - rows: [ - TableRow { - raw: "`hashes` | string | The hashes of the torrents you want to delete. `hashes` can contain multiple hashes separated by `\\|`, to delete multiple torrents, or set to `all`, to delete all torrents.", - columns: [ - "hashes", - "string", - "The hashes of the torrents you want to delete. hashes can contain multiple hashes separated by \\", - ", to delete multiple torrents, or set to all, to delete all torrents.", - ], - }, - TableRow { - raw: "`deleteFiles` | If set to `true`, the downloaded data will also be deleted, otherwise has no effect.", - columns: [ - "deleteFiles", - "If set to true, the downloaded data will also be deleted, otherwise has no effect.", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "/api/v2/torrents/delete?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32&deleteFiles=false", - ), - Text( - "```", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Recheck torrents", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hashes. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `recheck`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "------------|----------|------------", - rows: [ - TableRow { - raw: "`hashes` | string | The hashes of the torrents you want to recheck. `hashes` can contain multiple hashes separated by `\\|`, to recheck multiple torrents, or set to `all`, to recheck all torrents.", - columns: [ - "hashes", - "string", - "The hashes of the torrents you want to recheck. hashes can contain multiple hashes separated by \\", - ", to recheck multiple torrents, or set to all, to recheck all torrents.", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```http", - ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/recheck?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/recheck?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Reannounce torrents", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hashes. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `reannounce`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "------------|----------|------------", - rows: [ - TableRow { - raw: "`hashes` | string | The hashes of the torrents you want to reannounce. `hashes` can contain multiple hashes separated by `\\|`, to reannounce multiple torrents, or set to `all`, to reannounce all torrents.", - columns: [ - "hashes", - "string", - "The hashes of the torrents you want to reannounce. hashes can contain multiple hashes separated by \\", - ", to reannounce multiple torrents, or set to all, to reannounce all torrents.", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```http", - ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/reannounce?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/reannounce?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Add new torrent", - ), - content: [ - Text( - "", - ), - Text( - "This method can add torrents from server local file or from URLs. `http://`, `https://`, `magnet:` and `bc://bt/` links are supported.", - ), - Text( - "", - ), - Text( - "Name: `add`", - ), - Text( - "", - ), - Text( - "Add torrent from URLs example:", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/add HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: multipart/form-data; boundary=---------------------------6688794727912", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Text( - "-----------------------------6688794727912", - ), - Text( - "Content-Disposition: form-data; name=\"urls\"", - ), - Text( - "", - ), - Text( - "https://torcache.net/torrent/3B1A1469C180F447B77021074DBBCCAEF62611E7.torrent", - ), - Text( - "https://torcache.net/torrent/3B1A1469C180F447B77021074DBBCCAEF62611E8.torrent", - ), - Text( - "-----------------------------6688794727912", - ), - Text( - "Content-Disposition: form-data; name=\"savepath\"", - ), - Text( - "", - ), - Text( - "C:/Users/qBit/Downloads", - ), - Text( - "-----------------------------6688794727912", - ), - Text( - "Content-Disposition: form-data; name=\"cookie\"", - ), - Text( - "", - ), - Text( - "ui=28979218048197", - ), - Text( - "-----------------------------6688794727912", - ), - Text( - "Content-Disposition: form-data; name=\"category\"", - ), - Text( - "", - ), - Text( - "movies", - ), - Text( - "-----------------------------6688794727912", - ), - Text( - "Content-Disposition: form-data; name=\"skip_checking\"", - ), - Text( - "", - ), - Text( - "true", - ), - Text( - "-----------------------------6688794727912", - ), - Text( - "Content-Disposition: form-data; name=\"paused\"", - ), - Text( - "", - ), - Text( - "true", - ), - Text( - "-----------------------------6688794727912", - ), - Text( - "Content-Disposition: form-data; name=\"root_folder\"", - ), - Text( - "", - ), - Text( - "true", - ), - Text( - "-----------------------------6688794727912--", - ), - Text( - "```", - ), - Text( - "", - ), - Text( - "Add torrents from files example:", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/add HTTP/1.1", - ), - Text( - "Content-Type: multipart/form-data; boundary=-------------------------acebdf13572468", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Text( - "---------------------------acebdf13572468", - ), - Text( - "Content-Disposition: form-data; name=\"torrents\"; filename=\"8f18036b7a205c9347cb84a253975e12f7adddf2.torrent\"", - ), - Text( - "Content-Type: application/x-bittorrent", - ), - Text( - "", - ), - Text( - "file_binary_data_goes_here", - ), - Text( - "---------------------------acebdf13572468", - ), - Text( - "Content-Disposition: form-data; name=\"torrents\"; filename=\"UFS.torrent\"", - ), - Text( - "Content-Type: application/x-bittorrent", - ), - Text( - "", - ), - Text( - "file_binary_data_goes_here", - ), - Text( - "---------------------------acebdf13572468--", - ), - Text( - "", - ), - Text( - "```", - ), - Text( - "", - ), - Text( - "The above example will add two torrent files. `file_binary_data_goes_here` represents raw data of torrent file (basically a byte array).", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Property | Type | Description", - columns: [ - "Property", - "Type", - "Description", - ], - }, - split: "--------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`urls` | string | URLs separated with newlines", - columns: [ - "urls", - "string", - "URLs separated with newlines", - ], - }, - TableRow { - raw: "`torrents` | raw | Raw data of torrent file. `torrents` can be presented multiple times.", - columns: [ - "torrents", - "raw", - "Raw data of torrent file. torrents can be presented multiple times.", - ], - }, - TableRow { - raw: "`savepath` _optional_ | string | Download folder", - columns: [ - "savepath _optional_", - "string", - "Download folder", - ], - }, - TableRow { - raw: "`cookie` _optional_ | string | Cookie sent to download the .torrent file", - columns: [ - "cookie _optional_", - "string", - "Cookie sent to download the .torrent file", - ], - }, - TableRow { - raw: "`category` _optional_ | string | Category for the torrent", - columns: [ - "category _optional_", - "string", - "Category for the torrent", - ], - }, - TableRow { - raw: "`tags` _optional_ | string | Tags for the torrent, split by ','", - columns: [ - "tags _optional_", - "string", - "Tags for the torrent, split by ','", - ], - }, - TableRow { - raw: "`skip_checking` _optional_ | string | Skip hash checking. Possible values are `true`, `false` (default)", - columns: [ - "skip_checking _optional_", - "string", - "Skip hash checking. Possible values are true, false (default)", - ], - }, - TableRow { - raw: "`paused` _optional_ | string | Add torrents in the paused state. Possible values are `true`, `false` (default)", - columns: [ - "paused _optional_", - "string", - "Add torrents in the paused state. Possible values are true, false (default)", - ], - }, - TableRow { - raw: "`root_folder` _optional_ | string | Create the root folder. Possible values are `true`, `false`, unset (default)", - columns: [ - "root_folder _optional_", - "string", - "Create the root folder. Possible values are true, false, unset (default)", - ], - }, - TableRow { - raw: "`rename` _optional_ | string | Rename torrent", - columns: [ - "rename _optional_", - "string", - "Rename torrent", - ], - }, - TableRow { - raw: "`upLimit` _optional_ | integer | Set torrent upload speed limit. Unit in bytes/second", - columns: [ - "upLimit _optional_", - "integer", - "Set torrent upload speed limit. Unit in bytes/second", - ], - }, - TableRow { - raw: "`dlLimit` _optional_ | integer | Set torrent download speed limit. Unit in bytes/second", - columns: [ - "dlLimit _optional_", - "integer", - "Set torrent download speed limit. Unit in bytes/second", - ], - }, - TableRow { - raw: "`ratioLimit` _optional_ since 2.8.1 | float | Set torrent share ratio limit", - columns: [ - "ratioLimit _optional_ since 2.8.1", - "float", - "Set torrent share ratio limit", - ], - }, - TableRow { - raw: "`seedingTimeLimit` _optional_ since 2.8.1 | integer | Set torrent seeding time limit. Unit in seconds", - columns: [ - "seedingTimeLimit _optional_ since 2.8.1", - "integer", - "Set torrent seeding time limit. Unit in seconds", - ], - }, - TableRow { - raw: "`autoTMM` _optional_ | bool | Whether Automatic Torrent Management should be used", - columns: [ - "autoTMM _optional_", - "bool", - "Whether Automatic Torrent Management should be used", - ], - }, - TableRow { - raw: "`sequentialDownload` _optional_ | string | Enable sequential download. Possible values are `true`, `false` (default)", - columns: [ - "sequentialDownload _optional_", - "string", - "Enable sequential download. Possible values are true, false (default)", - ], - }, - TableRow { - raw: "`firstLastPiecePrio` _optional_ | string | Prioritize download first last piece. Possible values are `true`, `false` (default)", - columns: [ - "firstLastPiecePrio _optional_", - "string", - "Prioritize download first last piece. Possible values are true, false (default)", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "415 | Torrent file is not valid", - columns: [ - "415", - "Torrent file is not valid", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Add trackers to torrent", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `addTrackers`", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/addTrackers HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: application/x-www-form-urlencoded", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Text( - "hash=8c212779b4abde7c6bc608063a0d008b7e40ce32&urls=http://192.168.0.1/announce%0Audp://192.168.0.1:3333/dummyAnnounce", - ), - Text( - "```", - ), - Text( - "", - ), - Text( - "This adds two trackers to torrent with hash `8c212779b4abde7c6bc608063a0d008b7e40ce32`. Note `%0A` (aka LF newline) between trackers. Ampersand in tracker urls **MUST** be escaped.", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "404 | Torrent hash was not found", - columns: [ - "404", - "Torrent hash was not found", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Edit trackers", - ), - content: [ - Text( - "", - ), - Text( - "Name: `editTracker`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`hash` | string | The hash of the torrent", - columns: [ - "hash", - "string", - "The hash of the torrent", - ], - }, - TableRow { - raw: "`origUrl` | string | The tracker URL you want to edit", - columns: [ - "origUrl", - "string", - "The tracker URL you want to edit", - ], - }, - TableRow { - raw: "`newUrl` | string | The new URL to replace the `origUrl`", - columns: [ - "newUrl", - "string", - "The new URL to replace the origUrl", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "400 | `newUrl` is not a valid URL", - columns: [ - "400", - "newUrl is not a valid URL", - ], - }, - TableRow { - raw: "404 | Torrent hash was not found", - columns: [ - "404", - "Torrent hash was not found", - ], - }, - TableRow { - raw: "409 | `newUrl` already exists for the torrent", - columns: [ - "409", - "newUrl already exists for the torrent", - ], - }, - TableRow { - raw: "409 | `origUrl` was not found", - columns: [ - "409", - "origUrl was not found", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Remove trackers", - ), - content: [ - Text( - "", - ), - Text( - "Name: `removeTrackers`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`hash` | string | The hash of the torrent", - columns: [ - "hash", - "string", - "The hash of the torrent", - ], - }, - TableRow { - raw: "`urls` | string | URLs to remove, separated by `\\|`", - columns: [ - "urls", - "string", - "URLs to remove, separated by \\", - "", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "404 | Torrent hash was not found", - columns: [ - "404", - "Torrent hash was not found", - ], - }, - TableRow { - raw: "409 | All `urls` were not found", - columns: [ - "409", - "All urls were not found", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Add peers", - ), - content: [ - Text( - "", - ), - Text( - "Name: `addPeers`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`hashes` | string | The hash of the torrent, or multiple hashes separated by a pipe `\\|`", - columns: [ - "hashes", - "string", - "The hash of the torrent, or multiple hashes separated by a pipe \\", - "", - ], - }, - TableRow { - raw: "`peers` | string | The peer to add, or multiple peers separated by a pipe `\\|`. Each peer is a colon-separated `host:port`", - columns: [ - "peers", - "string", - "The peer to add, or multiple peers separated by a pipe \\", - ". Each peer is a colon-separated host:port", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "400 | None of the supplied peers are valid", - columns: [ - "400", - "None of the supplied peers are valid", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Increase torrent priority", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `increasePrio`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "------------|----------|------------", - rows: [ - TableRow { - raw: "`hashes` | string | The hashes of the torrents you want to increase the priority of. `hashes` can contain multiple hashes separated by `\\|`, to increase the priority of multiple torrents, or set to `all`, to increase the priority of all torrents.", - columns: [ - "hashes", - "string", - "The hashes of the torrents you want to increase the priority of. hashes can contain multiple hashes separated by \\", - ", to increase the priority of multiple torrents, or set to all, to increase the priority of all torrents.", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```http", - ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/increasePrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/increasePrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "409 | Torrent queueing is not enabled", - columns: [ - "409", - "Torrent queueing is not enabled", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Decrease torrent priority", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `decreasePrio`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "------------|----------|------------", - rows: [ - TableRow { - raw: "`hashes` | string | The hashes of the torrents you want to decrease the priority of. `hashes` can contain multiple hashes separated by `\\|`, to decrease the priority of multiple torrents, or set to `all`, to decrease the priority of all torrents.", - columns: [ - "hashes", - "string", - "The hashes of the torrents you want to decrease the priority of. hashes can contain multiple hashes separated by \\", - ", to decrease the priority of multiple torrents, or set to all, to decrease the priority of all torrents.", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```http", - ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/decreasePrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/decreasePrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "409 | Torrent queueing is not enabled", - columns: [ - "409", - "Torrent queueing is not enabled", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Maximal torrent priority", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `topPrio`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "------------|----------|------------", - rows: [ - TableRow { - raw: "`hashes` | string | The hashes of the torrents you want to set to the maximum priority. `hashes` can contain multiple hashes separated by `\\|`, to set multiple torrents to the maximum priority, or set to `all`, to set all torrents to the maximum priority.", - columns: [ - "hashes", - "string", - "The hashes of the torrents you want to set to the maximum priority. hashes can contain multiple hashes separated by \\", - ", to set multiple torrents to the maximum priority, or set to all, to set all torrents to the maximum priority.", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```http", - ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/topPrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/topPrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "409 | Torrent queueing is not enabled", - columns: [ - "409", - "Torrent queueing is not enabled", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Minimal torrent priority", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `bottomPrio`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "------------|----------|------------", - rows: [ - TableRow { - raw: "`hashes` | string | The hashes of the torrents you want to set to the minimum priority. `hashes` can contain multiple hashes separated by `\\|`, to set multiple torrents to the minimum priority, or set to `all`, to set all torrents to the minimum priority.", - columns: [ - "hashes", - "string", - "The hashes of the torrents you want to set to the minimum priority. hashes can contain multiple hashes separated by \\", - ", to set multiple torrents to the minimum priority, or set to all, to set all torrents to the minimum priority.", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```http", - ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/bottomPrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/bottomPrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "409 | Torrent queueing is not enabled", - columns: [ - "409", - "Torrent queueing is not enabled", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Set file priority", - ), - content: [ - Text( - "", - ), - Text( - "Name: `filePrio`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`hash` | string | The hash of the torrent", - columns: [ - "hash", - "string", - "The hash of the torrent", - ], - }, - TableRow { - raw: "`id` | string | File ids, separated by `\\|`", - columns: [ - "id", - "string", - "File ids, separated by \\", - "", - ], - }, - TableRow { - raw: "`priority` | number | File priority to set (consult [torrent contents API](#get-torrent-contents) for possible values)", - columns: [ - "priority", - "number", - "File priority to set (consult [torrent contents API](#get-torrent-contents) for possible values)", - ], - }, - ], - }, - ), - Text( - "`id` values correspond to file position inside the array returned by [torrent contents API](#get-torrent-contents), e.g. `id=0` for first file, `id=1` for second file, etc.", - ), - Text( - "", - ), - Text( - "Since 2.8.2 it is reccomended to use `index` field returned by [torrent contents API](#get-torrent-contents) (since the files can be filtered and the `index` value may differ from the position inside the response array).", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "400 | Priority is invalid", - columns: [ - "400", - "Priority is invalid", - ], - }, - TableRow { - raw: "400 | At least one file `id` is not a valid integer", - columns: [ - "400", - "At least one file id is not a valid integer", - ], - }, - TableRow { - raw: "404 | Torrent hash was not found", - columns: [ - "404", - "Torrent hash was not found", - ], - }, - TableRow { - raw: "409 | Torrent metadata hasn't downloaded yet", - columns: [ - "409", - "Torrent metadata hasn't downloaded yet", - ], - }, - TableRow { - raw: "409 | At least one file `id` was not found", - columns: [ - "409", - "At least one file id was not found", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get torrent download limit", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `downloadLimit`", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/downloadLimit HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: application/x-www-form-urlencoded", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0", - ], - }, - split: "```", - rows: [], - }, - ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "", - rows: [], - }, - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "HTTP/1.1 200 OK", - ), - Text( - "content-type: application/json", - ), - Text( - "content-length: length", - ), - Text( - "", - ), - Text( - "{\"8c212779b4abde7c6bc608063a0d008b7e40ce32\":338944,\"284b83c9c7935002391129fd97f43db5d7cc2ba0\":123}", - ), - Text( - "```", - ), - Text( - "", - ), - Text( - "`8c212779b4abde7c6bc608063a0d008b7e40ce32` is the hash of the torrent and `338944` its download speed limit in bytes per second; this value will be zero if no limit is applied.", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Set torrent download limit", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/setDownloadLimit HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: application/x-www-form-urlencoded", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&limit=131072", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0&limit=131072", - ], - }, - split: "```", - rows: [], - }, - ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "`limit` is the download speed limit in bytes per second you want to set.", - rows: [], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Set torrent share limit", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `setShareLimits`", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/setShareLimits HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: application/x-www-form-urlencoded", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&ratioLimit=1.0&seedingTimeLimit=60", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0&ratioLimit=1.0&seedingTimeLimit=60", - ], - }, - split: "```", - rows: [], - }, - ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "`ratioLimit` is the max ratio the torrent should be seeded until. `-2` means the global limit should be used, `-1` means no limit.", - rows: [], - }, - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get torrent upload limit", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `uploadLimit`", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/uploadLimit HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: application/x-www-form-urlencoded", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0", - ], - }, - split: "```", - rows: [], - }, - ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "", - rows: [], - }, - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "HTTP/1.1 200 OK", - ), - Text( - "content-type: application/json", - ), - Text( - "content-length: length", - ), - Text( - "", - ), - Text( - "{\"8c212779b4abde7c6bc608063a0d008b7e40ce32\":338944,\"284b83c9c7935002391129fd97f43db5d7cc2ba0\":123}", - ), - Text( - "```", - ), - Text( - "", - ), - Text( - "`8c212779b4abde7c6bc608063a0d008b7e40ce32` is the hash of the torrent in the request and `338944` its upload speed limit in bytes per second; this value will be zero if no limit is applied.", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Set torrent upload limit", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `setUploadLimit`", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/setUploadLimit HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: application/x-www-form-urlencoded", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&limit=131072", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0&limit=131072", - ], - }, - split: "```", - rows: [], - }, - ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "`limit` is the upload speed limit in bytes per second you want to set.", - rows: [], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Set torrent location", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `setLocation`", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/setLocation HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: application/x-www-form-urlencoded", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&location=/mnt/nfs/media", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0&location=/mnt/nfs/media", - ], - }, - split: "```", - rows: [], - }, - ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "`location` is the location to download the torrent to. If the location doesn't exist, the torrent's location is unchanged.", - rows: [], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "400 | Save path is empty", - columns: [ - "400", - "Save path is empty", - ], - }, - TableRow { - raw: "403 | User does not have write access to directory", - columns: [ - "403", - "User does not have write access to directory", - ], - }, - TableRow { - raw: "409 | Unable to create save path directory", - columns: [ - "409", - "Unable to create save path directory", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Set torrent name", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `rename`", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/rename HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: application/x-www-form-urlencoded", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Text( - "hash=8c212779b4abde7c6bc608063a0d008b7e40ce32&name=This%20is%20a%20test", - ), - Text( - "```", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "404 | Torrent hash is invalid", - columns: [ - "404", - "Torrent hash is invalid", - ], - }, - TableRow { - raw: "409 | Torrent name is empty", - columns: [ - "409", - "Torrent name is empty", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Set torrent category", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `setCategory`", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/setCategory HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: application/x-www-form-urlencoded", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&category=CategoryName", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0&category=CategoryName", - ], - }, - split: "```", - rows: [], - }, - ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "", - rows: [], - }, - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "409 | Category name does not exist", - columns: [ - "409", - "Category name does not exist", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get all categories", - ), - content: [ - Text( - "", - ), - Text( - "Name: `categories`", - ), - Text( - "", - ), - Text( - "Parameters:", - ), - Text( - "", - ), - Text( - "None", - ), - Text( - "", - ), - Text( - "Returns all categories in JSON format, e.g.:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "{", - ), - Text( - " \"Video\": {", - ), - Text( - " \"name\": \"Video\",", - ), - Text( - " \"savePath\": \"/home/user/torrents/video/\"", - ), - Text( - " },", - ), - Text( - " \"eBooks\": {", - ), - Text( - " \"name\": \"eBooks\",", - ), - Text( - " \"savePath\": \"/home/user/torrents/eBooks/\"", - ), - Text( - " }", - ), - Text( - "}", - ), - Text( - "```", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Add new category", - ), - content: [ - Text( - "", - ), - Text( - "Name: `createCategory`", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/createCategory HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: application/x-www-form-urlencoded", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Text( - "category=CategoryName&savePath=/path/to/dir", - ), - Text( - "```", - ), - Text( - "", - ), - Text( - "`category` is the category you want to create.", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "400 | Category name is empty", - columns: [ - "400", - "Category name is empty", - ], - }, - TableRow { - raw: "409 | Category name is invalid", - columns: [ - "409", - "Category name is invalid", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Edit category", - ), - content: [ - Text( - "", - ), - Text( - "Name: `editCategory`", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/editCategory HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: application/x-www-form-urlencoded", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Text( - "category=CategoryName&savePath=/path/to/save/torrents/to", - ), - Text( - "```", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "400 | Category name is empty", - columns: [ - "400", - "Category name is empty", - ], - }, - TableRow { - raw: "409 | Category editing failed", - columns: [ - "409", - "Category editing failed", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Remove categories", - ), - content: [ - Text( - "", - ), - Text( - "Name: `removeCategories`", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/removeCategories HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: application/x-www-form-urlencoded", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Text( - "categories=Category1%0ACategory2", - ), - Text( - "```", - ), - Text( - "", - ), - Text( - "`categories` can contain multiple cateogies separated by `\\n` (%0A urlencoded)", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Add torrent tags", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `addTags`", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/addTags HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: application/x-www-form-urlencoded", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&tags=TagName1,TagName2", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0&tags=TagName1,TagName2", - ], - }, - split: "```", - rows: [], - }, - ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "", - rows: [], - }, - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Remove torrent tags", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `removeTags`", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/removeTags HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: application/x-www-form-urlencoded", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&tags=TagName1,TagName2", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0&tags=TagName1,TagName2", - ], - }, - split: "```", - rows: [], - }, - ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "", - rows: [], - }, - ), - Text( - "Empty list removes all tags from relevant torrents.", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get all tags", - ), - content: [ - Text( - "", - ), - Text( - "Name: `tags`", - ), - Text( - "", - ), - Text( - "Parameters:", - ), - Text( - "", - ), - Text( - "None", - ), - Text( - "", - ), - Text( - "Returns all tags in JSON format, e.g.:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "[", - ), - Text( - " \"Tag 1\",", - ), - Text( - " \"Tag 2\"", - ), - Text( - "]", - ), - Text( - "```", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Create tags", - ), - content: [ - Text( - "", - ), - Text( - "Name: `createTags`", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/createTags HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: application/x-www-form-urlencoded", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Text( - "tags=TagName1,TagName2", - ), - Text( - "```", - ), - Text( - "`tags` is a list of tags you want to create.", - ), - Text( - "Can contain multiple tags separated by `,`.", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Delete tags", - ), - content: [ - Text( - "", - ), - Text( - "Name: `deleteTags`", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/deleteTags HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: application/x-www-form-urlencoded", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Text( - "tags=TagName1,TagName2", - ), - Text( - "```", - ), - Text( - "", - ), - Text( - "`tags` is a list of tags you want to delete.", - ), - Text( - "Can contain multiple tags separated by `,`.", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Set automatic torrent management", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `setAutoManagement`", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/setAutoManagement HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: application/x-www-form-urlencoded", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&enable=true", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0&enable=true", - ], - }, - split: "```", - rows: [], - }, - ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "`enable` is a boolean, affects the torrents listed in `hashes`, default is `false`", - rows: [], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Toggle sequential download", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `toggleSequentialDownload`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "------------|----------|------------", - rows: [ - TableRow { - raw: "`hashes` | string | The hashes of the torrents you want to toggle sequential download for. `hashes` can contain multiple hashes separated by `\\|`, to toggle sequential download for multiple torrents, or set to `all`, to toggle sequential download for all torrents.", - columns: [ - "hashes", - "string", - "The hashes of the torrents you want to toggle sequential download for. hashes can contain multiple hashes separated by \\", - ", to toggle sequential download for multiple torrents, or set to all, to toggle sequential download for all torrents.", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```http", - ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/toggleSequentialDownload?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/toggleSequentialDownload?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Set first/last piece priority", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `toggleFirstLastPiecePrio`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "------------|----------|------------", - rows: [ - TableRow { - raw: "`hashes` | string | The hashes of the torrents you want to toggle the first/last piece priority for. `hashes` can contain multiple hashes separated by `\\|`, to toggle the first/last piece priority for multiple torrents, or set to `all`, to toggle the first/last piece priority for all torrents.", - columns: [ - "hashes", - "string", - "The hashes of the torrents you want to toggle the first/last piece priority for. hashes can contain multiple hashes separated by \\", - ", to toggle the first/last piece priority for multiple torrents, or set to all, to toggle the first/last piece priority for all torrents.", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```http", - ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/toggleFirstLastPiecePrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/toggleFirstLastPiecePrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Set force start", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `setForceStart`", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/setForceStart HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: application/x-www-form-urlencoded", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Text( - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32?value=true", - ), - Text( - "```", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "`value` is a boolean, affects the torrents listed in `hashes`, default is `false`", - rows: [], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Set super seeding", - ), - content: [ - Text( - "", - ), - Text( - "Requires knowing the torrent hash. You can get it from [torrent list](#get-torrent-list).", - ), - Text( - "", - ), - Text( - "Name: `setSuperSeeding`", - ), - Text( - "", - ), - Text( - "```http", - ), - Text( - "POST /api/v2/torrents/setSuperSeeding HTTP/1.1", - ), - Text( - "User-Agent: Fiddler", - ), - Text( - "Host: 127.0.0.1", - ), - Text( - "Cookie: SID=your_sid", - ), - Text( - "Content-Type: application/x-www-form-urlencoded", - ), - Text( - "Content-Length: length", - ), - Text( - "", - ), - Text( - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32?value=true", - ), - Text( - "```", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "`value` is a boolean, affects the torrents listed in `hashes`, default is `false`", - rows: [], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Rename file", - ), - content: [ - Text( - "", - ), - Text( - "Name: `renameFile`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|----------|------------", - rows: [ - TableRow { - raw: "`hash` | string | The hash of the torrent", - columns: [ - "hash", - "string", - "The hash of the torrent", - ], - }, - TableRow { - raw: "`oldPath` | string | The old path of the torrent", - columns: [ - "oldPath", - "string", - "The old path of the torrent", - ], - }, - TableRow { - raw: "`newPath` | string | The new path to use for the file", - columns: [ - "newPath", - "string", - "The new path to use for the file", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "400 | Missing `newPath` parameter", - columns: [ - "400", - "Missing newPath parameter", - ], - }, - TableRow { - raw: "409 | Invalid `newPath` or `oldPath`, or `newPath` already in use", - columns: [ - "409", - "Invalid newPath or oldPath, or newPath already in use", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Rename folder", - ), - content: [ - Text( - "", - ), - Text( - "Name: `renameFolder`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|----------|------------", - rows: [ - TableRow { - raw: "`hash` | string | The hash of the torrent", - columns: [ - "hash", - "string", - "The hash of the torrent", - ], - }, - TableRow { - raw: "`oldPath` | string | The old path of the torrent", - columns: [ - "oldPath", - "string", - "The old path of the torrent", - ], - }, - TableRow { - raw: "`newPath` | string | The new path to use for the file", - columns: [ - "newPath", - "string", - "The new path to use for the file", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "400 | Missing `newPath` parameter", - columns: [ - "400", - "Missing newPath parameter", - ], - }, - TableRow { - raw: "409 | Invalid `newPath` or `oldPath`, or `newPath` already in use", - columns: [ - "409", - "Invalid newPath or oldPath, or newPath already in use", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - ], - }, - TokenTree { - title: Some( - "RSS (experimental)", - ), - content: [ - Text( - "", - ), - Text( - "All RSS API methods are under \"rss\", e.g.: `/api/v2/rss/methodName`.", - ), - Text( - "", - ), - ], - children: [ - TokenTree { - title: Some( - "Add folder", - ), - content: [ - Text( - "", - ), - Text( - "Name: `addFolder`", - ), - Text( - "", - ), - Text( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`path` | string | Full path of added folder (e.g. \"The Pirate Bay\\Top100\")", - columns: [ - "path", - "string", - "Full path of added folder (e.g. \"The Pirate Bay\\Top100\")", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "409 | Failure to add folder", - columns: [ - "409", - "Failure to add folder", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Add feed", - ), - content: [ - Text( - "", - ), - Text( - "Name: `addFeed`", - ), - Text( - "", - ), - Text( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`url` | string | URL of RSS feed (e.g. \"[http://thepiratebay.org/rss//top100/200](http://thepiratebay.org/rss//top100/200)\")", - columns: [ - "url", - "string", - "URL of RSS feed (e.g. \"[http://thepiratebay.org/rss//top100/200](http://thepiratebay.org/rss//top100/200)\")", - ], - }, - TableRow { - raw: "`path` _optional_ | string | Full path of added folder (e.g. \"The Pirate Bay\\Top100\\Video\")", - columns: [ - "path _optional_", - "string", - "Full path of added folder (e.g. \"The Pirate Bay\\Top100\\Video\")", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "409 | Failure to add feed", - columns: [ - "409", - "Failure to add feed", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Remove item", - ), - content: [ - Text( - "", - ), - Text( - "Removes folder or feed.", - ), - Text( - "", - ), - Text( - "Name: `removeItem`", - ), - Text( - "", - ), - Text( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`path` | string | Full path of removed item (e.g. \"The Pirate Bay\\Top100\")", - columns: [ - "path", - "string", - "Full path of removed item (e.g. \"The Pirate Bay\\Top100\")", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "409 | Failure to remove item", - columns: [ - "409", - "Failure to remove item", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Move item", - ), - content: [ - Text( - "", - ), - Text( - "Moves/renames folder or feed.", - ), - Text( - "", - ), - Text( - "Name: `moveItem`", - ), - Text( - "", - ), - Text( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`itemPath` | string | Current full path of item (e.g. \"The Pirate Bay\\Top100\")", - columns: [ - "itemPath", - "string", - "Current full path of item (e.g. \"The Pirate Bay\\Top100\")", - ], - }, - TableRow { - raw: "`destPath` | string | New full path of item (e.g. \"The Pirate Bay\")", - columns: [ - "destPath", - "string", - "New full path of item (e.g. \"The Pirate Bay\")", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "409 | Failure to move item", - columns: [ - "409", - "Failure to move item", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get all items", - ), - content: [ - Text( - "", - ), - Text( - "Name: `items`", - ), - Text( - "", - ), - Text( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`withData` _optional_ | bool | True if you need current feed articles", - columns: [ - "withData _optional_", - "bool", - "True if you need current feed articles", - ], - }, - ], - }, - ), - Text( - "Returns all RSS items in JSON format, e.g.:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "{", - ), - Text( - " \"HD-Torrents.org\": \"https://hd-torrents.org/rss.php\",", - ), - Text( - " \"PowerfulJRE\": \"https://www.youtube.com/feeds/videos.xml?channel_id=UCzQUP1qoWDoEbmsQxvdjxgQ\",", - ), - Text( - " \"The Pirate Bay\": {", - ), - Text( - " \"Audio\": \"https://thepiratebay.org/rss//top100/100\",", - ), - Text( - " \"Video\": \"https://thepiratebay.org/rss//top100/200\"", - ), - Text( - " }", - ), - Text( - "}", - ), - Text( - "```", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Mark as read", - ), - content: [ - Text( - "", - ), - Text( - "If `articleId` is provided only the article is marked as read otherwise the whole feed is going to be marked as read.", - ), - Text( - "", - ), - Text( - "Name: `markAsRead`", - ), - Text( - "", - ), - Text( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`itemPath` | string | Current full path of item (e.g. \"The Pirate Bay\\Top100\")", - columns: [ - "itemPath", - "string", - "Current full path of item (e.g. \"The Pirate Bay\\Top100\")", - ], - }, - TableRow { - raw: "`articleId` _optional_ | string | ID of article", - columns: [ - "articleId _optional_", - "string", - "ID of article", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Refresh item", - ), - content: [ - Text( - "", - ), - Text( - "Refreshes folder or feed.", - ), - Text( - "", - ), - Text( - "Name: `refreshItem`", - ), - Text( - "", - ), - Text( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`itemPath` | string | Current full path of item (e.g. \"The Pirate Bay\\Top100\")", - columns: [ - "itemPath", - "string", - "Current full path of item (e.g. \"The Pirate Bay\\Top100\")", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Set auto-downloading rule", - ), - content: [ - Text( - "", - ), - Text( - "Name: `setRule`", - ), - Text( - "", - ), - Text( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`ruleName` | string | Rule name (e.g. \"Punisher\")", - columns: [ - "ruleName", - "string", - "Rule name (e.g. \"Punisher\")", - ], - }, - TableRow { - raw: "`ruleDef` | string | JSON encoded rule definition", - columns: [ - "ruleDef", - "string", - "JSON encoded rule definition", - ], - }, - ], - }, - ), - Text( - "Rule definition is JSON encoded dictionary with the following fields:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Field | Type | Description", - columns: [ - "Field", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`enabled` | bool | Whether the rule is enabled", - columns: [ - "enabled", - "bool", - "Whether the rule is enabled", - ], - }, - TableRow { - raw: "`mustContain` | string | The substring that the torrent name must contain", - columns: [ - "mustContain", - "string", - "The substring that the torrent name must contain", - ], - }, - TableRow { - raw: "`mustNotContain` | string | The substring that the torrent name must not contain", - columns: [ - "mustNotContain", - "string", - "The substring that the torrent name must not contain", - ], - }, - TableRow { - raw: "`useRegex` | bool | Enable regex mode in \"mustContain\" and \"mustNotContain\"", - columns: [ - "useRegex", - "bool", - "Enable regex mode in \"mustContain\" and \"mustNotContain\"", - ], - }, - TableRow { - raw: "`episodeFilter` | string | Episode filter definition", - columns: [ - "episodeFilter", - "string", - "Episode filter definition", - ], - }, - TableRow { - raw: "`smartFilter` | bool | Enable smart episode filter", - columns: [ - "smartFilter", - "bool", - "Enable smart episode filter", - ], - }, - TableRow { - raw: "`previouslyMatchedEpisodes` | list | The list of episode IDs already matched by smart filter", - columns: [ - "previouslyMatchedEpisodes", - "list", - "The list of episode IDs already matched by smart filter", - ], - }, - TableRow { - raw: "`affectedFeeds` | list | The feed URLs the rule applied to", - columns: [ - "affectedFeeds", - "list", - "The feed URLs the rule applied to", - ], - }, - TableRow { - raw: "`ignoreDays` | number | Ignore sunsequent rule matches", - columns: [ - "ignoreDays", - "number", - "Ignore sunsequent rule matches", - ], - }, - TableRow { - raw: "`lastMatch` | string | The rule last match time", - columns: [ - "lastMatch", - "string", - "The rule last match time", - ], - }, - TableRow { - raw: "`addPaused` | bool | Add matched torrent in paused mode", - columns: [ - "addPaused", - "bool", - "Add matched torrent in paused mode", - ], - }, - TableRow { - raw: "`assignedCategory` | string | Assign category to the torrent", - columns: [ - "assignedCategory", - "string", - "Assign category to the torrent", - ], - }, - TableRow { - raw: "`savePath` | string | Save torrent to the given directory", - columns: [ - "savePath", - "string", - "Save torrent to the given directory", - ], - }, - ], - }, - ), - Text( - "E.g.:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "{", - ), - Text( - " \"enabled\": false,", - ), - Text( - " \"mustContain\": \"The *Punisher*\",", - ), - Text( - " \"mustNotContain\": \"\",", - ), - Text( - " \"useRegex\": false,", - ), - Text( - " \"episodeFilter\": \"1x01-;\",", - ), - Text( - " \"smartFilter\": false,", - ), - Text( - " \"previouslyMatchedEpisodes\": [", - ), - Text( - " ],", - ), - Text( - " \"affectedFeeds\": [", - ), - Text( - " \"http://showrss.info/user/134567.rss?magnets=true\"", - ), - Text( - " ],", - ), - Text( - " \"ignoreDays\": 0,", - ), - Text( - " \"lastMatch\": \"20 Nov 2017 09:05:11\",", - ), - Text( - " \"addPaused\": true,", - ), - Text( - " \"assignedCategory\": \"\",", - ), - Text( - " \"savePath\": \"C:/Users/JohnDoe/Downloads/Punisher\"", - ), - Text( - "}", - ), - Text( - "```", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Rename auto-downloading rule", - ), - content: [ - Text( - "", - ), - Text( - "Name: `renameRule`", - ), - Text( - "", - ), - Text( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`ruleName` | string | Rule name (e.g. \"Punisher\")", - columns: [ - "ruleName", - "string", - "Rule name (e.g. \"Punisher\")", - ], - }, - TableRow { - raw: "`newRuleName` | string | New rule name (e.g. \"The Punisher\")", - columns: [ - "newRuleName", - "string", - "New rule name (e.g. \"The Punisher\")", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Remove auto-downloading rule", - ), - content: [ - Text( - "", - ), - Text( - "Name: `removeRule`", - ), - Text( - "", - ), - Text( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`ruleName` | string | Rule name (e.g. \"Punisher\")", - columns: [ - "ruleName", - "string", - "Rule name (e.g. \"Punisher\")", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get all auto-downloading rules", - ), - content: [ - Text( - "", - ), - Text( - "Name: `rules`", - ), - Text( - "", - ), - Text( - "Returns all auto-downloading rules in JSON format, e.g.:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "{", - ), - Text( - " \"The Punisher\": {", - ), - Text( - " \"enabled\": false,", - ), - Text( - " \"mustContain\": \"The *Punisher*\",", - ), - Text( - " \"mustNotContain\": \"\",", - ), - Text( - " \"useRegex\": false,", - ), - Text( - " \"episodeFilter\": \"1x01-;\",", - ), - Text( - " \"smartFilter\": false,", - ), - Text( - " \"previouslyMatchedEpisodes\": [", - ), - Text( - " ],", - ), - Text( - " \"affectedFeeds\": [", - ), - Text( - " \"http://showrss.info/user/134567.rss?magnets=true\"", - ), - Text( - " ],", - ), - Text( - " \"ignoreDays\": 0,", - ), - Text( - " \"lastMatch\": \"20 Nov 2017 09:05:11\",", - ), - Text( - " \"addPaused\": true,", - ), - Text( - " \"assignedCategory\": \"\",", - ), - Text( - " \"savePath\": \"C:/Users/JohnDoe/Downloads/Punisher\"", - ), - Text( - " }", - ), - Text( - "}", - ), - Text( - "```", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get all articles matching a rule", - ), - content: [ - Text( - "", - ), - Text( - "Name: `matchingArticles`", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`ruleName` | string | Rule name (e.g. \"Linux\")", - columns: [ - "ruleName", - "string", - "Rule name (e.g. \"Linux\")", - ], - }, - ], - }, - ), - Text( - "", - ), - Text( - "Returns all articles that match a rule by feed name in JSON format, e.g.:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "{", - ), - Text( - " \"DistroWatch\":[", - ), - Text( - " \"sparkylinux-5.11-i686-minimalgui.iso.torrent\",", - ), - Text( - " \"sparkylinux-5.11-x86_64-minimalgui.iso.torrent\",", - ), - Text( - " \"sparkylinux-5.11-i686-xfce.iso.torrent\",", - ), - Text( - " \"bluestar-linux-5.6.3-2020.04.09-x86_64.iso.torrent\",", - ), - Text( - " \"robolinux64-mate3d-v10.10.iso.torrent\",", - ), - Text( - " ],", - ), - Text( - " \"Linuxtracker\":[", - ), - Text( - " \"[Alpine Linux] alpine-extended-3.11.6\",", - ), - Text( - " \"[Alpine Linux] alpine-standard-3.11.6\",", - ), - Text( - " \"[Linuxfx] linuxfx10-wxs-lts-beta5.iso\",", - ), - Text( - " \"[Linux Lite] linux-lite-5.0-rc1-64bit.iso (MULTI)\",", - ), - Text( - " \"[Scientific Linux] SL-7.8-x86_64-Pack\",", - ), - Text( - " \"[NixOS] nixos-plasma5-20.03.1418.5272327b81e-x86_64-linux.iso\"", - ), - Text( - " ]", - ), - Text( - "}", - ), - Text( - "```", - ), - Text( - "", - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "200 | All scenarios", - columns: [ - "200", - "All scenarios", - ], - }, - ], - }, - ), - Text( - "", - ), - ], - children: [], - }, - ], - }, - TokenTree { - title: Some( - "Search", - ), - content: [ - Text( - "", - ), - Text( - "All Search API methods are under \"search\", e.g.: `/api/v2/search/methodName`.", - ), - Text( - "", - ), - ], - children: [ - TokenTree { - title: Some( - "Start search", - ), - content: [ - Text( - "", - ), - Text( - "Name: `start`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`pattern` | string | Pattern to search for (e.g. \"Ubuntu 18.04\")", - columns: [ - "pattern", - "string", - "Pattern to search for (e.g. \"Ubuntu 18.04\")", - ], - }, - TableRow { - raw: "`plugins` | string | Plugins to use for searching (e.g. \"legittorrents\"). Supports multiple plugins separated by `\\|`. Also supports `all` and `enabled`", - columns: [ - "plugins", - "string", - "Plugins to use for searching (e.g. \"legittorrents\"). Supports multiple plugins separated by \\", - ". Also supports all and enabled", - ], - }, - TableRow { - raw: "`category` | string | Categories to limit your search to (e.g. \"legittorrents\"). Available categories depend on the specified `plugins`. Also supports `all`", - columns: [ - "category", - "string", - "Categories to limit your search to (e.g. \"legittorrents\"). Available categories depend on the specified plugins. Also supports all", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "409 | User has reached the limit of max `Running` searches (currently set to 5)", - columns: [ - "409", - "User has reached the limit of max Running searches (currently set to 5)", - ], - }, - TableRow { - raw: "200 | All other scenarios- see JSON below", - columns: [ - "200", - "All other scenarios- see JSON below", - ], - }, - ], - }, - ), - Text( - "The response is a JSON object with the following fields", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Field | Type | Description", - columns: [ - "Field", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`id` | number | ID of the search job", - columns: [ - "id", - "number", - "ID of the search job", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "{", - ), - Text( - " \"id\": 12345", - ), - Text( - "}", - ), - Text( - "```", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Stop search", - ), - content: [ - Text( - "", - ), - Text( - "Name: `stop`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`id` | number | ID of the search job", - columns: [ - "id", - "number", - "ID of the search job", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "404 | Search job was not found", - columns: [ - "404", - "Search job was not found", - ], - }, - TableRow { - raw: "200 | All other scenarios", - columns: [ - "200", - "All other scenarios", - ], - }, - ], - }, - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get search status", - ), - content: [ - Text( - "", - ), - Text( - "Name: `status`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`id` _optional_ | number | ID of the search job. If not specified, all search jobs are returned", - columns: [ - "id _optional_", - "number", - "ID of the search job. If not specified, all search jobs are returned", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "404 | Search job was not found", - columns: [ - "404", - "Search job was not found", - ], - }, - TableRow { - raw: "200 | All other scenarios- see JSON below", - columns: [ - "200", - "All other scenarios- see JSON below", - ], - }, - ], - }, - ), - Text( - "The response is a JSON array of objects containing the following fields", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Field | Type | Description", - columns: [ - "Field", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`id` | number | ID of the search job", - columns: [ - "id", - "number", - "ID of the search job", - ], - }, - TableRow { - raw: "`status` | string | Current status of the search job (either `Running` or `Stopped`)", - columns: [ - "status", - "string", - "Current status of the search job (either Running or Stopped)", - ], - }, - TableRow { - raw: "`total` | number | Total number of results. If the status is `Running` this number may contineu to increase", - columns: [ - "total", - "number", - "Total number of results. If the status is Running this number may contineu to increase", - ], - }, - ], - }, - ), - Text( - "Example:", - ), - Text( - "", - ), - Text( - "```JSON", - ), - Text( - "[", - ), - Text( - " {", - ), - Text( - " \"id\": 12345,", - ), - Text( - " \"status\": \"Running\",", - ), - Text( - " \"total\": 170", - ), - Text( - " }", - ), - Text( - "]", - ), - Text( - "```", - ), - Text( - "", - ), - ], - children: [], - }, - TokenTree { - title: Some( - "Get search results", - ), - content: [ - Text( - "", - ), - Text( - "Name: `results`", - ), - Text( - "", - ), - Asterix( - "Parameters:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Parameter | Type | Description", - columns: [ - "Parameter", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [ - TableRow { - raw: "`id` | number | ID of the search job", - columns: [ - "id", - "number", - "ID of the search job", - ], - }, - TableRow { - raw: "`limit` _optional_ | number | max number of results to return. 0 or negative means no limit", - columns: [ - "limit _optional_", - "number", - "max number of results to return. 0 or negative means no limit", - ], - }, - TableRow { - raw: "`offset` _optional_ | number | result to start at. A negative number means count backwards (e.g. `-2` returns the 2 most recent results)", - columns: [ - "offset _optional_", - "number", - "result to start at. A negative number means count backwards (e.g. -2 returns the 2 most recent results)", - ], - }, - ], - }, - ), - Asterix( - "Returns:", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "HTTP Status Code | Scenario", - columns: [ - "HTTP Status Code", - "Scenario", - ], - }, - split: "----------------------------------|---------------------", - rows: [ - TableRow { - raw: "404 | Search job was not found", - columns: [ - "404", - "Search job was not found", - ], - }, - TableRow { - raw: "409 | Offset is too large, or too small (e.g. absolute value of negative number is greater than # results)", - columns: [ - "409", - "Offset is too large, or too small (e.g. absolute value of negative number is greater than # results)", - ], - }, - TableRow { - raw: "200 | All other scenarios- see JSON below", - columns: [ - "200", - "All other scenarios- see JSON below", - ], - }, - ], - }, - ), - Text( - "The response is a JSON object with the following fields", - ), - Text( - "", - ), - Table( - Table { - header: TableRow { - raw: "Field | Type | Description", - columns: [ - "Field", - "Type", - "Description", - ], - }, - split: "----------------------------------|---------|------------", - rows: [], - }, - ), - ], - children: [], - }, - ], - }, - ], -} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/parser/util.rs b/qbittorrent-web-api-gen/src/parser/util.rs deleted file mode 100644 index 71e9160..0000000 --- a/qbittorrent-web-api-gen/src/parser/util.rs +++ /dev/null @@ -1,15 +0,0 @@ -use crate::md_parser::MdContent; - -pub fn find_content_starts_with(content: &[MdContent], starts_with: &str) -> Option { - content.iter().find_map(|row| match row { - MdContent::Text(content) if content.starts_with(starts_with) => Some(content.into()), - _ => None, - }) -} - -pub fn find_content_contains(content: &[MdContent], contains: &str) -> Option { - content.iter().find_map(|row| match row { - MdContent::Text(content) if content.contains(contains) => Some(content.into()), - _ => None, - }) -} diff --git a/qbittorrent-web-api-gen/src/types.rs b/qbittorrent-web-api-gen/src/types.rs index bf4deca..d2b70ef 100644 --- a/qbittorrent-web-api-gen/src/types.rs +++ b/qbittorrent-web-api-gen/src/types.rs @@ -1,4 +1,5 @@ -use std::collections::HashMap; +use case::CaseExt; +use regex::RegexBuilder; #[derive(Debug, Clone)] pub struct TypeDescriptions { @@ -14,30 +15,47 @@ pub struct TypeDescription { #[derive(Debug, Clone)] pub struct TypeInfo { pub name: String, - pub is_optional: bool, - pub is_list: bool, pub description: Option, - pub type_description: Option, + is_optional: bool, + is_list: bool, } impl TypeInfo { - pub fn new( - name: &str, - is_optional: bool, - is_list: bool, - description: Option, - type_description: Option, - ) -> Self { + pub fn new(name: &str, is_optional: bool, is_list: bool, description: Option) -> Self { Self { name: name.into(), + description, is_optional, is_list, - description, - type_description, } } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum RefType { + String(String), + Map(String, String), +} + +#[derive(Debug, Clone)] +pub struct Object { + pub type_info: TypeInfo, + pub ref_type: RefType, +} + +#[derive(Debug, Clone)] +pub struct Enum { + pub type_info: TypeInfo, + pub values: Vec, +} + +#[derive(Debug, Clone)] +pub struct EnumValue { + pub description: Option, + pub key: String, + pub value: String, +} + pub const OPTIONAL: &str = "_optional_"; #[derive(Debug, Clone)] @@ -47,22 +65,10 @@ pub enum Type { Bool(TypeInfo), String(TypeInfo), StringArray(TypeInfo), - Object(TypeInfo), + Object(Object), } impl Type { - pub fn to_owned_type(&self) -> String { - match self { - Type::Number(_) => "i128".into(), - Type::Float(_) => "f32".into(), - Type::Bool(_) => "bool".into(), - Type::String(_) => "String".into(), - // TODO: fixme - Type::StringArray(_) => "String".into(), - Type::Object(_) => "String".into(), - } - } - pub fn to_borrowed_type(&self) -> String { match self { Type::Number(_) => "i32".into(), @@ -70,7 +76,7 @@ impl Type { Type::Bool(_) => "bool".into(), Type::String(_) => "str".into(), Type::StringArray(_) => "&[str]".into(), - Type::Object(_) => "str".into(), + Type::Object(_) => todo!(), } } @@ -78,6 +84,14 @@ impl Type { matches!(self, Type::String(_) | Type::Object(_)) } + pub fn is_optional(&self) -> bool { + self.get_type_info().is_optional + } + + pub fn is_list(&self) -> bool { + self.get_type_info().is_list + } + pub fn get_type_info(&self) -> &TypeInfo { match self { Type::Number(t) => t, @@ -85,17 +99,11 @@ impl Type { Type::Bool(t) => t, Type::String(t) => t, Type::StringArray(t) => t, - Type::Object(t) => t, + Type::Object(t) => &t.type_info, } } - pub fn from( - type_as_str: &str, - name: &str, - description: Option, - types: &HashMap, - ) -> Option { - let available_types = types.get(name).cloned(); + pub fn from(type_as_str: &str, name: &str, description: Option) -> Option { let type_name = match name.split_once(OPTIONAL) { Some((split, _)) => split, None => name, @@ -103,17 +111,130 @@ impl Type { .trim(); let is_optional = name.contains(OPTIONAL); - let type_info = TypeInfo::new(type_name, is_optional, false, description, available_types); + let is_list = description + .clone() + .map(|desc| desc.contains("array")) + .unwrap_or(false); - match type_as_str { - "bool" => Some(Type::Bool(type_info)), - "integer" | "number" | "int" => Some(Type::Number(type_info)), - "string" => Some(Type::String(type_info)), - // This is probably not right but we don't have any information about the actual type. - "array" => Some(Type::StringArray(type_info)), - "object" => Some(Type::Object(type_info)), - "float" => Some(Type::Float(type_info)), - _ => None, + let (type_without_array, type_contains_array) = if type_as_str.contains("array") { + (type_as_str.replace("array", ""), true) + } else { + (type_as_str.to_owned(), false) + }; + + let create_type_info = || { + TypeInfo::new( + type_name, + is_optional, + is_list || type_contains_array, + description.clone(), + ) + }; + + let create_object_type = |ref_type: RefType| { + Some(Type::Object(Object { + type_info: create_type_info(), + ref_type, + })) + }; + + match type_without_array.trim() { + "raw" => None, + "bool" => Some(Type::Bool(create_type_info())), + "integer" | "number" | "int" => Some(Type::Number(create_type_info())), + "string" => Some(Type::String(create_type_info())), + "array" => description + .extract_type() + .and_then(create_object_type) + .or_else(|| Some(Type::StringArray(create_type_info()))), + "float" => Some(Type::Float(create_type_info())), + name => description + .extract_type() + .and_then(create_object_type) + .or_else(|| { + let n = if name.is_empty() { + "String".into() + } else { + name.into() + }; + + create_object_type(RefType::String(n)) + }), } } } + +trait ExtractType { + fn extract_type(&self) -> Option; +} + +impl ExtractType for Option { + fn extract_type(&self) -> Option { + let list_type = || { + self.as_ref().and_then(|t| { + let re = RegexBuilder::new(r"(?:Array|List) of (\w+) objects") + .case_insensitive(true) + .build() + .unwrap(); + + let cap = re.captures(t)?; + + cap.get(1) + .map(|m| m.as_str().to_camel()) + .map(RefType::String) + }) + }; + + let map_type = || { + self.as_ref().and_then(|t| { + let re = RegexBuilder::new(r"map from (\w+) to (\w+) object") + .case_insensitive(true) + .build() + .unwrap(); + + let cap = re.captures(t)?; + let key_type = match cap.get(1).map(|m| m.as_str().to_camel()) { + Some(k) => k, + None => return None, + }; + let value_type = match cap.get(2).map(|m| m.as_str().to_camel()) { + Some(v) => v, + None => return None, + }; + + Some(RefType::Map(key_type, value_type)) + }) + }; + + let object_type = || { + self.as_ref().and_then(|t| { + let re = RegexBuilder::new(r"(\w+) object see table below") + .case_insensitive(true) + .build() + .unwrap(); + + let cap = re.captures(t)?; + let object_type = match cap.get(1).map(|m| m.as_str().to_camel()) { + Some(k) => k, + None => return None, + }; + + Some(RefType::String(object_type)) + }) + }; + + list_type().or_else(map_type).or_else(object_type) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_regex() { + let input = Some("Array of result objects- see table below".to_string()); + let res = input.extract_type(); + assert_eq!(res.unwrap(), RefType::String("Result".into())); + } +} diff --git a/qbittorrent-web-api-gen/tests/access_impl_types.rs b/qbittorrent-web-api-gen/tests/access_impl_types.rs index cc59017..b0f6148 100644 --- a/qbittorrent-web-api-gen/tests/access_impl_types.rs +++ b/qbittorrent-web-api-gen/tests/access_impl_types.rs @@ -10,7 +10,7 @@ mod foo { #[tokio::main] async fn main() -> Result<()> { - let _ = foo::api_impl::ApplicationPreferencesBittorrentProtocol::TCP; + let _ = foo::api_impl::application::preferences::BittorrentProtocol::TCP; Ok(()) } diff --git a/qbittorrent-web-api-gen/tests/access_search.rs b/qbittorrent-web-api-gen/tests/access_search.rs new file mode 100644 index 0000000..504dbc3 --- /dev/null +++ b/qbittorrent-web-api-gen/tests/access_search.rs @@ -0,0 +1,20 @@ +mod common; + +use anyhow::Result; +use common::*; +use qbittorrent_web_api_gen::QBittorrentApiGen; + +#[derive(QBittorrentApiGen)] +struct Api {} + +#[tokio::main] +async fn main() -> Result<()> { + let api = Api::login(BASE_URL, USERNAME, PASSWORD).await?; + + let _ = api.search().delete(1).send().await?; + let _ = api.search().plugins().await?; + let _ = api.search().plugins().await?; + let _ = api.search().install_plugin("https://raw.githubusercontent.com/qbittorrent/search-plugins/master/nova3/engines/legittorrents.py").send().await?; + + Ok(()) +} diff --git a/qbittorrent-web-api-gen/tests/add_torrent.rs b/qbittorrent-web-api-gen/tests/add_torrent.rs index 697fb63..b1a0124 100644 --- a/qbittorrent-web-api-gen/tests/add_torrent.rs +++ b/qbittorrent-web-api-gen/tests/add_torrent.rs @@ -1,9 +1,8 @@ -use anyhow::Result; -use qbittorrent_web_api_gen::QBittorrentApiGen; +mod common; -const USERNAME: &str = "admin"; -const PASSWORD: &str = "adminadmin"; -const BASE_URL: &str = "http://localhost:8080"; +use anyhow::Result; +use common::*; +use qbittorrent_web_api_gen::QBittorrentApiGen; #[derive(QBittorrentApiGen)] struct Api {} diff --git a/qbittorrent-web-api-gen/tests/another_struct_name.rs b/qbittorrent-web-api-gen/tests/another_struct_name.rs index bca720b..7cccbf2 100644 --- a/qbittorrent-web-api-gen/tests/another_struct_name.rs +++ b/qbittorrent-web-api-gen/tests/another_struct_name.rs @@ -1,9 +1,8 @@ -use anyhow::Result; -use qbittorrent_web_api_gen::QBittorrentApiGen; +mod common; -const USERNAME: &str = "admin"; -const PASSWORD: &str = "adminadmin"; -const BASE_URL: &str = "http://localhost:8080"; +use anyhow::Result; +use common::*; +use qbittorrent_web_api_gen::QBittorrentApiGen; #[derive(QBittorrentApiGen)] struct Foo {} diff --git a/qbittorrent-web-api-gen/tests/common/mod.rs b/qbittorrent-web-api-gen/tests/common/mod.rs new file mode 100644 index 0000000..8180627 --- /dev/null +++ b/qbittorrent-web-api-gen/tests/common/mod.rs @@ -0,0 +1,3 @@ +pub const USERNAME: &str = "admin"; +pub const PASSWORD: &str = "adminadmin"; +pub const BASE_URL: &str = "http://localhost:8080"; diff --git a/qbittorrent-web-api-gen/tests/default_parameters.rs b/qbittorrent-web-api-gen/tests/default_parameters.rs index 2617e95..5cd7531 100644 --- a/qbittorrent-web-api-gen/tests/default_parameters.rs +++ b/qbittorrent-web-api-gen/tests/default_parameters.rs @@ -1,9 +1,8 @@ -use anyhow::Result; -use qbittorrent_web_api_gen::QBittorrentApiGen; +mod common; -const USERNAME: &str = "admin"; -const PASSWORD: &str = "adminadmin"; -const BASE_URL: &str = "http://localhost:8080"; +use anyhow::Result; +use common::*; +use qbittorrent_web_api_gen::QBittorrentApiGen; #[derive(QBittorrentApiGen)] struct Api {} diff --git a/qbittorrent-web-api-gen/tests/login.rs b/qbittorrent-web-api-gen/tests/login.rs index fb54bd4..ff9292d 100644 --- a/qbittorrent-web-api-gen/tests/login.rs +++ b/qbittorrent-web-api-gen/tests/login.rs @@ -1,9 +1,8 @@ -use anyhow::Result; -use qbittorrent_web_api_gen::QBittorrentApiGen; +mod common; -const USERNAME: &str = "admin"; -const PASSWORD: &str = "adminadmin"; -const BASE_URL: &str = "http://localhost:8080"; +use anyhow::Result; +use common::*; +use qbittorrent_web_api_gen::QBittorrentApiGen; #[derive(QBittorrentApiGen)] struct Api {} diff --git a/qbittorrent-web-api-gen/tests/logout.rs b/qbittorrent-web-api-gen/tests/logout.rs index 97bfeb9..c002f24 100644 --- a/qbittorrent-web-api-gen/tests/logout.rs +++ b/qbittorrent-web-api-gen/tests/logout.rs @@ -1,9 +1,8 @@ -use anyhow::Result; -use qbittorrent_web_api_gen::QBittorrentApiGen; +mod common; -const USERNAME: &str = "admin"; -const PASSWORD: &str = "adminadmin"; -const BASE_URL: &str = "http://localhost:8080"; +use anyhow::Result; +use common::*; +use qbittorrent_web_api_gen::QBittorrentApiGen; #[derive(QBittorrentApiGen)] struct Api {} diff --git a/qbittorrent-web-api-gen/tests/return_type.rs b/qbittorrent-web-api-gen/tests/return_type.rs index 6c87cab..55a3585 100644 --- a/qbittorrent-web-api-gen/tests/return_type.rs +++ b/qbittorrent-web-api-gen/tests/return_type.rs @@ -1,9 +1,8 @@ -use anyhow::Result; -use qbittorrent_web_api_gen::QBittorrentApiGen; +mod common; -const USERNAME: &str = "admin"; -const PASSWORD: &str = "adminadmin"; -const BASE_URL: &str = "http://localhost:8080"; +use anyhow::Result; +use common::*; +use qbittorrent_web_api_gen::QBittorrentApiGen; #[derive(QBittorrentApiGen)] struct Api {} diff --git a/qbittorrent-web-api-gen/tests/return_type_enum.rs b/qbittorrent-web-api-gen/tests/return_type_enum.rs index c557513..2e37c26 100644 --- a/qbittorrent-web-api-gen/tests/return_type_enum.rs +++ b/qbittorrent-web-api-gen/tests/return_type_enum.rs @@ -1,10 +1,9 @@ -use anyhow::Result; -use qbittorrent_web_api_gen::QBittorrentApiGen; -use tokio::time::{sleep, Duration}; +mod common; -const USERNAME: &str = "admin"; -const PASSWORD: &str = "adminadmin"; -const BASE_URL: &str = "http://localhost:8080"; +use anyhow::Result; +use common::*; +use qbittorrent_web_api_gen::QBittorrentApiGen; +use tokio::time::*; #[derive(QBittorrentApiGen)] struct Api {} diff --git a/qbittorrent-web-api-gen/tests/return_type_with_optional_params.rs b/qbittorrent-web-api-gen/tests/return_type_with_optional_params.rs index c557513..2e37c26 100644 --- a/qbittorrent-web-api-gen/tests/return_type_with_optional_params.rs +++ b/qbittorrent-web-api-gen/tests/return_type_with_optional_params.rs @@ -1,10 +1,9 @@ -use anyhow::Result; -use qbittorrent_web_api_gen::QBittorrentApiGen; -use tokio::time::{sleep, Duration}; +mod common; -const USERNAME: &str = "admin"; -const PASSWORD: &str = "adminadmin"; -const BASE_URL: &str = "http://localhost:8080"; +use anyhow::Result; +use common::*; +use qbittorrent_web_api_gen::QBittorrentApiGen; +use tokio::time::*; #[derive(QBittorrentApiGen)] struct Api {} diff --git a/qbittorrent-web-api-gen/tests/search_types.rs b/qbittorrent-web-api-gen/tests/search_types.rs new file mode 100644 index 0000000..4a21fbd --- /dev/null +++ b/qbittorrent-web-api-gen/tests/search_types.rs @@ -0,0 +1,19 @@ +mod common; + +use anyhow::Result; +use common::*; +use qbittorrent_web_api_gen::QBittorrentApiGen; + +#[derive(QBittorrentApiGen)] +struct Api {} + +#[tokio::main] +async fn main() -> Result<()> { + let api = Api::login(BASE_URL, USERNAME, PASSWORD).await?; + + let _ = api.search().install_plugin("https://raw.githubusercontent.com/qbittorrent/search-plugins/master/nova3/engines/legittorrents.py").await?; + // just check that the deserialization works + let _ = api.search().plugins().await?; + + Ok(()) +} diff --git a/qbittorrent-web-api-gen/tests/tests.rs b/qbittorrent-web-api-gen/tests/tests.rs index 61f2cd2..873c7ba 100644 --- a/qbittorrent-web-api-gen/tests/tests.rs +++ b/qbittorrent-web-api-gen/tests/tests.rs @@ -1,6 +1,7 @@ #[test] fn tests() { let t = trybuild::TestCases::new(); + // --- Auth --- t.pass("tests/login.rs"); t.pass("tests/logout.rs"); @@ -19,4 +20,5 @@ fn tests() { t.pass("tests/add_torrent.rs"); t.pass("tests/another_struct_name.rs"); t.pass("tests/access_impl_types.rs"); + t.pass("tests/search_types.rs"); } diff --git a/qbittorrent-web-api-gen/tests/without_parameters.rs b/qbittorrent-web-api-gen/tests/without_parameters.rs index aa23d4f..47dec5d 100644 --- a/qbittorrent-web-api-gen/tests/without_parameters.rs +++ b/qbittorrent-web-api-gen/tests/without_parameters.rs @@ -1,9 +1,8 @@ -use anyhow::Result; -use qbittorrent_web_api_gen::QBittorrentApiGen; +mod common; -const USERNAME: &str = "admin"; -const PASSWORD: &str = "adminadmin"; -const BASE_URL: &str = "http://localhost:8080"; +use anyhow::Result; +use common::*; +use qbittorrent_web_api_gen::QBittorrentApiGen; #[derive(QBittorrentApiGen)] struct Api {} diff --git a/qbittorrent-web-api-gen/token_tree.txt b/qbittorrent-web-api-gen/token_tree.txt index 52bd36c..0e4a9f3 100644 --- a/qbittorrent-web-api-gen/token_tree.txt +++ b/qbittorrent-web-api-gen/token_tree.txt @@ -380,7 +380,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "", ), Text( @@ -825,7 +825,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -862,7 +862,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -896,6 +899,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Upon success, the response will contain a cookie with your SID. You must supply the cookie whenever you want to perform an operation that requires authentication.", ), @@ -961,7 +967,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -973,7 +979,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -1000,6 +1006,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -1035,7 +1044,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -1047,7 +1056,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -1074,6 +1083,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is a string with the application version, e.g. `v4.1.3`", ), @@ -1097,7 +1109,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -1109,7 +1121,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -1136,6 +1148,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is a string with the WebAPI version, e.g. `2.0`", ), @@ -1159,7 +1174,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -1171,7 +1186,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -1198,6 +1213,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is a JSON object containing the following fields", ), @@ -1259,6 +1277,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -1276,7 +1297,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -1288,7 +1309,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -1315,6 +1336,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -1332,7 +1356,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -1344,7 +1368,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -1371,6 +1395,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is a JSON object with several fields (key-value) pairs representing the application's settings. The contents may vary depending on which settings are present in qBittorrent.ini.", ), @@ -2566,6 +2593,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Possible values of `scan_dirs`:", ), @@ -2607,6 +2637,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Possible values of `scheduler_days`:", ), @@ -2697,6 +2730,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Possible values of `encryption`:", ), @@ -2738,6 +2774,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "NB: the first options allows you to use both encrypted and unencrypted connections (this is the default); other options are mutually exclusive: e.g. by forcing encryption on you won't be able to use unencrypted connections and vice versa.", ), @@ -2806,6 +2845,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Possible values of `dyndns_service`:", ), @@ -2840,6 +2882,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Possible values of `max_ratio_act`:", ), @@ -2874,6 +2919,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Possible values of `bittorrent_protocol`:", ), @@ -2915,6 +2963,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Possible values of `upload_choking_algorithm`:", ), @@ -2956,6 +3007,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Possible values of `upload_slots_behavior`:", ), @@ -2990,6 +3044,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Possible values of `utp_tcp_mixed_mode`:", ), @@ -3024,6 +3081,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -3500,7 +3560,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -3530,7 +3590,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -3557,7 +3617,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Notes**:", ), Text( @@ -3598,7 +3661,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -3610,7 +3673,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -3637,6 +3700,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is a string with the default save path, e.g. `C:/Users/Dayman/Downloads`.", ), @@ -3678,7 +3744,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -3739,6 +3805,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -3757,7 +3826,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -3784,6 +3853,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is a JSON array in which each element is an entry of the log.", ), @@ -3843,6 +3915,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -4169,7 +4244,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -4198,7 +4273,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -4225,6 +4303,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response a JSON array. Each element of the array of objects (each object is the information relative to a peer) containing the following fields", ), @@ -4286,6 +4367,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -4324,7 +4408,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -4353,6 +4437,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -4371,7 +4458,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -4398,6 +4485,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is a JSON object with the following possible fields", ), @@ -4407,17 +4497,17 @@ TokenTree { Table( Table { header: TableRow { - raw: "Property | Type | Description", + raw: "Property | Type | Description", columns: [ "Property", "Type", "Description", ], }, - split: "------------------------------|---------|------------", + split: "--------------------------------|-----------|------------", rows: [ TableRow { - raw: "`rid` | integer | Response ID", + raw: "`rid` | integer | Response ID", columns: [ "rid", "integer", @@ -4425,72 +4515,75 @@ TokenTree { ], }, TableRow { - raw: "`full_update` | bool | Whether the response contains all the data or partial data", + raw: "`full_update`_optional_ | bool | Whether the response contains all the data or partial data", columns: [ - "full_update", + "full_update_optional_", "bool", "Whether the response contains all the data or partial data", ], }, TableRow { - raw: "`torrents` | object | Property: torrent hash, value: same as [torrent list](#get-torrent-list)", + raw: "`torrents`_optional_ | object | Property: torrent hash, value: same as [torrent list](#get-torrent-list), map from string to torrents object", columns: [ - "torrents", + "torrents_optional_", "object", - "Property: torrent hash, value: same as [torrent list](#get-torrent-list)", + "Property: torrent hash, value: same as [torrent list](#get-torrent-list), map from string to torrents object", ], }, TableRow { - raw: "`torrents_removed` | array | List of hashes of torrents removed since last request", + raw: "`torrents_removed`_optional_ | array | List of hashes of torrents removed since last request", columns: [ - "torrents_removed", + "torrents_removed_optional_", "array", "List of hashes of torrents removed since last request", ], }, TableRow { - raw: "`categories` | object | Info for categories added since last request", + raw: "`categories`_optional_ | object | Info for categories added since last request, map from string to categories object", columns: [ - "categories", + "categories_optional_", "object", - "Info for categories added since last request", + "Info for categories added since last request, map from string to categories object", ], }, TableRow { - raw: "`categories_removed` | array | List of categories removed since last request", + raw: "`categories_removed`_optional_ | array | List of categories removed since last request", columns: [ - "categories_removed", + "categories_removed_optional_", "array", "List of categories removed since last request", ], }, TableRow { - raw: "`tags` | array | List of tags added since last request", + raw: "`tags`_optional_ | array | List of tags added since last request", columns: [ - "tags", + "tags_optional_", "array", "List of tags added since last request", ], }, TableRow { - raw: "`tags_removed` | array | List of tags removed since last request", + raw: "`tags_removed`_optional_ | array | List of tags removed since last request", columns: [ - "tags_removed", + "tags_removed_optional_", "array", "List of tags removed since last request", ], }, TableRow { - raw: "`server_state` | object | Global transfer info", + raw: "`server_state`_optional_ | object | `server_state` object see table below", columns: [ - "server_state", + "server_state_optional_", "object", - "Global transfer info", + "server_state object see table below", ], }, ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -4536,6 +4629,502 @@ TokenTree { Text( "", ), + Asterisk( + "ServerState object:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Property | Type | Description", + columns: [ + "Property", + "Type", + "Description", + ], + }, + split: "------------------------------|---------|------------", + rows: [ + TableRow { + raw: "`average_time_queue` | integer | Average time queue", + columns: [ + "average_time_queue", + "integer", + "Average time queue", + ], + }, + TableRow { + raw: "`dl_info_data` | number | Download info data", + columns: [ + "dl_info_data", + "number", + "Download info data", + ], + }, + TableRow { + raw: "`dl_info_speed` | number | Download info speed", + columns: [ + "dl_info_speed", + "number", + "Download info speed", + ], + }, + TableRow { + raw: "`queued_io_jobs` | integer | Queued io jobs", + columns: [ + "queued_io_jobs", + "integer", + "Queued io jobs", + ], + }, + TableRow { + raw: "`total_buffers_size` | number | Total buffers size", + columns: [ + "total_buffers_size", + "number", + "Total buffers size", + ], + }, + TableRow { + raw: "`total_peer_connections` | integer | Total peer connections", + columns: [ + "total_peer_connections", + "integer", + "Total peer connections", + ], + }, + ], + }, + ), + Text( + "", + ), + Asterisk( + "Categories object:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Property | Type | Description", + columns: [ + "Property", + "Type", + "Description", + ], + }, + split: "------------------------------|---------|------------", + rows: [ + TableRow { + raw: "`name` | string | Category name", + columns: [ + "name", + "string", + "Category name", + ], + }, + TableRow { + raw: "`savePath` | string | Save path", + columns: [ + "savePath", + "string", + "Save path", + ], + }, + ], + }, + ), + Text( + "", + ), + Asterisk( + "Torrents object:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Property | Type | Description", + columns: [ + "Property", + "Type", + "Description", + ], + }, + split: "--------------------------------|-----------|------------", + rows: [ + TableRow { + raw: "`added_on`_optional_ | integer | Time (Unix Epoch) when the torrent was added to the client", + columns: [ + "added_on_optional_", + "integer", + "Time (Unix Epoch) when the torrent was added to the client", + ], + }, + TableRow { + raw: "`amount_left`_optional_ | integer | Amount of data left to download (bytes)", + columns: [ + "amount_left_optional_", + "integer", + "Amount of data left to download (bytes)", + ], + }, + TableRow { + raw: "`auto_tmm`_optional_ | bool | Whether this torrent is managed by Automatic Torrent Management", + columns: [ + "auto_tmm_optional_", + "bool", + "Whether this torrent is managed by Automatic Torrent Management", + ], + }, + TableRow { + raw: "`availability`_optional_ | float | Percentage of file pieces currently available", + columns: [ + "availability_optional_", + "float", + "Percentage of file pieces currently available", + ], + }, + TableRow { + raw: "`category`_optional_ | string | Category of the torrent", + columns: [ + "category_optional_", + "string", + "Category of the torrent", + ], + }, + TableRow { + raw: "`completed`_optional_ | integer | Amount of transfer data completed (bytes)", + columns: [ + "completed_optional_", + "integer", + "Amount of transfer data completed (bytes)", + ], + }, + TableRow { + raw: "`completion_on`_optional_ | integer | Time (Unix Epoch) when the torrent completed", + columns: [ + "completion_on_optional_", + "integer", + "Time (Unix Epoch) when the torrent completed", + ], + }, + TableRow { + raw: "`content_path`_optional_ | string | Absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents)", + columns: [ + "content_path_optional_", + "string", + "Absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents)", + ], + }, + TableRow { + raw: "`dl_limit`_optional_ | integer | Torrent download speed limit (bytes/s). `-1` if ulimited.", + columns: [ + "dl_limit_optional_", + "integer", + "Torrent download speed limit (bytes/s). -1 if ulimited.", + ], + }, + TableRow { + raw: "`dlspeed`_optional_ | integer | Torrent download speed (bytes/s)", + columns: [ + "dlspeed_optional_", + "integer", + "Torrent download speed (bytes/s)", + ], + }, + TableRow { + raw: "`downloaded`_optional_ | integer | Amount of data downloaded", + columns: [ + "downloaded_optional_", + "integer", + "Amount of data downloaded", + ], + }, + TableRow { + raw: "`downloaded_session`_optional_ | integer | Amount of data downloaded this session", + columns: [ + "downloaded_session_optional_", + "integer", + "Amount of data downloaded this session", + ], + }, + TableRow { + raw: "`eta`_optional_ | integer | Torrent ETA (seconds)", + columns: [ + "eta_optional_", + "integer", + "Torrent ETA (seconds)", + ], + }, + TableRow { + raw: "`f_l_piece_prio`_optional_ | bool | True if first last piece are prioritized", + columns: [ + "f_l_piece_prio_optional_", + "bool", + "True if first last piece are prioritized", + ], + }, + TableRow { + raw: "`force_start`_optional_ | bool | True if force start is enabled for this torrent", + columns: [ + "force_start_optional_", + "bool", + "True if force start is enabled for this torrent", + ], + }, + TableRow { + raw: "`hash`_optional_ | string | Torrent hash", + columns: [ + "hash_optional_", + "string", + "Torrent hash", + ], + }, + TableRow { + raw: "`last_activity`_optional_ | integer | Last time (Unix Epoch) when a chunk was downloaded/uploaded", + columns: [ + "last_activity_optional_", + "integer", + "Last time (Unix Epoch) when a chunk was downloaded/uploaded", + ], + }, + TableRow { + raw: "`magnet_uri`_optional_ | string | Magnet URI corresponding to this torrent", + columns: [ + "magnet_uri_optional_", + "string", + "Magnet URI corresponding to this torrent", + ], + }, + TableRow { + raw: "`max_ratio`_optional_ | float | Maximum share ratio until torrent is stopped from seeding/uploading", + columns: [ + "max_ratio_optional_", + "float", + "Maximum share ratio until torrent is stopped from seeding/uploading", + ], + }, + TableRow { + raw: "`max_seeding_time`_optional_ | integer | Maximum seeding time (seconds) until torrent is stopped from seeding", + columns: [ + "max_seeding_time_optional_", + "integer", + "Maximum seeding time (seconds) until torrent is stopped from seeding", + ], + }, + TableRow { + raw: "`name`_optional_ | string | Torrent name", + columns: [ + "name_optional_", + "string", + "Torrent name", + ], + }, + TableRow { + raw: "`num_complete`_optional_ | integer | Number of seeds in the swarm", + columns: [ + "num_complete_optional_", + "integer", + "Number of seeds in the swarm", + ], + }, + TableRow { + raw: "`num_incomplete`_optional_ | integer | Number of leechers in the swarm", + columns: [ + "num_incomplete_optional_", + "integer", + "Number of leechers in the swarm", + ], + }, + TableRow { + raw: "`num_leechs`_optional_ | integer | Number of leechers connected to", + columns: [ + "num_leechs_optional_", + "integer", + "Number of leechers connected to", + ], + }, + TableRow { + raw: "`num_seeds`_optional_ | integer | Number of seeds connected to", + columns: [ + "num_seeds_optional_", + "integer", + "Number of seeds connected to", + ], + }, + TableRow { + raw: "`priority`_optional_ | integer | Torrent priority. Returns -1 if queuing is disabled or torrent is in seed mode", + columns: [ + "priority_optional_", + "integer", + "Torrent priority. Returns -1 if queuing is disabled or torrent is in seed mode", + ], + }, + TableRow { + raw: "`progress`_optional_ | float | Torrent progress (percentage/100)", + columns: [ + "progress_optional_", + "float", + "Torrent progress (percentage/100)", + ], + }, + TableRow { + raw: "`ratio`_optional_ | float | Torrent share ratio. Max ratio value: 9999.", + columns: [ + "ratio_optional_", + "float", + "Torrent share ratio. Max ratio value: 9999.", + ], + }, + TableRow { + raw: "`ratio_limit`_optional_ | float | TODO (what is different from `max_ratio`?)", + columns: [ + "ratio_limit_optional_", + "float", + "TODO (what is different from max_ratio?)", + ], + }, + TableRow { + raw: "`save_path`_optional_ | string | Path where this torrent's data is stored", + columns: [ + "save_path_optional_", + "string", + "Path where this torrent's data is stored", + ], + }, + TableRow { + raw: "`seeding_time`_optional_ | integer | Torrent elapsed time while complete (seconds)", + columns: [ + "seeding_time_optional_", + "integer", + "Torrent elapsed time while complete (seconds)", + ], + }, + TableRow { + raw: "`seeding_time_limit`_optional_ | integer | TODO (what is different from `max_seeding_time`?) seeding_time_limit is a per torrent setting, when Automatic Torrent Management is disabled, furthermore then max_seeding_time is set to seeding_time_limit for this torrent. If Automatic Torrent Management is enabled, the value is -2. And if max_seeding_time is unset it have a default value -1.", + columns: [ + "seeding_time_limit_optional_", + "integer", + "TODO (what is different from max_seeding_time?) seeding_time_limit is a per torrent setting, when Automatic Torrent Management is disabled, furthermore then max_seeding_time is set to seeding_time_limit for this torrent. If Automatic Torrent Management is enabled, the value is -2. And if max_seeding_time is unset it have a default value -1.", + ], + }, + TableRow { + raw: "`seen_complete`_optional_ | integer | Time (Unix Epoch) when this torrent was last seen complete", + columns: [ + "seen_complete_optional_", + "integer", + "Time (Unix Epoch) when this torrent was last seen complete", + ], + }, + TableRow { + raw: "`seq_dl`_optional_ | bool | True if sequential download is enabled", + columns: [ + "seq_dl_optional_", + "bool", + "True if sequential download is enabled", + ], + }, + TableRow { + raw: "`size`_optional_ | integer | Total size (bytes) of files selected for download", + columns: [ + "size_optional_", + "integer", + "Total size (bytes) of files selected for download", + ], + }, + TableRow { + raw: "`state`_optional_ | string | Torrent state. See table here below for the possible values", + columns: [ + "state_optional_", + "string", + "Torrent state. See table here below for the possible values", + ], + }, + TableRow { + raw: "`super_seeding`_optional_ | bool | True if super seeding is enabled", + columns: [ + "super_seeding_optional_", + "bool", + "True if super seeding is enabled", + ], + }, + TableRow { + raw: "`tags`_optional_ | string | Comma-concatenated tag list of the torrent", + columns: [ + "tags_optional_", + "string", + "Comma-concatenated tag list of the torrent", + ], + }, + TableRow { + raw: "`time_active`_optional_ | integer | Total active time (seconds)", + columns: [ + "time_active_optional_", + "integer", + "Total active time (seconds)", + ], + }, + TableRow { + raw: "`total_size`_optional_ | integer | Total size (bytes) of all file in this torrent (including unselected ones)", + columns: [ + "total_size_optional_", + "integer", + "Total size (bytes) of all file in this torrent (including unselected ones)", + ], + }, + TableRow { + raw: "`tracker`_optional_ | string | The first tracker with working status. Returns empty string if no tracker is working.", + columns: [ + "tracker_optional_", + "string", + "The first tracker with working status. Returns empty string if no tracker is working.", + ], + }, + TableRow { + raw: "`up_limit`_optional_ | integer | Torrent upload speed limit (bytes/s). `-1` if ulimited.", + columns: [ + "up_limit_optional_", + "integer", + "Torrent upload speed limit (bytes/s). -1 if ulimited.", + ], + }, + TableRow { + raw: "`uploaded`_optional_ | integer | Amount of data uploaded", + columns: [ + "uploaded_optional_", + "integer", + "Amount of data uploaded", + ], + }, + TableRow { + raw: "`uploaded_session`_optional_ | integer | Amount of data uploaded this session", + columns: [ + "uploaded_session_optional_", + "integer", + "Amount of data uploaded this session", + ], + }, + TableRow { + raw: "`upspeed`_optional_ | integer | Torrent upload speed (bytes/s)", + columns: [ + "upspeed_optional_", + "integer", + "Torrent upload speed (bytes/s)", + ], + }, + ], + }, + ), + Text( + "", + ), ], children: [], }, @@ -4553,7 +5142,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -4590,6 +5179,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -4608,7 +5200,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -4642,6 +5234,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is TODO", ), @@ -4689,7 +5284,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -4701,7 +5296,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -4728,6 +5323,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is a JSON object with the following fields", ), @@ -4813,6 +5411,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "In addition to the above in partial data requests (see [Get partial data](#get-partial-data) for more info):", ), @@ -4858,30 +5459,29 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Possible values of `connection_status`:", ), Text( "", ), + Text( + "Value |", + ), Table( Table { header: TableRow { - raw: "Value |", + raw: "--------------------|", columns: [ - "Value", + "--------------------", "", ], }, - split: "--------------------|", + split: "`connected` |", rows: [ - TableRow { - raw: "`connected` |", - columns: [ - "connected", - "", - ], - }, TableRow { raw: "`firewalled` |", columns: [ @@ -4899,6 +5499,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -4961,7 +5564,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -4973,7 +5576,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -5000,6 +5603,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is `1` if alternative speed limits are enabled, `0` otherwise.", ), @@ -5023,7 +5629,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -5035,7 +5641,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -5062,6 +5668,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -5079,7 +5688,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -5091,7 +5700,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -5118,6 +5727,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is the value of current global download speed limit in bytes/second; this value will be zero if no limit is applied.", ), @@ -5141,7 +5753,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -5170,7 +5782,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -5197,6 +5812,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -5214,7 +5832,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -5226,7 +5844,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -5253,6 +5871,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is the value of current global upload speed limit in bytes/second; this value will be zero if no limit is applied.", ), @@ -5276,7 +5897,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -5305,7 +5926,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -5332,6 +5956,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -5349,7 +5976,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -5379,7 +6006,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -5406,6 +6036,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -5441,7 +6074,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -5527,6 +6160,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -5545,7 +6181,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -5572,6 +6208,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is a JSON array with the following fields", ), @@ -5953,6 +6592,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Possible values of `state`:", ), @@ -6106,6 +6748,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -6225,7 +6870,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -6254,7 +6899,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -6288,6 +6936,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is:", ), @@ -6582,6 +7233,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "NB: `-1` is returned if the type of the property is integer but its value is not known.", ), @@ -6731,7 +7385,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -6760,7 +7414,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -6794,6 +7451,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is a JSON array, where each element contains info about one tracker, with the following fields", ), @@ -6879,6 +7539,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Possible values of `status`:", ), @@ -6934,6 +7597,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -7005,7 +7671,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -7034,7 +7700,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -7068,6 +7737,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is a JSON array, where each element is information about one webseed, with the following fields", ), @@ -7097,6 +7769,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -7159,7 +7834,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -7197,7 +7872,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -7231,6 +7909,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is:", ), @@ -7325,6 +8006,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Possible values of `priority`:", ), @@ -7373,6 +8057,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -7450,7 +8137,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -7479,7 +8166,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -7513,6 +8203,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is:", ), @@ -7569,6 +8262,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -7610,7 +8306,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -7639,7 +8335,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -7673,6 +8372,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is:", ), @@ -7729,7 +8431,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -7759,6 +8461,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -7768,20 +8473,16 @@ TokenTree { Text( "```http", ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/pause?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/pause?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, + Text( + "/api/v2/torrents/pause?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", ), - Asterix( + Text( + "```", + ), + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -7808,6 +8509,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -7831,7 +8535,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -7861,6 +8565,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -7870,20 +8577,16 @@ TokenTree { Text( "```http", ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/resume?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/resume?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, + Text( + "/api/v2/torrents/resume?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", ), - Asterix( + Text( + "```", + ), + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -7910,6 +8613,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -7933,7 +8639,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -7961,15 +8667,19 @@ TokenTree { ], }, TableRow { - raw: "`deleteFiles` | If set to `true`, the downloaded data will also be deleted, otherwise has no effect.", + raw: "`deleteFiles` | bool | If set to `true`, the downloaded data will also be deleted, otherwise has no effect.", columns: [ "deleteFiles", + "bool", "If set to true, the downloaded data will also be deleted, otherwise has no effect.", ], }, ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -7988,7 +8698,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -8015,6 +8725,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -8038,7 +8751,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -8068,6 +8781,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -8077,20 +8793,16 @@ TokenTree { Text( "```http", ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/recheck?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/recheck?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, + Text( + "/api/v2/torrents/recheck?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", ), - Asterix( + Text( + "```", + ), + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -8117,6 +8829,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -8140,7 +8855,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -8170,6 +8885,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -8179,20 +8897,16 @@ TokenTree { Text( "```http", ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/reannounce?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/reannounce?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, + Text( + "/api/v2/torrents/reannounce?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", ), - Asterix( + Text( + "```", + ), + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -8219,6 +8933,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -8446,7 +9163,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -8603,7 +9320,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -8637,6 +9357,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -8699,7 +9422,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -8733,6 +9456,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -8750,7 +9476,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -8795,7 +9521,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -8850,6 +9579,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -8867,7 +9599,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -8905,7 +9637,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -8946,6 +9681,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -8963,7 +9701,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -9002,7 +9740,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -9036,6 +9777,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -9059,7 +9803,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -9089,6 +9833,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -9098,20 +9845,16 @@ TokenTree { Text( "```http", ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/increasePrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/increasePrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, + Text( + "/api/v2/torrents/increasePrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", ), - Asterix( + Text( + "```", + ), + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -9145,6 +9888,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -9168,7 +9914,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -9198,6 +9944,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -9207,20 +9956,16 @@ TokenTree { Text( "```http", ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/decreasePrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/decreasePrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, + Text( + "/api/v2/torrents/decreasePrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", ), - Asterix( + Text( + "```", + ), + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -9254,6 +9999,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -9277,7 +10025,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -9307,6 +10055,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -9316,20 +10067,16 @@ TokenTree { Text( "```http", ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/topPrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/topPrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, + Text( + "/api/v2/torrents/topPrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", ), - Asterix( + Text( + "```", + ), + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -9363,6 +10110,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -9386,7 +10136,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -9416,6 +10166,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -9425,20 +10178,16 @@ TokenTree { Text( "```http", ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/bottomPrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/bottomPrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, + Text( + "/api/v2/torrents/bottomPrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", ), - Asterix( + Text( + "```", + ), + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -9472,6 +10221,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -9489,7 +10241,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -9535,6 +10287,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "`id` values correspond to file position inside the array returned by [torrent contents API](#get-torrent-contents), e.g. `id=0` for first file, `id=1` for second file, etc.", ), @@ -9547,7 +10302,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -9609,6 +10364,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -9656,31 +10414,23 @@ TokenTree { Text( "", ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0", - ], - }, - split: "```", - rows: [], - }, + Text( + "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0", ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "", - rows: [], - }, + Text( + "```", + ), + Text( + "", + ), + Text( + "`hashes` can contain multiple hashes separated by `|` or set to `all`", + ), + Text( + "", + ), + Text( + "Server reply (example):", ), Text( "", @@ -9756,33 +10506,25 @@ TokenTree { Text( "", ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&limit=131072", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0&limit=131072", - ], - }, - split: "```", - rows: [], - }, + Text( + "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&limit=131072", ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "`limit` is the download speed limit in bytes per second you want to set.", - rows: [], - }, + Text( + "```", ), - Asterix( + Text( + "", + ), + Text( + "`hashes` can contain multiple hashes separated by `|` or set to `all`", + ), + Text( + "`limit` is the download speed limit in bytes per second you want to set.", + ), + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -9809,6 +10551,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -9856,36 +10601,28 @@ TokenTree { Text( "", ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&ratioLimit=1.0&seedingTimeLimit=60", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0&ratioLimit=1.0&seedingTimeLimit=60", - ], - }, - split: "```", - rows: [], - }, + Text( + "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&ratioLimit=1.0&seedingTimeLimit=60", ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "`ratioLimit` is the max ratio the torrent should be seeded until. `-2` means the global limit should be used, `-1` means no limit.", - rows: [], - }, + Text( + "```", ), Text( "", ), - Asterix( + Text( + "`hashes` can contain multiple hashes separated by `|` or set to `all`", + ), + Text( + "`ratioLimit` is the max ratio the torrent should be seeded until. `-2` means the global limit should be used, `-1` means no limit.", + ), + Text( + "`seedingTimeLimit` is the max amount of time the torrent should be seeded. `-2` means the global limit should be used, `-1` means no limit.", + ), + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -9912,6 +10649,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -9959,31 +10699,23 @@ TokenTree { Text( "", ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0", - ], - }, - split: "```", - rows: [], - }, + Text( + "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0", ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "", - rows: [], - }, + Text( + "```", + ), + Text( + "", + ), + Text( + "`hashes` can contain multiple hashes separated by `|` or set to `all`", + ), + Text( + "", + ), + Text( + "Server reply (example):", ), Text( "", @@ -10065,33 +10797,25 @@ TokenTree { Text( "", ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&limit=131072", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0&limit=131072", - ], - }, - split: "```", - rows: [], - }, + Text( + "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&limit=131072", ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "`limit` is the upload speed limit in bytes per second you want to set.", - rows: [], - }, + Text( + "```", ), - Asterix( + Text( + "", + ), + Text( + "`hashes` can contain multiple hashes separated by `|` or set to `all`", + ), + Text( + "`limit` is the upload speed limit in bytes per second you want to set.", + ), + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -10118,6 +10842,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -10165,33 +10892,25 @@ TokenTree { Text( "", ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&location=/mnt/nfs/media", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0&location=/mnt/nfs/media", - ], - }, - split: "```", - rows: [], - }, + Text( + "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&location=/mnt/nfs/media", ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "`location` is the location to download the torrent to. If the location doesn't exist, the torrent's location is unchanged.", - rows: [], - }, + Text( + "```", ), - Asterix( + Text( + "", + ), + Text( + "`hashes` can contain multiple hashes separated by `|` or set to `all`", + ), + Text( + "`location` is the location to download the torrent to. If the location doesn't exist, the torrent's location is unchanged.", + ), + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -10239,6 +10958,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -10295,7 +11017,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -10336,6 +11058,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -10383,36 +11108,28 @@ TokenTree { Text( "", ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&category=CategoryName", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0&category=CategoryName", - ], - }, - split: "```", - rows: [], - }, + Text( + "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&category=CategoryName", ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "", - rows: [], - }, + Text( + "```", ), Text( "", ), - Asterix( + Text( + "`hashes` can contain multiple hashes separated by `|` or set to `all`", + ), + Text( + "", + ), + Text( + "`category` is the torrent category you want to set.", + ), + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -10446,6 +11163,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -10517,7 +11237,7 @@ TokenTree { Text( "```", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -10544,6 +11264,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -10600,7 +11323,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -10641,6 +11364,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -10691,7 +11417,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -10732,6 +11458,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -10788,7 +11517,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -10815,6 +11544,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -10862,36 +11594,28 @@ TokenTree { Text( "", ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&tags=TagName1,TagName2", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0&tags=TagName1,TagName2", - ], - }, - split: "```", - rows: [], - }, + Text( + "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&tags=TagName1,TagName2", ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "", - rows: [], - }, + Text( + "```", ), Text( "", ), - Asterix( + Text( + "`hashes` can contain multiple hashes separated by `|` or set to `all`", + ), + Text( + "", + ), + Text( + "`tags` is the list of tags you want to add to passed torrents.", + ), + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -10918,6 +11642,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -10965,31 +11692,23 @@ TokenTree { Text( "", ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&tags=TagName1,TagName2", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0&tags=TagName1,TagName2", - ], - }, - split: "```", - rows: [], - }, + Text( + "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&tags=TagName1,TagName2", ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "", - rows: [], - }, + Text( + "```", + ), + Text( + "", + ), + Text( + "`hashes` can contain multiple hashes separated by `|` or set to `all`", + ), + Text( + "", + ), + Text( + "`tags` is the list of tags you want to remove from passed torrents.", ), Text( "Empty list removes all tags from relevant torrents.", @@ -10997,7 +11716,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -11024,6 +11743,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -11077,7 +11799,7 @@ TokenTree { Text( "```", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -11104,6 +11826,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -11160,7 +11885,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -11187,6 +11912,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -11246,7 +11974,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -11273,6 +12001,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -11320,33 +12051,25 @@ TokenTree { Text( "", ), - Table( - Table { - header: TableRow { - raw: "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&enable=true", - columns: [ - "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "284b83c9c7935002391129fd97f43db5d7cc2ba0&enable=true", - ], - }, - split: "```", - rows: [], - }, + Text( + "hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|284b83c9c7935002391129fd97f43db5d7cc2ba0&enable=true", ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "`enable` is a boolean, affects the torrents listed in `hashes`, default is `false`", - rows: [], - }, + Text( + "```", ), - Asterix( + Text( + "", + ), + Text( + "`hashes` can contain multiple hashes separated by `|` or set to `all`", + ), + Text( + "`enable` is a boolean, affects the torrents listed in `hashes`, default is `false`", + ), + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -11373,6 +12096,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -11396,7 +12122,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -11426,6 +12152,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -11435,20 +12164,16 @@ TokenTree { Text( "```http", ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/toggleSequentialDownload?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/toggleSequentialDownload?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, + Text( + "/api/v2/torrents/toggleSequentialDownload?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", ), - Asterix( + Text( + "```", + ), + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -11475,6 +12200,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -11498,7 +12226,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -11528,6 +12256,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -11537,20 +12268,16 @@ TokenTree { Text( "```http", ), - Table( - Table { - header: TableRow { - raw: "/api/v2/torrents/toggleFirstLastPiecePrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", - columns: [ - "/api/v2/torrents/toggleFirstLastPiecePrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32", - "54eddd830a5b58480a6143d616a97e3a6c23c439", - ], - }, - split: "```", - rows: [], - }, + Text( + "/api/v2/torrents/toggleFirstLastPiecePrio?hashes=8c212779b4abde7c6bc608063a0d008b7e40ce32|54eddd830a5b58480a6143d616a97e3a6c23c439", ), - Asterix( + Text( + "```", + ), + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -11577,6 +12304,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -11633,20 +12363,16 @@ TokenTree { Text( "", ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "`value` is a boolean, affects the torrents listed in `hashes`, default is `false`", - rows: [], - }, + Text( + "`hashes` can contain multiple hashes separated by `|` or set to `all`", ), - Asterix( + Text( + "`value` is a boolean, affects the torrents listed in `hashes`, default is `false`", + ), + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -11673,6 +12399,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -11729,20 +12458,16 @@ TokenTree { Text( "", ), - Table( - Table { - header: TableRow { - raw: "`hashes` can contain multiple hashes separated by `|` or set to `all`", - columns: [ - "hashes can contain multiple hashes separated by", - "or set to all", - ], - }, - split: "`value` is a boolean, affects the torrents listed in `hashes`, default is `false`", - rows: [], - }, + Text( + "`hashes` can contain multiple hashes separated by `|` or set to `all`", ), - Asterix( + Text( + "`value` is a boolean, affects the torrents listed in `hashes`, default is `false`", + ), + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -11769,6 +12494,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -11786,7 +12514,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -11831,7 +12559,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -11872,6 +12603,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -11889,7 +12623,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -11934,7 +12668,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -11975,6 +12712,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -12039,7 +12779,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -12073,6 +12816,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -12127,7 +12873,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -12161,6 +12910,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -12213,7 +12965,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -12247,6 +13002,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -12307,7 +13065,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -12341,6 +13102,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -12387,6 +13151,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Returns all RSS items in JSON format, e.g.:", ), @@ -12486,7 +13253,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -12513,6 +13283,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -12565,7 +13338,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -12592,6 +13368,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -12646,6 +13425,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Rule definition is JSON encoded dictionary with the following fields:", ), @@ -12771,6 +13553,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "E.g.:", ), @@ -12894,7 +13679,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -12921,6 +13709,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -12967,7 +13758,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -12997,6 +13791,9 @@ TokenTree { Text( "", ), + Text( + "", + ), ], children: [], }, @@ -13086,7 +13883,7 @@ TokenTree { Text( "```", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -13113,6 +13910,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -13156,6 +13956,9 @@ TokenTree { Text( "", ), + Text( + "", + ), Text( "Returns all articles that match a rule by feed name in JSON format, e.g.:", ), @@ -13222,7 +14025,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Returns:", ), Text( @@ -13252,6 +14055,9 @@ TokenTree { Text( "", ), + Text( + "", + ), ], children: [], }, @@ -13287,7 +14093,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -13333,7 +14139,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -13367,6 +14176,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is a JSON object with the following fields", ), @@ -13396,6 +14208,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -13437,7 +14252,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -13466,7 +14281,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -13500,6 +14318,9 @@ TokenTree { ], }, ), + Text( + "", + ), ], children: [], }, @@ -13517,7 +14338,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -13546,7 +14367,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -13580,6 +14404,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is a JSON array of objects containing the following fields", ), @@ -13625,6 +14452,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "Example:", ), @@ -13678,7 +14508,7 @@ TokenTree { Text( "", ), - Asterix( + Asterisk( "Parameters:", ), Text( @@ -13723,7 +14553,10 @@ TokenTree { ], }, ), - Asterix( + Text( + "", + ), + Asterisk( "Returns:", ), Text( @@ -13764,6 +14597,9 @@ TokenTree { ], }, ), + Text( + "", + ), Text( "The response is a JSON object with the following fields", ), @@ -13781,13 +14617,894 @@ TokenTree { ], }, split: "----------------------------------|---------|------------", - rows: [], + rows: [ + TableRow { + raw: "`results` | array | Array of `result` objects- see table below", + columns: [ + "results", + "array", + "Array of result objects- see table below", + ], + }, + TableRow { + raw: "`status` | string | Current status of the search job (either `Running` or `Stopped`)", + columns: [ + "status", + "string", + "Current status of the search job (either Running or Stopped)", + ], + }, + TableRow { + raw: "`total` | number | Total number of results. If the status is `Running` this number may continue to increase", + columns: [ + "total", + "number", + "Total number of results. If the status is Running this number may continue to increase", + ], + }, + ], }, ), + Text( + "", + ), + Asterisk( + "Result object:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Field | Type | Description", + columns: [ + "Field", + "Type", + "Description", + ], + }, + split: "----------------------------------|---------|------------", + rows: [ + TableRow { + raw: "`descrLink` | string | URL of the torrent's description page", + columns: [ + "descrLink", + "string", + "URL of the torrent's description page", + ], + }, + TableRow { + raw: "`fileName` | string | Name of the file", + columns: [ + "fileName", + "string", + "Name of the file", + ], + }, + TableRow { + raw: "`fileSize` | number | Size of the file in Bytes", + columns: [ + "fileSize", + "number", + "Size of the file in Bytes", + ], + }, + TableRow { + raw: "`fileUrl` | string | Torrent download link (usually either .torrent file or magnet link)", + columns: [ + "fileUrl", + "string", + "Torrent download link (usually either .torrent file or magnet link)", + ], + }, + TableRow { + raw: "`nbLeechers` | number | Number of leechers", + columns: [ + "nbLeechers", + "number", + "Number of leechers", + ], + }, + TableRow { + raw: "`nbSeeders` | number | Number of seeders", + columns: [ + "nbSeeders", + "number", + "Number of seeders", + ], + }, + TableRow { + raw: "`siteUrl` | string | URL of the torrent site", + columns: [ + "siteUrl", + "string", + "URL of the torrent site", + ], + }, + ], + }, + ), + Text( + "", + ), + Text( + "Example:", + ), + Text( + "", + ), + Text( + "```JSON", + ), + Text( + "{", + ), + Text( + " \"results\": [", + ), + Text( + " {", + ), + Text( + " \"descrLink\": \"http://www.legittorrents.info/index.php?page=torrent-details&id=8d5f512e1acb687029b8d7cc6c5a84dce51d7a41\",", + ), + Text( + " \"fileName\": \"Ubuntu-10.04-32bit-NeTV.ova\",", + ), + Text( + " \"fileSize\": -1,", + ), + Text( + " \"fileUrl\": \"http://www.legittorrents.info/download.php?id=8d5f512e1acb687029b8d7cc6c5a84dce51d7a41&f=Ubuntu-10.04-32bit-NeTV.ova.torrent\",", + ), + Text( + " \"nbLeechers\": 1,", + ), + Text( + " \"nbSeeders\": 0,", + ), + Text( + " \"siteUrl\": \"http://www.legittorrents.info\"", + ), + Text( + " },", + ), + Text( + " {", + ), + Text( + " \"descrLink\": \"http://www.legittorrents.info/index.php?page=torrent-details&id=d5179f53e105dc2c2401bcfaa0c2c4936a6aa475\",", + ), + Text( + " \"fileName\": \"mangOH-Legato-17_06-Ubuntu-16_04.ova\",", + ), + Text( + " \"fileSize\": -1,", + ), + Text( + " \"fileUrl\": \"http://www.legittorrents.info/download.php?id=d5179f53e105dc2c2401bcfaa0c2c4936a6aa475&f=mangOH-Legato-17_06-Ubuntu-16_04.ova.torrent\",", + ), + Text( + " \"nbLeechers\": 0,", + ), + Text( + " \"nbSeeders\": 59,", + ), + Text( + " \"siteUrl\": \"http://www.legittorrents.info\"", + ), + Text( + " }", + ), + Text( + " ],", + ), + Text( + " \"status\": \"Running\",", + ), + Text( + " \"total\": 2", + ), + Text( + "}", + ), + Text( + "```", + ), + Text( + "", + ), + ], + children: [], + }, + TokenTree { + title: Some( + "Delete search", + ), + content: [ + Text( + "", + ), + Text( + "Name: `delete`", + ), + Text( + "", + ), + Asterisk( + "Parameters:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Parameter | Type | Description", + columns: [ + "Parameter", + "Type", + "Description", + ], + }, + split: "----------------------------------|---------|------------", + rows: [ + TableRow { + raw: "`id` | number | ID of the search job", + columns: [ + "id", + "number", + "ID of the search job", + ], + }, + ], + }, + ), + Text( + "", + ), + Asterisk( + "Returns:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "HTTP Status Code | Scenario", + columns: [ + "HTTP Status Code", + "Scenario", + ], + }, + split: "----------------------------------|---------------------", + rows: [ + TableRow { + raw: "404 | Search job was not found", + columns: [ + "404", + "Search job was not found", + ], + }, + TableRow { + raw: "200 | All other scenarios", + columns: [ + "200", + "All other scenarios", + ], + }, + ], + }, + ), + Text( + "", + ), + ], + children: [], + }, + TokenTree { + title: Some( + "Get search plugins", + ), + content: [ + Text( + "", + ), + Text( + "Name: `plugins`", + ), + Text( + "", + ), + Asterisk( + "Parameters:", + ), + Text( + "", + ), + Text( + "None", + ), + Text( + "", + ), + Asterisk( + "Returns:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "HTTP Status Code | Scenario", + columns: [ + "HTTP Status Code", + "Scenario", + ], + }, + split: "----------------------------------|---------------------", + rows: [ + TableRow { + raw: "200 | All scenarios- see JSON below", + columns: [ + "200", + "All scenarios- see JSON below", + ], + }, + ], + }, + ), + Text( + "", + ), + Text( + "The response is a JSON array of objects containing the following fields", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Field | Type | Description", + columns: [ + "Field", + "Type", + "Description", + ], + }, + split: "----------------------------------|---------|------------", + rows: [ + TableRow { + raw: "`enabled` | bool | Whether the plugin is enabled", + columns: [ + "enabled", + "bool", + "Whether the plugin is enabled", + ], + }, + TableRow { + raw: "`fullName` | string | Full name of the plugin", + columns: [ + "fullName", + "string", + "Full name of the plugin", + ], + }, + TableRow { + raw: "`name` | string | Short name of the plugin", + columns: [ + "name", + "string", + "Short name of the plugin", + ], + }, + TableRow { + raw: "`supportedCategories` | array | List of category objects", + columns: [ + "supportedCategories", + "array", + "List of category objects", + ], + }, + TableRow { + raw: "`url` | string | URL of the torrent site", + columns: [ + "url", + "string", + "URL of the torrent site", + ], + }, + TableRow { + raw: "`version` | string | Installed version of the plugin", + columns: [ + "version", + "string", + "Installed version of the plugin", + ], + }, + ], + }, + ), + Text( + "", + ), + Text( + "```JSON", + ), + Text( + "[", + ), + Text( + " {", + ), + Text( + " \"enabled\": true,", + ), + Text( + " \"fullName\": \"Legit Torrents\",", + ), + Text( + " \"name\": \"legittorrents\",", + ), + Text( + " \"supportedCategories\": [{", + ), + Text( + " \"id\": \"all\",", + ), + Text( + " \"name\": \"All categories\"", + ), + Text( + " }, {", + ), + Text( + " \"id\": \"anime\",", + ), + Text( + " \"name\": \"Anime\"", + ), + Text( + " }, {", + ), + Text( + " \"id\": \"books\",", + ), + Text( + " \"name\": \"Books\"", + ), + Text( + " }, {", + ), + Text( + " \"id\": \"games\",", + ), + Text( + " \"name\": \"Games\"", + ), + Text( + " }, {", + ), + Text( + " \"id\": \"movies\",", + ), + Text( + " \"name\": \"Movies\"", + ), + Text( + " }, {", + ), + Text( + " \"id\": \"music\",", + ), + Text( + " \"name\": \"Music\"", + ), + Text( + " }, {", + ), + Text( + " \"id\": \"tv\",", + ), + Text( + " \"name\": \"TV shows\"", + ), + Text( + " }],", + ), + Text( + " \"url\": \"http://www.legittorrents.info\",", + ), + Text( + " \"version\": \"2.3\"", + ), + Text( + " }", + ), + Text( + "]", + ), + Text( + "```", + ), + Text( + "", + ), + Asterisk( + "Category object:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Field | Type | Description", + columns: [ + "Field", + "Type", + "Description", + ], + }, + split: "---------------------------|---------|------------", + rows: [ + TableRow { + raw: "`id` | string | Id", + columns: [ + "id", + "string", + "Id", + ], + }, + TableRow { + raw: "`name` | string | Name", + columns: [ + "name", + "string", + "Name", + ], + }, + ], + }, + ), + Text( + "", + ), + ], + children: [], + }, + TokenTree { + title: Some( + "Install search plugin", + ), + content: [ + Text( + "", + ), + Text( + "Name: `installPlugin`", + ), + Text( + "", + ), + Asterisk( + "Parameters:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Parameter | Type | Description", + columns: [ + "Parameter", + "Type", + "Description", + ], + }, + split: "----------------------------------|---------|------------", + rows: [ + TableRow { + raw: "`sources` | string | Url or file path of the plugin to install (e.g. \"[https://raw.githubusercontent.com/qbittorrent/search-plugins/master/nova3/engines/legittorrents.py](https://raw.githubusercontent.com/qbittorrent/search-plugins/master/nova3/engines/legittorrents.py)\"). Supports multiple sources separated by `\\|`", + columns: [ + "sources", + "string", + "Url or file path of the plugin to install (e.g. \"[https://raw.githubusercontent.com/qbittorrent/search-plugins/master/nova3/engines/legittorrents.py](https://raw.githubusercontent.com/qbittorrent/search-plugins/master/nova3/engines/legittorrents.py)\"). Supports multiple sources separated by \\", + "", + ], + }, + ], + }, + ), + Text( + "", + ), + Asterisk( + "Returns:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "HTTP Status Code | Scenario", + columns: [ + "HTTP Status Code", + "Scenario", + ], + }, + split: "----------------------------------|---------------------", + rows: [ + TableRow { + raw: "200 | All scenarios", + columns: [ + "200", + "All scenarios", + ], + }, + ], + }, + ), + Text( + "", + ), + ], + children: [], + }, + TokenTree { + title: Some( + "Uninstall search plugin", + ), + content: [ + Text( + "", + ), + Text( + "Name: `uninstallPlugin`", + ), + Text( + "", + ), + Asterisk( + "Parameters:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Parameter | Type | Description", + columns: [ + "Parameter", + "Type", + "Description", + ], + }, + split: "----------------------------------|---------|------------", + rows: [ + TableRow { + raw: "`names` | string | Name of the plugin to uninstall (e.g. \"legittorrents\"). Supports multiple names separated by `\\|`", + columns: [ + "names", + "string", + "Name of the plugin to uninstall (e.g. \"legittorrents\"). Supports multiple names separated by \\", + "", + ], + }, + ], + }, + ), + Text( + "", + ), + Asterisk( + "Returns:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "HTTP Status Code | Scenario", + columns: [ + "HTTP Status Code", + "Scenario", + ], + }, + split: "----------------------------------|---------------------", + rows: [ + TableRow { + raw: "200 | All scenarios", + columns: [ + "200", + "All scenarios", + ], + }, + ], + }, + ), + Text( + "", + ), + ], + children: [], + }, + TokenTree { + title: Some( + "Enable search plugin", + ), + content: [ + Text( + "", + ), + Text( + "Name: `enablePlugin`", + ), + Text( + "", + ), + Asterisk( + "Parameters:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Parameter | Type | Description", + columns: [ + "Parameter", + "Type", + "Description", + ], + }, + split: "----------------------------------|---------|------------", + rows: [ + TableRow { + raw: "`names` | string | Name of the plugin to enable/disable (e.g. \"legittorrents\"). Supports multiple names separated by `\\|`", + columns: [ + "names", + "string", + "Name of the plugin to enable/disable (e.g. \"legittorrents\"). Supports multiple names separated by \\", + "", + ], + }, + TableRow { + raw: "`enable` | bool | Whether the plugins should be enabled", + columns: [ + "enable", + "bool", + "Whether the plugins should be enabled", + ], + }, + ], + }, + ), + Text( + "", + ), + Asterisk( + "Returns:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "HTTP Status Code | Scenario", + columns: [ + "HTTP Status Code", + "Scenario", + ], + }, + split: "----------------------------------|---------------------", + rows: [ + TableRow { + raw: "200 | All scenarios", + columns: [ + "200", + "All scenarios", + ], + }, + ], + }, + ), + Text( + "", + ), + ], + children: [], + }, + TokenTree { + title: Some( + "Update search plugins", + ), + content: [ + Text( + "", + ), + Text( + "Name: `updatePlugins`", + ), + Text( + "", + ), + Asterisk( + "Parameters:", + ), + Text( + "", + ), + Text( + "None", + ), + Text( + "", + ), + Asterisk( + "Returns:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "HTTP Status Code | Scenario", + columns: [ + "HTTP Status Code", + "Scenario", + ], + }, + split: "----------------------------------|---------------------", + rows: [ + TableRow { + raw: "200 | All scenarios", + columns: [ + "200", + "All scenarios", + ], + }, + ], + }, + ), + Text( + "", + ), ], children: [], }, ], }, + TokenTree { + title: Some( + "WebAPI versioning", + ), + content: [ + Text( + "WebAPI uses the following versioning: `1.2.3`:", + ), + Text( + "1. Main version. Should be changed only on some global changes (e.g. total redesign/relayout)", + ), + Text( + "2. Changed on incompatible API changes (i.e. if it breaks outdated clients). E.g. if you change/remove something", + ), + Text( + "3. Changed on compatible API changes (i.e. if it doesn't break outdated clients). E.g. if you add something new outdated clients still can access old subset of API.", + ), + ], + children: [], + }, ], } \ No newline at end of file