Monday 28 December 2015

Perl script for my I3 Status Bar

I decided to roll out mu own little script to handle my I3 window manager status bar.  It's a good way to get back into a bit of Perl.
I also wanted to roll out my own little JSON formatter.  I did not feel to need to go with what ever Perl module offers.  Still some fine tuning required.  It crashes when a song title contains a double quote.

#!/usr/bin/perl 
use strict;

sub toJSON{
    my $retval, my $left, my $right;
    my $sep;
    while ( $left = shift){
        if ($left eq "text"){
            $left = "full_text";
        } 
        $right = shift;
        $retval = $retval . $sep. qq/"$left":"$right"/;
        $sep=",";
    }
    return "{".$retval ."}"; 
}

sub getvol{
    my $vol = 0;
    $vol=`mixerctl outputs.master`; #outputs.master=150,150
    $vol =~ /=(\d+),/;
    return sprintf ("%.0f",$1/2.55);
}

sub getdate{
    my @months = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
    my @days = qw(Sun Mon Tue Wed Thu Fri Sat Sun);
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
    return sprintf("%s %s %s, %02d:%02d:%02d", @days[$wday], $mday, @months[$mon], $hour, $min, $sec);
}

sub getsong{
    my $retval = `/usr/local/bin/mpc current`;
    chomp($retval);
    return $retval;
}

sub display{
    my $song_, my $date_, my $vol_, my $weather_;
    $song_ = toJSON("text", getsong(), "color", "#808000");
    $vol_ =  toJSON("text", "Vol:".getvol()."%");
    $date_ = toJSON("text", getdate(), "color", "#9060f0");
    $weather_ = toJSON("text", checkweather(), "color", "#009000");
    printf ("[%s,%s,%s,%s],", $song_ , $vol_ , $weather_, $date_);
}

sub checkweather{
    my $epoch_ = time();
    my $filename = "/tmp/tmp.xml";
    my $fileage = time() - (stat($filename))[9];
    if ($fileage > 3600){ #Time to refresh weather data
        system("ftp -o /tmp/tmp.xml http://weather.gc.ca/rss/city/qc-126_e.xml");
    }
my $temperature="No data";
my $condition, my $pressure, my $humididy, my $windchill, my $dewpoint, my $windspeed;
    my $overnightcondition;
    my $titletagcount=0; #at 5th tag, get overnight conditions.
    # 0 : Gatineau
    # 1 : Warning
    # 2 : Current conditions
    # 3 : Night conditions
open(FILE,"/tmp/tmp.xml") || die "Failed: $!\n";
while ( <FILE> ) {
        if (/<title>(.*)<\/title>/ ){
            ++$titletagcount;
            #printf ("%d : %s\n", $titletagcount, $1);
            if ($titletagcount == 4 ){
                $overnightcondition=$1;
            }
        }
if (/<b>Condition:<\/b> (.*) <b/){
  $condition = $1;
        }elsif (/<b>Temperature:<\/b> (-?[\d.]+)/){
  $temperature = sprintf("%s°C", $1);
}elsif (/<b>Pressure.*<\/b> ([\d.]+)/){
$pressure = sprintf("%s kPa",$1);
}elsif (/<b>Humidity:<\/b> ([\d]+)/){
$humididy = sprintf("%s\%",$1);
}elsif (/<b>Wind:<\/b> (.*)<br/){
$windspeed = sprintf("%s",$1);
}elsif (/<b>Dewpoint:<\/b> (-?[\d.]+)/){
$dewpoint = $1;
}elsif (/<b>Wind Chill:<\/b> (.*)<br/){
$windchill = sprintf("[%s]", $1);
}
}
return sprintf("%s %s%s, Wind:%s, P:%s, RH:%s, %s", 
        $condition, $temperature, $windchill, $windspeed, $pressure, $humididy, $overnightcondition);

}

sub main{
    print '{"version":1}[';
    for(;;){
        display();
        sleep(5);
    }
}

main();

(.*)<\/title>/ ){
            ++$titletagcount;
            #printf ("%d : %s\n", $titletagcount, $1);
            if ($titletagcount == 4 ){
                $overnightcondition=$1;
            }
        }
  if (/<b>Condition:<\/b> (.*) <b/){
     $condition = $1;
        }elsif (/<b>Temperature:<\/b> (-?[\d.]+)/){
     $temperature = sprintf("%s°C", $1);
  }elsif (/<b>Pressure.*<\/b> ([\d.]+)/){
   $pressure = sprintf("%s kPa",$1);
  }elsif (/<b>Humidity:<\/b> ([\d]+)/){
   $humididy = sprintf("%s\%",$1);
  }elsif (/<b>Wind:<\/b> (.*)<br/){
   $windspeed = sprintf("%s",$1);
  }elsif (/<b>Dewpoint:<\/b> (-?[\d.]+)/){
   $dewpoint = $1;
  }elsif (/<b>Wind Chill:<\/b> (.*)<br/){
   $windchill = sprintf("[%s]", $1);
  }
 }
 return sprintf("%s %s%s, Wind:%s, P:%s, RH:%s, %s", 
        $condition, $temperature, $windchill, $windspeed, $pressure, $humididy, $overnightcondition);

}

sub main{
    print '{"version":1}[';
    for(;;){
        display();
        sleep(5);
    }
}

main();
</pre>