diff options
Diffstat (limited to 'bin/hornet/status')
-rwxr-xr-x | bin/hornet/status | 276 |
1 files changed, 0 insertions, 276 deletions
diff --git a/bin/hornet/status b/bin/hornet/status deleted file mode 100755 index 5674876..0000000 --- a/bin/hornet/status +++ /dev/null @@ -1,276 +0,0 @@ -#!/usr/bin/env perl -use strict; -use warnings; -use 5.010; - -use IO::Select; -use IO::Socket::UNIX; -use JSON::PP; - -my $i3status = get_i3status_handle(); -my $ipc = get_ipc_handle(); -$|++; -say "[]"; - -my $select = IO::Select->new; -$select->add($i3status); -$select->add($ipc); - -my $current_data; - -while (my @ready = $select->can_read) { - for my $fh (@ready) { - if ($fh == $i3status) { - handle_i3status(scalar <$fh>); - } - elsif ($fh == $ipc) { - handle_ipc(receive_ipc_message($fh)); - } - else { - die "???"; - } - } -} - -sub get_i3status_handle { - open my $i3status, '-|', 'i3status'; - - print scalar(<$i3status>); - print scalar(<$i3status>); - - return $i3status; -} - -sub handle_i3status { - $_ = shift; - s/^,//; - - my $data = decode_json($_); - - my %line = map { $_->{name} => $_ } @$data; - my $line = [ - grep { - $_->{name} eq 'wireless' || $_->{name} eq 'ethernet' - ? $_->{instance} ne $_->{full_text} - : $_->{name} ne 'load' - } @$data - ]; - - my %discharge_rate; - my %battery_index; - - my $index = 0; - for my $item (@$line) { - if ($item->{name} eq 'wireless' || $item->{name} eq 'ethernet') { - my $iface = $item->{instance}; - my ($up, $down) = map { net_rate($iface, $_) } 'rx', 'tx'; - my $rate = sprintf("%6s/%6s", map { human_bytes($_) } $up, $down); - $item->{full_text} =~ s{^($iface:)}{$1 $rate}; - $item->{color} = - $up + $down >= 512000 ? '#FF0000' - : $up + $down >= 51200 ? '#FFFF00' - : $up + $down >= 5120 ? '#00FF00' - : '#FFFFFF'; - } - if ($item->{name} eq 'cpu_usage') { - my ($val) = $line{load}{full_text} * 100 / ncpu(); - $item->{color} = - $val >= 50 ? '#FF0000' - : $val >= 25 ? '#FFFF00' - : $val >= 5 ? '#00FF00' - : '#FFFFFF'; - } - if ($item->{name} eq 'battery') { - my ($state, $val) = $item->{full_text} =~ /(\w+) (\d+(?:\.\d+))%/; - my ($rate) = $item->{full_text} =~ /\(.* (.*)W\)/; - $rate *= -1 if defined($rate) && $state ne 'BAT'; - $rate //= 0; - - $discharge_rate{$item->{instance}} = $rate; - $battery_index{$item->{instance}} = $index; - - $item->{full_text} =~ s/\((.*) (.*)W\)/\($1\)/; - $item->{full_text} =~ s/ \(\)//; - $item->{color} = - !defined($val) ? '#FFFFFF' - : $val >= 80 ? '#00FF00' - : $state ne 'BAT' ? '#FFFFFF' - : $val >= 40 ? '#FFFFFF' - : $val >= 15 ? '#FFFF00' - : $val >= 5 ? '#CD0000' - : '#FF0000'; - } - $index++; - } - - my @batteries = sort { $battery_index{$b} <=> $battery_index{$a} } - keys %battery_index; - for my $battery (@batteries) { - next unless $discharge_rate{$battery}; - splice @$line, $battery_index{$battery} + 1, 0, { - name => 'battery_discharge', - full_text => sprintf("%0.2fW", $discharge_rate{$battery}), - color => ( - $discharge_rate{$battery} < 6 ? '#FFFFFF' - : $discharge_rate{$battery} < 10 ? '#00FF00' - : $discharge_rate{$battery} < 14 ? '#FFFF00' - : '#FF0000' - ), - }; - } - - my $weather_file = "$ENV{HOME}/.cache/weather"; - if (-r $weather_file && -f $weather_file) { - my $weather = slurp($weather_file); - chomp($weather); - my ($temp) = $weather =~ /\d+%.*?(-?\d+)C.*?-?\d+C/; - unshift @$line, { - name => 'weather', - full_text => $weather, - color => ( - $temp >= 30 ? '#FF0000' - : $temp >= 25 ? '#FFFF00' - : $temp >= 20 ? '#00FF00' - : $temp >= 10 ? '#FFFFFF' - : $temp >= 0 ? '#CDCDFF' - : '#0000FF' - ), - }; - } - - chomp(my $brightness = `backlight get`); - $brightness = sprintf("%3d", $brightness); - splice @$line, -1, 0, { - name => 'brightness', - full_text => "\N{WHITE SUN WITH RAYS} $brightness%", - color => '#FFFFFF' - }; - - chomp(my $volume = `volume get`); - if ($volume eq 'mute') { - splice @$line, -1, 0, { - name => 'volume', - full_text => "\N{SPEAKER} ", - color => '#FFFFFF' - }; - } - else { - $volume = sprintf("%3d", $volume); - splice @$line, -1, 0, { - name => 'volume', - full_text => "\N{SPEAKER WITH THREE SOUND WAVES} $volume%", - color => '#FFFFFF' - }; - } - - $current_data = $line; - - show_status(); -} - -sub get_ipc_handle { - chomp(my $path = qx(i3 --get-socketpath)); - - my $sock = IO::Socket::UNIX->new(Peer => $path); - $sock->write(format_ipc_message(2, q{["window", "workspace"]})); - my ($type, $payload) = receive_ipc_message($sock); - die "Couldn't subscribe: ($type) $payload" - unless $type == 2 && decode_json($payload)->{success}; - - return $sock; -} - -sub handle_ipc { - my ($type, $payload) = @_; - show_status(); -} - -sub format_ipc_message { - my ($type, $payload) = @_; - my $len = do { use bytes; length($payload) }; - return "i3-ipc" . pack("LL", $len, $type) . $payload; -} - -sub receive_ipc_message { - my ($sock) = @_; - - $sock->read(my $magic, 6); - die "unknown response: $magic" unless $magic eq 'i3-ipc'; - $sock->read(my $len, 4); - $len = unpack("L", $len); - $sock->read(my $type, 4); - $type = unpack("L", $type); - $sock->read(my $payload, $len); - - return ($type, $payload); -} - -sub show_status { - my @line = @$current_data; - unshift @line, { name => 'title', full_text => get_title() }; - say "," . encode_json(\@line); -} - -sub get_title { - my $node = find(decode_json(`i3-msg -t get_tree`)); - if ($node->{window}) { - return $node->{name}; - } - else { - return '-none-'; - } -} - -sub find { - my ($t) = @_; - if ($t->{focused}) { - return $t; - } - - for my $subtree (@{ $t->{nodes} }, @{ $t->{floating_nodes} }) { - my $found = find($subtree); - return $found if $found; - } - - return; -} - -{ - my %last_bytes; - sub net_rate { - my ($iface, $which) = @_; - my $stat_file = "/sys/class/net/$iface/statistics/${which}_bytes"; - chomp(my $bytes = slurp($stat_file)); - my $prev = $last_bytes{$iface}{$which}; - $last_bytes{$iface}{$which} = $bytes; - return 0 unless defined $prev; - return $bytes - $prev; - } -} - -sub ncpu { - scalar grep { !/^#/ } `lscpu -p=cpu` -} - -sub human_bytes { - my ($bytes) = @_; - my @prefixes = ('', qw(k M G T)); - my $prefix_index = 0; - while ($bytes > 512) { - $bytes /= 1024; - $prefix_index++; - } - my $prec = ($prefix_index == 0 ? 0 : 1); - return sprintf("%0.${prec}f%sB", $bytes, $prefixes[$prefix_index]); -} - -sub slurp { - open my $fh, '<:encoding(UTF-8)', $_[0] or die "Couldn't open $_[0]: $!"; - if (wantarray) { - <$fh> - } - else { - local $/; - <$fh> - } -} |