接入 Cloudflare 免费能力并修正跑道日高
This commit is contained in:
@@ -5,7 +5,7 @@ import re
|
||||
import threading
|
||||
import time
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from datetime import datetime, timezone
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import Any, Dict, List, Optional, Set, Tuple
|
||||
|
||||
import requests as requests_lib
|
||||
@@ -19,6 +19,7 @@ from src.database.runtime_state import (
|
||||
)
|
||||
from src.data_collection.city_registry import ALIASES
|
||||
from src.data_collection.city_registry import CITY_REGISTRY
|
||||
from src.data_collection.city_time import get_city_utc_offset_seconds
|
||||
from src.utils.telegram_chat_ids import get_telegram_chat_ids_from_env, parse_telegram_chat_ids
|
||||
from src.utils.telegram_i18n import (
|
||||
copy_text as _copy,
|
||||
@@ -1494,15 +1495,78 @@ def _get_airport_daily_high(city_weather: Dict[str, Any]):
|
||||
return max_so_far, max_time
|
||||
|
||||
|
||||
def _runway_history_point_local_date(point: Dict[str, Any], utc_offset_seconds: int) -> str:
|
||||
raw_time = (
|
||||
point.get("time")
|
||||
or point.get("timestamp")
|
||||
or point.get("observed_at")
|
||||
or point.get("otime_utc")
|
||||
or ""
|
||||
)
|
||||
parsed = _parse_iso_datetime_utc(raw_time)
|
||||
if parsed is None:
|
||||
return ""
|
||||
return (parsed + timedelta(seconds=utc_offset_seconds)).date().isoformat()
|
||||
|
||||
|
||||
def _today_runway_history_points(
|
||||
points: Any,
|
||||
*,
|
||||
local_date: str,
|
||||
utc_offset_seconds: int,
|
||||
) -> List[Dict[str, Any]]:
|
||||
if not isinstance(points, list):
|
||||
return []
|
||||
if not local_date:
|
||||
return [p for p in points if isinstance(p, dict)]
|
||||
return [
|
||||
p
|
||||
for p in points
|
||||
if isinstance(p, dict)
|
||||
and _runway_history_point_local_date(p, utc_offset_seconds) == local_date
|
||||
]
|
||||
|
||||
|
||||
def _runway_history_context(city_weather: Dict[str, Any], city: str) -> Tuple[str, int]:
|
||||
local_date = str(city_weather.get("local_date") or "").strip()
|
||||
anchor_values = [
|
||||
(city_weather.get("amos") or {}).get("observation_time"),
|
||||
(city_weather.get("airport_primary") or {}).get("obs_time"),
|
||||
(city_weather.get("airport_current") or {}).get("obs_time"),
|
||||
(city_weather.get("current") or {}).get("observed_at"),
|
||||
(city_weather.get("canonical_temperature") or {}).get("observed_at"),
|
||||
]
|
||||
anchor_dt = next(
|
||||
(parsed for parsed in (_parse_iso_datetime_utc(value) for value in anchor_values) if parsed is not None),
|
||||
None,
|
||||
)
|
||||
try:
|
||||
utc_offset_seconds = int(
|
||||
city_weather.get("utc_offset_seconds")
|
||||
if city_weather.get("utc_offset_seconds") is not None
|
||||
else get_city_utc_offset_seconds(city, anchor_dt),
|
||||
)
|
||||
except Exception:
|
||||
utc_offset_seconds = 0
|
||||
if not local_date and anchor_dt is not None:
|
||||
local_date = (anchor_dt + timedelta(seconds=utc_offset_seconds)).date().isoformat()
|
||||
return local_date, utc_offset_seconds
|
||||
|
||||
|
||||
def _runway_history_daily_max(city_weather: Dict[str, Any], city: str) -> Optional[float]:
|
||||
"""Compute today's runway high from runway_plate_history."""
|
||||
"""Compute today's local-date runway high from runway_plate_history."""
|
||||
history = city_weather.get("runway_plate_history")
|
||||
if not isinstance(history, dict) or not history:
|
||||
return None
|
||||
local_date, utc_offset_seconds = _runway_history_context(city_weather, city)
|
||||
settlement_pair = _settlement_runway_for_city(city)
|
||||
if settlement_pair:
|
||||
settlement_key = f"{settlement_pair[0]}/{settlement_pair[1]}"
|
||||
settlement_pts = history.get(settlement_key)
|
||||
settlement_pts = _today_runway_history_points(
|
||||
history.get(settlement_key),
|
||||
local_date=local_date,
|
||||
utc_offset_seconds=utc_offset_seconds,
|
||||
)
|
||||
if settlement_pts:
|
||||
temps = [p.get("temp") for p in settlement_pts if isinstance(p, dict) and p.get("temp") is not None]
|
||||
if temps:
|
||||
@@ -1510,8 +1574,12 @@ def _runway_history_daily_max(city_weather: Dict[str, Any], city: str) -> Option
|
||||
# Fallback: max across all runways
|
||||
all_temps = []
|
||||
for pts in history.values():
|
||||
if isinstance(pts, list):
|
||||
all_temps.extend(p.get("temp") for p in pts if isinstance(p, dict) and p.get("temp") is not None)
|
||||
today_pts = _today_runway_history_points(
|
||||
pts,
|
||||
local_date=local_date,
|
||||
utc_offset_seconds=utc_offset_seconds,
|
||||
)
|
||||
all_temps.extend(p.get("temp") for p in today_pts if p.get("temp") is not None)
|
||||
return round(max(all_temps), 1) if all_temps else None
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user