fix: MMDB中文路径解决方案 + 聚类优先使用最新GeoIP数据
- geoip.py: maxminddb C库不支持Windows中文路径,复制MMDB到ASCII临时目录 - views.py: _cluster_network 优先用 geoip_lookup()(MMDB) 而非上传时缓存(text) - 效果: IP地理坐标从 ~55城市粗定位 → 全球百万级精确城市定位 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+16
-2
@@ -12,6 +12,7 @@ import bisect
|
||||
import gzip
|
||||
import logging
|
||||
import shutil
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
@@ -107,11 +108,24 @@ def _load_mmdb() -> None:
|
||||
|
||||
try:
|
||||
import maxminddb
|
||||
_mmdb_city = maxminddb.open_database(city_path)
|
||||
|
||||
# maxminddb C extension cannot handle non-ASCII Windows paths.
|
||||
# Workaround: copy MMDB files to a temp dir with ASCII-only path.
|
||||
_tmp_dir = Path(tempfile.gettempdir()) / 'tianxuan_geoip'
|
||||
_tmp_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
_tmp_city = _tmp_dir / 'GeoLite2-City.mmdb'
|
||||
if not _tmp_city.exists() or _tmp_city.stat().st_size != city_path.stat().st_size:
|
||||
logger.info('[GEOIP] copying MMDB to ASCII-safe temp dir …')
|
||||
shutil.copy2(city_path, _tmp_city)
|
||||
_mmdb_city = maxminddb.open_database(str(_tmp_city))
|
||||
logger.info('[GEOIP] loaded GeoLite2-City.mmdb (MMDB format)')
|
||||
|
||||
if asn_path.exists():
|
||||
_mmdb_asn = maxminddb.open_database(asn_path)
|
||||
_tmp_asn = _tmp_dir / 'GeoLite2-ASN.mmdb'
|
||||
if not _tmp_asn.exists() or _tmp_asn.stat().st_size != asn_path.stat().st_size:
|
||||
shutil.copy2(asn_path, _tmp_asn)
|
||||
_mmdb_asn = maxminddb.open_database(str(_tmp_asn))
|
||||
logger.info('[GEOIP] loaded GeoLite2-ASN.mmdb (ISP/ORG)')
|
||||
except Exception as e:
|
||||
logger.warning('[GEOIP] failed to open MMDB: %s', e)
|
||||
|
||||
@@ -792,11 +792,12 @@ def _cluster_network(entry: dict, df: pl.DataFrame, meta: dict,
|
||||
logger.info('Network clustering: %d unique IPs from %d records', n_nodes, len(df))
|
||||
|
||||
# ── 2. GeoIP 解析所有 IP ───────────────────────────────────────────
|
||||
# MMDB优先(高精度),upload时的geo_cache兜底(低精度文本回退)
|
||||
node_geo = {} # ip → {lat, lon, city, country, isp, org}
|
||||
for ip in unique_ips:
|
||||
info = geo_cache.get(ip)
|
||||
info = geoip_lookup(ip) # 优先用当前加载的MMDB数据库
|
||||
if not info:
|
||||
info = geoip_lookup(ip)
|
||||
info = geo_cache.get(ip) # 回退到上传时的缓存
|
||||
if info:
|
||||
node_geo[ip] = info
|
||||
|
||||
|
||||
Reference in New Issue
Block a user