You are not logged in.

#1 2010-04-27 09:45:27

demian
Member
From: Frankfurt, Germany
Registered: 2009-05-06
Posts: 709

weather function

Hi everyone,

i thought you might be interested in a simple function that shows weather information about a specific city:

weather() { # shows weather information
if [ $# -eq 0 ]; then
echo "weather(): shows weather information, "
echo "Usage: weather <City>"
fi
declare -a temp weather wind date humidity
temp=(`curl -silent "http://www.google.com/ig/api?weather=$1+$2+$3" | grep -o 'temp_c data="[0-9]*"' | grep -o "[0-9]*"`)
weather=(`curl -silent "http://www.google.com/ig/api?weather=$1+$2+$3" | grep -o 'condition data=\"[A-Z].*\"/><temp_f' | grep -o '[A-Z][a-z]*'`)
wind=(`curl -silent "http://www.google.com/ig/api?weather=$1+$2+$3" | grep -o 'wind_condition data=".*mph"' | grep --color=never -o "[A-Z].*mph"`)
date=(`curl -silent "http://www.google.com/ig/api?weather=$1+$2+$3" | grep -o 'current_date_time data=".*000"' | grep --color=never -o '20.*:[0-9]*'`)
humidity=(`curl -silent "http://www.google.com/ig/api?weather=$1+$2+$3" | grep -o 'humidity data=\"Humidity:.*%' | grep --color=never -o '[0-9]*'`)
echo Temperature: $temp°C
echo Weather: $weather
echo $wind
echo Humidity: $humidity%
echo Date: $date
}
> weather Rio de Janeiro
Temperature: 26°C
Weather: Clear
Wind: N at 8 mph
Humidity: 83%
Date: 2010-04-27 09:00:00

It's very dirty, but does its job for me.

Since I'm also grateful to learn new things I'm open to all suggestions. For instance, the queried .xml contains forecast information but I'm having trouble containing it with grep and my limited knowledge of regular expressions.

Regards,
demian

Last edited by demian (2010-04-27 10:00:36)


no place like /home
github

Offline

#2 2010-04-27 12:04:31

kazuo
Member
From: São Paulo/Brazil
Registered: 2008-03-18
Posts: 413
Website

Re: weather function

Uhh, some sugestions.

First declare the language used (I think is bash).

Second I think that the $1+$2+$3 is ugly, what about joinging the $@ array? bash can do that (i think), in zsh it is really simple only change the $1+... to

${(j:+:)@}

Third what about parsing the xml? I think this is a lot better then using grep. (EDIT google search can give a lot more info, but I found xml2 (it is in aur) looks like a good one, ofcourse you can use something more portable, i.e. already installed on many systems e.g. xmllint(more on it bellow))

EDIT:
Fourth call curl only one time and save it to a var, a lot more fast and bandwidth friendly (and you solve inconsistencies too)

Five when posting time convert from the timezone to the user timezone (or report the timezone)

xmllint (avaliable on libxml2): for example to get the temp you can use

wget -q -O - htpp://.....|xmllint --xpath '/xml_api_reply/weather/current_conditions/temp_c' -

You need to make the curl only send the actual data and not the headers (wget do this by default, I too lazy to look at curl man page, sorry)

Another example to get the first forecast condition (e.g. chance of storm) you can use

xmllint --xpath '/xml_api_reply/weather/forecast_conditions[1]/condition' -

Last edited by kazuo (2010-04-27 12:42:12)

Offline

#3 2010-04-27 13:13:55

Profjim
Member
From: NYC
Registered: 2008-03-24
Posts: 658

Re: weather function

Thanks for sharing. Here are some improvements: specifically, curl from the website only once, allow city names with arbitrary number of spaces.

Why do you create arrays but then only use the first entry?

weather() { # shows weather information
    if [ $# -eq 0 ]; then
        echo "weather(): shows weather information, "
        echo "Usage: weather <City>"
    fi
    declare -a temp weather wind date humidity
    local city="$*"
    curlonce=$(curl -silent "http://www.google.com/ig/api?weather=${city// /+}")
    temp=(`echo "$curlonce" | grep -o 'temp_c data="[0-9]*"' | grep -o "[0-9]*"`)
    weather=(`echo "$curlonce" | grep -o 'condition data=\"[A-Z].*\"/><temp_f' | grep -o '[A-Z][a-z]*'`)
    wind=(`echo "$curlonce" | grep -o 'wind_condition data=".*mph"' | grep --color=never -o "[A-Z].*mph"`)
    date=(`echo "$curlonce" | grep -o 'current_date_time data=".*000"' | grep --color=never -o '20.*:[0-9]*'`)
    humidity=(`echo "$curlonce" | grep -o 'humidity data=\"Humidity:.*%' | grep --color=never -o '[0-9]*'`)
    echo Temperature: $temp°C
    echo Weather: $weather
    echo $wind
    echo Humidity: $humidity%
    echo Date: $date
}

Last edited by Profjim (2010-04-27 13:14:21)

Offline

#4 2010-04-27 16:55:33

demian
Member
From: Frankfurt, Germany
Registered: 2009-05-06
Posts: 709

Re: weather function

Done. You need curl and libxml to make full use of the function.

weatherin() { # shows weather information
if [ $# -eq 0 ]; then
echo "Usage: weatherin <City>" ; return 0
fi
local city="$*"
#curlde=$(curl -s "http://www.google.de/ig/api?weather=${city// /+}" | iconv - -f latin1 -t utf8)
curlen=$(curl -s "http://www.google.com/ig/api?weather=${city// /+}")
f4day=(`echo "$curlen" | xmllint --xpath '/xml_api_reply/weather/forecast_conditions[4]/day_of_week' - | grep -o '[A-Z][a-z]'`)
f4cond=(`echo "$curlen" | xmllint --xpath '/xml_api_reply/weather/forecast_conditions[4]/condition' - | grep -o '"[A-Z].*[a-z]"' | tr -d '"'`)
f4low=(`echo "$curlen" | xmllint --xpath '/xml_api_reply/weather/forecast_conditions[4]/low' - | grep -o '[0-9]*'`)
f4high=(`echo "$curlen" | xmllint --xpath '/xml_api_reply/weather/forecast_conditions[4]/high' - | grep -o '[0-9]*'`)
echo $f4day.:
echo Sky: $f4cond
echo Lowest: $f4low°F, Highest:$f4high°F
f3day=(`echo "$curlen" | xmllint --xpath '/xml_api_reply/weather/forecast_conditions[3]/day_of_week' - | grep -o '[A-Z][a-z]'`)
f3cond=(`echo "$curlen" | xmllint --xpath '/xml_api_reply/weather/forecast_conditions[3]/condition' - | grep -o '"[A-Z].*[a-z]"' | tr -d '"'`)
f3low=(`echo "$curlen" | xmllint --xpath '/xml_api_reply/weather/forecast_conditions[3]/low' - | grep -o '[0-9]*'`)
f3high=(`echo "$curlen" | xmllint --xpath '/xml_api_reply/weather/forecast_conditions[3]/high' - | grep -o '[0-9]*'`)
echo 
echo $f3day.:
echo Sky: $f3cond
echo Lowest: $f3low°F, Highest: $f3high°F
f2day=(`echo "$curlen" | xmllint --xpath '/xml_api_reply/weather/forecast_conditions[2]/day_of_week' - | grep -o '[A-Z][a-z]'`)
f2cond=(`echo "$curlen" | xmllint --xpath '/xml_api_reply/weather/forecast_conditions[2]/condition' - | grep -o '"[A-Z].*[a-z]"' | tr -d '"'`)
f2low=(`echo "$curlen" | xmllint --xpath '/xml_api_reply/weather/forecast_conditions[2]/low' - | grep -o '[0-9]*'`)
f2high=(`echo "$curlen" | xmllint --xpath '/xml_api_reply/weather/forecast_conditions[2]/high' - | grep -o '[0-9]*'`)
echo 
echo Day After Tomorrow, $f2day.:
echo Sky: $f2cond
echo Lowest: $f2low°F, Highest: $f2high°F
f1day=(`echo "$curlen" | xmllint --xpath '/xml_api_reply/weather/forecast_conditions[1]/day_of_week' - | grep -o '[A-Z][a-z]'`)
f1cond=(`echo "$curlen" | xmllint --xpath '/xml_api_reply/weather/forecast_conditions[1]/condition' - | grep -o '"[A-Z].*[a-z]"' | tr -d '"'`)
f1low=(`echo "$curlen" | xmllint --xpath '/xml_api_reply/weather/forecast_conditions[1]/low' - | grep -o '[0-9]*'`)
f1high=(`echo "$curlen" | xmllint --xpath '/xml_api_reply/weather/forecast_conditions[1]/high' - | grep -o '[0-9]*'`)
echo 
echo Tomorrow, $f1day.:
echo Sky: $f1cond
echo Lowest: $f1low°F, Highest: $f1high°F
curtemp=(`echo "$curlen" | grep -o 'temp_c data="[-0-9]*"' | grep -o "[-0-9]*"`)
curcond=(`echo "$curlen" | grep -o 'condition data=\"[A-Z].*[a-z]*\"/><temp_f' | grep -o '[A-Z].*[a-z]"' | tr -d '"'`)
curwind=(`echo "$curlen" | grep -o 'wind_condition data=".*mph"' | grep --color=never -o "[A-Z].*mph"`)
#curdate=(`echo "$curlen" | grep -o 'current_date_time data=".*000"' | grep --color=never -o '20.*:[0-9]*'`)
curhumi=(`echo "$curlen" | grep -o 'humidity data="Humidity:.*%' | grep -o 'H.*%'`)
echo 
echo Today:
echo Temperature: $curtemp°C
echo Sky: $curcond
echo $curwind
echo $curhumi
#echo Date: $curdate
}

Output:

> weatherin New York                                              [~] 20:48:28
Fr.:
Sky: Sunny
Lowest: 58°F, Highest:75°F

Th.:
Sky: Partly Cloudy
Lowest: 49°F, Highest: 67°F

Day After Tomorrow, We.:
Sky: Scattered Showers
Lowest: 43°F, Highest: 57°F

Tomorrow, Tu.:
Sky: Scattered Showers
Lowest: 39°F, Highest: 56°F

Today:
Temperature: 14°C
Sky: Partly Cloudy
Wind: NW at 20 mph
Humidity: 48%

I have not yet found a way to convert Fahrenheit to Celsius within the function so personally i will change the mirror back to google.de.
I hope this function works for you.

Regards,
demian

Last edited by demian (2010-04-28 13:04:38)


no place like /home
github

Offline

Board footer

Powered by FluxBB