rodalies_cli/rodalies/
client.rs1use clap::crate_version;
2use scraper::Html;
3use std::{error::Error, fs, time::Duration};
4use surf::{Client, Config, Response, StatusCode, Url};
5
6pub fn init_client() -> Client {
8 let rodalies_url = "https://rodalies.gencat.cat";
9
10 Config::new()
11 .set_base_url(Url::parse(rodalies_url).unwrap())
12 .set_timeout(Some(Duration::from_secs(5)))
13 .try_into()
14 .unwrap()
15}
16
17pub async fn get_search_page(client: &Client) -> Result<Html, Box<dyn Error>> {
19 let mut response = client
20 .get("/en/horaris")
21 .header(
22 "User-Agent",
23 format!(
24 "rodalies-cli/{} (github.com/gerardcl/rodalies-cli)",
25 crate_version!()
26 ),
27 )
28 .await?;
29
30 let body_response = get_page_body(&mut response).await?;
31
32 Ok(Html::parse_document(&body_response))
33}
34
35pub async fn get_timetable_page(
37 client: &Client,
38 from: String,
39 to: String,
40 date: String,
41) -> Result<Html, Box<dyn Error>> {
42 let mut response = client
43 .post("/en/horaris")
44 .header(
45 "User-Agent",
46 format!(
47 "rodalies-cli/{} (github.com/gerardcl/rodalies-cli)",
48 crate_version!()
49 ),
50 )
51 .content_type("application/x-www-form-urlencoded")
52 .body_string(format!(
53 "origen={}&desti={}&dataViatge={}&horaIni=00&lang=en&cercaRodalies=true&tornada=false",
54 from, to, date
55 ))
56 .await?;
57
58 let body_response = get_page_body(&mut response).await?;
59
60 Ok(Html::parse_document(&body_response))
61}
62
63async fn get_page_body(response: &mut Response) -> Result<String, Box<dyn Error>> {
65 let error = match response.status() {
66 StatusCode::Ok => false,
67 _ => {
68 println!(
69 "⛔ Rodalies server failed with HTTP Status: {}",
70 response.status()
71 );
72 true
73 }
74 };
75
76 if error {
77 return Err(
78 ("🚨 Please, try again later or open an issue if the error persists...").into(),
79 );
80 }
81
82 Ok(response.body_string().await?)
83}
84
85pub fn get_html_from_file(file_path: &str) -> Result<Html, Box<dyn Error>> {
86 let html_file = fs::read_to_string(file_path).expect("Should have been able to read the file");
87 Ok(Html::parse_document(&html_file))
88}
89
90#[cfg(test)]
91mod tests {
92 use super::init_client;
93 use surf::Url;
94
95 #[test]
96 fn test_init_client_with_rodalies_web() {
97 let client = init_client();
98 let expected_url = "https://rodalies.gencat.cat";
99 assert!(client
100 .config()
101 .base_url
102 .eq(&Some(Url::parse(expected_url).unwrap())));
103 }
104}