mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-10 06:23:15 +08:00
本次迁移将网关/通道/工具/技能/脚本与协议资源集中到新结构,统一路径常量与脚本转发机制,减少顶层噪音并保证运行与测试行为一致。 Made-with: Cursor
66 lines
2.2 KiB
Python
66 lines
2.2 KiB
Python
"""系统工具共用 HTTP 辅助函数(Nominatim 逆地理编码与 ipapi.co)。"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from typing import Any
|
||
|
||
import httpx
|
||
|
||
NOMINATIM_REQUEST_HEADERS = {"User-Agent": "OpsAssistant/1.0 (internal tool)"}
|
||
DEFAULT_HTTP_TIMEOUT = 10.0
|
||
|
||
|
||
def nominatim_reverse(
|
||
client: httpx.Client,
|
||
lat: float,
|
||
lon: float,
|
||
*,
|
||
accept_language: str = "en",
|
||
) -> dict[str, Any]:
|
||
"""调用 Nominatim 逆地理编码并返回解析后的 JSON,失败时返回空字典。"""
|
||
try:
|
||
r = client.get(
|
||
"https://nominatim.openstreetmap.org/reverse",
|
||
params={"lat": lat, "lon": lon, "format": "json", "accept-language": accept_language},
|
||
headers=NOMINATIM_REQUEST_HEADERS,
|
||
)
|
||
r.raise_for_status()
|
||
data = r.json()
|
||
return data if isinstance(data, dict) else {}
|
||
except Exception:
|
||
return {}
|
||
|
||
|
||
def ipapi_approximate_location(client: httpx.Client) -> dict[str, Any] | None:
|
||
try:
|
||
ip_resp = client.get("https://ipapi.co/json/")
|
||
ip_resp.raise_for_status()
|
||
ip_data = ip_resp.json()
|
||
lat = ip_data.get("latitude")
|
||
lon = ip_data.get("longitude")
|
||
if lat is None or lon is None:
|
||
return None
|
||
lat_f = float(lat)
|
||
lon_f = float(lon)
|
||
geo = nominatim_reverse(client, lat_f, lon_f)
|
||
display_name = geo.get("display_name") if geo else None
|
||
if not display_name or not str(display_name).strip():
|
||
parts = [ip_data.get("city"), ip_data.get("region"), ip_data.get("country_name")]
|
||
display_name = ", ".join(str(p) for p in parts if p)
|
||
if not display_name:
|
||
display_name = f"Approximate ({lat_f:.4f}, {lon_f:.4f})"
|
||
return {
|
||
"latitude": lat_f,
|
||
"longitude": lon_f,
|
||
"display_name": str(display_name).strip(),
|
||
"ip": ip_data.get("ip"),
|
||
"city": ip_data.get("city"),
|
||
"region": ip_data.get("region"),
|
||
"country_name": ip_data.get("country_name"),
|
||
"nominatim": geo,
|
||
}
|
||
except Exception:
|
||
return None
|
||
|
||
|
||
__all__ = ["DEFAULT_HTTP_TIMEOUT", "NOMINATIM_REQUEST_HEADERS", "ipapi_approximate_location", "nominatim_reverse"]
|