d5279b124f
Storage Persistence Guard / storage-persistence-audit (push) Has been cancelled
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled
Client Quality Gates / Shared client and Web (pull_request) Has been cancelled
Client Quality Gates / macOS Desktop (pull_request) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (pull_request) Has been cancelled
176 lines
5.4 KiB
Python
176 lines
5.4 KiB
Python
"""Canonical map metadata for monitoring source locations.
|
|
|
|
ip2region provides administrative names but no coordinates. This module keeps
|
|
the normalization and centroid contract on the server so web and desktop
|
|
clients render the same location semantics.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
|
|
from app.services.ip_location import IpLocation
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class GeoLocationMetadata:
|
|
country: str
|
|
country_code: str
|
|
region_code: str
|
|
longitude: float | None
|
|
latitude: float | None
|
|
accuracy_level: str
|
|
|
|
|
|
COUNTRY_ALIASES = {
|
|
"中国": "China",
|
|
"China": "China",
|
|
"Mainland China": "China",
|
|
"中国香港": "China",
|
|
"中国澳门": "China",
|
|
"中国台湾": "China",
|
|
"美国": "United States",
|
|
"United States": "United States",
|
|
"United States of America": "United States",
|
|
"USA": "United States",
|
|
"土耳其": "Türkiye",
|
|
"Turkey": "Türkiye",
|
|
"Türkiye": "Türkiye",
|
|
}
|
|
|
|
COUNTRY_CODES = {
|
|
"China": "CN",
|
|
"United States": "US",
|
|
"Netherlands": "NL",
|
|
"Türkiye": "TR",
|
|
"Australia": "AU",
|
|
"Japan": "JP",
|
|
"Singapore": "SG",
|
|
"Germany": "DE",
|
|
"France": "FR",
|
|
"United Kingdom": "GB",
|
|
"Canada": "CA",
|
|
"India": "IN",
|
|
"Russia": "RU",
|
|
}
|
|
|
|
COUNTRY_CENTROIDS = {
|
|
"China": (104.1954, 35.8617),
|
|
"United States": (-95.7129, 37.0902),
|
|
"Netherlands": (5.2913, 52.1326),
|
|
"Türkiye": (35.2433, 38.9637),
|
|
"Australia": (133.7751, -25.2744),
|
|
"Japan": (138.2529, 36.2048),
|
|
"Singapore": (103.8198, 1.3521),
|
|
"Germany": (10.4515, 51.1657),
|
|
"France": (2.2137, 46.2276),
|
|
"United Kingdom": (-3.436, 55.3781),
|
|
"Canada": (-106.3468, 56.1304),
|
|
"India": (78.9629, 20.5937),
|
|
"Russia": (105.3188, 61.524),
|
|
}
|
|
|
|
CHINA_REGION_METADATA = {
|
|
"北京市": ("CN-BJ", 116.4074, 39.9042),
|
|
"天津市": ("CN-TJ", 117.2008, 39.0842),
|
|
"河北省": ("CN-HE", 114.5025, 38.0455),
|
|
"山西省": ("CN-SX", 112.5492, 37.857),
|
|
"内蒙古自治区": ("CN-NM", 111.6708, 40.8183),
|
|
"辽宁省": ("CN-LN", 123.4315, 41.8057),
|
|
"吉林省": ("CN-JL", 125.3245, 43.8868),
|
|
"黑龙江省": ("CN-HL", 126.6424, 45.7567),
|
|
"上海市": ("CN-SH", 121.4737, 31.2304),
|
|
"江苏省": ("CN-JS", 118.7633, 32.0617),
|
|
"浙江省": ("CN-ZJ", 120.1551, 30.2741),
|
|
"安徽省": ("CN-AH", 117.2272, 31.8206),
|
|
"福建省": ("CN-FJ", 119.2965, 26.0745),
|
|
"江西省": ("CN-JX", 115.8582, 28.682),
|
|
"山东省": ("CN-SD", 117.1201, 36.6512),
|
|
"河南省": ("CN-HA", 113.6254, 34.7466),
|
|
"湖北省": ("CN-HB", 114.3055, 30.5928),
|
|
"湖南省": ("CN-HN", 112.9388, 28.2282),
|
|
"广东省": ("CN-GD", 113.2644, 23.1291),
|
|
"广西壮族自治区": ("CN-GX", 108.3669, 22.817),
|
|
"海南省": ("CN-HI", 110.3312, 20.0311),
|
|
"重庆": ("CN-CQ", 106.5516, 29.563),
|
|
"重庆市": ("CN-CQ", 106.5516, 29.563),
|
|
"四川省": ("CN-SC", 104.0665, 30.5723),
|
|
"贵州省": ("CN-GZ", 106.6302, 26.647),
|
|
"云南省": ("CN-YN", 102.8329, 24.8801),
|
|
"西藏自治区": ("CN-XZ", 91.1322, 29.6604),
|
|
"陕西省": ("CN-SN", 108.9398, 34.3416),
|
|
"甘肃省": ("CN-GS", 103.8343, 36.0611),
|
|
"青海省": ("CN-QH", 101.7782, 36.6171),
|
|
"宁夏回族自治区": ("CN-NX", 106.2309, 38.4872),
|
|
"新疆维吾尔自治区": ("CN-XJ", 87.6168, 43.8256),
|
|
"台湾省": ("CN-TW", 121.5654, 25.033),
|
|
"香港特别行政区": ("CN-HK", 114.1694, 22.3193),
|
|
"澳门特别行政区": ("CN-MO", 113.5439, 22.1987),
|
|
}
|
|
|
|
CITY_CENTROIDS = {
|
|
"南京": (118.7969, 32.0603),
|
|
"南京市": (118.7969, 32.0603),
|
|
"San Jose": (-121.8863, 37.3382),
|
|
"South Holland": (4.493, 52.0208),
|
|
"Istanbul": (28.9784, 41.0082),
|
|
}
|
|
|
|
|
|
def resolve_geo_location_metadata(location: IpLocation) -> GeoLocationMetadata:
|
|
if location.location in {"局域网", "本机"}:
|
|
return GeoLocationMetadata(
|
|
country="",
|
|
country_code="PRIVATE",
|
|
region_code="PRIVATE",
|
|
longitude=None,
|
|
latitude=None,
|
|
accuracy_level="private",
|
|
)
|
|
|
|
country = COUNTRY_ALIASES.get(location.country, location.country)
|
|
country_code = COUNTRY_CODES.get(country, "")
|
|
|
|
city_coordinate = CITY_CENTROIDS.get(location.city)
|
|
if city_coordinate:
|
|
return GeoLocationMetadata(
|
|
country=country,
|
|
country_code=country_code,
|
|
region_code="",
|
|
longitude=city_coordinate[0],
|
|
latitude=city_coordinate[1],
|
|
accuracy_level="city",
|
|
)
|
|
|
|
region_metadata = CHINA_REGION_METADATA.get(location.province)
|
|
if country in {"China", "中国"} and region_metadata:
|
|
region_code, longitude, latitude = region_metadata
|
|
return GeoLocationMetadata(
|
|
country="China",
|
|
country_code="CN",
|
|
region_code=region_code,
|
|
longitude=longitude,
|
|
latitude=latitude,
|
|
accuracy_level="region",
|
|
)
|
|
|
|
country_coordinate = COUNTRY_CENTROIDS.get(country)
|
|
if country_coordinate:
|
|
return GeoLocationMetadata(
|
|
country=country,
|
|
country_code=country_code,
|
|
region_code="",
|
|
longitude=country_coordinate[0],
|
|
latitude=country_coordinate[1],
|
|
accuracy_level="country",
|
|
)
|
|
|
|
return GeoLocationMetadata(
|
|
country=country,
|
|
country_code=country_code,
|
|
region_code="",
|
|
longitude=None,
|
|
latitude=None,
|
|
accuracy_level="unknown",
|
|
)
|