From 253113cd91eb6c436d934b9b8a098144405f81fd Mon Sep 17 00:00:00 2001 From: Tim Biermann Date: Sat, 7 Sep 2019 23:27:20 +0200 Subject: [PATCH] i3status-rust: cherry pick some patches --- i3status-rust/.signature | 6 +- i3status-rust/407.patch | 128 ++++++++++++++++++++++++++++++ i3status-rust/418.patch | 167 +++++++++++++++++++++++++++++++++++++++ i3status-rust/Pkgfile | 7 +- 4 files changed, 304 insertions(+), 4 deletions(-) create mode 100644 i3status-rust/407.patch create mode 100644 i3status-rust/418.patch diff --git a/i3status-rust/.signature b/i3status-rust/.signature index e9dc448e5..46ce9b0c4 100644 --- a/i3status-rust/.signature +++ b/i3status-rust/.signature @@ -1,5 +1,7 @@ untrusted comment: verify with /etc/ports/contrib.pub -RWSagIOpLGJF37OmgGXvHwKDo9/qeMo015151ix6vXgWcrjOgMzo0zgSSOXVDhBXaQDpmxX22ZpW+2hKgswadsEzPAgzWdWQRAU= -SHA256 (Pkgfile) = 514df7a5438b43e28078d70461097937f2d3e8e41a94bcb40a7c6fa5c9f99513 +RWSagIOpLGJF3yqTejWHKPkax2fPOzrUSK4wC+yYZppgf4KyLwUj8S7h/edup+AyEn6+Ts51gNdBss2qvOJFqTvObxbrprGmuQU= +SHA256 (Pkgfile) = a9b7d86dbca6419b8c20d81930cbb05e74e1989e58a98dbf8e733c0b4aae2640 SHA256 (.footprint) = 46e38c743630719fc5db8383d793d119a83726afb7568114366b2b9c2d3ed80b SHA256 (i3status-rust-0.10.0.tar.gz) = 84a12a91419fda35109a0be3980671c1d58e13c5987e6dc999cbe786d05053d9 +SHA256 (407.patch) = 06bce41061201b3ec2c9467d9f84478d18ed222d9e40f04d015697c0ab1d398e +SHA256 (418.patch) = 95373194871b6179a8eddf0fb84583ef3e5f22f9cc4efd84a32a8d3b30e2f8a6 diff --git a/i3status-rust/407.patch b/i3status-rust/407.patch new file mode 100644 index 000000000..ac4ca6b7a --- /dev/null +++ b/i3status-rust/407.patch @@ -0,0 +1,128 @@ +From 41fd7bf7a7a548aa3e1da05a3ac8ce2f873249c0 Mon Sep 17 00:00:00 2001 +From: Bram Vandenbogaerde +Date: Sat, 20 Jul 2019 19:05:58 +0200 +Subject: [PATCH] Made wind speed and degree optional by providing a default + value + cleaned up the JSON AST traversal code + +--- + src/blocks/weather.rs | 97 +++++++++++++++++-------------------------- + 1 file changed, 39 insertions(+), 58 deletions(-) + +diff --git a/src/blocks/weather.rs b/src/blocks/weather.rs +index 2c75067..8236b17 100644 +--- a/src/blocks/weather.rs ++++ b/src/blocks/weather.rs +@@ -48,6 +48,13 @@ pub struct Weather { + update_interval: Duration, + } + ++fn malformed_json_error() -> Error { ++ BlockError( ++ "weather".to_string(), ++ "Malformed JSON.".to_string(), ++ ) ++} ++ + impl Weather { + fn update_weather(&mut self) -> Result<()> { + match self.service { +@@ -97,67 +104,41 @@ impl Weather { + format!("API Error: {}", val.as_str().unwrap()), + )); + }; +- let raw_weather = match json.pointer("/weather/0/main") ++ let raw_weather = json.pointer("/weather/0/main") + .and_then(|v| v.as_str()) +- .map(|s| s.to_string()) { +- Some(v) => v, +- None => { +- return Err(BlockError( +- "weather".to_string(), +- "Malformed JSON.".to_string(), +- )); +- } +- }; +- let raw_temp = match json.pointer("/main/temp").and_then(|v| v.as_f64()) { +- Some(v) => v, +- None => { +- return Err(BlockError( +- "weather".to_string(), +- "Malformed JSON.".to_string(), +- )); +- } +- }; +- let raw_wind_speed = match json.pointer("/wind/speed").and_then(|v| v.as_f64()) { +- Some(v) => v, +- None => { +- return Err(BlockError( +- "weather".to_string(), +- "Malformed JSON.".to_string(), +- )); +- } +- }; +- let raw_wind_direction = match json.pointer("/wind/deg").and_then(|v| v.as_f64()) { +- Some(v) => v, +- None => { +- return Err(BlockError( +- "weather".to_string(), +- "Malformed JSON.".to_string(), +- )); +- } +- }; +- let raw_location = match json.pointer("/name").and_then(|v| v.as_str()).map(|s| { +- s.to_string() +- }) { +- Some(v) => v, +- None => { +- return Err(BlockError( +- "weather".to_string(), +- "Malformed JSON.".to_string(), +- )); +- } +- }; ++ .map(|s| s.to_string()) ++ .ok_or_else(malformed_json_error)?; ++ ++ let raw_temp = json.pointer("/main/temp").and_then(|v| v.as_f64()).ok_or_else(malformed_json_error)?; ++ ++ let raw_wind_speed: f64= json.pointer("/wind/speed") ++ .map_or(Some(0.0), |v| v.as_f64()) // provide default value 0.0 ++ .ok_or_else(malformed_json_error)?; // error when conversion to f64 fails ++ ++ let raw_wind_direction: Option= json.pointer("/wind/deg") ++ .map_or(Some(None), |v| v.as_f64().and_then(|v| Some(Some(v)))) // provide default value None ++ .ok_or_else(malformed_json_error)?; // error when conversion to f64 fails ++ ++ ++ let raw_location = json.pointer("/name") ++ .and_then(|v| v.as_str()) ++ .map(|s| s.to_string()) ++ .ok_or_else(malformed_json_error)?; + + // Convert wind direction in azimuth degrees to abbreviation names +- fn convert_wind_direction(direction: f64) -> String { +- match direction.round() as i64 { +- 24 ... 68 => "NE".to_string(), +- 69 ... 113 => "E".to_string(), +- 114 ... 158 => "SE".to_string(), +- 159 ... 203 => "S".to_string(), +- 204 ... 248 => "SW".to_string(), +- 249 ... 293 => "W".to_string(), +- 294 ... 338 => "NW".to_string(), +- _ => "N".to_string() ++ fn convert_wind_direction(direction_opt: Option) -> String { ++ match direction_opt { ++ Some(direction) => match direction.round() as i64 { ++ 24 ... 68 => "NE".to_string(), ++ 69 ... 113 => "E".to_string(), ++ 114 ... 158 => "SE".to_string(), ++ 159 ... 203 => "S".to_string(), ++ 204 ... 248 => "SW".to_string(), ++ 249 ... 293 => "W".to_string(), ++ 294 ... 338 => "NW".to_string(), ++ _ => "N".to_string() ++ }, ++ None => "-".to_string() + } + } + diff --git a/i3status-rust/418.patch b/i3status-rust/418.patch new file mode 100644 index 000000000..504933524 --- /dev/null +++ b/i3status-rust/418.patch @@ -0,0 +1,167 @@ +From b545460c66b8de1e94ae3ebd8614fe1d3b18b22c Mon Sep 17 00:00:00 2001 +From: Benjamin Bouvier +Date: Thu, 8 Aug 2019 10:05:25 +0200 +Subject: [PATCH] Fixes #387: Display WiFi signal strength in the net block. + +--- + blocks.md | 2 ++ + src/blocks/net.rs | 80 ++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 81 insertions(+), 1 deletion(-) + +diff --git a/blocks.md b/blocks.md +index 94e6cde..5584e66 100644 +--- a/blocks.md ++++ b/blocks.md +@@ -485,6 +485,7 @@ Creates a block which displays the upload and download throughput for a network + block = "net" + device = "wlp2s0" + ssid = true ++signal_strength = true + ip = true + speed_up = false + graph_up = true +@@ -497,6 +498,7 @@ Key | Values | Required | Default + ----|--------|----------|-------- + `device` | Network interface to moniter (name from /sys/class/net) | Yes | `lo` (loopback interface) + `ssid` | Display network SSID (wireless only). | No | `false` ++`signal_strength` | Display WiFi signal strength (wireless only). | No | `false` + `bitrate` | Display connection bitrate. | No | `false` + `ip` | Display connection IP address. | No | `false` + `speed_up` | Display upload speed. | No | `true` +diff --git a/src/blocks/net.rs b/src/blocks/net.rs +index 87b1332..328e587 100644 +--- a/src/blocks/net.rs ++++ b/src/blocks/net.rs +@@ -130,6 +130,62 @@ impl NetworkDevice { + } + } + ++ fn absolute_signal_strength(&self) -> Result> { ++ let up = self.is_up()?; ++ if !self.wireless || !up { ++ return Err(BlockError( ++ "net".to_string(), ++ "Signal strength is only available for connected wireless devices." ++ .to_string(), ++ )); ++ } ++ let mut iw_output = Command::new("sh") ++ .args(&[ ++ "-c", ++ &format!( ++ "iw dev {} link | sed -n 's/^\\s\\+signal: \\(.*\\) dBm/\\1/p'", ++ self.device ++ ), ++ ]) ++ .output() ++ .block_error("net", "Failed to execute signal strength query.")? ++ .stdout; ++ if iw_output.is_empty() { ++ Ok(None) ++ } else { ++ iw_output.pop(); // Remove trailing newline. ++ String::from_utf8(iw_output) ++ .block_error("net", "Non-UTF8 signal strength.") ++ .and_then(|as_str| as_str.parse::() ++ .block_error("net", "Non numerical signal strength.")) ++ .map(Some) ++ } ++ } ++ ++ fn relative_signal_strength(&self) -> Result> { ++ let xbm = if let Some(xbm) = self.absolute_signal_strength()? { ++ xbm as f64 ++ } else { ++ return Ok(None); ++ }; ++ ++ // Code inspired by https://github.com/NetworkManager/NetworkManager/blob/master/src/platform/wifi/nm-wifi-utils-nl80211.c ++ const NOISE_FLOOR_DBM: f64 = -90.; ++ const SIGNAL_MAX_DBM: f64 = -20.; ++ ++ let xbm = if xbm < NOISE_FLOOR_DBM { ++ NOISE_FLOOR_DBM ++ } else if xbm > SIGNAL_MAX_DBM { ++ SIGNAL_MAX_DBM ++ } else { ++ xbm ++ }; ++ ++ let result = 100. - 70. * ((SIGNAL_MAX_DBM - xbm) / (SIGNAL_MAX_DBM - NOISE_FLOOR_DBM)); ++ let result = result as u32; ++ Ok(Some(result)) ++ } ++ + /// Queries the inet IP of this device (using `ip`). + pub fn ip_addr(&self) -> Result> { + if !self.is_up()? { +@@ -196,6 +252,7 @@ pub struct Net { + network: ButtonWidget, + ssid: Option, + max_ssid_width: usize, ++ signal_strength: Option, + ip_addr: Option, + bitrate: Option, + output_tx: Option, +@@ -235,6 +292,10 @@ pub struct NetConfig { + #[serde(default = "NetConfig::default_max_ssid_width")] + pub max_ssid_width: usize, + ++ /// Whether to show the signal strength of active wireless networks. ++ #[serde(default = "NetConfig::default_signal_strength")] ++ pub signal_strength: bool, ++ + /// Whether to show the bitrate of active wireless networks. + #[serde(default = "NetConfig::default_bitrate")] + pub bitrate: bool, +@@ -296,6 +357,10 @@ impl NetConfig { + false + } + ++ fn default_signal_strength() -> bool { ++ false ++ } ++ + fn default_bitrate() -> bool { + false + } +@@ -350,6 +415,10 @@ impl ConfigBlock for Net { + None + }, + max_ssid_width: block_config.max_ssid_width, ++ signal_strength: if block_config.signal_strength && wireless { ++ Some(ButtonWidget::new(config.clone(), &id)) } else { ++ None ++ }, + bitrate: if block_config.bitrate { + Some(ButtonWidget::new(config.clone(), &id)) } else { + None +@@ -460,6 +529,12 @@ impl Block for Net { + ssid_widget.set_text(truncated); + } + } ++ if let Some(ref mut signal_strength_widget) = self.signal_strength { ++ let value = self.device.relative_signal_strength()?; ++ if value.is_some() { ++ signal_strength_widget.set_text(format!("{}%", value.unwrap())); ++ } ++ } + if let Some(ref mut ip_addr_widget) = self.ip_addr { + let ip_addr = self.device.ip_addr()?; + if ip_addr.is_some() { +@@ -510,11 +585,14 @@ impl Block for Net { + + fn view(&self) -> Vec<&I3BarWidget> { + if self.active { +- let mut widgets: Vec<&I3BarWidget> = Vec::with_capacity(7); ++ let mut widgets: Vec<&I3BarWidget> = Vec::with_capacity(8); + widgets.push(&self.network); + if let Some(ref ssid_widget) = self.ssid { + widgets.push(ssid_widget); + }; ++ if let Some(ref signal_strength_widget) = self.signal_strength { ++ widgets.push(signal_strength_widget); ++ }; + if let Some(ref bitrate_widget) = self.bitrate { + widgets.push(bitrate_widget); + } diff --git a/i3status-rust/Pkgfile b/i3status-rust/Pkgfile index d5e55a7c4..ffcc851b7 100644 --- a/i3status-rust/Pkgfile +++ b/i3status-rust/Pkgfile @@ -5,14 +5,17 @@ name=i3status-rust version=0.10.0 -release=1 -source=(https://github.com/greshake/i3status-rust/archive/v$version/$name-$version.tar.gz) +release=2 +source=(https://github.com/greshake/i3status-rust/archive/v$version/$name-$version.tar.gz + 407.patch 418.patch) build() { cd $name-$version prt-get isinst sccache && export RUSTC_WRAPPER=/usr/bin/sccache mkdir "$PKGMK_SOURCE_DIR/rust" || true export CARGO_HOME="$PKGMK_SOURCE_DIR/rust" + patch -Np1 -i $SRC/407.patch # fix weather block + patch -Np1 -i $SRC/418.patch # show wifi signal strength cargo fetch cargo build --release install -Dt $PKG/usr/bin target/release/i3status-rs