From c18ff504e495554fd2111e2c62406eef8f5da579 Mon Sep 17 00:00:00 2001
From: "2569718930@qq.com" <2569718930@qq.com>
Date: Sat, 23 May 2026 10:13:16 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20CMA=20=E6=B8=A9=E5=BA=A6?=
=?UTF-8?q?=E6=8F=90=E5=8F=96=EF=BC=9A=E6=94=B9=E7=94=A8=E7=BA=AF=E6=96=87?=
=?UTF-8?q?=E6=9C=AC=E6=95=B0=E5=AD=97=E5=8C=B9=E9=85=8D=E6=9B=BF=E4=BB=A3?=
=?UTF-8?q?=20HTML=20=E6=A0=87=E7=AD=BE=E7=8C=9C=E6=B5=8B=EF=BC=8C?=
=?UTF-8?q?=E5=A4=A9=E6=B0=94=E4=BC=98=E5=85=88=20CMA=E3=80=81=E6=B8=A9?=
=?UTF-8?q?=E5=BA=A6=E5=9B=9E=E9=80=80=20OM?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/utils/daily_weather_report.py | 104 ++++++++++++++----------------
1 file changed, 48 insertions(+), 56 deletions(-)
diff --git a/src/utils/daily_weather_report.py b/src/utils/daily_weather_report.py
index aaec86f6..62719ad2 100644
--- a/src/utils/daily_weather_report.py
+++ b/src/utils/daily_weather_report.py
@@ -115,14 +115,13 @@ def _fetch_cma_forecast(city_key: str) -> Optional[Dict[str, Any]]:
low_str: Optional[str] = None
if tem_text:
- # Patterns: 25℃ or 25°C
- high_match = re.search(r"]*>(-?\d+)\s*(?:℃|°C|°c)?", tem_text)
- if high_match:
- high_str = high_match.group(1)
- # Night temp in : 19℃
- low_match = re.search(r"]*>(-?\d+)\s*(?:℃|°C|°c)?", tem_text)
- if low_match:
- low_str = low_match.group(1)
+ # Strip all HTML tags, then find numbers followed by degree
+ clean = re.sub(r"<[^>]+>", " ", tem_text)
+ nums = re.findall(r"(-?\d+)\s*(?:℃|°C|°c|°)?", clean)
+ if len(nums) >= 1:
+ high_str = nums[0]
+ if len(nums) >= 2:
+ low_str = nums[1]
if not weather and not high_str:
return None
@@ -161,64 +160,57 @@ def _fetch_city_data(
) -> Optional[Dict[str, Any]]:
name = CITY_NAME_ZH.get(city_key, city_key)
- # 1. Try CMA first for weather description + official forecast high
+ # 1. Try CMA first for weather description
cma = _fetch_cma_forecast(city_key)
- if cma and cma.get("weather") and cma.get("forecast_high") is not None:
- logger.info(
- "daily_weather_report: {} using CMA weather={} high={}",
- city_key,
- cma["weather"],
- cma["forecast_high"],
- )
- return {
- "city": city_key,
- "name": name,
- "weather": cma["weather"],
- "forecast_high": cma["forecast_high"],
- }
- # 2. Fall back to Open-Meteo
+ # 2. Get Open-Meteo data for temperature fallback
+ om_high = None
info = CITY_REGISTRY.get(city_key)
- if not info:
- return None
+ if info:
+ try:
+ results = collector.fetch_all_sources(
+ city_key,
+ lat=info["lat"],
+ lon=info["lon"],
+ include_taf=False,
+ include_ensemble=False,
+ include_multi_model=False,
+ )
+ if isinstance(results, dict):
+ om = results.get("open-meteo", {})
+ daily = om.get("daily", {}) if isinstance(om, dict) else {}
+ daily_highs = daily.get("temperature_2m_max", []) or []
+ om_high = daily_highs[0] if daily_highs else None
+ except Exception as exc:
+ logger.warning(
+ "daily_weather_report: OM fetch failed for {}: {}", city_key, exc
+ )
- try:
- results = collector.fetch_all_sources(
- city_key,
- lat=info["lat"],
- lon=info["lon"],
- include_taf=False,
- include_ensemble=False,
- include_multi_model=False,
- )
- except Exception as exc:
- logger.warning(f"daily_weather_report: OM fetch failed for {city_key}: {exc}")
- return None
+ # Use CMA weather + CMA high, fall back to OM high
+ weather: Optional[str] = None
+ forecast_high: Optional[float] = None
- if not isinstance(results, dict):
- return None
-
- om = results.get("open-meteo", {}) if isinstance(results, dict) else {}
- current = om.get("current_weather", {}) if isinstance(om, dict) else {}
- daily = om.get("daily", {}) if isinstance(om, dict) else {}
-
- daily_highs = daily.get("temperature_2m_max", []) or []
- today_high = daily_highs[0] if daily_highs else None
-
- # Use CMA weather if available, fall back to WMO code translation
- weather = (
- cma.get("weather")
- if (cma and cma.get("weather"))
- else _wmo_to_weather(current.get("weathercode"))
- )
- forecast_high = cma.get("forecast_high") if cma else None
+ if cma:
+ weather = cma.get("weather")
+ forecast_high = cma.get("forecast_high")
if forecast_high is None:
- forecast_high = today_high
+ forecast_high = om_high
+
+ if not weather and not forecast_high:
+ return None
+
+ logger.info(
+ "daily_weather_report: {} weather={} high={} (cma_ok={})",
+ city_key,
+ weather or "?",
+ forecast_high,
+ bool(cma and cma.get("weather")),
+ )
return {
"city": city_key,
"name": name,
- "weather": weather,
+ "weather": weather or "?",
"forecast_high": forecast_high,
}