pmrony commited on
Commit
86bdd4e
·
verified ·
1 Parent(s): 276b7de

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +7 -28
app.py CHANGED
@@ -108,7 +108,7 @@ def get_file_stream(message_id):
108
  await asyncio.to_thread(q.put, None)
109
  return
110
 
111
- # ডাটা রিড করে থ্রেড-সেফ কিউ-তে রাখা হচ্ছে (asyncio.to_thread ব্যবহারের ফলে মেইন লুপ কখনো ফ্রিজ হবে না)
112
  async for chunk in bot.stream_media(media):
113
  await asyncio.to_thread(q.put, chunk)
114
  except Exception as e:
@@ -124,7 +124,7 @@ def get_file_stream(message_id):
124
  try:
125
  while True:
126
  try:
127
- # সর্বোচ্চ ১৫ সেকেন্ড অপেক্ষা করবে, ফলে থ্রেড কখনো অনন্তকাল হ্যাং হবে না
128
  chunk = q.get(timeout=15)
129
  except queue.Empty:
130
  break
@@ -132,7 +132,7 @@ def get_file_stream(message_id):
132
  break
133
  yield chunk
134
  except GeneratorExit:
135
- # ইউজার যদি মাঝপথে ব্রাউজার ট্যাব কেটে দেয়, তবে কিউ খালি করে ব্যাকগ্রাউন্ড থ্রেড রিলিজ করা হবে
136
  while not q.empty():
137
  try: q.get_nowait()
138
  except: break
@@ -420,7 +420,7 @@ async def send_to_specific_group(client, message):
420
 
421
  args = message.command
422
  if len(args) < 2:
423
- return await message.reply("❌ <b>Group ID missing!</b>\n\nCorrect format:\n`/sendto -1001234567890`")
424
 
425
  try:
426
  group_id = int(args[1])
@@ -616,7 +616,6 @@ def upload_file_sync(upload_url, file_path, api_key):
616
  except Exception as e:
617
  return {}
618
 
619
- # filters.document যুক্ত করা হলো যাতে ফাইল/ডকুমেন্ট হিসেবে ভিডিও পাঠালেও বট প্রসেস করতে পারে
620
  @bot.on_message((filters.video | filters.animation | filters.photo | filters.document) & filters.private & filters.user(ADMIN_IDS))
621
  async def handle_media_upload(client, message):
622
  global upload_mode
@@ -625,16 +624,13 @@ async def handle_media_upload(client, message):
625
  await process_broadcast(client, message)
626
  return
627
 
628
- # ফাইলটি ভিডিও, জিআইএফ নাকি ফটো তা নিখুঁতভাবে চেক করা হচ্ছে
629
  is_video = message.video or (message.document and message.document.mime_type and "video" in message.document.mime_type)
630
  is_animation = message.animation or (message.document and message.document.mime_type and "gif" in message.document.mime_type)
631
  is_photo = message.photo or (message.document and message.document.mime_type and "image" in message.document.mime_type)
632
 
633
- # যদি ভিডিও, ফটো বা অ্যানিমেশন না হয় তবে কাস্টম ফাইল স্কিপ করবে
634
  if not (is_video or is_animation or is_photo):
635
  return
636
 
637
- # FORCE ANIMATIONS (GIFS) TO BE TREATED AS VIDEOS FOR BROADCAST STABILITY
638
  media_type = "video" if (is_video or is_animation) else "photo"
639
  has_blur_caption = message.caption and "/blur" in message.caption.lower()
640
  is_persistent_blur = bool(state.get("blur_percent"))
@@ -675,7 +671,6 @@ async def handle_media_upload(client, message):
675
 
676
  is_large_video = False
677
  if media_type == "video":
678
- # Safe size checks for both Videos and Animations (GIFs/Documents)
679
  media = get_media_obj(message)
680
  duration = media.duration if media and hasattr(media, 'duration') and media.duration else 0
681
  file_size = media.file_size if media and hasattr(media, 'file_size') and media.file_size else 0
@@ -693,7 +688,6 @@ async def handle_media_upload(client, message):
693
  original_file, watermarked_file, blurred_file = None, None, None
694
  clean_upload_file, telegram_file, embed_link = None, None, None
695
 
696
- # === Progress Bar Function ===
697
  last_update_time = time.time()
698
  async def download_progress(current, total):
699
  nonlocal last_update_time
@@ -705,18 +699,15 @@ async def handle_media_upload(client, message):
705
  last_update_time = now
706
  except Exception:
707
  pass
708
- # =============================
709
 
710
  try:
711
  original_file = await message.download(progress=download_progress)
712
  clean_upload_file = original_file
713
 
714
- # ১. ওয়াটারমার্ক (Watermark) করা - Balanced (Superfast + CRF 23)
715
  if media_type == "video" and not is_large_video:
716
  await status_msg.edit_text("⏳ Watermarking video... (HD + Superfast Processing)")
717
  watermarked_file = f"{original_file}_wm.mp4"
718
 
719
- # জাইএফ ফাইলের ক্ষেত্রে অডিও ট্র্যাক বাদ দেওয়া হবে (-an) অন্যথায় কপি করা হবে
720
  has_audio = not (message.animation or (message.document and message.document.mime_type and "gif" in message.document.mime_type))
721
  audio_opts = ["-an"] if not has_audio else ["-c:a", "copy"]
722
 
@@ -730,18 +721,14 @@ async def handle_media_upload(client, message):
730
  process = await asyncio.create_subprocess_exec(*cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
731
  await process.communicate()
732
 
733
- # বাগ সংশোধন: ফাইলের সাইজ ০-এর চেয়ে বেশি হলে তবেই আউটপুট ব্যবহার করা হবে, অন্যথায় অরিじんাল ফাইল ব্যবহৃত হবে
734
  if process.returncode == 0 and os.path.exists(watermarked_file) and os.path.getsize(watermarked_file) > 0:
735
  clean_upload_file = watermarked_file
736
 
737
- # ২. আপনার নিজের টেলিগ্রাম স্টোরেজ চ্যানেলে ফাইল আপলোড (ভিডিও বা ফটো)
738
- # এখানে থাম্বনেইল, সঠিক ডিউরেশন এবং সাইজ জেনারেট করে পোস্ট করা হবে যাতে সাদা ০:০০ শো না করে
739
  storage_msg_id = None
740
  if media_type in ["video", "photo"]:
741
  if upload_mode == "telegram":
742
  await status_msg.edit_text("⏳ Uploading Clean HD video to your storage channel...")
743
 
744
- # স্টোরেজ চ্যানেলেও অরিজিনাল থাম্বনেইল, ডিউরেশন এবং সাইজ জেনারেট করে পাঠানো হচ্ছে যাতে সাদা ০:০০ শো না করে
745
  thumb_path_storage = f"{original_file}_storage_thumb.jpg"
746
  proc = await asyncio.create_subprocess_exec("ffmpeg", "-y", "-i", clean_upload_file, "-vframes", "1", thumb_path_storage, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
747
  await proc.communicate()
@@ -764,12 +751,10 @@ async def handle_media_upload(client, message):
764
  )
765
  storage_msg_id = sent_to_channel.id
766
 
767
- # আপনার নিজস্ব ডোমেইন বা সার্ভারের স্ট্রিমিং ও ডিরেক্ট ডাউনলোড লিংক জেনারেট
768
  stream_link = f"{BACKEND_URL}/stream/{storage_msg_id}"
769
  download_link = f"{BACKEND_URL}/download/{storage_msg_id}"
770
  embed_link = stream_link
771
  else:
772
- # Byse.sx আপলোড মোড
773
  await status_msg.edit_text("⏳ Uploading Clean HD video to byse.sx server...")
774
  api_endpoint = "https://api.byse.sx/upload/server"
775
  loop = asyncio.get_event_loop()
@@ -799,7 +784,6 @@ async def handle_media_upload(client, message):
799
  await status_msg.delete()
800
  return
801
 
802
- # ৩. পাঠানোর জন্য ভিডিও ব্লার করা
803
  telegram_file = clean_upload_file
804
  if is_blur and not is_large_video:
805
  await status_msg.edit_text(f"⏳ Applying {blur_percent}% blur for Telegram broadcast...")
@@ -815,7 +799,6 @@ async def handle_media_upload(client, message):
815
  else:
816
  ff_filter = ["-vf", f"boxblur={radius}:1"]
817
 
818
- # জাইএফ ফাইলের ক্ষেত্রে অডিও ট্র্যাক বাদ দেওয়া হবে (-an) অন্যথায় কপি করা হবে
819
  has_audio = not (message.animation or (message.document and message.document.mime_type and "gif" in message.document.mime_type))
820
  audio_opts_blur = ["-an"] if not has_audio else []
821
 
@@ -827,7 +810,6 @@ async def handle_media_upload(client, message):
827
  process_blur = await asyncio.create_subprocess_exec(*cmd_blur, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
828
  await process_blur.communicate()
829
 
830
- # বাগ সংশোধন: ফাইলের সাইজ ০-এর চেয়ে বেশি হলে তবেই আউটপুট ব্যবহার করা হবে, অন্যথায় অরিジナাল ফাইল ব্যবহৃত হবে
831
  if process_blur.returncode == 0 and os.path.exists(blurred_file) and os.path.getsize(blurred_file) > 0:
832
  telegram_file = blurred_file
833
 
@@ -839,7 +821,6 @@ async def handle_media_upload(client, message):
839
 
840
  group_markup = InlineKeyboardMarkup([[InlineKeyboardButton("🎬 Watch Full Video Here 🔞", url=bot_link)]])
841
 
842
- # অ্যাডমিন চ্যাটে সাকসেস মেসেজ ও লিংক পাঠানো হচ্ছে
843
  admin_cap = (
844
  f"✅ <b>Upload and Processing Complete!</b>\n\n"
845
  f"🎬 <b>Stream/Watch Online Link:</b>\n<code>{stream_link}</code>\n\n"
@@ -856,7 +837,6 @@ async def handle_media_upload(client, message):
856
  if media_type == "photo":
857
  sent_to_admin = await client.send_photo(message.chat.id, telegram_file, caption=admin_cap, parse_mode=enums.ParseMode.HTML)
858
  else:
859
- # Safe dimensions extraction for Videos and Animations
860
  media = get_media_obj(message)
861
  vid_duration = media.duration if media and hasattr(media, 'duration') and media.duration else 0
862
  vid_width = media.width if media and hasattr(media, 'width') and media.width else 0
@@ -873,10 +853,9 @@ async def handle_media_upload(client, message):
873
  thumb=thumb_path
874
  )
875
 
876
- # ক্র্যাশ-ফ্রি উপায়ে file_id রিড করার জন্য ইউনিভার্সাল এক্সট্রাক্টর
877
  tg_file_id = get_msg_file_id(sent_to_admin)
878
  if not tg_file_id:
879
- tg_file_id = get_msg_file_id(message) # Fallback to original
880
 
881
  await status_msg.delete()
882
 
@@ -907,7 +886,7 @@ async def handle_media_upload(client, message):
907
  except Exception as e: await message.reply(f"⚠️ Error occurred: {str(e)}")
908
  finally:
909
  for f in [original_file, watermarked_file, blurred_file, f"{original_file}_thumb.jpg" if original_file else None, f"{original_file}_storage_thumb.jpg" if original_file else None]:
910
- if f && os.path.exists(f):
911
  try: os.remove(f)
912
  except: pass
913
 
@@ -1047,7 +1026,7 @@ async def catch_admin_steps(client, message):
1047
  elif state.get("step") == "broadcast":
1048
  await process_broadcast(client, message)
1049
 
1050
- def run_flask(): app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 7860)), threaded=True) # Multithreading explicitly enabled
1051
 
1052
  async def main():
1053
  await bot.start()
 
108
  await asyncio.to_thread(q.put, None)
109
  return
110
 
111
+ # ডাটা রিড করে থ্রেড-সেফ কিউ-তে রাখা হচ্ছে
112
  async for chunk in bot.stream_media(media):
113
  await asyncio.to_thread(q.put, chunk)
114
  except Exception as e:
 
124
  try:
125
  while True:
126
  try:
127
+ # সর্বোচ্চ ১৫ সেকেন্ড অপেক্ষা করবে
128
  chunk = q.get(timeout=15)
129
  except queue.Empty:
130
  break
 
132
  break
133
  yield chunk
134
  except GeneratorExit:
135
+ # ইউজার যদি মাঝপথে ব্রাউজার ট্যাব কেটে দেয়
136
  while not q.empty():
137
  try: q.get_nowait()
138
  except: break
 
420
 
421
  args = message.command
422
  if len(args) < 2:
423
+ return await message.reply("❌ <b>Group ID missing!</b>\n\nCorrect format:\n`/sendto -1003973566529`")
424
 
425
  try:
426
  group_id = int(args[1])
 
616
  except Exception as e:
617
  return {}
618
 
 
619
  @bot.on_message((filters.video | filters.animation | filters.photo | filters.document) & filters.private & filters.user(ADMIN_IDS))
620
  async def handle_media_upload(client, message):
621
  global upload_mode
 
624
  await process_broadcast(client, message)
625
  return
626
 
 
627
  is_video = message.video or (message.document and message.document.mime_type and "video" in message.document.mime_type)
628
  is_animation = message.animation or (message.document and message.document.mime_type and "gif" in message.document.mime_type)
629
  is_photo = message.photo or (message.document and message.document.mime_type and "image" in message.document.mime_type)
630
 
 
631
  if not (is_video or is_animation or is_photo):
632
  return
633
 
 
634
  media_type = "video" if (is_video or is_animation) else "photo"
635
  has_blur_caption = message.caption and "/blur" in message.caption.lower()
636
  is_persistent_blur = bool(state.get("blur_percent"))
 
671
 
672
  is_large_video = False
673
  if media_type == "video":
 
674
  media = get_media_obj(message)
675
  duration = media.duration if media and hasattr(media, 'duration') and media.duration else 0
676
  file_size = media.file_size if media and hasattr(media, 'file_size') and media.file_size else 0
 
688
  original_file, watermarked_file, blurred_file = None, None, None
689
  clean_upload_file, telegram_file, embed_link = None, None, None
690
 
 
691
  last_update_time = time.time()
692
  async def download_progress(current, total):
693
  nonlocal last_update_time
 
699
  last_update_time = now
700
  except Exception:
701
  pass
 
702
 
703
  try:
704
  original_file = await message.download(progress=download_progress)
705
  clean_upload_file = original_file
706
 
 
707
  if media_type == "video" and not is_large_video:
708
  await status_msg.edit_text("⏳ Watermarking video... (HD + Superfast Processing)")
709
  watermarked_file = f"{original_file}_wm.mp4"
710
 
 
711
  has_audio = not (message.animation or (message.document and message.document.mime_type and "gif" in message.document.mime_type))
712
  audio_opts = ["-an"] if not has_audio else ["-c:a", "copy"]
713
 
 
721
  process = await asyncio.create_subprocess_exec(*cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
722
  await process.communicate()
723
 
 
724
  if process.returncode == 0 and os.path.exists(watermarked_file) and os.path.getsize(watermarked_file) > 0:
725
  clean_upload_file = watermarked_file
726
 
 
 
727
  storage_msg_id = None
728
  if media_type in ["video", "photo"]:
729
  if upload_mode == "telegram":
730
  await status_msg.edit_text("⏳ Uploading Clean HD video to your storage channel...")
731
 
 
732
  thumb_path_storage = f"{original_file}_storage_thumb.jpg"
733
  proc = await asyncio.create_subprocess_exec("ffmpeg", "-y", "-i", clean_upload_file, "-vframes", "1", thumb_path_storage, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
734
  await proc.communicate()
 
751
  )
752
  storage_msg_id = sent_to_channel.id
753
 
 
754
  stream_link = f"{BACKEND_URL}/stream/{storage_msg_id}"
755
  download_link = f"{BACKEND_URL}/download/{storage_msg_id}"
756
  embed_link = stream_link
757
  else:
 
758
  await status_msg.edit_text("⏳ Uploading Clean HD video to byse.sx server...")
759
  api_endpoint = "https://api.byse.sx/upload/server"
760
  loop = asyncio.get_event_loop()
 
784
  await status_msg.delete()
785
  return
786
 
 
787
  telegram_file = clean_upload_file
788
  if is_blur and not is_large_video:
789
  await status_msg.edit_text(f"⏳ Applying {blur_percent}% blur for Telegram broadcast...")
 
799
  else:
800
  ff_filter = ["-vf", f"boxblur={radius}:1"]
801
 
 
802
  has_audio = not (message.animation or (message.document and message.document.mime_type and "gif" in message.document.mime_type))
803
  audio_opts_blur = ["-an"] if not has_audio else []
804
 
 
810
  process_blur = await asyncio.create_subprocess_exec(*cmd_blur, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
811
  await process_blur.communicate()
812
 
 
813
  if process_blur.returncode == 0 and os.path.exists(blurred_file) and os.path.getsize(blurred_file) > 0:
814
  telegram_file = blurred_file
815
 
 
821
 
822
  group_markup = InlineKeyboardMarkup([[InlineKeyboardButton("🎬 Watch Full Video Here 🔞", url=bot_link)]])
823
 
 
824
  admin_cap = (
825
  f"✅ <b>Upload and Processing Complete!</b>\n\n"
826
  f"🎬 <b>Stream/Watch Online Link:</b>\n<code>{stream_link}</code>\n\n"
 
837
  if media_type == "photo":
838
  sent_to_admin = await client.send_photo(message.chat.id, telegram_file, caption=admin_cap, parse_mode=enums.ParseMode.HTML)
839
  else:
 
840
  media = get_media_obj(message)
841
  vid_duration = media.duration if media and hasattr(media, 'duration') and media.duration else 0
842
  vid_width = media.width if media and hasattr(media, 'width') and media.width else 0
 
853
  thumb=thumb_path
854
  )
855
 
 
856
  tg_file_id = get_msg_file_id(sent_to_admin)
857
  if not tg_file_id:
858
+ tg_file_id = get_msg_file_id(message)
859
 
860
  await status_msg.delete()
861
 
 
886
  except Exception as e: await message.reply(f"⚠️ Error occurred: {str(e)}")
887
  finally:
888
  for f in [original_file, watermarked_file, blurred_file, f"{original_file}_thumb.jpg" if original_file else None, f"{original_file}_storage_thumb.jpg" if original_file else None]:
889
+ if f and os.path.exists(f):
890
  try: os.remove(f)
891
  except: pass
892
 
 
1026
  elif state.get("step") == "broadcast":
1027
  await process_broadcast(client, message)
1028
 
1029
+ def run_flask(): app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 7860)), threaded=True)
1030
 
1031
  async def main():
1032
  await bot.start()