接入 Cloudflare 免费能力并修正跑道日高

This commit is contained in:
2569718930@qq.com
2026-06-16 03:59:01 +08:00
parent 7756b137a2
commit f9d3fc2d96
12 changed files with 342 additions and 5 deletions
+73 -5
View File
@@ -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