aboutsummaryrefslogtreecommitdiff
path: root/capibarra
diff options
context:
space:
mode:
Diffstat (limited to 'capibarra')
-rwxr-xr-xcapibarra160
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