forked from dracula/tmux
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathweather.sh
More file actions
executable file
Β·140 lines (123 loc) Β· 4.03 KB
/
weather.sh
File metadata and controls
executable file
Β·140 lines (123 loc) Β· 4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/usr/bin/env bash
# setting the locale, some users have issues with different locales, this forces the correct one
export LC_ALL=en_US.UTF-8
API_URL="https://wttr.in"
DELIM=":"
# emulate timeout command from bash - timeout is not available by default on OSX
if [ "$(uname)" == "Darwin" ]; then
function timeout() {
local _duration
_duration="${1:-1}"
command -p perl -e 'alarm shift; exec @ARGV' "$_duration" "$@"
}
fi
# Fetch weather information from remote API
# Globals:
# API_URL
# DELIM
# Arguments:
# show fahrenheit, either "true" or "false"
# optional fixed location to query weather data about
function fetch_weather_information() {
local _show_fahrenheit _location _unit
_show_fahrenheit="$1"
_location="$2"
if "$_show_fahrenheit"; then
_unit="u"
else
_unit="m"
fi
# If the user provies a "fixed location", `@dracula-fixed-location`, that the
# API does not recognize, the API may suggest a users actual geoip GPS
# location in the response body. This can lead to user PI leak.
# Drop response body when status code >= 400 and return nonzero by passing the
# `--fail` flag. Execute curl last to allow the consumer to leverage the
# return code. Pass `--show-error` and redirect stderr for the consumer.
command -p curl -L --silent --fail --show-error \
"${API_URL}/${_location// /%20}?format=%C${DELIM}%t${DELIM}%l&${_unit}" 2>&1
}
# Format raw weather information from API
# Globals:
# DELIM
# Arguments:
# The raw weather data as returned by "fetch_weather_information()"
# show location, either "true" or "false"
function format_weather_info() {
local _raw _show_location
_raw="$1" # e.g. "Rain:+63Β°F:Houston, Texas, United States"
_show_location="$2"
local _weather _temp _location
_weather="${_raw%%"${DELIM}"*}" # slice temp and location to get weather
_weather=$(printf '%s' "$_weather" | tr '[:upper:]' '[:lower:]') # lowercase weather, OSXβs bash3.2 does not support ${v,,}
_temp="${_raw#*"${DELIM}"}" # slice weather to get temp and location
_temp="${_temp%%"${DELIM}"*}" # slice location to get temp
_temp="${_temp/+/}" # slice "+" from "+74Β°F"
_location="${_raw##*"${DELIM}"}" # slice weather and temp to get location
[ "${_location//[^,]/}" == ",," ] && _location="${_location%,*}" # slice country if it exists
case "$_weather" in
'snow')
_weather='β'
;;
'rain' | 'shower')
_weather='β'
;;
'overcast' | 'cloud')
_weather='β'
;;
'na')
_weather=''
;;
*)
_weather='β'
;;
esac
if "$_show_location"; then
printf '%s %s %s' "$_weather" "$_temp" "$_location"
else
printf '%s %s' "$_weather" "$_temp"
fi
}
# Display weather, temperature, and location
# Globals
# none
# Arguments
# show fahrenheit, either "true" (default) or "false"
# show location, either "true" (default) or "false"
# optional fixed location to query data about, e.g. "Houston, Texas"
# hide errors, either "true" or "false" (default)
function main() {
local _show_fahrenheit _show_location _location _hide_errors
_show_fahrenheit="${1:-true}"
_show_location="${2:-true}"
_location="$3"
_hide_errors="${4:-false}"
# process should be cancelled when session is killed
if ! timeout 1 bash -c "</dev/tcp/wttr.in/443"; then
if "$_hide_errors"; then
printf ''
else
printf 'Weather Unavailable\n'
fi
return
fi
# BashFAQ/002: assignment of substitution does not effect status code.
local _resp
if ! _resp=$(fetch_weather_information "$_show_fahrenheit" "$_location"); then
if "$_hide_errors"; then
printf ''
return
fi
# e.g. "curl: (22) The requested URL returned error: 404"
case "${_resp##* }" in
404)
printf 'Unknown Location\n'
;;
*)
printf 'Weather Unavailable\n'
;;
esac
return
fi
format_weather_info "$_resp" "$_show_location"
}
main "$@"