#!/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