#!/bin/bash # 和风天气查询 → 输出 JSON read -r input LOCATION=$(echo "$input" | python3 -c "import sys,json; print(json.load(sys.stdin).get('location',''))" 2>/dev/null) DAYS=$(echo "$input" | python3 -c "import sys,json; print(json.load(sys.stdin).get('days',3))" 2>/dev/null) [ -z "$LOCATION" ] && echo '{"error":"请提供 location 参数"}' && exit 0 API_HOST="${QWEATHER_API_HOST}" KEY_FILE="${QWEATHER_JWT_PRIVATE_KEY_FILE:-qweather/ed25519-private.pem}" KEY_ID="${QWEATHER_JWT_KEY_ID}" PROJECT_ID="${QWEATHER_JWT_PROJECT_ID}" TTL="${QWEATHER_JWT_TTL_SECONDS:-3600}" NOW=$(date +%s) HEADER=$(echo -n '{"alg":"EdDSA","kid":"'"$KEY_ID"'"}' | base64 -w0 | tr '+/' '-_' | tr -d '=') PAYLOAD=$(echo -n '{"sub":"'"$PROJECT_ID"'","iat":'$((NOW-30))',"exp":'$((NOW+TTL))'}' | base64 -w0 | tr '+/' '-_' | tr -d '=') INPUT="${HEADER}.${PAYLOAD}" TMP=$(mktemp) && echo -n "$INPUT" > "$TMP" SIG=$(openssl pkeyutl -sign -inkey "$KEY_FILE" -rawin -in "$TMP" 2>/dev/null | base64 -w0 | tr '+/' '-_' | tr -d '=') rm -f "$TMP" JWT="${INPUT}.${SIG}" [ -z "$JWT" ] && JWT="${QWEATHER_JWT}" [ -z "$JWT" ] && echo '{"error":"JWT 生成失败"}' && exit 0 ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$LOCATION'))") CITY=$(curl -s --compressed "https://geoapi.qweather.com/v2/city/lookup?location=${ENCODED}" -H "Authorization: Bearer $JWT") CITY_ID=$(echo "$CITY" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['location'][0]['id'] if d.get('location') else '')" 2>/dev/null) [ -z "$CITY_ID" ] && echo '{"error":"未找到城市: '"$LOCATION"'"}' && exit 0 EP_DAYS=$([ "$DAYS" -le 3 ] && echo 3 || echo 7) NOW_RESP=$(curl -s --compressed "https://${API_HOST}/v7/weather/now?location=${CITY_ID}&lang=zh&unit=m" -H "Authorization: Bearer $JWT") DAILY_RESP=$(curl -s --compressed "https://${API_HOST}/v7/weather/${EP_DAYS}d?location=${CITY_ID}&lang=zh&unit=m" -H "Authorization: Bearer $JWT") export NOW_RESP DAILY_RESP LOCATION DAYS python3 -c " import os, json now = json.loads(os.environ['NOW_RESP']) daily = json.loads(os.environ['DAILY_RESP']) days = daily.get('daily', [])[:int(os.environ['DAYS'])] result = { 'location': os.environ['LOCATION'], 'now': { 'temp': now['now']['temp'], 'text': now['now']['text'], }, 'forecast': [ {'date': d['fxDate'], 'day': d['textDay'], 'night': d.get('textNight',''), 'tempMin': d['tempMin'], 'tempMax': d['tempMax']} for d in days ] } # 过滤空字段 result['now'] = {k: v for k, v in result['now'].items() if v} result['forecast'] = [{k: v for k, v in f.items() if v} for f in result['forecast']] print(json.dumps(result, ensure_ascii=False)) " 2>/dev/null || echo '{"error":"解析天气数据失败"}'