diff options
author | Guillermo Ramos | 2025-09-07 16:02:16 +0200 |
---|---|---|
committer | Guillermo Ramos | 2025-09-08 00:27:57 +0200 |
commit | a6da875f34b04590151411fd7a53ff6fad887423 (patch) | |
tree | deb040e690d4a7547408532e80006705fce29a06 /capibarra | |
parent | 5ab8b74a54bde4bc9ec472fe4c5ab8578796c6a3 (diff) | |
download | cli-a6da875f34b04590151411fd7a53ff6fad887423.tar.gz |
Add capibarra (sway status bar)
Diffstat (limited to 'capibarra')
-rwxr-xr-x | capibarra | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/capibarra b/capibarra new file mode 100755 index 0000000..90189c1 --- /dev/null +++ b/capibarra @@ -0,0 +1,160 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use feature 'signatures'; + +use Time::HiRes qw<gettimeofday>; + +# Turn off buffering +$| = 1; + + +################################################################################ +# Formatting + +sub pango_warning($txt, $enabled) { + return $enabled ? "<span background='red'>$txt</span>" : $txt; +} + +sub pango_onoff($txt, $on) { + return $on ? $txt : "<span strikethrough='true'>$txt</span>"; +} + +sub render_iface($is_wireless, $name, $status, $addr) { + my $extra = ''; + $extra .= " $addr" if $addr; + if ($is_wireless) { + my ($ssid) = `iw dev $name link` =~ /SSID: ([^\n]*).*/; + my ($dbm) = `iw dev $name link` =~ /signal: ([0-9-]+ dBm)/; + $extra .= ' (' . $ssid . ', ' . $dbm . ')'; + } + return pango_onoff($is_wireless eq 1 ? '๐' : '๐', $status eq 'UP') . $extra; +} + + +################################################################################ +# Profiling + +sub show_time_delta($section, $time0, $computed) { + my (undef, $time) = gettimeofday(); + my $diff = ($time - $time0) / 1000; + my $extra = $computed ? ' (COMPUTED)' : ''; + printf STDERR "Spent $diff milliseconds @ $section$extra\n"; +} + + +################################################################################ +# Modules + +open(my $loadf, '<', '/proc/loadavg'); +my %mod_cpu = ( + name => 'CPU', + period => 5, + compute => sub { + read($loadf, my $loads, 14); + seek($loadf, 0, 0); + return sprintf ("CPU %s/%s/%s", split ' ', $loads); + } +); + +my %mod_mem = ( + name => 'MEMORY', + period => 5, + compute => sub { + my $mused = `free | awk '/^Mem:/ {printf("%d", 100 * (\$3/\$2))}'`; + return pango_warning(sprintf("MEM %s%%", $mused), $mused > 90); + } +); + +my %mod_net = ( + name => 'NETWORK', + period => 4, + compute => sub { + my @wired = (); + my @wireless = (); + for (split("\n", `ip --br a`)) { + next if substr($_, 0, 2) eq 'lo'; # prevent regex + my ($if, $status, $addr) = $_ =~ /^(\S+)\s+(\S+)(?:\s+(\S+))?/; + push @wired, [0, $if, $status, $addr] if (substr($if, 0, 2) eq 'en'); + push @wireless, [1, $if, $status, $addr] if (substr($if, 0, 2) eq 'wl'); + } + return join ' | ', map { render_iface(@$_) } @wired, @wireless; + } +); + +my $BATDIR = glob '/sys/class/power_supply/BAT?'; +open(my $bcapf, '<', "$BATDIR/capacity"); +open(my $bstatf, '<', "$BATDIR/status"); +my %mod_bat = ( + name => 'BATTERY', + period => 3, + compute => sub { + my $batcharging = <$bstatf> eq "Charging\n" ? 'โก' : ''; + seek($bstatf, 0, 0); + my $batlevel = <$bcapf>; + chomp $batlevel; + seek($bcapf, 0, 0); + return pango_warning(sprintf("๐%s%s", $batlevel, $batcharging), $batlevel < 10); + } +); + +my %mod_audio = ( + name => 'AUDIO', + period => 2, + compute => sub { + return sprintf "%s%s", + pango_onoff('๐', do {`volctl vol-on`; $? == 0}), + pango_onoff('๐ค', do {`volctl mic-on`; $? == 0}); + } +); + +my %mod_date = ( + name => 'DATE', + period => 2, + compute => sub { + my $date = `date +'%Y-%m-%d %H:%M'`; + chomp $date; + return $date; + } +); + +################################################################################ +# Main + +my @mods = (\%mod_cpu, \%mod_mem, \%mod_net, \%mod_bat, \%mod_audio, \%mod_date); +my %cache; + +my $profile = 0; +foreach my $arg (@ARGV) { + if ($arg eq '--profile') { + $profile = 1; + } +} + +my $counter = 0; +while (1) { + my @sections; + + my (undef, $time0) = gettimeofday() if $profile; + foreach my $mod (@mods) { + my (undef, $time) = gettimeofday() if $profile; + my $result; + if ($counter % $mod->{period} == 0) { + $result = &{$mod->{compute}}; + $cache{$mod->{name}} = $result; + } else { + $result = $cache{$mod->{name}}; + } + push(@sections, $result); + show_time_delta($mod->{name}, $time, $counter % $mod->{period} == 0) if $profile; + } + show_time_delta('TOTAL', $time0, 0) if $profile; + + printf("%s\n", join(' ยท ', @sections)); + + $counter += 1; + sleep 1; +} + +# vim: set sw=4 |