From cb4daa5716638bf69aeede3843401f5c720ae3dc Mon Sep 17 00:00:00 2001 From: Gerard CL Date: Sun, 11 Jun 2023 21:39:09 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=85=20adding=20a=20check=20and=20inform?= =?UTF-8?q?=20about=20used=20CLI=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 50 ++++++++++++++++++++++++++++- Cargo.toml | 4 ++- README.md | 11 +++++-- src/config/check.rs | 73 ++++++++++++++++++++++++++++++++++++++++++ src/config/mod.rs | 3 ++ src/main.rs | 3 ++ src/rodalies/client.rs | 19 ++++++++++- 7 files changed, 157 insertions(+), 6 deletions(-) create mode 100644 src/config/check.rs diff --git a/Cargo.lock b/Cargo.lock index c10418d..cf6062b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -295,6 +295,28 @@ dependencies = [ "wasm-bindgen-futures", ] +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + [[package]] name = "async-task" version = "4.4.0" @@ -2062,7 +2084,7 @@ checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" [[package]] name = "rodalies-cli" -version = "1.0.3" +version = "1.1.0" dependencies = [ "assert_cmd", "chrono", @@ -2070,8 +2092,10 @@ dependencies = [ "predicates", "prettytable-rs", "scraper", + "serde_json", "surf", "tokio", + "tokio-test", ] [[package]] @@ -2707,6 +2731,30 @@ dependencies = [ "syn 2.0.15", ] +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-test" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53474327ae5e166530d17f2d956afcb4f8a004de581b3cae10f12006bc8163e3" +dependencies = [ + "async-stream", + "bytes 1.4.0", + "futures-core", + "tokio", + "tokio-stream", +] + [[package]] name = "tracing" version = "0.1.37" diff --git a/Cargo.toml b/Cargo.toml index c288c6a..311af2f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rodalies-cli" -version = "1.0.3" +version = "1.1.0" edition = "2021" authors = ["Gerard C.L. "] license = "BSD-3-Clause" @@ -18,7 +18,9 @@ tokio = { version = "1.28", features = ["full"] } scraper = "0.16" chrono = { version = "0.4", features = []} prettytable-rs = "0.10" +serde_json = "1.0" [dev-dependencies] assert_cmd = "2.0" predicates = "3.0" +tokio-test = "0.4" diff --git a/README.md b/README.md index 5cde324..c936766 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ After a release a github action updates it with x86_64 built binaries for: Run the following command to get the binary into your bin folder or tune it as you like: ```bash -curl -LO "https://github.com/gerardcl/rodalies-cli/releases/download/1.0.3/rodalies-cli-linux-amd64" && \ +curl -LO "https://github.com/gerardcl/rodalies-cli/releases/download/1.1.0/rodalies-cli-linux-amd64" && \ chmod +x rodalies-cli-linux-amd64 && mv rodalies-cli-linux-amd64 /usr/local/bin/rodalies-cli ``` @@ -28,7 +28,7 @@ chmod +x rodalies-cli-linux-amd64 && mv rodalies-cli-linux-amd64 /usr/local/bin/ Run the following command to get the binary into your bin folder or tune it as you like: ```bash -curl -LO "https://github.com/gerardcl/rodalies-cli/releases/download/1.0.3/rodalies-cli-darwin-amd64" && \ +curl -LO "https://github.com/gerardcl/rodalies-cli/releases/download/1.1.0/rodalies-cli-darwin-amd64" && \ chmod +x rodalies-cli-darwin-amd64 && mv rodalies-cli-darwin-amd64 /usr/local/bin/rodalies-cli ``` @@ -39,7 +39,7 @@ chmod +x rodalies-cli-darwin-amd64 && mv rodalies-cli-darwin-amd64 /usr/local/bi Run the following command to get the binary into your bin folder or tune it as you like: ```bash -curl -LO "https://github.com/gerardcl/rodalies-cli/releases/download/1.0.3/rodalies-cli-windows-amd64.exe" && \ +curl -LO "https://github.com/gerardcl/rodalies-cli/releases/download/1.1.0/rodalies-cli-windows-amd64.exe" && \ chmod +x rodalies-cli-windows-amd64.exe && mv rodalies-cli-windows-amd64.exe /mingw64/bin/rodalies-cli.exe ``` @@ -131,6 +131,7 @@ $ rodalies-cli -d 9 -m 9 ```bash $ rodalies-cli -s gir 🚂 Rodalies CLI 📅 Today's date is 02/08/2022 +✅ You are running the latest rodalies-cli, version 1.1.0! yayy ✨ Interactive mode enabled: 'false' 🔍 Searching stations that contain the text: 'gir' +--------------+------------+ @@ -141,6 +142,7 @@ $ rodalies-cli -s gir $ rodalies-cli -s si 🚂 Rodalies CLI 📅 Today's date is 02/08/2022 +✅ You are running the latest rodalies-cli, version 1.1.0! yayy ✨ Interactive mode enabled: 'false' 🔍 Searching stations that contain the text: 'si' +------------------------+------------+ @@ -157,6 +159,7 @@ $ rodalies-cli -s si ```bash $ rodalies-cli -f 79300 -t 79202 🚂 Rodalies CLI 📅 Today's date is 02/08/2022 +✅ You are running the latest rodalies-cli, version 1.1.0! yayy ✨ Interactive mode enabled: 'false' 🔍 Searching timetable for date 02/08/2022 📆 Listing timetable with 0 transfers @@ -204,6 +207,7 @@ If the timetable requires a transfer you will also see it: ```bash $ rodalies-cli -f 79300 -t 71701 🚂 Rodalies CLI 📅 Today's date is 02/08/2022 +✅ You are running the latest rodalies-cli, version 1.1.0! yayy ✨ Interactive mode enabled: 'false' 🔍 Searching timetable for date 02/08/2022 📆 Listing timetable with 1 transfers @@ -243,6 +247,7 @@ $ rodalies-cli -f 79300 -t 71701 ```bash $ rodalies-cli -f 79300 -t 72503 🚂 Rodalies CLI 📅 Today's date is 02/08/2022 +✅ You are running the latest rodalies-cli, version 1.1.0! yayy ✨ Interactive mode enabled: 'false' 🔍 Searching timetable for date 02/08/2022 📆 Listing timetable with 2 transfers diff --git a/src/config/check.rs b/src/config/check.rs new file mode 100644 index 0000000..32dff92 --- /dev/null +++ b/src/config/check.rs @@ -0,0 +1,73 @@ +use clap::crate_version; +use serde_json::Value; +use std::{error::Error, time::Duration}; +use surf::{Client, Config, Url}; + +struct IndexResponse { + name: String, + version: String, +} + +pub async fn check_rodalies_version() { + let online_crate_state = get_last_crate_index_response().await; + match online_crate_state { + Ok(state) => match state.version.as_str() { + crate_version!() => println!("✅ You are running the latest {}, version {}! yayy", state.name, state.version), + _ => println!("🤷 You are using an outdated version of rodalies-cli ({}), please upgrade to latest ({})", crate_version!(), state.version) + }, + _ => { + println!("🕵️ Could not check if using latest version...dismissing check, but if you keep seeing this message please open an issue.") + }, + }; +} + +/// Returns the HTML from`https://raw.githubusercontent.com/rust-lang/crates.io-index/master/ro/da/rodalies-cli`, if possible. +async fn get_last_crate_index_response() -> Result> { + let raw_githubcontent_base_url = "https://raw.githubusercontent.com"; + + let client: Client = Config::new() + .set_base_url(Url::parse(raw_githubcontent_base_url)?) + .set_timeout(Some(Duration::from_secs(5))) + .try_into()?; + + let mut response = client + .get("/rust-lang/crates.io-index/master/ro/da/rodalies-cli") + .header( + "User-Agent", + format!( + "rodalies-cli/{} (github.com/gerardcl/rodalies-cli)", + crate_version!() + ), + ) + .await?; + + let body_response = response.body_string().await?; + + let last_line = body_response.lines().last().unwrap(); + + let index_response: Value = serde_json::from_str(last_line)?; + + Ok(IndexResponse { + name: index_response["name"].to_string().replace('\"', ""), + version: index_response["vers"].to_string().replace('\"', ""), + }) +} + +#[cfg(test)] +mod tests { + use super::*; + + macro_rules! run_async { + ($e:expr) => { + tokio_test::block_on($e) + }; + } + + #[test] + fn test_get_index_returns_index_response() { + let response = run_async!(get_last_crate_index_response()); + let index = response.unwrap(); + assert_eq!(index.name, "rodalies-cli"); + assert!(!index.version.is_empty()); + } +} diff --git a/src/config/mod.rs b/src/config/mod.rs index edd415e..97c4ead 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -4,3 +4,6 @@ /// `cli` provides the methods to initialize the CLI input (args) and output (table). pub mod cli; + +/// `check` provides the methods to check and inform about latest published online version of the `rodalies-cli` and the one being used by the user. +pub mod check; diff --git a/src/main.rs b/src/main.rs index f256cca..7ea2ff2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ use std::error::Error; use chrono::{Datelike, Local}; +use rodalies_cli::config::check::check_rodalies_version; use rodalies_cli::config::cli::{init_cli, interactive_mode}; use rodalies_cli::rodalies::client::init_client; use rodalies_cli::rodalies::interactive::search_interactive; @@ -19,6 +20,8 @@ async fn main() -> Result<(), Box> { dt.year() ); + check_rodalies_version().await; + if !interactive_mode(&args).unwrap() { if args.contains_id("search") { // search station diff --git a/src/rodalies/client.rs b/src/rodalies/client.rs index 21095de..0463f15 100644 --- a/src/rodalies/client.rs +++ b/src/rodalies/client.rs @@ -1,3 +1,4 @@ +use clap::crate_version; use scraper::Html; use std::{error::Error, time::Duration}; use surf::{Client, Config, Response, StatusCode, Url}; @@ -15,7 +16,16 @@ pub fn init_client() -> Client { /// Returns the HTML body parsed of the main search page. pub async fn get_search_page(client: &Client) -> Result> { - let mut response = client.get("/en/horaris").await?; + let mut response = client + .get("/en/horaris") + .header( + "User-Agent", + format!( + "rodalies-cli/{} (github.com/gerardcl/rodalies-cli)", + crate_version!() + ), + ) + .await?; let body_response = get_page_body(&mut response).await?; @@ -31,6 +41,13 @@ pub async fn get_timetable_page( ) -> Result> { let mut response = client .post("/en/horaris") + .header( + "User-Agent", + format!( + "rodalies-cli/{} (github.com/gerardcl/rodalies-cli)", + crate_version!() + ), + ) .content_type("application/x-www-form-urlencoded") .body_string(format!( "origen={}&desti={}&dataViatge={}&horaIni=00&lang=en&cercaRodalies=true&tornada=false",