Show device country next to its IP address, resolved via ip-api.com

This commit is contained in:
ubuntu
2026-08-16 10:39:17 +00:00
parent 7a5dba7dbf
commit 10fd5106f8
2 changed files with 60 additions and 7 deletions
+50 -6
View File
@@ -31,6 +31,7 @@ import pathlib
from datetime import datetime
from bson import ObjectId
import urllib.request
import ipaddress
@@ -75,6 +76,8 @@ settings_collection = db_iptv['settings']
devices_db = db_iptv['devices']
devices = []
active_xtream_imports = {}
sio_session_ips = {}
ip_country_cache = {}
# Configure Socket IO
sio = socketio.AsyncServer(logger=True, engineio_logger=True, cors_allowed_origins='*')
@@ -1417,6 +1420,34 @@ app.router.add_post('/gemini_search', gemini_search)
app.router.add_get('/channels_epg', channels_epg)
app.router.add_get('/epg', epg_programs)
def resolve_ip_country(ip_address):
if not ip_address:
return ''
if ip_address in ip_country_cache:
return ip_country_cache[ip_address]
try:
ip_obj = ipaddress.ip_address(ip_address)
if ip_obj.is_private or ip_obj.is_loopback or ip_obj.is_link_local:
ip_country_cache[ip_address] = ''
return ''
except ValueError:
return ''
country = ''
try:
response = requests.get(
f'http://ip-api.com/json/{ip_address}',
params={'fields': 'status,country'},
timeout=5,
)
data = response.json()
if data.get('status') == 'success':
country = data.get('country', '') or ''
except requests.RequestException as exc:
logger.warning("IP country lookup failed for %s: %s", ip_address, exc)
ip_country_cache[ip_address] = country
return country
# SIO FUNCTIONS
def messageReceived():
@@ -1424,7 +1455,12 @@ def messageReceived():
@sio.event
def connect(sid, environ):
print("connect ", sid, flush=True)
# engineio's aiohttp integration hardcodes REMOTE_ADDR to 127.0.0.1;
# the real peer address is only available via the underlying aiohttp request.
aiohttp_request = environ.get('aiohttp.request')
ip_address = aiohttp_request.remote if aiohttp_request else ''
sio_session_ips[sid] = ip_address
print("connect ", sid, ip_address, flush=True)
@sio.event
@@ -1432,11 +1468,12 @@ async def communication(fromSid, data):
print("search request from ", fromSid, flush=True)
toSidDevice = data['toSidDevice']
print("send signal to ", toSidDevice, flush=True)
await sio.emit('communication', data, room=toSidDevice ,callback=messageReceived)
await sio.emit('communication', data, room=toSidDevice ,callback=messageReceived)
@sio.event
def disconnect(sid):
sio_session_ips.pop(sid, None)
print('disconnect ', sid, flush=True)
@@ -1455,14 +1492,21 @@ async def polling(sid, data):
try:
vpn_status = data['vpn_status']
except:
vpn_status = 'unknown'
device_data = devices_db.find_one({ 'id_device':IdDevice})
vpn_status = 'unknown'
ip_address = sio_session_ips.get(sid, '')
if ip_address in ip_country_cache:
ip_country = ip_country_cache[ip_address]
else:
ip_country = await asyncio.get_event_loop().run_in_executor(None, resolve_ip_country, ip_address)
device_data = devices_db.find_one({ 'id_device':IdDevice})
if device_data:
query = { 'id_device':IdDevice}
update = { "$set": { "last_datetime": device_last_datetime ,"name": device_name, "sid":sid, "mediaRunning":mediaRunning, 'vpn_status':vpn_status, 'data_running':data_running, 'auto_snapshot_enabled': auto_snapshot_enabled, 'snapshot_interval_seconds': snapshot_interval_seconds} }
update = { "$set": { "last_datetime": device_last_datetime ,"name": device_name, "sid":sid, "mediaRunning":mediaRunning, 'vpn_status':vpn_status, 'data_running':data_running, 'auto_snapshot_enabled': auto_snapshot_enabled, 'snapshot_interval_seconds': snapshot_interval_seconds, 'ip_address': ip_address, 'ip_country': ip_country} }
devices_db.update_one(query, update)
else:
new_device = { 'id_device': IdDevice, 'name' : device_name, 'last_datetime' : device_last_datetime, 'sid':sid ,'mediaRunning' : mediaRunning, 'vpn_status':vpn_status, 'data_running':data_running, 'auto_snapshot_enabled': auto_snapshot_enabled, 'snapshot_interval_seconds': snapshot_interval_seconds}
new_device = { 'id_device': IdDevice, 'name' : device_name, 'last_datetime' : device_last_datetime, 'sid':sid ,'mediaRunning' : mediaRunning, 'vpn_status':vpn_status, 'data_running':data_running, 'auto_snapshot_enabled': auto_snapshot_enabled, 'snapshot_interval_seconds': snapshot_interval_seconds, 'ip_address': ip_address, 'ip_country': ip_country}
devices_db.insert_one(new_device)
if data_running: