pmrony commited on
Commit
81c51c3
·
verified ·
1 Parent(s): f2806f2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +61 -27
app.py CHANGED
@@ -7,14 +7,13 @@ import re
7
  import urllib3
8
  from flask import Flask, jsonify, make_response, request, Response
9
  from supabase import create_client
10
- from pyrogram import Client, filters, enums, idle, utils # utils ইম্পোর্ট করা হলো
11
  from pyrogram.errors import SessionPasswordNeeded, PhoneCodeInvalid, PhoneCodeExpired, UserDeactivated, SessionRevoked, AuthKeyUnregistered, FloodWait
12
  from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, WebAppInfo
13
 
14
  urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
15
 
16
  # ==================== PYROGRAM NEW ID RANGE FIX (MONKEY PATCH) ====================
17
- # টেলিগ্রামের নতুন আইডিগুলোর জন্য Pyrogram-এর Peer ID Invalid বাগ সমাধান করা হলো
18
  def get_peer_type_new(peer_id: int) -> str:
19
  peer_id_str = str(peer_id)
20
  if not peer_id_str.startswith("-"):
@@ -37,7 +36,7 @@ SUPABASE_KEY = os.environ.get("SUPABASE_KEY")
37
  PREMIUM_CHANNEL_ID = -1002825744390
38
  STORAGE_CHANNEL_ID = -1002825744390 # যে চ্যানেলে ভিডিও স্টোর হবে
39
 
40
- # আপনার Hugging Face স্পেসের ডিরেক্ট ইউআরএল (টোকেন জেনারেট করার জন্য)
41
  BACKEND_URL = os.environ.get("BACKEND_URL", "https://pmrony-forwardbot.hf.space")
42
 
43
  # WebApp URL (index.html)
@@ -64,17 +63,45 @@ bot = Client("file_unlocker_bot", api_id=API_ID, api_hash=API_HASH, bot_token=BO
64
  async def db_query(func):
65
  return await asyncio.to_thread(func)
66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  # ==================== CUSTOM VIDEO STREAMING ENGINE ====================
68
  def get_file_stream(message_id):
69
  """টেলিগ্রামের স্টোরেজ চ্যানেল থেকে রিয়েল-টাইমে ডাটা স্ট্রিম করার জেনারেটর"""
70
  async def stream_generator():
71
  try:
72
  msg = await bot.get_messages(STORAGE_CHANNEL_ID, message_id)
73
- if not msg or not msg.video:
 
74
  return
75
 
76
  # chunk_size অনুযায়ী ডাটা রিয়েল-টাইমে রিড করে পাঠানো হবে
77
- async for chunk in bot.stream_media(msg.video):
78
  yield chunk
79
  except Exception as e:
80
  print(f"Error in stream_generator: {e}")
@@ -99,21 +126,23 @@ def get_file_stream(message_id):
99
 
100
  @app.route('/stream/<int:message_id>')
101
  def stream_video(message_id):
102
- """অনলাইনে প্লেয়ারে ভিডিও দেখার লিংক"""
103
  try:
104
  async def get_media_info():
105
  msg = await bot.get_messages(STORAGE_CHANNEL_ID, message_id)
106
- if msg and msg.video:
107
- return msg.video.file_size, msg.video.file_name, msg.video.mime_type
 
 
108
  return None, None, None
109
 
110
  file_size, file_name, mime_type = run_async(get_media_info())
111
  if not file_size:
112
  return "File not found or invalid message", 404
113
 
114
- response = make_response(Response(get_file_stream(message_id), mimetype=mime_type or "video/mp4"))
115
  response.headers['Content-Length'] = file_size
116
- response.headers['Content-Type'] = mime_type or "video/mp4"
117
  response.headers['Accept-Ranges'] = 'bytes'
118
  response.headers['Content-Disposition'] = f'inline; filename="{file_name or "video.mp4"}"'
119
  return response
@@ -126,15 +155,17 @@ def download_video(message_id):
126
  try:
127
  async def get_media_info():
128
  msg = await bot.get_messages(STORAGE_CHANNEL_ID, message_id)
129
- if msg and msg.video:
130
- return msg.video.file_size, msg.video.file_name, msg.video.mime_type
 
 
131
  return None, None, None
132
 
133
  file_size, file_name, mime_type = run_async(get_media_info())
134
  if not file_size:
135
  return "File not found or invalid message", 404
136
 
137
- response = make_response(Response(get_file_stream(message_id), mimetype=mime_type or "application/octet-stream"))
138
  response.headers['Content-Length'] = file_size
139
  response.headers['Content-Disposition'] = f'attachment; filename="{file_name or "video.mp4"}"'
140
  return response
@@ -649,25 +680,26 @@ async def handle_media_upload(client, message):
649
  if process.returncode == 0 and os.path.exists(watermarked_file):
650
  clean_upload_file = watermarked_file
651
 
652
- # ২. byse.sx এর বদলে আপনার নিজের টেলিগ্রাম স্টোরেজ চ্যানেলে HD ভিডিও আপল
653
- if media_type == "video":
654
- await status_msg.edit_text("⏳ Uploading Clean HD video to your storage channel...")
 
 
 
 
 
 
 
 
655
 
656
- # আপনার নিজের চ্যানেলে ব্যাকআপ হিসেবে HD ওয়াটারমার্কড ভিডিওটি পাঠানো হচ্ছে
657
- sent_to_channel = await client.send_video(
658
- chat_id=STORAGE_CHANNEL_ID,
659
- video=clean_upload_file,
660
- caption=f"Backup of video uploaded by Admin. File: {os.path.basename(clean_upload_file)}"
661
- )
662
  storage_msg_id = sent_to_channel.id
663
 
664
  # আপনার নিজস্ব ডোমেইন বা সার্ভারের স্ট্রিমিং ও ডিরেক্ট ডাউনলোড লিংক জেনারেট
665
  stream_link = f"{BACKEND_URL}/stream/{storage_msg_id}"
666
  download_link = f"{BACKEND_URL}/download/{storage_msg_id}"
667
- embed_link = stream_link # এমবেড লিংক হিসেবে এখন নিজস্ব স্ট্রিমিং লিংক ব্যবহার হবে
668
 
669
  if is_large_video:
670
- # যদি লার্জ ভিডিও হয়, তবে সেটিরও স্ট্রিমিং লিংক জেনারেট হয়ে অ্যাডমিন চ্যাটে শো করবে
671
  admin_cap = f"✅ <b>Success! (Large Video)</b>\n\n🔗 <b>Embed Link (Clean HD):</b>\n<code>{embed_link or 'N/A'}</code>\n\n📌 <i>Broadcast skipped due to large file size.</i>"
672
  await client.send_video(message.chat.id, message.video.file_id, caption=admin_cap, parse_mode=enums.ParseMode.HTML)
673
  await status_msg.delete()
@@ -725,10 +757,8 @@ async def handle_media_upload(client, message):
725
 
726
  if media_type == "photo":
727
  sent_to_admin = await client.send_photo(message.chat.id, telegram_file, caption=admin_cap, parse_mode=enums.ParseMode.HTML)
728
- tg_file_id = sent_to_admin.photo.file_id
729
  elif media_type == "animation":
730
  sent_to_admin = await client.send_animation(message.chat.id, telegram_file, caption=admin_cap, parse_mode=enums.ParseMode.HTML)
731
- tg_file_id = sent_to_admin.animation.file_id
732
  else:
733
  vid_duration = message.video.duration if message.video and message.video.duration else 0
734
  vid_width = message.video.width if message.video and message.video.width else 0
@@ -744,7 +774,11 @@ async def handle_media_upload(client, message):
744
  height=vid_height,
745
  thumb=thumb_path
746
  )
747
- tg_file_id = sent_to_admin.video.file_id
 
 
 
 
748
 
749
  await status_msg.delete()
750
 
 
7
  import urllib3
8
  from flask import Flask, jsonify, make_response, request, Response
9
  from supabase import create_client
10
+ from pyrogram import Client, filters, enums, idle, utils
11
  from pyrogram.errors import SessionPasswordNeeded, PhoneCodeInvalid, PhoneCodeExpired, UserDeactivated, SessionRevoked, AuthKeyUnregistered, FloodWait
12
  from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, WebAppInfo
13
 
14
  urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
15
 
16
  # ==================== PYROGRAM NEW ID RANGE FIX (MONKEY PATCH) ====================
 
17
  def get_peer_type_new(peer_id: int) -> str:
18
  peer_id_str = str(peer_id)
19
  if not peer_id_str.startswith("-"):
 
36
  PREMIUM_CHANNEL_ID = -1002825744390
37
  STORAGE_CHANNEL_ID = -1002825744390 # যে চ্যানেলে ভিডিও স্টোর হবে
38
 
39
+ # আপনার Hugging Face স্পেসের ডিরেক্ট ইউআরএল
40
  BACKEND_URL = os.environ.get("BACKEND_URL", "https://pmrony-forwardbot.hf.space")
41
 
42
  # WebApp URL (index.html)
 
63
  async def db_query(func):
64
  return await asyncio.to_thread(func)
65
 
66
+ # ==================== UNIVERSAL MEDIA HELPER ====================
67
+ def get_media_obj(msg):
68
+ """মেসেজ থেকে যেকোনো ধরনের মিডিয়া অবজেক্ট (ভিডিও, জিআইএফ, ডকুমেন্ট) খুঁজে বের করার ফাংশন"""
69
+ if not msg:
70
+ return None
71
+ if msg.video:
72
+ return msg.video
73
+ if msg.animation:
74
+ return msg.animation
75
+ if msg.document:
76
+ return msg.document
77
+ if msg.audio:
78
+ return msg.audio
79
+ return None
80
+
81
+ def get_msg_file_id(msg):
82
+ """মেসেজ থেকে ক্র্যাশ-ফ্রি উপায়ে file_id বের করার ফাংশন"""
83
+ if not msg:
84
+ return None
85
+ if msg.photo:
86
+ return msg.photo.file_id
87
+ media = get_media_obj(msg)
88
+ if media:
89
+ return media.file_id
90
+ return None
91
+ # ================================================================
92
+
93
  # ==================== CUSTOM VIDEO STREAMING ENGINE ====================
94
  def get_file_stream(message_id):
95
  """টেলিগ্রামের স্টোরেজ চ্যানেল থেকে রিয়েল-টাইমে ডাটা স্ট্রিম করার জেনারেটর"""
96
  async def stream_generator():
97
  try:
98
  msg = await bot.get_messages(STORAGE_CHANNEL_ID, message_id)
99
+ media = get_media_obj(msg)
100
+ if not media:
101
  return
102
 
103
  # chunk_size অনুযায়ী ডাটা রিয়েল-টাইমে রিড করে পাঠানো হবে
104
+ async for chunk in bot.stream_media(media):
105
  yield chunk
106
  except Exception as e:
107
  print(f"Error in stream_generator: {e}")
 
126
 
127
  @app.route('/stream/<int:message_id>')
128
  def stream_video(message_id):
129
+ """অনলাইনে প্লেয়ারে ভিডিও/জিআইএফ দেখার লিংক"""
130
  try:
131
  async def get_media_info():
132
  msg = await bot.get_messages(STORAGE_CHANNEL_ID, message_id)
133
+ media = get_media_obj(msg)
134
+ if media:
135
+ mime = getattr(media, 'mime_type', 'video/mp4') or 'video/mp4'
136
+ return media.file_size, getattr(media, 'file_name', 'video.mp4'), mime
137
  return None, None, None
138
 
139
  file_size, file_name, mime_type = run_async(get_media_info())
140
  if not file_size:
141
  return "File not found or invalid message", 404
142
 
143
+ response = make_response(Response(get_file_stream(message_id), mimetype=mime_type))
144
  response.headers['Content-Length'] = file_size
145
+ response.headers['Content-Type'] = mime_type
146
  response.headers['Accept-Ranges'] = 'bytes'
147
  response.headers['Content-Disposition'] = f'inline; filename="{file_name or "video.mp4"}"'
148
  return response
 
155
  try:
156
  async def get_media_info():
157
  msg = await bot.get_messages(STORAGE_CHANNEL_ID, message_id)
158
+ media = get_media_obj(msg)
159
+ if media:
160
+ mime = getattr(media, 'mime_type', 'application/octet-stream') or 'application/octet-stream'
161
+ return media.file_size, getattr(media, 'file_name', 'video.mp4'), mime
162
  return None, None, None
163
 
164
  file_size, file_name, mime_type = run_async(get_media_info())
165
  if not file_size:
166
  return "File not found or invalid message", 404
167
 
168
+ response = make_response(Response(get_file_stream(message_id), mimetype=mime_type))
169
  response.headers['Content-Length'] = file_size
170
  response.headers['Content-Disposition'] = f'attachment; filename="{file_name or "video.mp4"}"'
171
  return response
 
680
  if process.returncode == 0 and os.path.exists(watermarked_file):
681
  clean_upload_file = watermarked_file
682
 
683
+ # ২. আপনার নিজের টেলিগ্রাম স্টোরেজ চ্যানেলে ফাইল আপলোড (ভিডিও, অ্যানিমেশন বা ফট)
684
+ storage_msg_id = None
685
+ if media_type in ["video", "animation", "photo"]:
686
+ await status_msg.edit_text(f"⏳ Uploading {media_type} to your storage channel...")
687
+
688
+ if media_type == "photo":
689
+ sent_to_channel = await client.send_photo(chat_id=STORAGE_CHANNEL_ID, photo=clean_upload_file, caption="Backup of photo uploaded by Admin.")
690
+ elif media_type == "animation":
691
+ sent_to_channel = await client.send_animation(chat_id=STORAGE_CHANNEL_ID, animation=clean_upload_file, caption="Backup of GIF uploaded by Admin.")
692
+ else:
693
+ sent_to_channel = await client.send_video(chat_id=STORAGE_CHANNEL_ID, video=clean_upload_file, caption=f"Backup of video uploaded by Admin. File: {os.path.basename(clean_upload_file)}")
694
 
 
 
 
 
 
 
695
  storage_msg_id = sent_to_channel.id
696
 
697
  # আপনার নিজস্ব ডোমেইন বা সার্ভারের স্ট্রিমিং ও ডিরেক্ট ডাউনলোড লিংক জেনারেট
698
  stream_link = f"{BACKEND_URL}/stream/{storage_msg_id}"
699
  download_link = f"{BACKEND_URL}/download/{storage_msg_id}"
700
+ embed_link = stream_link
701
 
702
  if is_large_video:
 
703
  admin_cap = f"✅ <b>Success! (Large Video)</b>\n\n🔗 <b>Embed Link (Clean HD):</b>\n<code>{embed_link or 'N/A'}</code>\n\n📌 <i>Broadcast skipped due to large file size.</i>"
704
  await client.send_video(message.chat.id, message.video.file_id, caption=admin_cap, parse_mode=enums.ParseMode.HTML)
705
  await status_msg.delete()
 
757
 
758
  if media_type == "photo":
759
  sent_to_admin = await client.send_photo(message.chat.id, telegram_file, caption=admin_cap, parse_mode=enums.ParseMode.HTML)
 
760
  elif media_type == "animation":
761
  sent_to_admin = await client.send_animation(message.chat.id, telegram_file, caption=admin_cap, parse_mode=enums.ParseMode.HTML)
 
762
  else:
763
  vid_duration = message.video.duration if message.video and message.video.duration else 0
764
  vid_width = message.video.width if message.video and message.video.width else 0
 
774
  height=vid_height,
775
  thumb=thumb_path
776
  )
777
+
778
+ # ক্র্যাশ-ফ্রি উপায়ে file_id রিড করার জন্য ইউনিভার্সাল এক্সট্রাক্টর
779
+ tg_file_id = get_msg_file_id(sent_to_admin)
780
+ if not tg_file_id:
781
+ tg_file_id = get_msg_file_id(message) # Fallback to original
782
 
783
  await status_msg.delete()
784