~tsdh/public-inbox

2 2

Re: [PATCH swayr 0/1] Add wifi module

Details
Message ID
<87ilk5jevn.fsf@gmail.com>
DKIM signature
pass
Download raw message
Patch: +152 -2
Karl Eklund <localpart@gmail.com> writes:

> Tassilo Horn <tsdh@gnu.org> writes:
>
>> Tassilo Horn <tsdh@gnu.org> writes:
>>
>> I've asked on #srht on libera.chat.  There is or was some issue where
>> cloning a repo using the "Clone repo to your account" button resulted in
>> a broken repo with exactly the above problem.  When did you clone the
>> repo to your account?
>>
>> Anyway, I suggest you simply rebase your commits on the wifi branch and
>> squash them into a single commit and then send that as a new patch to
>> this list again.
>
> That's weird. I think I created the fork on the same day that I sent
> that initial patch. Also I'm able to do git clone via the git URL but
> not the https one. I will try to recreate the fork perhaps and then send a new patch.
>
> ~ 🐟 git clone https://git.sr.ht/~ke/swayr
> Cloning into 'swayr'...
> fatal: expected 'packfile'
>  ~ 128 🦩 git clone git@git.sr.ht:~ke/swayr
> Cloning into 'swayr'...
> remote: Enumerating objects: 2223, done.
> remote: Counting objects: 100% (2223/2223), done.
> remote: Compressing objects: 100% (669/669), done.
> remote: Total 2223 (delta 1568), reused 2178 (delta 1536), pack-reused 0
> Receiving objects: 100% (2223/2223), 1.58 MiB | 848.00 KiB/s, done.
> Resolving deltas: 100% (1568/1568), done.
>  ~ 🐟
>

I deleted my fork and recreated it, but the git clone problem persisted.
So I cloned it to Github... Here is a new "git request-pull" patch, one
commit, rebased on latest upstream.

The following changes since commit 0ea753f4e14b1a3174a8fcee46a5447b390b0039:

  Implement window and container stealing (2022-10-27 19:40:01 +0200)

are available in the Git repository at:

  https://github.com/kek/swayr wifi

for you to fetch changes up to 2d95634f2886a3bc4a4f993fe8c119fe8f13ca5a:

  Add wifi module (2022-10-27 20:19:34 +0200)

----------------------------------------------------------------
Karl Eklund (1):
      Add wifi module

 Cargo.lock                  |   2 +-
 README.md                   |   7 +++
 swayrbar/Cargo.toml         |   2 +-
 swayrbar/src/bar.rs         |   1 +
 swayrbar/src/module.rs      |   1 +
 swayrbar/src/module/wifi.rs | 141 ++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 152 insertions(+), 2 deletions(-)
 create mode 100644 swayrbar/src/module/wifi.rs

diff --git a/Cargo.lock b/Cargo.lock
index 831b2e7..5b3bd19 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -686,7 +686,7 @@ dependencies = [

[[package]]
name = "swayrbar"
version = "0.2.4"
version = "0.2.4-wifi"
dependencies = [
 "battery",
 "chrono",
diff --git a/README.md b/README.md
index b4fd1ae..190bdc4 100644
--- a/README.md
+++ b/README.md
@@ -806,6 +806,13 @@ By default, it has the following click bindings:
* `WheelUp` and `WheelDown` increase/decrease the volume of the default sink.


#### The `wifi` module

The `wifi` module displays information about the wi-fi connection. It supports the following placeholders:
* `{name}` Wi-fi network name.
* `{signal}` wireless signal strength.


#### The `date` module

The `date` module shows the date and time by defining the `format` using
diff --git a/swayrbar/Cargo.toml b/swayrbar/Cargo.toml
index cf1d254..9894489 100644
--- a/swayrbar/Cargo.toml
+++ b/swayrbar/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "swayrbar"
version = "0.2.4"
version = "0.2.4-wifi"
edition = "2021"
homepage = "https://sr.ht/~tsdh/swayr/#swayrbar"
repository = "https://git.sr.ht/~tsdh/swayr"
diff --git a/swayrbar/src/bar.rs b/swayrbar/src/bar.rs
index ea51ce4..2fa78a5 100644
--- a/swayrbar/src/bar.rs
+++ b/swayrbar/src/bar.rs
@@ -101,6 +101,7 @@ fn create_modules(config: config::Config) -> Vec<Box<dyn BarModuleFn>> {
            "battery" => module::battery::BarModuleBattery::create(mc),
            "date" => module::date::BarModuleDate::create(mc),
            "pactl" => module::pactl::BarModulePactl::create(mc),
            "wifi" => module::wifi::BarModuleWifi::create(mc),
            unknown => {
                log::warn!("Unknown module name '{}'.  Ignoring...", unknown);
                continue;
diff --git a/swayrbar/src/module.rs b/swayrbar/src/module.rs
index 152cc45..268cbc0 100644
--- a/swayrbar/src/module.rs
+++ b/swayrbar/src/module.rs
@@ -22,6 +22,7 @@ pub mod battery;
pub mod date;
pub mod pactl;
pub mod sysinfo;
pub mod wifi;
pub mod window;

#[derive(Debug, PartialEq, Eq)]
diff --git a/swayrbar/src/module/wifi.rs b/swayrbar/src/module/wifi.rs
new file mode 100644
index 0000000..d77be88
--- /dev/null
+++ b/swayrbar/src/module/wifi.rs
@@ -0,0 +1,141 @@
use crate::config;
use crate::module::BarModuleFn;
use crate::shared::fmt::subst_placeholders;
use std::sync::Mutex;
use swaybar_types as s;

use super::RefreshReason;

const NAME: &str = "wifi";

struct State {
    cached_text: String,
    signal: Option<String>,
    name: Option<String>,
}

pub struct BarModuleWifi {
    config: config::ModuleConfig,
    state: Mutex<State>,
}

fn run_nmcli() -> Result<String, String> {
    let cmd = "nmcli";
    let args = "-c no -g IN-USE,SSID,SIGNAL,BARS dev wifi".split(" ");
    let output = std::process::Command::new(cmd)
        .args(args)
        .output()
        .map_err(|e| format!("Failed to run nmcli: {}", e))?;

    if !output.status.success() {
        return Err(format!(
            "nmcli failed with status code {}",
            output.status.code().unwrap_or(-1)
        ));
    }

    Ok(String::from_utf8(output.stdout).unwrap())
}

fn subst_placeholders(fmt: &str, html_escape: bool, state: &State) -> String {
    subst_placeholders!(fmt, html_escape, {
        "name" => {
            match &state.name {
                None => "No wi-fi",
                Some(name) => name,
            }
        },
        "signal" => {
            match &state.signal {
                None => "None",
                Some(signal) => signal,
            }
        },
    })
}

fn refresh_state(state: &mut State, fmt_str: &str, html_escape: bool) {
    if let Ok(output) = run_nmcli() {
        if let Some(line) = output.lines().find(|line| line.starts_with("*")) {
            let mut parts = line.split(":");
            parts.next();
            state.name = Some(parts.next().unwrap().to_string());
            state.signal = Some(parts.next().unwrap().to_string());
        }
    }
    state.cached_text = subst_placeholders(fmt_str, html_escape, state);
}

impl BarModuleFn for BarModuleWifi {
    fn create(config: config::ModuleConfig) -> Box<dyn BarModuleFn>
    where
        Self: Sized,
    {
        Box::new(BarModuleWifi {
            config,
            state: Mutex::new(State {
                cached_text: String::new(),
                signal: None,
                name: None,
            }),
        })
    }

    fn default_config(instance: String) -> config::ModuleConfig
    where
        Self: Sized,
    {
        config::ModuleConfig {
            name: NAME.to_owned(),
            instance,
            format: "📡 Wi-fi {name} {signal}%".to_owned(),
            html_escape: Some(false),
            on_click: None,
        }
    }

    fn get_config(&self) -> &config::ModuleConfig {
        &self.config
    }

    fn build(&self, nai: &Option<super::NameInstanceAndReason>) -> s::Block {
        let mut state = self.state.lock().expect("Could not lock state.");

        if self.should_refresh(nai, true, &[RefreshReason::ClickEvent]) {
            refresh_state(
                &mut state,
                &self.config.format,
                self.config.is_html_escape(),
            );
        }

        s::Block {
            name: Some(NAME.to_owned()),
            instance: Some(self.config.instance.clone()),
            full_text: state.cached_text.to_owned(),
            align: Some(s::Align::Left),
            markup: Some(s::Markup::Pango),
            short_text: None,
            color: None,
            background: None,
            border: None,
            border_top: None,
            border_bottom: None,
            border_left: None,
            border_right: None,
            min_width: None,
            urgent: None,
            separator: Some(true),
            separator_block_width: None,
        }
    }

    fn subst_args<'a>(&'a self, cmd: &'a [String]) -> Option<Vec<String>> {
        let state = self.state.lock().expect("Could not lock state.");
        Some(
            cmd.iter()
                .map(|arg| subst_placeholders(arg, false, &state))
                .collect(),
        )
    }
}

Re: [PATCH swayr 0/1] Add wifi module

Details
Message ID
<87fsf9jdze.fsf@gmail.com>
In-Reply-To
<87ilk5jevn.fsf@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Patch: +167 -2
Karl Eklund <localpart@gmail.com> writes:

> I deleted my fork and recreated it, but the git clone problem persisted.
> So I cloned it to Github... Here is a new "git request-pull" patch, one
> commit, rebased on latest upstream.

Please ignore the previous message. It is not the right commit. It only
contained my first commit. I did something wrong when rebasing.

Here is the proper one. The branch is called nmcli now.

Sorry.

The following changes since commit 0ea753f4e14b1a3174a8fcee46a5447b390b0039:

  Implement window and container stealing (2022-10-27 19:40:01 +0200)

are available in the Git repository at:

  https://github.com/kek/swayr nmcli

for you to fetch changes up to b301beed5c159daf6900a38da4feb5ae90f92542:

  Add nmcli module (2022-10-27 20:50:29 +0200)

----------------------------------------------------------------
Karl Eklund (1):
      Add nmcli module

 Cargo.lock                   |   2 +-
 README.md                    |  10 +++
 swayrbar/Cargo.toml          |   2 +-
 swayrbar/src/bar.rs          |   1 +
 swayrbar/src/module.rs       |   1 +
 swayrbar/src/module/nmcli.rs | 153 +++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 167 insertions(+), 2 deletions(-)
 create mode 100644 swayrbar/src/module/nmcli.rs

diff --git a/Cargo.lock b/Cargo.lock
index 831b2e7..ded8bfa 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -686,7 +686,7 @@ dependencies = [

[[package]]
name = "swayrbar"
version = "0.2.4"
version = "0.2.4-nmcli"
dependencies = [
 "battery",
 "chrono",
diff --git a/README.md b/README.md
index b4fd1ae..0a0586c 100644
--- a/README.md
+++ b/README.md
@@ -806,6 +806,16 @@ By default, it has the following click bindings:
* `WheelUp` and `WheelDown` increase/decrease the volume of the default sink.


#### The `nmcli` module

The `nmcli` module requires NetworkManager and the `nmcli` command line tool.
It can display information about the wi-fi connection.  It supports the
following placeholders:
* `{name}` wi-fi network name.
* `{signal}` wireless signal strength.
* `{bars}` a visualization of connection strength, like "▂▄▆_".


#### The `date` module

The `date` module shows the date and time by defining the `format` using
diff --git a/swayrbar/Cargo.toml b/swayrbar/Cargo.toml
index cf1d254..1eac445 100644
--- a/swayrbar/Cargo.toml
+++ b/swayrbar/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "swayrbar"
version = "0.2.4"
version = "0.2.4-nmcli"
edition = "2021"
homepage = "https://sr.ht/~tsdh/swayr/#swayrbar"
repository = "https://git.sr.ht/~tsdh/swayr"
diff --git a/swayrbar/src/bar.rs b/swayrbar/src/bar.rs
index ea51ce4..e68c6d0 100644
--- a/swayrbar/src/bar.rs
+++ b/swayrbar/src/bar.rs
@@ -101,6 +101,7 @@ fn create_modules(config: config::Config) -> Vec<Box<dyn BarModuleFn>> {
            "battery" => module::battery::BarModuleBattery::create(mc),
            "date" => module::date::BarModuleDate::create(mc),
            "pactl" => module::pactl::BarModulePactl::create(mc),
            "nmcli" => module::nmcli::BarModuleNmcli::create(mc),
            unknown => {
                log::warn!("Unknown module name '{}'.  Ignoring...", unknown);
                continue;
diff --git a/swayrbar/src/module.rs b/swayrbar/src/module.rs
index 152cc45..74427cb 100644
--- a/swayrbar/src/module.rs
+++ b/swayrbar/src/module.rs
@@ -22,6 +22,7 @@ pub mod battery;
pub mod date;
pub mod pactl;
pub mod sysinfo;
pub mod nmcli;
pub mod window;

#[derive(Debug, PartialEq, Eq)]
diff --git a/swayrbar/src/module/nmcli.rs b/swayrbar/src/module/nmcli.rs
new file mode 100644
index 0000000..7bf2f1f
--- /dev/null
+++ b/swayrbar/src/module/nmcli.rs
@@ -0,0 +1,153 @@
use crate::config;
use crate::module::BarModuleFn;
use crate::shared::fmt::subst_placeholders;
use std::sync::Mutex;
use swaybar_types as s;

use super::RefreshReason;

const NAME: &str = "nmcli";

struct State {
    cached_text: String,
    signal: Option<String>,
    name: Option<String>,
    bars: Option<String>,
}

pub struct BarModuleNmcli {
    config: config::ModuleConfig,
    state: Mutex<State>,
}

fn run_nmcli() -> Result<String, String> {
    let cmd = "nmcli";
    let args = "-c no -g IN-USE,SSID,SIGNAL,BARS dev wifi".split(" ");
    let output = std::process::Command::new(cmd)
        .args(args)
        .output()
        .map_err(|e| format!("Failed to run nmcli: {}", e))?;

    if !output.status.success() {
        return Err(format!(
            "nmcli failed with status code {}",
            output.status.code().unwrap_or(-1)
        ));
    }

    Ok(String::from_utf8(output.stdout).unwrap())
}

fn subst_placeholders(fmt: &str, html_escape: bool, state: &State) -> String {
    subst_placeholders!(fmt, html_escape, {
        "name" => {
            match &state.name {
                None => "No wi-fi",
                Some(name) => name,
            }
        },
        "signal" => {
            match &state.signal {
                None => "".to_owned(),
                Some(signal) => " ".to_owned() + signal + "%",
            }
        },
        "bars" => {
            match &state.bars {
                None => "".to_owned(),
                Some(bars) => " ".to_owned() + bars,
            }
        },
    })
}

fn refresh_state(state: &mut State, fmt_str: &str, html_escape: bool) {
    if let Ok(output) = run_nmcli() {
        state.name = None;
        state.signal = None;
        state.bars = None;
        if let Some(line) = output.lines().find(|line| line.starts_with("*")) {
            let mut parts = line.split(":");
            parts.next();
            state.name = Some(parts.next().unwrap().to_string());
            state.signal = Some(parts.next().unwrap().to_string());
            state.bars = Some(parts.next().unwrap().to_string());
        }
    }
    state.cached_text = subst_placeholders(fmt_str, html_escape, state);
}

impl BarModuleFn for BarModuleNmcli {
    fn create(config: config::ModuleConfig) -> Box<dyn BarModuleFn>
    where
        Self: Sized,
    {
        Box::new(BarModuleNmcli {
            config,
            state: Mutex::new(State {
                cached_text: String::new(),
                signal: None,
                name: None,
                bars: None,
            }),
        })
    }

    fn default_config(instance: String) -> config::ModuleConfig
    where
        Self: Sized,
    {
        config::ModuleConfig {
            name: NAME.to_owned(),
            instance,
            format: "📡 Wi-fi: {name}{bars}{signal}".to_owned(),
            html_escape: Some(false),
            on_click: None,
        }
    }

    fn get_config(&self) -> &config::ModuleConfig {
        &self.config
    }

    fn build(&self, nai: &Option<super::NameInstanceAndReason>) -> s::Block {
        let mut state = self.state.lock().expect("Could not lock state.");

        if self.should_refresh(nai, true, &[RefreshReason::ClickEvent]) {
            refresh_state(
                &mut state,
                &self.config.format,
                self.config.is_html_escape(),
            );
        }

        s::Block {
            name: Some(NAME.to_owned()),
            instance: Some(self.config.instance.clone()),
            full_text: state.cached_text.to_owned(),
            align: Some(s::Align::Left),
            markup: Some(s::Markup::Pango),
            short_text: None,
            color: None,
            background: None,
            border: None,
            border_top: None,
            border_bottom: None,
            border_left: None,
            border_right: None,
            min_width: None,
            urgent: None,
            separator: Some(true),
            separator_block_width: None,
        }
    }

    fn subst_args<'a>(&'a self, cmd: &'a [String]) -> Option<Vec<String>> {
        let state = self.state.lock().expect("Could not lock state.");
        Some(
            cmd.iter()
                .map(|arg| subst_placeholders(arg, false, &state))
                .collect(),
        )
    }
}

Re: [PATCH swayr 0/1] Add wifi module

Details
Message ID
<875yg5awv2.fsf@gnu.org>
In-Reply-To
<87fsf9jdze.fsf@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Karl Eklund <localpart@gmail.com> writes:

Hi Karl,

> Please ignore the previous message. It is not the right commit. It
> only contained my first commit. I did something wrong when rebasing.
>
> Here is the proper one. The branch is called nmcli now.

Merged and released as swayrbar-0.3.0-beta.0.

Thank you,
Tassilo
Reply to thread Export thread (mbox)