From a6da875f34b04590151411fd7a53ff6fad887423 Mon Sep 17 00:00:00 2001 From: Guillermo Ramos Date: Sun, 7 Sep 2025 16:02:16 +0200 Subject: Add capibarra (sway status bar) --- capibarra | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100755 capibarra (limited to 'capibarra') 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; + +# Turn off buffering +$| = 1; + + +################################################################################ +# Formatting + +sub pango_warning($txt, $enabled) { + return $enabled ? "$txt" : $txt; +} + +sub pango_onoff($txt, $on) { + return $on ? $txt : "$txt"; +} + +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 -- cgit v1.2.3