7
7
from user_agents import parse
8
8
9
9
from backend .app .common .log import log
10
+ from backend .app .common .redis import redis_client
10
11
from backend .app .core .conf import settings
11
12
from backend .app .core .path_conf import IP2REGION_XDB
12
13
@@ -47,7 +48,7 @@ async def get_location_online(ip: str, user_agent: str) -> dict | None:
47
48
48
49
49
50
@sync_to_async
50
- def get_location_offline (ip : str ) -> list [ str ] | None :
51
+ def get_location_offline (ip : str ) -> dict | None :
51
52
"""
52
53
离线获取 ip 地址属地,无法保证准确率,100%可用
53
54
@@ -59,8 +60,12 @@ def get_location_offline(ip: str) -> list[str] | None:
59
60
searcher = XdbSearcher (contentBuff = cb )
60
61
data = searcher .search (ip )
61
62
searcher .close ()
62
- location_info = data .split ('|' )
63
- return location_info
63
+ data = data .split ('|' )
64
+ return {
65
+ 'country' : data [0 ] if data [0 ] != '0' else None ,
66
+ 'regionName' : data [2 ] if data [2 ] != '0' else None ,
67
+ 'city' : data [3 ] if data [3 ] != '0' else None ,
68
+ }
64
69
except Exception as e :
65
70
log .error (f'离线获取 ip 地址属地失败,错误信息:{ e } ' )
66
71
return None
@@ -69,18 +74,22 @@ def get_location_offline(ip: str) -> list[str] | None:
69
74
async def parse_ip_info (request : Request ) -> tuple [str , str , str , str ]:
70
75
country , region , city = None , None , None
71
76
ip = await get_request_ip (request )
77
+ location = await redis_client .get (f'{ settings .IP_LOCATION_REDIS_PREFIX } :{ ip } ' )
78
+ if location :
79
+ country , region , city = location .split (' ' )
80
+ return ip , country , region , city
72
81
if settings .LOCATION_PARSE == 'online' :
73
82
location_info = await get_location_online (ip , request .headers .get ('User-Agent' ))
74
- if location_info :
75
- country = location_info .get ('country' )
76
- region = location_info .get ('regionName' )
77
- city = location_info .get ('city' )
78
83
elif settings .LOCATION_PARSE == 'offline' :
79
84
location_info = await get_location_offline (ip )
80
- if location_info :
81
- country = location_info [0 ] if location_info [0 ] != '0' else None
82
- region = location_info [2 ] if location_info [2 ] != '0' else None
83
- city = location_info [3 ] if location_info [3 ] != '0' else None
85
+ else :
86
+ location_info = None
87
+ if location_info :
88
+ country = location_info .get ('country' )
89
+ region = location_info .get ('regionName' )
90
+ city = location_info .get ('city' )
91
+ await redis_client .set (f'{ settings .IP_LOCATION_REDIS_PREFIX } :{ ip } ' , f'{ country } { region } { city } ' ,
92
+ ex = settings .IP_LOCATION_EXPIRE_SECONDS )
84
93
return ip , country , region , city
85
94
86
95
0 commit comments