diff options
| -rw-r--r-- | Cargo.lock | 61 | ||||
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | src/main.rs | 89 | 
3 files changed, 128 insertions, 24 deletions
| @@ -141,6 +141,26 @@ dependencies = [  ]  [[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]]  name = "either"  version = "1.6.1"  source = "registry+https://github.com/rust-lang/crates.io-index" @@ -178,6 +198,17 @@ dependencies = [  ]  [[package]] +name = "getrandom" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]]  name = "hashbrown"  version = "0.11.2"  source = "registry+https://github.com/rust-lang/crates.io-index" @@ -375,6 +406,25 @@ dependencies = [  ]  [[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +dependencies = [ + "getrandom", + "redox_syscall", +] + +[[package]]  name = "ring"  version = "0.16.20"  source = "registry+https://github.com/rust-lang/crates.io-index" @@ -567,15 +617,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"  checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"  [[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]]  name = "traveltext"  version = "0.1.0"  dependencies = [   "chrono",   "clap",   "colored", + "dirs",   "itertools",   "serde",   "serde_json", + "toml",   "ureq",  ] @@ -13,3 +13,5 @@ serde_json = "1.0.78"  colored = "2.0.0"  chrono = "0.4.19"  itertools = "0.10.2" +dirs = "4.0.0" +toml = "0.5.8" diff --git a/src/main.rs b/src/main.rs index dc8ac75..cbaf251 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,21 +1,21 @@  use clap::{Parser, Subcommand}; -  use colored::*; +use serde::Deserialize;  use traveltext::types::*;  use traveltext::{iceportal::*, travelynx::*}; -#[allow(non_upper_case_globals)] -const token: &str = "1387-d942ee22-1d34-4dc2-89b6-5e7ef229fb5e"; -#[allow(non_upper_case_globals)] -const baseurl: &str = "https://travelynx.de"; -  #[derive(Parser)]  struct Cli {      #[clap(subcommand)]      command: Command, +    /// print requests that couldn't be parsed to help debugging      #[clap(long)]      debug: bool, +    #[clap(default_value = "https://travelynx.de")] +    baseurl: String, +    /// API token to use in requests +    token: Option<String>,  }  #[derive(Subcommand)] @@ -39,6 +39,12 @@ enum Command {      ICEPortal,  } +#[derive(Deserialize)] +struct Config { +    token_status: String, +    token_travel: String, +} +  fn main() -> Result<(), ureq::Error> {      let cli = Cli::parse(); @@ -50,22 +56,47 @@ fn main() -> Result<(), ureq::Error> {          "xt".cyan()      ); +    let configpath = { +        let mut path = dirs::config_dir().unwrap(); +        path.push("traveltext.toml"); +        path +    }; + +    let config: Config = match std::fs::read_to_string(&configpath) { +        Ok(text) => match toml::from_str(&text) { +            Ok(config) => config, +            Err(err) => exit_err( +                &err.to_string(), +                &format!( +                    "failed parsing config file {}", +                    configpath.to_string_lossy() +                ), +            ), +        }, +        Err(err) => exit_err( +            &err.to_string(), +            &format!("failed reading config at: {}", configpath.to_string_lossy()), +        ), +    }; +      match cli.command {          Command::Status => { -            let status: Status = -                exiting_get_request(&format!("{}/api/v1/status/{}", baseurl, token), cli.debug); +            let status: Status = exiting_get_request( +                &format!("{}/api/v1/status/{}", cli.baseurl, config.token_status), +                cli.debug, +            );              println!("{}: {}", traveltext, status);          }          Command::Checkin { from, to, train } => {              let resp: Response = exiting_post_request( -                &format!("{}/api/v1/travel", baseurl), +                &format!("{}/api/v1/travel", cli.baseurl),                  Action::CheckIn {                      train,                      from_station: from,                      to_station: Some(to),                      comment: None, -                    token: format!("{}", token), +                    token: format!("{}", config.token_travel),                  },                  cli.debug,              ); @@ -74,9 +105,9 @@ fn main() -> Result<(), ureq::Error> {          }          Command::Undo => {              let resp: Response = exiting_post_request( -                &format!("{}/api/v1/travel", baseurl), +                &format!("{}/api/v1/travel", cli.baseurl),                  Action::Undo { -                    token: token.to_owned(), +                    token: config.token_travel.to_owned(),                  },                  cli.debug,              ); @@ -94,13 +125,13 @@ fn main() -> Result<(), ureq::Error> {                  traveltext, train._type, train.no, last_stop              );              let resp: Response = exiting_post_request( -                &format!("{}/api/v1/travel", baseurl), +                &format!("{}/api/v1/travel", cli.baseurl),                  Action::CheckIn {                      train,                      from_station: last_stop,                      to_station: None,                      comment: None, -                    token: format!("{}", token), +                    token: format!("{}", config.token_travel),                  },                  cli.debug,              ); @@ -118,20 +149,30 @@ fn main() -> Result<(), ureq::Error> {      Ok(())  } -fn exiting_get_request<R: serde::de::DeserializeOwned>(uri: &str, debug: bool) -> R { +fn get_request<R>(uri: &str) -> Result<R, (serde_json::Error, String)> +where +    R: serde::de::DeserializeOwned, +{      let resp: String = ureq::get(uri)          .call() -        .unwrap_or_else(|err| exit_err(&err.to_string())) +        .unwrap_or_else(|err| exit_err(&err.to_string(), "get request failed"))          .into_string() -        .unwrap_or_else(|err| exit_err(&err.to_string())); +        .unwrap_or_else(|err| exit_err(&err.to_string(), "get request response failed"));      match serde_json::from_str::<R>(&resp) { +        Ok(obj) => Ok(obj), +        Err(err) => Err((err, resp)), +    } +} + +fn exiting_get_request<R: serde::de::DeserializeOwned>(uri: &str, debug: bool) -> R { +    match get_request(uri) {          Ok(obj) => obj, -        Err(err) => { +        Err((err, resp)) => {              if debug {                  eprintln!("DEBUG: {}", resp);              } -            exit_err(&err.to_string()) +            exit_err(&err.to_string(), "parsing response failed")          }      }  } @@ -143,9 +184,9 @@ where  {      let resp: String = ureq::post(uri)          .send_json(payload) -        .unwrap_or_else(|err| exit_err(&err.to_string())) +        .unwrap_or_else(|err| exit_err(&err.to_string(), "post request failed"))          .into_string() -        .unwrap_or_else(|err| exit_err(&err.to_string())); +        .unwrap_or_else(|err| exit_err(&err.to_string(), "post request response failed"));      match serde_json::from_str::<R>(&resp) {          Ok(obj) => obj, @@ -153,12 +194,12 @@ where              if debug {                  eprintln!("DEBUG: {}", resp);              } -            exit_err(&err.to_string()) +            exit_err(&err.to_string(), "parsing response failed")          }      }  } -fn exit_err(msg: &str) -> ! { -    eprintln!("{}", msg); +fn exit_err(msg: &str, scope: &str) -> ! { +    eprintln!("{}: {}", scope, msg);      std::process::exit(1)  } | 
