0

The following is a code adapted from this link for getting the weather and displaying on i3blocks.

#!/bin/bash 

METRIC=1 #Should be 0 or 1; 0 for F, 1 for C

if [ -z $1 ]; then
    echo
    echo "USAGE: weather.sh <locationcode>"
    echo
    exit 0;
fi

curl -s http://rss.accuweather.com/rss/liveweather_rss.asp\?metric\=${METRIC}\&locCode\=$1 | perl -ne 'use utf8;

if ( /Currently/ ) {

    chomp;
    /\<title\>Currently: (.*)?\<\/title\>/;

    my @values  = split(":", $1); 
    my $deg     = "°C";
    my @values2 = split("C", $values[1]);

    if ( $values[0] eq "Sunny" || $values[0] eq "Mostly Sunny" || $values[0] eq "Partly Sunny" || $values[0] eq "Intermittent Clouds" || $values[0] eq "Hazy Sunshine" || $values[0] eq "Hazy Sunshine" || $values[0] eq "Hot") {
        my $sun = "";
        binmode(STDOUT, ":utf8");
        print "$sun";
    }

    if ( $values[0] eq "Mostly Cloudy" || $values[0] eq "Cloudy" || $values[0] eq "Dreary (Overcast)" || $values[0] eq "Fog" ) {
        my $cloud = "";
        binmode(STDOUT, ":utf8");
        print "$cloud";
    }

    if ( $values[0] eq "Showers" || $values[0] eq "Mostly Cloudy w/ Showers" || $values[0] eq "Partly Sunny w/ Showers" || $values[0] eq "T-Storms"|| $values[0] eq "Mostly Cloudy w/ T-Storms"|| $values[0] eq "Partly Sunny w/ T-Storms"|| $values[0] eq "Rain" ) {
        my $rain = "";
        binmode(STDOUT, ":utf8");
        print "$rain";
    }

    if ( $values[0] eq "Windy" ) {
        my $wind = "";
        binmode(STDOUT, ":utf8");
        print "$wind";
    }

    if ( $values[0] eq "Flurries" || $values[0] eq "Mostly Cloudy w/ Flurries" || $values[0] eq "Partly Sunny w/ Flurries"|| $values[0] eq "Snow"|| $values[0] eq "Mostly Cloudy w/ Snow"|| $values[0] eq "Ice"|| $values[0] eq "Sleet"|| $values[0] eq "Freezing Rain"|| $values[0] eq "Rain and Snow"|| $values[0] eq "Cold" ) {
        my $snow = "";
        binmode(STDOUT, ":utf8");
        print "$snow";
    }

    if ( $values[0] eq "Clear" || $values[0] eq "Mostly Clear" || $values[0] eq "Partly Cloudy"|| $values[0] eq "Intermittent Clouds"|| $values[0] eq "Hazy Moonlight"|| $values[0] eq "Mostly Cloudy"|| $values[0] eq "Partly Cloudy w/ Showers"|| $values[0] eq "Mostly Cloudy w/ Showers"|| $values[0] eq "Partly Cloudy w/ T-Storms"|| $values[0] eq "Mostly Cloudy w/ Flurries" || $values[0] eq "Mostly Cloudy w/ Snow" ) {
        my $night = "";
        binmode(STDOUT, ":utf8");
        print "$night";
    }

    binmode(STDOUT, ":utf8");
    print  "$values2[0]$deg"; 
}'

(The text that might look like boxes are from the fontawesome font). All I added was the following lines

my $deg = "°C";
my @values2 = split("C",$values[1]);

and modified the last print statement which was originally print "$values[1]". The old print statement shows the temperature without a degree sign like 35C. My intention was just to add the degree in between like 35°C but the output is

35°C°C

Why is the substring printed twice? This happens even if I include it in a separate print statement or include the substring directly (print $values2[0]°C).

Oddly, including the value and unit in the inner blocks such as print "$sun$values2[0]$deg"; seems to work fine without duplication.

Borodin
  • 126,100
  • 9
  • 70
  • 144
Ébe Isaac
  • 11,563
  • 17
  • 64
  • 97
  • Your code has syntax errors when run with `use strict`. For snow, there's a copy/paste error because the variable is called `$rain`. When I run the program with just one line (`$_ = 'Currently: Sunny';`) I can't reproduce your problem. I tried will a value for each of the `if` blocks. It must be your input. Probably the RSS feed contains the trigger word twice. Please [edit] and include the input. – simbabque May 23 '18 at 09:59
  • Add the `use strict` and `use warnings` pragmas next to the `use utf8` pragma. You'll see two problems popping up. One is the wrong variable name, the other is related to the array. I didn't investigate them because I don't have the real input. – simbabque May 23 '18 at 10:06
  • Tell us the `locCode` so we can open the URL. – simbabque May 23 '18 at 10:08
  • @simbabque. The `locCode` is `"ASI|IN|IN031|MADRAS"` – Ébe Isaac May 23 '18 at 10:11
  • @simbabque About the `$rain`, there seems to be a bug in the code. Its second occurrence should be `$snow` (made the bug fix in the edit). – Ébe Isaac May 23 '18 at 10:19

1 Answers1

1

The script works by looking for the <title> tag in the RSS. If you do that manually, you'll see there are several.'

curl -s 'http://rss.accuweather.com/rss/liveweather_rss.asp?metric=1&locCode=ASI|IN|IN031|MADRAS' | grep title
<title>Madras, IN - AccuWeather.com Forecast</title>
            <title>Madras, IN - AccuWeather.com Forecast</title>
            <title>Currently: Partly Sunny: 35C</title> 
                <title>5/23/2018 Forecast</title>
                <title>5/24/2018 Forecast</title>
<title>The AccuWeather.com RSS Center</title>

If you add

use strict;
use warnings;

you will get a ton of warnings about variables being undefined. That's because it doesn't find a match for title with that pattern, but it still prints.

  if (/Currently/) {
    chomp;
    /\<title\>Currently: (.*)?\<\/title\>/;

    # ....
    print "$values2[0]$deg";
  }

That's also why you get the additional output.

You need to skip the line if there is no match.

/\<title\>Currently: (.*)?\<\/title\>/ or next;
Borodin
  • 126,100
  • 9
  • 70
  • 144
simbabque
  • 53,749
  • 8
  • 73
  • 136
  • Thank you so much! It is still so strange why one variable is printed twice while the other remains intact. You're right. I can only see it with the additional pragmas. – Ébe Isaac May 23 '18 at 10:26
  • 1
    In fact the test in the outermost `if` should be `/Currently: (.*)?<\/title>/`—there's no point in checking it twice. – Borodin May 23 '18 at 10:28
  • @Borodin yes, you're correct. And on top of that there is way too much escaping going on in the pattern. Another sign that the author of that code didn't really know what they were doing. :-/ – simbabque May 23 '18 at 11:05
  • The optional `(.*)?` is also very suspect. – Borodin May 23 '18 at 11:07
  • On a different note, why not just look out the window to get the weather? I've never understood why I would need a tool that tells me only the weather right now in the place where I am. Seeing a forecast, yes. But for a snapshot of right now I would just turn my head and take a loot outside. :D – simbabque May 23 '18 at 11:13