From 03540ab3d8b53e50ec254b8b2454ad2452ae9fa5 Mon Sep 17 00:00:00 2001 From: mustafa salih Date: Sun, 3 Jan 2021 01:47:40 +0300 Subject: [PATCH] rsblocks now is a multi threaded and have a delay for each item in the bar --- Cargo.toml | 5 +- README.md | 18 ++-- rsblocks.yml | 8 +- screenshots/1.png | Bin 5550 -> 6093 bytes src/lib.rs | 234 +++++++++++++++++++++++++++++++++------------- 5 files changed, 190 insertions(+), 75 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 908a1c0..c74fe6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,13 @@ [package] name = "rsblocks" -version = "0.1.1" +version = "0.1.2" authors = ["mustafa salih "] edition = "2018" readme = "README.md" license = "MIT" +keywords = ["linux", "dwm","statusbar"] repository = "https://github.com/MustafaSalih1993/rsblocks" -description = "This is a minimal status bar for dwm window manager for linux" +description = "a multi threaded status bar for dwm window manager for linux" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] diff --git a/README.md b/README.md index f88dc7c..4077e8c 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,21 @@ # rsblocks -A minimal fast dwm status bar written in **Rust** 🦀 +A minimal multi threaded fast status bar for dwm window manager written in **Rust** 🦀


## Features +* Multi Threads * Time/Date * Used Memory * Used Disk space -* Sound volume _reads from `amixer` for now_ -* Easy to configure -* Minimal +* Sound volume _reads from `alsa-utils` for now_ +* Easy to configure with `rsblocks.yml` file -## Note -This tool is still in development stage. + +## Notes +* This tool is still in development stage. +* currently supports only linux. ## Cargo Installation You can install the binary crate directly @@ -38,7 +40,9 @@ mv ./target/release/rsblocks /usr/local/bin you good to go now and can run `rsblocks` from your terminal or put that in your `.xinitrc` ## Configuration -**rsblocks** will try to read the file `~/.config/rsblocks/rsblocks.yml`, if it does not exist, it will load the defaults. +#### Notes: +* **rsblocks** will try to read the file `$HOME/.config/rsblocks/rsblocks.yml`, if it does not exist, it will load the defaults. +* **rsblocks** will read the configuration file **only** on startup, which means you have to kill it and start it again if you updated your `rsblocks.yml` file. create the directory ```sh diff --git a/rsblocks.yml b/rsblocks.yml index 7a6f910..be6939f 100644 --- a/rsblocks.yml +++ b/rsblocks.yml @@ -1,22 +1,28 @@ # This is the full configuration template available for rsblocks tool # the names are clearly defines itself. +# NOTE: the (delay) is **seconds** with the float point to update the item in the bar. + general: seperator: '┃' time: icon: '' format: '%d %b, %I:%M:%S %p' + delay: 1.0 memory: enable: true icon: '▦' + delay: 2.0 disk: enable: true icon: '' + delay: 120.0 -# reads from amixer +# reads from alsa-utils volume: enable: false icon: '' + delay: 0.18 diff --git a/screenshots/1.png b/screenshots/1.png index d9b333c8edd4bf064b09d73553a3e7a659c0799a..67bff904e53f53ed079826f9a8db651be48e4f27 100644 GIT binary patch literal 6093 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 T3k0US00000NkvXXu0mjfvU$e$ literal 5550 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 Result { let yml_source = env::var("HOME").unwrap() + "/.config/rsblocks/rsblocks.yml"; let mut data = String::new(); - let mut file = match File::open(yml_source) { + let mut file = match File::open(&yml_source) { Ok(file) => file, Err(_) => { - println!("~/.config/rsblocks/rsblocks.yml file not found, loading defaults!"); + eprintln!("{} file not found, loading defaults!", &yml_source); return Ok(load_defaults()); } }; file.read_to_string(&mut data)?; let yml_content = &YamlLoader::load_from_str(&data).unwrap()[0]; - let config = gen_default_config(yml_content); + let config = parse_config(yml_content); Ok(config) } -fn gen_default_config(doc: &yaml::Yaml) -> Config { - // setting icons +fn load_defaults() -> Config { + Config { + seperator: String::from("|"), + time: Time { + format: String::from("%T"), + icon: String::from(""), + delay: 1.0, + }, + memory: Memory { + icon: String::from(""), + enabled: true, + delay: 2.0, + }, + disk: Disk { + icon: String::from(""), + enabled: false, + delay: 60.0, + }, + volume: Volume { + icon: String::from(""), + enabled: false, + delay: 0.17, + }, + } +} + +fn parse_config(doc: &yaml::Yaml) -> Config { + // parsing icons and set default if not exist in the config file let seperator = get_or_set_string(doc, "general", "seperator", "|"); let time_icon = get_or_set_string(doc, "time", "icon", ""); let time_format = get_or_set_string(doc, "time", "format", "%T"); @@ -62,32 +105,52 @@ fn gen_default_config(doc: &yaml::Yaml) -> Config { let disk_icon = get_or_set_string(doc, "disk", "icon", ""); let volume_icon = get_or_set_string(doc, "volume", "icon", ""); - // everything false by default + // parsing enabled state (everything false by default) let disk_enabled = get_or_set_bool(doc, "disk", "enable"); let memory_enabled = get_or_set_bool(doc, "memory", "enable"); let volume_enabled = get_or_set_bool(doc, "volume", "enable"); + // parsing update_delay state (should be all seconds in f64 type) + let time_delay = get_or_set_f32(doc, "time", "delay", 1.0); + let disk_delay = get_or_set_f32(doc, "disk", "delay", 60.0); + let memory_delay = get_or_set_f32(doc, "memory", "delay", 2.0); + let volume_delay = get_or_set_f32(doc, "volume", "delay", 0.17); + Config { seperator, time: Time { format: time_format, icon: time_icon, + delay: time_delay, }, memory: Memory { icon: mem_icon, enabled: memory_enabled, + delay: memory_delay, }, disk: Disk { icon: disk_icon, enabled: disk_enabled, + delay: disk_delay, }, volume: Volume { icon: volume_icon, enabled: volume_enabled, + delay: volume_delay, }, } } +// getting a f32 value from rsblocks.yml file or set default (last argument) +fn get_or_set_f32(doc: &yaml::Yaml, parent: &str, child: &str, default: f64) -> f64 { + let val: f64 = if doc[parent][child].is_badvalue() { + default + } else { + doc[parent][child].as_f64().unwrap() + }; + val +} + // getting a boolean value from rsblocks.yml file or set it false if it does not exist fn get_or_set_bool(doc: &yaml::Yaml, parent: &str, child: &str) -> bool { let val: bool; @@ -99,7 +162,7 @@ fn get_or_set_bool(doc: &yaml::Yaml, parent: &str, child: &str) -> bool { val } -// getting a String value from the rsblocks.yml file or set the default in the last parameter +// getting a String value from the rsblocks.yml file or set the default(last argument) fn get_or_set_string(doc: &yaml::Yaml, parent: &str, child: &str, default_val: &str) -> String { let val: String; if doc[parent][child].is_badvalue() { @@ -111,68 +174,109 @@ fn get_or_set_string(doc: &yaml::Yaml, parent: &str, child: &str, default_val: & val } -fn load_defaults() -> Config { - Config { - seperator: String::from("|"), - time: Time { - format: String::from("%T"), - icon: String::from(""), - }, - memory: Memory { - icon: String::from(""), - enabled: false, - }, - disk: Disk { - icon: String::from(""), - enabled: false, - }, - volume: Volume { - icon: String::from(""), - enabled: false, - }, - } -} -/* LOADING CONFIGS ENDS HERE */ +/*######################## LOADING CONFIGS ENDS HERE ############################ + +*/ /* Running the program: +TODO: this is sucks, repeated code in threads below, fix me you fucking asshole + */ -TODO: this is sucks, i want to update each one in a diffrent delay, maybe i'll try to use threads -*/ pub fn run(config: Config) { - loop { - let mut bar = String::from(""); + let (tx, rx) = mpsc::channel(); - // the order of the IF's below matters to the final format + // volume thread + if config.volume.enabled { + let volume_tx = tx.clone(); + let configcp = config.clone(); + let mut vol_data = ThreadsData::Sound(get_volume(&configcp)); + thread::spawn(move || loop { + let _ = volume_tx.send(vol_data); + vol_data = ThreadsData::Sound(get_volume(&configcp)); + thread::sleep(Duration::from_secs_f64(configcp.volume.delay)) + }); + } - if config.volume.enabled { - // volume return String - bar.push_str(&get_sound(&config)); + // Disk thread + if config.disk.enabled { + let disk_tx = tx.clone(); + let configcp = config.clone(); + let mut disk_data = ThreadsData::Disk(get_disk(&configcp)); + thread::spawn(move || loop { + disk_tx.send(disk_data).unwrap(); + disk_data = ThreadsData::Disk(get_disk(&configcp)); + thread::sleep(Duration::from_secs_f64(configcp.disk.delay)) + }); + } + + // Memory thread + if config.memory.enabled { + let memory_tx = tx.clone(); + let configcp = config.clone(); + let memory_data = get_memory(&configcp).unwrap(); + let mut memory_data = ThreadsData::Memory(memory_data); + thread::spawn(move || loop { + memory_tx.send(memory_data).unwrap(); + memory_data = ThreadsData::Memory(get_memory(&configcp).unwrap()); + thread::sleep(Duration::from_secs_f64(configcp.memory.delay)) + }); + } + + // Time thread + { + let time_tx = tx; + let configcp = config.clone(); + let mut time_data = ThreadsData::Time(get_time(&configcp)); + thread::spawn(move || loop { + time_tx.send(time_data).unwrap(); + time_data = ThreadsData::Time(get_time(&configcp)); + thread::sleep(Duration::from_secs_f64(configcp.time.delay)) + }); + } + + //Main + { + // NOTE: order matters to the final format + + let mut bar: Vec = vec!["".to_string(); 4]; + //iterating the values recieved from the threads + for data in rx { + match data { + ThreadsData::Sound(x) => bar[0] = x, + ThreadsData::Disk(x) => bar[1] = x, + ThreadsData::Memory(x) => bar[2] = x, + ThreadsData::Time(x) => bar[3] = x, + } + + // match ends here + update(&bar); } - - if config.disk.enabled { - // disk_free return String - bar.push_str(&disk_free(&config)); - } - - if config.memory.enabled { - // mem return Result - bar.push_str(&mem(&config).unwrap()); - } - - bar.push_str(&fmt_date(&config)); - - Command::new("xsetroot") - .arg("-name") - .arg(bar) - .output() - .unwrap(); - - thread::sleep(Duration::from_millis(75)); } } -// format bar date/time -pub fn fmt_date(config: &Config) -> String { +pub fn update(bar: &Vec) { + // TODO: FIX ME, this solution sucks + let mut x = String::new(); + for i in bar.iter() { + x.push_str(i.as_str()); + } + Command::new("xsetroot") + .arg("-name") + .arg(x) + .output() + .unwrap(); +} + +/*############################ RUNNING THE PROGRAM ENDS HERE ###########################################*/ + +/* + + + + +############################# HELPER FUNCTIONS BELOW ################################### +*/ +pub fn get_time(config: &Config) -> String { let now = Local::now(); format!( @@ -183,7 +287,7 @@ pub fn fmt_date(config: &Config) -> String { ) } -pub fn disk_free(config: &Config) -> String { +pub fn get_disk(config: &Config) -> String { let cmd = Command::new("sh") .arg("-c") .args(&["df -h"]) @@ -205,9 +309,9 @@ pub fn disk_free(config: &Config) -> String { } // TODO: what a horrible solution to get the sound, i dont like it -// find another way you dumb fuck +// find another way -pub fn get_sound(config: &Config) -> String { +pub fn get_volume(config: &Config) -> String { let cmd_content = Command::new("amixer") .args(&["-D", "pulse", "get", "Master"]) .output() @@ -227,7 +331,7 @@ pub fn get_sound(config: &Config) -> String { format!(" {} {} {}", config.volume.icon, vol, config.seperator) } -pub fn mem(config: &Config) -> Result { +pub fn get_memory(config: &Config) -> Result { let mut buf = String::new(); File::open("/proc/meminfo")?.read_to_string(&mut buf)?; @@ -288,7 +392,7 @@ pub fn mem(config: &Config) -> Result { } Ok(result) } - +// helper function for the get_memory function fn assign_val(line: &str, assignable: &mut u32) { let parsed: u32 = line.split(':').collect::>()[1] .trim()