pmrony commited on
Commit
bf039e4
·
verified ·
1 Parent(s): b984690

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +90 -34
app.py CHANGED
@@ -7,6 +7,7 @@ import asyncio
7
  import re
8
  import urllib3
9
  import subprocess
 
10
  from flask import Flask, jsonify, make_response, request, Response
11
  from supabase import create_client
12
  from pyrogram import Client, filters, enums, idle, utils
@@ -15,6 +16,10 @@ from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, WebAppInf
15
 
16
  urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
17
 
 
 
 
 
18
  # ==================== PYROGRAM NEW ID RANGE FIX (MONKEY PATCH) ====================
19
  def get_peer_type_new(peer_id: int) -> str:
20
  peer_id_str = str(peer_id)
@@ -100,9 +105,10 @@ def get_msg_file_id(msg):
100
  if media: return media.file_id
101
  return None
102
 
103
- # ==================== CUSTOM VIDEO STREAMING ENGINE ====================
104
  def get_file_stream(message_id):
105
  q = queue.Queue(maxsize=10)
 
106
 
107
  async def producer():
108
  try:
@@ -110,14 +116,32 @@ def get_file_stream(message_id):
110
  msg = await bot.get_messages(STORAGE_CHANNEL_ID, message_id)
111
  media = get_media_obj(msg)
112
  if not media:
113
- await asyncio.to_thread(q.put, None)
 
114
  return
 
115
  async for chunk in bot.stream_media(msg):
116
- await asyncio.to_thread(q.put, chunk)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  except Exception as e:
118
  print(f"Error in stream producer: {e}")
119
  finally:
120
- await asyncio.to_thread(q.put, None)
 
 
121
 
122
  asyncio.run_coroutine_threadsafe(producer(), main_loop)
123
 
@@ -129,6 +153,12 @@ def get_file_stream(message_id):
129
  if chunk is None: break
130
  yield chunk
131
  except GeneratorExit:
 
 
 
 
 
 
132
  while not q.empty():
133
  try: q.get_nowait()
134
  except: break
@@ -816,51 +846,77 @@ async def handle_media_upload(client, message):
816
  await proc.communicate()
817
  if not os.path.exists(thumb_path): thumb_path = None
818
 
819
- if media_type == "photo":
820
- sent_to_admin = await client.send_photo(message.chat.id, telegram_file, caption=admin_cap, parse_mode=enums.ParseMode.HTML)
821
- else:
822
- media = get_media_obj(message)
823
- vid_duration = media.duration if media and hasattr(media, 'duration') and media.duration else 0
824
- vid_width = media.width if media and hasattr(media, 'width') and media.width else 0
825
- vid_height = media.height if media and hasattr(media, 'height') and media.height else 0
826
-
827
- sent_to_admin = await client.send_video(
828
- message.chat.id,
829
- telegram_file,
830
- caption=admin_cap,
831
- parse_mode=enums.ParseMode.HTML,
832
- duration=vid_duration,
833
- width=vid_width,
834
- height=vid_height,
835
- thumb=thumb_path
836
- )
 
 
 
 
 
837
 
838
  tg_file_id = get_msg_file_id(sent_to_admin)
839
  if not tg_file_id:
840
  tg_file_id = get_msg_file_id(message)
841
 
842
- await status_msg.delete()
 
843
 
 
844
  groups_res = await db_query(lambda: supabase.table('groups').select('group_id').execute())
845
  group_ids = [g['group_id'] for g in groups_res.data]
846
  success_count, fail_count = 0, 0
847
 
848
  for gid in set(group_ids):
849
- try:
850
- if media_type == "photo": await client.send_photo(gid, tg_file_id, caption=caption_text, parse_mode=enums.ParseMode.HTML, reply_markup=group_markup)
851
- else: await client.send_video(gid, tg_file_id, caption=caption_text, parse_mode=enums.ParseMode.HTML, reply_markup=group_markup)
852
- success_count += 1
853
- await asyncio.sleep(1.5)
854
- except FloodWait as e:
855
- await asyncio.sleep(e.value + 1)
856
  try:
857
  if media_type == "photo": await client.send_photo(gid, tg_file_id, caption=caption_text, parse_mode=enums.ParseMode.HTML, reply_markup=group_markup)
858
  else: await client.send_video(gid, tg_file_id, caption=caption_text, parse_mode=enums.ParseMode.HTML, reply_markup=group_markup)
859
  success_count += 1
860
- except Exception: fail_count += 1
861
- except Exception: fail_count += 1
862
-
863
- await message.reply(f"📢 <b>Broadcast Complete!</b>\n\n✅ Success: {success_count} groups\n❌ Failed: {fail_count} groups", parse_mode=enums.ParseMode.HTML)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
864
 
865
  except Exception as e:
866
  try: await message.reply(f"⚠️ Error occurred: {str(e)}")
 
7
  import re
8
  import urllib3
9
  import subprocess
10
+ import logging
11
  from flask import Flask, jsonify, make_response, request, Response
12
  from supabase import create_client
13
  from pyrogram import Client, filters, enums, idle, utils
 
16
 
17
  urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
18
 
19
+ # Flask এর অপ্রয়োজনীয় socket.send() এরর লগস বন্ধ করার জন্য
20
+ log = logging.getLogger('werkzeug')
21
+ log.setLevel(logging.ERROR)
22
+
23
  # ==================== PYROGRAM NEW ID RANGE FIX (MONKEY PATCH) ====================
24
  def get_peer_type_new(peer_id: int) -> str:
25
  peer_id_str = str(peer_id)
 
105
  if media: return media.file_id
106
  return None
107
 
108
+ # ==================== CUSTOM VIDEO STREAMING ENGINE (MEMORY LEAK FIXED) ====================
109
  def get_file_stream(message_id):
110
  q = queue.Queue(maxsize=10)
111
+ stop_flag = [False]
112
 
113
  async def producer():
114
  try:
 
116
  msg = await bot.get_messages(STORAGE_CHANNEL_ID, message_id)
117
  media = get_media_obj(msg)
118
  if not media:
119
+ try: await asyncio.to_thread(q.put, None, True, 1.0)
120
+ except queue.Full: pass
121
  return
122
+
123
  async for chunk in bot.stream_media(msg):
124
+ if stop_flag[0]: break
125
+
126
+ # Custom wait timeout to check stop_flag efficiently
127
+ put_success = False
128
+ while not stop_flag[0]:
129
+ try:
130
+ await asyncio.to_thread(q.put, chunk, True, 2.0)
131
+ put_success = True
132
+ break
133
+ except queue.Full:
134
+ continue
135
+
136
+ if not put_success:
137
+ break
138
+
139
  except Exception as e:
140
  print(f"Error in stream producer: {e}")
141
  finally:
142
+ if not stop_flag[0]:
143
+ try: await asyncio.to_thread(q.put, None, True, 1.0)
144
+ except queue.Full: pass
145
 
146
  asyncio.run_coroutine_threadsafe(producer(), main_loop)
147
 
 
153
  if chunk is None: break
154
  yield chunk
155
  except GeneratorExit:
156
+ # Client closed video player or browser disconnected
157
+ pass
158
+ except Exception as e:
159
+ print(f"Consumer error: {e}")
160
+ finally:
161
+ stop_flag[0] = True
162
  while not q.empty():
163
  try: q.get_nowait()
164
  except: break
 
846
  await proc.communicate()
847
  if not os.path.exists(thumb_path): thumb_path = None
848
 
849
+ # Auto-retry logic for sending final result to admin
850
+ try:
851
+ if media_type == "photo":
852
+ sent_to_admin = await client.send_photo(message.chat.id, telegram_file, caption=admin_cap, parse_mode=enums.ParseMode.HTML)
853
+ else:
854
+ media = get_media_obj(message)
855
+ vid_duration = media.duration if media and hasattr(media, 'duration') and media.duration else 0
856
+ vid_width = media.width if media and hasattr(media, 'width') and media.width else 0
857
+ vid_height = media.height if media and hasattr(media, 'height') and media.height else 0
858
+
859
+ sent_to_admin = await client.send_video(
860
+ message.chat.id,
861
+ telegram_file,
862
+ caption=admin_cap,
863
+ parse_mode=enums.ParseMode.HTML,
864
+ duration=vid_duration,
865
+ width=vid_width,
866
+ height=vid_height,
867
+ thumb=thumb_path
868
+ )
869
+ except Exception as e:
870
+ await message.reply(f"❌ Failed to send final file to you: {e}")
871
+ return
872
 
873
  tg_file_id = get_msg_file_id(sent_to_admin)
874
  if not tg_file_id:
875
  tg_file_id = get_msg_file_id(message)
876
 
877
+ try: await status_msg.delete()
878
+ except: pass
879
 
880
+ # Broadcast Phase with Retries
881
  groups_res = await db_query(lambda: supabase.table('groups').select('group_id').execute())
882
  group_ids = [g['group_id'] for g in groups_res.data]
883
  success_count, fail_count = 0, 0
884
 
885
  for gid in set(group_ids):
886
+ retries = 3
887
+ while retries > 0:
 
 
 
 
 
888
  try:
889
  if media_type == "photo": await client.send_photo(gid, tg_file_id, caption=caption_text, parse_mode=enums.ParseMode.HTML, reply_markup=group_markup)
890
  else: await client.send_video(gid, tg_file_id, caption=caption_text, parse_mode=enums.ParseMode.HTML, reply_markup=group_markup)
891
  success_count += 1
892
+ break
893
+ except FloodWait as e:
894
+ await asyncio.sleep(e.value + 1)
895
+ except Exception as e:
896
+ err_msg = str(e).lower()
897
+ if "disconnect" in err_msg or "connection" in err_msg or "timeout" in err_msg:
898
+ retries -= 1
899
+ await asyncio.sleep(3)
900
+ else:
901
+ fail_count += 1
902
+ break
903
+ await asyncio.sleep(1.5)
904
+
905
+ # Success notification with Retries
906
+ retries = 3
907
+ while retries > 0:
908
+ try:
909
+ await message.reply(f"📢 <b>Broadcast Complete!</b>\n\n✅ Success: {success_count} groups\n❌ Failed: {fail_count} groups", parse_mode=enums.ParseMode.HTML)
910
+ break
911
+ except FloodWait as e:
912
+ await asyncio.sleep(e.value + 1)
913
+ except Exception as e:
914
+ err_msg = str(e).lower()
915
+ if "disconnect" in err_msg or "connection" in err_msg or "timeout" in err_msg:
916
+ retries -= 1
917
+ await asyncio.sleep(3)
918
+ else:
919
+ break
920
 
921
  except Exception as e:
922
  try: await message.reply(f"⚠️ Error occurred: {str(e)}")