weather.sh
1 #!/usr/bin/env bash 2 # setting the locale, some users have issues with different locales, this forces the correct one 3 export LC_ALL=C.utf8 4 5 fahrenheit=$1 6 location=$2 7 fixedlocation=$3 8 9 # emulate timeout command from bash - timeout is not available by default on OSX 10 if [ "$(uname)" == "Darwin" ]; then 11 timeout() { 12 perl -e 'alarm shift; exec @ARGV' "$duration" "$@" 13 } 14 fi 15 16 display_location() 17 { 18 if $location && [[ ! -z "$fixedlocation" ]]; then 19 echo " $fixedlocation" 20 elif $location; then 21 city=$(curl -s https://ipinfo.io/city 2> /dev/null) 22 region=$(curl -s https://ipinfo.io/region 2> /dev/null) 23 echo " $city, $region" 24 else 25 echo '' 26 fi 27 } 28 29 fetch_weather_information() 30 { 31 display_weather=$1 32 # it gets the weather condition textual name (%C), and the temperature (%t) 33 api_response=$(curl -sL wttr.in/${fixedlocation// /%20}\?format="%C+%t$display_weather") 34 35 if [[ $api_response = "Unknown location;"* ]]; then 36 echo "Unknown location error" 37 else 38 echo $api_response 39 fi 40 } 41 42 #get weather display 43 display_weather() 44 { 45 if $fahrenheit; then 46 display_weather='&u' # for USA system 47 else 48 display_weather='&m' # for metric system 49 fi 50 weather_information=$(fetch_weather_information $display_weather) 51 52 weather_condition=$(echo "$weather_information" | awk -F' -?[0-9]' '{print $1}' | xargs) # Extract condition before temperature, e.g. Sunny, Snow, etc 53 temperature=$(echo "$weather_information" | grep -oE '[-+]?[0-9]+°[CF]') # Extract temperature, e.g. +31°C, -3°F, etc 54 unicode=$(forecast_unicode $weather_condition) 55 56 # Mac Only variant should be transparent on Linux 57 if [[ "${temperature/+/}" == *"===="* ]]; then 58 temperature="error" 59 fi 60 61 if [[ "${temperature/+/}" == "error" ]]; then 62 # Propagate Error 63 echo "error" 64 else 65 echo "$unicode ${temperature/+/}" # remove the plus sign to the temperature 66 fi 67 } 68 69 forecast_unicode() 70 { 71 weather_condition=$(echo $weather_condition | awk '{print tolower($0)}') 72 73 if [[ $weather_condition =~ 'snow' ]]; then 74 echo '❄ ' 75 elif [[ (($weather_condition =~ 'rain') || ($weather_condition =~ 'shower')) ]]; then 76 echo '☂ ' 77 elif [[ (($weather_condition =~ 'overcast') || ($weather_condition =~ 'cloud')) ]]; then 78 echo '☁ ' 79 elif [[ $weather_condition = 'NA' ]]; then 80 echo '' 81 else 82 echo '☀ ' 83 fi 84 } 85 86 main() 87 { 88 # process should be cancelled when session is killed 89 if timeout 1 bash -c "</dev/tcp/ipinfo.io/443" && timeout 1 bash -c "</dev/tcp/wttr.in/443" && [[ "$(display_weather)" != "error" ]]; then 90 echo "$(display_weather)$(display_location)" 91 else 92 echo "Weather Unavailable" 93 fi 94 } 95 96 #run main driver program 97 main