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