Refactoring of bar modules
* Moved debug functions to separate trait * Broke up module actions and moved assembling of icon and content in main instead of module itself. This will enable disabling of icon or content via options in the future
This commit is contained in:
parent
ade570b8af
commit
b7f83b4810
@ -5,15 +5,26 @@ use crate::bar_modules;
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct UnibarModuleMusic {
|
pub struct UnibarModuleMusic {
|
||||||
pub opts: common::AppOptions,
|
opts: common::AppOptions,
|
||||||
|
current_stdout :String,
|
||||||
|
progress_stdout :String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UnibarModuleMusic {
|
||||||
|
// --------------------
|
||||||
|
pub fn new(o :common::AppOptions) -> UnibarModuleMusic {
|
||||||
|
UnibarModuleMusic {
|
||||||
|
opts: o,
|
||||||
|
current_stdout: "".to_string(),
|
||||||
|
progress_stdout: "".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl bar_modules::BarModuleActions for UnibarModuleMusic {
|
impl bar_modules::BarModuleActions for UnibarModuleMusic {
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
fn get(&self) -> String {
|
fn generate_data(&mut self) {
|
||||||
let mut parts = Vec::new();
|
|
||||||
|
|
||||||
// MPD format options here:
|
// MPD format options here:
|
||||||
// https://manpages.ubuntu.com/manpages/plucky/man1/mpc.1.html
|
// https://manpages.ubuntu.com/manpages/plucky/man1/mpc.1.html
|
||||||
let current_output = Command::new("mpc")
|
let current_output = Command::new("mpc")
|
||||||
@ -23,9 +34,8 @@ impl bar_modules::BarModuleActions for UnibarModuleMusic {
|
|||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.output()
|
.output()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mut current_stdout = String::from_utf8(current_output.stdout).unwrap();
|
self.current_stdout = String::from_utf8(current_output.stdout).unwrap();
|
||||||
current_stdout.pop();
|
self.current_stdout.pop();
|
||||||
parts.push(format!("{}", current_stdout));
|
|
||||||
|
|
||||||
if self.opts.music_progress {
|
if self.opts.music_progress {
|
||||||
let progress_output = Command::new("mpc")
|
let progress_output = Command::new("mpc")
|
||||||
@ -34,11 +44,32 @@ impl bar_modules::BarModuleActions for UnibarModuleMusic {
|
|||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.output()
|
.output()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mut progress_stdout = String::from_utf8(progress_output.stdout).unwrap();
|
self.progress_stdout = String::from_utf8(progress_output.stdout).unwrap();
|
||||||
progress_stdout.pop();
|
self.progress_stdout.pop();
|
||||||
parts.push(format!("[{}]", progress_stdout));
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
fn get_content(&self) -> String {
|
||||||
|
let mut parts = Vec::new();
|
||||||
|
parts.push(format!("{}", self.current_stdout));
|
||||||
|
|
||||||
|
if self.opts.music_progress {
|
||||||
|
parts.push(format!("[{}]", self.progress_stdout));
|
||||||
}
|
}
|
||||||
|
|
||||||
return format!("{}", parts.join(" "));
|
return format!("{}", parts.join(" "));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
fn get_icon(&self) -> String {
|
||||||
|
return "".to_string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl bar_modules::BarModuleDebug for UnibarModuleMusic {
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
fn post_debug(&self) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::str;
|
use std::str;
|
||||||
use curl::easy::{Easy, List};
|
use curl::easy::{Easy, List};
|
||||||
|
use serde_json::json;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
@ -8,15 +9,24 @@ use crate::bar_modules;
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct UnibarModuleWeather {
|
pub struct UnibarModuleWeather {
|
||||||
pub opts: common::AppOptions,
|
opts: common::AppOptions,
|
||||||
|
weather_info: Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UnibarModuleWeather {
|
impl UnibarModuleWeather {
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
fn get_current_temperature(&self, v: Value) -> f32 {
|
pub fn new(o :common::AppOptions) -> UnibarModuleWeather {
|
||||||
let deg_c :f32 = v["features"][0]["properties"]["temperature"]["value"]
|
UnibarModuleWeather {
|
||||||
.to_string().parse().unwrap();
|
opts: o,
|
||||||
|
weather_info: json!(serde_json::Value::Null),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
fn get_current_temperature(&self) -> f32 {
|
||||||
|
let deg_c :f32 = self.weather_info["features"][0]["properties"]["temperature"]["value"]
|
||||||
|
.to_string().parse().unwrap();
|
||||||
|
|
||||||
match self.opts.weather_units {
|
match self.opts.weather_units {
|
||||||
common::TemperatureUnits::Metric => return deg_c,
|
common::TemperatureUnits::Metric => return deg_c,
|
||||||
@ -31,19 +41,8 @@ impl UnibarModuleWeather {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
fn get_icon(&self, v: Value) -> String {
|
fn get_unicode_symbol(&self, condition: &str) -> String {
|
||||||
// "icon": "https://api.weather.gov/icons/land/night/ovc?size=medium",
|
match condition {
|
||||||
let re = Regex::new(r"(\w+)\?size").unwrap();
|
|
||||||
let json_val = v["features"][0]["properties"]["icon"].to_string();
|
|
||||||
let caps = re.captures(&json_val).unwrap();
|
|
||||||
|
|
||||||
// println!("{}", caps.get(1).unwrap().as_str());
|
|
||||||
return self.get_unicode_symbol(caps.get(1).unwrap().as_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------
|
|
||||||
fn get_unicode_symbol(&self, v: &str) -> String {
|
|
||||||
match v {
|
|
||||||
"skc" => { return "☀️".to_string(); } // Fair/clear
|
"skc" => { return "☀️".to_string(); } // Fair/clear
|
||||||
"few" => { return "🌥️".to_string(); } // A few clouds
|
"few" => { return "🌥️".to_string(); } // A few clouds
|
||||||
"sct" => { return "🌥️".to_string(); } // Partly cloudy
|
"sct" => { return "🌥️".to_string(); } // Partly cloudy
|
||||||
@ -83,7 +82,7 @@ impl UnibarModuleWeather {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
pub fn get_icons(&self) {
|
fn get_icons(&self) {
|
||||||
// Print a web page onto stdout
|
// Print a web page onto stdout
|
||||||
let mut curl = Easy::new();
|
let mut curl = Easy::new();
|
||||||
let mut url_string = Vec::new();
|
let mut url_string = Vec::new();
|
||||||
@ -109,7 +108,7 @@ impl UnibarModuleWeather {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
pub fn show_icons(&self) {
|
fn show_icons(&self) {
|
||||||
println!("{} skc Fair/clear", self.get_unicode_symbol("skc"));
|
println!("{} skc Fair/clear", self.get_unicode_symbol("skc"));
|
||||||
println!("{} few A few clouds", self.get_unicode_symbol("few"));
|
println!("{} few A few clouds", self.get_unicode_symbol("few"));
|
||||||
println!("{} sct Partly cloudy", self.get_unicode_symbol("sct"));
|
println!("{} sct Partly cloudy", self.get_unicode_symbol("sct"));
|
||||||
@ -152,7 +151,7 @@ impl UnibarModuleWeather {
|
|||||||
impl bar_modules::BarModuleActions for UnibarModuleWeather {
|
impl bar_modules::BarModuleActions for UnibarModuleWeather {
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
fn get(&self) -> String {
|
fn generate_data(&mut self) {
|
||||||
// Print a web page onto stdout
|
// Print a web page onto stdout
|
||||||
let mut curl = Easy::new();
|
let mut curl = Easy::new();
|
||||||
let mut url_string = Vec::new();
|
let mut url_string = Vec::new();
|
||||||
@ -180,11 +179,35 @@ impl bar_modules::BarModuleActions for UnibarModuleWeather {
|
|||||||
println!("-----> curl_data - [{}]", std::str::from_utf8(&curl_ret).unwrap());
|
println!("-----> curl_data - [{}]", std::str::from_utf8(&curl_ret).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
let v: Value = serde_json::from_str(str::from_utf8(&curl_ret).unwrap()).unwrap();
|
self.weather_info = serde_json::from_str(str::from_utf8(&curl_ret).unwrap()).unwrap();
|
||||||
let temperature_value :f32 = self.get_current_temperature(v.clone());
|
}
|
||||||
let temperature_unit :String = self.get_temperature_unit();
|
|
||||||
let temperature_icon :String = self.get_icon(v.clone());
|
|
||||||
|
|
||||||
return format!("{} {:.2}{}", temperature_icon, temperature_value, temperature_unit);
|
// --------------------
|
||||||
|
fn get_content(&self) -> String {
|
||||||
|
let temperature_value :f32 = self.get_current_temperature();
|
||||||
|
let temperature_unit :String = self.get_temperature_unit();
|
||||||
|
// let temperature_icon :String = self.get_icon(v.clone());
|
||||||
|
|
||||||
|
return format!("{:.2}{}", temperature_value, temperature_unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
fn get_icon(&self) -> String {
|
||||||
|
// "icon": "https://api.weather.gov/icons/land/night/ovc?size=medium",
|
||||||
|
let re = Regex::new(r"(\w+)\?size").unwrap();
|
||||||
|
let json_val = self.weather_info["features"][0]["properties"]["icon"].to_string();
|
||||||
|
let caps = re.captures(&json_val).unwrap();
|
||||||
|
|
||||||
|
// println!("{}", caps.get(1).unwrap().as_str());
|
||||||
|
return self.get_unicode_symbol(caps.get(1).unwrap().as_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl bar_modules::BarModuleDebug for UnibarModuleWeather {
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
fn post_debug(&self) {
|
||||||
|
self.get_icons();
|
||||||
|
self.show_icons();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,20 @@
|
|||||||
// --------------------
|
// --------------------
|
||||||
// All Bar modules must implement the actions
|
/// All Bar modules must implement the actions
|
||||||
pub trait BarModuleActions {
|
pub trait BarModuleActions {
|
||||||
fn get(&self) -> String;
|
/// Do necessary processing to generate data for this bar module
|
||||||
|
fn generate_data(&mut self);
|
||||||
|
|
||||||
|
/// Return String content to be displayed in the bar
|
||||||
|
fn get_content(&self) -> String;
|
||||||
|
|
||||||
|
/// Return a Unicode icon to display before content in the bar.
|
||||||
|
/// This icon may differ based on content of the data
|
||||||
|
fn get_icon(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait BarModuleDebug {
|
||||||
|
/// Print debug information at the end
|
||||||
|
fn post_debug(&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod bar_module_weather;
|
pub mod bar_module_weather;
|
||||||
|
@ -27,5 +27,5 @@ pub struct AppOptions {
|
|||||||
pub weather_station: String,
|
pub weather_station: String,
|
||||||
pub music_progress: bool,
|
pub music_progress: bool,
|
||||||
pub debug_json: bool,
|
pub debug_json: bool,
|
||||||
pub debug_icons: bool,
|
pub debug_modules: bool,
|
||||||
}
|
}
|
||||||
|
49
src/main.rs
49
src/main.rs
@ -32,7 +32,7 @@ struct CommandlineArgs {
|
|||||||
|
|
||||||
/// Show ICON debug information
|
/// Show ICON debug information
|
||||||
#[arg(short = 'I', long)]
|
#[arg(short = 'I', long)]
|
||||||
debug_icons: bool,
|
debug_modules: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -51,24 +51,45 @@ impl Unibar {
|
|||||||
self.debug_msg("Debugging ...");
|
self.debug_msg("Debugging ...");
|
||||||
}
|
}
|
||||||
self.check_options();
|
self.check_options();
|
||||||
let mut parts = Vec::new();
|
|
||||||
|
|
||||||
|
// Set up a list of all modules to be used
|
||||||
let bar_modules_enabled: Vec<Box<dyn bar_modules::BarModuleActions>> = vec! [
|
let bar_modules_enabled: Vec<Box<dyn bar_modules::BarModuleActions>> = vec! [
|
||||||
Box::new(bar_modules::bar_module_weather::UnibarModuleWeather { opts: self.opts.clone() }),
|
Box::new(bar_modules::bar_module_weather::UnibarModuleWeather::new(self.opts.clone())),
|
||||||
Box::new(bar_modules::bar_module_music::UnibarModuleMusic { opts: self.opts.clone() }),
|
Box::new(bar_modules::bar_module_music::UnibarModuleMusic::new(self.opts.clone())),
|
||||||
];
|
];
|
||||||
|
|
||||||
for md in bar_modules_enabled {
|
// Get module's part to be displayed in the bar
|
||||||
parts.push(md.get());
|
let mut parts = Vec::new();
|
||||||
|
for mut md in bar_modules_enabled {
|
||||||
|
let mut mod_parts = Vec::new();
|
||||||
|
|
||||||
|
// Each bar module implements following 3 steps:
|
||||||
|
// * Generate raw data with pertinent information
|
||||||
|
// * Return a unicode icon to be displayed
|
||||||
|
// * Return a String content to be displayed after the icon
|
||||||
|
//
|
||||||
|
// Following generates ICON+CONTENT string for a module to be displayed
|
||||||
|
// in the bar
|
||||||
|
md.generate_data();
|
||||||
|
mod_parts.push(md.get_icon());
|
||||||
|
mod_parts.push(md.get_content());
|
||||||
|
|
||||||
|
parts.push(mod_parts.join(" "));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Show module debug information if enabled
|
||||||
|
if self.opts.debug_modules {
|
||||||
|
let bar_modules_debugged: Vec<Box<dyn bar_modules::BarModuleDebug>> = vec! [
|
||||||
|
Box::new(bar_modules::bar_module_weather::UnibarModuleWeather::new(self.opts.clone())),
|
||||||
|
Box::new(bar_modules::bar_module_music::UnibarModuleMusic::new(self.opts.clone())),
|
||||||
|
];
|
||||||
|
for md in bar_modules_debugged {
|
||||||
|
md.post_debug();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print parts provided by each module
|
||||||
println!("{}", parts.join(" | "));
|
println!("{}", parts.join(" | "));
|
||||||
|
|
||||||
if self.opts.debug_icons {
|
|
||||||
let w = bar_modules::bar_module_weather::UnibarModuleWeather { opts: self.opts.clone() };
|
|
||||||
w.get_icons();
|
|
||||||
w.show_icons();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
@ -99,7 +120,7 @@ fn main() {
|
|||||||
weather_station: cmd_args.weather_station,
|
weather_station: cmd_args.weather_station,
|
||||||
music_progress: cmd_args.music_progress,
|
music_progress: cmd_args.music_progress,
|
||||||
debug_json: cmd_args.debug_json,
|
debug_json: cmd_args.debug_json,
|
||||||
debug_icons: cmd_args.debug_icons
|
debug_modules: cmd_args.debug_modules
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user