MPD and weather module
This commit is contained in:
		
							
								
								
									
										119
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										119
									
								
								src/main.rs
									
									
									
									
									
								
							| @@ -1,5 +1,6 @@ | ||||
| use std::str; | ||||
| use std::fmt; | ||||
| use std::process::{Stdio, Command}; | ||||
| use curl::easy::{Easy, List}; | ||||
| use serde_json::Value; | ||||
| use clap::Parser; | ||||
| @@ -57,53 +58,88 @@ struct AppOptions { | ||||
| // | ||||
| // Application (BarWeather) | ||||
| // | ||||
| #[derive(Clone)] | ||||
| struct BarWeather { | ||||
|     // acts    :BarWeatherActions | ||||
|     opts :AppOptions, | ||||
| } | ||||
|  | ||||
| impl BarWeather { | ||||
|     fn run(self) { | ||||
|         self.check_options(); | ||||
|         self.get_weather(); | ||||
|     } | ||||
|  | ||||
|     fn get_weather(self) { | ||||
|         // Print a web page onto stdout | ||||
|         let mut curl = Easy::new(); | ||||
|         let url_string_1 :String = "https://api.weather.gov/stations/".to_owned(); | ||||
|         let url_string_2 :&str   = self.opts.station.as_str(); | ||||
|         let url_string_3 :String = "/observations?limit=1".to_owned(); | ||||
|  | ||||
|         let url_string = url_string_1 + url_string_2 + &url_string_3; | ||||
|  | ||||
|         curl.url(url_string.as_str()).unwrap(); | ||||
|  | ||||
|         let mut list = List::new(); | ||||
|         list.append("User-Agent: Bar Weather (mahesh@heshapps.com)").unwrap(); | ||||
|         curl.http_headers(list).unwrap(); | ||||
|  | ||||
|         curl.write_function(move |data| { | ||||
|             // To debug returned JSON | ||||
|             if self.opts.debug_json { | ||||
|                 use std::io::{stdout, Write}; | ||||
|                 println!("-----> Start of debug"); | ||||
|                 stdout().write_all(data).unwrap(); | ||||
|                 println!("-----> End of debug"); | ||||
|             } | ||||
|  | ||||
|             let v: Value = serde_json::from_str(str::from_utf8(data).unwrap()).unwrap(); | ||||
|             let temperature_value :f32 = self.get_current_temperature(v); | ||||
|             let temperature_unit :String = self.get_temperature_unit(); | ||||
|  | ||||
|             println!("{:.2}{}", temperature_value, temperature_unit); | ||||
|  | ||||
|             Ok(data.len()) | ||||
|     // -------------------- | ||||
|     fn run(&self) { | ||||
|         if self.opts.debug_json { | ||||
|             self.debug_msg("Debugging ..."); | ||||
|         } | ||||
|         ).unwrap(); | ||||
|         curl.perform().unwrap(); | ||||
|         self.check_options(); | ||||
|         let mut bar_modules = Vec::new(); | ||||
|  | ||||
|         bar_modules.push(self.clone().get_weather()); | ||||
|         bar_modules.push(self.clone().get_music()); | ||||
|  | ||||
|         println!("{}", bar_modules.join(" | ")); | ||||
|     } | ||||
|  | ||||
|     // -------------------- | ||||
|     fn get_weather(self) -> String { | ||||
|         // Print a web page onto stdout | ||||
|         let mut curl        = Easy::new(); | ||||
|         let mut url_string  = Vec::new(); | ||||
|         let mut curl_ret    = Vec::new(); | ||||
|  | ||||
|         url_string.push("https://api.weather.gov/stations/".to_owned()); | ||||
|         url_string.push(self.opts.station.to_owned()); | ||||
|         url_string.push("/observations?limit=1".to_owned()); | ||||
|  | ||||
|         curl.url(url_string.concat().as_str()).unwrap(); | ||||
|         { | ||||
|             let mut list = List::new(); | ||||
|             list.append("User-Agent: Bar Weather (mahesh@heshapps.com)").unwrap(); | ||||
|             curl.http_headers(list).unwrap(); | ||||
|  | ||||
|             let mut transfer = curl.transfer(); | ||||
|  | ||||
|             transfer.write_function(|data| { | ||||
|                 curl_ret.extend_from_slice(data); | ||||
|                 Ok(data.len()) | ||||
|             }).unwrap(); | ||||
|             transfer.perform().unwrap(); | ||||
|         } | ||||
|         if self.opts.debug_json { | ||||
|             println!("-----> curl_data - [{}]", std::str::from_utf8(&curl_ret).unwrap()); | ||||
|         } | ||||
|  | ||||
|         let v: Value = serde_json::from_str(str::from_utf8(&curl_ret).unwrap()).unwrap(); | ||||
|         let temperature_value :f32 = self.get_current_temperature(v); | ||||
|         let temperature_unit :String = self.get_temperature_unit(); | ||||
|  | ||||
|         return format!("{:.2}{}", temperature_value, temperature_unit); | ||||
|     } | ||||
|  | ||||
|     // -------------------- | ||||
|     fn get_music(&self) -> String { | ||||
|         // MPD format options here: | ||||
|         //   https://manpages.ubuntu.com/manpages/plucky/man1/mpc.1.html | ||||
|         let current_output = Command::new("mpc") | ||||
|                             .arg("--format") | ||||
|                             .arg("[%artist% - ][%title%]") | ||||
|                             .arg("current") | ||||
|                             .stdout(Stdio::piped()) | ||||
|                             .output() | ||||
|                             .unwrap(); | ||||
|         let mut current_stdout = String::from_utf8(current_output.stdout).unwrap(); | ||||
|         current_stdout.pop(); | ||||
|         let progress_output = Command::new("mpc") | ||||
|                             .arg("status") | ||||
|                             .arg("%percenttime% %totaltime%") | ||||
|                             .stdout(Stdio::piped()) | ||||
|                             .output() | ||||
|                             .unwrap(); | ||||
|         let mut progress_stdout = String::from_utf8(progress_output.stdout).unwrap(); | ||||
|         progress_stdout.pop(); | ||||
|         return format!("{} [{}]", current_stdout, progress_stdout); | ||||
|     } | ||||
|  | ||||
|     // -------------------- | ||||
|     fn check_options(&self) -> bool { | ||||
|         let mut all_good = true; | ||||
|  | ||||
| @@ -115,6 +151,7 @@ impl BarWeather { | ||||
|         return all_good; | ||||
|     } | ||||
|  | ||||
|     // -------------------- | ||||
|     fn get_current_temperature(&self, v: Value) -> f32 { | ||||
|         let deg_c :f32 = v["features"][0]["properties"]["temperature"]["value"] | ||||
|                             .to_string().parse().unwrap(); | ||||
| @@ -123,10 +160,16 @@ impl BarWeather { | ||||
|                                                          else { (deg_c * 9.0 / 5.0) + 32.0}; | ||||
|     } | ||||
|  | ||||
|     // -------------------- | ||||
|     fn get_temperature_unit(&self) -> String{ | ||||
|         return if self.opts.units == TemperatureUnits::Metric { "°C".to_string() } | ||||
|                                                          else { "°F".to_string() }; | ||||
|     } | ||||
|  | ||||
|     // -------------------- | ||||
|     fn debug_msg(&self, msg: &str) { | ||||
|         println!("[Debug ] -----> {}", msg); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // | ||||
|   | ||||
		Reference in New Issue
	
	Block a user