diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-18 14:32:43 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-18 14:32:43 +0200 |
| commit | 41f58faca0ddac855f0a01254b9c8b7770444e0b (patch) | |
| tree | 1119c65ef76486096b8308954270407b1ccbdf23 /bin/weather-fetch.sh | |
| parent | 28a3edc57047c2d8176e1cc726308c70f34ebc2e (diff) | |
| download | conky-theme-udt-41f58faca0ddac855f0a01254b9c8b7770444e0b.tar.gz conky-theme-udt-41f58faca0ddac855f0a01254b9c8b7770444e0b.zip | |
fix(weather): fetcher review fixes
- quote CITY in weather.env.example and note why
- re-geocode when weather-loc lacks a longitude; write it atomically
- parse the air body with --rawfile/fromjson? so a bad body drops only the air line
- set umask before mkdir so the cache dir is 700
- drop the unneeded set -a/set +a around the source
- require at least one digit in the epoch guard
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Diffstat (limited to 'bin/weather-fetch.sh')
| -rwxr-xr-x | bin/weather-fetch.sh | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/bin/weather-fetch.sh b/bin/weather-fetch.sh index 4b37b17..e9f205b 100755 --- a/bin/weather-fetch.sh +++ b/bin/weather-fetch.sh @@ -21,10 +21,8 @@ if [ ! -r "$ENV_FILE" ]; then exit 1 fi -set -a # shellcheck source=/dev/null . "$ENV_FILE" -set +a if [ -z "${CITY:-}" ]; then echo "weather-fetch: CITY is empty in $ENV_FILE" >&2 @@ -32,20 +30,21 @@ if [ -z "${CITY:-}" ]; then fi UNITS="${UNITS:-metric}" -mkdir -p "$CACHE_DIR" - # Location data shares a directory with UDT's other generated state, all of -# which is 600. Set the mode before anything lands, so no file is briefly +# which is 600. Set the mode before anything lands, the +# directory included, so no file is briefly # world-readable. umask 077 +mkdir -p "$CACHE_DIR" + # Temp files sit beside the target, because rename is only atomic within a # filesystem. The widgets read the cache on their own 2s cadence, so a fetch # killed mid-write would otherwise hand them half a cache. TMP="$CACHE.tmp.$$" FC="$TMP.forecast" AIR="$TMP.air" -trap 'rm -f "$TMP" "$FC" "$AIR"' EXIT +trap 'rm -f "$TMP" "$FC" "$AIR" "$LOC.tmp.$$"' EXIT # Geocode once per CITY/COUNTRY pair. The cache's first field records which # pair it answers, so editing weather.env re-geocodes on the next run. @@ -53,7 +52,7 @@ PAIR="$CITY,${COUNTRY:-}" lat="" lon="" cached="" if [ -r "$LOC" ]; then IFS=$'\t' read -r cached lat lon < "$LOC" - [ "$cached" = "$PAIR" ] || lat="" + [ "$cached" = "$PAIR" ] && [ -n "$lon" ] || lat="" fi if [ -z "$lat" ]; then read -r lat lon < <(curl -fsS --max-time 15 --get \ @@ -66,7 +65,8 @@ if [ -z "$lat" ]; then echo "weather-fetch: cannot geocode $PAIR" >&2 exit 1 fi - printf '%s\t%s\t%s\n' "$PAIR" "$lat" "$lon" > "$LOC" + printf '%s\t%s\t%s\n' "$PAIR" "$lat" "$lon" > "$LOC.tmp.$$" + mv -f "$LOC.tmp.$$" "$LOC" fi if [ "$UNITS" = imperial ]; then @@ -98,13 +98,13 @@ curl -fsS --max-time 15 --get "https://air-quality-api.open-meteo.com/v1/air-qua # Flatten to the line format lib/weather.lua parses. The 24 hours start at # the current hour: the first hourly slot later than an hour before now. -if ! jq -r --arg units "$UNITS" --slurpfile air "$AIR" ' +if ! jq -r --arg units "$UNITS" --rawfile air "$AIR" ' .current.time as $now | ([.hourly.time | to_entries[] | select(.value > $now - 3600) | .key] | first) as $i | "units\t\($units)", (.current | "current\t\(.time)\t\(.temperature_2m)\t\(.apparent_temperature)\t\(.weather_code)\t\(.is_day)\t\(.relative_humidity_2m)\t\(.wind_speed_10m)\t\(.wind_direction_10m)"), "sun\t\(.daily.sunrise[0])\t\(.daily.sunset[0])", - ($air[0].current.european_aqi // empty | "air\t\(.)"), + (($air | fromjson?) | .current.european_aqi // empty | "air\t\(.)"), (.hourly as $h | range($i; [$i + 24, ($h.time | length)] | min) as $k | "hour\t\($h.time[$k])\t\($h.temperature_2m[$k])\t\($h.weather_code[$k])\t\($h.precipitation_probability[$k])\t\($h.is_day[$k])\t\($h.uv_index[$k])"), (.daily as $d | range(0; $d.time | length) as $k @@ -115,7 +115,7 @@ if ! jq -r --arg units "$UNITS" --slurpfile air "$AIR" ' fi # A 200 whose body is not a usable forecast must not replace a good cache. -if ! grep -q $'^current\t[0-9]*\t-\\?[0-9]' "$TMP"; then +if ! grep -q $'^current\t[0-9]\+\t-\\?[0-9]' "$TMP"; then echo "weather-fetch: forecast has no current temperature" >&2 exit 1 fi |
