From e5c5ab0abbc6d3ef1b41563bea1eddf06a9e4839 Mon Sep 17 00:00:00 2001 From: stuebinm Date: Wed, 26 Jan 2022 03:20:04 +0100 Subject: add a config file because why not --- Cargo.lock | 61 ++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 ++ src/main.rs | 89 ++++++++++++++++++++++++++++++++++++++++++++----------------- 3 files changed, 128 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 389e3b5..5d23665 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -140,6 +140,26 @@ dependencies = [ "cfg-if", ] +[[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" @@ -177,6 +197,17 @@ dependencies = [ "percent-encoding", ] +[[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" @@ -374,6 +405,25 @@ dependencies = [ "proc-macro2", ] +[[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" @@ -566,6 +616,15 @@ version = "0.1.0" 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" @@ -573,9 +632,11 @@ dependencies = [ "chrono", "clap", "colored", + "dirs", "itertools", "serde", "serde_json", + "toml", "ureq", ] diff --git a/Cargo.toml b/Cargo.toml index a1c58ce..fa1f2de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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, } #[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(uri: &str, debug: bool) -> R { +fn get_request(uri: &str) -> Result +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::(&resp) { + Ok(obj) => Ok(obj), + Err(err) => Err((err, resp)), + } +} + +fn exiting_get_request(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::(&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) } -- cgit v1.2.3