49 lines
1.4 KiB
Bash
Executable File
49 lines
1.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Print the current weather as a short icon+temp string, e.g. "🌦️ +83°F".
|
|
# Caches the wttr.in response so the lock screen and waybar don't hit the
|
|
# network on every refresh. A cached value is served immediately -- even when
|
|
# stale -- and refreshed in the background, so a slow network never delays the
|
|
# lock screen's first frame. Override the location with WEATHER_CITY or edit
|
|
# CITY below.
|
|
set -u
|
|
|
|
CITY="${WEATHER_CITY:-Denver}"
|
|
CACHE_DIR="${XDG_RUNTIME_DIR:-/tmp}"
|
|
CACHE="${CACHE_DIR}/wttr.cache"
|
|
CACHE_MAX_AGE=1800 # 30 minutes
|
|
URL="https://wttr.in/${CITY}?format=%c+%t"
|
|
|
|
fetch() {
|
|
TMP="${CACHE}.tmp.$$"
|
|
if curl -fsS --connect-timeout 2 --max-time 5 "${URL}" > "${TMP}" 2>/dev/null; then
|
|
mv "${TMP}" "${CACHE}"
|
|
cat "${CACHE}"
|
|
else
|
|
rm -f "${TMP}" || true
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Fresh cache: print it.
|
|
if [ -f "${CACHE}" ] && [ "$(( $(date +%s) - $(stat -c %Y "${CACHE}") ))" -lt "${CACHE_MAX_AGE}" ]; then
|
|
cat "${CACHE}"
|
|
exit 0
|
|
fi
|
|
|
|
# Stale cache: print it immediately, then refresh in the background so the
|
|
# caller never blocks. flock keeps a pile-up of refreshes from several clients
|
|
# (lock screen, waybar) from running concurrent curls.
|
|
if [ -f "${CACHE}" ]; then
|
|
cat "${CACHE}"
|
|
(
|
|
exec 9>"${CACHE}.lock"
|
|
flock -n 9 || exit 0
|
|
fetch >/dev/null 2>&1
|
|
) &
|
|
disown
|
|
exit 0
|
|
fi
|
|
|
|
# No cache at all: fetch synchronously, but with tight timeouts.
|
|
fetch
|