aboutsummaryrefslogtreecommitdiff
path: root/capibarra
diff options
context:
space:
mode:
Diffstat (limited to 'capibarra')
-rwxr-xr-xcapibarra289
1 files changed, 159 insertions, 130 deletions
diff --git a/capibarra b/capibarra
index 93efb37..413a0c7 100755
--- a/capibarra
+++ b/capibarra
@@ -13,7 +13,6 @@ use Time::HiRes qw<gettimeofday>;
# Turn off buffering
$| = 1;
-
################################################################################
# Formatting
@@ -32,18 +31,62 @@ sub color_thresholds($x, $warn, $err) {
}
}
-sub pango_warning($txt, $enabled) {
- return $enabled ? "<span background='red'>$txt</span>" : $txt;
+sub txt_onoff($txt, $on) {
+ return $on ? $txt : "${txt}X";
}
-sub pango_onoff($txt, $on) {
- return $on ? $txt : "<span strikethrough='true'>$txt</span>";
-}
+################################################################################
+# Profiling
-sub txt_onoff($txt, $on) {
- return $on ? $txt : "${txt}X";
+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
+
+my %MODS;
+
+
+##########################################
+# Linux
+
+my %linux_mods;
+
+$linux_mods{'CPU'} = {
+ period => 5,
+ init => sub {
+ open(my $loadf, '<', '/proc/loadavg');
+ return { state => $loadf };
+ },
+ compute => sub {
+ my $loadf = shift;
+ read($loadf, my $loads, 14);
+ seek($loadf, 0, 0);
+ my @loads = split ' ', $loads;
+ return {
+ text => sprintf ("CPU %s/%s/%s", @loads),
+ color => color_thresholds($loads[1], 1, 3),
+ state => $loadf,
+ };
+ }
+};
+
+$linux_mods{'MEM'} = {
+ period => 5,
+ compute => sub {
+ my $mused = `free | awk '/^Mem:/ {printf("%d", 100 * (\$3/\$2))}'`;
+ return {
+ text => sprintf("MEM %s%%", $mused),
+ color => color_thresholds($mused, 70, 90),
+ };
+ }
+};
+
sub render_iface_linux($is_wireless, $name, $status, $addr) {
my $extra = $addr ? " $addr" : '';
if ($is_wireless and $status eq 'UP') {
@@ -51,49 +94,66 @@ sub render_iface_linux($is_wireless, $name, $status, $addr) {
my ($dbm) = `iw dev $name link` =~ /signal: ([0-9-]+ dBm)/;
$extra .= ' (' . $ssid . ', ' . $dbm . ')';
}
- return pango_onoff($is_wireless ? '๐Ÿ›œ' : '๐ŸŒ', $status eq 'UP') . $extra;
+ return txt_onoff($is_wireless ? '๐Ÿ›œ' : '๐ŸŒ', $status eq 'UP') . $extra;
}
+$linux_mods{'NET'} = {
+ 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 { text => join ' | ', map { render_iface_linux(@$_) } @wired, @wireless };
+ }
+};
-
-sub render_iface_openbsd($ifaces, $ifname) {
- my $iface = $ifaces->{$ifname};
- my $extra = $iface->{'ip'} ? " $iface->{'ip'}" : '';
- my $is_wireless = exists $iface->{'wifi'};
- my $is_up = $iface->{'up'};
- if ($is_wireless and $is_up) {
- $extra .= ' (' . $iface->{'wifi_ssid'} . ', ' . $iface->{'wifi_signal'} . ')';
+$linux_mods{'BAT'} = {
+ period => 3,
+ init => sub {
+ my $BATDIR = glob '/sys/class/power_supply/BAT?';
+ open(my $bcapf, '<', "$BATDIR/capacity");
+ open(my $bstatf, '<', "$BATDIR/status");
+ return { state => [$bcapf, $bstatf] };
+ },
+ compute => sub {
+ my $state = shift;
+ my ($bcapf, $bstatf) = @$state;
+ my $batlevel = <$bcapf>;
+ chomp $batlevel;
+ seek($bcapf, 0, 0);
+ my $batcharging = <$bstatf> eq "Charging\n" ? 'โšก' : '';
+ seek($bstatf, 0, 0);
+ return {
+ text => sprintf("๐Ÿ”‹%s%s", $batlevel, $batcharging),
+ color => color_thresholds(100 - $batlevel, 70, 90),
+ state => $state,
+ };
}
- return txt_onoff($is_wireless ? '๐Ÿ“ถ' : '๐ŸŒ', $is_up) . $extra;
-}
+};
+$linux_mods{'AUDIO'} = {
+ period => 2,
+ compute => sub {
+ return { text => sprintf "%s%s",
+ txt_onoff('๐Ÿ”Š', do {`~/.local/bin/volctl vol-on`; $? == 0}),
+ txt_onoff('๐ŸŽค', do {`~/.local/bin/volctl mic-on`; $? == 0})
+ };
+ }
+};
-################################################################################
-# Profiling
+$MODS{'Linux'} = \%linux_mods;
-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";
-}
+##########################################
+# OpenBSD
-################################################################################
-# Modules
+my %openbsd_mods;
-# open(my $loadf, '<', '/proc/loadavg');
-# my %mod_cpu_linux = (
-# name => 'CPU',
-# period => 5,
-# compute => sub {
-# read($loadf, my $loads, 14);
-# seek($loadf, 0, 0);
-# return { text => sprintf ("CPU %s/%s/%s", split ' ', $loads) };
-# }
-# );
-
-my %mod_cpu_openbsd = (
- name => 'CPU',
+$openbsd_mods{'CPU'} = {
period => 5,
compute => sub {
my $loads = `sysctl -n vm.loadavg`;
@@ -104,19 +164,9 @@ my %mod_cpu_openbsd = (
color => color_thresholds($loads[1], 1, 3),
};
}
-);
-
-# my %mod_mem_linux = (
-# name => 'MEMORY',
-# period => 5,
-# compute => sub {
-# my $mused = `free | awk '/^Mem:/ {printf("%d", 100 * (\$3/\$2))}'`;
-# return { text => pango_warning(sprintf("MEM %s%%", $mused), $mused > 90) };
-# }
-# );
-
-my %mod_mem_openbsd = (
- name => 'MEMORY',
+};
+
+$openbsd_mods{'MEM'} = {
period => 5,
compute => sub {
my $uvmexp = `vmstat -s`;
@@ -128,26 +178,19 @@ my %mod_mem_openbsd = (
color => color_thresholds($mused, 70, 90),
};
}
-);
-
-# my %mod_net_linux = (
-# 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 { text => join ' | ', map { render_iface_linux(@$_) } @wired, @wireless };
-# }
-# );
-
-my %mod_net_openbsd = (
- name => 'NETWORK',
+};
+
+sub render_iface_openbsd($ifaces, $ifname) {
+ my $iface = $ifaces->{$ifname};
+ my $extra = $iface->{'ip'} ? " $iface->{'ip'}" : '';
+ my $is_wireless = exists $iface->{'wifi'};
+ my $is_up = $iface->{'up'};
+ if ($is_wireless and $is_up) {
+ $extra .= ' (' . $iface->{'wifi_ssid'} . ', ' . $iface->{'wifi_signal'} . ')';
+ }
+ return txt_onoff($is_wireless ? '๐Ÿ“ถ' : '๐ŸŒ', $is_up) . $extra;
+}
+$openbsd_mods{'NET'} = {
period => 4,
compute => sub {
my @wired = ();
@@ -179,36 +222,15 @@ my %mod_net_openbsd = (
push @wired, $ifname;
}
}
- # use Data::Dumper;
- # print Dumper(\%ifaces);
- # print Dumper(\@wired);
- # print Dumper(\@wireless);
return { text => join ' ยท ', map { render_iface_openbsd(\%ifaces, $_) } sort(@wired), @wireless };
}
-);
-
-# my $BATDIR = glob '/sys/class/power_supply/BAT?';
-# open(my $bcapf, '<', "$BATDIR/capacity");
-# open(my $bstatf, '<', "$BATDIR/status");
-# my %mod_bat_linux = (
-# name => 'BATTERY',
-# period => 3,
-# compute => sub {
-# my $batlevel = <$bcapf>;
-# chomp $batlevel;
-# seek($bcapf, 0, 0);
-# my $batcharging = <$bstatf> eq "Charging\n" ? 'โšก' : '';
-# seek($bstatf, 0, 0);
-# return { text => pango_warning(sprintf("๐Ÿ”‹%s%s", $batlevel, $batcharging), $batlevel < 10) };
-# }
-# );
+};
sub obsd_get_sysctl($mib) {
my @parts = split(' ', `sysctl -n $mib`);
return $parts[0];
}
-my %mod_bat_openbsd = (
- name => 'BATTERY',
+$openbsd_mods{'BAT'} = {
period => 3,
compute => sub {
my $batcharging = obsd_get_sysctl('hw.sensors.acpibat0.raw0') eq "0" ? 'โšก' : '';
@@ -220,21 +242,9 @@ my %mod_bat_openbsd = (
color => color_thresholds(100 - $batlevel, 70, 90)
};
}
-);
-
-# my %mod_audio_linux = (
-# name => 'AUDIO',
-# period => 2,
-# compute => sub {
-# return { text => sprintf "%s%s",
-# pango_onoff('๐Ÿ”Š', do {`volctl vol-on`; $? == 0}),
-# pango_onoff('๐ŸŽค', do {`volctl mic-on`; $? == 0})
-# };
-# }
-# );
-
-my %mod_audio_openbsd = (
- name => 'AUDIO',
+};
+
+$openbsd_mods{'AUDIO'} = {
period => 2,
compute => sub {
my $audioinfo = `sndioctl`;
@@ -245,24 +255,44 @@ my %mod_audio_openbsd = (
txt_onoff('๐ŸŽค', $micmuted == 0)
};
}
-);
+};
+
+$MODS{'OpenBSD'} = \%openbsd_mods;
-my %mod_date = (
- name => 'DATE',
+##########################################
+# Common (POSIX)
+
+my %common_mods;
+
+$common_mods{'DATE'} = {
period => 2,
compute => sub {
my $date = `date +'%Y-%m-%d %H:%M'`;
chomp $date;
return { text => $date };
}
-);
+};
+
+$MODS{'_common'} = \%common_mods;
################################################################################
# Main
-my @mods = (\%mod_cpu_openbsd, \%mod_mem_openbsd, \%mod_net_openbsd, \%mod_bat_openbsd, \%mod_audio_openbsd, \%mod_date);
+my $OS = `uname -s`;
+chomp $OS;
+my %os_mods = ( %{$MODS{$OS}}, %{$MODS{'_common'}} );
+
+my @mods = ('CPU', 'MEM', 'NET', 'BAT', 'AUDIO', 'DATE');
my %cache;
+sub render_section($result) {
+ my $color = $result->{color};
+ my $color = $color ? ",\"$color->{type}\":\"$color->{val}\"" : '';
+ return sprintf "{\"full_text\":\"%s\",\"separator\":false$color}", $result->{text};
+}
+
+my $separator = render_section({text => 'ยท'});
+
my $profile = 0;
foreach my $arg (@ARGV) {
if ($arg eq '--profile') {
@@ -272,10 +302,10 @@ foreach my $arg (@ARGV) {
printf("{ \"version\": 1 }\n[\n");
-sub render_section($result) {
- my $color = $result->{color};
- my $color = $color ? ",\"$color->{type}\":\"$color->{val}\"" : '';
- return sprintf "{\"full_text\":\"%s\",\"separator\":false$color}", $result->{text};
+# Call each module's init subroutine
+foreach my $modname (@mods) {
+ my $mod = $os_mods{$modname};
+ $cache{$modname} = &{$mod->{init}} if $mod->{init};
}
my $counter = 0;
@@ -283,21 +313,20 @@ while (1) {
my @sections;
my (undef, $time0) = gettimeofday() if $profile;
- foreach my $mod (@mods) {
+ foreach my $modname (@mods) {
+ my $mod = $os_mods{$modname};
my (undef, $time) = gettimeofday() if $profile;
- my $result;
+ my $result = $cache{$modname};
if ($counter % $mod->{period} == 0) {
- $result = &{$mod->{compute}};
- $cache{$mod->{name}} = $result;
- } else {
- $result = $cache{$mod->{name}};
+ $result = &{$mod->{compute}}($result->{state});
+ $cache{$modname} = $result;
}
push(@sections, render_section($result));
- show_time_delta($mod->{name}, $time, $counter % $mod->{period} == 0) if $profile;
+ show_time_delta($modname, $time, $counter % $mod->{period} == 0) if $profile;
}
show_time_delta('TOTAL', $time0, 0) if $profile;
- printf("[%s],\n", join(',{"full_text":"ยท","separator":false},', @sections));
+ printf("[%s],\n", join(",$separator,", @sections));
$counter += 1;
sleep 1;