Compare commits

...
2 Commits
Author SHA1 Message Date
ubuntuandClaude Sonnet 5 2eaa0fee64 Remove dead code and tighten error handling
- Drop analyse_m3u_file2: an unrouted, unused ~90%-duplicate of
  analyse_m3u_file (a bug fixed in one would never apply to the other).
- Drop the in-memory `devices` list from polling/list_devices: it was
  only ever written to, never read (list_devices already returns from
  devices_db, the real source of truth).
- Remove the resulting unused NUM_MAX_CHANNEL variable and duplicate
  `from pymongo import MongoClient` import.
- Narrow a bare `except:` to `except KeyError:` so it can't also
  swallow SystemExit/KeyboardInterrupt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 23:36:07 +00:00
ubuntuandClaude Sonnet 5 3eff9519db Stop Xtream imports from freezing the server while fetching from the provider
run_xtream_import made 6 sequential synchronous requests.get() calls
(60s timeout each) directly inside an asyncio task, so the whole
event loop — and every other request/socket the server was handling
— stalled for the full duration of each Xtream import, same failure
mode as the logo-download freeze fixed earlier. Run them through
run_in_executor instead so the loop stays free.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 23:35:57 +00:00
+13 -154
View File
@@ -33,10 +33,6 @@ import urllib.request
import ipaddress
from pymongo import MongoClient
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)s %(message)s",
@@ -74,7 +70,6 @@ settings_collection = db_iptv['settings']
devices_db = db_iptv['devices']
MAX_STREAMING_ERRORS_PER_DEVICE = 5
devices = []
active_xtream_imports = {}
sio_session_ips = {}
ip_country_cache = {}
@@ -445,8 +440,6 @@ async def init_db(request):
async def analyse_m3u_file(request):
NUM_MAX_CHANNEL = 300000
data = await request.post()
id_playlist = data['id_playlist']
title_playlist = data['title']
@@ -554,120 +547,6 @@ async def analyse_m3u_file(request):
return web.json_response(result)
async def analyse_m3u_file2(request):
NUM_MAX_CHANNEL = 300000
data = await request.post()
id_playlist = data['id_playlist']
title_playlist = data['title']
url_playlist = data['url']
date_end_playlist = data['date_end']
filename = data['filename']
sidClient = data['sidClient']
playlist_comment = data.get('comment', '').strip()
new_path_filename = "./" + UPLOAD_PLAYLIST_DIR + '/' + id_playlist + '.m3u'
old_path_filename = "./" + UPLOAD_PLAYLIST_DIR + '/' +filename
os.rename(old_path_filename,new_path_filename)
collection_channels = get_playlist_collection(id_playlist)
collection_channels.drop()
new_playlist = build_playlist_document(
id_playlist,
title_playlist,
date_end_playlist,
'',
{
'playlist_type': 'm3u',
'url_playlist': url_playlist,
'comment': playlist_comment,
'xtream_server': '',
'xtream_username': '',
'xtream_password': '',
}
)
save_playlist_document(new_playlist)
# Process the m3u file
TypeLangChannel = ['EN','FR','US','CA', 'UK' ]
new_channels =[]
f = open(new_path_filename, "r", encoding="utf8")
Lines = f.readlines()
print('ouverture fichier', flush=True)
channel = {}
separator = '--------'
topic = ''
num_channel = 0
total_lines = len(Lines)
number_line = 0
for line in Lines:
number_line += 1
if separator in line:
topic = line[10:]
topic = topic.replace(separator,'')
if len(channel)>0 and line[0:4]=="http":
channel["url"] = line.strip('\n')
if len(LanguageChannel) > 0:
new_channels.append(channel)
print(num_channel, flush=True)
if num_channel % 1000 == 0:
bulk_insert_channels(collection_channels, new_channels, num_channel)
new_channels = []
print('%d / %d' % (number_line, total_lines), flush=True)
if line[0:4] == "#EXT":
channel = {}
# DEFINE CHANNEL NAME
name_channel = line[line.rfind(',')+1:].strip('\n')
id_channel = str(uuid.uuid4())
LanguageChannel =''
for langChannel in TypeLangChannel:
if langChannel in line:
LanguageChannel = langChannel
# deternine url logo
url_logo = findInfo('tvg-logo', line)
#if len(url_logo) == 0:
# cleaned_channel_name = clean_name_channel(name_channel)
# logo_data = logos.find({ 'logo_name': { '$regex': cleaned_channel_name, '$options': "i" } })
# for l in logo_data:
# url_logo = l['logo_url']
# break
channel_exist = False
if len(name_channel)>0:
channel = {"id_playlist":id_playlist, "id_channel":id_channel, "Name":name_channel, "Language":LanguageChannel, "Topic":topic, "urlLogo" : url_logo}
num_channel += 1
channel_exist = True
if channel_exist == False:
name_channel = line[line.rfind('|')+2:].strip('\n')
if len(name_channel) > 0:
channel = {"id_playlist":id_playlist, "id_channel":id_channel, "Name":name_channel, "Language":LanguageChannel, "Topic":topic, "urlLogo" : url_logo}
bulk_insert_channels(collection_channels, new_channels, num_channel)
print("Save final channels ", num_channel, flush=True)
number_channels = collection_channels.count_documents({"id_playlist":id_playlist})
playlists.update_many({'id_playlist':id_playlist}, { "$set": { "num_channels": number_channels } } )
result = {'num_channel': number_channels}
return web.json_response(result)
async def import_xtream_codes(request):
data = await request.post()
id_playlist = data.get('id_playlist', '').strip()
@@ -741,19 +620,20 @@ async def run_xtream_import(id_playlist, import_key, collection_channels,
try:
await emit_analysis_progress({'percentage': 0.02}, sidClient)
live_categories = parse_xtream_category_map(
fetch_xtream_json(xtream_server, xtream_username, xtream_password, 'get_live_categories')
)
vod_categories = parse_xtream_category_map(
fetch_xtream_json(xtream_server, xtream_username, xtream_password, 'get_vod_categories')
)
series_categories = parse_xtream_category_map(
fetch_xtream_json(xtream_server, xtream_username, xtream_password, 'get_series_categories')
loop = asyncio.get_running_loop()
async def fetch(action, **extra_params):
return await loop.run_in_executor(
None, lambda: fetch_xtream_json(xtream_server, xtream_username, xtream_password, action, **extra_params)
)
live_streams = fetch_xtream_json(xtream_server, xtream_username, xtream_password, 'get_live_streams')
vod_streams = fetch_xtream_json(xtream_server, xtream_username, xtream_password, 'get_vod_streams')
series_list = fetch_xtream_json(xtream_server, xtream_username, xtream_password, 'get_series')
live_categories = parse_xtream_category_map(await fetch('get_live_categories'))
vod_categories = parse_xtream_category_map(await fetch('get_vod_categories'))
series_categories = parse_xtream_category_map(await fetch('get_series_categories'))
live_streams = await fetch('get_live_streams')
vod_streams = await fetch('get_vod_streams')
series_list = await fetch('get_series')
total_steps = max(1, len(live_streams) + len(vod_streams) + len(series_list))
processed_steps = 0
@@ -1151,8 +1031,6 @@ async def list_logo(request):
async def list_devices(request):
json_devices = json.dumps(devices)
#return web.json_response(json_devices)
return web.json_response(dumps(devices_db.find({}).limit(50)))
@@ -1503,7 +1381,6 @@ def disconnect(sid):
@sio.event
async def polling(sid, data):
global devices
device_name = data['name']
IdDevice = data['IdDevice']
mediaRunning = data['mediaRunning']
@@ -1515,7 +1392,7 @@ async def polling(sid, data):
print('data_running :', data_running, flush=True)
try:
vpn_status = data['vpn_status']
except:
except KeyError:
vpn_status = 'unknown'
ip_address = sio_session_ips.get(sid, '')
@@ -1564,24 +1441,6 @@ async def polling(sid, data):
else:
recents.insert_one(new_record)
test_exist_device = False
for device in devices:
if device['IdDevice'] == IdDevice:
test_exist_device = True
device['last_datetime'] = device_last_datetime
device['name'] = device_name
device['sid'] = sid
device['mediaRunning'] = mediaRunning
try:
device['vpn_status'] = vpn_status
except:
device['vpn_status'] = 'unknown'
if not test_exist_device:
new_device = { 'IdDevice': IdDevice, 'name' : device_name, 'last_datetime' : device_last_datetime, 'sid':sid ,'mediaRunning' : mediaRunning, 'vpn_status':vpn_status}
devices.append(new_device)
# Main
if __name__ == '__main__':