summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Cargo.lock61
-rw-r--r--Cargo.toml2
-rw-r--r--src/main.rs89
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
@@ -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",
]
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<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)
}