feat: add weekly reward loop, i18n support, and scan terminal dashboard components
This commit is contained in:
@@ -22,6 +22,7 @@ except Exception:
|
||||
|
||||
from src.data_collection.city_registry import CITY_REGISTRY
|
||||
from src.data_collection.weather_sources import WeatherDataCollector
|
||||
from src.utils.telegram_i18n import copy_text, normalize_push_language, telegram_push_language
|
||||
|
||||
TARGET_CITIES: List[str] = [
|
||||
"beijing",
|
||||
@@ -73,6 +74,14 @@ def _env_int(name: str, default: int, min_val: int = 0) -> int:
|
||||
return default
|
||||
|
||||
|
||||
def _daily_report_language() -> str:
|
||||
return telegram_push_language(
|
||||
"DAILY_WEATHER_REPORT_LANGUAGE",
|
||||
"TELEGRAM_PUSH_LANGUAGE",
|
||||
"POLYWEATHER_TELEGRAM_PUSH_LANGUAGE",
|
||||
)
|
||||
|
||||
|
||||
def _fetch_cma_forecast(city_key: str) -> Optional[Dict[str, Any]]:
|
||||
"""Scrape today's forecast from weather.com.cn (CMA)."""
|
||||
code = CMA_CITY_CODES.get(city_key)
|
||||
@@ -158,13 +167,14 @@ def _fetch_city_data(
|
||||
collector: WeatherDataCollector, city_key: str
|
||||
) -> Optional[Dict[str, Any]]:
|
||||
name = CITY_NAME_ZH.get(city_key, city_key)
|
||||
info = CITY_REGISTRY.get(city_key)
|
||||
name_en = str((info or {}).get("name") or city_key.title())
|
||||
|
||||
# 1. Try CMA first for weather description
|
||||
cma = _fetch_cma_forecast(city_key)
|
||||
|
||||
# 2. Get Open-Meteo data for temperature fallback
|
||||
om_high = None
|
||||
info = CITY_REGISTRY.get(city_key)
|
||||
if info:
|
||||
try:
|
||||
results = collector.fetch_all_sources(
|
||||
@@ -209,6 +219,7 @@ def _fetch_city_data(
|
||||
return {
|
||||
"city": city_key,
|
||||
"name": name,
|
||||
"name_en": name_en,
|
||||
"weather": weather or "?",
|
||||
"forecast_high": forecast_high,
|
||||
}
|
||||
@@ -235,12 +246,40 @@ def _wmo_to_weather(code: Any) -> str:
|
||||
return "阴"
|
||||
|
||||
|
||||
def _build_ai_prompt(cities_data: List[Dict[str, Any]], report_date: str) -> str:
|
||||
lines = [f"今天是 {report_date}。请用自然亲切的中文写一段天气日报。\n"]
|
||||
lines.append("城市天气数据:")
|
||||
def _build_ai_prompt(
|
||||
cities_data: List[Dict[str, Any]],
|
||||
report_date: str,
|
||||
language: Optional[str] = None,
|
||||
) -> str:
|
||||
language = normalize_push_language(language or _daily_report_language())
|
||||
if language == "zh":
|
||||
lines = [f"今天是 {report_date}。请用自然亲切的中文写一段天气日报。\n"]
|
||||
lines.append("城市天气数据:")
|
||||
for c in cities_data:
|
||||
lines.append(f"{c['name']}:{c['weather']},最高{c['forecast_high']}度")
|
||||
lines.append("\n要求:每城一行播报,城市名<b>加粗</b>,开头问候,禁止结尾废话。")
|
||||
return "\n".join(lines)
|
||||
|
||||
if language == "en":
|
||||
lines = [f"Today is {report_date}. Write a concise Telegram weather briefing in English.\n"]
|
||||
lines.append("City weather data:")
|
||||
for c in cities_data:
|
||||
lines.append(
|
||||
f"{c.get('name_en') or c['city'].title()}: weather={c['weather']}, high={c['forecast_high']}°C"
|
||||
)
|
||||
lines.append("\nRequirements: one line per city, bold city names with <b>, start with a short greeting, no generic closing.")
|
||||
return "\n".join(lines)
|
||||
|
||||
lines = [f"Today is {report_date}. Write a bilingual Telegram weather briefing.\n"]
|
||||
lines.append("City weather data:")
|
||||
for c in cities_data:
|
||||
lines.append(f"{c['name']}:{c['weather']},最高{c['forecast_high']}度")
|
||||
lines.append("\n要求:每城一行播报,城市名<b>加粗</b>,开头问候,禁止结尾废话。")
|
||||
lines.append(
|
||||
f"{c.get('name_en') or c['city'].title()} / {c['name']}: weather={c['weather']}, high={c['forecast_high']}°C"
|
||||
)
|
||||
lines.append(
|
||||
"\nRequirements: one line per city, English first then Chinese in the same line, "
|
||||
"bold city names with <b>, start with a short bilingual greeting, no generic closing."
|
||||
)
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
@@ -352,8 +391,9 @@ def _runner(bot: Any, config: Dict[str, Any]) -> None:
|
||||
time.sleep(60)
|
||||
continue
|
||||
|
||||
language = _daily_report_language()
|
||||
report_date = now.strftime("%m月%d日")
|
||||
prompt = _build_ai_prompt(cities_data, report_date)
|
||||
prompt = _build_ai_prompt(cities_data, report_date, language=language)
|
||||
report_text = _call_ai(prompt)
|
||||
|
||||
if not report_text:
|
||||
@@ -363,7 +403,11 @@ def _runner(bot: Any, config: Dict[str, Any]) -> None:
|
||||
continue
|
||||
|
||||
try:
|
||||
report_text += "\n\n⚠️ 以上为粗略预测,仅供参考。"
|
||||
report_text += "\n\n" + copy_text(
|
||||
language,
|
||||
"⚠️ Rough forecast only. For reference.",
|
||||
"⚠️ 以上为粗略预测,仅供参考。",
|
||||
)
|
||||
bot.send_message(
|
||||
FORUM_CHAT_ID,
|
||||
report_text,
|
||||
|
||||
Reference in New Issue
Block a user