diff --git a/Cargo.toml b/Cargo.toml index cacd0b2..a26521f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fie" -version = "0.7.0" +version = "0.7.1" authors = ["Douman "] repository = "https://github.com/DoumanAsh/fie" description = "Small and cute twitter app." diff --git a/fie.toml b/fie.toml index d9563f4..b0286aa 100644 --- a/fie.toml +++ b/fie.toml @@ -26,3 +26,9 @@ password = "password" minds = true gab = true twitter = true + +[settings] +# Amount of seconds to wait for responses from API server. +# All request fails when it exceeds this time +# Default value is 5 seconds +timeout = 5 diff --git a/src/actors/gab.rs b/src/actors/gab.rs index 9d97e52..042459c 100644 --- a/src/actors/gab.rs +++ b/src/actors/gab.rs @@ -17,6 +17,7 @@ use misc::{ClientRequestBuilderExt, ClientRequestExt}; /// Gab actor pub struct Gab { config: config::Gab, + settings: config::Settings } impl Actor for Gab { @@ -26,8 +27,8 @@ impl Actor for Gab { } impl Gab { - pub fn new(config: config::Gab) -> Self { - Self { config } + pub fn new(config: config::Gab, settings: config::Settings) -> Self { + Self { config, settings } } } @@ -53,7 +54,7 @@ impl Handler for Gab { Err(error) => return Box::new(future::err(error)), }; - let req = req.send_ext() + let req = req.send_with_timeout(self.settings.timeout) .map_err(|error| format!("Gab upload error: {}", error)) .and_then(|response| match response.status().is_success() { true => Ok(response), @@ -134,7 +135,7 @@ impl Handler for Gab { Err(error) => return Box::new(future::err(format!("Gab post actix error: {}", error))), }; - let req = req.send_ext() + let req = req.send_with_timeout(self.settings.timeout) .map_err(|error| format!("Gab post error: {}", error)) .and_then(|response| match response.status().is_success() { true => Ok(response), diff --git a/src/actors/minds.rs b/src/actors/minds.rs index 8109e00..049b28f 100644 --- a/src/actors/minds.rs +++ b/src/actors/minds.rs @@ -81,18 +81,31 @@ mod payload { } } -pub enum Minds { +enum State { NotStarted(config::Minds), Started(payload::Oauth2), } +pub struct Minds { + state: State, + settings: config::Settings +} + +impl Minds { + pub fn new(config: config::Minds, settings: config::Settings) -> Self { + Self { + state: State::NotStarted(config), + settings + } + } +} impl Actor for Minds { type Context = Context; fn started(&mut self, ctx: &mut Context) { const OAUTH2_URL: &'static str = "https://www.minds.com/oauth2/token"; - let config = match self { - &mut Minds::NotStarted(ref config) => config, + let config = match &self.state { + &State::NotStarted(ref config) => config, _ => { eprintln!("Minds: internal error. Actor in a started state already"); return ctx.stop(); @@ -112,7 +125,7 @@ impl Actor for Minds { }, }; - req.send_ext() + req.send_with_timeout(self.settings.timeout) .into_actor(self) .map_err(|error, _act, ctx| { eprintln!("Minds oauth2 error: {}", error); @@ -121,7 +134,7 @@ impl Actor for Minds { .and_then(|rsp, act, _ctx| { rsp.json() .into_actor(act) - .map(|oauth2, act, _ctx| *act = Minds::Started(oauth2)) + .map(|oauth2, act, _ctx| (*act).state = State::Started(oauth2)) .map_err(|error, _act, ctx| { eprintln!("Minds oauth2 parse error: {}", error); ctx.stop() @@ -131,20 +144,14 @@ impl Actor for Minds { } } -impl Minds { - pub fn new(config: config::Minds) -> Self { - Minds::NotStarted(config) - } -} - impl Handler for Minds { type Result = ResponseFuture; fn handle(&mut self, msg: UploadImage, _: &mut Self::Context) -> Self::Result { const IMAGES_URL: &'static str = "https://www.minds.com/api/v1/media"; - let access_token = match self { - &mut Minds::Started(ref oauth2) => &oauth2.access_token, + let access_token = match &self.state { + &State::Started(ref oauth2) => &oauth2.access_token, _ => return Box::new(future::err("Unable to send Minds request".to_string())), }; @@ -159,7 +166,7 @@ impl Handler for Minds { Err(error) => return Box::new(future::err(error)), }; - let req = req.send_ext() + let req = req.send_with_timeout(self.settings.timeout) .map_err(|error| format!("Minds upload error: {}", error)) .and_then(|response| match response.status().is_success() { true => Ok(response), @@ -183,8 +190,8 @@ impl Handler for Minds { fn handle(&mut self, msg: PostMessage, _: &mut Self::Context) -> Self::Result { const POST_URL: &'static str = "https://www.minds.com/api/v1/newsfeed"; - let access_token = match self { - &mut Minds::Started(ref oauth2) => &oauth2.access_token, + let access_token = match &self.state { + &State::Started(ref oauth2) => &oauth2.access_token, _ => return Box::new(future::err("Unable to send Minds request".to_string())), }; @@ -204,7 +211,7 @@ impl Handler for Minds { Err(error) => return Box::new(future::err(format!("Minds post actix error: {}", error))), }; - let req = req.send_ext() + let req = req.send_with_timeout(self.settings.timeout) .map_err(|error| format!("Minds post error: {}", error)) .and_then(|response| match response.status().is_success() { true => Ok(response), diff --git a/src/actors/mod.rs b/src/actors/mod.rs index 9c7c7a7..22f2199 100644 --- a/src/actors/mod.rs +++ b/src/actors/mod.rs @@ -25,6 +25,7 @@ pub struct API { pub twitter: Option>, pub gab: Option>, pub minds: Option>, + settings: config::Settings } impl API { @@ -33,12 +34,13 @@ impl API { twitter: None, gab: None, minds: None, + settings: config::Settings::default() } } pub fn start_minds_if(mut self, cond: bool, minds: config::Minds) -> Self { if cond { - self.minds = Some(Minds::new(minds).start()); + self.minds = Some(Minds::new(minds, self.settings.clone()).start()); } self @@ -46,7 +48,7 @@ impl API { pub fn start_gab_if(mut self, cond: bool, gab: config::Gab) -> Self { if cond { - self.gab = Some(Gab::new(gab).start()); + self.gab = Some(Gab::new(gab, self.settings.clone()).start()); } self diff --git a/src/config.rs b/src/config.rs index 5ffa5b5..7819a01 100644 --- a/src/config.rs +++ b/src/config.rs @@ -53,12 +53,30 @@ pub struct Gab { /// You can get it after logging into gab.io and examining your HTTP requests. pub token: String, } + #[derive(Deserialize, Debug)] pub struct Minds { pub username: String, pub password: String, } +fn default_timeout() -> u64 { 5 } + +#[derive(Deserialize, Debug, Clone)] +pub struct Settings { + #[serde(default = "default_timeout")] + ///Amount of settings to wait for all HTTP responses + pub timeout: u64, +} + +impl Default for Settings { + fn default() -> Self { + Self { + timeout: 5 + } + } +} + #[derive(Deserialize, Debug)] pub struct Config { #[serde(default)] @@ -66,6 +84,8 @@ pub struct Config { pub gab: Gab, pub twitter: Twitter, pub minds: Minds, + #[serde(default)] + pub settings: Settings } impl Config { diff --git a/src/misc.rs b/src/misc.rs index bdf57a2..5464af9 100644 --- a/src/misc.rs +++ b/src/misc.rs @@ -22,18 +22,16 @@ impl ResultExt for Result { ///Number of seconds to wait for connection const CONN_TIMEOUT_S: u64 = 5; -///Number of seconds to wait for response -const WAIT_TIMEOUT_S: u64 = 300; pub trait ClientRequestExt { - fn send_ext(self) -> SendRequest; + fn send_with_timeout(self, timeout: u64) -> SendRequest; } impl ClientRequestExt for ClientRequest { - fn send_ext(self) -> SendRequest { + fn send_with_timeout(self, timeout: u64) -> SendRequest { self.send() - .timeout(time::Duration::new(WAIT_TIMEOUT_S, 0)) + .timeout(time::Duration::new(timeout, 0)) .conn_timeout(time::Duration::new(CONN_TIMEOUT_S, 0)) - .wait_timeout(time::Duration::new(WAIT_TIMEOUT_S, 0)) + .wait_timeout(time::Duration::new(timeout, 0)) } }