added some extra sample tool scripts
This commit is contained in:
Executable
+190
@@ -0,0 +1,190 @@
|
||||
#!/bin/sh
|
||||
# weather - query current weather and forecasts for any location via wttr.in.
|
||||
#
|
||||
# wttr.in (https://github.com/chubin/wttr.in) is a console-oriented weather
|
||||
# service backed by World Weather Online data. It supports several output
|
||||
# formats: a graphical ANSI view for terminals (the default), one-line text
|
||||
# formats (built-in presets 1-4 or a custom %-notation string), a rich JSON
|
||||
# document (?format=j1 / j2) for scripts and APIs, plus PNG / HTML /
|
||||
# Prometheus metrics.
|
||||
#
|
||||
# This script is a thin, friendly wrapper around the wttr.in HTTP API. It
|
||||
# builds the request URL from the supplied location and options, fetches the
|
||||
# data with curl and (when JSON is requested) pretty-prints it with jq.
|
||||
#
|
||||
# Usage:
|
||||
# weather [options] [location]
|
||||
#
|
||||
# Options:
|
||||
# -l, --location LOC Location: city, airport code, domain, IP,
|
||||
# "lat,lon" coordinates, or "~Name" for a custom label.
|
||||
# Default: auto-detect from the request IP.
|
||||
# -u, --units U Unit system: m (metric, default), u (USCS/imperial),
|
||||
# M (metric with wind speed in m/s).
|
||||
# -L, --lang LANG Output language code, e.g. de, fr, ru, zh-cn.
|
||||
# -f, --format FMT Output format:
|
||||
# j1 -> rich JSON document (default for --json)
|
||||
# j2 -> JSON document, imperial units
|
||||
# 1-4 -> built-in one-line presets
|
||||
# "%..." -> custom one-line %-notation format
|
||||
# Omit to get the default graphical terminal view.
|
||||
# -j, --json Alias for --format j1 (emit JSON).
|
||||
# -0 Current weather only.
|
||||
# -1 Current weather + today's forecast.
|
||||
# -2 Current weather + today's + tomorrow's forecast.
|
||||
# -q, --quiet Quiet: no "Weather report" header / city name.
|
||||
# -A Force ANSI output (ignore User-Agent detection).
|
||||
# -h, --help Show this help text.
|
||||
#
|
||||
# Environment:
|
||||
# WTTRAPI Base endpoint. Default: https://wttr.in
|
||||
# WEATHER_TIMEOUT curl connect/read timeout in seconds. Default: 20
|
||||
#
|
||||
# Dependencies: curl, jq (jq only needed for the JSON format).
|
||||
#
|
||||
# Examples:
|
||||
# weather
|
||||
# weather London
|
||||
# weather -u u -L de Berlin
|
||||
# weather -f 3 "New York"
|
||||
# weather -f "%l: %c %t (feels %f), wind %w %m" Paris
|
||||
# weather -j Tokyo
|
||||
|
||||
set -eu
|
||||
|
||||
WTTRAPI="${WTTRAPI:-https://wttr.in}"
|
||||
TIMEOUT="${WEATHER_TIMEOUT:-20}"
|
||||
|
||||
# Single-letter options (view/quiet/units) concatenated into one run.
|
||||
SHORT=""
|
||||
LANG_CODE=""
|
||||
FORMAT=""
|
||||
LOCATION=""
|
||||
|
||||
usage() {
|
||||
sed -n '/^# Usage:/,/^# Examples:/p' "$0" | sed 's/^# \{0,1\}//'
|
||||
}
|
||||
|
||||
# --- Parse arguments. ---
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-l|--location)
|
||||
[ "$#" -ge 2 ] || { echo "weather: $1 requires an argument" >&2; exit 1; }
|
||||
LOCATION="$2"
|
||||
shift 2
|
||||
;;
|
||||
-u|--units)
|
||||
[ "$#" -ge 2 ] || { echo "weather: $1 requires an argument" >&2; exit 1; }
|
||||
case "$2" in
|
||||
m|u|M) SHORT="${SHORT}$2" ;;
|
||||
*) echo "weather: unknown unit '$2' (use m, u or M)" >&2; exit 1 ;;
|
||||
esac
|
||||
shift 2
|
||||
;;
|
||||
-L|--lang)
|
||||
[ "$#" -ge 2 ] || { echo "weather: $1 requires an argument" >&2; exit 1; }
|
||||
LANG_CODE="$2"
|
||||
shift 2
|
||||
;;
|
||||
-f|--format)
|
||||
[ "$#" -ge 2 ] || { echo "weather: $1 requires an argument" >&2; exit 1; }
|
||||
FORMAT="$2"
|
||||
shift 2
|
||||
;;
|
||||
-j|--json)
|
||||
FORMAT="j1"
|
||||
shift
|
||||
;;
|
||||
-0|-1|-2|-q|-A)
|
||||
SHORT="${SHORT}${1#-}"
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
LOCATION="${LOCATION:+$LOCATION }$(printf '%s' "$*" | sed 's/^ //')"
|
||||
break
|
||||
;;
|
||||
-*)
|
||||
echo "weather: unknown option '$1' (try --help)" >&2
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
# Positional: append to location (preserves multi-word locations).
|
||||
LOCATION="${LOCATION:+$LOCATION }$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# --- Assemble the query string. ---
|
||||
# wttr.in accepts a leading run of single-letter options, then '&'-joined
|
||||
# long options (key=value). We build both parts and join them.
|
||||
QUERY="$SHORT"
|
||||
|
||||
# Long options: format and lang.
|
||||
LONG=""
|
||||
if [ -n "$FORMAT" ]; then
|
||||
case "$FORMAT" in
|
||||
j1|j2)
|
||||
LONG="${LONG:+$LONG&}format=${FORMAT}"
|
||||
;;
|
||||
[1-4])
|
||||
LONG="${LONG:+$LONG&}format=${FORMAT}"
|
||||
;;
|
||||
*)
|
||||
# Custom %-notation one-line format -> URL-encode it.
|
||||
ENC=$(printf '%s' "$FORMAT" | jq -sRr @uri)
|
||||
LONG="${LONG:+$LONG&}format=${ENC}"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
if [ -n "$LANG_CODE" ]; then
|
||||
LONG="${LONG:+$LONG&}lang=$(printf '%s' "$LANG_CODE" | jq -sRr @uri)"
|
||||
fi
|
||||
|
||||
# Combine short + long parts into a single query string.
|
||||
if [ -n "$QUERY" ] && [ -n "$LONG" ]; then
|
||||
QUERY="${QUERY}&${LONG}"
|
||||
elif [ -z "$QUERY" ] && [ -n "$LONG" ]; then
|
||||
QUERY="$LONG"
|
||||
fi
|
||||
|
||||
# URL-encode the location (spaces -> %20, etc.). Empty means auto-detect.
|
||||
if [ -n "$LOCATION" ]; then
|
||||
LOC_ENC=$(printf '%s' "$LOCATION" | jq -sRr @uri)
|
||||
else
|
||||
LOC_ENC=""
|
||||
fi
|
||||
|
||||
URL="${WTTRAPI}/${LOC_ENC}"
|
||||
if [ -n "$QUERY" ]; then
|
||||
URL="${URL}?${QUERY}"
|
||||
fi
|
||||
|
||||
# --- Fetch. ---
|
||||
# wttr.in returns the graphical ANSI art whenever the request looks like it
|
||||
# comes from a console client (curl's default User-Agent), and HTML for
|
||||
# browsers. So we keep curl's default identity. The "-A" flag above is a
|
||||
# wttr.in URL option ("force ANSI") and is already part of the query string.
|
||||
|
||||
RESP=$(curl -s -L --max-time "$TIMEOUT" "$URL") || {
|
||||
echo "weather: failed to reach $WTTRAPI" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# --- Emit. ---
|
||||
if [ "$FORMAT" = "j1" ] || [ "$FORMAT" = "j2" ]; then
|
||||
if command -v jq >/dev/null 2>&1; then
|
||||
printf '%s\n' "$RESP" | jq . 2>/dev/null || printf '%s\n' "$RESP"
|
||||
else
|
||||
printf '%s\n' "$RESP"
|
||||
fi
|
||||
else
|
||||
printf '%s\n' "$RESP"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user