mirror of
https://github.com/ksyasuda/dotfiles.git
synced 2026-03-20 06:11:27 -07:00
update
This commit is contained in:
@@ -1 +0,0 @@
|
||||
../../../projects/scripts/waybar/wttr.sh
|
||||
167
.config/waybar/scripts/wttr.sh
Executable file
167
.config/waybar/scripts/wttr.sh
Executable file
@@ -0,0 +1,167 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
location_input="${1:-Los_Angeles}"
|
||||
location_query="${location_input//_/ }"
|
||||
cache_dir="${XDG_CACHE_HOME:-$HOME/.cache}/waybar"
|
||||
cache_key="${location_input//[^[:alnum:]_.-]/_}"
|
||||
geo_cache_file="$cache_dir/weather-geo-${cache_key}.json"
|
||||
weather_cache_file="$cache_dir/weather-${cache_key}.json"
|
||||
|
||||
json_escape() {
|
||||
jq -Rsa .
|
||||
}
|
||||
|
||||
emit_json() {
|
||||
local text="$1"
|
||||
local tooltip="$2"
|
||||
|
||||
printf '{"text":%s,"tooltip":%s}\n' \
|
||||
"$(printf '%s' "$text" | json_escape)" \
|
||||
"$(printf '%s' "$tooltip" | json_escape)"
|
||||
}
|
||||
|
||||
emit_cached_or_error() {
|
||||
if [[ -f "$weather_cache_file" ]]; then
|
||||
cat "$weather_cache_file"
|
||||
return
|
||||
fi
|
||||
|
||||
emit_json "weather unavailable" "weather service unavailable"
|
||||
}
|
||||
|
||||
url_encode() {
|
||||
jq -rn --arg value "$1" '$value | @uri'
|
||||
}
|
||||
|
||||
weather_icon() {
|
||||
local code="$1"
|
||||
local is_day="$2"
|
||||
|
||||
case "$code" in
|
||||
0) [[ "$is_day" == "1" ]] && printf '☀' || printf '☾' ;;
|
||||
1 | 2) [[ "$is_day" == "1" ]] && printf '⛅' || printf '☁' ;;
|
||||
3) printf '☁' ;;
|
||||
45 | 48) printf '🌫' ;;
|
||||
51 | 53 | 55 | 56 | 57) printf '🌦' ;;
|
||||
61 | 63 | 65 | 66 | 67 | 80 | 81 | 82) printf '🌧' ;;
|
||||
71 | 73 | 75 | 77 | 85 | 86) printf '🌨' ;;
|
||||
95 | 96 | 99) printf '⛈' ;;
|
||||
*) printf '☁' ;;
|
||||
esac
|
||||
}
|
||||
|
||||
weather_description() {
|
||||
case "$1" in
|
||||
0) printf 'Clear sky' ;;
|
||||
1) printf 'Mainly clear' ;;
|
||||
2) printf 'Partly cloudy' ;;
|
||||
3) printf 'Overcast' ;;
|
||||
45 | 48) printf 'Fog' ;;
|
||||
51) printf 'Light drizzle' ;;
|
||||
53) printf 'Drizzle' ;;
|
||||
55) printf 'Dense drizzle' ;;
|
||||
56 | 57) printf 'Freezing drizzle' ;;
|
||||
61) printf 'Slight rain' ;;
|
||||
63) printf 'Rain' ;;
|
||||
65) printf 'Heavy rain' ;;
|
||||
66 | 67) printf 'Freezing rain' ;;
|
||||
71) printf 'Slight snow' ;;
|
||||
73) printf 'Snow' ;;
|
||||
75) printf 'Heavy snow' ;;
|
||||
77) printf 'Snow grains' ;;
|
||||
80) printf 'Rain showers' ;;
|
||||
81) printf 'Rain showers' ;;
|
||||
82) printf 'Heavy rain showers' ;;
|
||||
85 | 86) printf 'Snow showers' ;;
|
||||
95) printf 'Thunderstorm' ;;
|
||||
96 | 99) printf 'Thunderstorm with hail' ;;
|
||||
*) printf 'Weather unavailable' ;;
|
||||
esac
|
||||
}
|
||||
|
||||
load_geocode() {
|
||||
if [[ -f "$geo_cache_file" ]]; then
|
||||
cat "$geo_cache_file"
|
||||
return
|
||||
fi
|
||||
|
||||
local encoded_query response
|
||||
encoded_query="$(url_encode "$location_query")"
|
||||
response="$(
|
||||
curl \
|
||||
--silent \
|
||||
--show-error \
|
||||
--fail \
|
||||
--max-time 10 \
|
||||
"https://geocoding-api.open-meteo.com/v1/search?name=${encoded_query}&count=1&language=en&format=json" 2>/dev/null || true
|
||||
)"
|
||||
|
||||
if jq -e '.results[0] | .name and .latitude and .longitude and .timezone' >/dev/null <<<"$response"; then
|
||||
jq -c '.results[0] | {name, admin1, country, latitude, longitude, timezone}' <<<"$response" | tee "$geo_cache_file"
|
||||
return
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
fetch_weather() {
|
||||
local latitude="$1"
|
||||
local longitude="$2"
|
||||
local timezone="$3"
|
||||
|
||||
curl \
|
||||
--silent \
|
||||
--show-error \
|
||||
--fail \
|
||||
--max-time 10 \
|
||||
"https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}¤t=temperature_2m,relative_humidity_2m,apparent_temperature,weather_code,wind_speed_10m,is_day&timezone=$(url_encode "$timezone")" 2>/dev/null || true
|
||||
}
|
||||
|
||||
format_weather() {
|
||||
local place_json="$1"
|
||||
local weather_json="$2"
|
||||
local name region place code is_day icon description temperature feels_like humidity wind text tooltip
|
||||
|
||||
name="$(jq -r '.name' <<<"$place_json")"
|
||||
region="$(jq -r '.admin1 // empty' <<<"$place_json")"
|
||||
place="$name"
|
||||
if [[ -n "$region" ]]; then
|
||||
place+=", $region"
|
||||
fi
|
||||
|
||||
code="$(jq -r '.current.weather_code' <<<"$weather_json")"
|
||||
is_day="$(jq -r '.current.is_day' <<<"$weather_json")"
|
||||
icon="$(weather_icon "$code" "$is_day")"
|
||||
description="$(weather_description "$code")"
|
||||
temperature="$(jq -r '.current.temperature_2m | round | "\(.)"' <<<"$weather_json")"
|
||||
feels_like="$(jq -r '.current.apparent_temperature | round | "\(.)"' <<<"$weather_json")"
|
||||
humidity="$(jq -r '.current.relative_humidity_2m | round | "\(.)"' <<<"$weather_json")"
|
||||
wind="$(jq -r '.current.wind_speed_10m | round | "\(.)"' <<<"$weather_json")"
|
||||
|
||||
text="${icon} ${temperature}°C"
|
||||
tooltip="${place}: ${description}. Feels like ${feels_like}°C, humidity ${humidity}%, wind ${wind} km/h"
|
||||
|
||||
emit_json "$text" "$tooltip"
|
||||
}
|
||||
|
||||
mkdir -p "$cache_dir"
|
||||
|
||||
if ! place_json="$(load_geocode)"; then
|
||||
emit_cached_or_error
|
||||
exit 0
|
||||
fi
|
||||
|
||||
latitude="$(jq -r '.latitude' <<<"$place_json")"
|
||||
longitude="$(jq -r '.longitude' <<<"$place_json")"
|
||||
timezone="$(jq -r '.timezone' <<<"$place_json")"
|
||||
|
||||
weather_json="$(fetch_weather "$latitude" "$longitude" "$timezone")"
|
||||
|
||||
if jq -e '.current | .temperature_2m and .relative_humidity_2m and .apparent_temperature and .weather_code and .wind_speed_10m and .is_day' >/dev/null <<<"$weather_json"; then
|
||||
format_weather "$place_json" "$weather_json" | tee "$weather_cache_file"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
emit_cached_or_error
|
||||
Reference in New Issue
Block a user