ansiweather (11020B)
1 #!/bin/sh 2 3 # 4 # AnsiWeather 1.18.0 5 # Copyright (c) 2013-2021, Frederic Cambus 6 # https://github.com/fcambus/ansiweather 7 # 8 # Created: 2013-08-29 9 # Last Updated: 2021-09-14 10 # 11 # AnsiWeather is released under the BSD 2-Clause license. 12 # See LICENSE file for details. 13 # 14 # SPDX-License-Identifier: BSD-2-Clause 15 # 16 17 ###[ Configuration options ]################################################### 18 19 LC_ALL=C; export LC_ALL 20 21 if [ -n "$ANSIWEATHERRC" ] ; then 22 config_file="$ANSIWEATHERRC" 23 elif [ -s "$XDG_CONFIG_HOME"/ansiweather/config ] ; then 24 config_file="$XDG_CONFIG_HOME"/ansiweather/config 25 elif [ -s "$HOME"/.config/ansiweather/config ] ; then 26 config_file="$HOME"/.config/ansiweather/config 27 else 28 config_file=~/.ansiweatherrc 29 fi 30 31 get_config() { 32 ret="" 33 if [ -f "$config_file" ] 34 then 35 ret=$(grep "^$1:" "$config_file" | cut -d: -f2-) 36 fi 37 38 if [ "X$ret" = "X" ] 39 then 40 return 1 41 else 42 echo "$ret" 43 fi 44 } 45 46 fetch_cmd=$(get_config "fetch_cmd" || echo "curl -sf") 47 48 49 50 ###[ Parse the command line ]################################################## 51 52 # Get config options from command line flags 53 while getopts l:u:f:FH:a:s:k:i:w:h:p:d:v option 54 do 55 case "${option}" 56 in 57 l) location=${OPTARG};; 58 u) units=${OPTARG};; 59 f) forecast=${OPTARG};; 60 F) forecast="5";; 61 H) show_feels_like=${OPTARG};; 62 a) ansi=${OPTARG};; 63 s) symbols=${OPTARG};; 64 k) api_key=${OPTARG};; 65 i) show_uvi=${OPTARG};; 66 w) show_wind=${OPTARG};; 67 h) show_humidity=${OPTARG};; 68 p) show_pressure=${OPTARG};; 69 d) show_daylight=${OPTARG};; 70 v) echo "AnsiWeather 1.18.0" && exit 0;; 71 \?) exit 64;; # EX_USAGE 72 esac 73 done 74 75 76 77 ###[ Check if bc and jq are installed ]######################################## 78 79 jqpath=$(command -v jq) 80 if [ "$jqpath" = "" ] 81 then 82 echo "ERROR: Cannot find jq binary" 83 exit 69 # EX_UNAVAILABLE 84 fi 85 86 bcpath=$(command -v bc) 87 if [ "$bcpath" = "" ] 88 then 89 echo "ERROR: Cannot find bc binary" 90 exit 69 # EX_UNAVAILABLE 91 fi 92 93 94 95 ###[ Set options that are not set from command line ]########################## 96 97 # OpenWeatherMap API key 98 [ -z "$api_key" ] && api_key=$(get_config "api_key" || echo "85a4e3c55b73909f42c6a23ec35b7147") 99 100 # Location: example "Rzeszow,PL" 101 [ -z "$location" ] && location=$(get_config "location" || echo "Rzeszow,PL") 102 103 # System of Units: "metric" or "imperial" 104 [ -z "$units" ] && units=$(get_config "units" || echo "metric") 105 106 # Show forecast: How many days, example "5". "0" is standard output 107 [ -z "$forecast" ] && forecast=$(get_config "forecast" || echo 0) 108 109 # Display ANSI colors: "true" or "false" 110 [ -z "$ansi" ] && ansi=$(get_config "ansi" || echo true) 111 112 # Display symbols: "true" or "false" (requires a Unicode capable display) 113 [ -z "$symbols" ] && symbols=$(get_config "symbols" || echo false) 114 115 # Show feels-like: "true" or "false" 116 [ -z "$show_feels_like" ] && show_feels_like=$(get_config "show_feels_like" || echo false) 117 118 # Show UVI: "true" or "false" 119 [ -z "$show_uvi" ] && show_uvi=$(get_config "show_uvi" || echo true) 120 121 # Show wind: "true" or "false" 122 [ -z "$show_wind" ] && show_wind=$(get_config "show_wind" || echo true) 123 124 # Show humidity: "true" or "false" 125 [ -z "$show_humidity" ] && show_humidity=$(get_config "show_humidity" || echo true) 126 127 # Show pressure: "true" or "false" 128 [ -z "$show_pressure" ] && show_pressure=$(get_config "show_pressure" || echo true) 129 130 # Show daylight: "true" or "false" 131 [ -z "$show_daylight" ] && show_daylight=$(get_config "show_daylight" || echo false) 132 133 dateformat=$(get_config "dateformat" || echo "%a %b %d") 134 timeformat=$(get_config "timeformat" || echo "%b %d %r") 135 136 137 138 ###[ Colors and characters ]################################################### 139 140 background=$(get_config "background" || echo "\033[44m") 141 text=$(get_config "text" || echo "\033[36;1m") 142 data=$(get_config "data" || echo "\033[33;1m") 143 delimiter=$(get_config "delimiter" || echo "\033[35m:") 144 dashes=$(get_config "dashes" || echo "\033[34m-") 145 146 147 148 ###[ Text Labels ]############################################################# 149 150 greeting_text=$(get_config "greeting_text" || echo "Weather in") 151 wind_text=$(get_config "wind_text" || echo "Wind") 152 feels_like_text=$(get_config "feels_like_text" || echo "Feels like") 153 humidity_text=$(get_config "humidity_text" || echo "Humidity") 154 pressure_text=$(get_config "pressure_text" || echo "Pressure") 155 sunrise_text=$(get_config "sunrise_text" || echo "Sunrise") 156 sunset_text=$(get_config "sunset_text" || echo "Sunset") 157 forecast_text=$(get_config "forecast_text" || echo "forecast") 158 159 160 161 ###[ Unicode Symbols for icons ]############################################### 162 163 sun=$(get_config "sun" || echo "\033[33;1m\xe2\x98\x80") 164 moon=$(get_config "moon" || echo "\033[36m\xe2\x98\xbd") 165 clouds=$(get_config "clouds" || echo "\033[37;1m\xe2\x98\x81") 166 rain=$(get_config "rain" || echo "\033[37;1m\xe2\x98\x94") 167 fog=$(get_config "fog" || echo "\033[37;1m\xe2\x96\x92") 168 mist=$(get_config "mist" || echo "\033[34m\xe2\x96\x91") 169 haze=$(get_config "haze" || echo "\033[33m\xe2\x96\x91") 170 snow=$(get_config "snow" || echo "\033[37;1m\xe2\x9d\x84") 171 thunderstorm=$(get_config "thunderstorm" || echo "\033[33;1m\xe2\x9a\xa1") 172 173 174 175 ###[ Fetch Weather data ]###################################################### 176 177 api_cmd=$([ "$forecast" != 0 ] && echo "forecast/daily" || echo "weather") 178 179 if [ "$location" -gt 0 ] 2> /dev/null 180 then 181 # Location is all numeric 182 weather=$($fetch_cmd "https://api.openweathermap.org/data/2.5/$api_cmd?id=$location&units=$units&appid=$api_key") 183 else 184 # Location is a string 185 location=$(echo "$location" | sed "s/ /%20/g") 186 weather=$($fetch_cmd "https://api.openweathermap.org/data/2.5/$api_cmd?q=$location&units=$units&appid=$api_key") 187 fi 188 189 if [ -z "$weather" ] 190 then 191 echo "ERROR: Cannot fetch weather data" 192 exit 75 # EX_TEMPFAIL 193 fi 194 195 status_code=$(echo "$weather" | jq -r '.cod' 2>/dev/null) 196 197 if [ "$status_code" != 200 ] 198 then 199 echo "ERROR: Cannot fetch weather data for the given location" 200 exit 69 # EX_UNAVAILABLE 201 fi 202 203 204 205 ###[ Fetch UV data ]########################################################### 206 207 if [ "$show_uvi" = true ] && [ "$forecast" = 0 ] 208 then 209 lat=$(echo "$weather" | jq -r '.coord.lat') 210 lon=$(echo "$weather" | jq -r '.coord.lon') 211 212 uvdata=$($fetch_cmd "https://api.openweathermap.org/data/2.5/uvi?lat=$lat&lon=$lon&appid=$api_key") 213 uvi=$(echo "$uvdata" | jq -r '.value') 214 fi 215 216 217 218 ###[ Process Weather data ]#################################################### 219 220 epoch_to_date() { 221 if date -j -r "$1" +"%a %b %d" > /dev/null 2>&1; then 222 # BSD 223 ret=$(date -j -r "$1" +"$dateformat") 224 else 225 # GNU 226 ret=$(date -d "@$1" +"$dateformat") 227 fi 228 echo "$ret" 229 } 230 231 if [ "$forecast" != 0 ] 232 then 233 city=$(echo "$weather" | jq -r '.city.name') 234 flength=$(echo "$weather" | jq '.list | length') 235 forecast=$([ "$forecast" -gt "$flength" ] && echo "$flength" || echo "$forecast") 236 else 237 city=$(echo "$weather" | jq -r '.name') 238 temperature=$(echo "$weather" | jq '.main.temp' | xargs printf "%.0f") 239 humidity=$(echo "$weather" | jq '.main.humidity') 240 feels_like=$(echo "$weather" | jq '.main.feels_like' | xargs printf "%.0f") 241 pressure=$(echo "$weather" | jq '.main.pressure') 242 sky=$(echo "$weather" | jq -r '.weather[0].main') 243 sunrise=$(echo "$weather" | jq '.sys.sunrise') 244 sunset=$(echo "$weather" | jq '.sys.sunset') 245 wind=$(echo "$weather" | jq '.wind.speed') 246 azimuth=$(echo "$weather" | jq '.wind.deg') 247 fi 248 249 250 251 ###[ Process Wind data ]####################################################### 252 253 set -- $(get_config "wind_directions" || echo "N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW") 254 255 if [ "$forecast" = 0 ] 256 then 257 shift "$(echo "scale=0; ($azimuth + 11.25)/22.5 % 16" | bc)" 258 direction=$1 259 fi 260 261 262 263 ###[ Process Sunrise and Sunset data ]######################################### 264 265 epoch_to_time() { 266 if date -j -r "$1" +"%r" > /dev/null 2>&1; then 267 # BSD 268 ret=$(date -j -r "$1" +"$timeformat") 269 else 270 # GNU 271 ret=$(date -d "@$1" +"$timeformat") 272 fi 273 echo "$ret" 274 } 275 276 if [ "$forecast" = 0 ] 277 then 278 if [ -n "$sunrise" ] 279 then 280 sunrise_time=$(epoch_to_time "$sunrise") 281 fi 282 283 if [ -n "$sunset" ] 284 then 285 sunset_time=$(epoch_to_time "$sunset") 286 fi 287 fi 288 289 290 291 ###[ Set the period ]########################################################## 292 293 now=$(date +%s) 294 295 if [ "$forecast" != 0 ] 296 then 297 period="none" 298 else 299 if [ -z "$sunset" ] || [ -z "$sunrise" ] 300 then 301 period="day" 302 elif [ "$now" -ge "$sunset" ] || [ "$now" -le "$sunrise" ] 303 then 304 period="night" 305 else 306 period="day" 307 fi 308 fi 309 310 311 312 ###[ Set the scale ]########################################################### 313 314 case $units in 315 metric) 316 scale="°C" 317 speed_unit="m/s" 318 pressure_unit="hPa" 319 pressure=$(echo "$pressure" | xargs printf "%.0f") 320 ;; 321 imperial) 322 scale="°F" 323 speed_unit="mph" 324 pressure_unit="inHg" 325 if [ "$forecast" = 0 ] 326 then 327 pressure=$(echo "$pressure*0.0295" | bc | xargs printf "%.2f") 328 fi 329 ;; 330 esac 331 332 333 334 ###[ Set icons ]############################################################### 335 336 get_icon() { 337 case $1 in 338 Clear) 339 if [ $period = "night" ] 340 then 341 echo "$moon " 342 else 343 echo "$sun " 344 fi 345 ;; 346 Clouds) 347 echo "$clouds " 348 ;; 349 Rain) 350 echo "$rain " 351 ;; 352 Fog) 353 echo "$fog " 354 ;; 355 Mist) 356 echo "$mist " 357 ;; 358 Haze) 359 echo "$haze " 360 ;; 361 Snow) 362 echo "$snow " 363 ;; 364 Thunderstorm) 365 echo "$thunderstorm " 366 ;; 367 esac 368 } 369 370 371 372 ###[ Display current Weather ]################################################# 373 374 if [ "$forecast" != 0 ] 375 then 376 output="$background$text $city $forecast_text$text$delimiter " 377 378 i=0 379 while [ $i -lt "$forecast" ] 380 do 381 day=$(echo "$weather" | jq ".list[$i]") 382 date=$(epoch_to_date "$(echo "$day" | jq -r '.dt')") 383 low=$(echo "$day" | jq -r '.temp.min' | xargs printf "%.0f") 384 high=$(echo "$day" | jq -r '.temp.max' | xargs printf "%.0f") 385 386 icon="" 387 if [ "$symbols" = true ] 388 then 389 sky=$(echo "$day" | jq -r '.weather[0].main') 390 icon=$(get_icon "$sky") 391 fi 392 393 output="$output$text$date$delimiter $data$high$text/$data$low $scale $icon" 394 if [ $i -lt $((forecast-1)) ] 395 then 396 output="$output$dashes " 397 fi 398 399 i=$((i + 1)) 400 done 401 else 402 if [ "$symbols" = true ] 403 then 404 icon="$(get_icon "$sky")" 405 fi 406 output="$background$text $greeting_text $city$delimiter$data $temperature $scale $icon" 407 408 if [ "$show_feels_like" = true ] 409 then 410 output="$output$dashes$text $feels_like_text$delimiter$data $feels_like $scale " 411 fi 412 413 if [ "$show_uvi" = true ] 414 then 415 output="$output$dashes$text UVI$delimiter$data $uvi " 416 fi 417 418 if [ "$show_wind" = true ] 419 then 420 output="$output$dashes$text $wind_text$delimiter$data $wind $speed_unit $direction " 421 fi 422 423 if [ "$show_humidity" = true ] 424 then 425 output="$output$dashes$text $humidity_text$delimiter$data $humidity%% " 426 fi 427 428 if [ "$show_pressure" = true ] 429 then 430 output="$output$dashes$text $pressure_text$delimiter$data $pressure $pressure_unit " 431 fi 432 433 if [ "$show_daylight" = true ] 434 then 435 output="$output$dashes$text $sunrise_text$delimiter$data $sunrise_time $dashes$text $sunset_text$delimiter$data $sunset_time " 436 fi 437 fi 438 439 if [ "$ansi" = true ] 440 then 441 env printf "$output\033[0m\n" 442 else 443 env printf "$output\n" | sed "s/$(printf '\033')\[[0-9;]*m//g" 444 fi