11use crate :: apps:: { App , Protocol , endpoint} ;
22use reqwest:: blocking:: Client ;
3+ use serde_json:: Value ;
34use std:: collections:: HashMap ;
45use std:: path:: { Path , PathBuf } ;
56use std:: time:: Duration ;
@@ -8,6 +9,7 @@ use tracing::{debug, error, info, warn};
89// API Endpoints
910const QB_LOGIN_ENDPOINT : & str = "/api/v2/auth/login" ;
1011const QB_SET_PREFERENCES_ENDPOINT : & str = "/api/v2/app/setPreferences" ;
12+ const QB_GET_PREFERENCES_ENDPOINT : & str = "/api/v2/app/preferences" ;
1113
1214pub struct Qbittorrent {
1315 pub client : Client ,
@@ -51,18 +53,35 @@ impl App for Qbittorrent {
5153
5254 fn set_port ( & self , port : u16 ) -> bool {
5355 let client = & self . client ;
54- let json = HashMap :: from ( [ ( "json" . to_string ( ) , format ! ( "{{listen_port:{} }}" , port) ) ] ) ;
56+ let json = HashMap :: from ( [ ( "json" . to_string ( ) , format ! ( "{{\" listen_port\" :{} }}" , port) ) ] ) ;
5557 let response = client
5658 . post ( self . set_preference_endpoint ( ) )
5759 . form ( & json)
5860 . send ( ) ;
59-
6061 match response {
6162 Ok ( r) => {
6263 let status = r. status ( ) ;
6364 if status. is_success ( ) {
64- info ! ( "Port updated to {}" , port) ;
65- true
65+ let actual_port = self . get_current_listen_port ( ) ;
66+ debug ! ( "actual_port: {:?}" , actual_port) ;
67+ match actual_port {
68+ None => {
69+ error ! ( "unable to get actual port value" ) ;
70+ false
71+ }
72+ Some ( actual) => {
73+ if port == actual {
74+ info ! ( "Port updated to {}" , port) ;
75+ true
76+ } else {
77+ warn ! (
78+ "Actual port {} does not match expected port number {}" ,
79+ actual, port
80+ ) ;
81+ false
82+ }
83+ }
84+ }
6685 } else {
6786 warn ! ( "Port update request failed with status code: {}" , status) ;
6887 false
@@ -109,4 +128,38 @@ impl Qbittorrent {
109128 QB_SET_PREFERENCES_ENDPOINT ,
110129 )
111130 }
131+
132+ fn get_preference_endpoint ( & self ) -> String {
133+ endpoint (
134+ self . protocol ,
135+ self . hostname . as_str ( ) ,
136+ self . port ,
137+ QB_GET_PREFERENCES_ENDPOINT ,
138+ )
139+ }
140+
141+ fn get_current_listen_port ( & self ) -> Option < u16 > {
142+ let client = & self . client ;
143+ let response = client. get ( self . get_preference_endpoint ( ) ) . send ( ) ;
144+
145+ match response {
146+ Ok ( r) => {
147+ let status = r. status ( ) ;
148+ if status. is_success ( ) {
149+ let json: Value = r. json ( ) . expect ( "cannot get preference json" ) ;
150+ let current_port = json. as_object ( ) . unwrap ( ) . get ( "listen_port" ) . unwrap ( ) ;
151+ current_port
152+ . as_number ( )
153+ . map ( |p| p. as_u64 ( ) . unwrap_or_default ( ) as u16 )
154+ } else {
155+ warn ! ( "get preference request failed with status code: {}" , status) ;
156+ None
157+ }
158+ }
159+ Err ( e) => {
160+ error ! ( "{}" , e) ;
161+ None
162+ }
163+ }
164+ }
112165}
0 commit comments