#!/bin/sh # hanta — hantavirus outbreak tracker via dunst # Left click: Outbreak vessel + case stats # Right click: CDC snapshot + spread arcs + latest headlines # No args: Quick summary line (for statusbar) DATA_URL="https://hantavirusonline.org/data.json" CACHE="$HOME/.cache/hanta.json" CACHE_MAX=300 # 5 minutes fetch_data() { if [ -f "$CACHE" ]; then age=$(( $(date +%s) - $(stat -c %Y "$CACHE" 2>/dev/null || echo 0) )) [ "$age" -lt "$CACHE_MAX" ] && return 0 fi mkdir -p "$(dirname "$CACHE")" curl -sf --max-time 10 "$DATA_URL" -o "$CACHE" 2>/dev/null || return 1 } fetch_data || { notify-send -u critical "HANTA" "Failed to fetch data" exit 1 } # Parse fields once total=$(jq -r '.vessel.counts.cases_total // "?"' "$CACHE") confirmed=$(jq -r '.vessel.counts.cases_confirmed // "?"' "$CACHE") suspected=$(jq -r '.vessel.counts.cases_suspected // "?"' "$CACHE") deaths=$(jq -r '.vessel.counts.deaths // "?"' "$CACHE") critical=$(jq -r '.vessel.counts.critical // "?"' "$CACHE") as_of=$(jq -r '.vessel.counts.as_of // "?"' "$CACHE") source=$(jq -r '.vessel.counts.source // "?"' "$CACHE") vessel=$(jq -r '.vessel.name // "?"' "$CACHE") operator=$(jq -r '.vessel.operator // "?"' "$CACHE") flag=$(jq -r '.vessel.flag // "?"' "$CACHE") departed=$(jq -r '.vessel.departed_from // "?"' "$CACHE") departed_at=$(jq -r '.vessel.departed_at // "?"' "$CACHE") pos_lat=$(jq -r '.vessel.position.lat // "?"' "$CACHE") pos_lng=$(jq -r '.vessel.position.lng // "?"' "$CACHE") pos_hdg=$(jq -r '.vessel.position.heading_deg // "?"' "$CACHE") pos_time=$(jq -r '.vessel.position.fetched_at // "?"' "$CACHE") onboard=$(jq -r '.vessel.counts.on_board // "?"' "$CACHE") passengers=$(jq -r '.vessel.counts.passengers // "?"' "$CACHE") crew=$(jq -r '.vessel.counts.crew // "?"' "$CACHE") generated=$(jq -r '.generated_at // "?"' "$CACHE") case "${BUTTON:-$1}" in 1|left) # LEFT CLICK: Vessel + outbreak detail notify-send -u critical -t 20000 \ "HANTAVIRUS OUTBREAK" \ "CASE COUNT ($source, $as_of) Total cases: $total Lab confirmed: $confirmed Suspected: $suspected Deaths: $deaths Critical: $critical OUTBREAK VESSEL $vessel ($operator) Flag: $flag Departed: $departed ($departed_at) On board: $onboard ($passengers pax / $crew crew) LAST AIS FIX $(echo "$pos_time" | cut -dT -f1,2 | tr T ' ') Position: ${pos_lat}, ${pos_lng} Heading: ${pos_hdg}deg AFFECTED REGIONS $(jq -r '.country_index[] | " \(.country): \(.count) reports"' "$CACHE") Updated: $(echo "$generated" | cut -dT -f1,2 | tr T ' ')" ;; 3|right) # RIGHT CLICK: CDC snapshot + spread + headlines cdc_total=$(jq -r '.cdc_snapshot.total_cases // "?"' "$CACHE") cdc_hps=$(jq -r '.cdc_snapshot.hps_cases // "?"' "$CACHE") cdc_cfr=$(jq -r '.cdc_snapshot.case_fatality_rate_pct // "?"' "$CACHE") cdc_west=$(jq -r '.cdc_snapshot.pct_west_of_mississippi // "?"' "$CACHE") cdc_age=$(jq -r '.cdc_snapshot.median_age // "?"' "$CACHE") cdc_male=$(jq -r '.cdc_snapshot.pct_male // "?"' "$CACHE") cdc_since=$(jq -r '.cdc_snapshot.surveillance_start // "?"' "$CACHE") cdc_asof=$(jq -r '.cdc_snapshot.as_of // "?"' "$CACHE") notify-send -u normal -t 20000 \ "HANTA CDC + SPREAD" \ "CDC SURVEILLANCE ($cdc_since-$cdc_asof) Total US cases: $cdc_total HPS cases: $cdc_hps Fatality rate: ${cdc_cfr}% West of Miss.: ${cdc_west}% Median age: $cdc_age Male: ${cdc_male}% SPREAD ARCS $(jq -r '.spread_arcs[] | " \(.from) -> \(.to): \(.label)"' "$CACHE") LATEST HEADLINES $(jq -r '.items[:6][] | " [\(.published)] \(.title[:70])"' "$CACHE")" ;; *) # No button / statusbar mode: one-line summary printf "HANTA %s/%s/%s" "$total" "$deaths" "$critical" ;; esac