feat: Implement initial FastAPI web map API for weather data processing and serving a static frontend.
This commit is contained in:
+16
-3
@@ -116,7 +116,10 @@ def _analyze(city: str) -> Dict[str, Any]:
|
|||||||
mg_cur = mgm.get("current", {}) if mgm else {}
|
mg_cur = mgm.get("current", {}) if mgm else {}
|
||||||
|
|
||||||
cur_temp = _sf(mc.get("temp"))
|
cur_temp = _sf(mc.get("temp"))
|
||||||
if cur_temp is None:
|
# For Ankara, prioritize MGM over METAR as it's often more representative of city center
|
||||||
|
if city_lower == "ankara" and _sf(mg_cur.get("temp")) is not None:
|
||||||
|
cur_temp = _sf(mg_cur.get("temp"))
|
||||||
|
elif cur_temp is None:
|
||||||
cur_temp = _sf(mg_cur.get("temp"))
|
cur_temp = _sf(mg_cur.get("temp"))
|
||||||
|
|
||||||
max_so_far = _sf(mc.get("max_temp_so_far"))
|
max_so_far = _sf(mc.get("max_temp_so_far"))
|
||||||
@@ -354,12 +357,22 @@ def _analyze(city: str) -> Dict[str, Any]:
|
|||||||
if mgm:
|
if mgm:
|
||||||
mgc = mgm.get("current", {})
|
mgc = mgm.get("current", {})
|
||||||
mgm_time_str = mgc.get("time", "")
|
mgm_time_str = mgc.get("time", "")
|
||||||
|
# MGM time is usually "2026-03-04T10:40:00.000Z" (UTC)
|
||||||
if mgm_time_str and "T" in mgm_time_str:
|
if mgm_time_str and "T" in mgm_time_str:
|
||||||
try:
|
try:
|
||||||
dt = datetime.fromisoformat(mgm_time_str.replace("Z", "+00:00"))
|
# Handle ISO format with Z or +00:00
|
||||||
|
ts = mgm_time_str.replace("Z", "+00:00")
|
||||||
|
if "." in ts:
|
||||||
|
# Strip fractional seconds if present to be safe for 3.8
|
||||||
|
base, offset_part = ts.split("+")
|
||||||
|
if "." in base:
|
||||||
|
base = base.split(".")[0]
|
||||||
|
ts = base + "+" + offset_part
|
||||||
|
dt = datetime.fromisoformat(ts)
|
||||||
local_dt = dt.astimezone(timezone(timedelta(seconds=utc_offset)))
|
local_dt = dt.astimezone(timezone(timedelta(seconds=utc_offset)))
|
||||||
mgm_time_str = local_dt.strftime("%H:%M")
|
mgm_time_str = local_dt.strftime("%H:%M")
|
||||||
except Exception:
|
except Exception as e:
|
||||||
|
logger.debug(f"MGM time conversion failed: {e}")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
mgm_data = {
|
mgm_data = {
|
||||||
|
|||||||
+4
-2
@@ -439,8 +439,10 @@ function renderHero(data) {
|
|||||||
if (data.mgm?.temp != null) {
|
if (data.mgm?.temp != null) {
|
||||||
let mgmTimeStr = "";
|
let mgmTimeStr = "";
|
||||||
if (data.mgm.time) {
|
if (data.mgm.time) {
|
||||||
const match = data.mgm.time.match(/T?(\d{2}:\d{2})/);
|
if (data.mgm.time.includes(":")) {
|
||||||
if (match) mgmTimeStr = ` @${match[1]}`;
|
const match = data.mgm.time.match(/T?(\d{2}:\d{2})/);
|
||||||
|
if (match) mgmTimeStr = ` @${match[1]}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
parts.push(
|
parts.push(
|
||||||
`<span style="color:#eab308;font-weight:600;background:rgba(234, 179, 8, 0.1);padding:2px 8px;border-radius:12px;border:1px solid rgba(234, 179, 8, 0.3);">⭐ MGM 实测: ${data.mgm.temp}${sym}${mgmTimeStr}</span>`,
|
`<span style="color:#eab308;font-weight:600;background:rgba(234, 179, 8, 0.1);padding:2px 8px;border-radius:12px;border:1px solid rgba(234, 179, 8, 0.3);">⭐ MGM 实测: ${data.mgm.temp}${sym}${mgmTimeStr}</span>`,
|
||||||
|
|||||||
Reference in New Issue
Block a user