Spaces:
Build error
Build error
Update app.py
Browse files
app.py
CHANGED
|
@@ -33,6 +33,7 @@ API_ID = int(os.environ.get("API_ID", 0))
|
|
| 33 |
API_HASH = os.environ.get("API_HASH")
|
| 34 |
SUPABASE_URL = os.environ.get("SUPABASE_URL")
|
| 35 |
SUPABASE_KEY = os.environ.get("SUPABASE_KEY")
|
|
|
|
| 36 |
|
| 37 |
PREMIUM_CHANNEL_ID = -1002825744390
|
| 38 |
STORAGE_CHANNEL_ID = -1002825744390 # যে চ্যানেলে ভিডিও স্টোর হবে
|
|
@@ -49,6 +50,9 @@ supabase = create_client(SUPABASE_URL, SUPABASE_KEY)
|
|
| 49 |
admin_states = {}
|
| 50 |
temp_clients = {}
|
| 51 |
|
|
|
|
|
|
|
|
|
|
| 52 |
try:
|
| 53 |
main_loop = asyncio.get_running_loop()
|
| 54 |
except RuntimeError:
|
|
@@ -553,6 +557,25 @@ async def start_cloning(client, message):
|
|
| 553 |
|
| 554 |
# =================================================================
|
| 555 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 556 |
@bot.on_message(filters.command("blur") & filters.private & filters.user(ADMIN_IDS))
|
| 557 |
async def set_blur_state(client, message):
|
| 558 |
try:
|
|
@@ -595,15 +618,26 @@ def upload_file_sync(upload_url, file_path, api_key):
|
|
| 595 |
except Exception as e:
|
| 596 |
return {}
|
| 597 |
|
| 598 |
-
|
|
|
|
| 599 |
async def handle_media_upload(client, message):
|
|
|
|
| 600 |
state = admin_states.get(message.chat.id, {})
|
| 601 |
if state.get("step") == "broadcast":
|
| 602 |
await process_broadcast(client, message)
|
| 603 |
return
|
| 604 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 605 |
# FORCE ANIMATIONS (GIFS) TO BE TREATED AS VIDEOS FOR BROADCAST STABILITY
|
| 606 |
-
media_type = "video" if (
|
| 607 |
has_blur_caption = message.caption and "/blur" in message.caption.lower()
|
| 608 |
is_persistent_blur = bool(state.get("blur_percent"))
|
| 609 |
|
|
@@ -643,6 +677,7 @@ async def handle_media_upload(client, message):
|
|
| 643 |
|
| 644 |
is_large_video = False
|
| 645 |
if media_type == "video":
|
|
|
|
| 646 |
media = get_media_obj(message)
|
| 647 |
duration = media.duration if media and hasattr(media, 'duration') and media.duration else 0
|
| 648 |
file_size = media.file_size if media and hasattr(media, 'file_size') and media.file_size else 0
|
|
@@ -679,11 +714,13 @@ async def handle_media_upload(client, message):
|
|
| 679 |
clean_upload_file = original_file
|
| 680 |
|
| 681 |
# ১. ওয়াটারমার্ক (Watermark) করা - Balanced (Superfast + CRF 23)
|
|
|
|
| 682 |
if media_type == "video" and not is_large_video:
|
| 683 |
await status_msg.edit_text("⏳ Watermarking video... (HD + Superfast Processing)")
|
| 684 |
watermarked_file = f"{original_file}_wm.mp4"
|
| 685 |
|
| 686 |
-
|
|
|
|
| 687 |
audio_opts = ["-an"] if not has_audio else ["-c:a", "copy"]
|
| 688 |
|
| 689 |
cmd = [
|
|
@@ -696,19 +733,17 @@ async def handle_media_upload(client, message):
|
|
| 696 |
process = await asyncio.create_subprocess_exec(*cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
|
| 697 |
await process.communicate()
|
| 698 |
|
|
|
|
| 699 |
if process.returncode == 0 and os.path.exists(watermarked_file) and os.path.getsize(watermarked_file) > 0:
|
| 700 |
clean_upload_file = watermarked_file
|
| 701 |
|
| 702 |
-
# ২. আপ
|
| 703 |
-
# এখানে থাম্বনেইল, সঠিক ডিউরেশন এবং সাইজ জেনারেট করে পোস্ট করা হবে যাতে সাদা ০:০০ শো না করে
|
| 704 |
storage_msg_id = None
|
| 705 |
-
if media_type
|
| 706 |
-
|
| 707 |
-
|
| 708 |
-
|
| 709 |
-
|
| 710 |
-
else:
|
| 711 |
-
# ভিডিওর অরিজিনাল মেটাডাটা ও থাম্বনেইল বের করা হচ্ছে
|
| 712 |
thumb_path_storage = f"{original_file}_storage_thumb.jpg"
|
| 713 |
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)
|
| 714 |
await proc.communicate()
|
|
@@ -729,13 +764,36 @@ async def handle_media_upload(client, message):
|
|
| 729 |
height=vid_height,
|
| 730 |
thumb=thumb_path_storage
|
| 731 |
)
|
| 732 |
-
|
| 733 |
-
|
| 734 |
-
|
| 735 |
-
|
| 736 |
-
|
| 737 |
-
|
| 738 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 739 |
|
| 740 |
if is_large_video:
|
| 741 |
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>"
|
|
@@ -759,16 +817,18 @@ async def handle_media_upload(client, message):
|
|
| 759 |
else:
|
| 760 |
ff_filter = ["-vf", f"boxblur={radius}:1"]
|
| 761 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 762 |
if media_type == "photo":
|
| 763 |
cmd_blur = ["ffmpeg", "-y", "-i", clean_upload_file] + ff_filter + [blurred_file]
|
| 764 |
-
elif media_type == "animation":
|
| 765 |
-
cmd_blur = ["ffmpeg", "-y", "-i", clean_upload_file] + ff_filter + ["-c:v", "libx264", "-preset", "superfast", "-pix_fmt", "yuv420p", blurred_file]
|
| 766 |
else:
|
| 767 |
-
cmd_blur = ["ffmpeg", "-y", "-i", clean_upload_file] + ff_filter + ["-c:v", "libx264", "-preset", "superfast", "-crf", "23", "-pix_fmt", "yuv420p"
|
| 768 |
|
| 769 |
process_blur = await asyncio.create_subprocess_exec(*cmd_blur, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
|
| 770 |
await process_blur.communicate()
|
| 771 |
-
if process_blur.returncode == 0 and os.path.exists(blurred_file):
|
| 772 |
telegram_file = blurred_file
|
| 773 |
|
| 774 |
await status_msg.edit_text("⏳ Preparing to broadcast to groups...")
|
|
@@ -795,8 +855,6 @@ async def handle_media_upload(client, message):
|
|
| 795 |
|
| 796 |
if media_type == "photo":
|
| 797 |
sent_to_admin = await client.send_photo(message.chat.id, telegram_file, caption=admin_cap, parse_mode=enums.ParseMode.HTML)
|
| 798 |
-
elif media_type == "animation":
|
| 799 |
-
sent_to_admin = await client.send_animation(message.chat.id, telegram_file, caption=admin_cap, parse_mode=enums.ParseMode.HTML)
|
| 800 |
else:
|
| 801 |
media = get_media_obj(message)
|
| 802 |
vid_duration = media.duration if media and hasattr(media, 'duration') and media.duration else 0
|
|
@@ -950,54 +1008,10 @@ async def manual_clean_channel(client, message):
|
|
| 950 |
try: await temp_client.disconnect()
|
| 951 |
except: pass
|
| 952 |
await db_query(lambda: supabase.table('user_sessions').delete().eq('user_id', user_id).execute())
|
| 953 |
-
|
| 954 |
-
|
| 955 |
-
|
| 956 |
-
|
| 957 |
-
await bot.unban_chat_member(PREMIUM_CHANNEL_ID, user_id)
|
| 958 |
-
kicked += 1
|
| 959 |
-
except Exception: pass
|
| 960 |
-
|
| 961 |
-
await asyncio.sleep(1.5)
|
| 962 |
-
except FloodWait as e:
|
| 963 |
-
await asyncio.sleep(e.value + 1)
|
| 964 |
-
except Exception:
|
| 965 |
-
pass
|
| 966 |
-
|
| 967 |
-
await message.reply(f"✅ <b>Cleanup Complete!</b>\n\n👥 Members checked: {checked}\n👢 Users Kicked: {kicked}")
|
| 968 |
-
except Exception as e:
|
| 969 |
-
await message.reply(f"❌ Error: {e}")
|
| 970 |
-
|
| 971 |
-
async def auto_clean_channel_loop():
|
| 972 |
-
await asyncio.sleep(60)
|
| 973 |
-
while True:
|
| 974 |
-
try:
|
| 975 |
-
res_users = await db_query(lambda: supabase.table('referrals').select('user_id').execute())
|
| 976 |
-
if res_users.data:
|
| 977 |
-
user_ids = [u['user_id'] for u in res_users.data]
|
| 978 |
-
for user_id in set(user_ids):
|
| 979 |
-
try:
|
| 980 |
-
chat_member = await bot.get_chat_member(PREMIUM_CHANNEL_ID, user_id)
|
| 981 |
-
if chat_member.status in [enums.ChatMemberStatus.MEMBER, enums.ChatMemberStatus.RESTRICTED]:
|
| 982 |
-
res_session = await db_query(lambda: supabase.table('user_sessions').select('session_string').eq('user_id', user_id).execute())
|
| 983 |
-
|
| 984 |
-
is_valid = False
|
| 985 |
-
if res_session.data:
|
| 986 |
-
session_string = res_session.data[0]['session_string']
|
| 987 |
-
temp_client = Client(f"bg_chk_{user_id}", session_string=session_string, api_id=API_ID, api_hash=API_HASH, in_memory=True)
|
| 988 |
-
try:
|
| 989 |
-
await temp_client.connect()
|
| 990 |
-
await temp_client.get_me()
|
| 991 |
-
await temp_client.disconnect()
|
| 992 |
-
is_valid = True
|
| 993 |
-
except (SessionRevoked, AuthKeyUnregistered, UserDeactivated):
|
| 994 |
-
try: await temp_client.disconnect()
|
| 995 |
-
except: pass
|
| 996 |
-
await db_query(lambda: supabase.table('user_sessions').delete().eq('user_id', user_id).execute())
|
| 997 |
-
except Exception:
|
| 998 |
-
try: await temp_client.disconnect()
|
| 999 |
-
except: pass
|
| 1000 |
-
is_valid = True
|
| 1001 |
|
| 1002 |
if not is_valid:
|
| 1003 |
try:
|
|
@@ -1014,7 +1028,7 @@ async def auto_clean_channel_loop():
|
|
| 1014 |
|
| 1015 |
await asyncio.sleep(4 * 3600)
|
| 1016 |
|
| 1017 |
-
@bot.on_message(filters.private & filters.user(ADMIN_IDS) & ~filters.command(["start", "stats", "users", "broadcast", "png", "addvideo", "blur", "clean", "sendto", "clone"]))
|
| 1018 |
async def catch_admin_steps(client, message):
|
| 1019 |
state = admin_states.get(message.chat.id, {})
|
| 1020 |
if state.get("step") == 1:
|
|
|
|
| 33 |
API_HASH = os.environ.get("API_HASH")
|
| 34 |
SUPABASE_URL = os.environ.get("SUPABASE_URL")
|
| 35 |
SUPABASE_KEY = os.environ.get("SUPABASE_KEY")
|
| 36 |
+
BYSE_API_KEY = os.environ.get("BYSE_API_KEY", "133323knboif885fhgwxvf")
|
| 37 |
|
| 38 |
PREMIUM_CHANNEL_ID = -1002825744390
|
| 39 |
STORAGE_CHANNEL_ID = -1002825744390 # যে চ্যানেলে ভিডিও স্টোর হবে
|
|
|
|
| 50 |
admin_states = {}
|
| 51 |
temp_clients = {}
|
| 52 |
|
| 53 |
+
# ডিফল্ট আপলোড সার্ভার মোড (Telegram)
|
| 54 |
+
upload_mode = "telegram"
|
| 55 |
+
|
| 56 |
try:
|
| 57 |
main_loop = asyncio.get_running_loop()
|
| 58 |
except RuntimeError:
|
|
|
|
| 557 |
|
| 558 |
# =================================================================
|
| 559 |
|
| 560 |
+
# ================= NEW: SET UPLOAD SERVER MODE =================
|
| 561 |
+
@bot.on_message(filters.command("upload") & filters.private & filters.user(ADMIN_IDS))
|
| 562 |
+
async def set_upload_mode(client, message):
|
| 563 |
+
global upload_mode
|
| 564 |
+
args = message.command
|
| 565 |
+
if len(args) > 1:
|
| 566 |
+
mode = args[1].lower()
|
| 567 |
+
if mode in ["telegram", "tg", "local"]:
|
| 568 |
+
upload_mode = "telegram"
|
| 569 |
+
await message.reply("✅ <b>Upload server set to: Telegram</b>\nVideos will be uploaded to your own channel and streamed via Hugging Face.")
|
| 570 |
+
elif mode in ["byse", "byse.sx", "external"]:
|
| 571 |
+
upload_mode = "byse"
|
| 572 |
+
await message.reply("✅ <b>Upload server set to: Byse.sx</b>\nVideos will be uploaded to Byse.sx and streamed via their player.")
|
| 573 |
+
else:
|
| 574 |
+
await message.reply("❌ <b>Invalid server!</b> Use `/upload telegram` or `/upload byse`.")
|
| 575 |
+
else:
|
| 576 |
+
await message.reply(f"📌 <b>Current Upload Server:</b> <code>{upload_mode.upper()}</code>\n\nTo change, use:\n👉 `/upload telegram` (Storage Channel Stream)\n👉 `/upload byse` (Byse.sx third-party player)")
|
| 577 |
+
# ===============================================================
|
| 578 |
+
|
| 579 |
@bot.on_message(filters.command("blur") & filters.private & filters.user(ADMIN_IDS))
|
| 580 |
async def set_blur_state(client, message):
|
| 581 |
try:
|
|
|
|
| 618 |
except Exception as e:
|
| 619 |
return {}
|
| 620 |
|
| 621 |
+
# filters.document যুক্ত করা হলো যাতে ফাইল/ডকুমেন্ট হিসেবে ভিডিও পাঠালেও বট প্রসেস করতে পারে
|
| 622 |
+
@bot.on_message((filters.video | filters.animation | filters.photo | filters.document) & filters.private & filters.user(ADMIN_IDS))
|
| 623 |
async def handle_media_upload(client, message):
|
| 624 |
+
global upload_mode
|
| 625 |
state = admin_states.get(message.chat.id, {})
|
| 626 |
if state.get("step") == "broadcast":
|
| 627 |
await process_broadcast(client, message)
|
| 628 |
return
|
| 629 |
|
| 630 |
+
# ফাইলটি ভিডিও, জিআইএফ নাকি ফটো তা নিখুঁতভাবে চেক করা হচ্ছে
|
| 631 |
+
is_video = message.video or (message.document and message.document.mime_type and "video" in message.document.mime_type)
|
| 632 |
+
is_animation = message.animation or (message.document and message.document.mime_type and "gif" in message.document.mime_type)
|
| 633 |
+
is_photo = message.photo or (message.document and message.document.mime_type and "image" in message.document.mime_type)
|
| 634 |
+
|
| 635 |
+
# যদি ভিডিও, ফটো বা অ্যানিমেশন না হয় তবে কাস্টম ফাইল স্কিপ করবে
|
| 636 |
+
if not (is_video or is_animation or is_photo):
|
| 637 |
+
return
|
| 638 |
+
|
| 639 |
# FORCE ANIMATIONS (GIFS) TO BE TREATED AS VIDEOS FOR BROADCAST STABILITY
|
| 640 |
+
media_type = "video" if (is_video or is_animation) else "photo"
|
| 641 |
has_blur_caption = message.caption and "/blur" in message.caption.lower()
|
| 642 |
is_persistent_blur = bool(state.get("blur_percent"))
|
| 643 |
|
|
|
|
| 677 |
|
| 678 |
is_large_video = False
|
| 679 |
if media_type == "video":
|
| 680 |
+
# Safe size checks for both Videos and Animations (GIFs/Documents)
|
| 681 |
media = get_media_obj(message)
|
| 682 |
duration = media.duration if media and hasattr(media, 'duration') and media.duration else 0
|
| 683 |
file_size = media.file_size if media and hasattr(media, 'file_size') and media.file_size else 0
|
|
|
|
| 714 |
clean_upload_file = original_file
|
| 715 |
|
| 716 |
# ১. ওয়াটারমার্ক (Watermark) করা - Balanced (Superfast + CRF 23)
|
| 717 |
+
# জাইএফ (Animation) ফাইলের কোনো অডিও ট্র্যাক থাকে না, তাই এফএফএমপেগ ফেইল হওয়া ঠেকাতে অডিও বাইপাস করা হলো
|
| 718 |
if media_type == "video" and not is_large_video:
|
| 719 |
await status_msg.edit_text("⏳ Watermarking video... (HD + Superfast Processing)")
|
| 720 |
watermarked_file = f"{original_file}_wm.mp4"
|
| 721 |
|
| 722 |
+
# জাইএফ ফাইলের ক্ষেত্রে অডিও ট্র্যাক বাদ দেওয়া হবে (-an) অন্যথায় কপি করা হবে
|
| 723 |
+
has_audio = not (message.animation or (message.document and message.document.mime_type and "gif" in message.document.mime_type))
|
| 724 |
audio_opts = ["-an"] if not has_audio else ["-c:a", "copy"]
|
| 725 |
|
| 726 |
cmd = [
|
|
|
|
| 733 |
process = await asyncio.create_subprocess_exec(*cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
|
| 734 |
await process.communicate()
|
| 735 |
|
| 736 |
+
# বাগ সংশোধন: ফাইলের সাইজ ০-এর চেয়ে বেশি হলে তবেই আউটপুট ব্যবহার করা হবে, অন্যথায় অরিজিনাল ফাইল ব্যবহৃত হবে
|
| 737 |
if process.returncode == 0 and os.path.exists(watermarked_file) and os.path.getsize(watermarked_file) > 0:
|
| 738 |
clean_upload_file = watermarked_file
|
| 739 |
|
| 740 |
+
# ২. ভিডিও আপলোড (টেলিগ্রাম স্টোরেজ বা byse.sx - ইউজার সেটিং অনুযায়ী)
|
|
|
|
| 741 |
storage_msg_id = None
|
| 742 |
+
if media_type == "video":
|
| 743 |
+
if upload_mode == "telegram":
|
| 744 |
+
await status_msg.edit_text("⏳ Uploading Clean HD video to your storage channel...")
|
| 745 |
+
|
| 746 |
+
# স্টোরেজ চ্যানেলেও অরিজিনাল থাম্বনেইল, ডিউরেশন এবং সাইজ জেনারেট করে পাঠানো হচ্ছে যাতে সাদা ০:০০ শো না করে
|
|
|
|
|
|
|
| 747 |
thumb_path_storage = f"{original_file}_storage_thumb.jpg"
|
| 748 |
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)
|
| 749 |
await proc.communicate()
|
|
|
|
| 764 |
height=vid_height,
|
| 765 |
thumb=thumb_path_storage
|
| 766 |
)
|
| 767 |
+
storage_msg_id = sent_to_channel.id
|
| 768 |
+
|
| 769 |
+
# আপনার নিজস্ব ডোমেইন বা সার্ভারের স্ট্রিমিং ও ডিরেক্ট ডাউনলোড লিংক জেনারেট
|
| 770 |
+
stream_link = f"{BACKEND_URL}/stream/{storage_msg_id}"
|
| 771 |
+
download_link = f"{BACKEND_URL}/download/{storage_msg_id}"
|
| 772 |
+
embed_link = stream_link
|
| 773 |
+
else:
|
| 774 |
+
# Byse.sx আপলোড মোড
|
| 775 |
+
await status_msg.edit_text("⏳ Uploading Clean HD video to byse.sx server...")
|
| 776 |
+
api_endpoint = "https://api.byse.sx/upload/server"
|
| 777 |
+
loop = asyncio.get_event_loop()
|
| 778 |
+
response = await loop.run_in_executor(None, lambda: requests.get(api_endpoint, params={'key': BYSE_API_KEY}, timeout=30))
|
| 779 |
+
result = response.json()
|
| 780 |
+
|
| 781 |
+
if result.get('status') == 200:
|
| 782 |
+
upload_res = await loop.run_in_executor(None, upload_file_sync, result.get('result'), clean_upload_file, BYSE_API_KEY)
|
| 783 |
+
if upload_res.get('status') == 200 and 'files' in upload_res and len(upload_res['files']) > 0:
|
| 784 |
+
file_status = upload_res['files'][0].get('status', '')
|
| 785 |
+
if "not allowed" in str(file_status).lower():
|
| 786 |
+
await status_msg.edit_text(f"❌ byse.sx rejected the file: <code>{file_status}</code>", parse_mode=enums.ParseMode.HTML)
|
| 787 |
+
return
|
| 788 |
+
file_code = upload_res['files'][0].get('filecode')
|
| 789 |
+
if file_code: embed_link = f"https://bysesayeveum.com/e/{file_code}"
|
| 790 |
+
|
| 791 |
+
if not embed_link:
|
| 792 |
+
await status_msg.edit_text("❌ Uploaded to byse.sx but Embed Link not found.")
|
| 793 |
+
return
|
| 794 |
+
|
| 795 |
+
stream_link = embed_link
|
| 796 |
+
download_link = embed_link
|
| 797 |
|
| 798 |
if is_large_video:
|
| 799 |
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>"
|
|
|
|
| 817 |
else:
|
| 818 |
ff_filter = ["-vf", f"boxblur={radius}:1"]
|
| 819 |
|
| 820 |
+
# জাইএফ ফাইলের ক্ষেত্রে অডিও ট্র্যাক বাদ দেওয়া হবে (-an) অন্যথায় কপি করা হবে
|
| 821 |
+
has_audio = not (message.animation or (message.document and message.document.mime_type and "gif" in message.document.mime_type))
|
| 822 |
+
audio_opts_blur = ["-an"] if not has_audio else []
|
| 823 |
+
|
| 824 |
if media_type == "photo":
|
| 825 |
cmd_blur = ["ffmpeg", "-y", "-i", clean_upload_file] + ff_filter + [blurred_file]
|
|
|
|
|
|
|
| 826 |
else:
|
| 827 |
+
cmd_blur = ["ffmpeg", "-y", "-i", clean_upload_file] + ff_filter + ["-c:v", "libx264", "-preset", "superfast", "-crf", "23", "-pix_fmt", "yuv420p"] + audio_opts_blur + ["-movflags", "+faststart", blurred_file]
|
| 828 |
|
| 829 |
process_blur = await asyncio.create_subprocess_exec(*cmd_blur, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
|
| 830 |
await process_blur.communicate()
|
| 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 |
|
| 834 |
await status_msg.edit_text("⏳ Preparing to broadcast to groups...")
|
|
|
|
| 855 |
|
| 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 |
media = get_media_obj(message)
|
| 860 |
vid_duration = media.duration if media and hasattr(media, 'duration') and media.duration else 0
|
|
|
|
| 1008 |
try: await temp_client.disconnect()
|
| 1009 |
except: pass
|
| 1010 |
await db_query(lambda: supabase.table('user_sessions').delete().eq('user_id', user_id).execute())
|
| 1011 |
+
except Exception:
|
| 1012 |
+
try: await temp_client.disconnect()
|
| 1013 |
+
except: pass
|
| 1014 |
+
is_valid = True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1015 |
|
| 1016 |
if not is_valid:
|
| 1017 |
try:
|
|
|
|
| 1028 |
|
| 1029 |
await asyncio.sleep(4 * 3600)
|
| 1030 |
|
| 1031 |
+
@bot.on_message(filters.private & filters.user(ADMIN_IDS) & ~filters.command(["start", "stats", "users", "broadcast", "png", "addvideo", "blur", "clean", "sendto", "clone", "upload"]))
|
| 1032 |
async def catch_admin_steps(client, message):
|
| 1033 |
state = admin_states.get(message.chat.id, {})
|
| 1034 |
if state.get("step") == 1:
|