#!/bin/bash # desktop-assistant tool: weather from OpenWeatherMap. # Copyright (C) 2026 Danilo M. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # weather.sh [PLACE] [WHEN]: PLACE empty = home, WHEN now (default), today # or tomorrow. WEATHER_ENV names an env file with KEY, CITY, COUNTRY and # UNITS (the conky-theme-udt format). Home "now" reuses that project's # cache when it is under 30 minutes old, so it costs no request. # ponytail: wind is converted as metric (m/s to km/h); UNITS=imperial # would need mph instead. set -uo pipefail env_file="${WEATHER_ENV:-$HOME/.config/udt/weather.env}" [ -r "$env_file" ] || { echo "no weather env file at $env_file" >&2; exit 1; } # shellcheck source=/dev/null . "$env_file" [ -n "${KEY:-}" ] || { echo "KEY is empty in $env_file" >&2; exit 1; } place="${1:-}" when="${2:-}" q="${place:-$CITY,$COUNTRY}" get() { curl -fsS --max-time 8 --get "https://api.openweathermap.org/data/2.5/$1" \ --data-urlencode "appid=$KEY" --data-urlencode "units=${UNITS:-metric}" \ --data-urlencode "q=$q" \ || { echo "weather request failed for $q" >&2; exit 1; } } case "${when:-now}" in now) cache="${XDG_CACHE_HOME:-$HOME/.cache}/udt/weather.json" if [ -z "$place" ] && [ -n "$(find "$cache" -mmin -30 2>/dev/null)" ]; then json=$(cat "$cache") else json=$(get weather) || exit 1 fi jq -r '"\(.name), \(.sys.country): \(.weather[0].description), \(.main.temp|round) degrees, feels like \(.main.feels_like|round), humidity \(.main.humidity)%, wind \(.wind.speed*3.6|round) km/h"' <<<"$json" ;; today|tomorrow) day=$(date -d "$when" +%F) json=$(get forecast) || exit 1 jq -r --arg day "$day" ' "\(.city.name), \(.city.country)" as $c | [.list[] | select((.dt | localtime | strftime("%Y-%m-%d")) == $day)] | if length == 0 then "no forecast for \($c) on \($day)" else "\($c) \($day): " + (map("\(.dt | localtime | strftime("%H:%M")) \(.weather[0].description) \(.main.temp|round) degrees") | join(", ")) end' <<<"$json" ;; *) echo "when must be now, today or tomorrow" >&2 exit 1 ;; esac