feat: emoji-visualized gold + weather entertainment plugins
gold: headline price is now USD per gram (XAU/oz divided by 31.1034768), ounce + bid/ask as reference, timestamp cleaned of timezone/fraction. weather: per-WMO-code emoji (day/night-aware clear sky), temp + feels like, humidity, wind. Both verified live; safe in default plain send mode.
This commit is contained in:
@@ -16,6 +16,8 @@ summary (newest last).
|
||||
|
||||
## Done
|
||||
|
||||
- **2026-08-09** — Entertainment plugins `gold` + `weather` now emit emoji-visualized Telegram messages. Gold: headline is USD/**gram** (XAU/oz ÷ 31.1034768), ounce as reference, bid/ask, cleaned timestamp (`+00:00`/fractional seconds stripped). Weather: per-WMO-code emoji (☀️/🌙 day-night aware for clear sky), °C + feels-like, humidity, wind with unit spacing. Both verified live; emojis are safe in the default plain send mode.
|
||||
|
||||
- **2026-08-09** — `pos tree`: prints the live `pos` command tree (categories → commands → subcommands) by deriving the hierarchy from `bin/pos-*` filenames + `# POS:` / `# POS_SUBCMDS:` headers, so it always matches what the dispatcher can run. Category-less like `pos-config`; `--depth N` limit; `pos help tree` works. Docs: POS.md `tree` section, `bin/pos` usage example, `make gen` regenerated the AGENT_Context tree/dispatch/filetable + `_pos_flags[tree]`.
|
||||
|
||||
- **2026-08-09** — Telegram sender `config` / `config set` removed — redundant with `pos config telegram` (same `# POS_CONFIG:` registry, masked token display + input, chat-id validation, chmod 600); sender/listener error hints now point there. Deep-review bugfixes in the same commit: mapped `/command` values containing `|` are no longer truncated (`load_map` switched from a `|` to a `\x1f` delimiter — previously `/up=echo hi | head` silently ran `echo hi `); `pos entertainment send <plugin> [args…]` actually forwards the extra args (every arg was `shift`ed in the flag loop, so `$@` was empty) and passes `--` before the message so leading-`-` plugin output isn't parsed as an option; `write_config_key` (entertainment-lib) and `cfg_write` (config-ui) replaced unescaped `sed -i "s|^K=.*|K=\"$v\"|"` with grep-v+append so values with `&`/`|`/`\` no longer mangle (also the path all telegram config now flows through); `sync_systemd` daemon-reloads after removing timer units; `digits` config validation accepts negative group/supergroup chat ids (`-100…`).
|
||||
|
||||
+11
-5
@@ -2,6 +2,7 @@
|
||||
set -euo pipefail
|
||||
|
||||
# Entertainment plugin: gold spot price (XAU/USD) via goldprice.dev (no API key).
|
||||
# Headline price is USD per gram; the ounce quote is shown as reference.
|
||||
# POS_PLUGIN: gold
|
||||
# Contract: stdout is the message sent by 'pos entertainment send gold'.
|
||||
|
||||
@@ -29,15 +30,20 @@ if ! json="$(curl -fsS --max-time 20 \
|
||||
err "Failed to fetch gold price from goldprice.dev"
|
||||
fi
|
||||
|
||||
symbol="$(jq -r '.symbols[0].symbol' <<<"$json")"
|
||||
price="$(jq -r '.symbols[0].price' <<<"$json")"
|
||||
bid="$(jq -r '.symbols[0].bid' <<<"$json")"
|
||||
ask="$(jq -r '.symbols[0].ask' <<<"$json")"
|
||||
unit="$(jq -r '.symbols[0].unit' <<<"$json")"
|
||||
when="$(jq -r '.symbols[0].computed_at' <<<"$json")"
|
||||
when="${when/T/ }"; when="${when%Z}"
|
||||
when="${when:0:19}"
|
||||
when="${when/T/ }"
|
||||
|
||||
[ -n "$price" ] || err "No price received"
|
||||
|
||||
printf 'Gold spot (%s/USD): %s USD/%s\nBid %s · Ask %s\nas of %s UTC\n' \
|
||||
"$symbol" "$price" "$unit" "$bid" "$ask" "$when"
|
||||
# XAU spot is quoted per troy ounce (31.1034768 g) — convert to USD/gram.
|
||||
per_g="$(awk -v p="$price" -v o="31.1034768" 'BEGIN{printf "%.2f", p/o}')"
|
||||
|
||||
printf '🪙 Gold (XAU/USD)\n'
|
||||
printf '💰 1 gram $%s\n' "$per_g"
|
||||
printf '⚖️ 1 oz $%s\n' "$price"
|
||||
printf '📉 Bid $%s · 📈 Ask $%s\n' "$bid" "$ask"
|
||||
printf '🕐 %s UTC\n' "$when"
|
||||
|
||||
+37
-14
@@ -2,6 +2,7 @@
|
||||
set -euo pipefail
|
||||
|
||||
# Entertainment plugin: current weather via Open-Meteo (no API key).
|
||||
# Emoji + em-dash layout for Telegram; day/night-aware for clear skies.
|
||||
# POS_PLUGIN: weather
|
||||
# POS_KEYS: WEATHER_LAT <latitude> (required)
|
||||
# POS_KEYS: WEATHER_LON <longitude> (required)
|
||||
@@ -27,19 +28,36 @@ load_config() {
|
||||
done < <(grep -E '^[A-Z_]+=' "$CONFIG_FILE" || true)
|
||||
}
|
||||
|
||||
# First arg: weather code; second arg: is_day (1=day). Prints the emoji.
|
||||
wmo_emoji() {
|
||||
case "$1" in
|
||||
0) [ "${2:-1}" = "1" ] && echo "☀️" || echo "🌙" ;;
|
||||
1) echo "🌤️" ;;
|
||||
2) echo "⛅" ;;
|
||||
3) echo "☁️" ;;
|
||||
45|48) echo "🌫️" ;;
|
||||
51|53|55) echo "🌦️" ;;
|
||||
61|63|65) echo "🌧️" ;;
|
||||
71|73|75) echo "❄️" ;;
|
||||
80|81|82) echo "🌧️" ;;
|
||||
95|96|99) echo "⛈️" ;;
|
||||
*) echo "🌡️" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
wmo_desc() {
|
||||
case "$1" in
|
||||
0) echo "clear sky" ;;
|
||||
1) echo "mainly clear" ;;
|
||||
2) echo "partly cloudy" ;;
|
||||
3) echo "overcast" ;;
|
||||
45|48) echo "fog" ;;
|
||||
51|53|55) echo "drizzle" ;;
|
||||
61|63|65) echo "rain" ;;
|
||||
71|73|75) echo "snow" ;;
|
||||
80|81|82) echo "rain showers" ;;
|
||||
95|96|99) echo "thunderstorm" ;;
|
||||
*) echo "weather code $1" ;;
|
||||
0) echo "Clear sky" ;;
|
||||
1) echo "Mainly clear" ;;
|
||||
2) echo "Partly cloudy" ;;
|
||||
3) echo "Overcast" ;;
|
||||
45|48) echo "Fog" ;;
|
||||
51|53|55) echo "Drizzle" ;;
|
||||
61|63|65) echo "Rain" ;;
|
||||
71|73|75) echo "Snow" ;;
|
||||
80|81|82) echo "Rain showers" ;;
|
||||
95|96|99) echo "Thunderstorm" ;;
|
||||
*) echo "Weather code $1" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
@@ -71,7 +89,7 @@ load_config
|
||||
label="${WEATHER_CITY:-$WEATHER_LAT,$WEATHER_LON}"
|
||||
|
||||
if ! json="$(curl -fsS --max-time 20 \
|
||||
"https://api.open-meteo.com/v1/forecast?latitude=${WEATHER_LAT}&longitude=${WEATHER_LON}¤t=temperature_2m,relative_humidity_2m,apparent_temperature,weather_code,wind_speed_10m")"; then
|
||||
"https://api.open-meteo.com/v1/forecast?latitude=${WEATHER_LAT}&longitude=${WEATHER_LON}¤t=temperature_2m,relative_humidity_2m,apparent_temperature,weather_code,wind_speed_10m,is_day")"; then
|
||||
err "Failed to fetch weather from Open-Meteo"
|
||||
fi
|
||||
|
||||
@@ -80,8 +98,13 @@ feels="$(jq -r '.current.apparent_temperature' <<<"$json")"
|
||||
humidity="$(jq -r '.current.relative_humidity_2m' <<<"$json")"
|
||||
code="$(jq -r '.current.weather_code' <<<"$json")"
|
||||
wind="$(jq -r '.current.wind_speed_10m' <<<"$json")"
|
||||
is_day="$(jq -r '.current.is_day' <<<"$json")"
|
||||
unit_temp="$(jq -r '.current_units.temperature_2m' <<<"$json")"
|
||||
unit_wind="$(jq -r '.current_units.wind_speed_10m' <<<"$json")"
|
||||
|
||||
printf 'Weather in %s: %s, %s%s (feels like %s%s), humidity %s%%, wind %s%s\n' \
|
||||
"$label" "$(wmo_desc "$code")" "$temp" "$unit_temp" "$feels" "$unit_temp" "$humidity" "$wind" "$unit_wind"
|
||||
emoji="$(wmo_emoji "$code" "$is_day")"
|
||||
|
||||
printf '%s %s · %s\n' "$emoji" "$(wmo_desc "$code")" "$label"
|
||||
printf '🌡️ %s%s (feels like %s%s)\n' "$temp" "$unit_temp" "$feels" "$unit_temp"
|
||||
printf '💧 Humidity %s%%\n' "$humidity"
|
||||
printf '💨 Wind %s %s\n' "$wind" "$unit_wind"
|
||||
|
||||
Reference in New Issue
Block a user