diff --git a/src/run.rs b/src/run.rs index 12efefa..3f7405d 100644 --- a/src/run.rs +++ b/src/run.rs @@ -5,136 +5,86 @@ use std::sync::mpsc; use std::thread; use std::time::Duration; +fn spawn_thread_loop(tx: std::sync::mpsc::Sender, data: F, delay: f64) +where + F: Fn() -> ThreadsData + Send + 'static, +{ + thread::spawn(move || loop { + tx.send(data()).unwrap(); + thread::sleep(Duration::from_secs_f64(delay)); + }); +} + pub fn run(mut blocks: Blocks) { let (tx, rx) = mpsc::channel(); // loadavrage thread if CONFIG.loadavg.enabled { - let loadavg_tx = tx.clone(); - thread::spawn(move || loop { - let loadavg_data = ThreadsData::LoadAvg(load_average::get_load_avg()); - loadavg_tx.send(loadavg_data).unwrap(); - thread::sleep(Duration::from_secs_f64(CONFIG.loadavg.delay)) - }); + spawn_thread_loop(tx.clone(), load_average::get_load_avg, CONFIG.loadavg.delay); } // public ip thread if CONFIG.pub_ip.enabled { - let pub_ip_tx = tx.clone(); - thread::spawn(move || loop { - let pub_ip_data = ThreadsData::PubIp(pub_ip::get_pub_ip()); - pub_ip_tx.send(pub_ip_data).unwrap(); - thread::sleep(Duration::from_secs_f64(CONFIG.pub_ip.delay)) - }); + spawn_thread_loop(tx.clone(), pub_ip::get_pub_ip, CONFIG.pub_ip.delay); } // spotify thread if CONFIG.spotify.enabled { - let spotify_tx = tx.clone(); - thread::spawn(move || loop { - let spotify_data = ThreadsData::Spotify(spotify::get_spotify()); - spotify_tx.send(spotify_data).unwrap(); - thread::sleep(Duration::from_secs_f64(CONFIG.spotify.delay)) - }); + spawn_thread_loop(tx.clone(), spotify::get_spotify, CONFIG.spotify.delay); } // mpd thread if CONFIG.mpd.enabled { - let mpd_tx = tx.clone(); - thread::spawn(move || loop { - let mpd_data = ThreadsData::Mpd(mpd::get_mpd_current()); - mpd_tx.send(mpd_data).unwrap(); - thread::sleep(Duration::from_secs_f64(CONFIG.mpd.delay)) - }); + spawn_thread_loop(tx.clone(), mpd::get_mpd_current, CONFIG.mpd.delay); } // volume thread if CONFIG.volume.enabled { - let volume_tx = tx.clone(); - thread::spawn(move || loop { - let vol_data = ThreadsData::Sound(volume::get_volume()); - volume_tx.send(vol_data).unwrap(); - thread::sleep(Duration::from_secs_f64(CONFIG.volume.delay)) - }); - } - - // net speed thread - if CONFIG.netspeed.enabled { - let net_tx = tx.clone(); - thread::spawn(move || loop { - // get_netspeed will sleep inside the function - let net_data = ThreadsData::NetSpeed(netspeed::get_netspeed()); - net_tx.send(net_data).unwrap(); - }); + spawn_thread_loop(tx.clone(), volume::get_volume, CONFIG.volume.delay); } // Disk thread if CONFIG.disk.enabled { - let disk_tx = tx.clone(); - thread::spawn(move || loop { - let disk_data = ThreadsData::Disk(disk::get_disk()); - disk_tx.send(disk_data).unwrap(); - thread::sleep(Duration::from_secs_f64(CONFIG.disk.delay)) - }); + spawn_thread_loop(tx.clone(), disk::get_disk, CONFIG.disk.delay); } // Memory thread if CONFIG.memory.enabled { - let memory_tx = tx.clone(); - thread::spawn(move || loop { - let memory_data = ThreadsData::Memory(memory::get_memory().unwrap()); - memory_tx.send(memory_data).unwrap(); - thread::sleep(Duration::from_secs_f64(CONFIG.memory.delay)) - }); + spawn_thread_loop(tx.clone(), memory::get_memory, CONFIG.memory.delay); } // Weather thread if CONFIG.weather.enabled { - let weather_tx = tx.clone(); - thread::spawn(move || loop { - let weather_data = ThreadsData::Weather(weather::get_weather()); - weather_tx.send(weather_data).unwrap(); - thread::sleep(Duration::from_secs_f64(CONFIG.weather.delay)) - }); + spawn_thread_loop(tx.clone(), weather::get_weather, CONFIG.weather.delay); } // Battery thread if CONFIG.battery.enabled { - let battery_tx = tx.clone(); - thread::spawn(move || loop { - let battery_data = ThreadsData::Battery(battery::get_battery().unwrap()); - battery_tx.send(battery_data).unwrap(); - thread::sleep(Duration::from_secs_f64(CONFIG.battery.delay)) - }); + spawn_thread_loop(tx.clone(), battery::get_battery, CONFIG.battery.delay); } // Cpu temperature thread if CONFIG.cpu_temperature.enabled { - let cpu_temp_tx = tx.clone(); - thread::spawn(move || loop { - let cpu_temp_data = ThreadsData::CpuTemp(cpu::get_cpu_temp().unwrap()); - cpu_temp_tx.send(cpu_temp_data).unwrap(); - thread::sleep(Duration::from_secs_f64(CONFIG.cpu_temperature.delay)) - }); + spawn_thread_loop(tx.clone(), cpu::get_cpu_temp, CONFIG.cpu_temperature.delay); } // Uptime thread if CONFIG.uptime.enabled { - let uptime_tx = tx.clone(); + spawn_thread_loop(tx.clone(), uptime::get_uptime, CONFIG.uptime.delay); + } + + // net speed thread + // get_netspeed will sleep inside the function + if CONFIG.netspeed.enabled { + let net_tx = tx.clone(); thread::spawn(move || loop { - let uptime_data = ThreadsData::Uptime(uptime::get_uptime().unwrap()); - uptime_tx.send(uptime_data).unwrap(); - thread::sleep(Duration::from_secs_f64(CONFIG.uptime.delay)) + let net_data = netspeed::get_netspeed(); + net_tx.send(net_data).unwrap(); }); } // Time thread { - let time_tx = tx; - thread::spawn(move || loop { - let time_data = ThreadsData::Time(time::get_time()); - time_tx.send(time_data).unwrap(); - thread::sleep(Duration::from_secs_f64(CONFIG.time.delay)) - }); + spawn_thread_loop(tx, time::get_time, CONFIG.time.delay); } //Main diff --git a/src/utils/battery.rs b/src/utils/battery.rs index 1278303..041965a 100644 --- a/src/utils/battery.rs +++ b/src/utils/battery.rs @@ -1,10 +1,11 @@ use crate::config::CONFIG; -use std::fs::File; -use std::io::Error; -use std::io::Read; +use crate::types::ThreadsData; +use std::fs::read_to_string; // getting battery percentage -pub fn get_battery() -> Result { +pub fn get_battery() -> ThreadsData { + let error = ThreadsData::Battery(String::from("check your battery source name")); + let battery_full_cap_file = format!( "/sys/class/power_supply/{}/charge_full_design", CONFIG.battery.source @@ -14,17 +15,16 @@ pub fn get_battery() -> Result { CONFIG.battery.source ); - let mut buf = String::new(); - - match File::open(&battery_full_cap_file) { - Ok(mut file) => file.read_to_string(&mut buf)?, - Err(_) => return Ok(String::from("check your battery source name")), + let buf = match read_to_string(battery_full_cap_file) { + Ok(file) => file, + Err(_) => return error, }; let full_design = buf.trim().parse::().unwrap(); - buf.clear(); - // No need to error check if passed the above match - File::open(&battery_charge_now_file)?.read_to_string(&mut buf)?; + let buf = match read_to_string(&battery_charge_now_file) { + Ok(data) => data, + _ => return error, + }; let charge_now = buf.trim().parse::().unwrap(); @@ -33,5 +33,5 @@ pub fn get_battery() -> Result { " {} {:.0}% {}", CONFIG.battery.icon, battery_percentage, CONFIG.seperator ); - Ok(result) + ThreadsData::Battery(result) } diff --git a/src/utils/cpu.rs b/src/utils/cpu.rs index f8ae595..2047a07 100644 --- a/src/utils/cpu.rs +++ b/src/utils/cpu.rs @@ -1,11 +1,14 @@ use crate::config::CONFIG; -use std::fs::File; -use std::io::Read; +use crate::types::ThreadsData; +use std::fs::read_to_string; // getting cpu temperature -pub fn get_cpu_temp() -> Result { - let mut buf = String::new(); - File::open("/sys/class/thermal/thermal_zone0/temp")?.read_to_string(&mut buf)?; +pub fn get_cpu_temp() -> ThreadsData { + let buf = match read_to_string("/sys/class/thermal/thermal_zone0/temp") { + Ok(data) => data, + _ => return ThreadsData::CpuTemp(String::from("Error reading temp")), + }; + let value = buf.trim().parse::().unwrap(); let result = format!( @@ -14,5 +17,5 @@ pub fn get_cpu_temp() -> Result { value / 1000.0, CONFIG.seperator ); - Ok(result) + ThreadsData::CpuTemp(result) } diff --git a/src/utils/disk.rs b/src/utils/disk.rs index f082ef1..2250911 100644 --- a/src/utils/disk.rs +++ b/src/utils/disk.rs @@ -1,6 +1,7 @@ use crate::config::CONFIG; +use crate::types::ThreadsData; -pub fn get_disk() -> String { +pub fn get_disk() -> ThreadsData { const GB: u64 = (1024 * 1024) * 1024; let statvfs = nix::sys::statvfs::statvfs("/").unwrap(); let mut disk_used = String::new(); @@ -10,8 +11,9 @@ pub fn get_disk() -> String { let used = total - available; disk_used.push_str(&format!("{}G", used)); - format!( + let data = format!( " {} {} {}", CONFIG.disk.icon, disk_used, CONFIG.seperator - ) + ); + ThreadsData::Disk(data) } diff --git a/src/utils/load_average.rs b/src/utils/load_average.rs index 4fd38f7..70e4a72 100644 --- a/src/utils/load_average.rs +++ b/src/utils/load_average.rs @@ -1,16 +1,18 @@ use crate::config::CONFIG; +use crate::types::ThreadsData; use std::fs::File; use std::io::Read; -pub fn get_load_avg() -> String { +pub fn get_load_avg() -> ThreadsData { let mut buf = String::new(); match File::open("/proc/loadavg") { Ok(mut file) => match file.read_to_string(&mut buf) { Ok(data) => data, - _ => return String::from(""), + _ => return ThreadsData::LoadAvg(String::from("")), }, - _ => return String::from("Error"), + _ => return ThreadsData::LoadAvg(String::from("Error")), }; let buf = buf.split_whitespace().collect::>()[0]; - format!(" {} {} {}", CONFIG.loadavg.icon, buf, CONFIG.seperator) + let data = format!(" {} {} {}", CONFIG.loadavg.icon, buf, CONFIG.seperator); + ThreadsData::LoadAvg(data) } diff --git a/src/utils/memory.rs b/src/utils/memory.rs index 6283527..3d51fd5 100644 --- a/src/utils/memory.rs +++ b/src/utils/memory.rs @@ -1,16 +1,17 @@ use crate::config::CONFIG; -use std::fs::File; -use std::io::Read; +use crate::types::ThreadsData; +use std::fs::read_to_string; /* mem_used = (mem_total + shmem - mem_free - mem_buffers - mem_cached - mem_srecl thanks for htop's developer on stackoverflow for providing this algorithm to calculate used memory. */ -pub fn get_memory() -> Result { - let mut buf = String::new(); - - File::open("/proc/meminfo")?.read_to_string(&mut buf)?; +pub fn get_memory() -> ThreadsData { + let buf = match read_to_string("/proc/meminfo") { + Ok(data) => data, + _ => return ThreadsData::Memory(String::from("Error Reading memory!")), + }; let mut mem_total: u32 = 0; let mut shmem: u32 = 0; @@ -66,7 +67,7 @@ pub fn get_memory() -> Result { CONFIG.memory.icon, mem_used, CONFIG.seperator ); } - Ok(result) + ThreadsData::Memory(result) } /* diff --git a/src/utils/mpd.rs b/src/utils/mpd.rs index b7fdbd6..3752387 100644 --- a/src/utils/mpd.rs +++ b/src/utils/mpd.rs @@ -1,21 +1,22 @@ use crate::config::CONFIG; +use crate::types::ThreadsData; use mpd::{Client, Song}; // yes, error handling looks fucking sucks! // getting mpd song file -pub fn get_mpd_current() -> String { +pub fn get_mpd_current() -> ThreadsData { let stream_path = format!("{}:{}", CONFIG.mpd.host, CONFIG.mpd.port); - let empty_string = String::from(""); + let empty_data = ThreadsData::Mpd(String::from("")); let mut conn = match Client::connect(&stream_path) { Ok(connection) => connection, - _ => return empty_string, + _ => return empty_data, }; let current: Song = match conn.currentsong() { Ok(opt) => match opt { Some(song) => song, - _ => return empty_string, + _ => return empty_data, }, - _ => return empty_string, + _ => return empty_data, }; let result = format!( @@ -23,5 +24,5 @@ pub fn get_mpd_current() -> String { CONFIG.mpd.icon, current.file, CONFIG.seperator ); - result + ThreadsData::Mpd(result) } diff --git a/src/utils/netspeed.rs b/src/utils/netspeed.rs index 59f740f..fe172a3 100644 --- a/src/utils/netspeed.rs +++ b/src/utils/netspeed.rs @@ -1,9 +1,10 @@ use crate::config::CONFIG; +use crate::types::ThreadsData; use std::fs::read_to_string; use std::thread; use std::time::Duration; -pub fn get_netspeed() -> String { +pub fn get_netspeed() -> ThreadsData { let tx1: u64 = parse_speed_file("tx_bytes"); let rx1: u64 = parse_speed_file("rx_bytes"); thread::sleep(Duration::from_secs(1)); @@ -16,10 +17,11 @@ pub fn get_netspeed() -> String { let tx = calculate(tx_bps); let rx = calculate(rx_bps); - format!( + let data = format!( " {} {} {} {} {}", CONFIG.netspeed.recieve_icon, rx, CONFIG.netspeed.transmit_icon, tx, CONFIG.seperator - ) + ); + ThreadsData::NetSpeed(data) } fn parse_speed_file(pth: &str) -> u64 { diff --git a/src/utils/pub_ip.rs b/src/utils/pub_ip.rs index ce2da92..c0e6e4c 100644 --- a/src/utils/pub_ip.rs +++ b/src/utils/pub_ip.rs @@ -1,15 +1,17 @@ use crate::config::CONFIG; +use crate::types::ThreadsData; -pub fn get_pub_ip() -> String { +pub fn get_pub_ip() -> ThreadsData { let url = format!("http://api.ipify.org"); - let err_string = String::from("Error"); + let _err = String::from("Error"); let res = match minreq::get(url).send() { Ok(resp) => match resp.as_str() { Ok(res_str) => res_str.trim().to_string(), - Err(_) => err_string, + Err(_) => _err, }, - Err(_) => err_string, + Err(_) => _err, }; - format!(" {} {} {}", CONFIG.pub_ip.icon, res, CONFIG.seperator) + let data = format!(" {} {} {}", CONFIG.pub_ip.icon, res, CONFIG.seperator); + ThreadsData::PubIp(data) } diff --git a/src/utils/spotify.rs b/src/utils/spotify.rs index a73128d..9e5c5da 100644 --- a/src/utils/spotify.rs +++ b/src/utils/spotify.rs @@ -1,14 +1,15 @@ use crate::config::CONFIG; +use crate::types::ThreadsData; use dbus::blocking::stdintf::org_freedesktop_dbus::Properties; use dbus::{arg, blocking::Connection}; use std::time::Duration; - // getting spotify current artist and title. -// FIXME: I know im lazy asshole, this error handling looks ugly, i dont like it too, need to fix soon. -pub fn get_spotify() -> String { + +pub fn get_spotify() -> ThreadsData { + let empty_data = ThreadsData::Spotify(String::from("")); let conn = match Connection::new_session() { Ok(conn) => conn, - _ => return String::from(""), + _ => return empty_data, }; let p = conn.with_proxy( @@ -19,7 +20,7 @@ pub fn get_spotify() -> String { let metadata: arg::PropMap = match p.get("org.mpris.MediaPlayer2.Player", "Metadata") { Ok(data) => data, - _ => return String::from(""), + _ => return empty_data, }; let title: Option<&String> = arg::prop_cast(&metadata, "xesam:title"); @@ -38,8 +39,9 @@ pub fn get_spotify() -> String { None => "", }; - format!( + let data = format!( " {} {} - {} {}", CONFIG.spotify.icon, artist, title, CONFIG.seperator - ) + ); + ThreadsData::Spotify(data) } diff --git a/src/utils/time.rs b/src/utils/time.rs index fcfb691..191d91b 100644 --- a/src/utils/time.rs +++ b/src/utils/time.rs @@ -1,13 +1,16 @@ use crate::config::CONFIG; +use crate::types::ThreadsData; use chrono::prelude::*; -pub fn get_time() -> String { +pub fn get_time() -> ThreadsData { let now = Local::now(); - format!( + let data = format!( " {} {} {}", CONFIG.time.icon, now.format(&CONFIG.time.format), CONFIG.seperator - ) + ); + + ThreadsData::Time(data) } diff --git a/src/utils/uptime.rs b/src/utils/uptime.rs index b5de930..140c4c4 100644 --- a/src/utils/uptime.rs +++ b/src/utils/uptime.rs @@ -1,12 +1,11 @@ use crate::config::CONFIG; -use std::fs::File; -use std::io::Read; +use crate::types::ThreadsData; +use std::fs::read_to_string; -pub fn get_uptime() -> Result { - let mut buf = String::new(); - match File::open("/proc/uptime") { - Ok(mut file) => file.read_to_string(&mut buf)?, - _ => return Ok("cant find uptime file!".to_string()), +pub fn get_uptime() -> ThreadsData { + let buf = match read_to_string("/proc/uptime") { + Ok(data) => data, + _ => return ThreadsData::Uptime("cant find uptime file!".to_string()), }; let buf: f32 = buf.split(' ').collect::>()[0].parse().unwrap(); @@ -21,5 +20,5 @@ pub fn get_uptime() -> Result { format!("{} min", minutes) }; let result = format!(" {} {} {}", CONFIG.uptime.icon, uptime, CONFIG.seperator); - Ok(result) + ThreadsData::Uptime(result) } diff --git a/src/utils/volume.rs b/src/utils/volume.rs index c020ce8..05c1dbe 100644 --- a/src/utils/volume.rs +++ b/src/utils/volume.rs @@ -1,8 +1,9 @@ use crate::config::CONFIG; +use crate::types::ThreadsData; use alsa::mixer::{Mixer, SelemChannelId, SelemId}; // getting volume percentage -pub fn get_volume() -> String { +pub fn get_volume() -> ThreadsData { let card = if CONFIG.volume.card == "PULSE" { "pulse" } else { @@ -27,5 +28,6 @@ pub fn get_volume() -> String { ((raw_volume as f64 / range as f64) * 100.) as u64 }; - format!(" {} {}% {}", CONFIG.volume.icon, vol, CONFIG.seperator) + let data = format!(" {} {}% {}", CONFIG.volume.icon, vol, CONFIG.seperator); + ThreadsData::Sound(data) } diff --git a/src/utils/weather.rs b/src/utils/weather.rs index 9dc053b..11e446f 100644 --- a/src/utils/weather.rs +++ b/src/utils/weather.rs @@ -1,7 +1,8 @@ use crate::config::CONFIG; +use crate::types::ThreadsData; // will make a GET request from wttr.in -pub fn get_weather() -> String { +pub fn get_weather() -> ThreadsData { let format = if CONFIG.weather.format.is_empty() { String::from("%l:+%t") } else { @@ -18,5 +19,6 @@ pub fn get_weather() -> String { Err(_) => err_string, }; - format!(" {} {} {}", CONFIG.weather.icon, res, CONFIG.seperator) + let data = format!(" {} {} {}", CONFIG.weather.icon, res, CONFIG.seperator); + ThreadsData::Weather(data) }