From 78730743e2bfbb4ec3ff5fcf7dcf5bb183ba372c Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Sun, 13 Sep 2026 11:56:58 +0530 Subject: [PATCH 01/77] Implement callback functions for menu interactions Added callback functions for about, disclaimer, home menu, and filter buttons. --- plugins/Boultflix-fix.py | 126 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 plugins/Boultflix-fix.py diff --git a/plugins/Boultflix-fix.py b/plugins/Boultflix-fix.py new file mode 100644 index 00000000..5cef33b5 --- /dev/null +++ b/plugins/Boultflix-fix.py @@ -0,0 +1,126 @@ +import logging +from pyrogram import Client, filters, enums +from pyrogram.types import CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton +from utils import get_size, clean_filename, temp +from database.ia_filterdb import get_search_results + +logger = logging.getLogger(__name__) + +# ========================================== +# 1. FIX: ABOUT & START MENUS (NO CRASH / UNRESPONSIVE) +# ========================================== +@Client.on_callback_query(filters.regex(r"^about"), group=-1) +async def fix_about_callback(client: Client, query: CallbackQuery): + await query.answer("About Details") + about_text = ( + "╭─────[ Mʏ Dᴇᴛᴀɪʟs 🫧 ]──────⍟\n" + f"├⍟ Mʏ Nᴀᴍᴇ : Bᴏᴜʟᴛғʟɪx Mᴏᴠɪᴇs 🫧🫶🏼\n" + f"├⍟ Dᴇᴠᴇʟᴏᴘᴇʀ : Oᴡɴᴇʀ ⚡\n" + "├⍟ Lɪʙʀᴀʀʏ : Pʏʀᴏɢʀᴀᴍ\n" + "├⍟ Lᴀɴɢᴜᴀɢᴇ : Pʏᴛʜᴏɴ 3\n" + "├⍟ Dᴀᴛᴀʙᴀsᴇ : Mᴏɴɢᴏ DB\n" + "├⍟ Bᴏᴛ Sᴇʀᴠᴇʀ : Rᴇɴᴅᴇʀ\n" + "├⍟ Bᴜɪʟᴅ Sᴛᴀᴛᴜs : v1.4 [ Sᴛᴀʙʟᴇ 🚀 ]\n" + "╰───────────────⍟" + ) + buttons = InlineKeyboardMarkup([ + [InlineKeyboardButton("‼️ Dɪsᴄʟᴀɪᴍᴇʀ ‼️", callback_data="disclaimer_menu")], + [InlineKeyboardButton("⇋ Bᴀᴄᴋ ⇋", callback_data="home_menu")] + ]) + try: + await query.message.edit_caption(caption=about_text, reply_markup=buttons) + except Exception: + await query.message.edit_text(text=about_text, reply_markup=buttons) + + +@Client.on_callback_query(filters.regex(r"^disclaimer_menu"), group=-1) +async def fix_disclaimer_callback(client: Client, query: CallbackQuery): + await query.answer("Disclaimer") + disclaimer_text = ( + "ᴛʜɪꜱ ɪꜱ ᴀɴ ᴏᴘᴇɴ ꜱᴏᴜʀᴄᴇ ᴘʀᴏᴊᴇᴄᴛ.\n\n" + "ᴀʟʟ ᴛʜᴇ ꜰɪʟᴇꜱ ɪɴ ᴛʜɪꜱ ʙᴏᴛ ᴀʀᴇ ꜰʀᴇᴇʟʏ ᴀᴠᴀɪʟᴀʙʟᴇ ᴏɴ ᴛʜᴇ ɪɴᴛᴇʀɴᴇᴛ ᴏʀ ᴘᴏꜱᴛᴇᴅ ʙʏ ꜱᴏᴍᴇʙᴏᴅʏ ᴇʟꜱᴇ. " + "ᴊᴜꜱᴛ ꜰᴏʀ ᴇᴀꜱʏ ꜱᴇᴀʀᴄʜɪɴɢ ᴛʜɪꜱ ʙᴏᴛ ɪꜱ ɪɴᴅᴇxɪɴɢ ꜰɪʟᴇꜱ ᴡʜɪᴄʜ ᴀʀᴇ ᴀʟʀᴇᴀᴅʏ ᴜᴘʟᴏᴀᴅᴇᴅ ᴏɴ ᴛᴇʟᴇɢʀᴀᴍ." + ) + buttons = InlineKeyboardMarkup([ + [InlineKeyboardButton("⇋ Bᴀᴄᴋ ⇋", callback_data="about")] + ]) + try: + await query.message.edit_caption(caption=disclaimer_text, reply_markup=buttons) + except Exception: + await query.message.edit_text(text=disclaimer_text, reply_markup=buttons) + + +@Client.on_callback_query(filters.regex(r"^home_menu"), group=-1) +async def fix_home_callback(client: Client, query: CallbackQuery): + await query.answer("Home Menu") + caption = ( + f"Hᴇʏ 🍿 {query.from_user.mention} 🥷\n\n" + f"📍 Wᴇʟᴄᴏᴍᴇ ᴛᴏ ᴛʜᴇ ᴡᴏʀʟᴅ's ᴄᴏᴏʟᴇsᴛ sᴇᴀʀᴄʜ ᴇɴɢɪɴᴇ! ⚡\n\n" + f"Hᴇʀᴇ ʏᴏᴜ ᴄᴀɴ ʀᴇǫᴜᴇsᴛ ᴍᴏᴠɪᴇs & sᴇʀɪᴇs, ᴊᴜsᴛ sᴇɴᴅ ɴᴀᴍᴇ ᴡɪᴛʜ ᴘʀᴏᴘᴇʀ Gᴏᴏɢʟᴇ sᴘᴇʟʟɪɴɢ..!! 🫧🎬" + ) + buttons = InlineKeyboardMarkup([ + [InlineKeyboardButton("🔰 Aᴅᴅ Mᴇ Tᴏ Yᴏᴜʀ Gʀᴏᴜᴘ 🔰", url=f"https://t.me/{temp.U_NAME}?startgroup=true")], + [InlineKeyboardButton("📢 Uᴘᴅᴀᴛᴇs Cʜᴀɴɴᴇﻟ 📢", url="https://t.me/+f-k01NScSxEyNzc1")], + [InlineKeyboardButton("📑 Hᴇʟᴘ", callback_data="help_menu"), InlineKeyboardButton("ℹ️ Aʙᴏᴜᴛ", callback_data="about")] + ]) + try: + await query.message.edit_caption(caption=caption, reply_markup=buttons) + except Exception: + await query.message.edit_text(text=caption, reply_markup=buttons) + + +# ========================================== +# 2. FIX: QUALITY, LANGUAGE & SEASON FILTER BUTTONS +# ========================================== +@Client.on_callback_query(filters.regex(r"^(btn_quality|filter_quality|QUALITY)"), group=-1) +async def fix_quality_buttons(client: Client, query: CallbackQuery): + await query.answer("Select Quality") + q_markup = InlineKeyboardMarkup([ + [InlineKeyboardButton("360P", callback_data="filter_exec_360p"), InlineKeyboardButton("480P", callback_data="filter_exec_480p")], + [InlineKeyboardButton("720P", callback_data="filter_exec_720p"), InlineKeyboardButton("1080P", callback_data="filter_exec_1080p")], + [InlineKeyboardButton("1440P", callback_data="filter_exec_1440p"), InlineKeyboardButton("2160P", callback_data="filter_exec_2160p")], + [InlineKeyboardButton("4K", callback_data="filter_exec_4k")], + [InlineKeyboardButton("« Bᴀᴄᴋ Tᴏ Fɪʟᴇs »", callback_data="close_data")] + ]) + try: + await query.message.edit_reply_markup(reply_markup=q_markup) + except Exception: + pass + + +@Client.on_callback_query(filters.regex(r"^(btn_language|filter_language|LANGUAGE)"), group=-1) +async def fix_language_buttons(client: Client, query: CallbackQuery): + await query.answer("Select Language") + l_markup = InlineKeyboardMarkup([ + [InlineKeyboardButton("Mᴀʟᴀʏᴀʟᴀᴍ", callback_data="filter_exec_malayalam"), InlineKeyboardButton("Tᴀᴍɪʟ", callback_data="filter_exec_tamil")], + [InlineKeyboardButton("Eɴɢʟɪsʜ", callback_data="filter_exec_english"), InlineKeyboardButton("Hɪɴᴅɪ", callback_data="filter_exec_hindi")], + [InlineKeyboardButton("Tᴇʟᴜɢᴜ", callback_data="filter_exec_telugu"), InlineKeyboardButton("Kᴀɴɴᴀᴅᴀ", callback_data="filter_exec_kannada")], + [InlineKeyboardButton("Gᴜᴊᴀʀᴀᴛɪ", callback_data="filter_exec_gujarati"), InlineKeyboardButton("Mᴀʀᴀᴛʜɪ", callback_data="filter_exec_marathi")], + [InlineKeyboardButton("Pᴜɴᴊᴀʙɪ", callback_data="filter_exec_punjabi"), InlineKeyboardButton("Dᴜᴀʟ Aᴜᴅɪᴏ", callback_data="filter_exec_dual")], + [InlineKeyboardButton("« Bᴀᴄᴋ Tᴏ Fɪʟᴇs »", callback_data="close_data")] + ]) + try: + await query.message.edit_reply_markup(reply_markup=l_markup) + except Exception: + pass + + +@Client.on_callback_query(filters.regex(r"^(btn_season|filter_season|SEASON)"), group=-1) +async def fix_season_buttons(client: Client, query: CallbackQuery): + await query.answer("Select Season") + s_markup = InlineKeyboardMarkup([ + [InlineKeyboardButton("Sᴇᴀsᴏɴ 1", callback_data="filter_exec_s01"), InlineKeyboardButton("Sᴇᴀsᴏɴ 2", callback_data="filter_exec_s02")], + [InlineKeyboardButton("Sᴇᴀsᴏɴ 3", callback_data="filter_exec_s03"), InlineKeyboardButton("Sᴇᴀsᴏɴ 4", callback_data="filter_exec_s04")], + [InlineKeyboardButton("Sᴇᴀsᴏɴ 5", callback_data="filter_exec_s05"), InlineKeyboardButton("Sᴇᴀsᴏɴ 6", callback_data="filter_exec_s06")], + [InlineKeyboardButton("« Bᴀᴄᴋ Tᴏ Fɪʟᴇs »", callback_data="close_data")] + ]) + try: + await query.message.edit_reply_markup(reply_markup=s_markup) + except Exception: + pass + + +@Client.on_callback_query(filters.regex(r"^filter_exec_"), group=-1) +async def handle_filter_execution(client: Client, query: CallbackQuery): + tag = query.data.replace("filter_exec_", "") + await query.answer(f"Filtering files with '{tag.upper()}'... 🍿", show_alert=False) From 52223a07a54cacdbfcdf7266d8ea0d2246d8b287 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Sun, 13 Sep 2026 12:02:30 +0530 Subject: [PATCH 02/77] Update Boultflix-fix.py --- plugins/Boultflix-fix.py | 226 +++++++++++++++++++++++++++++++++------ 1 file changed, 195 insertions(+), 31 deletions(-) diff --git a/plugins/Boultflix-fix.py b/plugins/Boultflix-fix.py index 5cef33b5..d218ee15 100644 --- a/plugins/Boultflix-fix.py +++ b/plugins/Boultflix-fix.py @@ -1,15 +1,160 @@ +import os +import re +import asyncio import logging +from datetime import datetime, timedelta +import pytz from pyrogram import Client, filters, enums -from pyrogram.types import CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton -from utils import get_size, clean_filename, temp -from database.ia_filterdb import get_search_results +from pyrogram.types import CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton, Message +from pyrogram.errors import MessageNotModified +from shortzy import Shortzy + +from info import ( + SHORTENER_API, + SHORTENER_WEBSITE, + UPDATES_CHANNEL_URL if 'UPDATES_CHANNEL_URL' in globals() else 'UPDATE_CHNL_LNK', + LOG_CHANNEL +) +from utils import temp, get_size, clean_filename +from database.users_chats_db import db +from database.ia_filterdb import get_file_details, get_search_results logger = logging.getLogger(__name__) +UPDATES_LINK = "https://t.me/+f-k01NScSxEyNzc1" +DELETE_TIME = 300 # 5 minutes auto-delete timer + +# ========================================== +# 1. 24-HOURS TOKEN VERIFICATION SYSTEM +# ========================================== +async def is_user_verified_24h(user_id: int): + user = await db.get_notcopy_user(user_id) + if not user: + return False + + last_verified = user.get("last_verified") + if not last_verified: + return False + + ist_timezone = pytz.timezone('Asia/Kolkata') + if last_verified.tzinfo is None: + last_verified = ist_timezone.localize(last_verified) + else: + last_verified = last_verified.astimezone(ist_timezone) + + current_time = datetime.now(tz=ist_timezone) + time_diff = (current_time - last_verified).total_seconds() + + # 24 Hours = 86400 Seconds + return time_diff < 86400 + +async def set_user_verified_24h(user_id: int): + ist_timezone = pytz.timezone('Asia/Kolkata') + current_time = datetime.now(tz=ist_timezone) + await db.update_notcopy_user(user_id, {"last_verified": current_time}) + # ========================================== -# 1. FIX: ABOUT & START MENUS (NO CRASH / UNRESPONSIVE) +# 2. START HANDLER INTERCEPTOR (VERIFICATION + AUTO-DELETE) # ========================================== -@Client.on_callback_query(filters.regex(r"^about"), group=-1) +@Client.on_message(filters.command("start") & filters.private, group=-2) +async def fix_start_delivery_interceptor(client: Client, message: Message): + user_id = message.from_user.id + command_parts = message.text.split() + + if len(command_parts) > 1: + param = command_parts[1] + + # 1. Handle Verification Return Token + if param.startswith("verify_"): + verify_token = param.replace("verify_", "") + verify_doc = await db.get_verify_id_info(user_id, verify_token) + if verify_doc: + await set_user_verified_24h(user_id) + await message.reply_text( + "✅ Vᴇʀɪғɪᴄᴀᴛɪᴏɴ Sᴜᴄᴄᴇssғᴜʟ!\n\n" + "Yᴏᴜ ɴᴏᴡ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ᴛᴏ ᴅᴏᴡɴʟᴏᴀᴅ ғɪʟᴇs ғᴏʀ ᴛʜᴇ ɴᴇxᴛ 24 Hᴏᴜʀs! 🍿⚡", + quote=True + ) + return + else: + await message.reply_text("❌ Iɴᴠᴀʟɪᴅ ᴏʀ Exᴘɪʀᴇᴅ Vᴇʀɪғɪᴄᴀᴛɪᴏɴ Lɪɴᴋ!", quote=True) + return + + # 2. Handle File Delivery (Deep Links) + if param.startswith("file_") or param.startswith("getfile-"): + # Check 24 Hours Verification Status + is_verified = await is_user_verified_24h(user_id) + has_prem = await db.has_premium_access(user_id) + + if not is_verified and not has_prem and SHORTENER_API and SHORTENER_WEBSITE: + token_hash = str(user_id) + "_" + str(int(datetime.now().timestamp())) + await db.create_verify_id(user_id, token_hash) + + bypass_url = f"https://t.me/{temp.U_NAME}?start=verify_{token_hash}" + try: + shortzy = Shortzy(SHORTENER_API, SHORTENER_WEBSITE) + short_link = await shortzy.convert(bypass_url) + except Exception: + short_link = bypass_url + + v_btn = InlineKeyboardMarkup([ + [InlineKeyboardButton("🔓 Cʟɪᴄᴋ Hᴇʀᴇ Tᴏ Vᴇʀɪғʏ (24h) 🔓", url=short_link)], + [InlineKeyboardButton("❓ Hᴏᴡ Tᴏ Vᴇʀɪғʏ (Tᴜᴛᴏʀɪᴀʟ) ❓", url=UPDATES_LINK)] + ]) + await message.reply_text( + f"👋 Hᴇʏ {message.from_user.mention},\n\n" + f"⚠️ Aᴄᴄᴇss Dᴇɴɪᴇᴅ: Vᴇʀɪғɪᴄᴀᴛɪᴏɴ Rᴇǫᴜɪʀᴇᴅ!\n\n" + f"Pʟᴇᴀsᴇ ᴠᴇʀɪғʏ ʏᴏᴜʀ ᴛᴏᴋᴇɴ ᴛᴏ ɢᴇᴛ 24 Hᴏᴜʀs Uɴʟɪᴍɪᴛᴇᴅ Fɪʟᴇ Aᴄᴄᴇss. " + f"Cʟɪᴄᴋ ᴛʜᴇ ʙᴜᴛᴛᴏɴ ʙᴇʟᴏᴡ ᴛᴏ ᴠᴇʀɪғʏ 👇", + reply_markup=v_btn, + quote=True + ) + message.stop_propagation() + return + + # Extract File ID + file_id = param.split("_")[-1] if "_" in param else param.replace("getfile-", "") + files_ = await get_file_details(file_id) + if files_: + file_info = files_[0] + file_btn = InlineKeyboardMarkup([ + [InlineKeyboardButton("📌 JOIN UPDATES CHANNEL 📌", url=UPDATES_LINK)] + ]) + caption = f"📁 FILENAME : {clean_filename(file_info.file_name)}\n\n⚙️ SIZE : {get_size(file_info.file_size)}" + + try: + sent_msg = await client.send_cached_media( + chat_id=user_id, + file_id=file_info.file_id, + caption=caption, + reply_markup=file_btn + ) + + # Auto-Delete Warning Banner + warn_text = ( + "⚠️ THIS MOVIE FILE/VIDEO WILL BE DELETED IN 5 MINUTE\n\n" + "PLEASE FORWARD THIS FILE TO SOMEWHERE ELSE & START DOWNLOADING THERE" + ) + warn_msg = await message.reply_text(warn_text) + + async def auto_delete_task(): + await asyncio.sleep(DELETE_TIME) + try: + await sent_msg.delete() + await warn_msg.edit_text("❌ YOUR VIDEO / FILE IS SUCCESSFULLY DELETED TO PROTECT THIS BOT FROM COPYRIGHT TAKEDOWN ✨🎬") + except Exception: + pass + + asyncio.create_task(auto_delete_task()) + message.stop_propagation() + return + except Exception as e: + logger.error(f"Send Cached Media Error: {e}") + +# ========================================== +# 3. ABOUT, DISCLAIMER & HOME MENU CALLBACKS +# ========================================== +@Client.on_callback_query(filters.regex(r"^(about|about_menu)"), group=-1) async def fix_about_callback(client: Client, query: CallbackQuery): await query.answer("About Details") about_text = ( @@ -32,7 +177,6 @@ async def fix_about_callback(client: Client, query: CallbackQuery): except Exception: await query.message.edit_text(text=about_text, reply_markup=buttons) - @Client.on_callback_query(filters.regex(r"^disclaimer_menu"), group=-1) async def fix_disclaimer_callback(client: Client, query: CallbackQuery): await query.answer("Disclaimer") @@ -49,7 +193,6 @@ async def fix_disclaimer_callback(client: Client, query: CallbackQuery): except Exception: await query.message.edit_text(text=disclaimer_text, reply_markup=buttons) - @Client.on_callback_query(filters.regex(r"^home_menu"), group=-1) async def fix_home_callback(client: Client, query: CallbackQuery): await query.answer("Home Menu") @@ -60,7 +203,7 @@ async def fix_home_callback(client: Client, query: CallbackQuery): ) buttons = InlineKeyboardMarkup([ [InlineKeyboardButton("🔰 Aᴅᴅ Mᴇ Tᴏ Yᴏᴜʀ Gʀᴏᴜᴘ 🔰", url=f"https://t.me/{temp.U_NAME}?startgroup=true")], - [InlineKeyboardButton("📢 Uᴘᴅᴀᴛᴇs Cʜᴀɴɴᴇﻟ 📢", url="https://t.me/+f-k01NScSxEyNzc1")], + [InlineKeyboardButton("📢 Uᴘᴅᴀᴛᴇs Cʜᴀɴɴᴇﻟ 📢", url=UPDATES_LINK)], [InlineKeyboardButton("📑 Hᴇʟᴘ", callback_data="help_menu"), InlineKeyboardButton("ℹ️ Aʙᴏᴜᴛ", callback_data="about")] ]) try: @@ -68,59 +211,80 @@ async def fix_home_callback(client: Client, query: CallbackQuery): except Exception: await query.message.edit_text(text=caption, reply_markup=buttons) - # ========================================== -# 2. FIX: QUALITY, LANGUAGE & SEASON FILTER BUTTONS +# 4. QUALITY, LANGUAGE & SEASON FILTER MENUS # ========================================== @Client.on_callback_query(filters.regex(r"^(btn_quality|filter_quality|QUALITY)"), group=-1) async def fix_quality_buttons(client: Client, query: CallbackQuery): await query.answer("Select Quality") q_markup = InlineKeyboardMarkup([ - [InlineKeyboardButton("360P", callback_data="filter_exec_360p"), InlineKeyboardButton("480P", callback_data="filter_exec_480p")], - [InlineKeyboardButton("720P", callback_data="filter_exec_720p"), InlineKeyboardButton("1080P", callback_data="filter_exec_1080p")], - [InlineKeyboardButton("1440P", callback_data="filter_exec_1440p"), InlineKeyboardButton("2160P", callback_data="filter_exec_2160p")], - [InlineKeyboardButton("4K", callback_data="filter_exec_4k")], - [InlineKeyboardButton("« Bᴀᴄᴋ Tᴏ Fɪʟᴇs »", callback_data="close_data")] + [InlineKeyboardButton("360P", callback_data="filter_run#360p"), InlineKeyboardButton("480P", callback_data="filter_run#480p")], + [InlineKeyboardButton("720P", callback_data="filter_run#720p"), InlineKeyboardButton("1080P", callback_data="filter_run#1080p")], + [InlineKeyboardButton("1440P", callback_data="filter_run#1440p"), InlineKeyboardButton("2160P", callback_data="filter_run#2160p")], + [InlineKeyboardButton("4K", callback_data="filter_run#4k")], + [InlineKeyboardButton("« Bᴀᴄᴋ Tᴏ Fɪʟᴇs »", callback_data="back_to_results")] ]) try: await query.message.edit_reply_markup(reply_markup=q_markup) except Exception: pass - @Client.on_callback_query(filters.regex(r"^(btn_language|filter_language|LANGUAGE)"), group=-1) async def fix_language_buttons(client: Client, query: CallbackQuery): await query.answer("Select Language") l_markup = InlineKeyboardMarkup([ - [InlineKeyboardButton("Mᴀʟᴀʏᴀʟᴀᴍ", callback_data="filter_exec_malayalam"), InlineKeyboardButton("Tᴀᴍɪʟ", callback_data="filter_exec_tamil")], - [InlineKeyboardButton("Eɴɢʟɪsʜ", callback_data="filter_exec_english"), InlineKeyboardButton("Hɪɴᴅɪ", callback_data="filter_exec_hindi")], - [InlineKeyboardButton("Tᴇʟᴜɢᴜ", callback_data="filter_exec_telugu"), InlineKeyboardButton("Kᴀɴɴᴀᴅᴀ", callback_data="filter_exec_kannada")], - [InlineKeyboardButton("Gᴜᴊᴀʀᴀᴛɪ", callback_data="filter_exec_gujarati"), InlineKeyboardButton("Mᴀʀᴀᴛʜɪ", callback_data="filter_exec_marathi")], - [InlineKeyboardButton("Pᴜɴᴊᴀʙɪ", callback_data="filter_exec_punjabi"), InlineKeyboardButton("Dᴜᴀʟ Aᴜᴅɪᴏ", callback_data="filter_exec_dual")], - [InlineKeyboardButton("« Bᴀᴄᴋ Tᴏ Fɪʟᴇs »", callback_data="close_data")] + [InlineKeyboardButton("Mᴀʟᴀʏᴀʟᴀᴍ", callback_data="filter_run#malayalam"), InlineKeyboardButton("Tᴀᴍɪʟ", callback_data="filter_run#tamil")], + [InlineKeyboardButton("Eɴɢʟɪsʜ", callback_data="filter_run#english"), InlineKeyboardButton("Hɪɴᴅɪ", callback_data="filter_run#hindi")], + [InlineKeyboardButton("Tᴇʟᴜɢᴜ", callback_data="filter_run#telugu"), InlineKeyboardButton("Kᴀɴɴᴀᴅᴀ", callback_data="filter_run#kannada")], + [InlineKeyboardButton("Gᴜᴊᴀʀᴀᴛɪ", callback_data="filter_run#gujarati"), InlineKeyboardButton("Mᴀʀᴀᴛʜɪ", callback_data="filter_run#marathi")], + [InlineKeyboardButton("Pᴜɴᴊᴀʙɪ", callback_data="filter_run#punjabi"), InlineKeyboardButton("Dᴜᴀʟ Aᴜᴅɪᴏ", callback_data="filter_run#dual")], + [InlineKeyboardButton("« Bᴀᴄᴋ Tᴏ Fɪʟᴇs »", callback_data="back_to_results")] ]) try: await query.message.edit_reply_markup(reply_markup=l_markup) except Exception: pass - @Client.on_callback_query(filters.regex(r"^(btn_season|filter_season|SEASON)"), group=-1) async def fix_season_buttons(client: Client, query: CallbackQuery): await query.answer("Select Season") s_markup = InlineKeyboardMarkup([ - [InlineKeyboardButton("Sᴇᴀsᴏɴ 1", callback_data="filter_exec_s01"), InlineKeyboardButton("Sᴇᴀsᴏɴ 2", callback_data="filter_exec_s02")], - [InlineKeyboardButton("Sᴇᴀsᴏɴ 3", callback_data="filter_exec_s03"), InlineKeyboardButton("Sᴇᴀsᴏɴ 4", callback_data="filter_exec_s04")], - [InlineKeyboardButton("Sᴇᴀsᴏɴ 5", callback_data="filter_exec_s05"), InlineKeyboardButton("Sᴇᴀsᴏɴ 6", callback_data="filter_exec_s06")], - [InlineKeyboardButton("« Bᴀᴄᴋ Tᴏ Fɪʟᴇs »", callback_data="close_data")] + [InlineKeyboardButton("Sᴇᴀsᴏɴ 1", callback_data="filter_run#s01"), InlineKeyboardButton("Sᴇᴀsᴏɴ 2", callback_data="filter_run#s02")], + [InlineKeyboardButton("Sᴇᴀsᴏɴ 3", callback_data="filter_run#s03"), InlineKeyboardButton("Sᴇᴀsᴏɴ 4", callback_data="filter_run#s04")], + [InlineKeyboardButton("Sᴇᴀsᴏɴ 5", callback_data="filter_run#s05"), InlineKeyboardButton("Sᴇᴀsᴏɴ 6", callback_data="filter_run#s06")], + [InlineKeyboardButton("« Bᴀᴄᴋ Tᴏ Fɪʟᴇs »", callback_data="back_to_results")] ]) try: await query.message.edit_reply_markup(reply_markup=s_markup) except Exception: pass +# ========================================== +# 5. BACK TO FILES & FILTER EXECUTION +# ========================================== +@Client.on_callback_query(filters.regex(r"^back_to_results"), group=-1) +async def back_to_files_handler(client: Client, query: CallbackQuery): + await query.answer("Loading original files list...") + original_markup = InlineKeyboardMarkup([ + [InlineKeyboardButton("REMOVE ADS", callback_data="remove_ads"), InlineKeyboardButton("⚡ SEND ALL", callback_data="send_all")], + [ + InlineKeyboardButton("QUALITY", callback_data="btn_quality"), + InlineKeyboardButton("LANGUAGE", callback_data="btn_language"), + InlineKeyboardButton("SEASON", callback_data="btn_season") + ], + [ + InlineKeyboardButton("PAGE", callback_data="ignore"), + InlineKeyboardButton("1/1", callback_data="ignore"), + InlineKeyboardButton("NEXT ➢", callback_data="ignore") + ], + [InlineKeyboardButton("« NO MORE PAGES AVAILABLE »", callback_data="ignore")] + ]) + try: + await query.message.edit_reply_markup(reply_markup=original_markup) + except Exception: + pass -@Client.on_callback_query(filters.regex(r"^filter_exec_"), group=-1) -async def handle_filter_execution(client: Client, query: CallbackQuery): - tag = query.data.replace("filter_exec_", "") - await query.answer(f"Filtering files with '{tag.upper()}'... 🍿", show_alert=False) +@Client.on_callback_query(filters.regex(r"^filter_run#"), group=-1) +async def filter_run_handler(client: Client, query: CallbackQuery): + tag = query.data.split("#")[1] + await query.answer(f"Filtering files by: {tag.upper()} 🍿", show_alert=False) From f37e5332998cc2f8e88474e1967f389852accf52 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Sun, 13 Sep 2026 12:04:44 +0530 Subject: [PATCH 03/77] Refactor verification messages and imports --- plugins/Boultflix-fix.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/plugins/Boultflix-fix.py b/plugins/Boultflix-fix.py index d218ee15..9c15ec52 100644 --- a/plugins/Boultflix-fix.py +++ b/plugins/Boultflix-fix.py @@ -12,12 +12,11 @@ from info import ( SHORTENER_API, SHORTENER_WEBSITE, - UPDATES_CHANNEL_URL if 'UPDATES_CHANNEL_URL' in globals() else 'UPDATE_CHNL_LNK', LOG_CHANNEL ) from utils import temp, get_size, clean_filename from database.users_chats_db import db -from database.ia_filterdb import get_file_details, get_search_results +from database.ia_filterdb import get_file_details logger = logging.getLogger(__name__) @@ -72,17 +71,17 @@ async def fix_start_delivery_interceptor(client: Client, message: Message): await set_user_verified_24h(user_id) await message.reply_text( "✅ Vᴇʀɪғɪᴄᴀᴛɪᴏɴ Sᴜᴄᴄᴇssғᴜʟ!\n\n" - "Yᴏᴜ ɴᴏᴡ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ᴛᴏ ᴅᴏᴡɴʟᴏᴀᴅ ғɪʟᴇs ғᴏʀ ᴛʜᴇ ɴᴇxᴛ 24 Hᴏᴜʀs! 🍿⚡", - quote=True + "Yᴏᴜ ɴᴏᴡ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ᴛᴏ ᴅᴏᴡɴʟᴏᴀᴅ ғɪʟᴇs ғᴏʀ ᴛʜᴇ ɴᴇxᴛ 24 Hᴏᴜʀs! 🍿⚡" ) + message.stop_propagation() return else: - await message.reply_text("❌ Iɴᴠᴀʟɪᴅ ᴏʀ Exᴘɪʀᴇᴅ Vᴇʀɪғɪᴄᴀᴛɪᴏɴ Lɪɴᴋ!", quote=True) + await message.reply_text("❌ Iɴᴠᴀʟɪᴅ ᴏʀ Exᴘɪʀᴇᴅ Vᴇʀɪғɪᴄᴀᴛɪᴏɴ Lɪɴᴋ!") + message.stop_propagation() return # 2. Handle File Delivery (Deep Links) if param.startswith("file_") or param.startswith("getfile-"): - # Check 24 Hours Verification Status is_verified = await is_user_verified_24h(user_id) has_prem = await db.has_premium_access(user_id) @@ -106,8 +105,7 @@ async def fix_start_delivery_interceptor(client: Client, message: Message): f"⚠️ Aᴄᴄᴇss Dᴇɴɪᴇᴅ: Vᴇʀɪғɪᴄᴀᴛɪᴏɴ Rᴇǫᴜɪʀᴇᴅ!\n\n" f"Pʟᴇᴀsᴇ ᴠᴇʀɪғʏ ʏᴏᴜʀ ᴛᴏᴋᴇɴ ᴛᴏ ɢᴇᴛ 24 Hᴏᴜʀs Uɴʟɪᴍɪᴛᴇᴅ Fɪʟᴇ Aᴄᴄᴇss. " f"Cʟɪᴄᴋ ᴛʜᴇ ʙᴜᴛᴛᴏɴ ʙᴇʟᴏᴡ ᴛᴏ ᴠᴇʀɪғʏ 👇", - reply_markup=v_btn, - quote=True + reply_markup=v_btn ) message.stop_propagation() return @@ -130,7 +128,7 @@ async def fix_start_delivery_interceptor(client: Client, message: Message): reply_markup=file_btn ) - # Auto-Delete Warning Banner + # Kurigram safe reply warn_text = ( "⚠️ THIS MOVIE FILE/VIDEO WILL BE DELETED IN 5 MINUTE\n\n" "PLEASE FORWARD THIS FILE TO SOMEWHERE ELSE & START DOWNLOADING THERE" From 925517e6b2345d68868a655e9efd316e732c5fb0 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Sun, 13 Sep 2026 12:11:11 +0530 Subject: [PATCH 04/77] Delete plugins/Boultflix-fix.py --- plugins/Boultflix-fix.py | 288 --------------------------------------- 1 file changed, 288 deletions(-) delete mode 100644 plugins/Boultflix-fix.py diff --git a/plugins/Boultflix-fix.py b/plugins/Boultflix-fix.py deleted file mode 100644 index 9c15ec52..00000000 --- a/plugins/Boultflix-fix.py +++ /dev/null @@ -1,288 +0,0 @@ -import os -import re -import asyncio -import logging -from datetime import datetime, timedelta -import pytz -from pyrogram import Client, filters, enums -from pyrogram.types import CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton, Message -from pyrogram.errors import MessageNotModified -from shortzy import Shortzy - -from info import ( - SHORTENER_API, - SHORTENER_WEBSITE, - LOG_CHANNEL -) -from utils import temp, get_size, clean_filename -from database.users_chats_db import db -from database.ia_filterdb import get_file_details - -logger = logging.getLogger(__name__) - -UPDATES_LINK = "https://t.me/+f-k01NScSxEyNzc1" -DELETE_TIME = 300 # 5 minutes auto-delete timer - -# ========================================== -# 1. 24-HOURS TOKEN VERIFICATION SYSTEM -# ========================================== -async def is_user_verified_24h(user_id: int): - user = await db.get_notcopy_user(user_id) - if not user: - return False - - last_verified = user.get("last_verified") - if not last_verified: - return False - - ist_timezone = pytz.timezone('Asia/Kolkata') - if last_verified.tzinfo is None: - last_verified = ist_timezone.localize(last_verified) - else: - last_verified = last_verified.astimezone(ist_timezone) - - current_time = datetime.now(tz=ist_timezone) - time_diff = (current_time - last_verified).total_seconds() - - # 24 Hours = 86400 Seconds - return time_diff < 86400 - -async def set_user_verified_24h(user_id: int): - ist_timezone = pytz.timezone('Asia/Kolkata') - current_time = datetime.now(tz=ist_timezone) - await db.update_notcopy_user(user_id, {"last_verified": current_time}) - -# ========================================== -# 2. START HANDLER INTERCEPTOR (VERIFICATION + AUTO-DELETE) -# ========================================== -@Client.on_message(filters.command("start") & filters.private, group=-2) -async def fix_start_delivery_interceptor(client: Client, message: Message): - user_id = message.from_user.id - command_parts = message.text.split() - - if len(command_parts) > 1: - param = command_parts[1] - - # 1. Handle Verification Return Token - if param.startswith("verify_"): - verify_token = param.replace("verify_", "") - verify_doc = await db.get_verify_id_info(user_id, verify_token) - if verify_doc: - await set_user_verified_24h(user_id) - await message.reply_text( - "✅ Vᴇʀɪғɪᴄᴀᴛɪᴏɴ Sᴜᴄᴄᴇssғᴜʟ!\n\n" - "Yᴏᴜ ɴᴏᴡ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ᴛᴏ ᴅᴏᴡɴʟᴏᴀᴅ ғɪʟᴇs ғᴏʀ ᴛʜᴇ ɴᴇxᴛ 24 Hᴏᴜʀs! 🍿⚡" - ) - message.stop_propagation() - return - else: - await message.reply_text("❌ Iɴᴠᴀʟɪᴅ ᴏʀ Exᴘɪʀᴇᴅ Vᴇʀɪғɪᴄᴀᴛɪᴏɴ Lɪɴᴋ!") - message.stop_propagation() - return - - # 2. Handle File Delivery (Deep Links) - if param.startswith("file_") or param.startswith("getfile-"): - is_verified = await is_user_verified_24h(user_id) - has_prem = await db.has_premium_access(user_id) - - if not is_verified and not has_prem and SHORTENER_API and SHORTENER_WEBSITE: - token_hash = str(user_id) + "_" + str(int(datetime.now().timestamp())) - await db.create_verify_id(user_id, token_hash) - - bypass_url = f"https://t.me/{temp.U_NAME}?start=verify_{token_hash}" - try: - shortzy = Shortzy(SHORTENER_API, SHORTENER_WEBSITE) - short_link = await shortzy.convert(bypass_url) - except Exception: - short_link = bypass_url - - v_btn = InlineKeyboardMarkup([ - [InlineKeyboardButton("🔓 Cʟɪᴄᴋ Hᴇʀᴇ Tᴏ Vᴇʀɪғʏ (24h) 🔓", url=short_link)], - [InlineKeyboardButton("❓ Hᴏᴡ Tᴏ Vᴇʀɪғʏ (Tᴜᴛᴏʀɪᴀʟ) ❓", url=UPDATES_LINK)] - ]) - await message.reply_text( - f"👋 Hᴇʏ {message.from_user.mention},\n\n" - f"⚠️ Aᴄᴄᴇss Dᴇɴɪᴇᴅ: Vᴇʀɪғɪᴄᴀᴛɪᴏɴ Rᴇǫᴜɪʀᴇᴅ!\n\n" - f"Pʟᴇᴀsᴇ ᴠᴇʀɪғʏ ʏᴏᴜʀ ᴛᴏᴋᴇɴ ᴛᴏ ɢᴇᴛ 24 Hᴏᴜʀs Uɴʟɪᴍɪᴛᴇᴅ Fɪʟᴇ Aᴄᴄᴇss. " - f"Cʟɪᴄᴋ ᴛʜᴇ ʙᴜᴛᴛᴏɴ ʙᴇʟᴏᴡ ᴛᴏ ᴠᴇʀɪғʏ 👇", - reply_markup=v_btn - ) - message.stop_propagation() - return - - # Extract File ID - file_id = param.split("_")[-1] if "_" in param else param.replace("getfile-", "") - files_ = await get_file_details(file_id) - if files_: - file_info = files_[0] - file_btn = InlineKeyboardMarkup([ - [InlineKeyboardButton("📌 JOIN UPDATES CHANNEL 📌", url=UPDATES_LINK)] - ]) - caption = f"📁 FILENAME : {clean_filename(file_info.file_name)}\n\n⚙️ SIZE : {get_size(file_info.file_size)}" - - try: - sent_msg = await client.send_cached_media( - chat_id=user_id, - file_id=file_info.file_id, - caption=caption, - reply_markup=file_btn - ) - - # Kurigram safe reply - warn_text = ( - "⚠️ THIS MOVIE FILE/VIDEO WILL BE DELETED IN 5 MINUTE\n\n" - "PLEASE FORWARD THIS FILE TO SOMEWHERE ELSE & START DOWNLOADING THERE" - ) - warn_msg = await message.reply_text(warn_text) - - async def auto_delete_task(): - await asyncio.sleep(DELETE_TIME) - try: - await sent_msg.delete() - await warn_msg.edit_text("❌ YOUR VIDEO / FILE IS SUCCESSFULLY DELETED TO PROTECT THIS BOT FROM COPYRIGHT TAKEDOWN ✨🎬") - except Exception: - pass - - asyncio.create_task(auto_delete_task()) - message.stop_propagation() - return - except Exception as e: - logger.error(f"Send Cached Media Error: {e}") - -# ========================================== -# 3. ABOUT, DISCLAIMER & HOME MENU CALLBACKS -# ========================================== -@Client.on_callback_query(filters.regex(r"^(about|about_menu)"), group=-1) -async def fix_about_callback(client: Client, query: CallbackQuery): - await query.answer("About Details") - about_text = ( - "╭─────[ Mʏ Dᴇᴛᴀɪʟs 🫧 ]──────⍟\n" - f"├⍟ Mʏ Nᴀᴍᴇ : Bᴏᴜʟᴛғʟɪx Mᴏᴠɪᴇs 🫧🫶🏼\n" - f"├⍟ Dᴇᴠᴇʟᴏᴘᴇʀ : Oᴡɴᴇʀ ⚡\n" - "├⍟ Lɪʙʀᴀʀʏ : Pʏʀᴏɢʀᴀᴍ\n" - "├⍟ Lᴀɴɢᴜᴀɢᴇ : Pʏᴛʜᴏɴ 3\n" - "├⍟ Dᴀᴛᴀʙᴀsᴇ : Mᴏɴɢᴏ DB\n" - "├⍟ Bᴏᴛ Sᴇʀᴠᴇʀ : Rᴇɴᴅᴇʀ\n" - "├⍟ Bᴜɪʟᴅ Sᴛᴀᴛᴜs : v1.4 [ Sᴛᴀʙʟᴇ 🚀 ]\n" - "╰───────────────⍟" - ) - buttons = InlineKeyboardMarkup([ - [InlineKeyboardButton("‼️ Dɪsᴄʟᴀɪᴍᴇʀ ‼️", callback_data="disclaimer_menu")], - [InlineKeyboardButton("⇋ Bᴀᴄᴋ ⇋", callback_data="home_menu")] - ]) - try: - await query.message.edit_caption(caption=about_text, reply_markup=buttons) - except Exception: - await query.message.edit_text(text=about_text, reply_markup=buttons) - -@Client.on_callback_query(filters.regex(r"^disclaimer_menu"), group=-1) -async def fix_disclaimer_callback(client: Client, query: CallbackQuery): - await query.answer("Disclaimer") - disclaimer_text = ( - "ᴛʜɪꜱ ɪꜱ ᴀɴ ᴏᴘᴇɴ ꜱᴏᴜʀᴄᴇ ᴘʀᴏᴊᴇᴄᴛ.\n\n" - "ᴀʟʟ ᴛʜᴇ ꜰɪʟᴇꜱ ɪɴ ᴛʜɪꜱ ʙᴏᴛ ᴀʀᴇ ꜰʀᴇᴇʟʏ ᴀᴠᴀɪʟᴀʙʟᴇ ᴏɴ ᴛʜᴇ ɪɴᴛᴇʀɴᴇᴛ ᴏʀ ᴘᴏꜱᴛᴇᴅ ʙʏ ꜱᴏᴍᴇʙᴏᴅʏ ᴇʟꜱᴇ. " - "ᴊᴜꜱᴛ ꜰᴏʀ ᴇᴀꜱʏ ꜱᴇᴀʀᴄʜɪɴɢ ᴛʜɪꜱ ʙᴏᴛ ɪꜱ ɪɴᴅᴇxɪɴɢ ꜰɪʟᴇꜱ ᴡʜɪᴄʜ ᴀʀᴇ ᴀʟʀᴇᴀᴅʏ ᴜᴘʟᴏᴀᴅᴇᴅ ᴏɴ ᴛᴇʟᴇɢʀᴀᴍ." - ) - buttons = InlineKeyboardMarkup([ - [InlineKeyboardButton("⇋ Bᴀᴄᴋ ⇋", callback_data="about")] - ]) - try: - await query.message.edit_caption(caption=disclaimer_text, reply_markup=buttons) - except Exception: - await query.message.edit_text(text=disclaimer_text, reply_markup=buttons) - -@Client.on_callback_query(filters.regex(r"^home_menu"), group=-1) -async def fix_home_callback(client: Client, query: CallbackQuery): - await query.answer("Home Menu") - caption = ( - f"Hᴇʏ 🍿 {query.from_user.mention} 🥷\n\n" - f"📍 Wᴇʟᴄᴏᴍᴇ ᴛᴏ ᴛʜᴇ ᴡᴏʀʟᴅ's ᴄᴏᴏʟᴇsᴛ sᴇᴀʀᴄʜ ᴇɴɢɪɴᴇ! ⚡\n\n" - f"Hᴇʀᴇ ʏᴏᴜ ᴄᴀɴ ʀᴇǫᴜᴇsᴛ ᴍᴏᴠɪᴇs & sᴇʀɪᴇs, ᴊᴜsᴛ sᴇɴᴅ ɴᴀᴍᴇ ᴡɪᴛʜ ᴘʀᴏᴘᴇʀ Gᴏᴏɢʟᴇ sᴘᴇʟʟɪɴɢ..!! 🫧🎬" - ) - buttons = InlineKeyboardMarkup([ - [InlineKeyboardButton("🔰 Aᴅᴅ Mᴇ Tᴏ Yᴏᴜʀ Gʀᴏᴜᴘ 🔰", url=f"https://t.me/{temp.U_NAME}?startgroup=true")], - [InlineKeyboardButton("📢 Uᴘᴅᴀᴛᴇs Cʜᴀɴɴᴇﻟ 📢", url=UPDATES_LINK)], - [InlineKeyboardButton("📑 Hᴇʟᴘ", callback_data="help_menu"), InlineKeyboardButton("ℹ️ Aʙᴏᴜᴛ", callback_data="about")] - ]) - try: - await query.message.edit_caption(caption=caption, reply_markup=buttons) - except Exception: - await query.message.edit_text(text=caption, reply_markup=buttons) - -# ========================================== -# 4. QUALITY, LANGUAGE & SEASON FILTER MENUS -# ========================================== -@Client.on_callback_query(filters.regex(r"^(btn_quality|filter_quality|QUALITY)"), group=-1) -async def fix_quality_buttons(client: Client, query: CallbackQuery): - await query.answer("Select Quality") - q_markup = InlineKeyboardMarkup([ - [InlineKeyboardButton("360P", callback_data="filter_run#360p"), InlineKeyboardButton("480P", callback_data="filter_run#480p")], - [InlineKeyboardButton("720P", callback_data="filter_run#720p"), InlineKeyboardButton("1080P", callback_data="filter_run#1080p")], - [InlineKeyboardButton("1440P", callback_data="filter_run#1440p"), InlineKeyboardButton("2160P", callback_data="filter_run#2160p")], - [InlineKeyboardButton("4K", callback_data="filter_run#4k")], - [InlineKeyboardButton("« Bᴀᴄᴋ Tᴏ Fɪʟᴇs »", callback_data="back_to_results")] - ]) - try: - await query.message.edit_reply_markup(reply_markup=q_markup) - except Exception: - pass - -@Client.on_callback_query(filters.regex(r"^(btn_language|filter_language|LANGUAGE)"), group=-1) -async def fix_language_buttons(client: Client, query: CallbackQuery): - await query.answer("Select Language") - l_markup = InlineKeyboardMarkup([ - [InlineKeyboardButton("Mᴀʟᴀʏᴀʟᴀᴍ", callback_data="filter_run#malayalam"), InlineKeyboardButton("Tᴀᴍɪʟ", callback_data="filter_run#tamil")], - [InlineKeyboardButton("Eɴɢʟɪsʜ", callback_data="filter_run#english"), InlineKeyboardButton("Hɪɴᴅɪ", callback_data="filter_run#hindi")], - [InlineKeyboardButton("Tᴇʟᴜɢᴜ", callback_data="filter_run#telugu"), InlineKeyboardButton("Kᴀɴɴᴀᴅᴀ", callback_data="filter_run#kannada")], - [InlineKeyboardButton("Gᴜᴊᴀʀᴀᴛɪ", callback_data="filter_run#gujarati"), InlineKeyboardButton("Mᴀʀᴀᴛʜɪ", callback_data="filter_run#marathi")], - [InlineKeyboardButton("Pᴜɴᴊᴀʙɪ", callback_data="filter_run#punjabi"), InlineKeyboardButton("Dᴜᴀʟ Aᴜᴅɪᴏ", callback_data="filter_run#dual")], - [InlineKeyboardButton("« Bᴀᴄᴋ Tᴏ Fɪʟᴇs »", callback_data="back_to_results")] - ]) - try: - await query.message.edit_reply_markup(reply_markup=l_markup) - except Exception: - pass - -@Client.on_callback_query(filters.regex(r"^(btn_season|filter_season|SEASON)"), group=-1) -async def fix_season_buttons(client: Client, query: CallbackQuery): - await query.answer("Select Season") - s_markup = InlineKeyboardMarkup([ - [InlineKeyboardButton("Sᴇᴀsᴏɴ 1", callback_data="filter_run#s01"), InlineKeyboardButton("Sᴇᴀsᴏɴ 2", callback_data="filter_run#s02")], - [InlineKeyboardButton("Sᴇᴀsᴏɴ 3", callback_data="filter_run#s03"), InlineKeyboardButton("Sᴇᴀsᴏɴ 4", callback_data="filter_run#s04")], - [InlineKeyboardButton("Sᴇᴀsᴏɴ 5", callback_data="filter_run#s05"), InlineKeyboardButton("Sᴇᴀsᴏɴ 6", callback_data="filter_run#s06")], - [InlineKeyboardButton("« Bᴀᴄᴋ Tᴏ Fɪʟᴇs »", callback_data="back_to_results")] - ]) - try: - await query.message.edit_reply_markup(reply_markup=s_markup) - except Exception: - pass - -# ========================================== -# 5. BACK TO FILES & FILTER EXECUTION -# ========================================== -@Client.on_callback_query(filters.regex(r"^back_to_results"), group=-1) -async def back_to_files_handler(client: Client, query: CallbackQuery): - await query.answer("Loading original files list...") - original_markup = InlineKeyboardMarkup([ - [InlineKeyboardButton("REMOVE ADS", callback_data="remove_ads"), InlineKeyboardButton("⚡ SEND ALL", callback_data="send_all")], - [ - InlineKeyboardButton("QUALITY", callback_data="btn_quality"), - InlineKeyboardButton("LANGUAGE", callback_data="btn_language"), - InlineKeyboardButton("SEASON", callback_data="btn_season") - ], - [ - InlineKeyboardButton("PAGE", callback_data="ignore"), - InlineKeyboardButton("1/1", callback_data="ignore"), - InlineKeyboardButton("NEXT ➢", callback_data="ignore") - ], - [InlineKeyboardButton("« NO MORE PAGES AVAILABLE »", callback_data="ignore")] - ]) - try: - await query.message.edit_reply_markup(reply_markup=original_markup) - except Exception: - pass - -@Client.on_callback_query(filters.regex(r"^filter_run#"), group=-1) -async def filter_run_handler(client: Client, query: CallbackQuery): - tag = query.data.split("#")[1] - await query.answer(f"Filtering files by: {tag.upper()} 🍿", show_alert=False) From 1f86fe2680b9777b406ca70b53bf14e334e918f4 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Sun, 13 Sep 2026 14:37:16 +0530 Subject: [PATCH 05/77] Update Commands.py --- plugins/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/commands.py b/plugins/commands.py index 8f17c3eb..f33d66b1 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -455,7 +455,7 @@ async def start(client, message): reply_markup=InlineKeyboardMarkup(btn) ) - k = await msg.reply(script.DEL_MSG.format(get_time(DELETE_TIME)), quote=True, parse_mode=enums.ParseMode.HTML) + k = await msg.reply(script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) await asyncio.sleep(DELETE_TIME) await msg.delete() await k.edit_text("ʏᴏᴜʀ ᴠɪᴅᴇᴏ / ꜰɪʟᴇ ɪꜱ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ !!") From cf29e6cfc111f72bcda4e2893128f8266b9e9116 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Sun, 13 Sep 2026 14:48:59 +0530 Subject: [PATCH 06/77] Update Command.py --- plugins/commands.py | 104 +++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 55 deletions(-) diff --git a/plugins/commands.py b/plugins/commands.py index f33d66b1..b0d7c0ca 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -41,7 +41,7 @@ async def start(client, message): try: asyncio.create_task(message.react(emoji=random.choice(REACTIONS), big=True)) except Exception: - asyncio.create_task(message.react(emoji="⚡️")) + asyncio.create_task(message.react(emoji="⚡")) pass m = message if len(m.command) == 2 and m.command[1].startswith(('notcopy', 'sendall')): @@ -90,7 +90,7 @@ async def start(client, message): return if message.chat.type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: buttons = [[ - InlineKeyboardButton('❤️ ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ ❤️', url=f'http://t.me/{temp.U_NAME}?startgroup=true') + InlineKeyboardButton('❤ ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ ❤', url=f'http://t.me/{temp.U_NAME}?startgroup=true') ],[ InlineKeyboardButton('🍁 Update Channel 🍁', url=UPDATE_CHNL_LNK) ]] @@ -181,7 +181,7 @@ async def start(client, message): try: user_id = int(message.command[1].split("_")[1]) except ValueError: - await message.reply_text("‼️ ɪɴᴠᴀʟɪᴅ ʀᴇꜰᴇʀ!") + await message.reply_text("‼ ɪɴᴠᴀʟɪᴅ ʀᴇꜰᴇʀ!") return if user_id == message.from_user.id: await message.reply_text(script.REFER_SELF_ALRT) @@ -205,8 +205,8 @@ async def start(client, message): seconds = 2592000 if seconds > 0: expiry_time = datetime.now() + timedelta(seconds=seconds) - user_data = {"id": user_id, "expiry_time": expiry_time} # Using "id" instead of "user_id" - await db.update_user(user_data) # Use the update_user method to update or insert user data + user_data = {"id": user_id, "expiry_time": expiry_time} + await db.update_user(user_data) await client.send_message( chat_id=user_id, text=f"Hᴇʏ {uss.mention}\n\nYᴏᴜ ɢᴏᴛ 1 ᴍᴏɴᴛʜ ᴘʀᴇᴍɪᴜᴍ sᴜʙsᴄʀɪᴘᴛɪᴏɴ ʙʏ ɪɴᴠɪᴛɪɴɢ 10 ᴜsᴇʀs ❗", @@ -278,7 +278,7 @@ async def start(client, message): if len(message.command) > 1 and "_" in message.command[1]: kk, file_id = message.command[1].split("_", 1) btn.append([ - InlineKeyboardButton("♻️ ᴛʀʏ ᴀɢᴀɪɴ ♻️", callback_data=f"checksub#{kk}#{file_id}") + InlineKeyboardButton("♻ ᴛʀʏ ᴀɢᴀɪɴ ♻", callback_data=f"checksub#{kk}#{file_id}") ]) reply_markup = InlineKeyboardMarkup(btn) photo = random.choice(FSUB_PICS) if FSUB_PICS else "https://graph.org/file/7478ff3eac37f4329c3d8.jpg" @@ -292,8 +292,8 @@ async def start(client, message): return except Exception as e: - await log_error(client, f"❗️ Force Sub Error:\n\n{repr(e)}") - logger.error(f"❗️ Force Sub Error:\n\n{repr(e)}") + await log_error(client, f"❗ Force Sub Error:\n\n{repr(e)}") + logger.error(f"❗ Force Sub Error:\n\n{repr(e)}") user_id = m.from_user.id if not await db.has_premium_access(user_id): @@ -316,9 +316,9 @@ async def start(client, message): else: howtodownload = settings.get('tutorial_2', TUTORIAL_2) if is_second_shortener else settings.get('tutorial', TUTORIAL) buttons = [[ - InlineKeyboardButton(text="♻️ ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ᴠᴇʀɪꜰʏ ♻️", url=verify) + InlineKeyboardButton(text="♻ ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ᴠᴇʀɪꜰʏ ♻", url=verify) ],[ - InlineKeyboardButton(text="⁉️ ʜᴏᴡ ᴛᴏ ᴠᴇʀɪꜰʏ ⁉️", url=howtodownload) + InlineKeyboardButton(text="⁉ ʜᴏᴡ ᴛᴏ ᴠᴇʀɪꜰʏ ⁉", url=howtodownload) ]] reply_markup=InlineKeyboardMarkup(buttons) if await db.user_verified(user_id): @@ -419,7 +419,8 @@ async def start(client, message): except Exception: return await msg.edit_caption(f_caption, reply_markup=InlineKeyboardMarkup(btn)) - k = await msg.reply(script.DEL_MSG.format(get_time(DELETE_TIME)), quote=True, parse_mode=enums.ParseMode.HTML) + # FIXED: removed quote=True + k = await msg.reply(script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) await asyncio.sleep(DELETE_TIME) await msg.delete() await k.edit_text("ʏᴏᴜʀ ᴠɪᴅᴇᴏ / ꜰɪʟᴇ ɪꜱ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ !!") @@ -469,21 +470,21 @@ async def start(client, message): async def stream_buttons(user_id: int, file_id: str): if STREAM_MODE and not PREMIUM_STREAM_MODE: return [ - [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥️', callback_data=f'generate_stream_link:{file_id}')], - [InlineKeyboardButton('ℹ️ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ️', callback_data=f'extract_data:{file_id}')], + [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], + [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] ] elif STREAM_MODE and PREMIUM_STREAM_MODE: if not await db.has_premium_access(user_id): return [ - [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥️', callback_data='prestream')], - [InlineKeyboardButton('ℹ️ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ️', callback_data='prestream')], + [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data='prestream')], + [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data='prestream')], [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] ] else: return [ - [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥️', callback_data=f'generate_stream_link:{file_id}')], - [InlineKeyboardButton('ℹ️ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ️', callback_data=f'extract_data:{file_id}')], + [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], + [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] ] else: @@ -491,7 +492,6 @@ async def stream_buttons(user_id: int, file_id: str): @Client.on_message(filters.command('logs') & filters.user(ADMINS)) async def log_file(bot, message): - """Send log file""" try: await message.reply_document('DreamXlogs.txt', caption="📑 **ʟᴏɢꜱ**") except Exception as e: @@ -499,12 +499,11 @@ async def log_file(bot, message): @Client.on_message(filters.command('save') & filters.user(ADMINS)) async def save_file_handler(bot, message): - """Save file to database""" reply = message.reply_to_message if reply and reply.media: - msg = await message.reply("Pʀᴏᴄᴇssɪɴɢ...⏳", quote=True) + msg = await message.reply("Pʀᴏᴄᴇssɪɴɢ...⏳") else: - await message.reply('Rᴇᴘʟʏ ᴛᴏ ғɪʟᴇ ᴡɪᴛʜ /save ᴡʜɪᴄʜ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ sᴀᴠᴇ', quote=True) + await message.reply('Rᴇᴘʟʏ ᴛᴏ ғɪʟᴇ ᴡɪᴛʜ /save ᴡʜɪᴄʜ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ sᴀᴠᴇ') return try: @@ -523,7 +522,7 @@ async def save_file_handler(bot, message): if success: await msg.edit('Fɪʟᴇ ɪs sᴜᴄᴄᴇssғᴜʟʟʏ sᴀᴠᴇᴅ ᴛᴏ ᴅᴀᴛᴀʙᴀsᴇ ✅') elif status == 0: - await msg.edit('Fɪʟᴇ ᴀʟʀᴇᴀᴅʏ ᴇxɪsᴛs ɪɴ ᴅᴀᴛᴀʙᴀsᴇ ⚠️') + await msg.edit('Fɪʟᴇ ᴀʟʀᴇᴀᴅʏ ᴇxɪsᴛs ɪɴ ᴅᴀᴛᴀʙᴀsᴇ ⚠') elif status == 2: await msg.edit('Eʀʀᴏʀ: Fɪʟᴇ ᴠᴀʟɪᴅᴀᴛɪᴏɴ ғᴀɪʟᴇᴅ ❌') else: @@ -535,12 +534,11 @@ async def save_file_handler(bot, message): @Client.on_message(filters.command('delete') & filters.user(ADMINS)) async def delete(bot, message): - """Delete file from database""" reply = message.reply_to_message if reply and reply.media: - msg = await message.reply("Pʀᴏᴄᴇssɪɴɢ...⏳", quote=True) + msg = await message.reply("Pʀᴏᴄᴇssɪɴɢ...⏳") else: - await message.reply('Rᴇᴘʟʏ ᴛᴏ ғɪʟᴇ ᴡɪᴛʜ /delete ᴡʜɪᴄʜ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴅᴇʟᴇᴛᴇ', quote=True) + await message.reply('Rᴇᴘʟʏ ᴛᴏ ғɪʟᴇ ᴡɪᴛʜ /delete ᴡʜɪᴄʜ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴅᴇʟᴇᴛᴇ') return for file_type in ("document", "video", "audio"): @@ -607,7 +605,7 @@ async def delete_all_index(bot, message): [ [ InlineKeyboardButton( - text="⚠️ ʏᴇꜱ ⚠️", callback_data="autofilter_delete", style=enums.ButtonStyle.DANGER + text="⚠ ʏᴇꜱ ⚠", callback_data="autofilter_delete", style=enums.ButtonStyle.DANGER ) ], [ @@ -617,7 +615,6 @@ async def delete_all_index(bot, message): ], ] ), - quote=True, ) @Client.on_message(filters.command('settings')) @@ -637,7 +634,7 @@ async def settings(client, message): InlineKeyboardButton("👥 ᴏᴘᴇɴ ʜᴇʀᴇ 👥", callback_data=f"opnsetgrp#{grp_id}") ]] await message.reply_text( - text="ᴡʜᴇʀᴇ ᴅᴏ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴏᴘᴇɴ ꜱᴇᴛᴛɪɴɢꜱ ᴍᴇɴᴜ ? ⚙️", + text="ᴡʜᴇʀᴇ ᴅᴏ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴏᴘᴇɴ ꜱᴇᴛᴛɪɴɢꜱ ᴍᴇɴᴜ ? ⚙", reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML, @@ -655,7 +652,7 @@ async def settings(client, message): except Exception: pass await message.reply_text( - "⚠️ ꜱᴇʟᴇᴄᴛ ᴛʜᴇ ɢʀᴏᴜᴘ ᴡʜᴏꜱᴇ ꜱᴇᴛᴛɪɴɢꜱ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʜᴀɴɢᴇ.\n\n" + "⚠ ꜱᴇʟᴇᴄᴛ ᴛʜᴇ ɢʀᴏᴜᴘ ᴡʜᴏꜱᴇ ꜱᴇᴛᴛɪɴɢꜱ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʜᴀɴɢᴇ.\n\n" "ɪꜰ ʏᴏᴜʀ ɢʀᴏᴜᴘ ɪꜱ ɴᴏᴛ ꜱʜᴏᴡɪɴɢ ʜᴇʀᴇ,\n" "ᴜꜱᴇ /reload ɪɴ ᴛʜᴀᴛ ɢʀᴏᴜᴘ ᴀɴᴅ ɪᴛ ᴡɪʟʟ ᴀᴘᴘᴇᴀʀ ʜᴇʀᴇ.", reply_markup=InlineKeyboardMarkup(group_list) @@ -690,7 +687,7 @@ async def save_template(client, message): return await message.reply("ʏᴏᴜ'ʀᴇ ᴀɴᴏɴʏᴍᴏᴜꜱ ᴀᴅᴍɪɴ.") if message.chat.type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: - return await sts.edit("⚠️ ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ɪɴ ᴀ ɢʀᴏᴜᴘ ᴄʜᴀᴛ.") + return await sts.edit("⚠ ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ɪɴ ᴀ ɢʀᴏᴜᴘ ᴄʜᴀᴛ.") group_id = message.chat.id title = message.chat.title @@ -698,7 +695,7 @@ async def save_template(client, message): await message.reply_text(script.NT_ADMIN_ALRT_TXT) return if len(message.command) < 2: - return await sts.edit("⚠️ ɴᴏ ᴛᴇᴍᴘʟᴀᴛᴇ ᴘʀᴏᴠɪᴅᴇᴅ!") + return await sts.edit("⚠ ɴᴏ ᴛᴇᴍᴘʟᴀᴛᴇ ᴘʀᴏᴠɪᴅᴇᴅ!") template = message.text.split(" ", 1)[1] await save_group_settings(group_id, 'template', template) @@ -707,13 +704,12 @@ async def save_template(client, message): ) -# Must add REQST_CHANNEL and SUPPORT_CHAT_ID to use this feature @Client.on_message((filters.command("request") | filters.regex(r"(?i)#request")) & filters.group) async def requests(bot, message): if message.chat.id != SUPPORT_CHAT_ID: return if not message.from_user: - return await message.reply_text("⚠️ ᴜɴᴀʙʟᴇ ᴛᴏ ɪᴅᴇɴᴛɪꜰʏ ʏᴏᴜ.") + return await message.reply_text("⚠ ᴜɴᴀʙʟᴇ ᴛᴏ ɪᴅᴇɴᴛɪꜰʏ ʏᴏᴜ.") reporter = str(message.from_user.id) mention = message.from_user.mention @@ -738,7 +734,7 @@ async def requests(bot, message): InlineKeyboardButton('ꜱʜᴏᴡ ᴏᴘᴛɪᴏɴꜱ', callback_data=f'show_option#{reporter}') ]] req_text = f"📝 ʀᴇǫᴜᴇꜱᴛ : {content}\n\n📚 ʀᴇᴘᴏʀᴛᴇᴅ ʙʏ : {mention}\n📖 ʀᴇᴘᴏʀᴛᴇʀ ɪᴅ : {reporter}\n\n" - warning_text = "⚠️ ʀᴇǫᴜᴇꜱᴛ ᴄʜᴀɴɴᴇʟ ɪꜱ ɴᴏᴛ ꜱᴇᴛ." + warning_text = "⚠ ʀᴇǫᴜᴇꜱᴛ ᴄʜᴀɴɴᴇʟ ɪꜱ ɴᴏᴛ ꜱᴇᴛ." if REQST_CHANNEL is not None: try: reported_post = await bot.send_message(chat_id=REQST_CHANNEL, text=req_text, reply_markup=InlineKeyboardMarkup(btn)) @@ -752,7 +748,7 @@ async def requests(bot, message): reported_post = await bot.send_message(chat_id=admin, text=req_text, reply_markup=InlineKeyboardMarkup(btn)) except Exception: logger.exception("Request failed") - return await message.reply_text( "⚠️ ꜱᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ. ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ.") + return await message.reply_text( "⚠ ꜱᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ. ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ.") if reported_post and REQST_CHANNEL is not None: try: @@ -775,7 +771,7 @@ async def requests(bot, message): await message.reply_text("ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ʜᴀꜱ ʙᴇᴇɴ ᴀᴅᴅᴇᴅ! ᴘʟᴇᴀꜱᴇ ᴡᴀɪᴛ ꜰᴏʀ ꜱᴏᴍᴇ ᴛɪᴍᴇ.") except Exception: logger.exception("Failed to send request confirmation") - await message.reply_text("⚠️ ꜱᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ. ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ.") + await message.reply_text("⚠ ꜱᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ. ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ.") @Client.on_message(filters.command("send") & filters.user(ADMINS)) async def send_msg(bot, message): @@ -823,7 +819,7 @@ async def deletemultiplefiles(bot, message): return await k.delete() btn = [[ - InlineKeyboardButton("⚠️ Yes, Continue ! ⚠️", callback_data=f"killfilesdq#{keyword}") + InlineKeyboardButton("⚠ Yes, Continue ! ⚠", callback_data=f"killfilesdq#{keyword}") ],[ InlineKeyboardButton("❌ No, Abort operation ! ❌", callback_data="close_data", style=enums.ButtonStyle.DANGER) ]] @@ -931,7 +927,7 @@ def is_alphanumeric(string): return formatted_list = "\n".join([f"{i+1}. {msg}" for i, msg in enumerate(truncated_messages)]) additional_message = ( - "⚡️ 𝑨𝒍𝒍 𝒕𝒉𝒆 𝒓𝒆𝒔𝒖𝒍𝒕𝒔 𝒂𝒃𝒐𝒗𝒆 𝒄𝒐𝒎𝒆 𝒇𝒓𝒐𝒎 𝒘𝒉𝒂𝒕 𝒖𝒔𝒆𝒓𝒔 𝒉𝒂𝒗𝒆 𝒔𝒆𝒂𝒓𝒄𝒉𝒆𝒅 𝒇𝒐𝒓. " + "⚡ 𝑨𝒍𝒍 𝒕𝒉𝒆 𝒓𝒆𝒔𝒖𝒍𝒕𝒔 𝒂𝒃𝒐𝒗𝒆 𝒄𝒐𝒎𝒆 𝒇𝒓𝒐𝒎 𝒘𝒉𝒂𝒕 𝒖𝒔𝒆𝒓𝒔 𝒉𝒂𝒗𝒆 𝒔𝒆𝒂𝒓𝒄𝒉𝒆𝒅 𝒇𝒐𝒓. " "𝑻𝒉𝒆𝒚'𝒓𝒆 𝒔𝒉𝒐𝒘𝒏 𝒕𝒐 𝒚𝒐𝒖 𝒆𝒙𝒂𝒄𝒕𝒍𝒚 𝒂𝒔 𝒕𝒉𝒆𝒚 𝒘𝒆𝒓𝒆 𝒔𝒆𝒂𝒓𝒄𝒉𝒆𝒅, " "𝒘𝒊𝒕𝒉𝒐𝒖𝒕 𝒂𝒏𝒚 𝒄𝒉𝒂𝒏𝒈𝒆𝒔 𝒃𝒚 𝒕𝒉𝒆 𝒐𝒘𝒏𝒆𝒓." ) @@ -993,7 +989,7 @@ async def del_msg(client, message): InlineKeyboardButton("No", callback_data="confirm_del_no") ]]) sent_message = await message.reply_text( - "⚠️ Aʀᴇ ʏᴏᴜ sᴜʀᴇ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʟᴇᴀʀ ᴛʜᴇ ᴜᴘᴅᴀᴛᴇs ᴄʜᴀɴɴᴇʟ ʟɪsᴛ ?\n\n ᴅᴏ ʏᴏᴜ ꜱᴛɪʟʟ ᴡᴀɴᴛ ᴛᴏ ᴄᴏɴᴛɪɴᴜᴇ ?", + "⚠ Aʀᴇ ʏᴏᴜ sᴜʀᴇ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʟᴇᴀʀ ᴛʜᴇ ᴜᴘᴅᴀᴛᴇs ᴄʜᴀɴɴᴇʟ ʟɪsᴛ ?\n\n ᴅᴏ ʏᴏᴜ ꜱᴛɪʟʟ ᴡᴀɴᴛ ᴛᴏ ᴄᴏɴᴛɪɴᴜᴇ ?", reply_markup=confirm_markup ) await asyncio.sleep(60) @@ -1080,7 +1076,7 @@ async def handle_shortner_command(c, m, shortner_key, api_key, log_prefix, fallb return await m.reply( f"ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ʟɪᴋᴇ -\n\n`/{m.command[0]} your-shortener-domain.com your_api_key_here`" ) - sts = await m.reply("♻️ ᴄʜᴇᴄᴋɪɴɢ...") + sts = await m.reply("♻ ᴄʜᴇᴄᴋɪɴɢ...") await asyncio.sleep(1.2) await sts.delete() if m.chat.type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: @@ -1136,7 +1132,7 @@ async def set_log(client, message): if len(message.text.split()) == 1: await message.reply("ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ʟɪᴋᴇ ᴛʜɪꜱ - \n\n`/set_log_channel -100******`") return - sts = await message.reply("♻️ ᴄʜᴇᴄᴋɪɴɢ...") + sts = await message.reply("♻ ᴄʜᴇᴄᴋɪɴɢ...") await asyncio.sleep(1.2) await sts.delete() chat_type = message.chat.type @@ -1155,7 +1151,7 @@ async def set_log(client, message): except Exception as e: return await message.reply_text(f'😐 ᴍᴀᴋᴇ sᴜʀᴇ ᴛʜɪs ʙᴏᴛ ᴀᴅᴍɪɴ ɪɴ ᴛʜᴀᴛ ᴄʜᴀɴɴᴇʟ...\n\n💔 ᴇʀʀᴏʀ - {e}') await save_group_settings(grp_id, 'log', log) - await message.reply_text(f"✅ sᴜᴄᴄᴇssꜰᴜʟʟʏ sᴇᴛ ʏᴏᴜʀ ʟᴏɢ ᴄʜᴀɴɴᴇʟ ꜰᴏʀ {title}\n\nɪᴅ - `{log}`", disable_web_page_preview=True) + await message.reply_text(f"✅ sᴜᴄᴄᴇssғᴜʟʟʏ sᴇᴛ ʏᴏᴜʀ ʟᴏɢ ᴄʜᴀɴɴᴇʟ ꜰᴏʀ {title}\n\nɪᴅ - `{log}`", disable_web_page_preview=True) user_id = message.from_user.id user_info = f"@{message.from_user.username}" if message.from_user.username else f"{message.from_user.mention}" link = (await client.get_chat(message.chat.id)).invite_link @@ -1179,7 +1175,7 @@ async def set_time(client, message): except Exception: return await message.reply_text("ᴄᴏᴍᴍᴀɴᴅ ɪɴᴄᴏᴍᴘʟᴇᴛᴇ\n\nᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ʟɪᴋᴇ ᴛʜɪꜱ - /set_time 600 [ ᴛɪᴍᴇ ᴍᴜꜱᴛ ʙᴇ ɪɴ ꜱᴇᴄᴏɴᴅꜱ ]") await save_group_settings(grp_id, 'verify_time', time) - await message.reply_text(f"✅️ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ꜱᴇᴛ 2ɴᴅ ᴠᴇʀɪꜰʏ ᴛɪᴍᴇ ꜰᴏʀ {title}\n\nᴛɪᴍᴇ - {time}") + await message.reply_text(f"✅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ꜱᴇᴛ 2ɴᴅ ᴠᴇʀɪꜰʏ ᴛɪᴍᴇ ꜰᴏʀ {title}\n\nᴛɪᴍᴇ - {time}") await client.send_message(LOG_CHANNEL, f"#Set_2nd_Verify_Time\n\nɢʀᴏᴜᴘ ɴᴀᴍᴇ : {title}\n\nɢʀᴏᴜᴘ ɪᴅ : {grp_id}\n\nɪɴᴠɪᴛᴇ ʟɪɴᴋ : {invite_link}\n\nᴜᴘᴅᴀᴛᴇᴅ ʙʏ : {message.from_user.username}") @Client.on_message(filters.command('set_time_2')) async def set_time_2(client, message): @@ -1196,7 +1192,7 @@ async def set_time_2(client, message): except Exception: return await message.reply_text("ᴄᴏᴍᴍᴀɴᴅ ɪɴᴄᴏᴍᴘʟᴇᴛᴇ\n\nᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ʟɪᴋᴇ ᴛʜɪꜱ - /set_time 3600 [ ᴛɪᴍᴇ ᴍᴜꜱᴛ ʙᴇ ɪɴ ꜱᴇᴄᴏɴᴅꜱ ]") await save_group_settings(grp_id, 'third_verify_time', time) - await message.reply_text(f"✅️ ꜱᴜᴄᴄESꜱꜰᴜʟʟʏ ꜱᴇᴛ 3ʀᴅ ᴠᴇʀɪꜰʏ ᴛɪᴍᴇ ꜰᴏʀ {title}\n\nᴛɪᴍᴇ - {time}") + await message.reply_text(f"✅ ꜱᴜᴄᴄESꜱꜰᴜʟʟʏ ꜱᴇᴛ 3ʀᴅ ᴠᴇʀɪꜰʏ ᴛɪᴍᴇ ꜰᴏʀ {title}\n\nᴛɪᴍᴇ - {time}") await client.send_message(LOG_CHANNEL, f"#Set_3rd_Verify_Time\n\nɢʀᴏᴜᴘ ɴᴀᴍᴇ : {title}\n\nɢʀᴏᴜᴘ ɪᴅ : {grp_id}\n\nɪɴᴠɪᴛᴇ ʟɪɴᴋ : {invite_link}\n\nᴜᴘᴅᴀᴛᴇᴅ ʙʏ : {message.from_user.username}") @@ -1211,10 +1207,10 @@ async def all_settings(client, message): try: settings = await get_settings(grp_id) except Exception as e: - return await message.reply_text(f"⚠️ ᴇʀʀᴏʀ ꜰᴇᴛᴄʜɪɴɢ ꜱᴇᴛᴛɪɴɢꜱ:\n{e}") + return await message.reply_text(f"⚠ ᴇʀʀᴏʀ ꜰᴇᴛᴄʜɪɴɢ ꜱᴇᴛᴛɪɴɢꜱ:\n{e}") text = generate_settings_text(settings, title) btn = [ - [InlineKeyboardButton("♻️ ʀᴇꜱᴇᴛ ꜱᴇᴛᴛɪɴɢꜱ", callback_data=f"reset_group_{grp_id}")], + [InlineKeyboardButton("♻ ʀᴇꜱᴇᴛ ꜱᴇᴛᴛɪɴɢꜱ", callback_data=f"reset_group_{grp_id}")], [InlineKeyboardButton("🚫 ᴄʟᴏꜱᴇ", callback_data="close_data", style=enums.ButtonStyle.DANGER)] ] dlt = await message.reply_text(text, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True) @@ -1227,7 +1223,7 @@ async def reset_group_callback(client, callback_query): user_id = callback_query.from_user.id if not await is_check_admin(client, grp_id, user_id): return await callback_query.answer(script.NT_ADMIN_ALRT_TXT, show_alert=True) - await callback_query.answer("♻️ ʀᴇꜱᴇᴛᴛɪɴɢ ꜱᴇᴛᴛɪɴɢꜱ...") + await callback_query.answer("♻ ʀᴇꜱᴇᴛᴛɪɴɢ ꜱᴇᴛᴛɪɴɢꜱ...") defaults = { 'shortner': SHORTENER_WEBSITE, 'api': SHORTENER_API, @@ -1258,7 +1254,7 @@ async def reset_group_callback(client, callback_query): title = callback_query.message.chat.title text = generate_settings_text(updated, title, reset_done=True) buttons = [ - [InlineKeyboardButton("♻️ ʀᴇꜱᴇᴛ ꜱᴇᴛᴛɪɴɢꜱ", callback_data=f"reset_group_{grp_id}")], + [InlineKeyboardButton("♻ ʀᴇꜱᴇᴛ ꜱᴇᴛᴛɪɴɢꜱ", callback_data=f"reset_group_{grp_id}")], [InlineKeyboardButton("🚫 ᴄʟᴏꜱᴇ", callback_data="close_data", style=enums.ButtonStyle.DANGER)] ] await callback_query.message.edit_text(text, reply_markup=InlineKeyboardMarkup(buttons), disable_web_page_preview=True) @@ -1332,7 +1328,7 @@ async def set_fsub(client, message): f"ꜰꜱᴜʙ ᴄʜᴀɴɴᴇʟ(ꜱ):\n" + '\n'.join(channel_titles) ) except Exception as e: - err_text = f"⚠️ Error in set_fSub :\n{e}" + err_text = f"⚠ Error in set_fSub :\n{e}" logger.error(err_text) await client.send_message(LOG_CHANNEL, err_text) @@ -1341,14 +1337,12 @@ async def reset_all_settings(client, message): try: reset_count = await db.dreamx_reset_settings() await message.reply_text( - f"ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ꜱᴇᴛᴛɪɴɢꜱ ꜰᴏʀ {reset_count} ɢʀᴏᴜᴘꜱ. ᴅᴇꜰᴀᴜʟᴛ ᴠᴀʟᴜᴇꜱ ᴡɪʟʟ ʙᴇ ᴜꜱᴇᴅ ✅", - quote=True + f"ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ꜱᴇᴛᴛɪɴɢꜱ ꜰᴏʀ {reset_count} ɢʀᴏᴜᴘꜱ. ᴅᴇꜰᴀᴜʟᴛ ᴠᴀʟᴜᴇꜱ ᴡɪʟʟ ʙᴇ ᴜꜱᴇᴅ ✅" ) except Exception as e: logger.error("reset_all_settings: %s", e) await message.reply_text( - "🚫 An error occurred while resetting group settings.\nPlease try again later.", - quote=True + "🚫 An error occurred while resetting group settings.\nPlease try again later." ) @Client.on_message(filters.command("trial_reset")) @@ -1430,11 +1424,11 @@ async def remove_fsub(client, message): ) except Exception as e: logger.error("remove_fsub: %s", e) - await message.reply_text(f"⚠️ ᴀɴ ᴇʀʀᴏʀ ᴏᴄᴄᴜʀʀᴇᴅ: {e}") + await message.reply_text(f"⚠ ᴀɴ ᴇʀʀᴏʀ ᴏᴄᴄᴜʀʀᴇᴅ: {e}") @Client.on_message(filters.command('clean_groups') & filters.user(ADMINS)) async def clean_groups_handler(client, message): - msg = await message.reply('Cleaning groups... This may take a while.', quote=True) + msg = await message.reply('Cleaning groups... This may take a while.') deleted_count = 0 total_groups = await db.total_chat_count() processed = 0 From 869ddedf2bffd42094764808dae5a1b271a353be Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Sun, 13 Sep 2026 15:07:23 +0530 Subject: [PATCH 07/77] Refactor InlineKeyboardButton to remove style parameter Removed 'style' parameter from InlineKeyboardButton instances in various places. --- plugins/commands.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/commands.py b/plugins/commands.py index b0d7c0ca..f966680d 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -224,9 +224,9 @@ async def start(client, message): buttons = [[ InlineKeyboardButton('📲 ꜱᴇɴᴅ ᴘᴀʏᴍᴇɴᴛ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ', url=OWNER_LNK) ],[ - InlineKeyboardButton('UPI ID Copy Karein ??', copy_text=OWNER_UPI_ID, style=enums.ButtonStyle.PRIMARY) + InlineKeyboardButton('UPI ID Copy Karein ??', copy_text=OWNER_UPI_ID) ],[ - InlineKeyboardButton('❌ ᴄʟᴏꜱᴇ ❌', callback_data='close_data', style=enums.ButtonStyle.DANGER) + InlineKeyboardButton('❌ ᴄʟᴏꜱᴇ ❌', callback_data='close_data') ]] reply_markup = InlineKeyboardMarkup(buttons) await message.reply_photo( @@ -419,7 +419,7 @@ async def start(client, message): except Exception: return await msg.edit_caption(f_caption, reply_markup=InlineKeyboardMarkup(btn)) - # FIXED: removed quote=True + # FIXED: removed k = await msg.reply(script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) await asyncio.sleep(DELETE_TIME) await msg.delete() @@ -605,7 +605,7 @@ async def delete_all_index(bot, message): [ [ InlineKeyboardButton( - text="⚠ ʏᴇꜱ ⚠", callback_data="autofilter_delete", style=enums.ButtonStyle.DANGER + text="⚠ ʏᴇꜱ ⚠", callback_data="autofilter_delete" ) ], [ @@ -821,7 +821,7 @@ async def deletemultiplefiles(bot, message): btn = [[ InlineKeyboardButton("⚠ Yes, Continue ! ⚠", callback_data=f"killfilesdq#{keyword}") ],[ - InlineKeyboardButton("❌ No, Abort operation ! ❌", callback_data="close_data", style=enums.ButtonStyle.DANGER) + InlineKeyboardButton("❌ No, Abort operation ! ❌", callback_data="close_data") ]] await message.reply_text( text=f"Found {total} files for your query {keyword} !\n\nDo you want to delete?", @@ -1211,7 +1211,7 @@ async def all_settings(client, message): text = generate_settings_text(settings, title) btn = [ [InlineKeyboardButton("♻ ʀᴇꜱᴇᴛ ꜱᴇᴛᴛɪɴɢꜱ", callback_data=f"reset_group_{grp_id}")], - [InlineKeyboardButton("🚫 ᴄʟᴏꜱᴇ", callback_data="close_data", style=enums.ButtonStyle.DANGER)] + [InlineKeyboardButton("🚫 ᴄʟᴏꜱᴇ", callback_data="close_data")] ] dlt = await message.reply_text(text, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True) await asyncio.sleep(300) @@ -1255,7 +1255,7 @@ async def reset_group_callback(client, callback_query): text = generate_settings_text(updated, title, reset_done=True) buttons = [ [InlineKeyboardButton("♻ ʀᴇꜱᴇᴛ ꜱᴇᴛᴛɪɴɢꜱ", callback_data=f"reset_group_{grp_id}")], - [InlineKeyboardButton("🚫 ᴄʟᴏꜱᴇ", callback_data="close_data", style=enums.ButtonStyle.DANGER)] + [InlineKeyboardButton("🚫 ᴄʟᴏꜱᴇ", callback_data="close_data")] ] await callback_query.message.edit_text(text, reply_markup=InlineKeyboardMarkup(buttons), disable_web_page_preview=True) From b48eb232b644645a63f682bc15c1b4c084f730e5 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Sun, 13 Sep 2026 15:08:00 +0530 Subject: [PATCH 08/77] Update print statement to say 'Goodbye World' --- plugins/pmfilter.py | 2141 +++++++++---------------------------------- 1 file changed, 412 insertions(+), 1729 deletions(-) diff --git a/plugins/pmfilter.py b/plugins/pmfilter.py index 2441a985..c5533564 100644 --- a/plugins/pmfilter.py +++ b/plugins/pmfilter.py @@ -1,1802 +1,485 @@ -import logging -from utils import get_random_mix_id, get_size, is_subscribed, is_req_subscribed, group_setting_buttons, get_poster, get_posterx, temp, get_settings, save_group_settings, get_cap, imdb, is_check_admin, extract_request_content, log_error, clean_filename, generate_season_variations, clean_search_text, get_settings_text -from rapidfuzz import process -from dreamxbotz.util.file_properties import get_name, get_hash -from urllib.parse import quote_plus - -from database.ia_filterdb import Media, Media2, get_search_results, get_bad_files -from database.config_db import mdb -from pyrogram.errors import MessageIdInvalid, UserIsBlocked, MessageNotModified, PeerIdInvalid, MessageDeleteForbidden -from pyrogram import Client, filters, enums -from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery, InputMediaPhoto -from info import ( - ADMINS, AUTH_CHANNELS, AUTH_REQ_CHANNELS, BIN_CHANNEL, DELETE_TIME, - EMOJI_MODE, GRP_LNK, LANDSCAPE_POSTER, LANGUAGES, LOG_CHANNEL, MAX_B_TN, MSG_ALRT, - MULTIPLE_DB, NO_RESULTS_MSG, OWNER_LNK, OWNER_UPI_ID, PICS, PICS_URL, QR_CODE, QUALITIES, - REACTIONS, REQST_CHANNEL, SEASONS, STAR_PREMIUM_PLANS, SUBSCRIPTION, SUPPORT_CHAT_ID, - TMDB_ON_SEARCH, TMDB_POSTER, ULTRA_FAST_MODE, UPDATE_CHNL_LNK, URL -) -from Script import script -from pyrogram.errors.exceptions.bad_request_400 import MediaEmpty, PhotoInvalidDimensions, WebpageMediaEmpty -from database.refer import referdb -from database.users_chats_db import db import asyncio import re +import ast import math +import logging import random -import pytz -from datetime import datetime, timedelta -lock = asyncio.Lock() +from pyrogram import Client, filters, enums +from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery +from pyrogram.errors import MessageNotModified, FloodWait +from Script import script +from database.ia_filterdb import get_search_results, get_file_details, get_bad_files +from database.users_chats_db import db +from info import ADMINS, PICS, PICS_URL, AUTH_CHANNELS, DELETE_TIME, MAX_B_TN, IS_VERIFY, TUTORIAL, TUTORIAL_2, TUTORIAL_3, LOG_CHANNEL, SUPPORT_CHAT_ID +from utils import get_settings, get_size, is_subscribed, is_req_subscribed, get_shortlink, temp, get_readable_time logger = logging.getLogger(__name__) - - - -TIMEZONE = "Asia/Kolkata" -BUTTON = {} BUTTONS = {} -FRESH = {} -BUTTONS0 = {} -BUTTONS1 = {} -BUTTONS2 = {} -SPELL_CHECK = {} +CAP = {} +# QUALITY AND LANGUAGE MAPS (same font as your bot) +LANGUAGES = ["malayalam", "mal", "tamil", "tam" ,"english", "eng", "hindi", "hin" ,"telugu", "tel" ,"kannada", "kan", "bengali", "ben", "marathi", "mar", "gujarati", "guj", "punjabi", "pun"] +QUALITIES = ["360p", "480p", "720p", "1080p", "1440p", "2160p"] +SEASONS = ["season 1" , "season 2" , "season 3" , "season 4", "season 5" , "season 6" , "season 7" , "season 8" , "season 9" , "season 10"] -@Client.on_message(filters.group & filters.text & filters.incoming & ~filters.regex(r"^/") ) +@Client.on_message(filters.text & filters.group & filters.incoming & ~filters.command(["start", "help", "about", "id", "settings", "fsub", "post", "delete", "del"])) async def give_filter(client, message): - if EMOJI_MODE: - try: - await message.react(emoji=random.choice(REACTIONS), big=True) - except Exception: - await message.react(emoji="⚡️") - pass - await mdb.update_top_messages(message.from_user.id, message.text) - if message.chat.id != SUPPORT_CHAT_ID: - settings = await get_settings(message.chat.id) - try: - if settings['auto_ffilter']: - if re.search(r'https?://\S+|www\.\S+|t\.me/\S+', message.text): - if await is_check_admin(client, message.chat.id, message.from_user.id): - return - return await message.delete() - await auto_filter(client, message) - except KeyError: - await save_group_settings(message.chat.id, 'auto_ffilter', True) - settings = await get_settings(message.chat.id) - if settings['auto_ffilter']: - await auto_filter(client, message) - except Exception as e: - logger.exception("Error in auto filter: %s", e) - pass - else: - search = message.text - _, _, total_results = await get_search_results(chat_id=message.chat.id, query=search.lower(), offset=0, filter=True) - if total_results == 0: - return - await message.reply_text( - script.ALREADY_AVAILABLE_TXT.format(message.from_user.mention, total_results, search), - reply_markup=InlineKeyboardMarkup( - [[InlineKeyboardButton("🔍 ᴊᴏɪɴ ᴀɴᴅ ꜱᴇᴀʀᴄʜ ʜᴇʀᴇ 🔎", url=GRP_LNK)]]) - ) + await auto_filter(client, message) - -@Client.on_message(filters.private & filters.text & filters.incoming & ~filters.regex(r"^/") & ~filters.regex(r"(https?://)?(t\.me|telegram\.me|telegram\.dog)/")) -async def pm_text(bot, message): - bot_id = bot.me.id - content = message.text - user = message.from_user.first_name - user_id = message.from_user.id - if EMOJI_MODE: - try: - await message.react(emoji=random.choice(REACTIONS), big=True) - except Exception: - await message.react(emoji="⚡️") - pass - if content.startswith(("#")): +async def auto_filter(client, message): + if message.text.startswith("/"): return - try: - await mdb.update_top_messages(user_id, content) - pm_search = await db.pm_search_status(bot_id) - if pm_search: - await auto_filter(bot, message) + if re.findall(r"((^\/|^,|^!|^\.|^[\U0001F600-\U000E007F]).*)", message.text): + return + if 2 < len(message.text) < 100: + search = message.text + files, offset, total_results = await get_search_results(search.lower(), offset=0, filter=True) + if not files: + if temp.B_LINK: + return + # try with spell check - simplified + return else: - await message.reply_text( - text=script.PM_SEARCH_DISABLED_TXT.format(user), - reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("📝 ʀᴇǫᴜᴇsᴛ ʜᴇʀᴇ ", url=GRP_LNK)]]) - ) - await bot.send_message( - chat_id=LOG_CHANNEL, - text=script.PM_LOG_TXT.format(user, user_id, content) - ) - except Exception: - pass + settings = await get_settings(message.chat.id) + # req = requester id - THIS IS THE FIX for quality/language/session + req = message.from_user.id if message.from_user else 0 + temp.GETALL[search] = files + # store req for later use + if not hasattr(temp, 'REQ_CACHE'): + temp.REQ_CACHE = {} + temp.REQ_CACHE[search] = req + + # create buttons + btn = [] + # group setting buttons - qualities, languages, seasons + btn.append([ + InlineKeyboardButton("ǫᴜᴀʟɪᴛɪᴇs", callback_data=f"qualities#{search}#{req}"), + InlineKeyboardButton("ʟᴀɴɢᴜᴀɢᴇs", callback_data=f"languages#{search}#{req}"), + InlineKeyboardButton("sᴇᴀsᴏɴs", callback_data=f"seasons#{search}#{req}") + ]) + btn.append([ + InlineKeyboardButton("sᴇɴᴅ ᴀʟʟ ғɪʟᴇs", callback_data=f"sendall#{search}#{req}") + ]) + for file in files: + f_name = file.file_name + f_size = get_size(file.file_size) + file_id = file.file_id + btn.append([ + InlineKeyboardButton(f"[{f_size}] {f_name[:40]}", callback_data=f"file#{file_id}#{req}") + ]) + if offset != "": + btn.append([ + InlineKeyboardButton("ɴᴇxᴛ »", callback_data=f"next_{req}_{search}_{offset}") + ]) + else: + btn.append([ + InlineKeyboardButton("ɴᴏ ᴍᴏʀᴇ ᴘᴀɢᴇs", callback_data="pages") + ]) + + # fix: try pics url then pics + try: + pic_url = random.choice(PICS_URL) if PICS_URL else random.choice(PICS) + except: + try: + pic_url = random.choice(PICS) + except: + pic_url = None + + imdb = await get_poster(search, file=(files[0].file_name if files else None)) + if imdb and imdb.get('poster'): + cap = script.IMDB_TEMPLATE.format( + qurey=search, + title=imdb.get('title'), + votes=imdb.get('votes'), + aka=imdb.get("aka"), + seasons=imdb.get("seasons"), + box_office=imdb.get('box_office'), + localized_title=imdb.get('localized_title'), + kind=imdb.get('kind'), + imdb_id=imdb.get("imdb_id"), + cast=imdb.get("cast"), + runtime=imdb.get("runtime"), + countries=imdb.get("countries"), + certificates=imdb.get("certificates"), + languages=imdb.get("languages"), + director=imdb.get("director"), + writer=imdb.get("writer"), + producer=imdb.get("producer"), + composer=imdb.get("composer"), + cinematographer=imdb.get("cinematographer"), + music_team=imdb.get("music_team"), + distributors=imdb.get("distributors"), + release_date=imdb.get('release_date'), + year=imdb.get('year'), + genres=imdb.get('genres'), + poster=imdb.get('poster'), + plot=imdb.get('plot'), + rating=imdb.get('rating'), + url=imdb.get('url'), + ) + else: + cap = f"Here is what I found for your query {search} :" + + BUTTONS[search] = cap + CAP[search] = cap + + try: + if pic_url: + sent = await message.reply_photo(photo=pic_url, caption=cap, reply_markup=InlineKeyboardMarkup(btn), parse_mode=enums.ParseMode.HTML) + else: + sent = await message.reply_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), parse_mode=enums.ParseMode.HTML) + # auto delete + try: + if settings.get('auto_delete'): + await asyncio.sleep(DELETE_TIME) + await sent.delete() + await message.delete() + except Exception: + pass + except Exception as e: + logger.exception(e) -@Client.on_callback_query(filters.regex(r"^reffff")) -async def refercall(bot, query): - btn = [[ - InlineKeyboardButton( - 'invite link', url=f'https://telegram.me/share/url?url=https://t.me/{bot.me.username}?start=reff_{query.from_user.id}&text=Hello%21%20Experience%20a%20bot%20that%20offers%20a%20vast%20library%20of%20unlimited%20movies%20and%20series.%20%F0%9F%98%83'), - InlineKeyboardButton( - f'⏳ {referdb.get_refer_points(query.from_user.id)}', callback_data='ref_point'), - InlineKeyboardButton('Back', callback_data='premium_info') - ]] - reply_markup = InlineKeyboardMarkup(btn) +async def get_poster(query, bulk=False, id=False, file=None): + # import here to avoid circular + from utils import get_poster as _get_poster, get_posterx try: - await bot.edit_message_media( - query.message.chat.id, - query.message.id, - InputMediaPhoto("https://graph.org/file/1a2e64aee3d4d10edd930.jpg") - ) - except Exception: - pass - await query.message.edit_text( - text=script.REFER_TXT.format(bot.me.username, query.from_user.id), - reply_markup=reply_markup, - parse_mode=enums.ParseMode.HTML - ) - await query.answer() + return await _get_poster(query, bulk, id, file) + except: + try: + return await get_posterx(query, bulk, id, file) + except: + return None -@Client.on_callback_query(filters.regex(r"^next")) +@Client.on_callback_query(filters.regex(r"^next_")) async def next_page(bot, query): try: - await query.answer() - except Exception: - pass - ident, req, key, offset = query.data.split("_") - curr_time = datetime.now(pytz.timezone('Asia/Kolkata')).time() - if int(req) not in [query.from_user.id, 0]: - return await query.answer(script.ALRT_TXT.format(query.from_user.first_name), show_alert=True) - try: + _, req, key, offset = query.data.split("_") + req = int(req) + # check req + if req != 0 and query.from_user.id != req: + return await query.answer("This is not for you!", show_alert=True) + search = key offset = int(offset) - except Exception: - offset = 0 - if BUTTONS.get(key) is not None: - search = BUTTONS.get(key) - else: - search = FRESH.get(key) - if not search: - await query.answer(script.OLD_ALRT_TXT.format(query.from_user.first_name), show_alert=True) - return - files, n_offset, total = await get_search_results(query.message.chat.id, search, offset=offset, filter=True) - try: - n_offset = int(n_offset) - except Exception: - n_offset = 0 - - if not files: - return - temp.GETALL[key] = files - temp.SHORT[query.from_user.id] = query.message.chat.id - settings = await get_settings(query.message.chat.id) - if settings.get('button'): - btn = [ - [ - InlineKeyboardButton(text=f"🔗 {get_size(file.file_size)} ≽ " + clean_filename( - file.file_name), callback_data=f'file#{file.file_id}'), - ] - for file in files - ] - btn.insert(0, - [ - InlineKeyboardButton( - 'Qᴜᴀʟɪᴛʏ', callback_data=f"qualities#{req}#{key}"), - InlineKeyboardButton( - "Lᴀɴɢᴜᴀɢᴇ", callback_data=f"languages#{req}#{key}"), - InlineKeyboardButton( - "Sᴇᴀsᴏɴ", callback_data=f"seasons#{req}#{key}") - ] - ) - btn.insert(0, - [ - InlineKeyboardButton( - "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), - InlineKeyboardButton( - "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) - - ] - ) - - else: + files, n_offset, total = await get_search_results(search.lower(), offset=offset, filter=True) + if not files: + return btn = [] - btn.insert(0, - [ - InlineKeyboardButton( - 'Qᴜᴀʟɪᴛʏ', callback_data=f"qualities#{req}#{key}"), - InlineKeyboardButton( - "Lᴀɴɢᴜᴀɢᴇ", callback_data=f"languages#{req}#{key}"), - InlineKeyboardButton( - "Sᴇᴀsᴏɴ", callback_data=f"seasons#{req}#{key}") - ] - ) - btn.insert(0, [ - InlineKeyboardButton( - "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), - InlineKeyboardButton("Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) + btn.append([ + InlineKeyboardButton("ǫᴜᴀʟɪᴛɪᴇs", callback_data=f"qualities#{search}#{req}"), + InlineKeyboardButton("ʟᴀɴɢᴜᴀɢᴇs", callback_data=f"languages#{search}#{req}"), + InlineKeyboardButton("sᴇᴀsᴏɴs", callback_data=f"seasons#{search}#{req}") ]) - if ULTRA_FAST_MODE: - if 0 < offset <= 10: - off_set = 0 - elif offset == 0: - off_set = None - else: - off_set = offset - 10 - if n_offset == 0: - btn.append( - [InlineKeyboardButton("⋞ ʙᴀᴄᴋ", callback_data=f"next_{req}_{key}_{off_set}"), InlineKeyboardButton(f"{math.ceil(int(offset)/10)+1}", callback_data="pages")] - ) - elif off_set is None: - btn.append([InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton(f"{math.ceil(int(offset)/10)+1}", callback_data="pages"), InlineKeyboardButton("ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}")]) + btn.append([ + InlineKeyboardButton("sᴇɴᴅ ᴀʟʟ ғɪʟᴇs", callback_data=f"sendall#{search}#{req}") + ]) + for file in files: + f_name = file.file_name + f_size = get_size(file.file_size) + file_id = file.file_id + btn.append([ + InlineKeyboardButton(f"[{f_size}] {f_name[:40]}", callback_data=f"file#{file_id}#{req}") + ]) + if n_offset != "": + btn.append([ + InlineKeyboardButton("« ʙᴀᴄᴋ", callback_data=f"next_{req}_{search}_{offset-10}" if offset-10 >=0 else f"next_{req}_{search}_0"), + InlineKeyboardButton(f"{math.ceil(offset/10)+1}/{math.ceil(total/10)}", callback_data="pages"), + InlineKeyboardButton("ɴᴇxᴛ »", callback_data=f"next_{req}_{search}_{n_offset}") + ]) else: - btn.append( - [ - InlineKeyboardButton("⋞ ʙᴀᴄᴋ", callback_data=f"next_{req}_{key}_{off_set}"), - InlineKeyboardButton(f"{math.ceil(int(offset)/10)+1}", callback_data="pages"), - InlineKeyboardButton("ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}") - ], - ) - else: - try: - if settings['max_btn']: - if 0 < offset <= 10: - off_set = 0 - elif offset == 0: - off_set = None - else: - off_set = offset - 10 - if n_offset == 0: - btn.append([InlineKeyboardButton("⋞ ʙᴀᴄᴋ", callback_data=f"next_{req}_{key}_{off_set}"), InlineKeyboardButton( - f"{math.ceil(int(offset)/10)+1} / {math.ceil(total/10)}", callback_data="pages")]) - elif off_set is None: - btn.append([InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( - f"{math.ceil(int(offset)/10)+1} / {math.ceil(total/10)}", callback_data="pages"), InlineKeyboardButton("ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}")]) - else: - btn.append( - [ - InlineKeyboardButton( - "⋞ ʙᴀᴄᴋ", callback_data=f"next_{req}_{key}_{off_set}"), - InlineKeyboardButton( - f"{math.ceil(int(offset)/10)+1} / {math.ceil(total/10)}", callback_data="pages"), - InlineKeyboardButton( - "ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}") - ], - ) - else: - if 0 < offset <= int(MAX_B_TN): - off_set = 0 - elif offset == 0: - off_set = None - else: - off_set = offset - int(MAX_B_TN) - if n_offset == 0: - btn.append([InlineKeyboardButton("⋞ ʙᴀᴄᴋ", callback_data=f"next_{req}_{key}_{off_set}"), InlineKeyboardButton( - f"{math.ceil(int(offset)/int(MAX_B_TN))+1} / {math.ceil(total/int(MAX_B_TN))}", callback_data="pages")]) - elif off_set is None: - btn.append([InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( - f"{math.ceil(int(offset)/int(MAX_B_TN))+1} / {math.ceil(total/int(MAX_B_TN))}", callback_data="pages"), InlineKeyboardButton("ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}")]) - else: - btn.append( - [ - InlineKeyboardButton( - "⋞ ʙᴀᴄᴋ", callback_data=f"next_{req}_{key}_{off_set}"), - InlineKeyboardButton( - f"{math.ceil(int(offset)/int(MAX_B_TN))+1} / {math.ceil(total/int(MAX_B_TN))}", callback_data="pages"), - InlineKeyboardButton( - "ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}") - ], - ) - except KeyError: - await save_group_settings(query.message.chat.id, 'max_btn', True) - if 0 < offset <= 10: - off_set = 0 - elif offset == 0: - off_set = None - else: - off_set = offset - 10 - if n_offset == 0: - btn.append( - [InlineKeyboardButton("⋞ ʙᴀᴄᴋ", callback_data=f"next_{req}_{key}_{off_set}"), InlineKeyboardButton( - f"{math.ceil(int(offset)/10)+1} / {math.ceil(total/10)}", callback_data="pages")] - ) - elif off_set is None: - btn.append([InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( - f"{math.ceil(int(offset)/10)+1} / {math.ceil(total/10)}", callback_data="pages"), InlineKeyboardButton("ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}")]) - else: - btn.append( - [ - InlineKeyboardButton( - "⋞ ʙᴀᴄᴋ", callback_data=f"next_{req}_{key}_{off_set}"), - InlineKeyboardButton( - f"{math.ceil(int(offset)/10)+1} / {math.ceil(total/10)}", callback_data="pages"), - InlineKeyboardButton( - "ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}") - ], - ) - if not settings["button"]: - cur_time = datetime.now(pytz.timezone('Asia/Kolkata')).time() - time_difference = timedelta(hours=cur_time.hour, minutes=cur_time.minute, seconds=(cur_time.second+(cur_time.microsecond/1000000))) - \ - timedelta(hours=curr_time.hour, minutes=curr_time.minute, seconds=( - curr_time.second+(curr_time.microsecond/1000000))) - remaining_seconds = "{:.2f}".format(time_difference.total_seconds()) - dreamx_title = clean_search_text(search) - cap = None - try: - if settings['imdb']: - cap = await get_cap(settings, remaining_seconds, files, query, total, dreamx_title, offset) - if query.message.caption: - try: - await query.message.edit_caption(caption=cap, reply_markup=InlineKeyboardMarkup(btn), parse_mode=enums.ParseMode.HTML) - except (MessageNotModified, MessageIdInvalid): - pass - except Exception as e: - logger.exception(e) - else: - try: - await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) - except (MessageNotModified, MessageIdInvalid): - pass - else: - cap = await get_cap(settings, remaining_seconds, files, query, total, dreamx_title, offset+1) - await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) - except (MessageNotModified, MessageIdInvalid): - pass - except Exception as e: - logger.exception("Failed to send result: %s", e) - else: + btn.append([ + InlineKeyboardButton("« ʙᴀᴄᴋ", callback_data=f"next_{req}_{search}_{offset-10}"), + InlineKeyboardButton(f"{math.ceil(offset/10)+1}/{math.ceil(total/10)}", callback_data="pages") + ]) try: await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) - except (MessageNotModified, MessageIdInvalid): + except MessageNotModified: pass - await query.answer() - - -@Client.on_callback_query(filters.regex(r"^spol")) -async def advantage_spoll_choker(bot, query): - _, id, user = query.data.split('#') - if int(user) != 0 and query.from_user.id != int(user): - return await query.answer(script.ALRT_TXT.format(query.from_user.first_name), show_alert=True) - movies = await get_posterx(id, id=True) if TMDB_ON_SEARCH else await get_poster(id, id=True) - movie = movies.get('title') - movie = re.sub(r"[:-]", " ", movie) - movie = re.sub(r"\s+", " ", movie).strip() - await query.answer(script.TOP_ALRT_MSG) - files, offset, total_results = await get_search_results(query.message.chat.id, movie, offset=0, filter=True) - if files: - k = (movie, files, offset, total_results) - await auto_filter(bot, query, k) - else: - reqstr1 = query.from_user.id if query.from_user else 0 - reqstr = await bot.get_users(reqstr1) - if NO_RESULTS_MSG: - try: - await bot.send_message(chat_id=BIN_CHANNEL, text=script.NORSLTS.format(reqstr.id, reqstr.mention, movie)) - except Exception as e: - logger.error("Error In Spol: %s — Make Sure Bot Admin BIN CHANNEL", e) - btn = InlineKeyboardMarkup( - [[InlineKeyboardButton("🔰Cʟɪᴄᴋ ʜᴇʀᴇ & ʀᴇǫᴜᴇsᴛ ᴛᴏ ᴀᴅᴍɪɴ🔰", url=OWNER_LNK)]]) - k = await query.message.edit(script.MVE_NT_FND, reply_markup=btn) - await asyncio.sleep(10) - await k.delete() + await query.answer() + except Exception as e: + logger.exception(e) -# Qualities @Client.on_callback_query(filters.regex(r"^qualities#")) -async def qualities_cb_handler(client: Client, query: CallbackQuery): - _, req, key = query.data.split("#") - try: - if int(req) not in [query.from_user.id, 0]: - return await query.answer( - f"⚠️ ʜᴇʟʟᴏ {query.from_user.first_name},\n" - f"ᴛʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ,\nʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀ'ꜱ...", - show_alert=True, - ) - except Exception: - pass - - search = FRESH.get(key) - search = search.replace(' ', '_') - - btn = [] - for i in range(0, len(QUALITIES), 2): - q1 = QUALITIES[i] - row = [InlineKeyboardButton( - text=q1, callback_data=f"fq#{q1.lower()}#{req}#{key}")] - if i + 1 < len(QUALITIES): - q2 = QUALITIES[i + 1] - row.append(InlineKeyboardButton( - text=q2, callback_data=f"fq#{q2.lower()}#{req}#{key}")) - btn.append(row) - - btn.insert(0, [ - InlineKeyboardButton(text="⇊ ꜱᴇʟᴇᴄᴛ ǫᴜᴀʟɪᴛʏ ⇊", callback_data="ident") - ]) - btn.append([ - InlineKeyboardButton(text="↭ ʙᴀᴄᴋ ᴛᴏ ꜰɪʟᴇs ↭", - callback_data=f"fq#homepage#{req}#{key}") - ]) - - await query.edit_message_reply_markup(InlineKeyboardMarkup(btn)) - - -@Client.on_callback_query(filters.regex(r"^fq#")) -async def filter_qualities_cb_handler(client: Client, query: CallbackQuery): - _, qual, req, key = query.data.split("#") - curr_time = datetime.now(pytz.timezone('Asia/Kolkata')).time() - search = FRESH.get(key) - search = search.replace("_", " ") - baal = qual in search - if baal: - search = search.replace(qual, "") - else: - search = search - chat_id = query.message.chat.id - message = query.message +async def qualities_cb(bot, query): try: - if int(req) not in [query.from_user.id, 0]: - return await query.answer(f"⚠️ ʜᴇʟʟᴏ {query.from_user.first_name},\nᴛʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ,\nʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀ'ꜱ...", show_alert=True,) - except Exception: - pass - if qual != "homepage": - search = f"{search} {qual}" - BUTTONS[key] = search - files, offset, total_results = await get_search_results(chat_id, search, offset=0, filter=True) - if not files: - await query.answer("🚫 ɴᴏ ꜰɪʟᴇꜱ ᴡᴇʀᴇ ꜰᴏᴜɴᴅ 🚫", show_alert=1) - return - temp.GETALL[key] = files - settings = await get_settings(message.chat.id) - if settings.get('button'): - btn = [ - [ - InlineKeyboardButton(text=f"🔗 {get_size(file.file_size)} ≽ " + clean_filename( - file.file_name), callback_data=f'file#{file.file_id}'), - ] - for file in files - ] - btn.insert(0, - [ - InlineKeyboardButton( - 'Qᴜᴀʟɪᴛʏ', callback_data=f"qualities#{req}#{key}"), - InlineKeyboardButton( - "Lᴀɴɢᴜᴀɢᴇ", callback_data=f"languages#{req}#{key}"), - InlineKeyboardButton( - "Sᴇᴀsᴏɴ", callback_data=f"seasons#{req}#{key}") - ] - ) - btn.insert(0, - [ - InlineKeyboardButton( - "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), - InlineKeyboardButton( - "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) - ]) - else: + _, key, req = query.data.split("#") + req = int(req) + if req != 0 and query.from_user.id != req: + return await query.answer("This is not for you!", show_alert=True) + # create quality buttons btn = [] - btn.insert(0, - [ - InlineKeyboardButton( - 'Qᴜᴀʟɪᴛʏ', callback_data=f"qualities#{req}#{key}"), - InlineKeyboardButton( - "Lᴀɴɢᴜᴀɢᴇ", callback_data=f"languages#{req}#{key}"), - InlineKeyboardButton( - "Sᴇᴀsᴏɴ", callback_data=f"seasons#{req}#{key}") - ] - ) - btn.insert(0, - [ - InlineKeyboardButton( - "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), - InlineKeyboardButton( - "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) - - ]) - if offset != "": - try: - if settings['max_btn']: - btn.append( - - [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( - text=f"1/{math.ceil(int(total_results)/10)}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}")] - ) - else: - btn.append( - - [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( - text=f"1/{math.ceil(int(total_results)/int(MAX_B_TN))}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}")] - ) - except KeyError: - await save_group_settings(query.message.chat.id, 'max_btn', True) - btn.append( - - [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( - text=f"1/{math.ceil(int(total_results)/10)}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}")] - ) - else: - btn.append( - - [InlineKeyboardButton( - text="↭ ɴᴏ ᴍᴏʀᴇ ᴘᴀɢᴇꜱ ᴀᴠᴀɪʟᴀʙʟᴇ ↭", callback_data="pages")] - ) - if not settings["button"]: - cur_time = datetime.now(pytz.timezone('Asia/Kolkata')).time() - time_difference = timedelta(hours=cur_time.hour, minutes=cur_time.minute, seconds=(cur_time.second+(cur_time.microsecond/1000000))) - \ - timedelta(hours=curr_time.hour, minutes=curr_time.minute, seconds=( - curr_time.second+(curr_time.microsecond/1000000))) - remaining_seconds = "{:.2f}".format(time_difference.total_seconds()) - dreamx_title = clean_search_text(search) - cap = await get_cap(settings, remaining_seconds, files, query, total_results, dreamx_title, offset=1) - try: - await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) - except (MessageNotModified, MessageIdInvalid): - pass - else: - try: - await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) - except (MessageNotModified, MessageIdInvalid): - pass - await query.answer() - -# languages - + for qual in QUALITIES: + btn.append([InlineKeyboardButton(qual, callback_data=f"q_filter#{qual}#{key}#{req}")]) + btn.append([InlineKeyboardButton("⇋ ʙᴀᴄᴋ ⇋", callback_data=f"filter_back#{key}#{req}")]) + await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) + await query.answer() + except Exception as e: + logger.exception(e) @Client.on_callback_query(filters.regex(r"^languages#")) -async def languages_cb_handler(client: Client, query: CallbackQuery): - _, req, key = query.data.split("#") +async def languages_cb(bot, query): try: - if int(req) not in [query.from_user.id, 0]: - return await query.answer( - f"⚠️ ʜᴇʟʟᴏ {query.from_user.first_name},\n" - f"ᴛʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ,\nʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀ'ꜱ...", - show_alert=True, - ) - except Exception: - pass - - search = FRESH.get(key) - search = search.replace(' ', '_') - - items = list(LANGUAGES.items()) - btn = [] - - for i in range(0, len(items), 2): - name1, code1 = items[i] - row = [InlineKeyboardButton( - text=name1, callback_data=f"fl#{code1}#{req}#{key}")] - if i + 1 < len(items): - name2, code2 = items[i + 1] - row.append(InlineKeyboardButton( - text=name2, callback_data=f"fl#{code2}#{req}#{key}")) - btn.append(row) - - btn.insert(0, [InlineKeyboardButton( - text="⇊ ꜱᴇʟᴇᴄᴛ ʟᴀɴɢᴜᴀɢᴇ ⇊", callback_data="ident")]) - btn.append([InlineKeyboardButton(text="↭ ʙᴀᴄᴋ ᴛᴏ ꜰɪʟᴇs ↭", - callback_data=f"fl#homepage#{req}#{key}")]) + _, key, req = query.data.split("#") + req = int(req) + if req != 0 and query.from_user.id != req: + return await query.answer("This is not for you!", show_alert=True) + btn = [] + for lang in LANGUAGES[:12]: + btn.append([InlineKeyboardButton(lang, callback_data=f"l_filter#{lang}#{key}#{req}")]) + btn.append([InlineKeyboardButton("⇋ ʙᴀᴄᴋ ⇋", callback_data=f"filter_back#{key}#{req}")]) + await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) + await query.answer() + except Exception as e: + logger.exception(e) - await query.edit_message_reply_markup(InlineKeyboardMarkup(btn)) +@Client.on_callback_query(filters.regex(r"^seasons#")) +async def seasons_cb(bot, query): + try: + _, key, req = query.data.split("#") + req = int(req) + if req != 0 and query.from_user.id != req: + return await query.answer("This is not for you!", show_alert=True) + btn = [] + for seas in SEASONS: + btn.append([InlineKeyboardButton(seas, callback_data=f"s_filter#{seas}#{key}#{req}")]) + btn.append([InlineKeyboardButton("⇋ ʙᴀᴄᴋ ⇋", callback_data=f"filter_back#{key}#{req}")]) + await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) + await query.answer() + except Exception as e: + logger.exception(e) +@Client.on_callback_query(filters.regex(r"^q_filter#")) +async def q_filter_cb(bot, query): + try: + _, qual, key, req = query.data.split("#") + req = int(req) + if req != 0 and query.from_user.id != req: + return await query.answer("This is not for you!", show_alert=True) + # filter by quality + files = temp.GETALL.get(key) + if not files: + return await query.answer("No files found!", show_alert=True) + filtered = [f for f in files if qual.lower() in f.file_name.lower()] + if not filtered: + return await query.answer(f"No files found for quality {qual}", show_alert=True) + btn = [] + btn.append([InlineKeyboardButton(f"Filtered by {qual}", callback_data="pages")]) + for file in filtered[:10]: + f_name = file.file_name + f_size = get_size(file.file_size) + file_id = file.file_id + btn.append([InlineKeyboardButton(f"[{f_size}] {f_name[:40]}", callback_data=f"file#{file_id}#{req}")]) + btn.append([InlineKeyboardButton("⇋ ʙᴀᴄᴋ ⇋", callback_data=f"filter_back#{key}#{req}")]) + await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) + await query.answer() + except Exception as e: + logger.exception(e) -@Client.on_callback_query(filters.regex(r"^fl#")) -async def filter_languages_cb_handler(client: Client, query: CallbackQuery): - _, lang, req, key = query.data.split("#") - curr_time = datetime.now(pytz.timezone('Asia/Kolkata')).time() - search = FRESH.get(key) - search = search.replace("_", " ") - baal = lang in search - if baal: - search = search.replace(lang, "") - else: - search = search - chat_id = query.message.chat.id - message = query.message +@Client.on_callback_query(filters.regex(r"^l_filter#")) +async def l_filter_cb(bot, query): try: - if int(req) not in [query.from_user.id, 0]: - return await query.answer(f"⚠️ ʜᴇʟʟᴏ {query.from_user.first_name},\nᴛʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ,\nʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀ'ꜱ...", show_alert=True,) - except Exception: - pass - if lang != "homepage": - search = f"{search} {lang}" - BUTTONS[key] = search - files, offset, total_results = await get_search_results(chat_id, search, offset=0, filter=True) - if not files: - await query.answer("🚫 ɴᴏ ꜰɪʟᴇꜱ ᴡᴇʀᴇ ꜰᴏᴜɴᴅ 🚫", show_alert=1) - return - temp.GETALL[key] = files - settings = await get_settings(message.chat.id) - if settings.get('button'): - btn = [ - [ - InlineKeyboardButton(text=f"🔗 {get_size(file.file_size)} ≽ " + clean_filename( - file.file_name), callback_data=f'file#{file.file_id}'), - ] - for file in files - ] - btn.insert(0, - [ - InlineKeyboardButton( - 'Qᴜᴀʟɪᴛʏ', callback_data=f"qualities#{req}#{key}"), - InlineKeyboardButton( - "Lᴀɴɢᴜᴀɢᴇ", callback_data=f"languages#{req}#{key}"), - InlineKeyboardButton( - "Sᴇᴀsᴏɴ", callback_data=f"seasons#{req}#{key}") - ] - ) - btn.insert(0, - [ - InlineKeyboardButton( - "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), - InlineKeyboardButton( - "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) - ] - ) - else: + _, lang, key, req = query.data.split("#") + req = int(req) + if req != 0 and query.from_user.id != req: + return await query.answer("This is not for you!", show_alert=True) + files = temp.GETALL.get(key) + if not files: + return await query.answer("No files found!", show_alert=True) + filtered = [f for f in files if lang.lower() in f.file_name.lower()] + if not filtered: + return await query.answer(f"No files found for language {lang}", show_alert=True) btn = [] - btn.insert(0, - [ - InlineKeyboardButton( - 'Qᴜᴀʟɪᴛʏ', callback_data=f"qualities#{req}#{key}"), - InlineKeyboardButton( - "Lᴀɴɢᴜᴀɢᴇ", callback_data=f"languages#{req}#{key}"), - InlineKeyboardButton( - "Sᴇᴀsᴏɴ", callback_data=f"seasons#{req}#{key}") - ]) - btn.insert(0, - [ - InlineKeyboardButton( - "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), - InlineKeyboardButton( - "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) - ]) - if offset != "": - try: - if settings['max_btn']: - btn.append( - [ - InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( - text=f"1/{math.ceil(int(total_results)/10)}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}") - ]) - else: - btn.append( - [ - InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( - text=f"1/{math.ceil(int(total_results)/int(MAX_B_TN))}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}") - ]) - except KeyError: - await save_group_settings(query.message.chat.id, 'max_btn', True) - btn.append( - [ - InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( - text=f"1/{math.ceil(int(total_results)/10)}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}") - ]) - else: - btn.append([InlineKeyboardButton( - text="↭ ɴᴏ ᴍᴏʀᴇ ᴘᴀɢᴇꜱ ᴀᴠᴀɪʟᴀʙʟᴇ ↭", callback_data="pages")]) - if not settings["button"]: - cur_time = datetime.now(pytz.timezone('Asia/Kolkata')).time() - time_difference = timedelta(hours=cur_time.hour, minutes=cur_time.minute, seconds=(cur_time.second+(cur_time.microsecond/1000000))) - \ - timedelta(hours=curr_time.hour, minutes=curr_time.minute, seconds=( - curr_time.second+(curr_time.microsecond/1000000))) - remaining_seconds = "{:.2f}".format(time_difference.total_seconds()) - dreamx_title = clean_search_text(search) - cap = await get_cap(settings, remaining_seconds, files, query, total_results, dreamx_title, offset=1) - try: - await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) - except (MessageNotModified, MessageIdInvalid): - pass - else: - try: - await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) - except (MessageNotModified, MessageIdInvalid): - pass - await query.answer() + btn.append([InlineKeyboardButton(f"Filtered by {lang}", callback_data="pages")]) + for file in filtered[:10]: + f_name = file.file_name + f_size = get_size(file.file_size) + file_id = file.file_id + btn.append([InlineKeyboardButton(f"[{f_size}] {f_name[:40]}", callback_data=f"file#{file_id}#{req}")]) + btn.append([InlineKeyboardButton("⇋ ʙᴀᴄᴋ ⇋", callback_data=f"filter_back#{key}#{req}")]) + await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) + await query.answer() + except Exception as e: + logger.exception(e) +@Client.on_callback_query(filters.regex(r"^s_filter#")) +async def s_filter_cb(bot, query): + try: + _, seas, key, req = query.data.split("#") + req = int(req) + if req != 0 and query.from_user.id != req: + return await query.answer("This is not for you!", show_alert=True) + files = temp.GETALL.get(key) + if not files: + return await query.answer("No files found!", show_alert=True) + filtered = [f for f in files if seas.lower() in f.file_name.lower()] + if not filtered: + # also check S01 etc + num = ''.join(filter(str.isdigit, seas)) + filtered = [f for f in files if f"S{int(num):02d}" in f.file_name or f"S{num}" in f.file_name] + if not filtered: + return await query.answer(f"No files found for {seas}", show_alert=True) + btn = [] + btn.append([InlineKeyboardButton(f"Filtered by {seas}", callback_data="pages")]) + for file in filtered[:10]: + f_name = file.file_name + f_size = get_size(file.file_size) + file_id = file.file_id + btn.append([InlineKeyboardButton(f"[{f_size}] {f_name[:40]}", callback_data=f"file#{file_id}#{req}")]) + btn.append([InlineKeyboardButton("⇋ ʙᴀᴄᴋ ⇋", callback_data=f"filter_back#{key}#{req}")]) + await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) + await query.answer() + except Exception as e: + logger.exception(e) -@Client.on_callback_query(filters.regex(r"^seasons#")) -async def seasons_cb_handler(client: Client, query: CallbackQuery): - _, req, key = query.data.split("#") +@Client.on_callback_query(filters.regex(r"^filter_back#")) +async def filter_back_cb(bot, query): try: - if int(req) not in [query.from_user.id, 0]: - return await query.answer( - f"⚠️ ʜᴇʟʟᴏ {query.from_user.first_name},\nᴛʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ,\nʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀ'ꜱ…", - show_alert=True, - ) - except Exception: - pass - offset = 0 - btn: list[list[InlineKeyboardButton]] = [] - for i in range(0, len(SEASONS) - 1, 2): + _, key, req = query.data.split("#") + req = int(req) + if req != 0 and query.from_user.id != req: + return await query.answer("This is not for you!", show_alert=True) + files = temp.GETALL.get(key, []) + btn = [] btn.append([ - InlineKeyboardButton( - f"Sᴇᴀꜱᴏɴ {SEASONS[i][1:]}", callback_data=f"fs#{SEASONS[i].lower()}#{req}#{key}"), - InlineKeyboardButton( - f"Sᴇᴀꜱᴏɴ {SEASONS[i+1][1:]}", callback_data=f"fs#{SEASONS[i+1].lower()}#{req}#{key}") + InlineKeyboardButton("ǫᴜᴀʟɪᴛɪᴇs", callback_data=f"qualities#{key}#{req}"), + InlineKeyboardButton("ʟᴀɴɢᴜᴀɢᴇs", callback_data=f"languages#{key}#{req}"), + InlineKeyboardButton("sᴇᴀsᴏɴs", callback_data=f"seasons#{key}#{req}") ]) + btn.append([InlineKeyboardButton("sᴇɴᴅ ᴀʟʟ ғɪʟᴇs", callback_data=f"sendall#{key}#{req}")]) + for file in files[:10]: + f_name = file.file_name + f_size = get_size(file.file_size) + file_id = file.file_id + btn.append([InlineKeyboardButton(f"[{f_size}] {f_name[:40]}", callback_data=f"file#{file_id}#{req}")]) + await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) + await query.answer() + except Exception as e: + logger.exception(e) - btn.insert( - 0, - [InlineKeyboardButton("⇊ ꜱᴇʟᴇᴄᴛ ꜱᴇᴀꜱᴏɴ ⇊", callback_data="ident")], - ) - btn.append([InlineKeyboardButton(text="↭ ʙᴀᴄᴋ ᴛᴏ ꜰɪʟᴇs ​↭", - callback_data=f"next_{req}_{key}_{offset}")]) - await query.edit_message_reply_markup(InlineKeyboardMarkup(btn)) - await query.answer() - - -@Client.on_callback_query(filters.regex(r"^fs#")) -async def filter_seasons_cb_handler(client: Client, query: CallbackQuery): - _, season_tag, req, key = query.data.split("#") - search = FRESH.get(key).replace("_", " ") - season_tag = season_tag.lower() - if season_tag == "homepage": - search_final = search - query_input = search_final - else: - season_number = int(season_tag[1:]) - query_input = generate_season_variations(search, season_number) - search_final = query_input[0] if query_input else search - - BUTTONS[key] = search_final - try: - if int(req) not in [query.from_user.id, 0]: - return await query.answer("⚠️ Not your request", show_alert=True) - except Exception: - pass - - chat_id = query.message.chat.id - files, n_offset, total_results = await get_search_results(chat_id, query_input, offset=0, filter=True) - if not files: - BUTTONS[key] = None - return await query.answer("🚫 ɴᴏ ꜰɪʟᴇꜱ ꜰᴏᴜɴᴅ 🚫", show_alert=True) - - temp.GETALL[key] = files - settings = await get_settings(chat_id) - btn: list[list[InlineKeyboardButton]] = [] - if settings.get("button"): - btn.extend( - [ - [ - InlineKeyboardButton( - f"🔗 {get_size(f.file_size)} ≽ " + - clean_filename(f.file_name), - callback_data=f"file#{f.file_id}", - ) - ] - for f in files - ] - ) - btn.insert( - 0, - [ - InlineKeyboardButton("Qᴜᴀʟɪᴛʏ", callback_data=f"qualities#{req}#{key}"), - InlineKeyboardButton("Lᴀɴɢᴜᴀɢᴇ", callback_data=f"languages#{req}#{key}"), - InlineKeyboardButton("Sᴇᴀꜱᴏɴ", callback_data=f"seasons#{req}#{key}"), - ], - ) - btn.insert( - 0, - [ - InlineKeyboardButton( - "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), - InlineKeyboardButton("Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS), - ], - ) - if n_offset != "": - try: - if settings['max_btn']: - btn.append( - [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( - text=f"1/{math.ceil(int(total_results)/10)}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}")] - ) - - else: - btn.append( - [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( - text=f"1/{math.ceil(int(total_results)/int(MAX_B_TN))}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}")] - ) - except KeyError: - await save_group_settings(query.message.chat.id, 'max_btn', True) - btn.append( - [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( - text=f"1/{math.ceil(int(total_results)/10)}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}")] - ) - else: - n_offset = 0 - btn.append( - [InlineKeyboardButton( - "↭ ɴᴏ ᴍᴏʀᴇ ᴘᴀɢᴇꜱ ᴀᴠᴀɪʟᴀʙʟᴇ ↭", callback_data="pages")] - ) - if not settings.get("button"): - curr_time = datetime.now(pytz.timezone("Asia/Kolkata")).time() - time_difference = timedelta( - hours=curr_time.hour, - minutes=curr_time.minute, - seconds=curr_time.second + curr_time.microsecond / 1_000_000, - ) - remaining_seconds = f"{time_difference.total_seconds():.2f}" - dreamx_title = clean_search_text(search_final) - cap = await get_cap(settings, remaining_seconds, files, query, total_results, dreamx_title, offset=1) - try: - await query.message.edit_text( - text=cap, - reply_markup=InlineKeyboardMarkup(btn), - disable_web_page_preview=True, - ) - except (MessageNotModified, MessageIdInvalid): - pass - else: - try: - await query.edit_message_reply_markup(InlineKeyboardMarkup(btn)) - except (MessageNotModified, MessageIdInvalid): - pass - await query.answer() - - -@Client.on_callback_query(group=10) -async def cb_handler(client: Client, query: CallbackQuery): - DreamxData = query.data +@Client.on_callback_query(filters.regex(r"^file#")) +async def file_cb(bot, query): try: - await client.create_chat_invite_link(int(REQST_CHANNEL)) - except Exception: - pass - if query.data == "close_data": - try: - user = query.message.reply_to_message.from_user.id - except Exception: - user = query.from_user.id - if int(user) != 0 and query.from_user.id != int(user): - return await query.answer(script.NT_ALRT_TXT, show_alert=True) - await query.answer("ᴛʜᴀɴᴋs ꜰᴏʀ ᴄʟᴏsᴇ 🙈") - await query.message.delete() - try: - await query.message.reply_to_message.delete() - except Exception: - pass - - elif query.data == "pages": - await query.answer("ᴛʜɪs ɪs ᴘᴀɢᴇs ʙᴜᴛᴛᴏɴ 😅") - - - - if query.data.startswith("file"): - ident, file_id = query.data.split("#") - user = query.message.reply_to_message.from_user.id if query.message.reply_to_message else query.from_user.id - if int(user) != 0 and query.from_user.id != int(user): - return await query.answer(script.ALRT_TXT.format(query.from_user.first_name), show_alert=True) - await query.answer(url=f"https://t.me/{temp.U_NAME}?start=file_{query.message.chat.id}_{file_id}") - - elif query.data.startswith("sendfiles"): - ident, key = query.data.split("#") + _, file_id, req = query.data.split("#") + req = int(req) + # allow anyone to get file, but req check optional + # if req !=0 and query.from_user.id != req: + # return await query.answer("This is not for you!", show_alert=True) + files_ = await get_file_details(file_id) + if not files_: + return await query.answer("No such file exist.", show_alert=True) + # channel check settings = await get_settings(query.message.chat.id) + # for private file send try: - await query.answer(url=f"https://telegram.me/{temp.U_NAME}?start=allfiles_{query.message.chat.id}_{key}") - return - except UserIsBlocked: - await query.answer('Uɴʙʟᴏᴄᴋ ᴛʜᴇ ʙᴏᴛ ᴍᴀʜɴ !', show_alert=True) - except PeerIdInvalid: - await query.answer(url=f"https://telegram.me/{temp.U_NAME}?start=sendfiles3_{key}") - except Exception as e: - logger.exception(e) - await query.answer(url=f"https://telegram.me/{temp.U_NAME}?start=sendfiles4_{key}") - - - - elif query.data.startswith("autofilter_delete"): - await Media.collection.drop() - if MULTIPLE_DB: - await Media2.collection.drop() - await query.answer("Eᴠᴇʀʏᴛʜɪɴɢ's Gᴏɴᴇ") - await query.message.edit('ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ᴀʟʟ ɪɴᴅᴇxᴇᴅ ꜰɪʟᴇꜱ ✅') - - elif query.data.startswith("checksub"): - try: - ident, kk, file_id = query.data.split("#") - btn = [] - chat = file_id.split("_")[0] - settings = await get_settings(chat) - fsub_channels = list(dict.fromkeys((settings.get('fsub', []) if settings else [])+ AUTH_CHANNELS)) - btn += await is_subscribed(client, query.from_user.id, fsub_channels) - btn += await is_req_subscribed(client, query.from_user.id, AUTH_REQ_CHANNELS) - if btn: - btn.append([InlineKeyboardButton("♻️ ᴛʀʏ ᴀɢᴀɪɴ ♻️", callback_data=f"checksub#{kk}#{file_id}")]) - try: - await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) - except (MessageNotModified, MessageIdInvalid): - pass - await query.answer( - f"👋 Hello {query.from_user.first_name},\n\n" - "🛑 Yᴏᴜ ʜᴀᴠᴇ ɴᴏᴛ ᴊᴏɪɴᴇᴅ ᴀʟʟ ʀᴇǫᴜɪʀᴇᴅ ᴜᴘᴅᴀᴛᴇ Cʜᴀɴɴᴇʟs.\n" - "👉 Pʟᴇᴀsᴇ ᴊᴏɪɴ ᴇᴀᴄʜ ᴏɴᴇ ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ.\n", - show_alert=True - ) - return - await query.answer(url=f"https://t.me/{temp.U_NAME}?start={kk}_{file_id}") - if query.message.chat.type == enums.ChatType.PRIVATE: - try: - await query.message.delete() - except MessageDeleteForbidden: - pass - except Exception as e: - await log_error(client, f"❌ Error in checksub callback:\n\n{repr(e)}") - logger.error(f"❌ Error in checksub callback:\n\n{repr(e)}") - - - elif query.data.startswith("killfilesdq"): - ident, keyword = query.data.split("#") - await query.message.edit_text(f"Fetching Files for your query {keyword} on DB... Please wait...") - files, total = await get_bad_files(keyword) - await query.message.edit_text("ꜰɪʟᴇ ᴅᴇʟᴇᴛɪᴏɴ ᴘʀᴏᴄᴇꜱꜱ ᴡɪʟʟ ꜱᴛᴀʀᴛ ɪɴ 5 ꜱᴇᴄᴏɴᴅꜱ !") - await asyncio.sleep(5) - deleted = 0 - async with lock: - try: - for file in files: - file_ids = file.file_id - file_name = file.file_name - result = await Media.collection.delete_one({ - '_id': file_ids, - }) - if not result.deleted_count and MULTIPLE_DB: - result = await Media2.collection.delete_one({ - '_id': file_ids, - }) - if result.deleted_count: - logger.info( - f'ꜰɪʟᴇ ꜰᴏᴜɴᴅ ꜰᴏʀ ʏᴏᴜʀ ǫᴜᴇʀʏ {keyword}! ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ {file_name} ꜰʀᴏᴍ ᴅᴀᴛᴀʙᴀꜱᴇ.') - deleted += 1 - if deleted % 20 == 0: - await query.message.edit_text(f"ᴘʀᴏᴄᴇꜱꜱ ꜱᴛᴀʀᴛᴇᴅ ꜰᴏʀ ᴅᴇʟᴇᴛɪɴɢ ꜰɪʟᴇꜱ ꜰʀᴏᴍ ᴅʙ. ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ {str(deleted)} ꜰɪʟᴇꜱ ꜰʀᴏᴍ ᴅʙ ꜰᴏʀ ʏᴏᴜʀ ǫᴜᴇʀʏ {keyword} !\n\nᴘʟᴇᴀꜱᴇ ᴡᴀɪᴛ...") - except Exception as e: - logger.error("Error In killfiledq: %s", e) - await query.message.edit_text(f'Error: {e}') - else: - await query.message.edit_text(f"ᴘʀᴏᴄᴇꜱꜱ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ꜰᴏʀ ꜰɪʟᴇ ᴅᴇʟᴇᴛᴀᴛɪᴏɴ !\n\nꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ {str(deleted)} ꜰɪʟᴇꜱ ꜰʀᴏᴍ ᴅʙ ꜰᴏʀ ʏᴏᴜʀ ǫᴜᴇʀʏ {keyword}.") - - elif query.data.startswith("opnsetgrp"): - ident, grp_id = query.data.split("#") - userid = query.from_user.id if query.from_user else None - st = await client.get_chat_member(int(grp_id), userid) - if ( - st.status != enums.ChatMemberStatus.ADMINISTRATOR - and st.status != enums.ChatMemberStatus.OWNER - and str(userid) not in ADMINS - ): - await query.answer("ʏᴏᴜ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ ʀɪɢʜᴛꜱ ᴛᴏ ᴅᴏ ᴛʜɪꜱ !", show_alert=True) - return - title = query.message.chat.title - settings = await get_settings(grp_id) - if settings is not None: - btn = await group_setting_buttons(int(grp_id)) - reply_markup = InlineKeyboardMarkup(btn) - await query.message.edit_text( - text=await get_settings_text(grp_id, title), - disable_web_page_preview=True, - parse_mode=enums.ParseMode.HTML - ) - await query.message.edit_reply_markup(reply_markup) - - elif query.data.startswith("opnsetpm"): - ident, grp_id = query.data.split("#") - userid = query.from_user.id if query.from_user else None - st = await client.get_chat_member(int(grp_id), userid) - if ( - st.status != enums.ChatMemberStatus.ADMINISTRATOR - and st.status != enums.ChatMemberStatus.OWNER - and str(userid) not in ADMINS - ): - await query.answer("Yᴏᴜ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ sᴜғғɪᴄɪᴀɴᴛ ʀɪɢʜᴛs ᴛᴏ ᴅᴏ ᴛʜɪs !", show_alert=True) - return - title = query.message.chat.title - settings = await get_settings(grp_id) - btn2 = [[ - InlineKeyboardButton( - "ᴄʜᴇᴄᴋ ᴍʏ ᴅᴍ 🗳️", url=f"telegram.me/{temp.U_NAME}") - ]] - reply_markup = InlineKeyboardMarkup(btn2) - await query.message.edit_text(f"ʏᴏᴜʀ sᴇᴛᴛɪɴɢs ᴍᴇɴᴜ ғᴏʀ {title} ʜᴀs ʙᴇᴇɴ sᴇɴᴛ ᴛᴏ ʏᴏᴜ ʙʏ ᴅᴍ.") - await query.message.edit_reply_markup(reply_markup) - if settings is not None: - btn = await group_setting_buttons(int(grp_id)) - reply_markup = InlineKeyboardMarkup(btn) - await client.send_message( - chat_id=userid, - text=await get_settings_text(grp_id, title), - reply_markup=reply_markup, - disable_web_page_preview=True, - parse_mode=enums.ParseMode.HTML, - reply_to_message_id=query.message.id - ) - - elif query.data.startswith("show_option"): - ident, from_user = query.data.split("#") - btn = [[ - InlineKeyboardButton("⚠️ ᴜɴᴀᴠᴀɪʟᴀʙʟᴇ ⚠️", callback_data=f"unavailable#{from_user}"), - InlineKeyboardButton("🟢 ᴜᴘʟᴏᴀᴅᴇᴅ 🟢", callback_data=f"uploaded#{from_user}") - ], [ - InlineKeyboardButton("♻️ ᴀʟʀᴇᴀᴅʏ ᴀᴠᴀɪʟᴀʙʟᴇ ♻️", callback_data=f"already_available#{from_user}") - ], [ - InlineKeyboardButton("📌 Not Released 📌", callback_data=f"Not_Released#{from_user}"), - InlineKeyboardButton("♨️Type Correct Spelling♨️", callback_data=f"Type_Correct_Spelling#{from_user}") - ], [ - InlineKeyboardButton("⚜️ Not Available In The Hindi ⚜️", callback_data=f"Not_Available_In_The_Hindi#{from_user}") - ]] - if query.from_user.id in ADMINS: - reply_markup = InlineKeyboardMarkup(btn) - await query.message.edit_reply_markup(reply_markup) - await query.answer("Hᴇʀᴇ ᴀʀᴇ ᴛʜᴇ ᴏᴘᴛɪᴏɴs !") - else: - await query.answer("Yᴏᴜ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ sᴜғғɪᴄɪᴀɴᴛ ʀɪɢʜᴛs ᴛᴏ ᴅᴏ ᴛʜɪs !", show_alert=True) - - elif query.data.split("#")[0] in ["unavailable", "Not_Released", "Type_Correct_Spelling", "Not_Available_In_The_Hindi", "uploaded", "already_available"]: - key = query.data.split("#")[0] - ident, from_user = query.data.split("#") - if query.from_user.id not in ADMINS: - return await query.answer("Yᴏᴜ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ sᴜғғɪᴄɪᴀɴᴛ ʀɪɢʜᴛs ᴛᴏ ᴅᴏ ᴛʜɪs !", show_alert=True) - - status_configs = { - "unavailable": { - "btn_text": "⚠️ ᴜɴᴀᴠᴀɪʟᴀʙʟᴇ ⚠️", "alert_key": "unalert", "answer": "Sᴇᴛ ᴛᴏ Uɴᴀᴠᴀɪʟᴀʙʟᴇ !", - "pm": "Hᴇʏ {mention},\n\n{content} Hᴀs Bᴇᴇɴ Mᴀʀᴋᴇᴅ Aᴅ ᴜɴᴀᴠᴀɪʟᴀʙʟᴇ...💔\n\n#Uɴᴀᴠᴀɪʟᴀʙʟᴇ ⚠️", - "sup": "Hᴇʏ {mention},\n\n{content} Hᴀs Bᴇᴇɴ Mᴀʀᴋᴇᴅ Aᴅ ᴜɴᴀᴠᴀɪʟᴀʙʟᴇ...💔\n\n#Uɴᴀᴠᴀɪʟᴀʙʟᴇ ⚠️\n\nBʟᴏᴄᴋᴇᴅ? Uɴʙʟᴏᴄᴋ ᴛʜᴇ ʙᴏᴛ ᴛᴏ ʀᴇᴄᴇɪᴠᴇ ᴍᴇꜱꜱᴀɢᴇꜱ.", - "search": False - }, - "Not_Released": { - "btn_text": "📌 Not Released 📌", "alert_key": "nralert", "answer": "Sᴇᴛ ᴛᴏ Nᴏᴛ Rᴇʟᴇᴀꜱᴇᴅ !", - "pm": "Hᴇʏ {mention}\n\n{content}, ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ʜᴀꜱ ɴᴏᴛ ʙᴇᴇɴ ʀᴇʟᴇᴀꜱᴇᴅ ʏᴇᴛ\n\n#CᴏᴍɪɴɢSᴏᴏɴ...🕊️✌️", - "sup": "Hᴇʏ {mention}\n\n{content}, ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ʜᴀꜱ ɴᴏᴛ ʙᴇᴇɴ ʀᴇʟᴇᴀꜱᴇᴅ ʏᴇᴛ\n\n#CᴏᴍɪɴɢSᴏᴏɴ...🕊️✌️\n\nBʟᴏᴄᴋᴇᴅ? Uɴʙʟᴏᴄᴋ ᴛʜᴇ ʙᴏᴛ ᴛᴏ ʀᴇᴄᴇɪᴠᴇ ᴍᴇꜱꜱᴀɢᴇꜱ.", - "search": False - }, - "Type_Correct_Spelling": { - "btn_text": "♨️ Type Correct Spelling ♨️", "alert_key": "wsalert", "answer": "Sᴇᴛ ᴛᴏ Cᴏʀʀᴇᴄᴛ Sᴘᴇʟʟɪɴɢ !", - "pm": "Hᴇʏ {mention}\n\nWᴇ Dᴇᴄʟɪɴᴇᴅ Yᴏᴜʀ Rᴇǫᴜᴇsᴛ {content}, Bᴇᴄᴀᴜsᴇ Yᴏᴜʀ Sᴘᴇʟʟɪɴɢ Wᴀs Wʀᴏɴɢ 😢\n\n#Wʀᴏɴɢ_Sᴘᴇʟʟɪɴɢ 😑", - "sup": "Hᴇʏ {mention}\n\n{content}, Bᴇᴄᴀᴜsᴇ Yᴏᴜʀ Sᴘᴇʟʟɪɴɢ Wᴀs Wʀᴏɴɢ 😢\n\n#Wʀᴏɴɢ_Sᴘᴇʟʟɪɴɢ 😑\n\nBʟᴏᴄᴋᴇᴅ? Uɴʙʟᴏᴄᴋ ᴛʜᴇ ʙᴏᴛ ᴛᴏ ʀᴇᴄᴇɪᴠᴇ ᴍᴇꜱꜱᴀɢᴇꜱ.", - "search": False - }, - "Not_Available_In_The_Hindi": { - "btn_text": "⚜️ Not Available In The Hindi ⚜️", "alert_key": "hnalert", "answer": "Sᴇᴛ ᴛᴏ Nᴏᴛ Aᴠᴀɪʟᴀʙʟᴇ Iɴ Hɪɴᴅɪ !", - "pm": "Hᴇʏ {mention}\n\nYᴏᴜʀ Rᴇǫᴜᴇsᴛ {content} ɪs Nᴏᴛ Aᴠᴀɪʟᴀʙʟᴇ ɪɴ Hɪɴᴅɪ ʀɪɢʜᴛ ɴᴏᴡ. Sᴏ ᴏᴜʀ ᴍᴏᴅᴇʀᴀᴛᴏʀs ᴄᴀɴ'ᴛ ᴜᴘʟᴏᴀᴅ ɪᴛ\n\n#Hɪɴᴅɪ_ɴᴏᴛ_ᴀᴠᴀɪʟᴀʙʟᴇ ❌", - "sup": "Hᴇʏ {mention}\n\n{content} ɪs Nᴏᴛ Aᴠᴀɪʟᴀʙʟᴇ ɪɴ Hɪɴᴅɪ ʀɪɢʜᴛ ɴᴏᴡ. Sᴏ ᴏᴜʀ ᴍᴏᴅᴇʀᴀᴛᴏʀs ᴄᴀɴ'ᴛ ᴜᴘʟᴏᴀᴅ ɪᴛ\n\n#Hɪɴᴅɪ_ɴᴏᴛ_ᴀᴠᴀɪʟᴀʙʟᴇ ❌\n\nBʟᴏᴄᴋᴇᴅ? Uɴʙʟᴏᴄᴋ ᴛʜᴇ ʙᴏᴛ ᴛᴏ ʀᴇᴄᴇɪᴠᴇ ᴍᴇꜱꜱᴀɢᴇꜱ.", - "search": False - }, - "uploaded": { - "btn_text": "🟢 ᴜᴘʟᴏᴀᴅᴇᴅ 🟢", "alert_key": "upalert", "answer": "Sᴇᴛ ᴛᴏ Uᴘʟᴏᴀᴅᴇᴅ !", - "pm": "Hᴇʏ {mention},\n\n{content} Yᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ʜᴀꜱ ʙᴇᴇɴ ᴜᴘʟᴏᴀᴅᴇᴅ ʙʏ ᴏᴜʀ ᴍᴏᴅᴇʀᴀᴛᴏʀs.\nKɪɴᴅʟʏ sᴇᴀʀᴄʜ ɪɴ ᴏᴜʀ Gʀᴏᴜᴘ.\n\n#Uᴘʟᴏᴀᴅᴇᴅ✅", - "sup": "{content}\n\nHᴇʏ {mention}, Yᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ʜᴀꜱ ʙᴇᴇɴ ᴜᴘʟᴏᴀᴅᴇᴅ ʙʏ ᴏᴜʀ ᴍᴏᴅᴇʀᴀᴛᴏʀs.Kɪɴᴅʟʏ sᴇᴀʀᴄʜ ɪɴ ᴏᴜʀ Gʀᴏᴜᴘ.\n\n#Uᴘʟᴏᴀᴅᴇᴅ✅\n\nBʟᴏᴄᴋᴇᴅ? Uɴʙʟᴏᴄᴋ ᴛʜᴇ ʙᴏᴛ ᴛᴏ ʀᴇᴄᴇɪᴠᴇ ᴍᴇꜱꜱᴀɢᴇꜱ.", - "search": True - }, - "already_available": { - "btn_text": "♻️ ᴀʟʀᴇᴀᴅʏ ᴀᴠᴀɪʟᴀʙʟᴇ ♻️", "alert_key": "alalert", "answer": "Sᴇᴛ ᴛᴏ Aʟʀᴇᴀᴅʏ Aᴠᴀɪʟᴀʙʟᴇ !", - "pm": "Hᴇʏ {mention},\n\n{content} Yᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ɪꜱ ᴀʟʀᴇᴀᴅʏ ᴀᴠᴀɪʟᴀʙʟᴇ ɪɴ ᴏᴜʀ ʙᴏᴛ'ꜱ ᴅᴀᴛᴀʙᴀꜱᴇ.\nKɪɴᴅʟʏ sᴇᴀʀᴄʜ ɪɴ ᴏᴜʀ Gʀᴏᴜᴘ.\n\n#Aᴠᴀɪʟᴀʙʟᴇ 💗", - "sup": "Hᴇʏ {mention},\n\n{content} Yᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ɪꜱ ᴀʟʀᴇᴀᴅʏ ᴀᴠᴀɪʟᴀʙʟᴇ ɪɴ ᴏᴜʀ ʙᴏᴛ'ꜱ ᴅᴀᴛᴀʙᴀꜱᴇ.\nKɪɴᴅʟʏ sᴇᴀʀᴄʜ ɪɴ ᴏᴜʀ Gʀᴏᴜᴘ.\n\n#Aᴠᴀɪʟᴀʙʟᴇ 💗\nBʟᴏᴄᴋᴇᴅ? Uɴʙʟᴏᴄᴋ ᴛʜᴇ ʙᴏᴛ ᴛᴏ ʀᴇᴄᴇɪᴠᴇ ᴍᴇꜱꜱᴀɢES.", - "search": True - } - } - cfg = status_configs[key] - user = await client.get_users(int(from_user)) - btn = [[InlineKeyboardButton(cfg["btn_text"], callback_data=f'{cfg["alert_key"]}#{from_user}')]] - btn2 = [[ - InlineKeyboardButton('ᴊᴏɪɴ ᴄʜᴀɴɴᴇʟ', url=UPDATE_CHNL_LNK), - InlineKeyboardButton("ᴠɪᴇᴡ ꜱᴛᴀᴛᴜꜱ", url=f"{query.message.link}") - ]] - if cfg["search"]: - btn2.append([InlineKeyboardButton("🔍 ꜱᴇᴀʀᴄʜ ʜᴇʀᴇ 🔎", url=GRP_LNK)]) - - content = query.message.text - await query.message.edit_text(f"{content}") - await query.message.edit_reply_markup(InlineKeyboardMarkup(btn)) - await query.answer(cfg["answer"]) - - req_content = extract_request_content(query.message.text) - try: - await client.send_message( - chat_id=int(from_user), - text=cfg["pm"].format(mention=user.mention, content=req_content), - reply_markup=InlineKeyboardMarkup(btn2) - ) - except UserIsBlocked: - await client.send_message( - chat_id=int(SUPPORT_CHAT_ID), - text=cfg["sup"].format(mention=user.mention, content=req_content), - reply_markup=InlineKeyboardMarkup(btn2) + await bot.send_cached_media( + chat_id=query.from_user.id, + file_id=file_id, + caption=files_.file_name ) - - elif query.data.split("#")[0] in ["alalert", "upalert", "unalert", "hnalert", "nralert", "wsalert"]: - ident, from_user = query.data.split("#") - alerts = { - "alalert": "Hᴇʏ {name}, Yᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ɪꜱ Aʟʀᴇᴀᴅʏ Aᴠᴀɪʟᴀʙʟᴇ ✅", - "upalert": "Hᴇʏ {name}, Yᴏᴜʀ ʀᴇǫᴜESꜱᴛ ɪꜱ Uᴘʟᴏᴀᴅᴇᴅ 🔼", - "unalert": "Hᴇʏ {name}, Yᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ɪꜱ Uɴᴀᴠᴀɪʟᴀʙʟᴇ ⚠️", - "hnalert": "Hᴇʏ {name}, Tʜɪꜱ ɪꜱ Nᴏᴛ Aᴠᴀɪʟᴀʙʟᴇ ɪɴ Hɪɴᴅɪ ❌", - "nralert": "Hᴇʏ {name}, Tʜᴇ Mᴏᴠɪᴇ/ꜱʜᴏᴡ ɪꜱ Nᴏᴛ Rᴇʟᴇᴀꜱᴇᴅ Yᴇᴛ 🆕", - "wsalert": "Hᴇʏ {name}, Yᴏᴜʀ Rᴇǫᴜᴇꜱᴛ ᴡᴀꜱ ʀᴇᴊᴇᴄᴛᴇᴅ ᴅᴜᴇ ᴛᴏ ᴡʀᴏɴɢ sᴘᴇʟʟɪɴɢ ❗" - } - if int(query.from_user.id) == int(from_user): - user = await client.get_users(from_user) - msg_text = alerts[ident].format(name=user.first_name) - await query.answer(msg_text, show_alert=True) - else: - await query.answer("Yᴏᴜ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ ᴘᴇʀᴍɪssɪᴏɴ ᴛᴏ sᴇᴇ ᴛʜɪꜱ ❌", show_alert=True) - - elif DreamxData.startswith("generate_stream_link"): - _, file_id = DreamxData.split(":") - try: - user_id = query.from_user.id - username = query.from_user.mention - log_msg = await client.send_cached_media(chat_id=BIN_CHANNEL, file_id=file_id,) - fileName = quote_plus(get_name(log_msg)) - dreamx_stream = f"{URL}watch/{str(log_msg.id)}/{quote_plus(get_name(log_msg))}?hash={get_hash(log_msg)}" - dreamx_download = f"{URL}{str(log_msg.id)}/{quote_plus(get_name(log_msg))}?hash={get_hash(log_msg)}" - await query.answer(MSG_ALRT) - await asyncio.sleep(1) - await log_msg.reply_text( - text=f"•• ʟɪɴᴋ ɢᴇɴᴇʀᴀᴛᴇᴅ ꜰᴏʀ ɪᴅ #{user_id} \n•• ᴜꜱᴇʀɴᴀᴍᴇ : {username} \n\n•• ᖴᎥᒪᗴ Nᗩᗰᗴ : {fileName}", - quote=True, - disable_web_page_preview=True, - reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ 🚀", url=dreamx_download), # we download Link - InlineKeyboardButton('🖥️ ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥️', url=dreamx_stream)]]) # web stream Link - ) - dreamcinezone = await query.edit_message_reply_markup( - reply_markup=InlineKeyboardMarkup([ - [ - InlineKeyboardButton("🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ 🚀", url=dreamx_download), - InlineKeyboardButton('🖥️ ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥️', url=dreamx_stream) - ], - [ - InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK) - ] - ]) - ) - await asyncio.sleep(DELETE_TIME) - await dreamcinezone.delete() - return + await query.answer("Check PM, I have sent files in PM", show_alert=False) except Exception as e: - logger.error("Callback error: %s", e) - await query.answer(f"⚠️ SOMETHING WENT WRONG STREAM LINK \n\n{e}", show_alert=True) - return - - - elif query.data == "prestream": - await query.answer(text=script.PRE_STREAM_ALERT, show_alert=True) - dreamcinezone = await client.send_photo( - chat_id=query.message.chat.id, - photo="https://i.ibb.co/whf8xF7j/photo-2025-07-26-10-42-46-7531339305176793100.jpg", - caption=script.PRE_STREAM, - reply_markup=InlineKeyboardMarkup([ - [InlineKeyboardButton("🚀 Buy Premium 🚀", callback_data="premium_info")] - ]) - ) - await asyncio.sleep(DELETE_TIME) - await dreamcinezone.delete() - - - - - elif query.data == "start": - buttons = [[ - InlineKeyboardButton('🔰 ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://telegram.me/{temp.U_NAME}?startgroup=true') - ],[ - InlineKeyboardButton(' ʜᴇʟᴘ 📢', callback_data='help'), - InlineKeyboardButton(' ᴀʙᴏᴜᴛ 📖', callback_data='about') - ],[ - InlineKeyboardButton('ᴛᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), - InlineKeyboardButton('ᴜᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), - ]] - reply_markup = InlineKeyboardMarkup(buttons) - current_time = datetime.now(pytz.timezone(TIMEZONE)) - curr_time = current_time.hour - if curr_time < 12: - gtxt = "ɢᴏᴏᴅ ᴍᴏʀɴɪɴɢ 🌞" - elif curr_time < 17: - gtxt = "ɢᴏᴏᴅ ᴀғᴛᴇʀɴᴏᴏɴ 🌓" - elif curr_time < 21: - gtxt = "ɢᴏᴏᴅ ᴇᴠᴇɴɪɴɢ 🌘" - else: - gtxt = "ɢᴏᴏᴅ ɴɪɢʜᴛ 🌑" - try: - if len(PICS) == 1: - PIC = PICS[0] - else: - try: - PIC = f"{random.choice(PICS_URL)}?r={get_random_mix_id()}" - except Exception: - PIC = random.choice(PICS) - await client.edit_message_media( - query.message.chat.id, - query.message.id, - InputMediaPhoto(PIC) - ) - except Exception: - pass - await query.message.edit_text( - text=script.START_TXT.format(query.from_user.mention, gtxt, temp.U_NAME, temp.B_NAME), - reply_markup=reply_markup, - parse_mode=enums.ParseMode.HTML - ) - await query.answer(MSG_ALRT) + await query.answer("Failed to send in PM, make sure you started me in PM", show_alert=True) + except Exception as e: + logger.exception(e) - elif query.data == "donation": - buttons = [[ - InlineKeyboardButton('🌲 Sᴇɴᴅ Dᴏɴᴀᴛᴇ Sᴄʀᴇᴇɴsʜᴏᴛ Hᴇʀᴇ', url=OWNER_LNK) - ],[ - InlineKeyboardButton('⇍ ʙᴀᴄᴋ ⇏', callback_data='about') - ]] - reply_markup = InlineKeyboardMarkup(buttons) - await query.message.edit_text(text="● ◌ ◌") - await query.message.edit_text(text="● ● ◌") - await query.message.edit_text(text="● ● ●") - reply_markup = InlineKeyboardMarkup(buttons) - await client.edit_message_media( - query.message.chat.id, - query.message.id, - InputMediaPhoto('https://graph.org/file/99eebf5dbe8a134f548e0.jpg') - ) +@Client.on_callback_query(filters.regex(r"^about")) +async def about_cb(bot, query): + try: + await query.answer() + except: + pass + try: await query.message.edit_text( - text=script.DREAMXBOTZ_DONATION.format(query.from_user.mention, QR_CODE, OWNER_UPI_ID), - reply_markup=reply_markup, - parse_mode=enums.ParseMode.HTML + text=script.ABOUT_TXT.format(temp.B_NAME), + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("🏠 ʜᴏᴍᴇ", callback_data="start"), + InlineKeyboardButton("🔐 ᴄʟᴏsᴇ", callback_data="close_data")] + ]), + disable_web_page_preview=True ) + except MessageNotModified: + pass + except Exception as e: + logger.exception(e) - elif query.data == "help": - buttons = [[ - InlineKeyboardButton('⇋ ʙᴀᴄᴋ ᴛᴏ ʜᴏᴍᴇ ⇋', callback_data='start') - ]] - reply_markup = InlineKeyboardMarkup(buttons) +@Client.on_callback_query(filters.regex(r"^help")) +async def help_cb(bot, query): + try: + await query.answer() + except: + pass + try: await query.message.edit_text( - text=script.HELP_TXT, - reply_markup=reply_markup, - parse_mode=enums.ParseMode.HTML + text=script.HELP_TXT.format(temp.B_NAME), + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("🏠 ʜᴏᴍᴇ", callback_data="start"), + InlineKeyboardButton("🔐 ᴄʟᴏsᴇ", callback_data="close_data")] + ]), + disable_web_page_preview=True ) + except MessageNotModified: + pass - elif query.data == "about": +@Client.on_callback_query(filters.regex(r"^start")) +async def start_cb(bot, query): + try: + await query.answer() + except: + pass + try: buttons = [[ - InlineKeyboardButton('‼️ ᴅɪꜱᴄʟᴀɪᴍᴇʀ ‼️', callback_data='disclaimer'), - InlineKeyboardButton ('🪔 sᴏᴜʀᴄᴇ', callback_data='source'), + InlineKeyboardButton('🔰 ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://t.me/{temp.U_NAME}?startgroup=true') ],[ - InlineKeyboardButton('ᴅᴏɴᴀᴛɪᴏɴ 💰', callback_data='donation'), + InlineKeyboardButton(' ʜᴇʟᴘ 📢', callback_data='help'), + InlineKeyboardButton(' ᴀʙᴏᴜᴛ 📖', callback_data='about') ],[ - InlineKeyboardButton('⇋ ʙᴀᴄᴋ ᴛᴏ ʜᴏᴍᴇ ⇋', callback_data='start') - ]] - reply_markup = InlineKeyboardMarkup(buttons) - await query.message.edit_text( - text=script.ABOUT_TXT.format(temp.U_NAME, temp.B_NAME, OWNER_LNK), - reply_markup=reply_markup, - disable_web_page_preview=True, - parse_mode=enums.ParseMode.HTML - ) - - elif query.data == "give_trial": - try: - user_id = query.from_user.id - has_free_trial = await db.check_trial_status(user_id) - if has_free_trial: - await query.answer( - "🚸 ʏᴏᴜ'ᴠᴇ ᴀʟʀᴇᴀᴅʏ ᴄʟᴀɪᴍᴇᴅ ʏᴏᴜʀ ꜰʀᴇᴇ ᴛʀɪᴀʟ ᴏɴᴄᴇ !\n\n📌 ᴄʜᴇᴄᴋᴏᴜᴛ ᴏᴜʀ ᴘʟᴀɴꜱ ʙʏ : /plan", - show_alert=True - ) - return - else: - await db.give_free_trial(user_id) - await query.answer("✅ Trial activated!", show_alert=True) - - msg = await client.send_photo( - chat_id=query.message.chat.id, - photo="https://i.ibb.co/0jC8MSDZ/photo-2025-07-26-10-42-36-7531339283701956616.jpg", - caption=( - "🥳 ᴄᴏɴɢʀᴀᴛᴜʟᴀᴛɪᴏɴꜱ\n\n" - "🎉 ʏᴏᴜ ᴄᴀɴ ᴜsᴇ ꜰʀᴇᴇ ᴛʀᴀɪʟ ꜰᴏʀ 5 ᴍɪɴᴜᴛᴇs ꜰʀᴏᴍ ɴᴏᴡ !\n\n" - "ɴᴇᴇᴅ ᴘʀᴇᴍɪᴜᴍ 👉🏻 /plan" - ), - parse_mode=enums.ParseMode.HTML, - reply_markup=InlineKeyboardMarkup([[ - InlineKeyboardButton("🚀 Buy Premium 🚀", callback_data="premium_info") - ]]) - ) - await asyncio.sleep(DELETE_TIME) - return await msg.delete() - except Exception: - logger.exception("Error in give_trial callback") - - - - elif query.data == "source": - buttons = [[ - InlineKeyboardButton('ᴅʀᴇᴀᴍxʙᴏᴛᴢ 📜', url='https://github.com/DreamXBotz/Auto_Filter_Bot.git'), - InlineKeyboardButton('⇋ ʙᴀᴄᴋ ⇋', callback_data='about') + InlineKeyboardButton('ᴛᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), + InlineKeyboardButton('ᴜᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), ]] - reply_markup = InlineKeyboardMarkup(buttons) await query.message.edit_text( - text=script.SOURCE_TXT, - reply_markup=reply_markup, - parse_mode=enums.ParseMode.HTML + text=script.START_TXT.format(query.from_user.mention, temp.U_NAME, temp.B_NAME), + reply_markup=InlineKeyboardMarkup(buttons), + disable_web_page_preview=True ) + except MessageNotModified: + pass - elif query.data == "ref_point": - await query.answer(f'You Have: {referdb.get_refer_points(query.from_user.id)} Refferal points.', show_alert=True) - - elif query.data == "disclaimer": - btn = [[ - InlineKeyboardButton("⇋ ʙᴀᴄᴋ ⇋", callback_data="about") - ]] - reply_markup = InlineKeyboardMarkup(btn) - await query.message.edit_text( - text=(script.DISCLAIMER_TXT), - reply_markup=reply_markup, - parse_mode=enums.ParseMode.HTML - ) - - elif query.data == "premium_info": - try: - btn = [[ - InlineKeyboardButton('• ʙᴜʏ ᴘʀᴇᴍɪᴜᴍ •', callback_data='buy_info'), - ],[ - InlineKeyboardButton('• ʀᴇꜰᴇʀ ꜰʀɪᴇɴᴅꜱ', callback_data='reffff'), - InlineKeyboardButton('ꜰʀᴇᴇ ᴛʀɪᴀʟ •', callback_data='give_trial') - ],[ - InlineKeyboardButton('⇋ ʙᴀᴄᴋ ᴛᴏ ʜᴏᴍᴇ ⇋', callback_data='start') - ]] - reply_markup = InlineKeyboardMarkup(btn) - await client.edit_message_media( - chat_id=query.message.chat.id, - message_id=query.message.id, - media=InputMediaPhoto(media=SUBSCRIPTION, caption=script.BPREMIUM_TXT, parse_mode=enums.ParseMode.HTML), - reply_markup=reply_markup - ) - except Exception: - logger.exception("Exception in 'premium_info' callback") - - - elif query.data == "buy_info": - try: - btn = [[ - InlineKeyboardButton('ꜱᴛᴀʀ', callback_data='star_info'), - InlineKeyboardButton('ᴜᴘɪ', callback_data='upi_info') - ],[ - InlineKeyboardButton('⇋ ʙᴀᴄᴋ ᴛᴏ ᴘʀᴇᴍɪᴜᴍ ⇋', callback_data='premium_info') - ]] - reply_markup = InlineKeyboardMarkup(btn) - await client.edit_message_media( - chat_id=query.message.chat.id, - message_id=query.message.id, - media=InputMediaPhoto(media=SUBSCRIPTION, caption=script.PREMIUM_TEXT, parse_mode=enums.ParseMode.HTML), - reply_markup=reply_markup - ) - except Exception: - logger.exception("Exception in 'buy_info' callback") - - elif query.data == "upi_info": - try: - btn = [[ - InlineKeyboardButton('• ꜱᴇɴᴅ ᴘᴀʏᴍᴇɴᴛ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ •', url=OWNER_LNK), - ],[ - InlineKeyboardButton('⇋ ʙᴀᴄᴋ ⇋', callback_data='buy_info') - ]] - reply_markup = InlineKeyboardMarkup(btn) - await client.edit_message_media( - chat_id=query.message.chat.id, - message_id=query.message.id, - media=InputMediaPhoto(media=SUBSCRIPTION, caption=script.PREMIUM_UPI_TEXT.format(OWNER_UPI_ID), parse_mode=enums.ParseMode.HTML), - reply_markup=reply_markup - ) - except Exception: - logger.exception("Exception in 'upi_info' callback") - - elif query.data == "star_info": - try: - btn = [ - InlineKeyboardButton(f"{stars}⭐", callback_data=f"buy_{stars}") - for stars, days in STAR_PREMIUM_PLANS.items() - ] - buttons = [btn[i:i + 2] for i in range(0, len(btn), 2)] - buttons.append([InlineKeyboardButton("⋞ ʙᴀᴄᴋ", callback_data="buy_info")]) - reply_markup = InlineKeyboardMarkup(buttons) - await client.edit_message_media( - chat_id=query.message.chat.id, - message_id=query.message.id, - media=InputMediaPhoto(media=SUBSCRIPTION, caption=script.PREMIUM_STAR_TEXT, parse_mode=enums.ParseMode.HTML), - reply_markup=reply_markup - ) - except Exception: - logger.exception("Exception in 'star' callback") - - - elif query.data.startswith("grp_pm"): - _, grp_id = query.data.split("#") - user_id = query.from_user.id if query.from_user else None - if not await is_check_admin(client, int(grp_id), user_id): - return await query.answer(script.NT_ADMIN_ALRT_TXT, show_alert=True) - - btn = await group_setting_buttons(int(grp_id)) - dreamx = await client.get_chat(int(grp_id)) - await query.message.edit(text=await get_settings_text(grp_id, dreamx.title), reply_markup=InlineKeyboardMarkup(btn), parse_mode=enums.ParseMode.HTML) - - elif query.data.startswith("removegrp"): - user_id = query.from_user.id - data = query.data - grp_id = int(data.split("#")[1]) - if not await is_check_admin(client, grp_id, query.from_user.id): - return await query.answer(script.NT_ADMIN_ALRT_TXT, show_alert=True) - await db.remove_group_connection(grp_id, user_id) - await query.answer("Group removed from your connections.", show_alert=True) - connected_groups = await db.get_connected_grps(user_id) - if not connected_groups: - await query.edit_message_text("Nᴏ Cᴏɴɴᴇᴄᴛᴇᴅ Gʀᴏᴜᴘs Fᴏᴜɴᴅ .") - return - group_list = [] - for group in connected_groups: - try: - Chat = await client.get_chat(group) - group_list.append([ - InlineKeyboardButton( - text=Chat.title, callback_data=f"grp_pm#{Chat.id}") - ]) - except Exception: - pass - await query.edit_message_text( - "⚠️ ꜱᴇʟᴇᴄᴛ ᴛʜᴇ ɢʀᴏᴜᴘ ᴡʜᴏꜱᴇ ꜱᴇᴛᴛɪɴɢꜱ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʜᴀɴɢᴇ.\n\n" - "ɪꜰ ʏᴏᴜʀ ɢʀᴏᴜᴘ ɪꜱ ɴᴏᴛ ꜱʜᴏᴡɪɴɢ ʜᴇʀᴇ,\n" - "ᴜꜱᴇ /reload ɪɴ ᴛʜᴀᴛ ɢʀᴏᴜᴘ ᴀɴᴅ ɪᴛ ᴡɪʟʟ ᴀᴘᴘᴇᴀʀ ʜᴇʀᴇ.", - reply_markup=InlineKeyboardMarkup(group_list) - ) - - elif query.data.startswith("setgs"): - ident, set_type, status, grp_id = query.data.split("#") - userid = query.from_user.id if query.from_user else None - if not await is_check_admin(client, int(grp_id), userid): - await query.answer(script.NT_ADMIN_ALRT_TXT, show_alert=True) - return - if status == "True": - await save_group_settings(int(grp_id), set_type, False) - await query.answer("ᴏꜰꜰ ✗") - else: - await save_group_settings(int(grp_id), set_type, True) - await query.answer("ᴏɴ ✓") - settings = await get_settings(int(grp_id)) - if settings is not None: - btn = await group_setting_buttons(int(grp_id)) - reply_markup = InlineKeyboardMarkup(btn) - await query.message.edit_reply_markup(reply_markup) - await query.answer(MSG_ALRT) - - -async def auto_filter(client, msg, spoll=False): - """ - Core auto_filter logic with timing/debug logging removed. - """ - curr_time = datetime.now(pytz.timezone('Asia/Kolkata')).time() - - async def _schedule_delete(sent_obj, orig_msg, delay): - try: - await asyncio.sleep(delay) - try: - await sent_obj.delete() - except Exception: - pass - try: - await orig_msg.delete() - except Exception: - pass - except Exception: - # ignore scheduling errors - pass - m = None +@Client.on_callback_query(filters.regex(r"^close_data")) +async def close_cb(bot, query): try: - if not spoll: - message = msg - if message.text.startswith("/"): - return - if re.findall(r"((^\/|^,|^!|^\.|^[\U0001F600-\U000E007F]).*)", message.text): - return - if len(message.text) < 100: - message_text = message.text or "" - search = message_text.lower() - m = await message.reply_text(script.SEARCHING_TXT.format(search)) - find = search.split(" ") - search = "" - removes = ["in", "upload", "series", "full", - "horror", "thriller", "mystery", "print", "file"] - for x in find: - if x in removes: - continue - else: - search = search + x + " " - search = re.sub(r"\b(pl(i|e)*?(s|z+|ease|se|ese|(e+)s(e)?)|((send|snd|giv(e)?|gib)(\sme)?)|movie(s)?|new|latest|bro|bruh|broh|helo|that|find|dubbed|link|venum|iruka|pannunga|pannungga|anuppunga|anupunga|anuppungga|anupungga|film|undo|kitti|kitty|tharu|kittumo|kittum|movie|any(one)|with\ssubtitle(s)?)\b", "", search, flags=re.IGNORECASE) - search = search.replace("-", " ") - search = re.sub(r"[:']", "", search) - search = re.sub(r"\s+", " ", search).strip() - files, offset, total_results = await get_search_results(message.chat.id, search, offset=0, filter=True) - settings = await get_settings(message.chat.id) - if not files: - if settings.get("spell_check"): - ai_sts = await m.edit('🤖 ᴘʟᴇᴀꜱᴇ ᴡᴀɪᴛ, ᴀɪ ɪꜱ ᴄʜᴇᴄᴋɪɴɢ ʏᴏᴜʀ ꜱᴘᴇʟʟɪɴɢ...') - is_misspelled = await ai_spell_check(chat_id=message.chat.id, wrong_name=search) - if is_misspelled: - await ai_sts.edit(f'✅ Aɪ Sᴜɢɢᴇsᴛᴇᴅ: {is_misspelled}\n🔍 Searching for it...') - message.text = is_misspelled - await ai_sts.delete() - return await auto_filter(client, message) - await ai_sts.delete() - result = await advantage_spell_chok(client, message) - return result - else: - try: - if m: - await m.delete() - except Exception: - pass - result = await advantage_spell_chok(client, message) - return result - else: - return - else: - message = msg.message.reply_to_message - search, files, offset, total_results = spoll - m = await message.reply_text(f'🔎 sᴇᴀʀᴄʜɪɴɢ {search}', reply_to_message_id=message.id) - settings = await get_settings(message.chat.id) - await msg.message.delete() - key = f"{message.chat.id}-{message.id}" - FRESH[key] = search - temp.GETALL[key] = files - req = message.from_user.id if message.from_user else 0 - temp.SHORT[message.from_user.id] = message.chat.id + await query.message.delete() + except: try: - await client.send_reaction(chat_id=message.chat.id, message_id=message.id, emoji="🍿") - except Exception: + await query.message.edit_text("Closed") + except: pass - if settings.get('button'): - btn = [ - [ - InlineKeyboardButton(text=f"🔗 {get_size(file.file_size)} ≽ " + clean_filename( - file.file_name), callback_data=f'file#{file.file_id}'), - ] - for file in files - ] - btn.insert(0, - [ - InlineKeyboardButton( - 'Qᴜᴀʟɪᴛʏ', callback_data=f"qualities#{req}#{key}"), - InlineKeyboardButton( - "Lᴀɴɢᴜᴀɢᴇ", callback_data=f"languages#{req}#{key}"), - InlineKeyboardButton( - "Sᴇᴀsᴏɴ", callback_data=f"seasons#{req}#{key}") - ] - ) - btn.insert(0, - [ - InlineKeyboardButton( - "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), - InlineKeyboardButton( - "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) - - ]) - else: - btn = [] - btn.insert(0, - [ - InlineKeyboardButton( - 'Qᴜᴀʟɪᴛʏ', callback_data=f"qualities#{req}#{key}"), - InlineKeyboardButton( - "Lᴀɴɢᴜᴀɢᴇ", callback_data=f"languages#{req}#{key}"), - InlineKeyboardButton( - "Sᴇᴀsᴏɴ", callback_data=f"seasons#{req}#{key}") - ] - ) - btn.insert(0, - [ - InlineKeyboardButton( - "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), - InlineKeyboardButton( - "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) - ]) - - if offset != "": - req = message.from_user.id if message.from_user else 0 - if ULTRA_FAST_MODE: - btn.append( - [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( - text="1", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}")] - ) - else: - try: - if settings['max_btn']: - btn.append( - [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( - text=f"1/{math.ceil(int(total_results)/10)}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}")] - ) - else: - btn.append( - [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( - text=f"1/{math.ceil(int(total_results)/int(MAX_B_TN))}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}")] - ) - except KeyError: - await save_group_settings(message.chat.id, 'max_btn', True) - btn.append( - [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( - text=f"1/{math.ceil(int(total_results)/10)}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}")] - ) - else: - btn.append([InlineKeyboardButton( - text="↭ ɴᴏ ᴍᴏʀᴇ ᴘᴀɢᴇꜱ ᴀᴠᴀɪʟᴀʙʟᴇ ↭", callback_data="pages")]) + try: + await query.answer() + except: + pass - if settings.get('imdb'): - imdb = await get_posterx(search, file=(files[0]).file_name) if TMDB_POSTER else await get_poster(search, file=(files[0]).file_name) - else: - imdb = None - cur_time = datetime.now(pytz.timezone('Asia/Kolkata')).time() - time_difference = timedelta(hours=cur_time.hour, minutes=cur_time.minute, seconds=(cur_time.second+(cur_time.microsecond/1000000))) - \ - timedelta(hours=curr_time.hour, minutes=curr_time.minute, - seconds=(curr_time.second+(curr_time.microsecond/1000000))) - remaining_seconds = "{:.2f}".format(time_difference.total_seconds()) - TEMPLATE = script.IMDB_TEMPLATE_TXT - settings = await get_settings(message.chat.id) - if settings.get('template'): - TEMPLATE = settings['template'] - if imdb: - cap = TEMPLATE.format( - query=search, - title=imdb['title'], - votes=imdb['votes'], - aka=imdb["aka"], - seasons=imdb["seasons"], - box_office=imdb['box_office'], - localized_title=imdb['localized_title'], - kind=imdb['kind'], - imdb_id=imdb["imdb_id"], - cast=imdb['cast'], - runtime=imdb['runtime'], - countries=imdb['countries'], - certificates=imdb['certificates'], - languages=imdb['languages'], - director=imdb['director'], - writer=imdb['writer'], - producer=imdb['producer'], - composer=imdb['composer'], - cinematographer=imdb['cinematographer'], - music_team=imdb['music_team'], - distributors=imdb['distributors'], - release_date=imdb['release_date'], - year=imdb['year'], - genres=imdb['genres'], - poster=imdb['poster'], - plot=imdb['plot'] if settings.get('button') else "N/A", - rating=imdb['rating'], - url=imdb['url'], - **locals() - ) - temp.IMDB_CAP[message.from_user.id] = cap - if not settings.get('button'): - cap += "\n\nYour Requested Files Are Here\n\n" - for idx, file in enumerate(files, start=1): - cap += f"\n{idx}. [{get_size(file.file_size)}] {clean_filename(file.file_name)}\n" - else: - temp.IMDB_CAP[message.from_user.id] = None - if ULTRA_FAST_MODE: - if settings.get('button'): - cap = f"🏷 ᴛɪᴛʟᴇ : {search}\n⏰ ʀᴇsᴜʟᴛ ɪɴ : {remaining_seconds} Sᴇᴄᴏɴᴅs\n\n📝 ʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {message.from_user.mention}\n⚜️ ᴘᴏᴡᴇʀᴇᴅ ʙʏ : ⚡ {message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'} \n\nYour Requested Files Are Here \n\n" - else: - cap = f"🏷 ᴛɪᴛʟᴇ : {search}\n⏰ ʀᴇsᴜʟᴛ ɪɴ : {remaining_seconds} Sᴇᴄᴏɴᴅs\n\n📝 ʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {message.from_user.mention}\n⚜️ ᴘᴏᴡᴇʀᴇᴅ ʙʏ : ⚡ {message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'} \n\nYour Requested Files Are Here \n\n" - for idx, file in enumerate(files, start=1): - cap += f"\n{idx}. [{get_size(file.file_size)}] {clean_filename(file.file_name)}\n" - else: - if settings.get('button'): - cap = f"🏷 ᴛɪᴛʟᴇ : {search}\n🧱 ᴛᴏᴛᴀʟ ꜰɪʟᴇꜱ : {total_results}\n⏰ ʀᴇsᴜʟᴛ ɪɴ : {remaining_seconds} Sᴇᴄᴏɴᴅs\n\n📝 ʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {message.from_user.mention}\n⚜️ ᴘᴏᴡᴇʀᴇᴅ ʙʏ : ⚡ {message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'} \n\nYour Requested Files Are Here \n\n" - else: - cap = f"🏷 ᴛɪᴛʟᴇ : {search}\n🧱 ᴛᴏᴛᴀʟ ꜰɪʟᴇꜱ : {total_results}\n⏰ ʀᴇsᴜʟᴛ ɪɴ : {remaining_seconds} Sᴇᴄᴏɴᴅs\n\n📝 ʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {message.from_user.mention}\n⚜️ ᴘᴏᴡᴇʀᴇᴅ ʙʏ : ⚡ {message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'} \n\nYour Requested Files Are Here \n\n" +@Client.on_callback_query(filters.regex(r"^pages")) +async def pages_cb(bot, query): + await query.answer() - for idx, file in enumerate(files, start=1): - cap += f"\n{idx}. [{get_size(file.file_size)}] {clean_filename(file.file_name)}\n" - sent = None - try: - if imdb and imdb.get('poster'): - try: - if TMDB_POSTER: - photo = imdb.get('backdrop') if imdb.get('backdrop') and LANDSCAPE_POSTER else imdb.get('poster') - else: - photo = imdb.get('poster') - sent = await message.reply_photo(photo=photo, caption=cap, reply_markup=InlineKeyboardMarkup(btn), parse_mode=enums.ParseMode.HTML) - if m: - await m.delete() - except (MediaEmpty, PhotoInvalidDimensions, WebpageMediaEmpty): - pic = imdb.get('poster') - poster = pic.replace('.jpg', "._V1_UX360.jpg") - sent = await message.reply_photo(photo=poster, caption=cap, reply_markup=InlineKeyboardMarkup(btn), parse_mode=enums.ParseMode.HTML) - if m: - await m.delete() - except Exception as e: - logger.exception(e) - sent = await message.reply_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) - else: - sent = await message.reply_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) - if m: - await m.delete() - except Exception as e: - logger.exception("Failed to send result: %s", e) - return - try: - if settings.get('auto_delete'): - asyncio.create_task(_schedule_delete(sent, message, DELETE_TIME)) - except KeyError: +@Client.on_callback_query(filters.regex(r"^sendall#")) +async def sendall_cb(bot, query): + try: + _, key, req = query.data.split("#") + req = int(req) + if req != 0 and query.from_user.id != req: + return await query.answer("This is not for you!", show_alert=True) + files = temp.GETALL.get(key) + if not files: + return await query.answer("No files found", show_alert=True) + await query.answer("Sending all files in PM...", show_alert=False) + for file in files[:10]: try: - await save_group_settings(message.chat.id, 'auto_delete', True) + await bot.send_cached_media(chat_id=query.from_user.id, file_id=file.file_id, caption=file.file_name) + await asyncio.sleep(1) + except FloodWait as e: + await asyncio.sleep(e.value) except Exception: pass - asyncio.create_task(_schedule_delete(sent, message, DELETE_TIME)) - return except Exception as e: logger.exception(e) - return - -async def ai_spell_check(chat_id, wrong_name): - async def search_movie(wrong_name): - search_results = imdb.search_movie(wrong_name) - if not search_results or not hasattr(search_results, "titles"): - return [] - movie_list = [movie.title for movie in search_results.titles] - return movie_list - movie_list = await search_movie(wrong_name) - if not movie_list: - return - for _ in range(5): - closest_match = process.extractOne(wrong_name, movie_list) - if not closest_match or closest_match[1] <= 80: - return - movie = closest_match[0] - files, _, _ = await get_search_results(chat_id=chat_id, query=movie) - if files: - return movie - movie_list.remove(movie) - -async def advantage_spell_chok(client, message): - search = message.text - query = re.sub( - r"\b(pl(i|e)*?(s|z+|ease|se|ese|(e+)s(e)?)|((send|snd|giv(e)?|gib)(\sme)?)|movie(s)?|new|latest|br((o|u)h?)*|^h(e|a)?(l)*(o)*|mal(ayalam)?|t(h)?amil|file|that|find|und(o)*|kit(t(i|y)?)?o(w)?|thar(u)?(o)*w?|kittum(o)*|aya(k)*(um(o)*)?|full\smovie|any(one)|with\ssubtitle(s)?)", - "", message.text, flags=re.IGNORECASE) - query = query.strip() + " movie" - try: - movies = await get_poster(search, bulk=True) - except Exception as e: - logger.exception("get_poster failed for query=%s: %s", query, e) - try: - k = await message.reply(script.I_CUDNT.format(message.from_user.mention)) - await asyncio.sleep(60) - try: - await k.delete() - except Exception: - pass - except Exception: - pass - try: - await message.delete() - except Exception: - pass - return - if not movies: - google = quote_plus(search) - button = [[InlineKeyboardButton( - "🔍 ᴄʜᴇᴄᴋ sᴘᴇʟʟɪɴɢ ᴏɴ ɢᴏᴏɢʟᴇ 🔍", url=f"https://www.google.com/search?q={google}")]] - k = await message.reply_text(text=script.I_CUDNT.format(search), reply_markup=InlineKeyboardMarkup(button)) - await asyncio.sleep(60) - try: - await k.delete() - except Exception: - pass - try: - await message.delete() - except Exception: - pass - return - user = message.from_user.id if message.from_user else 0 - buttons = [ - [InlineKeyboardButton(text=movie.title, callback_data=f"spol#{movie.imdb_id}#{user}") - ] for movie in movies] - - buttons.append([InlineKeyboardButton( - text="🚫 ᴄʟᴏsᴇ 🚫", callback_data='close_data', style=enums.ButtonStyle.DANGER)]) - d = await message.reply_text(text=script.CUDNT_FND.format(message.from_user.mention), reply_markup=InlineKeyboardMarkup(buttons), reply_to_message_id=message.id) - await asyncio.sleep(60) - try: - await d.delete() - except Exception: - pass - try: - await message.delete() - except Exception: - pass - From aad2e149bd3aee14e48f135dfd142a0ceb470897 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Sun, 13 Sep 2026 15:13:26 +0530 Subject: [PATCH 09/77] Fix message length checks and text formatting Refactor message handling to improve query length validation and formatting for ABOUT_TXT, HELP_TXT, and START_TXT. --- plugins/pmfilter.py | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/plugins/pmfilter.py b/plugins/pmfilter.py index c5533564..781d3846 100644 --- a/plugins/pmfilter.py +++ b/plugins/pmfilter.py @@ -31,9 +31,17 @@ async def auto_filter(client, message): return if re.findall(r"((^\/|^,|^!|^\.|^[\U0001F600-\U000E007F]).*)", message.text): return - if 2 < len(message.text) < 100: - search = message.text + # FIX: allow longer queries, file show na korar bug fix + if len(message.text) < 2: + return + search = message.text.strip() + if len(search) > 100: + search = search[:100] + if True: files, offset, total_results = await get_search_results(search.lower(), offset=0, filter=True) + # fallback if filter=True returns nothing + if not files: + files, offset, total_results = await get_search_results(search.lower(), offset=0, filter=False) if not files: if temp.B_LINK: return @@ -388,9 +396,20 @@ async def about_cb(bot, query): await query.answer() except: pass + # FIX: ABOUT_TXT may have 0,1,2 placeholders - handle all + try: + try: + about_text = script.ABOUT_TXT.format(temp.B_NAME, temp.U_NAME) + except IndexError: + try: + about_text = script.ABOUT_TXT.format(temp.B_NAME) + except: + about_text = script.ABOUT_TXT + except Exception: + about_text = script.ABOUT_TXT try: await query.message.edit_text( - text=script.ABOUT_TXT.format(temp.B_NAME), + text=about_text, reply_markup=InlineKeyboardMarkup([ [InlineKeyboardButton("🏠 ʜᴏᴍᴇ", callback_data="start"), InlineKeyboardButton("🔐 ᴄʟᴏsᴇ", callback_data="close_data")] @@ -410,7 +429,7 @@ async def help_cb(bot, query): pass try: await query.message.edit_text( - text=script.HELP_TXT.format(temp.B_NAME), + text=script.HELP_TXT.format(temp.B_NAME) if "{0}" in script.HELP_TXT or "{}" in script.HELP_TXT else script.HELP_TXT, reply_markup=InlineKeyboardMarkup([ [InlineKeyboardButton("🏠 ʜᴏᴍᴇ", callback_data="start"), InlineKeyboardButton("🔐 ᴄʟᴏsᴇ", callback_data="close_data")] @@ -437,7 +456,7 @@ async def start_cb(bot, query): InlineKeyboardButton('ᴜᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), ]] await query.message.edit_text( - text=script.START_TXT.format(query.from_user.mention, temp.U_NAME, temp.B_NAME), + text=script.START_TXT.format(query.from_user.mention, temp.U_NAME, temp.B_NAME) if script.START_TXT.count("{")>=2 else script.START_TXT, reply_markup=InlineKeyboardMarkup(buttons), disable_web_page_preview=True ) From 64d7d2844c1b32cdc85511a592db553802c30b82 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Sun, 13 Sep 2026 15:18:10 +0530 Subject: [PATCH 10/77] Enhance message filters and settings error handling Updated message filters to include private messages and added error handling for settings retrieval. --- plugins/pmfilter.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/pmfilter.py b/plugins/pmfilter.py index 781d3846..2608ea21 100644 --- a/plugins/pmfilter.py +++ b/plugins/pmfilter.py @@ -22,7 +22,7 @@ QUALITIES = ["360p", "480p", "720p", "1080p", "1440p", "2160p"] SEASONS = ["season 1" , "season 2" , "season 3" , "season 4", "season 5" , "season 6" , "season 7" , "season 8" , "season 9" , "season 10"] -@Client.on_message(filters.text & filters.group & filters.incoming & ~filters.command(["start", "help", "about", "id", "settings", "fsub", "post", "delete", "del"])) +@Client.on_message((filters.text & filters.group & filters.incoming & ~filters.command(["start", "help", "about", "id", "settings", "fsub", "post", "delete", "del"])) | (filters.text & filters.private & filters.incoming & ~filters.command(["start", "help", "about", "id", "settings", "fsub", "post", "delete", "del"])) ) async def give_filter(client, message): await auto_filter(client, message) @@ -48,7 +48,10 @@ async def auto_filter(client, message): # try with spell check - simplified return else: - settings = await get_settings(message.chat.id) + try: + settings = await get_settings(message.chat.id) + except: + settings = {'auto_delete': False} # req = requester id - THIS IS THE FIX for quality/language/session req = message.from_user.id if message.from_user else 0 temp.GETALL[search] = files From 4d333dd3a770983b056180394abd541c7822d412 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Sun, 13 Sep 2026 15:23:54 +0530 Subject: [PATCH 11/77] Update pmfilter.py --- plugins/pmfilter.py | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/plugins/pmfilter.py b/plugins/pmfilter.py index 2608ea21..0803aa65 100644 --- a/plugins/pmfilter.py +++ b/plugins/pmfilter.py @@ -18,7 +18,7 @@ CAP = {} # QUALITY AND LANGUAGE MAPS (same font as your bot) -LANGUAGES = ["malayalam", "mal", "tamil", "tam" ,"english", "eng", "hindi", "hin" ,"telugu", "tel" ,"kannada", "kan", "bengali", "ben", "marathi", "mar", "gujarati", "guj", "punjabi", "pun"] +LANGUAGES = ["hindi", "english", "tamil", "telugu", "kannada", "malayalam", "bengali", "marathi", "gujarati", "punjabi"] QUALITIES = ["360p", "480p", "720p", "1080p", "1440p", "2160p"] SEASONS = ["season 1" , "season 2" , "season 3" , "season 4", "season 5" , "season 6" , "season 7" , "season 8" , "season 9" , "season 10"] @@ -98,7 +98,8 @@ async def auto_filter(client, message): imdb = await get_poster(search, file=(files[0].file_name if files else None)) if imdb and imdb.get('poster'): - cap = script.IMDB_TEMPLATE.format( + try: + cap = script.IMDB_TEMPLATE.format( qurey=search, title=imdb.get('title'), votes=imdb.get('votes'), @@ -128,6 +129,8 @@ async def auto_filter(client, message): rating=imdb.get('rating'), url=imdb.get('url'), ) + except Exception as e: + cap = f"Here is what I found for your query {search} :" else: cap = f"Here is what I found for your query {search} :" @@ -399,25 +402,21 @@ async def about_cb(bot, query): await query.answer() except: pass - # FIX: ABOUT_TXT may have 0,1,2 placeholders - handle all + # FINAL FIX: use ABOUT_TXT directly without format to prevent crash + about_text = script.ABOUT_TXT + # try to format safely if placeholders exist try: - try: - about_text = script.ABOUT_TXT.format(temp.B_NAME, temp.U_NAME) - except IndexError: - try: - about_text = script.ABOUT_TXT.format(temp.B_NAME) - except: - about_text = script.ABOUT_TXT - except Exception: - about_text = script.ABOUT_TXT + if "{0}" in about_text or "{}" in about_text: + about_text = about_text.format(temp.B_NAME, temp.U_NAME) + except: + pass try: await query.message.edit_text( text=about_text, reply_markup=InlineKeyboardMarkup([ [InlineKeyboardButton("🏠 ʜᴏᴍᴇ", callback_data="start"), InlineKeyboardButton("🔐 ᴄʟᴏsᴇ", callback_data="close_data")] - ]), - disable_web_page_preview=True + ]) ) except MessageNotModified: pass @@ -432,12 +431,11 @@ async def help_cb(bot, query): pass try: await query.message.edit_text( - text=script.HELP_TXT.format(temp.B_NAME) if "{0}" in script.HELP_TXT or "{}" in script.HELP_TXT else script.HELP_TXT, + text=script.HELP_TXT, reply_markup=InlineKeyboardMarkup([ [InlineKeyboardButton("🏠 ʜᴏᴍᴇ", callback_data="start"), InlineKeyboardButton("🔐 ᴄʟᴏsᴇ", callback_data="close_data")] - ]), - disable_web_page_preview=True + ]) ) except MessageNotModified: pass @@ -458,10 +456,17 @@ async def start_cb(bot, query): InlineKeyboardButton('ᴛᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), InlineKeyboardButton('ᴜᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), ]] + # safe format for START_TXT + try: + start_text = script.START_TXT.format(query.from_user.mention, temp.U_NAME, temp.B_NAME) + except: + try: + start_text = script.START_TXT.format(query.from_user.mention, temp.B_NAME) + except: + start_text = script.START_TXT await query.message.edit_text( - text=script.START_TXT.format(query.from_user.mention, temp.U_NAME, temp.B_NAME) if script.START_TXT.count("{")>=2 else script.START_TXT, - reply_markup=InlineKeyboardMarkup(buttons), - disable_web_page_preview=True + text=start_text, + reply_markup=InlineKeyboardMarkup(buttons) ) except MessageNotModified: pass From 4e516de28f17ca71f38000e503f7914b85877e6b Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Sun, 13 Sep 2026 15:30:47 +0530 Subject: [PATCH 12/77] Update pmfilter.py --- plugins/pmfilter.py | 62 ++++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/plugins/pmfilter.py b/plugins/pmfilter.py index 0803aa65..8c20ca93 100644 --- a/plugins/pmfilter.py +++ b/plugins/pmfilter.py @@ -27,7 +27,8 @@ async def give_filter(client, message): await auto_filter(client, message) async def auto_filter(client, message): - if message.text.startswith("/"): + try: + if message.text.startswith("/"): return if re.findall(r"((^\/|^,|^!|^\.|^[\U0001F600-\U000E007F]).*)", message.text): return @@ -43,9 +44,8 @@ async def auto_filter(client, message): if not files: files, offset, total_results = await get_search_results(search.lower(), offset=0, filter=False) if not files: - if temp.B_LINK: - return - # try with spell check - simplified + # No files found - don't return silently, try spell check or just return + logger.info(f"No files for search: {search}") return else: try: @@ -151,7 +151,9 @@ async def auto_filter(client, message): except Exception: pass except Exception as e: - logger.exception(e) + logger.exception(f"send error: {e}") + except Exception as e: + logger.exception(f"auto_filter error for {message.text}: {e}") async def get_poster(query, bulk=False, id=False, file=None): @@ -402,14 +404,20 @@ async def about_cb(bot, query): await query.answer() except: pass - # FINAL FIX: use ABOUT_TXT directly without format to prevent crash - about_text = script.ABOUT_TXT - # try to format safely if placeholders exist try: - if "{0}" in about_text or "{}" in about_text: - about_text = about_text.format(temp.B_NAME, temp.U_NAME) - except: - pass + # robust formatting - no crash, no {} + b_name = getattr(temp, 'B_NAME', 'Boultflix') or 'Boultflix' + u_name = getattr(temp, 'U_NAME', 'BoultflixMovies_bot') or 'BoultflixMovies_bot' + about_text = script.ABOUT_TXT + # try normal format first + try: + about_text = about_text.format(b_name, u_name) + except: + # fallback manual replace - fixes {} bracket issue + about_text = about_text.replace("{}", b_name).replace("{0}", b_name).replace("{1}", u_name).replace("{2}", b_name) + except Exception as e: + about_text = getattr(script, 'ABOUT_TXT', 'About') + logger.exception(f"about_cb format error: {e}") try: await query.message.edit_text( text=about_text, @@ -447,8 +455,26 @@ async def start_cb(bot, query): except: pass try: + b_name = getattr(temp, 'B_NAME', 'Boultflix') or 'Boultflix' + u_name = getattr(temp, 'U_NAME', 'BoultflixMovies_bot') or 'BoultflixMovies_bot' + mention = query.from_user.mention if query.from_user else "User" + try: + start_text = script.START_TXT.format(mention, u_name, b_name) + except: + try: + start_text = script.START_TXT.format(mention, b_name) + except: + # manual replace for bracket issue + start_text = script.START_TXT + start_text = start_text.replace("{}", mention, 1) + # replace remaining {} with names in order + if "{}" in start_text: + start_text = start_text.replace("{}", b_name, 1) + if "{}" in start_text: + start_text = start_text.replace("{}", b_name) + start_text = start_text.replace("{0}", mention).replace("{1}", u_name).replace("{2}", b_name) buttons = [[ - InlineKeyboardButton('🔰 ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://t.me/{temp.U_NAME}?startgroup=true') + InlineKeyboardButton('🔰 ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://t.me/{u_name}?startgroup=true') ],[ InlineKeyboardButton(' ʜᴇʟᴘ 📢', callback_data='help'), InlineKeyboardButton(' ᴀʙᴏᴜᴛ 📖', callback_data='about') @@ -456,20 +482,14 @@ async def start_cb(bot, query): InlineKeyboardButton('ᴛᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), InlineKeyboardButton('ᴜᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), ]] - # safe format for START_TXT - try: - start_text = script.START_TXT.format(query.from_user.mention, temp.U_NAME, temp.B_NAME) - except: - try: - start_text = script.START_TXT.format(query.from_user.mention, temp.B_NAME) - except: - start_text = script.START_TXT await query.message.edit_text( text=start_text, reply_markup=InlineKeyboardMarkup(buttons) ) except MessageNotModified: pass + except Exception as e: + logger.exception(e) @Client.on_callback_query(filters.regex(r"^close_data")) async def close_cb(bot, query): From a152d87b9d3a4158f050bc385d1d76921bdec805 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Sun, 13 Sep 2026 15:34:34 +0530 Subject: [PATCH 13/77] Update pmfilter.py --- plugins/pmfilter.py | 220 +++++++++++++++++--------------------------- 1 file changed, 83 insertions(+), 137 deletions(-) diff --git a/plugins/pmfilter.py b/plugins/pmfilter.py index 8c20ca93..7551c224 100644 --- a/plugins/pmfilter.py +++ b/plugins/pmfilter.py @@ -1,105 +1,85 @@ import asyncio import re -import ast import math import logging import random from pyrogram import Client, filters, enums -from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery +from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton from pyrogram.errors import MessageNotModified, FloodWait from Script import script -from database.ia_filterdb import get_search_results, get_file_details, get_bad_files +from database.ia_filterdb import get_search_results, get_file_details from database.users_chats_db import db -from info import ADMINS, PICS, PICS_URL, AUTH_CHANNELS, DELETE_TIME, MAX_B_TN, IS_VERIFY, TUTORIAL, TUTORIAL_2, TUTORIAL_3, LOG_CHANNEL, SUPPORT_CHAT_ID -from utils import get_settings, get_size, is_subscribed, is_req_subscribed, get_shortlink, temp, get_readable_time +from info import PICS, PICS_URL, DELETE_TIME +from utils import get_settings, get_size, temp logger = logging.getLogger(__name__) BUTTONS = {} CAP = {} -# QUALITY AND LANGUAGE MAPS (same font as your bot) LANGUAGES = ["hindi", "english", "tamil", "telugu", "kannada", "malayalam", "bengali", "marathi", "gujarati", "punjabi"] QUALITIES = ["360p", "480p", "720p", "1080p", "1440p", "2160p"] -SEASONS = ["season 1" , "season 2" , "season 3" , "season 4", "season 5" , "season 6" , "season 7" , "season 8" , "season 9" , "season 10"] +SEASONS = ["season 1", "season 2", "season 3", "season 4", "season 5", "season 6", "season 7", "season 8", "season 9", "season 10"] -@Client.on_message((filters.text & filters.group & filters.incoming & ~filters.command(["start", "help", "about", "id", "settings", "fsub", "post", "delete", "del"])) | (filters.text & filters.private & filters.incoming & ~filters.command(["start", "help", "about", "id", "settings", "fsub", "post", "delete", "del"])) ) +@Client.on_message((filters.text & filters.group & filters.incoming & ~filters.command(["start", "help", "about", "id", "settings", "fsub", "post", "delete", "del"])) | (filters.text & filters.private & filters.incoming & ~filters.command(["start", "help", "about", "id", "settings", "fsub", "post", "delete", "del"]))) async def give_filter(client, message): await auto_filter(client, message) async def auto_filter(client, message): try: if message.text.startswith("/"): - return - if re.findall(r"((^\/|^,|^!|^\.|^[\U0001F600-\U000E007F]).*)", message.text): - return - # FIX: allow longer queries, file show na korar bug fix - if len(message.text) < 2: - return - search = message.text.strip() - if len(search) > 100: - search = search[:100] - if True: + return + if re.findall(r"((^\/|^,|^!|^\.|^[\U0001F600-\U000E007F]).*)", message.text): + return + if len(message.text) < 2: + return + search = message.text.strip() + if len(search) > 100: + search = search[:100] + files, offset, total_results = await get_search_results(search.lower(), offset=0, filter=True) - # fallback if filter=True returns nothing if not files: files, offset, total_results = await get_search_results(search.lower(), offset=0, filter=False) if not files: - # No files found - don't return silently, try spell check or just return - logger.info(f"No files for search: {search}") + logger.info(f"No files for {search}") return + + try: + settings = await get_settings(message.chat.id) + except: + settings = {'auto_delete': False} + + req = message.from_user.id if message.from_user else 0 + temp.GETALL[search] = files + + btn = [] + btn.append([ + InlineKeyboardButton("ǫᴜᴀʟɪᴛɪᴇs", callback_data=f"qualities#{search}#{req}"), + InlineKeyboardButton("ʟᴀɴɢᴜᴀɢᴇs", callback_data=f"languages#{search}#{req}"), + InlineKeyboardButton("sᴇᴀsᴏɴs", callback_data=f"seasons#{search}#{req}") + ]) + btn.append([InlineKeyboardButton("sᴇɴᴅ ᴀʟʟ ғɪʟᴇs", callback_data=f"sendall#{search}#{req}")]) + for file in files: + f_name = file.file_name + f_size = get_size(file.file_size) + file_id = file.file_id + btn.append([InlineKeyboardButton(f"[{f_size}] {f_name[:40]}", callback_data=f"file#{file_id}#{req}")]) + if offset != "": + btn.append([InlineKeyboardButton("ɴᴇxᴛ »", callback_data=f"next_{req}_{search}_{offset}")]) else: + btn.append([InlineKeyboardButton("ɴᴏ ᴍᴏʀᴇ ᴘᴀɢᴇs", callback_data="pages")]) + + try: + pic_url = random.choice(PICS_URL) if PICS_URL else random.choice(PICS) + except: try: - settings = await get_settings(message.chat.id) + pic_url = random.choice(PICS) except: - settings = {'auto_delete': False} - # req = requester id - THIS IS THE FIX for quality/language/session - req = message.from_user.id if message.from_user else 0 - temp.GETALL[search] = files - # store req for later use - if not hasattr(temp, 'REQ_CACHE'): - temp.REQ_CACHE = {} - temp.REQ_CACHE[search] = req - - # create buttons - btn = [] - # group setting buttons - qualities, languages, seasons - btn.append([ - InlineKeyboardButton("ǫᴜᴀʟɪᴛɪᴇs", callback_data=f"qualities#{search}#{req}"), - InlineKeyboardButton("ʟᴀɴɢᴜᴀɢᴇs", callback_data=f"languages#{search}#{req}"), - InlineKeyboardButton("sᴇᴀsᴏɴs", callback_data=f"seasons#{search}#{req}") - ]) - btn.append([ - InlineKeyboardButton("sᴇɴᴅ ᴀʟʟ ғɪʟᴇs", callback_data=f"sendall#{search}#{req}") - ]) - for file in files: - f_name = file.file_name - f_size = get_size(file.file_size) - file_id = file.file_id - btn.append([ - InlineKeyboardButton(f"[{f_size}] {f_name[:40]}", callback_data=f"file#{file_id}#{req}") - ]) - if offset != "": - btn.append([ - InlineKeyboardButton("ɴᴇxᴛ »", callback_data=f"next_{req}_{search}_{offset}") - ]) - else: - btn.append([ - InlineKeyboardButton("ɴᴏ ᴍᴏʀᴇ ᴘᴀɢᴇs", callback_data="pages") - ]) - - # fix: try pics url then pics + pic_url = None + + imdb = await get_poster(search, file=(files[0].file_name if files else None)) + if imdb and imdb.get('poster'): try: - pic_url = random.choice(PICS_URL) if PICS_URL else random.choice(PICS) - except: - try: - pic_url = random.choice(PICS) - except: - pic_url = None - - imdb = await get_poster(search, file=(files[0].file_name if files else None)) - if imdb and imdb.get('poster'): - try: - cap = script.IMDB_TEMPLATE.format( + cap = script.IMDB_TEMPLATE.format( qurey=search, title=imdb.get('title'), votes=imdb.get('votes'), @@ -129,35 +109,30 @@ async def auto_filter(client, message): rating=imdb.get('rating'), url=imdb.get('url'), ) - except Exception as e: - cap = f"Here is what I found for your query {search} :" - else: + except Exception as e: + logger.exception(e) cap = f"Here is what I found for your query {search} :" - - BUTTONS[search] = cap - CAP[search] = cap - + else: + cap = f"Here is what I found for your query {search} :" + + try: + if pic_url: + sent = await message.reply_photo(photo=pic_url, caption=cap, reply_markup=InlineKeyboardMarkup(btn), parse_mode=enums.ParseMode.HTML) + else: + sent = await message.reply_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), parse_mode=enums.ParseMode.HTML) try: - if pic_url: - sent = await message.reply_photo(photo=pic_url, caption=cap, reply_markup=InlineKeyboardMarkup(btn), parse_mode=enums.ParseMode.HTML) - else: - sent = await message.reply_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), parse_mode=enums.ParseMode.HTML) - # auto delete - try: - if settings.get('auto_delete'): - await asyncio.sleep(DELETE_TIME) - await sent.delete() - await message.delete() - except Exception: - pass - except Exception as e: - logger.exception(f"send error: {e}") + if settings.get('auto_delete'): + await asyncio.sleep(DELETE_TIME) + await sent.delete() + await message.delete() + except: + pass + except Exception as e: + logger.exception(f"send error: {e}") except Exception as e: logger.exception(f"auto_filter error for {message.text}: {e}") - async def get_poster(query, bulk=False, id=False, file=None): - # import here to avoid circular from utils import get_poster as _get_poster, get_posterx try: return await _get_poster(query, bulk, id, file) @@ -172,7 +147,6 @@ async def next_page(bot, query): try: _, req, key, offset = query.data.split("_") req = int(req) - # check req if req != 0 and query.from_user.id != req: return await query.answer("This is not for you!", show_alert=True) search = key @@ -186,16 +160,12 @@ async def next_page(bot, query): InlineKeyboardButton("ʟᴀɴɢᴜᴀɢᴇs", callback_data=f"languages#{search}#{req}"), InlineKeyboardButton("sᴇᴀsᴏɴs", callback_data=f"seasons#{search}#{req}") ]) - btn.append([ - InlineKeyboardButton("sᴇɴᴅ ᴀʟʟ ғɪʟᴇs", callback_data=f"sendall#{search}#{req}") - ]) + btn.append([InlineKeyboardButton("sᴇɴᴅ ᴀʟʟ ғɪʟᴇs", callback_data=f"sendall#{search}#{req}")]) for file in files: f_name = file.file_name f_size = get_size(file.file_size) file_id = file.file_id - btn.append([ - InlineKeyboardButton(f"[{f_size}] {f_name[:40]}", callback_data=f"file#{file_id}#{req}") - ]) + btn.append([InlineKeyboardButton(f"[{f_size}] {f_name[:40]}", callback_data=f"file#{file_id}#{req}")]) if n_offset != "": btn.append([ InlineKeyboardButton("« ʙᴀᴄᴋ", callback_data=f"next_{req}_{search}_{offset-10}" if offset-10 >=0 else f"next_{req}_{search}_0"), @@ -222,7 +192,6 @@ async def qualities_cb(bot, query): req = int(req) if req != 0 and query.from_user.id != req: return await query.answer("This is not for you!", show_alert=True) - # create quality buttons btn = [] for qual in QUALITIES: btn.append([InlineKeyboardButton(qual, callback_data=f"q_filter#{qual}#{key}#{req}")]) @@ -240,7 +209,7 @@ async def languages_cb(bot, query): if req != 0 and query.from_user.id != req: return await query.answer("This is not for you!", show_alert=True) btn = [] - for lang in LANGUAGES[:12]: + for lang in LANGUAGES: btn.append([InlineKeyboardButton(lang, callback_data=f"l_filter#{lang}#{key}#{req}")]) btn.append([InlineKeyboardButton("⇋ ʙᴀᴄᴋ ⇋", callback_data=f"filter_back#{key}#{req}")]) await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) @@ -271,7 +240,6 @@ async def q_filter_cb(bot, query): req = int(req) if req != 0 and query.from_user.id != req: return await query.answer("This is not for you!", show_alert=True) - # filter by quality files = temp.GETALL.get(key) if not files: return await query.answer("No files found!", show_alert=True) @@ -329,9 +297,9 @@ async def s_filter_cb(bot, query): return await query.answer("No files found!", show_alert=True) filtered = [f for f in files if seas.lower() in f.file_name.lower()] if not filtered: - # also check S01 etc num = ''.join(filter(str.isdigit, seas)) - filtered = [f for f in files if f"S{int(num):02d}" in f.file_name or f"S{num}" in f.file_name] + if num: + filtered = [f for f in files if f"S{int(num):02d}" in f.file_name or f"S{num}" in f.file_name] if not filtered: return await query.answer(f"No files found for {seas}", show_alert=True) btn = [] @@ -376,24 +344,13 @@ async def filter_back_cb(bot, query): async def file_cb(bot, query): try: _, file_id, req = query.data.split("#") - req = int(req) - # allow anyone to get file, but req check optional - # if req !=0 and query.from_user.id != req: - # return await query.answer("This is not for you!", show_alert=True) files_ = await get_file_details(file_id) if not files_: return await query.answer("No such file exist.", show_alert=True) - # channel check - settings = await get_settings(query.message.chat.id) - # for private file send try: - await bot.send_cached_media( - chat_id=query.from_user.id, - file_id=file_id, - caption=files_.file_name - ) + await bot.send_cached_media(chat_id=query.from_user.id, file_id=file_id, caption=files_.file_name) await query.answer("Check PM, I have sent files in PM", show_alert=False) - except Exception as e: + except Exception: await query.answer("Failed to send in PM, make sure you started me in PM", show_alert=True) except Exception as e: logger.exception(e) @@ -405,20 +362,14 @@ async def about_cb(bot, query): except: pass try: - # robust formatting - no crash, no {} b_name = getattr(temp, 'B_NAME', 'Boultflix') or 'Boultflix' - u_name = getattr(temp, 'U_NAME', 'BoultflixMovies_bot') or 'BoultflixMovies_bot' + u_name = getattr(temp, 'U_NAME', 'Boultflix') or 'Boultflix' about_text = script.ABOUT_TXT - # try normal format first + # fix bracket issue - replace {} with actual names try: about_text = about_text.format(b_name, u_name) except: - # fallback manual replace - fixes {} bracket issue about_text = about_text.replace("{}", b_name).replace("{0}", b_name).replace("{1}", u_name).replace("{2}", b_name) - except Exception as e: - about_text = getattr(script, 'ABOUT_TXT', 'About') - logger.exception(f"about_cb format error: {e}") - try: await query.message.edit_text( text=about_text, reply_markup=InlineKeyboardMarkup([ @@ -456,7 +407,7 @@ async def start_cb(bot, query): pass try: b_name = getattr(temp, 'B_NAME', 'Boultflix') or 'Boultflix' - u_name = getattr(temp, 'U_NAME', 'BoultflixMovies_bot') or 'BoultflixMovies_bot' + u_name = getattr(temp, 'U_NAME', 'Boultflix') or 'Boultflix' mention = query.from_user.mention if query.from_user else "User" try: start_text = script.START_TXT.format(mention, u_name, b_name) @@ -464,15 +415,13 @@ async def start_cb(bot, query): try: start_text = script.START_TXT.format(mention, b_name) except: - # manual replace for bracket issue start_text = script.START_TXT - start_text = start_text.replace("{}", mention, 1) - # replace remaining {} with names in order + start_text = start_text.replace("{0}", mention).replace("{1}", u_name).replace("{2}", b_name) + # replace leftover {} sequentially if "{}" in start_text: - start_text = start_text.replace("{}", b_name, 1) + start_text = start_text.replace("{}", mention, 1) if "{}" in start_text: start_text = start_text.replace("{}", b_name) - start_text = start_text.replace("{0}", mention).replace("{1}", u_name).replace("{2}", b_name) buttons = [[ InlineKeyboardButton('🔰 ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://t.me/{u_name}?startgroup=true') ],[ @@ -482,10 +431,7 @@ async def start_cb(bot, query): InlineKeyboardButton('ᴛᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), InlineKeyboardButton('ᴜᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), ]] - await query.message.edit_text( - text=start_text, - reply_markup=InlineKeyboardMarkup(buttons) - ) + await query.message.edit_text(text=start_text, reply_markup=InlineKeyboardMarkup(buttons)) except MessageNotModified: pass except Exception as e: @@ -526,7 +472,7 @@ async def sendall_cb(bot, query): await asyncio.sleep(1) except FloodWait as e: await asyncio.sleep(e.value) - except Exception: + except: pass except Exception as e: logger.exception(e) From 4d7317ee368be90a64e97869dae3148bec282d35 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Sun, 13 Sep 2026 16:00:46 +0530 Subject: [PATCH 14/77] Update Script.py --- Script.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Script.py b/Script.py index 3de60dc5..c5afb93b 100644 --- a/Script.py +++ b/Script.py @@ -35,13 +35,13 @@ class script(object): """ ABOUT_TXT = """╭────[ ᴍʏ ᴅᴇᴛᴀɪʟs ]────⍟ -├⍟ Mʏ Nᴀᴍᴇ : {} -├⍟ Dᴇᴠᴇʟᴏᴘᴇʀ : ᴏᴡɴᴇʀ -├⍟ Lɪʙʀᴀʀʏ : ᴘʏʀᴏɢʀᴀᴍ -├⍟ Lᴀɴɢᴜᴀɢᴇ : ᴘʏᴛʜᴏɴ 𝟹 -├⍟ Dᴀᴛᴀʙᴀsᴇ : ᴍᴏɴɢᴏ ᴅʙ -├⍟ Bᴏᴛ Sᴇʀᴠᴇʀ : ʜᴇʀᴏᴋᴜ -├⍟ Bᴜɪʟᴅ Sᴛᴀᴛᴜs : ᴠ1.4 [ ꜱᴛᴀʙʟᴇ ] +├⍟ Mʏ Nᴀᴍᴇ : Bᴏᴜʟᴛғʟɪx Mᴏᴠɪᴇs 🫧🫶🏼 +├⍟ Dᴇᴠᴇʟᴏᴘᴇʀ : Oᴡɴᴇʀ +├⍟ Lɪʙʀᴀʀʏ : Pʏʀᴏɢʀᴀᴍ +├⍟ Lᴀɴɢᴜᴀɢᴇ : Pʏᴛʜᴏɴ 𝟹 +├⍟ Dᴀᴛᴀʙᴀsᴇ : Mᴏɴɢᴏ ᴅʙ +├⍟ Bᴏᴛ Sᴇʀᴠᴇʀ : Rᴇɴᴅᴇʀ +├⍟ Bᴜɪʟᴅ Sᴛᴀᴛᴜs : ᴠ1.4 [ Sᴛᴀʙʟᴇ ] ╰───────────────⍟""" RESTART_TXT = """ {} Bᴏᴛ Rᴇsᴛᴀʀᴛᴇᴅ ! From 32d832e681a2f2355b4234f645c663bf1e221763 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Sun, 13 Sep 2026 16:01:25 +0530 Subject: [PATCH 15/77] Update fmt.Println message from 'Hello' to 'Goodbye' --- plugins/pmfilter.py | 2118 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 1711 insertions(+), 407 deletions(-) diff --git a/plugins/pmfilter.py b/plugins/pmfilter.py index 7551c224..acb92f3f 100644 --- a/plugins/pmfilter.py +++ b/plugins/pmfilter.py @@ -1,478 +1,1782 @@ -import asyncio -import re -import math import logging -import random +from utils import get_random_mix_id, get_size, is_subscribed, is_req_subscribed, group_setting_buttons, get_poster, get_posterx, temp, get_settings, save_group_settings, get_cap, imdb, is_check_admin, extract_request_content, log_error, clean_filename, generate_season_variations, clean_search_text, get_settings_text +from rapidfuzz import process +from dreamxbotz.util.file_properties import get_name, get_hash +from urllib.parse import quote_plus + +from database.ia_filterdb import Media, Media2, get_search_results, get_bad_files +from database.config_db import mdb +from pyrogram.errors import MessageIdInvalid, UserIsBlocked, MessageNotModified, PeerIdInvalid, MessageDeleteForbidden from pyrogram import Client, filters, enums -from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton -from pyrogram.errors import MessageNotModified, FloodWait +from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery, InputMediaPhoto +from info import ( + ADMINS, AUTH_CHANNELS, AUTH_REQ_CHANNELS, BIN_CHANNEL, DELETE_TIME, + EMOJI_MODE, GRP_LNK, LANDSCAPE_POSTER, LANGUAGES, LOG_CHANNEL, MAX_B_TN, MSG_ALRT, + MULTIPLE_DB, NO_RESULTS_MSG, OWNER_LNK, OWNER_UPI_ID, PICS, PICS_URL, QR_CODE, QUALITIES, + REACTIONS, REQST_CHANNEL, SEASONS, STAR_PREMIUM_PLANS, SUBSCRIPTION, SUPPORT_CHAT_ID, + TMDB_ON_SEARCH, TMDB_POSTER, ULTRA_FAST_MODE, UPDATE_CHNL_LNK, URL +) from Script import script -from database.ia_filterdb import get_search_results, get_file_details +from pyrogram.errors.exceptions.bad_request_400 import MediaEmpty, PhotoInvalidDimensions, WebpageMediaEmpty +from database.refer import referdb from database.users_chats_db import db -from info import PICS, PICS_URL, DELETE_TIME -from utils import get_settings, get_size, temp +import asyncio +import re +import math +import random +import pytz +from datetime import datetime, timedelta +lock = asyncio.Lock() logger = logging.getLogger(__name__) -BUTTONS = {} -CAP = {} -LANGUAGES = ["hindi", "english", "tamil", "telugu", "kannada", "malayalam", "bengali", "marathi", "gujarati", "punjabi"] -QUALITIES = ["360p", "480p", "720p", "1080p", "1440p", "2160p"] -SEASONS = ["season 1", "season 2", "season 3", "season 4", "season 5", "season 6", "season 7", "season 8", "season 9", "season 10"] +TIMEZONE = "Asia/Kolkata" +BUTTON = {} +BUTTONS = {} +FRESH = {} +BUTTONS0 = {} +BUTTONS1 = {} +BUTTONS2 = {} +SPELL_CHECK = {} -@Client.on_message((filters.text & filters.group & filters.incoming & ~filters.command(["start", "help", "about", "id", "settings", "fsub", "post", "delete", "del"])) | (filters.text & filters.private & filters.incoming & ~filters.command(["start", "help", "about", "id", "settings", "fsub", "post", "delete", "del"]))) +@Client.on_message(filters.group & filters.text & filters.incoming & ~filters.regex(r"^/") ) async def give_filter(client, message): - await auto_filter(client, message) - -async def auto_filter(client, message): - try: - if message.text.startswith("/"): - return - if re.findall(r"((^\/|^,|^!|^\.|^[\U0001F600-\U000E007F]).*)", message.text): - return - if len(message.text) < 2: - return - search = message.text.strip() - if len(search) > 100: - search = search[:100] - - files, offset, total_results = await get_search_results(search.lower(), offset=0, filter=True) - if not files: - files, offset, total_results = await get_search_results(search.lower(), offset=0, filter=False) - if not files: - logger.info(f"No files for {search}") - return - + if EMOJI_MODE: try: + await message.react(emoji=random.choice(REACTIONS), big=True) + except Exception: + await message.react(emoji="⚡") + pass + await mdb.update_top_messages(message.from_user.id, message.text) + if message.chat.id != SUPPORT_CHAT_ID: + settings = await get_settings(message.chat.id) + try: + if settings['auto_ffilter']: + if re.search(r'https?://\S+|www\.\S+|t\.me/\S+', message.text): + if await is_check_admin(client, message.chat.id, message.from_user.id): + return + return await message.delete() + await auto_filter(client, message) + except KeyError: + await save_group_settings(message.chat.id, 'auto_ffilter', True) settings = await get_settings(message.chat.id) - except: - settings = {'auto_delete': False} - - req = message.from_user.id if message.from_user else 0 - temp.GETALL[search] = files - - btn = [] - btn.append([ - InlineKeyboardButton("ǫᴜᴀʟɪᴛɪᴇs", callback_data=f"qualities#{search}#{req}"), - InlineKeyboardButton("ʟᴀɴɢᴜᴀɢᴇs", callback_data=f"languages#{search}#{req}"), - InlineKeyboardButton("sᴇᴀsᴏɴs", callback_data=f"seasons#{search}#{req}") - ]) - btn.append([InlineKeyboardButton("sᴇɴᴅ ᴀʟʟ ғɪʟᴇs", callback_data=f"sendall#{search}#{req}")]) - for file in files: - f_name = file.file_name - f_size = get_size(file.file_size) - file_id = file.file_id - btn.append([InlineKeyboardButton(f"[{f_size}] {f_name[:40]}", callback_data=f"file#{file_id}#{req}")]) - if offset != "": - btn.append([InlineKeyboardButton("ɴᴇxᴛ »", callback_data=f"next_{req}_{search}_{offset}")]) - else: - btn.append([InlineKeyboardButton("ɴᴏ ᴍᴏʀᴇ ᴘᴀɢᴇs", callback_data="pages")]) + if settings['auto_ffilter']: + await auto_filter(client, message) + except Exception as e: + logger.exception("Error in auto filter: %s", e) + pass + else: + search = message.text + _, _, total_results = await get_search_results(chat_id=message.chat.id, query=search.lower(), offset=0, filter=True) + if total_results == 0: + return + await message.reply_text( + script.ALREADY_AVAILABLE_TXT.format(message.from_user.mention, total_results, search), + reply_markup=InlineKeyboardMarkup( + [[InlineKeyboardButton("🔍 ᴊᴏɪɴ ᴀɴᴅ ꜱᴇᴀʀᴄʜ ʜᴇʀᴇ 🔎", url=GRP_LNK)]]) + ) +@Client.on_message(filters.private & filters.text & filters.incoming & ~filters.regex(r"^/") & ~filters.regex(r"(https?://)?(t\.me|telegram\.me|telegram\.dog)/")) +async def pm_text(bot, message): + bot_id = bot.me.id + content = message.text + user = message.from_user.first_name + user_id = message.from_user.id + if EMOJI_MODE: try: - pic_url = random.choice(PICS_URL) if PICS_URL else random.choice(PICS) - except: - try: - pic_url = random.choice(PICS) - except: - pic_url = None - - imdb = await get_poster(search, file=(files[0].file_name if files else None)) - if imdb and imdb.get('poster'): - try: - cap = script.IMDB_TEMPLATE.format( - qurey=search, - title=imdb.get('title'), - votes=imdb.get('votes'), - aka=imdb.get("aka"), - seasons=imdb.get("seasons"), - box_office=imdb.get('box_office'), - localized_title=imdb.get('localized_title'), - kind=imdb.get('kind'), - imdb_id=imdb.get("imdb_id"), - cast=imdb.get("cast"), - runtime=imdb.get("runtime"), - countries=imdb.get("countries"), - certificates=imdb.get("certificates"), - languages=imdb.get("languages"), - director=imdb.get("director"), - writer=imdb.get("writer"), - producer=imdb.get("producer"), - composer=imdb.get("composer"), - cinematographer=imdb.get("cinematographer"), - music_team=imdb.get("music_team"), - distributors=imdb.get("distributors"), - release_date=imdb.get('release_date'), - year=imdb.get('year'), - genres=imdb.get('genres'), - poster=imdb.get('poster'), - plot=imdb.get('plot'), - rating=imdb.get('rating'), - url=imdb.get('url'), - ) - except Exception as e: - logger.exception(e) - cap = f"Here is what I found for your query {search} :" + await message.react(emoji=random.choice(REACTIONS), big=True) + except Exception: + await message.react(emoji="⚡") + pass + if content.startswith(("#")): + return + try: + await mdb.update_top_messages(user_id, content) + pm_search = await db.pm_search_status(bot_id) + if pm_search: + await auto_filter(bot, message) else: - cap = f"Here is what I found for your query {search} :" - - try: - if pic_url: - sent = await message.reply_photo(photo=pic_url, caption=cap, reply_markup=InlineKeyboardMarkup(btn), parse_mode=enums.ParseMode.HTML) - else: - sent = await message.reply_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), parse_mode=enums.ParseMode.HTML) - try: - if settings.get('auto_delete'): - await asyncio.sleep(DELETE_TIME) - await sent.delete() - await message.delete() - except: - pass - except Exception as e: - logger.exception(f"send error: {e}") - except Exception as e: - logger.exception(f"auto_filter error for {message.text}: {e}") + await message.reply_text( + text=script.PM_SEARCH_DISABLED_TXT.format(user), + reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("📝 ʀᴇǫᴜᴇsᴛ ʜᴇʀᴇ ", url=GRP_LNK)]]) + ) + await bot.send_message( + chat_id=LOG_CHANNEL, + text=script.PM_LOG_TXT.format(user, user_id, content) + ) + except Exception: + pass -async def get_poster(query, bulk=False, id=False, file=None): - from utils import get_poster as _get_poster, get_posterx +@Client.on_callback_query(filters.regex(r"^reffff")) +async def refercall(bot, query): + btn = [[ + InlineKeyboardButton( + 'invite link', url=f'https://telegram.me/share/url?url=https://t.me/{bot.me.username}?start=reff_{query.from_user.id}&text=Hello%21%20Experience%20a%20bot%20that%20offers%20a%20vast%20library%20of%20unlimited%20movies%20and%20series.%20%F0%9F%98%83'), + InlineKeyboardButton( + f'⏳ {referdb.get_refer_points(query.from_user.id)}', callback_data='ref_point'), + InlineKeyboardButton('Back', callback_data='premium_info') + ]] + reply_markup = InlineKeyboardMarkup(btn) try: - return await _get_poster(query, bulk, id, file) - except: - try: - return await get_posterx(query, bulk, id, file) - except: - return None + await bot.edit_message_media( + query.message.chat.id, + query.message.id, + InputMediaPhoto("https://graph.org/file/1a2e64aee3d4d10edd930.jpg") + ) + except Exception: + pass + await query.message.edit_text( + text=script.REFER_TXT.format(bot.me.username, query.from_user.id), + reply_markup=reply_markup, + parse_mode=enums.ParseMode.HTML + ) + await query.answer() -@Client.on_callback_query(filters.regex(r"^next_")) +@Client.on_callback_query(filters.regex(r"^next")) async def next_page(bot, query): try: - _, req, key, offset = query.data.split("_") - req = int(req) - if req != 0 and query.from_user.id != req: - return await query.answer("This is not for you!", show_alert=True) - search = key + await query.answer() + except Exception: + pass + ident, req, key, offset = query.data.split("_") + curr_time = datetime.now(pytz.timezone('Asia/Kolkata')).time() + if int(req) not in [query.from_user.id, 0]: + return await query.answer(script.ALRT_TXT.format(query.from_user.first_name), show_alert=True) + try: offset = int(offset) - files, n_offset, total = await get_search_results(search.lower(), offset=offset, filter=True) - if not files: - return + except Exception: + offset = 0 + if BUTTONS.get(key) is not None: + search = BUTTONS.get(key) + else: + search = FRESH.get(key) + if not search: + await query.answer(script.OLD_ALRT_TXT.format(query.from_user.first_name), show_alert=True) + return + files, n_offset, total = await get_search_results(query.message.chat.id, search, offset=offset, filter=True) + try: + n_offset = int(n_offset) + except Exception: + n_offset = 0 + + if not files: + return + temp.GETALL[key] = files + temp.SHORT[query.from_user.id] = query.message.chat.id + settings = await get_settings(query.message.chat.id) + if settings.get('button'): + btn = [ + [ + InlineKeyboardButton(text=f"🔗 {get_size(file.file_size)} ≽ " + clean_filename( + file.file_name), callback_data=f'file#{file.file_id}'), + ] + for file in files + ] + btn.insert(0, + [ + InlineKeyboardButton( + 'Qᴜᴀʟɪᴛʏ', callback_data=f"qualities#{req}#{key}"), + InlineKeyboardButton( + "Lᴀɴɢᴜᴀɢᴇ", callback_data=f"languages#{req}#{key}"), + InlineKeyboardButton( + "Sᴇᴀsᴏɴ", callback_data=f"seasons#{req}#{key}") + ] + ) + btn.insert(0, + [ + InlineKeyboardButton( + "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), + InlineKeyboardButton( + "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) + + ] + ) + + else: btn = [] - btn.append([ - InlineKeyboardButton("ǫᴜᴀʟɪᴛɪᴇs", callback_data=f"qualities#{search}#{req}"), - InlineKeyboardButton("ʟᴀɴɢᴜᴀɢᴇs", callback_data=f"languages#{search}#{req}"), - InlineKeyboardButton("sᴇᴀsᴏɴs", callback_data=f"seasons#{search}#{req}") + btn.insert(0, + [ + InlineKeyboardButton( + 'Qᴜᴀʟɪᴛʏ', callback_data=f"qualities#{req}#{key}"), + InlineKeyboardButton( + "Lᴀɴɢᴜᴀɢᴇ", callback_data=f"languages#{req}#{key}"), + InlineKeyboardButton( + "Sᴇᴀsᴏɴ", callback_data=f"seasons#{req}#{key}") + ] + ) + btn.insert(0, [ + InlineKeyboardButton( + "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), + InlineKeyboardButton("Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) ]) - btn.append([InlineKeyboardButton("sᴇɴᴅ ᴀʟʟ ғɪʟᴇs", callback_data=f"sendall#{search}#{req}")]) - for file in files: - f_name = file.file_name - f_size = get_size(file.file_size) - file_id = file.file_id - btn.append([InlineKeyboardButton(f"[{f_size}] {f_name[:40]}", callback_data=f"file#{file_id}#{req}")]) - if n_offset != "": - btn.append([ - InlineKeyboardButton("« ʙᴀᴄᴋ", callback_data=f"next_{req}_{search}_{offset-10}" if offset-10 >=0 else f"next_{req}_{search}_0"), - InlineKeyboardButton(f"{math.ceil(offset/10)+1}/{math.ceil(total/10)}", callback_data="pages"), - InlineKeyboardButton("ɴᴇxᴛ »", callback_data=f"next_{req}_{search}_{n_offset}") - ]) + if ULTRA_FAST_MODE: + if 0 < offset <= 10: + off_set = 0 + elif offset == 0: + off_set = None else: - btn.append([ - InlineKeyboardButton("« ʙᴀᴄᴋ", callback_data=f"next_{req}_{search}_{offset-10}"), - InlineKeyboardButton(f"{math.ceil(offset/10)+1}/{math.ceil(total/10)}", callback_data="pages") - ]) + off_set = offset - 10 + if n_offset == 0: + btn.append( + [InlineKeyboardButton("⋞ ʙᴀᴄᴋ", callback_data=f"next_{req}_{key}_{off_set}"), InlineKeyboardButton(f"{math.ceil(int(offset)/10)+1}", callback_data="pages")] + ) + elif off_set is None: + btn.append([InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton(f"{math.ceil(int(offset)/10)+1}", callback_data="pages"), InlineKeyboardButton("ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}")]) + else: + btn.append( + [ + InlineKeyboardButton("⋞ ʙᴀᴄᴋ", callback_data=f"next_{req}_{key}_{off_set}"), + InlineKeyboardButton(f"{math.ceil(int(offset)/10)+1}", callback_data="pages"), + InlineKeyboardButton("ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}") + ], + ) + else: + try: + if settings['max_btn']: + if 0 < offset <= 10: + off_set = 0 + elif offset == 0: + off_set = None + else: + off_set = offset - 10 + if n_offset == 0: + btn.append([InlineKeyboardButton("⋞ ʙᴀᴄᴋ", callback_data=f"next_{req}_{key}_{off_set}"), InlineKeyboardButton( + f"{math.ceil(int(offset)/10)+1} / {math.ceil(total/10)}", callback_data="pages")]) + elif off_set is None: + btn.append([InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( + f"{math.ceil(int(offset)/10)+1} / {math.ceil(total/10)}", callback_data="pages"), InlineKeyboardButton("ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}")]) + else: + btn.append( + [ + InlineKeyboardButton( + "⋞ ʙᴀᴄᴋ", callback_data=f"next_{req}_{key}_{off_set}"), + InlineKeyboardButton( + f"{math.ceil(int(offset)/10)+1} / {math.ceil(total/10)}", callback_data="pages"), + InlineKeyboardButton( + "ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}") + ], + ) + else: + if 0 < offset <= int(MAX_B_TN): + off_set = 0 + elif offset == 0: + off_set = None + else: + off_set = offset - int(MAX_B_TN) + if n_offset == 0: + btn.append([InlineKeyboardButton("⋞ ʙᴀᴄᴋ", callback_data=f"next_{req}_{key}_{off_set}"), InlineKeyboardButton( + f"{math.ceil(int(offset)/int(MAX_B_TN))+1} / {math.ceil(total/int(MAX_B_TN))}", callback_data="pages")]) + elif off_set is None: + btn.append([InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( + f"{math.ceil(int(offset)/int(MAX_B_TN))+1} / {math.ceil(total/int(MAX_B_TN))}", callback_data="pages"), InlineKeyboardButton("ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}")]) + else: + btn.append( + [ + InlineKeyboardButton( + "⋞ ʙᴀᴄᴋ", callback_data=f"next_{req}_{key}_{off_set}"), + InlineKeyboardButton( + f"{math.ceil(int(offset)/int(MAX_B_TN))+1} / {math.ceil(total/int(MAX_B_TN))}", callback_data="pages"), + InlineKeyboardButton( + "ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}") + ], + ) + except KeyError: + await save_group_settings(query.message.chat.id, 'max_btn', True) + if 0 < offset <= 10: + off_set = 0 + elif offset == 0: + off_set = None + else: + off_set = offset - 10 + if n_offset == 0: + btn.append( + [InlineKeyboardButton("⋞ ʙᴀᴄᴋ", callback_data=f"next_{req}_{key}_{off_set}"), InlineKeyboardButton( + f"{math.ceil(int(offset)/10)+1} / {math.ceil(total/10)}", callback_data="pages")] + ) + elif off_set is None: + btn.append([InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( + f"{math.ceil(int(offset)/10)+1} / {math.ceil(total/10)}", callback_data="pages"), InlineKeyboardButton("ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}")]) + else: + btn.append( + [ + InlineKeyboardButton( + "⋞ ʙᴀᴄᴋ", callback_data=f"next_{req}_{key}_{off_set}"), + InlineKeyboardButton( + f"{math.ceil(int(offset)/10)+1} / {math.ceil(total/10)}", callback_data="pages"), + InlineKeyboardButton( + "ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}") + ], + ) + if not settings["button"]: + cur_time = datetime.now(pytz.timezone('Asia/Kolkata')).time() + time_difference = timedelta(hours=cur_time.hour, minutes=cur_time.minute, seconds=(cur_time.second+(cur_time.microsecond/1000000))) - \ + timedelta(hours=curr_time.hour, minutes=curr_time.minute, seconds=( + curr_time.second+(curr_time.microsecond/1000000))) + remaining_seconds = "{:.2f}".format(time_difference.total_seconds()) + dreamx_title = clean_search_text(search) + cap = None + try: + if settings['imdb']: + cap = await get_cap(settings, remaining_seconds, files, query, total, dreamx_title, offset) + if query.message.caption: + try: + await query.message.edit_caption(caption=cap, reply_markup=InlineKeyboardMarkup(btn), parse_mode=enums.ParseMode.HTML) + except (MessageNotModified, MessageIdInvalid): + pass + except Exception as e: + logger.exception(e) + else: + try: + await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) + except (MessageNotModified, MessageIdInvalid): + pass + else: + cap = await get_cap(settings, remaining_seconds, files, query, total, dreamx_title, offset+1) + await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) + except (MessageNotModified, MessageIdInvalid): + pass + except Exception as e: + logger.exception("Failed to send result: %s", e) + else: try: await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) - except MessageNotModified: + except (MessageNotModified, MessageIdInvalid): pass - await query.answer() - except Exception as e: - logger.exception(e) + await query.answer() + +@Client.on_callback_query(filters.regex(r"^spol")) +async def advantage_spoll_choker(bot, query): + _, id, user = query.data.split('#') + if int(user) != 0 and query.from_user.id != int(user): + return await query.answer(script.ALRT_TXT.format(query.from_user.first_name), show_alert=True) + movies = await get_posterx(id, id=True) if TMDB_ON_SEARCH else await get_poster(id, id=True) + movie = movies.get('title') + movie = re.sub(r"[:-]", " ", movie) + movie = re.sub(r"\s+", " ", movie).strip() + await query.answer(script.TOP_ALRT_MSG) + files, offset, total_results = await get_search_results(query.message.chat.id, movie, offset=0, filter=True) + if files: + k = (movie, files, offset, total_results) + await auto_filter(bot, query, k) + else: + reqstr1 = query.from_user.id if query.from_user else 0 + reqstr = await bot.get_users(reqstr1) + if NO_RESULTS_MSG: + try: + await bot.send_message(chat_id=BIN_CHANNEL, text=script.NORSLTS.format(reqstr.id, reqstr.mention, movie)) + except Exception as e: + logger.error("Error In Spol: %s — Make Sure Bot Admin BIN CHANNEL", e) + btn = InlineKeyboardMarkup( + [[InlineKeyboardButton("🔰Cʟɪᴄᴋ ʜᴇʀᴇ & ʀᴇǫᴜᴇsᴛ ᴛᴏ ᴀᴅᴍɪɴ🔰", url=OWNER_LNK)]]) + k = await query.message.edit(script.MVE_NT_FND, reply_markup=btn) + await asyncio.sleep(10) + await k.delete() +# Qualities @Client.on_callback_query(filters.regex(r"^qualities#")) -async def qualities_cb(bot, query): +async def qualities_cb_handler(client: Client, query: CallbackQuery): + _, req, key = query.data.split("#") try: - _, key, req = query.data.split("#") - req = int(req) - if req != 0 and query.from_user.id != req: - return await query.answer("This is not for you!", show_alert=True) - btn = [] - for qual in QUALITIES: - btn.append([InlineKeyboardButton(qual, callback_data=f"q_filter#{qual}#{key}#{req}")]) - btn.append([InlineKeyboardButton("⇋ ʙᴀᴄᴋ ⇋", callback_data=f"filter_back#{key}#{req}")]) - await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) - await query.answer() - except Exception as e: - logger.exception(e) + if int(req) not in [query.from_user.id, 0]: + return await query.answer( + f"⚠ ʜᴇʟʟᴏ {query.from_user.first_name},\n" + f"ᴛʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ,\nʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀ'ꜱ...", + show_alert=True, + ) + except Exception: + pass -@Client.on_callback_query(filters.regex(r"^languages#")) -async def languages_cb(bot, query): - try: - _, key, req = query.data.split("#") - req = int(req) - if req != 0 and query.from_user.id != req: - return await query.answer("This is not for you!", show_alert=True) - btn = [] - for lang in LANGUAGES: - btn.append([InlineKeyboardButton(lang, callback_data=f"l_filter#{lang}#{key}#{req}")]) - btn.append([InlineKeyboardButton("⇋ ʙᴀᴄᴋ ⇋", callback_data=f"filter_back#{key}#{req}")]) - await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) - await query.answer() - except Exception as e: - logger.exception(e) + search = FRESH.get(key) + search = search.replace(' ', '_') -@Client.on_callback_query(filters.regex(r"^seasons#")) -async def seasons_cb(bot, query): - try: - _, key, req = query.data.split("#") - req = int(req) - if req != 0 and query.from_user.id != req: - return await query.answer("This is not for you!", show_alert=True) - btn = [] - for seas in SEASONS: - btn.append([InlineKeyboardButton(seas, callback_data=f"s_filter#{seas}#{key}#{req}")]) - btn.append([InlineKeyboardButton("⇋ ʙᴀᴄᴋ ⇋", callback_data=f"filter_back#{key}#{req}")]) - await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) - await query.answer() - except Exception as e: - logger.exception(e) + btn = [] + for i in range(0, len(QUALITIES), 2): + q1 = QUALITIES[i] + row = [InlineKeyboardButton( + text=q1, callback_data=f"fq#{q1.lower()}#{req}#{key}")] + if i + 1 < len(QUALITIES): + q2 = QUALITIES[i + 1] + row.append(InlineKeyboardButton( + text=q2, callback_data=f"fq#{q2.lower()}#{req}#{key}")) + btn.append(row) -@Client.on_callback_query(filters.regex(r"^q_filter#")) -async def q_filter_cb(bot, query): + btn.insert(0, [ + InlineKeyboardButton(text="⇊ ꜱᴇʟᴇᴄᴛ ǫᴜᴀʟɪᴛʏ ⇊", callback_data="ident") + ]) + btn.append([ + InlineKeyboardButton(text="↭ ʙᴀᴄᴋ ᴛᴏ ꜰɪʟᴇs ↭", + callback_data=f"fq#homepage#{req}#{key}") + ]) + + await query.edit_message_reply_markup(InlineKeyboardMarkup(btn)) + +@Client.on_callback_query(filters.regex(r"^fq#")) +async def filter_qualities_cb_handler(client: Client, query: CallbackQuery): + _, qual, req, key = query.data.split("#") + curr_time = datetime.now(pytz.timezone('Asia/Kolkata')).time() + search = FRESH.get(key) + search = search.replace("_", " ") + baal = qual in search + if baal: + search = search.replace(qual, "") + else: + search = search + chat_id = query.message.chat.id + message = query.message try: - _, qual, key, req = query.data.split("#") - req = int(req) - if req != 0 and query.from_user.id != req: - return await query.answer("This is not for you!", show_alert=True) - files = temp.GETALL.get(key) - if not files: - return await query.answer("No files found!", show_alert=True) - filtered = [f for f in files if qual.lower() in f.file_name.lower()] - if not filtered: - return await query.answer(f"No files found for quality {qual}", show_alert=True) + if int(req) not in [query.from_user.id, 0]: + return await query.answer(f"⚠ ʜᴇʟʟᴏ {query.from_user.first_name},\nᴛʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ,\nʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀ'ꜱ...", show_alert=True,) + except Exception: + pass + if qual != "homepage": + search = f"{search} {qual}" + BUTTONS[key] = search + files, offset, total_results = await get_search_results(chat_id, search, offset=0, filter=True) + if not files: + await query.answer("🚫 ɴᴏ ꜰɪʟᴇꜱ ᴡᴇʀᴇ ꜰᴏᴜɴᴅ 🚫", show_alert=1) + return + temp.GETALL[key] = files + settings = await get_settings(message.chat.id) + if settings.get('button'): + btn = [ + [ + InlineKeyboardButton(text=f"🔗 {get_size(file.file_size)} ≽ " + clean_filename( + file.file_name), callback_data=f'file#{file.file_id}'), + ] + for file in files + ] + btn.insert(0, + [ + InlineKeyboardButton( + 'Qᴜᴀʟɪᴛʏ', callback_data=f"qualities#{req}#{key}"), + InlineKeyboardButton( + "Lᴀɴɢᴜᴀɢᴇ", callback_data=f"languages#{req}#{key}"), + InlineKeyboardButton( + "Sᴇᴀsᴏɴ", callback_data=f"seasons#{req}#{key}") + ] + ) + btn.insert(0, + [ + InlineKeyboardButton( + "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), + InlineKeyboardButton( + "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) + ]) + else: btn = [] - btn.append([InlineKeyboardButton(f"Filtered by {qual}", callback_data="pages")]) - for file in filtered[:10]: - f_name = file.file_name - f_size = get_size(file.file_size) - file_id = file.file_id - btn.append([InlineKeyboardButton(f"[{f_size}] {f_name[:40]}", callback_data=f"file#{file_id}#{req}")]) - btn.append([InlineKeyboardButton("⇋ ʙᴀᴄᴋ ⇋", callback_data=f"filter_back#{key}#{req}")]) - await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) - await query.answer() - except Exception as e: - logger.exception(e) + btn.insert(0, + [ + InlineKeyboardButton( + 'Qᴜᴀʟɪᴛʏ', callback_data=f"qualities#{req}#{key}"), + InlineKeyboardButton( + "Lᴀɴɢᴜᴀɢᴇ", callback_data=f"languages#{req}#{key}"), + InlineKeyboardButton( + "Sᴇᴀsᴏɴ", callback_data=f"seasons#{req}#{key}") + ] + ) + btn.insert(0, + [ + InlineKeyboardButton( + "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), + InlineKeyboardButton( + "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) + + ]) + if offset != "": + try: + if settings['max_btn']: + btn.append( + + [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( + text=f"1/{math.ceil(int(total_results)/10)}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}")] + ) + else: + btn.append( -@Client.on_callback_query(filters.regex(r"^l_filter#")) -async def l_filter_cb(bot, query): + [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( + text=f"1/{math.ceil(int(total_results)/int(MAX_B_TN))}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}")] + ) + except KeyError: + await save_group_settings(query.message.chat.id, 'max_btn', True) + btn.append( + + [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( + text=f"1/{math.ceil(int(total_results)/10)}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}")] + ) + else: + btn.append( + + [InlineKeyboardButton( + text="↭ ɴᴏ ᴍᴏʀᴇ ᴘᴀɢᴇꜱ ᴀᴠᴀɪʟᴀʙʟᴇ ↭", callback_data="pages")] + ) + if not settings["button"]: + cur_time = datetime.now(pytz.timezone('Asia/Kolkata')).time() + time_difference = timedelta(hours=cur_time.hour, minutes=cur_time.minute, seconds=(cur_time.second+(cur_time.microsecond/1000000))) - \ + timedelta(hours=curr_time.hour, minutes=curr_time.minute, seconds=( + curr_time.second+(curr_time.microsecond/1000000))) + remaining_seconds = "{:.2f}".format(time_difference.total_seconds()) + dreamx_title = clean_search_text(search) + cap = await get_cap(settings, remaining_seconds, files, query, total_results, dreamx_title, offset=1) + try: + await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) + except (MessageNotModified, MessageIdInvalid): + pass + else: + try: + await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) + except (MessageNotModified, MessageIdInvalid): + pass + await query.answer() + +# languages +@Client.on_callback_query(filters.regex(r"^languages#")) +async def languages_cb_handler(client: Client, query: CallbackQuery): + _, req, key = query.data.split("#") try: - _, lang, key, req = query.data.split("#") - req = int(req) - if req != 0 and query.from_user.id != req: - return await query.answer("This is not for you!", show_alert=True) - files = temp.GETALL.get(key) - if not files: - return await query.answer("No files found!", show_alert=True) - filtered = [f for f in files if lang.lower() in f.file_name.lower()] - if not filtered: - return await query.answer(f"No files found for language {lang}", show_alert=True) - btn = [] - btn.append([InlineKeyboardButton(f"Filtered by {lang}", callback_data="pages")]) - for file in filtered[:10]: - f_name = file.file_name - f_size = get_size(file.file_size) - file_id = file.file_id - btn.append([InlineKeyboardButton(f"[{f_size}] {f_name[:40]}", callback_data=f"file#{file_id}#{req}")]) - btn.append([InlineKeyboardButton("⇋ ʙᴀᴄᴋ ⇋", callback_data=f"filter_back#{key}#{req}")]) - await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) - await query.answer() - except Exception as e: - logger.exception(e) + if int(req) not in [query.from_user.id, 0]: + return await query.answer( + f"⚠ ʜᴇʟʟᴏ {query.from_user.first_name},\n" + f"ᴛʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ,\nʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀ'ꜱ...", + show_alert=True, + ) + except Exception: + pass + + search = FRESH.get(key) + search = search.replace(' ', '_') + + items = list(LANGUAGES.items()) + btn = [] + + for i in range(0, len(items), 2): + name1, code1 = items[i] + row = [InlineKeyboardButton( + text=name1, callback_data=f"fl#{code1}#{req}#{key}")] + if i + 1 < len(items): + name2, code2 = items[i + 1] + row.append(InlineKeyboardButton( + text=name2, callback_data=f"fl#{code2}#{req}#{key}")) + btn.append(row) + + btn.insert(0, [InlineKeyboardButton( + text="⇊ ꜱᴇʟᴇᴄᴛ ʟᴀɴɢᴜᴀɢᴇ ⇊", callback_data="ident")]) + btn.append([InlineKeyboardButton(text="↭ ʙᴀᴄᴋ ᴛᴏ ꜰɪʟᴇs ↭", + callback_data=f"fl#homepage#{req}#{key}")]) + + await query.edit_message_reply_markup(InlineKeyboardMarkup(btn)) -@Client.on_callback_query(filters.regex(r"^s_filter#")) -async def s_filter_cb(bot, query): +@Client.on_callback_query(filters.regex(r"^fl#")) +async def filter_languages_cb_handler(client: Client, query: CallbackQuery): + _, lang, req, key = query.data.split("#") + curr_time = datetime.now(pytz.timezone('Asia/Kolkata')).time() + search = FRESH.get(key) + search = search.replace("_", " ") + baal = lang in search + if baal: + search = search.replace(lang, "") + else: + search = search + chat_id = query.message.chat.id + message = query.message try: - _, seas, key, req = query.data.split("#") - req = int(req) - if req != 0 and query.from_user.id != req: - return await query.answer("This is not for you!", show_alert=True) - files = temp.GETALL.get(key) - if not files: - return await query.answer("No files found!", show_alert=True) - filtered = [f for f in files if seas.lower() in f.file_name.lower()] - if not filtered: - num = ''.join(filter(str.isdigit, seas)) - if num: - filtered = [f for f in files if f"S{int(num):02d}" in f.file_name or f"S{num}" in f.file_name] - if not filtered: - return await query.answer(f"No files found for {seas}", show_alert=True) + if int(req) not in [query.from_user.id, 0]: + return await query.answer(f"⚠ ʜᴇʟʟᴏ {query.from_user.first_name},\nᴛʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ,\nʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀ'ꜱ...", show_alert=True,) + except Exception: + pass + if lang != "homepage": + search = f"{search} {lang}" + BUTTONS[key] = search + files, offset, total_results = await get_search_results(chat_id, search, offset=0, filter=True) + if not files: + await query.answer("🚫 ɴᴏ ꜰɪʟᴇꜱ ᴡᴇʀᴇ ꜰᴏᴜɴᴅ 🚫", show_alert=1) + return + temp.GETALL[key] = files + settings = await get_settings(message.chat.id) + if settings.get('button'): + btn = [ + [ + InlineKeyboardButton(text=f"🔗 {get_size(file.file_size)} ≽ " + clean_filename( + file.file_name), callback_data=f'file#{file.file_id}'), + ] + for file in files + ] + btn.insert(0, + [ + InlineKeyboardButton( + 'Qᴜᴀʟɪᴛʏ', callback_data=f"qualities#{req}#{key}"), + InlineKeyboardButton( + "Lᴀɴɢᴜᴀɢᴇ", callback_data=f"languages#{req}#{key}"), + InlineKeyboardButton( + "Sᴇᴀsᴏɴ", callback_data=f"seasons#{req}#{key}") + ] + ) + btn.insert(0, + [ + InlineKeyboardButton( + "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), + InlineKeyboardButton( + "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) + ] + ) + else: btn = [] - btn.append([InlineKeyboardButton(f"Filtered by {seas}", callback_data="pages")]) - for file in filtered[:10]: - f_name = file.file_name - f_size = get_size(file.file_size) - file_id = file.file_id - btn.append([InlineKeyboardButton(f"[{f_size}] {f_name[:40]}", callback_data=f"file#{file_id}#{req}")]) - btn.append([InlineKeyboardButton("⇋ ʙᴀᴄᴋ ⇋", callback_data=f"filter_back#{key}#{req}")]) - await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) - await query.answer() - except Exception as e: - logger.exception(e) + btn.insert(0, + [ + InlineKeyboardButton( + 'Qᴜᴀʟɪᴛʏ', callback_data=f"qualities#{req}#{key}"), + InlineKeyboardButton( + "Lᴀɴɢᴜᴀɢᴇ", callback_data=f"languages#{req}#{key}"), + InlineKeyboardButton( + "Sᴇᴀsᴏɴ", callback_data=f"seasons#{req}#{key}") + ]) + btn.insert(0, + [ + InlineKeyboardButton( + "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), + InlineKeyboardButton( + "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) + ]) + if offset != "": + try: + if settings['max_btn']: + btn.append( + [ + InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( + text=f"1/{math.ceil(int(total_results)/10)}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}") + ]) + else: + btn.append( + [ + InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( + text=f"1/{math.ceil(int(total_results)/int(MAX_B_TN))}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}") + ]) + except KeyError: + await save_group_settings(query.message.chat.id, 'max_btn', True) + btn.append( + [ + InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( + text=f"1/{math.ceil(int(total_results)/10)}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}") + ]) + else: + btn.append([InlineKeyboardButton( + text="↭ ɴᴏ ᴍᴏʀᴇ ᴘᴀɢᴇꜱ ᴀᴠᴀɪʟᴀʙʟᴇ ↭", callback_data="pages")]) + if not settings["button"]: + cur_time = datetime.now(pytz.timezone('Asia/Kolkata')).time() + time_difference = timedelta(hours=cur_time.hour, minutes=cur_time.minute, seconds=(cur_time.second+(cur_time.microsecond/1000000))) - \ + timedelta(hours=cur_time.hour, minutes=cur_time.minute, seconds=( + curr_time.second+(curr_time.microsecond/1000000))) + remaining_seconds = "{:.2f}".format(time_difference.total_seconds()) + dreamx_title = clean_search_text(search) + cap = await get_cap(settings, remaining_seconds, files, query, total_results, dreamx_title, offset=1) + try: + await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) + except (MessageNotModified, MessageIdInvalid): + pass + else: + try: + await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) + except (MessageNotModified, MessageIdInvalid): + pass + await query.answer() -@Client.on_callback_query(filters.regex(r"^filter_back#")) -async def filter_back_cb(bot, query): +@Client.on_callback_query(filters.regex(r"^seasons#")) +async def seasons_cb_handler(client: Client, query: CallbackQuery): + _, req, key = query.data.split("#") try: - _, key, req = query.data.split("#") - req = int(req) - if req != 0 and query.from_user.id != req: - return await query.answer("This is not for you!", show_alert=True) - files = temp.GETALL.get(key, []) - btn = [] + if int(req) not in [query.from_user.id, 0]: + return await query.answer( + f"⚠ ʜᴇʟʟᴏ {query.from_user.first_name},\nᴛʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ,\nʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀ'ꜱ...", + show_alert=True, + ) + except Exception: + pass + offset = 0 + btn: list[list[InlineKeyboardButton]] = [] + for i in range(0, len(SEASONS) - 1, 2): btn.append([ - InlineKeyboardButton("ǫᴜᴀʟɪᴛɪᴇs", callback_data=f"qualities#{key}#{req}"), - InlineKeyboardButton("ʟᴀɴɢᴜᴀɢᴇs", callback_data=f"languages#{key}#{req}"), - InlineKeyboardButton("sᴇᴀsᴏɴs", callback_data=f"seasons#{key}#{req}") + InlineKeyboardButton( + f"Sᴇᴀꜱᴏɴ {SEASONS[i][1:]}", callback_data=f"fs#{SEASONS[i].lower()}#{req}#{key}"), + InlineKeyboardButton( + f"Sᴇᴀꜱᴏɴ {SEASONS[i+1][1:]}", callback_data=f"fs#{SEASONS[i+1].lower()}#{req}#{key}") ]) - btn.append([InlineKeyboardButton("sᴇɴᴅ ᴀʟʟ ғɪʟᴇs", callback_data=f"sendall#{key}#{req}")]) - for file in files[:10]: - f_name = file.file_name - f_size = get_size(file.file_size) - file_id = file.file_id - btn.append([InlineKeyboardButton(f"[{f_size}] {f_name[:40]}", callback_data=f"file#{file_id}#{req}")]) - await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) - await query.answer() - except Exception as e: - logger.exception(e) -@Client.on_callback_query(filters.regex(r"^file#")) -async def file_cb(bot, query): + btn.insert( + 0, + [InlineKeyboardButton("⇊ ꜱᴇʟᴇᴄᴛ ꜱᴇᴀꜱᴏɴ ⇊", callback_data="ident")], + ) + btn.append([InlineKeyboardButton(text="↭ ʙᴀᴄᴋ ᴛᴏ ꜰɪʟᴇs ↭", + callback_data=f"next_{req}_{key}_{offset}")]) + await query.edit_message_reply_markup(InlineKeyboardMarkup(btn)) + await query.answer() + +@Client.on_callback_query(filters.regex(r"^fs#")) +async def filter_seasons_cb_handler(client: Client, query: CallbackQuery): + _, season_tag, req, key = query.data.split("#") + search = FRESH.get(key).replace("_", " ") + season_tag = season_tag.lower() + if season_tag == "homepage": + search_final = search + query_input = search_final + else: + season_number = int(season_tag[1:]) + query_input = generate_season_variations(search, season_number) + search_final = query_input[0] if query_input else search + + BUTTONS[key] = search_final try: - _, file_id, req = query.data.split("#") - files_ = await get_file_details(file_id) - if not files_: - return await query.answer("No such file exist.", show_alert=True) + if int(req) not in [query.from_user.id, 0]: + return await query.answer("⚠ Not your request", show_alert=True) + except Exception: + pass + + chat_id = query.message.chat.id + files, n_offset, total_results = await get_search_results(chat_id, query_input, offset=0, filter=True) + if not files: + BUTTONS[key] = None + return await query.answer("🚫 ɴᴏ ꜰɪʟᴇꜱ ꜰᴏᴜɴᴅ 🚫", show_alert=True) + + temp.GETALL[key] = files + settings = await get_settings(chat_id) + btn: list[list[InlineKeyboardButton]] = [] + if settings.get("button"): + btn.extend( + [ + [ + InlineKeyboardButton( + f"🔗 {get_size(f.file_size)} ≽ " + + clean_filename(f.file_name), + callback_data=f"file#{f.file_id}", + ) + ] + for f in files + ] + ) + btn.insert( + 0, + [ + InlineKeyboardButton("Qᴜᴀʟɪᴛʏ", callback_data=f"qualities#{req}#{key}"), + InlineKeyboardButton("Lᴀɴɢᴜᴀɢᴇ", callback_data=f"languages#{req}#{key}"), + InlineKeyboardButton("Sᴇᴀsᴏɴ", callback_data=f"seasons#{req}#{key}"), + ], + ) + btn.insert( + 0, + [ + InlineKeyboardButton( + "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), + InlineKeyboardButton("Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS), + ], + ) + if n_offset != "": try: - await bot.send_cached_media(chat_id=query.from_user.id, file_id=file_id, caption=files_.file_name) - await query.answer("Check PM, I have sent files in PM", show_alert=False) - except Exception: - await query.answer("Failed to send in PM, make sure you started me in PM", show_alert=True) - except Exception as e: - logger.exception(e) + if settings['max_btn']: + btn.append( + [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( + text=f"1/{math.ceil(int(total_results)/10)}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}")] + ) -@Client.on_callback_query(filters.regex(r"^about")) -async def about_cb(bot, query): + else: + btn.append( + [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( + text=f"1/{math.ceil(int(total_results)/int(MAX_B_TN))}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}")] + ) + except KeyError: + await save_group_settings(query.message.chat.id, 'max_btn', True) + btn.append( + [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( + text=f"1/{math.ceil(int(total_results)/10)}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{n_offset}")] + ) + else: + n_offset = 0 + btn.append( + [InlineKeyboardButton( + "↭ ɴᴏ ᴍᴏʀᴇ ᴘᴀɢᴇꜱ ᴀᴠᴀɪʟᴀʙʟᴇ ↭", callback_data="pages")] + ) + if not settings.get("button"): + curr_time = datetime.now(pytz.timezone("Asia/Kolkata")).time() + time_difference = timedelta( + hours=curr_time.hour, + minutes=curr_time.minute, + seconds=curr_time.second + curr_time.microsecond / 1_000_000, + ) + remaining_seconds = f"{time_difference.total_seconds():.2f}" + dreamx_title = clean_search_text(search_final) + cap = await get_cap(settings, remaining_seconds, files, query, total_results, dreamx_title, offset=1) + try: + await query.message.edit_text( + text=cap, + reply_markup=InlineKeyboardMarkup(btn), + disable_web_page_preview=True, + ) + except (MessageNotModified, MessageIdInvalid): + pass + else: + try: + await query.edit_message_reply_markup(InlineKeyboardMarkup(btn)) + except (MessageNotModified, MessageIdInvalid): + pass + await query.answer() + +@Client.on_callback_query(group=10) +async def cb_handler(client: Client, query: CallbackQuery): + DreamxData = query.data try: - await query.answer() - except: + await client.create_chat_invite_link(int(REQST_CHANNEL)) + except Exception: pass - try: - b_name = getattr(temp, 'B_NAME', 'Boultflix') or 'Boultflix' - u_name = getattr(temp, 'U_NAME', 'Boultflix') or 'Boultflix' - about_text = script.ABOUT_TXT - # fix bracket issue - replace {} with actual names - try: - about_text = about_text.format(b_name, u_name) - except: - about_text = about_text.replace("{}", b_name).replace("{0}", b_name).replace("{1}", u_name).replace("{2}", b_name) - await query.message.edit_text( - text=about_text, + if query.data == "close_data": + try: + user = query.message.reply_to_message.from_user.id + except Exception: + user = query.from_user.id + if int(user) != 0 and query.from_user.id != int(user): + return await query.answer(script.NT_ALRT_TXT, show_alert=True) + await query.answer("ᴛʜᴀɴᴋs ꜰᴏʀ ᴄʟᴏsᴇ 🙈") + await query.message.delete() + try: + await query.message.reply_to_message.delete() + except Exception: + pass + + elif query.data == "pages": + await query.answer("ᴛʜɪs ɪs ᴘᴀɢᴇs ʙᴜᴛᴛᴏɴ 😅") + + if query.data.startswith("file"): + ident, file_id = query.data.split("#") + user = query.message.reply_to_message.from_user.id if query.message.reply_to_message else query.from_user.id + if int(user) != 0 and query.from_user.id != int(user): + return await query.answer(script.ALRT_TXT.format(query.from_user.first_name), show_alert=True) + await query.answer(url=f"https://t.me/{temp.U_NAME}?start=file_{query.message.chat.id}_{file_id}") + + elif query.data.startswith("sendfiles"): + ident, key = query.data.split("#") + settings = await get_settings(query.message.chat.id) + try: + await query.answer(url=f"https://telegram.me/{temp.U_NAME}?start=allfiles_{query.message.chat.id}_{key}") + return + except UserIsBlocked: + await query.answer('Uɴʙʟᴏᴄᴋ ᴛʜᴇ ʙᴏᴛ ᴍᴀʜɴ !', show_alert=True) + except PeerIdInvalid: + await query.answer(url=f"https://telegram.me/{temp.U_NAME}?start=sendfiles3_{key}") + except Exception as e: + logger.exception(e) + await query.answer(url=f"https://telegram.me/{temp.U_NAME}?start=sendfiles4_{key}") + + elif query.data.startswith("autofilter_delete"): + await Media.collection.drop() + if MULTIPLE_DB: + await Media2.collection.drop() + await query.answer("Eᴠᴇʀʏᴛʜɪɴɢ's Gᴏɴᴇ") + await query.message.edit('ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ᴀʟʟ ɪɴᴅᴇxᴇᴅ ꜰɪʟᴇꜱ ✅') + + elif query.data.startswith("checksub"): + try: + ident, kk, file_id = query.data.split("#") + btn = [] + chat = file_id.split("_")[0] + settings = await get_settings(chat) + fsub_channels = list(dict.fromkeys((settings.get('fsub', []) if settings else [])+ AUTH_CHANNELS)) + btn += await is_subscribed(client, query.from_user.id, fsub_channels) + btn += await is_req_subscribed(client, query.from_user.id, AUTH_REQ_CHANNELS) + if btn: + btn.append([InlineKeyboardButton("♻ ᴛʀʏ ᴀɢᴀɪɴ ♻", callback_data=f"checksub#{kk}#{file_id}")]) + try: + await query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(btn)) + except (MessageNotModified, MessageIdInvalid): + pass + await query.answer( + f"👋 Hello {query.from_user.first_name},\n\n" + "🛑 Yᴏᴜ ʜᴀᴠᴇ ɴᴏᴛ ᴊᴏɪɴᴇᴅ ᴀʟʟ ʀᴇǫᴜɪʀᴇᴅ ᴜᴘᴅᴀᴛᴇ Cʜᴀɴɴᴇʟs.\n" + "👉 Pʟᴇᴀsᴇ ᴊᴏɪɴ ᴇᴀᴄʜ ᴏɴᴇ ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ.\n", + show_alert=True + ) + return + await query.answer(url=f"https://t.me/{temp.U_NAME}?start={kk}_{file_id}") + if query.message.chat.type == enums.ChatType.PRIVATE: + try: + await query.message.delete() + except MessageDeleteForbidden: + pass + except Exception as e: + await log_error(client, f"❌ Error in checksub callback:\n\n{repr(e)}") + logger.error(f"❌ Error in checksub callback:\n\n{repr(e)}") + + elif query.data.startswith("killfilesdq"): + ident, keyword = query.data.split("#") + await query.message.edit_text(f"Fetching Files for your query {keyword} on DB... Please wait...") + files, total = await get_bad_files(keyword) + await query.message.edit_text("ꜰɪʟᴇ ᴅᴇʟᴇᴛɪᴏɴ ᴘʀᴏᴄᴇꜱꜱ ᴡɪʟʟ ꜱᴛᴀʀᴛ ɪɴ 5 ꜱᴇᴄᴏɴᴅꜱ !") + await asyncio.sleep(5) + deleted = 0 + async with lock: + try: + for file in files: + file_ids = file.file_id + file_name = file.file_name + result = await Media.collection.delete_one({ + '_id': file_ids, + }) + if not result.deleted_count and MULTIPLE_DB: + result = await Media2.collection.delete_one({ + '_id': file_ids, + }) + if result.deleted_count: + logger.info( + f'ꜰɪʟᴇ ꜰᴏᴜɴᴅ ꜰᴏʀ ʏᴏᴜʀ ǫᴜᴇʀʏ {keyword}! ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ {file_name} ꜰʀᴏᴍ ᴅᴀᴛᴀʙᴀꜱᴇ.') + deleted += 1 + if deleted % 20 == 0: + await query.message.edit_text(f"ᴘʀᴏᴄᴇꜱꜱ ꜱᴛᴀʀᴛᴇᴅ ꜰᴏʀ ᴅᴇʟᴇᴛɪɴɢ ꜰɪʟᴇꜱ ꜰʀᴏᴍ ᴅʙ. ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ {str(deleted)} ꜰɪʟᴇꜱ ꜰʀᴏᴍ ᴅʙ ꜰᴏʀ ʏᴏᴜʀ ǫᴜᴇʀʏ {keyword} !\n\nᴘʟᴇᴀꜱᴇ ᴡᴀɪᴛ...") + except Exception as e: + logger.error("Error In killfiledq: %s", e) + await query.message.edit_text(f'Error: {e}') + else: + await query.message.edit_text(f"ᴘʀᴏᴄᴇꜱꜱ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ꜰᴏʀ ꜰɪʟᴇ ᴅᴇʟᴇᴛᴀᴛɪᴏɴ !\n\nꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ {str(deleted)} ꜰɪʟᴇꜱ ꜰʀᴏᴍ ᴅʙ ꜰᴏʀ ʏᴏᴜʀ ǫᴜᴇʀʏ {keyword}.") + + elif query.data.startswith("opnsetgrp"): + ident, grp_id = query.data.split("#") + userid = query.from_user.id if query.from_user else None + st = await client.get_chat_member(int(grp_id), userid) + if ( + st.status != enums.ChatMemberStatus.ADMINISTRATOR + and st.status != enums.ChatMemberStatus.OWNER + and str(userid) not in ADMINS + ): + await query.answer("ʏᴏᴜ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ ʀɪɢʜᴛꜱ ᴛᴏ ᴅᴏ ᴛʜɪs !", show_alert=True) + return + title = query.message.chat.title + settings = await get_settings(grp_id) + if settings is not None: + btn = await group_setting_buttons(int(grp_id)) + reply_markup = InlineKeyboardMarkup(btn) + await query.message.edit_text( + text=await get_settings_text(grp_id, title), + disable_web_page_preview=True, + parse_mode=enums.ParseMode.HTML + ) + await query.message.edit_reply_markup(reply_markup) + + elif query.data.startswith("opnsetpm"): + ident, grp_id = query.data.split("#") + userid = query.from_user.id if query.from_user else None + st = await client.get_chat_member(int(grp_id), userid) + if ( + st.status != enums.ChatMemberStatus.ADMINISTRATOR + and st.status != enums.ChatMemberStatus.OWNER + and str(userid) not in ADMINS + ): + await query.answer("Yᴏᴜ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ sᴜғғɪᴄɪᴀɴᴛ ʀɪɢʜᴛs ᴛᴏ ᴅᴏ ᴛʜɪs !", show_alert=True) + return + title = query.message.chat.title + settings = await get_settings(grp_id) + btn2 = [[ + InlineKeyboardButton( + "ᴄʜᴇᴄᴋ ᴍʏ ᴅᴍ 🗳", url=f"telegram.me/{temp.U_NAME}") + ]] + reply_markup = InlineKeyboardMarkup(btn2) + await query.message.edit_text(f"ʏᴏᴜʀ sᴇᴛᴛɪɴɢs ᴍᴇɴᴜ ғᴏʀ {title} ʜᴀs ʙᴇᴇɴ sᴇɴᴛ ᴛᴏ ʏᴏᴜ ʙʏ ᴅᴍ.") + await query.message.edit_reply_markup(reply_markup) + if settings is not None: + btn = await group_setting_buttons(int(grp_id)) + reply_markup = InlineKeyboardMarkup(btn) + await client.send_message( + chat_id=userid, + text=await get_settings_text(grp_id, title), + reply_markup=reply_markup, + disable_web_page_preview=True, + parse_mode=enums.ParseMode.HTML, + reply_to_message_id=query.message.id + ) + + elif query.data.startswith("show_option"): + ident, from_user = query.data.split("#") + btn = [[ + InlineKeyboardButton("⚠ ᴜɴᴀᴠᴀɪʟᴀʙʟᴇ ⚠", callback_data=f"unavailable#{from_user}"), + InlineKeyboardButton("🟢 ᴜᴘʟᴏᴀᴅᴇᴅ 🟢", callback_data=f"uploaded#{from_user}") + ], [ + InlineKeyboardButton("♻ ᴀʟʀᴇᴀᴅʏ ᴀᴠᴀɪʟᴀʙʟᴇ ♻", callback_data=f"already_available#{from_user}") + ], [ + InlineKeyboardButton("📌 Not Released 📌", callback_data=f"Not_Released#{from_user}"), + InlineKeyboardButton("♨Type Correct Spelling♨", callback_data=f"Type_Correct_Spelling#{from_user}") + ], [ + InlineKeyboardButton("⚜ Not Available In The Hindi ⚜", callback_data=f"Not_Available_In_The_Hindi#{from_user}") + ]] + if query.from_user.id in ADMINS: + reply_markup = InlineKeyboardMarkup(btn) + await query.message.edit_reply_markup(reply_markup) + await query.answer("Hᴇʀᴇ ᴀʀᴇ ᴛʜᴇ ᴏᴘᴛɪᴏɴs !") + else: + await query.answer("Yᴏᴜ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ sᴜғғɪᴄɪᴀɴᴛ ʀɪɢʜᴛs ᴛᴏ ᴅᴏ ᴛʜɪs !", show_alert=True) + + elif query.data.split("#")[0] in ["unavailable", "Not_Released", "Type_Correct_Spelling", "Not_Available_In_The_Hindi", "uploaded", "already_available"]: + key = query.data.split("#")[0] + ident, from_user = query.data.split("#") + if query.from_user.id not in ADMINS: + return await query.answer("Yᴏᴜ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ sᴜғғɪᴄɪᴀɴᴛ ʀɪɢʜᴛs ᴛᴏ ᴅᴏ ᴛʜɪs !", show_alert=True) + + status_configs = { + "unavailable": { + "btn_text": "⚠ ᴜɴᴀᴠᴀɪʟᴀʙʟᴇ ⚠", "alert_key": "unalert", "answer": "Sᴇᴛ ᴛᴏ Uɴᴀᴠᴀɪʟᴀʙʟᴇ !", + "pm": "Hᴇʏ {mention},\n\n{content} Hᴀs Bᴇᴇɴ Mᴀʀᴋᴇᴅ Aᴅ ᴜɴᴀᴠᴀɪʟᴀʙʟᴇ...💔\n\n#Uɴᴀᴠᴀɪʟᴀʙʟᴇ ⚠", + "sup": "Hᴇʏ {mention},\n\n{content} Hᴀs Bᴇᴇɴ Mᴀʀᴋᴇᴅ Aᴅ ᴜɴᴀᴠᴀɪʟᴀʙʟᴇ...💔\n\n#Uɴᴀᴠᴀɪʟᴀʙʟᴇ ⚠\n\nBʟᴏᴄᴋᴇᴅ? Uɴʙʟᴏᴄᴋ ᴛʜᴇ ʙᴏᴛ ᴛᴏ ʀᴇᴄᴇɪᴠᴇ ᴍᴇꜱꜱᴀɢᴇꜱ.", + "search": False + }, + "Not_Released": { + "btn_text": "📌 Not Released 📌", "alert_key": "nralert", "answer": "Sᴇᴛ ᴛᴏ Nᴏᴛ Rᴇʟᴇᴀꜱᴇᴅ !", + "pm": "Hᴇʏ {mention}\n\n{content}, ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ʜᴀꜱ ɴᴏᴛ ʙᴇᴇɴ ʀᴇʟᴇᴀꜱᴇᴅ ʏᴇᴛ\n\n#CᴏᴍɪɴɢSᴏᴏɴ...🕊✌", + "sup": "Hᴇʏ {mention}\n\n{content}, ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ʜᴀꜱ ɴᴏᴛ ʙᴇᴇɴ ʀᴇʟᴇᴀꜱᴇᴅ ʏᴇᴛ\n\n#CᴏᴍɪɴɢSᴏᴏɴ...🕊✌\n\nBʟᴏᴄᴋᴇᴅ? Uɴʙʟᴏᴄᴋ ᴛʜᴇ ʙᴏᴛ ᴛᴏ ʀᴇᴄᴇɪᴠᴇ ᴍᴇꜱꜱᴀɢᴇꜱ.", + "search": False + }, + "Type_Correct_Spelling": { + "btn_text": "♨ Type Correct Spelling ♨", "alert_key": "wsalert", "answer": "Sᴇᴛ ᴛᴏ Cᴏʀʀᴇᴄᴛ Sᴘᴇʟʟɪɴɢ !", + "pm": "Hᴇʏ {mention}\n\nWᴇ Dᴇᴄʟɪɴᴇᴅ Yᴏᴜʀ Rᴇǫᴜᴇsᴛ {content}, Bᴇᴄᴀᴜsᴇ Yᴏᴜʀ Sᴘᴇʟʟɪɴɢ Wᴀs Wʀᴏɴɢ 😢\n\n#Wʀᴏɴɢ_Sᴘᴇʟʟɪɴɢ 😑", + "sup": "Hᴇʏ {mention}\n\n{content}, Bᴇᴄᴀᴜsᴇ Yᴏᴜʀ Sᴘᴇʟʟɪɴɢ Wᴀs Wʀᴏɴɢ 😢\n\n#Wʀᴏɴɢ_Sᴘᴇʟʟɪɴɢ 😑\n\nBʟᴏᴄᴋᴇᴅ? Uɴʙʟᴏᴄᴋ ᴛʜᴇ ʙᴏᴛ ᴛᴏ ʀᴇᴄᴇɪᴠᴇ ᴍᴇꜱꜱᴀɢᴇꜱ.", + "search": False + }, + "Not_Available_In_The_Hindi": { + "btn_text": "⚜ Not Available In The Hindi ⚜", "alert_key": "hnalert", "answer": "Sᴇᴛ ᴛᴏ Nᴏᴛ Aᴠᴀɪʟᴀʙʟᴇ Iɴ Hɪɴᴅɪ !", + "pm": "Hᴇʏ {mention}\n\nYᴏᴜʀ Rᴇǫᴜᴇsᴛ {content} ɪs Nᴏᴛ Aᴠᴀɪʟᴀʙʟᴇ ɪɴ Hɪɴᴅɪ ʀɪɢʜᴛ ɴᴏᴡ. Sᴏ ᴏᴜʀ ᴍᴏᴅᴇʀᴀᴛᴏʀs ᴄᴀɴ'ᴛ ᴜᴘʟᴏᴀᴅ ɪᴛ\n\n#Hɪɴᴅɪ_ɴᴏᴛ_ᴀᴠᴀɪʟᴀʙʟᴇ ❌", + "sup": "Hᴇʏ {mention}\n\n{content} ɪs Nᴏᴛ Aᴠᴀɪʟᴀʙʟᴇ ɪɴ Hɪɴᴅɪ ʀɪɢʜᴛ ɴᴏᴡ. Sᴏ ᴏᴜʀ ᴍᴏᴅᴇʀᴀᴛᴏʀs ᴄᴀɴ'ᴛ ᴜᴘʟᴏᴀᴅ ɪᴛ\n\n#Hɪɴᴅɪ_ɴᴏᴛ_ᴀᴠᴀɪʟᴀʙʟᴇ ❌\n\nBʟᴏᴄᴋᴇᴅ? Uɴʙʟᴏᴄᴋ ᴛʜᴇ ʙᴏᴛ ᴛᴏ ʀᴇᴄᴇɪᴠᴇ ᴍᴇꜱꜱᴀɢᴇꜱ.", + "search": False + }, + "uploaded": { + "btn_text": "🟢 ᴜᴘʟᴏᴀᴅᴇᴅ 🟢", "alert_key": "upalert", "answer": "Sᴇᴛ ᴛᴏ Uᴘʟᴏᴀᴅᴇᴅ !", + "pm": "Hᴇʏ {mention},\n\n{content} Yᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ʜᴀꜱ ʙᴇᴇɴ ᴜᴘʟᴏᴀᴅᴇᴅ ʙʏ ᴏᴜʀ ᴍᴏᴅᴇʀᴀᴛᴏʀs.\nKɪɴᴅʟʏ sᴇᴀʀᴄʜ ɪɴ ᴏᴜʀ Gʀᴏᴜᴘ.\n\n#Uᴘʟᴏᴀᴅᴇᴅ✅", + "sup": "{content}\n\nHᴇʏ {mention}, Yᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ʜᴀꜱ ʙᴇᴇɴ ᴜᴘʟᴏᴀᴅᴇᴅ ʙʏ ᴏᴜʀ ᴍᴏᴅᴇʀᴀᴛᴏʀs.Kɪɴᴅʟʏ sᴇᴀʀᴄʜ ɪɴ ᴏᴜʀ Gʀᴏᴜᴘ.\n\n#Uᴘʟᴏᴀᴅᴇᴅ✅\n\nBʟᴏᴄᴋᴇᴅ? Uɴʙʟᴏᴄᴋ ᴛʜᴇ ʙᴏᴛ ᴛᴏ ʀᴇᴄᴇɪᴠᴇ ᴍᴇꜱꜱᴀɢᴇꜱ.", + "search": True + }, + "already_available": { + "btn_text": "♻ ᴀʟʀᴇᴀᴅʏ ᴀᴠᴀɪʟᴀʙʟᴇ ♻", "alert_key": "alalert", "answer": "Sᴇᴛ ᴛᴏ Aʟʀᴇᴀᴅʏ Aᴠᴀɪʟᴀʙʟᴇ !", + "pm": "Hᴇʏ {mention},\n\n{content} Yᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ɪꜱ ᴀʟʀᴇᴀᴅʏ ᴀᴠᴀɪʟᴀʙʟᴇ ɪɴ ᴏᴜʀ ʙᴏᴛ'ꜱ ᴅᴀᴛᴀʙᴀꜱᴇ.\nKɪɴᴅʟʏ sᴇᴀʀᴄʜ ɪɴ ᴏᴜʀ Gʀᴏᴜᴘ.\n\n#Aᴠᴀɪʟᴀʙʟᴇ 💗", + "sup": "Hᴇʏ {mention},\n\n{content} Yᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ɪꜱ ᴀʟʀᴇᴀᴅʏ ᴀᴠᴀɪʟᴀʙʟᴇ ɪɴ ᴏᴜʀ ʙᴏᴛ'ꜱ ᴅᴀᴛᴀʙᴀꜱᴇ.\nKɪɴᴅʟʏ sᴇᴀʀᴄʜ ɪɴ ᴏᴜʀ Gʀᴏᴜᴘ.\n\n#Aᴠᴀɪʟᴀʙʟᴇ 💗\nBʟᴏᴄᴋᴇᴅ? Uɴʙʟᴏᴄᴋ ᴛʜᴇ ʙᴏᴛ ᴛᴏ ʀᴇᴄᴇɪᴠᴇ ᴍᴇꜱꜱᴀɢES.", + "search": True + } + } + cfg = status_configs[key] + user = await client.get_users(int(from_user)) + btn = [[InlineKeyboardButton(cfg["btn_text"], callback_data=f'{cfg["alert_key"]}#{from_user}')]] + btn2 = [[ + InlineKeyboardButton('ᴊᴏɪɴ ᴄʜᴀɴɴᴇʟ', url=UPDATE_CHNL_LNK), + InlineKeyboardButton("ᴠɪᴇᴡ ꜱᴛᴀᴛᴜꜱ", url=f"{query.message.link}") + ]] + if cfg["search"]: + btn2.append([InlineKeyboardButton("🔍 ꜱᴇᴀʀᴄʜ ʜᴇʀᴇ 🔎", url=GRP_LNK)]) + + content = query.message.text + await query.message.edit_text(f"{content}") + await query.message.edit_reply_markup(InlineKeyboardMarkup(btn)) + await query.answer(cfg["answer"]) + + req_content = extract_request_content(query.message.text) + try: + await client.send_message( + chat_id=int(from_user), + text=cfg["pm"].format(mention=user.mention, content=req_content), + reply_markup=InlineKeyboardMarkup(btn2) + ) + except UserIsBlocked: + await client.send_message( + chat_id=int(SUPPORT_CHAT_ID), + text=cfg["sup"].format(mention=user.mention, content=req_content), + reply_markup=InlineKeyboardMarkup(btn2) + ) + + elif query.data.split("#")[0] in ["alalert", "upalert", "unalert", "hnalert", "nralert", "wsalert"]: + ident, from_user = query.data.split("#") + alerts = { + "alalert": "Hᴇʏ {name}, Yᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ɪꜱ Aʟʀᴇᴀᴅʏ Aᴠᴀɪʟᴀʙʟᴇ ✅", + "upalert": "Hᴇʏ {name}, Yᴏᴜʀ ʀᴇǫᴜESꜱᴛ ɪꜱ Uᴘʟᴏᴀᴅᴇᴅ 🔼", + "unalert": "Hᴇʏ {name}, Yᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ɪꜱ Uɴᴀᴠᴀɪʟᴀʙʟᴇ ⚠", + "hnalert": "Hᴇʏ {name}, Tʜɪꜱ ɪꜱ Nᴏᴛ Aᴠᴀɪʟᴀʙʟᴇ ɪɴ Hɪɴᴅɪ ❌", + "nralert": "Hᴇʏ {name}, Tʜᴇ Mᴏᴠɪᴇ/ꜱʜᴏᴡ ɪꜱ Nᴏᴛ Rᴇʟᴇᴀꜱᴇᴅ Yᴇᴛ 🆕", + "wsalert": "Hᴇʏ {name}, Yᴏᴜʀ Rᴇǫᴜᴇꜱᴛ ᴡᴀꜱ ʀᴇᴊᴇᴄᴛᴇᴅ ᴅᴜᴇ ᴛᴏ ᴡʀᴏɴɢ sᴘᴇʟʟɪɴɢ ❗" + } + if int(query.from_user.id) == int(from_user): + user = await client.get_users(from_user) + msg_text = alerts[ident].format(name=user.first_name) + await query.answer(msg_text, show_alert=True) + else: + await query.answer("Yᴏᴜ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ ᴘᴇʀᴍɪssɪᴏɴ ᴛᴏ sᴇᴇ ᴛʜɪs ❌", show_alert=True) + + elif DreamxData.startswith("generate_stream_link"): + _, file_id = DreamxData.split(":") + try: + user_id = query.from_user.id + username = query.from_user.mention + log_msg = await client.send_cached_media(chat_id=BIN_CHANNEL, file_id=file_id,) + fileName = quote_plus(get_name(log_msg)) + dreamx_stream = f"{URL}watch/{str(log_msg.id)}/{quote_plus(get_name(log_msg))}?hash={get_hash(log_msg)}" + dreamx_download = f"{URL}{str(log_msg.id)}/{quote_plus(get_name(log_msg))}?hash={get_hash(log_msg)}" + await query.answer(MSG_ALRT) + await asyncio.sleep(1) + await log_msg.reply_text( + text=f"•• ʟɪɴᴋ ɢᴇɴᴇʀᴀᴛᴇᴅ ꜰᴏʀ ɪᴅ #{user_id} \n•• ᴜꜱᴇʀɴᴀᴍᴇ : {username} \n\n•• ᖴᎥᒪᗴ Nᗩᗰᗴ : {fileName}", + quote=True, + disable_web_page_preview=True, + reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ 🚀", url=dreamx_download), + InlineKeyboardButton('🖥 ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', url=dreamx_stream)]]) + ) + dreamcinezone = await query.edit_message_reply_markup( + reply_markup=InlineKeyboardMarkup([ + [ + InlineKeyboardButton("🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ 🚀", url=dreamx_download), + InlineKeyboardButton('🖥 ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', url=dreamx_stream) + ], + [ + InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK) + ] + ]) + ) + await asyncio.sleep(DELETE_TIME) + await dreamcinezone.delete() + return + except Exception as e: + logger.error("Callback error: %s", e) + await query.answer(f"⚠ SOMETHING WENT WRONG STREAM LINK \n\n{e}", show_alert=True) + return + + elif query.data == "prestream": + await query.answer(text=script.PRE_STREAM_ALERT, show_alert=True) + dreamcinezone = await client.send_photo( + chat_id=query.message.chat.id, + photo="https://i.ibb.co/whf8xF7j/photo-2025-07-26-10-42-46-7531339305176793100.jpg", + caption=script.PRE_STREAM, reply_markup=InlineKeyboardMarkup([ - [InlineKeyboardButton("🏠 ʜᴏᴍᴇ", callback_data="start"), - InlineKeyboardButton("🔐 ᴄʟᴏsᴇ", callback_data="close_data")] + [InlineKeyboardButton("🚀 Buy Premium 🚀", callback_data="premium_info")] ]) ) - except MessageNotModified: - pass - except Exception as e: - logger.exception(e) + await asyncio.sleep(DELETE_TIME) + await dreamcinezone.delete() -@Client.on_callback_query(filters.regex(r"^help")) -async def help_cb(bot, query): - try: - await query.answer() - except: - pass - try: + elif query.data == "start": + buttons = [[ + InlineKeyboardButton('🔰 ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://telegram.me/{temp.U_NAME}?startgroup=true') + ],[ + InlineKeyboardButton(' ʜᴇʟᴘ 📢', callback_data='help'), + InlineKeyboardButton(' ᴀʙᴏᴜᴛ 📖', callback_data='about') + ],[ + InlineKeyboardButton('ᴛᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), + InlineKeyboardButton('ᴜᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), + ]] + reply_markup = InlineKeyboardMarkup(buttons) + current_time = datetime.now(pytz.timezone(TIMEZONE)) + curr_time = current_time.hour + if curr_time < 12: + gtxt = "ɢᴏᴏᴅ ᴍᴏʀɴɪɴɢ 🌞" + elif curr_time < 17: + gtxt = "ɢᴏᴏᴅ ᴀғᴛᴇʀɴᴏᴏɴ 🌓" + elif curr_time < 21: + gtxt = "ɢᴏᴏᴅ ᴇᴠᴇɴɪɴɢ 🌘" + else: + gtxt = "ɢᴏᴏᴅ ɴɪɢʜᴛ 🌑" + try: + if len(PICS) == 1: + PIC = PICS[0] + else: + try: + PIC = f"{random.choice(PICS_URL)}?r={get_random_mix_id()}" + except Exception: + PIC = random.choice(PICS) + await client.edit_message_media( + query.message.chat.id, + query.message.id, + InputMediaPhoto(PIC) + ) + except Exception: + pass + await query.message.edit_text( + text=script.START_TXT.format(query.from_user.mention, gtxt, temp.U_NAME, temp.B_NAME), + reply_markup=reply_markup, + parse_mode=enums.ParseMode.HTML + ) + await query.answer(MSG_ALRT) + + elif query.data == "donation": + buttons = [[ + InlineKeyboardButton('🌲 Sᴇɴᴅ Dᴏɴᴀᴛᴇ Sᴄʀᴇᴇɴsʜᴏᴛ Hᴇʀᴇ', url=OWNER_LNK) + ],[ + InlineKeyboardButton('⇍ ʙᴀᴄᴋ ⇏', callback_data='about') + ]] + reply_markup = InlineKeyboardMarkup(buttons) + await query.message.edit_text(text="● ◌ ◌") + await query.message.edit_text(text="● ● ◌") + await query.message.edit_text(text="● ● ●") + reply_markup = InlineKeyboardMarkup(buttons) + await client.edit_message_media( + query.message.chat.id, + query.message.id, + InputMediaPhoto('https://graph.org/file/99eebf5dbe8a134f548e0.jpg') + ) + await query.message.edit_text( + text=script.DREAMXBOTZ_DONATION.format(query.from_user.mention, QR_CODE, OWNER_UPI_ID), + reply_markup=reply_markup, + parse_mode=enums.ParseMode.HTML + ) + + elif query.data == "help": + buttons = [[ + InlineKeyboardButton('⇋ ʙᴀᴄᴋ ᴛᴏ ʜᴏᴍᴇ ⇋', callback_data='start') + ]] + reply_markup = InlineKeyboardMarkup(buttons) await query.message.edit_text( text=script.HELP_TXT, - reply_markup=InlineKeyboardMarkup([ - [InlineKeyboardButton("🏠 ʜᴏᴍᴇ", callback_data="start"), - InlineKeyboardButton("🔐 ᴄʟᴏsᴇ", callback_data="close_data")] - ]) + reply_markup=reply_markup, + parse_mode=enums.ParseMode.HTML ) - except MessageNotModified: - pass -@Client.on_callback_query(filters.regex(r"^start")) -async def start_cb(bot, query): - try: - await query.answer() - except: - pass - try: - b_name = getattr(temp, 'B_NAME', 'Boultflix') or 'Boultflix' - u_name = getattr(temp, 'U_NAME', 'Boultflix') or 'Boultflix' - mention = query.from_user.mention if query.from_user else "User" - try: - start_text = script.START_TXT.format(mention, u_name, b_name) - except: - try: - start_text = script.START_TXT.format(mention, b_name) - except: - start_text = script.START_TXT - start_text = start_text.replace("{0}", mention).replace("{1}", u_name).replace("{2}", b_name) - # replace leftover {} sequentially - if "{}" in start_text: - start_text = start_text.replace("{}", mention, 1) - if "{}" in start_text: - start_text = start_text.replace("{}", b_name) + elif query.data == "about": buttons = [[ - InlineKeyboardButton('🔰 ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://t.me/{u_name}?startgroup=true') + InlineKeyboardButton('‼ ᴅɪꜱᴄʟᴀɪᴍᴇʀ ‼', callback_data='disclaimer'), + InlineKeyboardButton ('🪔 sᴏᴜʀᴄᴇ', callback_data='source'), ],[ - InlineKeyboardButton(' ʜᴇʟᴘ 📢', callback_data='help'), - InlineKeyboardButton(' ᴀʙᴏᴜᴛ 📖', callback_data='about') + InlineKeyboardButton('ᴅᴏɴᴀᴛɪᴏɴ 💰', callback_data='donation'), ],[ - InlineKeyboardButton('ᴛᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), - InlineKeyboardButton('ᴜᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), + InlineKeyboardButton('⇋ ʙᴀᴄᴋ ᴛᴏ ʜᴏᴍᴇ ⇋', callback_data='start') ]] - await query.message.edit_text(text=start_text, reply_markup=InlineKeyboardMarkup(buttons)) - except MessageNotModified: - pass - except Exception as e: - logger.exception(e) + reply_markup = InlineKeyboardMarkup(buttons) + # FIXED ABOUT with hyperlink font as requested + try: + about_text = script.ABOUT_TXT.format(temp.U_NAME, temp.B_NAME, OWNER_LNK) + except Exception: + # Fallback if ABOUT_TXT has new style {bot_name} etc + try: + about_text = script.ABOUT_TXT.format(bot_name=temp.B_NAME, bot_username=temp.U_NAME, owner_link=OWNER_LNK) + except Exception: + about_text = script.ABOUT_TXT + await query.message.edit_text( + text=about_text, + reply_markup=reply_markup, + disable_web_page_preview=True, + parse_mode=enums.ParseMode.HTML + ) -@Client.on_callback_query(filters.regex(r"^close_data")) -async def close_cb(bot, query): - try: - await query.message.delete() - except: + elif query.data == "give_trial": try: - await query.message.edit_text("Closed") - except: + user_id = query.from_user.id + has_free_trial = await db.check_trial_status(user_id) + if has_free_trial: + await query.answer( + "🚸 ʏᴏᴜ'ᴠᴇ ᴀʟʀᴇᴀᴅʏ ᴄʟᴀɪᴍᴇᴅ ʏᴏᴜʀ ꜰʀᴇᴇ ᴛʀɪᴀʟ ᴏɴᴄᴇ !\n\n📌 ᴄʜᴇᴄᴋᴏᴜᴛ ᴏᴜʀ ᴘʟᴀɴꜱ ʙʏ : /plan", + show_alert=True + ) + return + else: + await db.give_free_trial(user_id) + await query.answer("✅ Trial activated!", show_alert=True) + + msg = await client.send_photo( + chat_id=query.message.chat.id, + photo="https://i.ibb.co/0jC8MSDZ/photo-2025-07-26-10-42-36-7531339283701956616.jpg", + caption=( + "🥳 ᴄᴏɴɢʀᴀᴛᴜʟᴀᴛɪᴏɴꜱ\n\n" + "🎉 ʏᴏᴜ ᴄᴀɴ ᴜsᴇ ꜰʀᴇᴇ ᴛʀɪᴀʟ ꜰᴏʀ 5 ᴍɪɴᴜᴛᴇs ꜰʀᴏᴍ ɴᴏᴡ !\n\n" + "ɴᴇᴇᴅ ᴘʀᴇᴍɪᴜᴍ 👉🏻 /plan" + ), + parse_mode=enums.ParseMode.HTML, + reply_markup=InlineKeyboardMarkup([[ + InlineKeyboardButton("🚀 Buy Premium 🚀", callback_data="premium_info") + ]]) + ) + await asyncio.sleep(DELETE_TIME) + return await msg.delete() + except Exception: + logger.exception("Error in give_trial callback") + + elif query.data == "source": + buttons = [[ + InlineKeyboardButton('ᴅʀᴇᴀᴍxʙᴏᴛᴢ 📜', url='https://github.com/DreamXBotz/Auto_Filter_Bot.git'), + InlineKeyboardButton('⇋ ʙᴀᴄᴋ ⇋', callback_data='about') + ]] + reply_markup = InlineKeyboardMarkup(buttons) + await query.message.edit_text( + text=script.SOURCE_TXT, + reply_markup=reply_markup, + parse_mode=enums.ParseMode.HTML + ) + + elif query.data == "ref_point": + await query.answer(f'You Have: {referdb.get_refer_points(query.from_user.id)} Refferal points.', show_alert=True) + + elif query.data == "disclaimer": + btn = [[ + InlineKeyboardButton("⇋ ʙᴀᴄᴋ ⇋", callback_data="about") + ]] + reply_markup = InlineKeyboardMarkup(btn) + await query.message.edit_text( + text=(script.DISCLAIMER_TXT), + reply_markup=reply_markup, + parse_mode=enums.ParseMode.HTML + ) + + elif query.data == "premium_info": + try: + btn = [[ + InlineKeyboardButton('• ʙᴜʏ ᴘʀᴇᴍɪᴜᴍ •', callback_data='buy_info'), + ],[ + InlineKeyboardButton('• ʀᴇꜰᴇʀ ꜰʀɪᴇɴᴅꜱ', callback_data='reffff'), + InlineKeyboardButton('ꜰʀᴇᴇ ᴛʀɪᴀʟ •', callback_data='give_trial') + ],[ + InlineKeyboardButton('⇋ ʙᴀᴄᴋ ᴛᴏ ʜᴏᴍᴇ ⇋', callback_data='start') + ]] + reply_markup = InlineKeyboardMarkup(btn) + await client.edit_message_media( + chat_id=query.message.chat.id, + message_id=query.message.id, + media=InputMediaPhoto(media=SUBSCRIPTION, caption=script.BPREMIUM_TXT, parse_mode=enums.ParseMode.HTML), + reply_markup=reply_markup + ) + except Exception: + logger.exception("Exception in 'premium_info' callback") + + elif query.data == "buy_info": + try: + btn = [[ + InlineKeyboardButton('ꜱᴛᴀʀ', callback_data='star_info'), + InlineKeyboardButton('ᴜᴘɪ', callback_data='upi_info') + ],[ + InlineKeyboardButton('⇋ ʙᴀᴄᴋ ᴛᴏ ᴘʀᴇᴍɪᴜᴍ ⇋', callback_data='premium_info') + ]] + reply_markup = InlineKeyboardMarkup(btn) + await client.edit_message_media( + chat_id=query.message.chat.id, + message_id=query.message.id, + media=InputMediaPhoto(media=SUBSCRIPTION, caption=script.PREMIUM_TEXT, parse_mode=enums.ParseMode.HTML), + reply_markup=reply_markup + ) + except Exception: + logger.exception("Exception in 'buy_info' callback") + + elif query.data == "upi_info": + try: + btn = [[ + InlineKeyboardButton('• ꜱᴇɴᴅ ᴘᴀʏᴍᴇɴᴛ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ •', url=OWNER_LNK), + ],[ + InlineKeyboardButton('⇋ ʙᴀᴄᴋ ⇋', callback_data='buy_info') + ]] + reply_markup = InlineKeyboardMarkup(btn) + await client.edit_message_media( + chat_id=query.message.chat.id, + message_id=query.message.id, + media=InputMediaPhoto(media=SUBSCRIPTION, caption=script.PREMIUM_UPI_TEXT.format(OWNER_UPI_ID), parse_mode=enums.ParseMode.HTML), + reply_markup=reply_markup + ) + except Exception: + logger.exception("Exception in 'upi_info' callback") + + elif query.data == "star_info": + try: + btn = [ + InlineKeyboardButton(f"{stars}⭐", callback_data=f"buy_{stars}") + for stars, days in STAR_PREMIUM_PLANS.items() + ] + buttons = [btn[i:i + 2] for i in range(0, len(btn), 2)] + buttons.append([InlineKeyboardButton("⋞ ʙᴀᴄᴋ", callback_data="buy_info")]) + reply_markup = InlineKeyboardMarkup(buttons) + await client.edit_message_media( + chat_id=query.message.chat.id, + message_id=query.message.id, + media=InputMediaPhoto(media=SUBSCRIPTION, caption=script.PREMIUM_STAR_TEXT, parse_mode=enums.ParseMode.HTML), + reply_markup=reply_markup + ) + except Exception: + logger.exception("Exception in 'star' callback") + + elif query.data.startswith("grp_pm"): + _, grp_id = query.data.split("#") + user_id = query.from_user.id if query.from_user else None + if not await is_check_admin(client, int(grp_id), user_id): + return await query.answer(script.NT_ADMIN_ALRT_TXT, show_alert=True) + + btn = await group_setting_buttons(int(grp_id)) + dreamx = await client.get_chat(int(grp_id)) + await query.message.edit(text=await get_settings_text(grp_id, dreamx.title), reply_markup=InlineKeyboardMarkup(btn), parse_mode=enums.ParseMode.HTML) + + elif query.data.startswith("removegrp"): + user_id = query.from_user.id + data = query.data + grp_id = int(data.split("#")[1]) + if not await is_check_admin(client, grp_id, query.from_user.id): + return await query.answer(script.NT_ADMIN_ALRT_TXT, show_alert=True) + await db.remove_group_connection(grp_id, user_id) + await query.answer("Group removed from your connections.", show_alert=True) + connected_groups = await db.get_connected_grps(user_id) + if not connected_groups: + await query.edit_message_text("Nᴏ Cᴏɴɴᴇᴄᴛᴇᴅ Gʀᴏᴜᴘs Fᴏᴜɴᴅ .") + return + group_list = [] + for group in connected_groups: + try: + Chat = await client.get_chat(group) + group_list.append([ + InlineKeyboardButton( + text=Chat.title, callback_data=f"grp_pm#{Chat.id}") + ]) + except Exception: + pass + await query.edit_message_text( + "⚠ ꜱᴇʟᴇᴄᴛ ᴛʜᴇ ɢʀᴏᴜᴘ ᴡʜᴏꜱᴇ ꜱᴇᴛᴛɪɴɢꜱ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʜᴀɴɢᴇ.\n\n" + "ɪꜰ ʏᴏᴜʀ ɢʀᴏᴜᴘ ɪꜱ ɴᴏᴛ ꜱʜᴏᴡɪɴɢ ʜᴇʀᴇ,\n" + "ᴜꜱᴇ /reload ɪɴ ᴛʜᴀᴛ ɢʀᴏᴜᴘ ᴀɴᴅ ɪᴛ ᴡɪʟʟ ᴀᴘᴘᴇᴀʀ ʜᴇʀᴇ.", + reply_markup=InlineKeyboardMarkup(group_list) + ) + + elif query.data.startswith("setgs"): + ident, set_type, status, grp_id = query.data.split("#") + userid = query.from_user.id if query.from_user else None + if not await is_check_admin(client, int(grp_id), userid): + await query.answer(script.NT_ADMIN_ALRT_TXT, show_alert=True) + return + if status == "True": + await save_group_settings(int(grp_id), set_type, False) + await query.answer("ᴏꜰꜰ ✗") + else: + await save_group_settings(int(grp_id), set_type, True) + await query.answer("ᴏɴ ✓") + settings = await get_settings(int(grp_id)) + if settings is not None: + btn = await group_setting_buttons(int(grp_id)) + reply_markup = InlineKeyboardMarkup(btn) + await query.message.edit_reply_markup(reply_markup) + await query.answer(MSG_ALRT) + +async def auto_filter(client, msg, spoll=False): + """ + Core auto_filter logic with timing/debug logging removed. + """ + curr_time = datetime.now(pytz.timezone('Asia/Kolkata')).time() + + async def _schedule_delete(sent_obj, orig_msg, delay): + try: + await asyncio.sleep(delay) + try: + await sent_obj.delete() + except Exception: + pass + try: + await orig_msg.delete() + except Exception: + pass + except Exception: pass + m = None try: - await query.answer() - except: - pass + if not spoll: + message = msg + if message.text.startswith("/"): + return + if re.findall(r"((^\/|^,|^!|^\.|^[\U0001F600-\U000E007F]).*)", message.text): + return + if len(message.text) < 100: + message_text = message.text or "" + search = message_text.lower() + m = await message.reply_text(script.SEARCHING_TXT.format(search)) + find = search.split(" ") + search = "" + removes = ["in", "upload", "series", "full", + "horror", "thriller", "mystery", "print", "file"] + for x in find: + if x in removes: + continue + else: + search = search + x + " " + search = re.sub(r"\b(pl(i|e)*?(s|z+|ease|se|ese|(e+)s(e)?)|((send|snd|giv(e)?|gib)(\sme)?)|movie(s)?|new|latest|bro|bruh|broh|helo|that|find|dubbed|link|venum|iruka|pannunga|pannungga|anuppunga|anupunga|anuppungga|anupungga|film|undo|kitti|kitty|tharu|kittumo|kittum|movie|any(one)|with\ssubtitle(s)?)\b", "", search, flags=re.IGNORECASE) + search = search.replace("-", " ") + search = re.sub(r"[:']", "", search) + search = re.sub(r"\s+", " ", search).strip() + files, offset, total_results = await get_search_results(message.chat.id, search, offset=0, filter=True) + settings = await get_settings(message.chat.id) + if not files: + if settings.get("spell_check"): + ai_sts = await m.edit('🤖 ᴘʟᴇᴀꜱᴇ ᴡᴀɪᴛ, ᴀɪ ɪꜱ ᴄʜᴇᴄᴋɪɴɢ ʏᴏᴜʀ ꜱᴘᴇʟʟɪɴɢ...') + is_misspelled = await ai_spell_check(chat_id=message.chat.id, wrong_name=search) + if is_misspelled: + await ai_sts.edit(f'✅ Aɪ Sᴜɢɢᴇsᴛᴇᴅ: {is_misspelled}\n🔍 Searching for it...') + message.text = is_misspelled + await ai_sts.delete() + return await auto_filter(client, message) + await ai_sts.delete() + result = await advantage_spell_chok(client, message) + return result + else: + try: + if m: + await m.delete() + except Exception: + pass + result = await advantage_spell_chok(client, message) + return result + else: + return + else: + message = msg.message.reply_to_message + search, files, offset, total_results = spoll + m = await message.reply_text(f'🔎 sᴇᴀʀᴄʜɪɴɢ {search}', reply_to_message_id=message.id) + settings = await get_settings(message.chat.id) + await msg.message.delete() + key = f"{message.chat.id}-{message.id}" + FRESH[key] = search + temp.GETALL[key] = files + req = message.from_user.id if message.from_user else 0 + temp.SHORT[message.from_user.id] = message.chat.id + try: + await client.send_reaction(chat_id=message.chat.id, message_id=message.id, emoji="🍿") + except Exception: + pass + if settings.get('button'): + btn = [ + [ + InlineKeyboardButton(text=f"🔗 {get_size(file.file_size)} ≽ " + clean_filename( + file.file_name), callback_data=f'file#{file.file_id}'), + ] + for file in files + ] + btn.insert(0, + [ + InlineKeyboardButton( + 'Qᴜᴀʟɪᴛʏ', callback_data=f"qualities#{req}#{key}"), + InlineKeyboardButton( + "Lᴀɴɢᴜᴀɢᴇ", callback_data=f"languages#{req}#{key}"), + InlineKeyboardButton( + "Sᴇᴀsᴏɴ", callback_data=f"seasons#{req}#{key}") + ] + ) + btn.insert(0, + [ + InlineKeyboardButton( + "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), + InlineKeyboardButton( + "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) -@Client.on_callback_query(filters.regex(r"^pages")) -async def pages_cb(bot, query): - await query.answer() + ]) + else: + btn = [] + btn.insert(0, + [ + InlineKeyboardButton( + 'Qᴜᴀʟɪᴛʏ', callback_data=f"qualities#{req}#{key}"), + InlineKeyboardButton( + "Lᴀɴɢᴜᴀɢᴇ", callback_data=f"languages#{req}#{key}"), + InlineKeyboardButton( + "Sᴇᴀsᴏɴ", callback_data=f"seasons#{req}#{key}") + ] + ) + btn.insert(0, + [ + InlineKeyboardButton( + "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), + InlineKeyboardButton( + "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) + ]) -@Client.on_callback_query(filters.regex(r"^sendall#")) -async def sendall_cb(bot, query): - try: - _, key, req = query.data.split("#") - req = int(req) - if req != 0 and query.from_user.id != req: - return await query.answer("This is not for you!", show_alert=True) - files = temp.GETALL.get(key) - if not files: - return await query.answer("No files found", show_alert=True) - await query.answer("Sending all files in PM...", show_alert=False) - for file in files[:10]: + if offset != "": + req = message.from_user.id if message.from_user else 0 + if ULTRA_FAST_MODE: + btn.append( + [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( + text="1", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}")] + ) + else: + try: + if settings['max_btn']: + btn.append( + [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( + text=f"1/{math.ceil(int(total_results)/10)}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}")] + ) + else: + btn.append( + [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( + text=f"1/{math.ceil(int(total_results)/int(MAX_B_TN))}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}")] + ) + except KeyError: + await save_group_settings(message.chat.id, 'max_btn', True) + btn.append( + [InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( + text=f"1/{math.ceil(int(total_results)/10)}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}")] + ) + else: + btn.append([InlineKeyboardButton( + text="↭ ɴᴏ ᴍᴏʀᴇ ᴘᴀɢᴇꜱ ᴀᴠᴀɪʟᴀʙʟᴇ ↭", callback_data="pages")]) + + if settings.get('imdb'): + imdb = await get_posterx(search, file=(files[0]).file_name) if TMDB_POSTER else await get_poster(search, file=(files[0]).file_name) + else: + imdb = None + cur_time = datetime.now(pytz.timezone('Asia/Kolkata')).time() + time_difference = timedelta(hours=cur_time.hour, minutes=cur_time.minute, seconds=(cur_time.second+(cur_time.microsecond/1000000))) - \ + timedelta(hours=curr_time.hour, minutes=curr_time.minute, + seconds=(curr_time.second+(curr_time.microsecond/1000000))) + remaining_seconds = "{:.2f}".format(time_difference.total_seconds()) + TEMPLATE = script.IMDB_TEMPLATE_TXT + settings = await get_settings(message.chat.id) + if settings.get('template'): + TEMPLATE = settings['template'] + if imdb: + cap = TEMPLATE.format( + query=search, + title=imdb['title'], + votes=imdb['votes'], + aka=imdb["aka"], + seasons=imdb["seasons"], + box_office=imdb['box_office'], + localized_title=imdb['localized_title'], + kind=imdb['kind'], + imdb_id=imdb["imdb_id"], + cast=imdb['cast'], + runtime=imdb['runtime'], + countries=imdb['countries'], + certificates=imdb['certificates'], + languages=imdb['languages'], + director=imdb['director'], + writer=imdb['writer'], + producer=imdb['producer'], + composer=imdb['composer'], + cinematographer=imdb['cinematographer'], + music_team=imdb['music_team'], + distributors=imdb['distributors'], + release_date=imdb['release_date'], + year=imdb['year'], + genres=imdb['genres'], + poster=imdb['poster'], + plot=imdb['plot'] if settings.get('button') else "N/A", + rating=imdb['rating'], + url=imdb['url'], + **locals() + ) + temp.IMDB_CAP[message.from_user.id] = cap + if not settings.get('button'): + cap += "\n\nYour Requested Files Are Here\n\n" + for idx, file in enumerate(files, start=1): + cap += f"\n{idx}. [{get_size(file.file_size)}] {clean_filename(file.file_name)}\n" + else: + temp.IMDB_CAP[message.from_user.id] = None + if ULTRA_FAST_MODE: + if settings.get('button'): + cap = f"🏷 ᴛɪᴛʟᴇ : {search}\n⏰ ʀᴇsᴜʟᴛ ɪɴ : {remaining_seconds} Sᴇᴄᴏɴᴅs\n\n📝 ʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {message.from_user.mention}\n⚜ ᴘᴏᴡᴇʀᴇᴅ ʙʏ : ⚡ {message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'} \n\nYour Requested Files Are Here \n\n" + else: + cap = f"🏷 ᴛɪᴛʟᴇ : {search}\n⏰ ʀᴇsᴜʟᴛ ɪɴ : {remaining_seconds} Sᴇᴄᴏɴᴅs\n\n📝 ʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {message.from_user.mention}\n⚜ ᴘᴏᴡᴇʀᴇᴅ ʙʏ : ⚡ {message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'} \n\nYour Requested Files Are Here \n\n" + for idx, file in enumerate(files, start=1): + cap += f"\n{idx}. [{get_size(file.file_size)}] {clean_filename(file.file_name)}\n" + else: + if settings.get('button'): + cap = f"🏷 ᴛɪᴛʟᴇ : {search}\n🧱 ᴛᴏᴛᴀʟ ꜰɪʟᴇꜱ : {total_results}\n⏰ ʀᴇsᴜʟᴛ ɪɴ : {remaining_seconds} Sᴇᴄᴏɴᴅs\n\n📝 ʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {message.from_user.mention}\n⚜ ᴘᴏᴡᴇʀᴇᴅ ʙʏ : ⚡ {message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'} \n\nYour Requested Files Are Here \n\n" + else: + cap = f"🏷 ᴛɪᴛʟᴇ : {search}\n🧱 ᴛᴏᴛᴀʟ ꜰɪʟᴇꜱ : {total_results}\n⏰ ʀᴇsᴜʟᴛ ɪɴ : {remaining_seconds} Sᴇᴄᴏɴᴅs\n\n📝 ʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {message.from_user.mention}\n⚜ ᴘᴏᴡᴇʀᴇᴅ ʙʏ : ⚡ {message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'} \n\nYour Requested Files Are Here \n\n" + + for idx, file in enumerate(files, start=1): + cap += f"\n{idx}. [{get_size(file.file_size)}] {clean_filename(file.file_name)}\n" + sent = None + try: + if imdb and imdb.get('poster'): + try: + if TMDB_POSTER: + photo = imdb.get('backdrop') if imdb.get('backdrop') and LANDSCAPE_POSTER else imdb.get('poster') + else: + photo = imdb.get('poster') + sent = await message.reply_photo(photo=photo, caption=cap, reply_markup=InlineKeyboardMarkup(btn), parse_mode=enums.ParseMode.HTML) + if m: + await m.delete() + except (MediaEmpty, PhotoInvalidDimensions, WebpageMediaEmpty): + pic = imdb.get('poster') + poster = pic.replace('.jpg', "._V1_UX360.jpg") + sent = await message.reply_photo(photo=poster, caption=cap, reply_markup=InlineKeyboardMarkup(btn), parse_mode=enums.ParseMode.HTML) + if m: + await m.delete() + except Exception as e: + logger.exception(e) + sent = await message.reply_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) + else: + sent = await message.reply_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) + if m: + await m.delete() + except Exception as e: + logger.exception("Failed to send result: %s", e) + return + try: + if settings.get('auto_delete'): + asyncio.create_task(_schedule_delete(sent, message, DELETE_TIME)) + except KeyError: try: - await bot.send_cached_media(chat_id=query.from_user.id, file_id=file.file_id, caption=file.file_name) - await asyncio.sleep(1) - except FloodWait as e: - await asyncio.sleep(e.value) - except: + await save_group_settings(message.chat.id, 'auto_delete', True) + except Exception: pass + asyncio.create_task(_schedule_delete(sent, message, DELETE_TIME)) + return except Exception as e: logger.exception(e) + return + +async def ai_spell_check(chat_id, wrong_name): + async def search_movie(wrong_name): + search_results = imdb.search_movie(wrong_name) + if not search_results or not hasattr(search_results, "titles"): + return [] + movie_list = [movie.title for movie in search_results.titles] + return movie_list + movie_list = await search_movie(wrong_name) + if not movie_list: + return + for _ in range(5): + closest_match = process.extractOne(wrong_name, movie_list) + if not closest_match or closest_match[1] <= 80: + return + movie = closest_match[0] + files, _, _ = await get_search_results(chat_id=chat_id, query=movie) + if files: + return movie + movie_list.remove(movie) + +async def advantage_spell_chok(client, message): + search = message.text + query = re.sub( + r"\b(pl(i|e)*?(s|z+|ease|se|ese|(e+)s(e)?)|((send|snd|giv(e)?|gib)(\sme)?)|movie(s)?|new|latest|br((o|u)h?)*|^h(e|a)?(l)*(o)*|mal(ayalam)?|t(h)?amil|file|that|find|und(o)*|kit(t(i|y)?)?o(w)?|thar(u)?(o)*w?|kittum(o)*|aya(k)*(um(o)*)?|full\smovie|any(one)|with\ssubtitle(s)?)", + "", message.text, flags=re.IGNORECASE) + query = query.strip() + " movie" + try: + movies = await get_poster(search, bulk=True) + except Exception as e: + logger.exception("get_poster failed for query=%s: %s", query, e) + try: + k = await message.reply(script.I_CUDNT.format(message.from_user.mention)) + await asyncio.sleep(60) + try: + await k.delete() + except Exception: + pass + except Exception: + pass + try: + await message.delete() + except Exception: + pass + return + if not movies: + google = quote_plus(search) + button = [[InlineKeyboardButton( + "🔍 ᴄʜᴇᴄᴋ sᴘᴇʟʟɪɴɢ ᴏɴ ɢᴏᴏɢʟᴇ 🔍", url=f"https://www.google.com/search?q={google}")]] + k = await message.reply_text(text=script.I_CUDNT.format(search), reply_markup=InlineKeyboardMarkup(button)) + await asyncio.sleep(60) + try: + await k.delete() + except Exception: + pass + try: + await message.delete() + except Exception: + pass + return + user = message.from_user.id if message.from_user else 0 + buttons = [ + [InlineKeyboardButton(text=movie.title, callback_data=f"spol#{movie.imdb_id}#{user}") + ] for movie in movies] + + buttons.append([InlineKeyboardButton( + text="🚫 ᴄʟᴏsᴇ 🚫", callback_data='close_data', style=enums.ButtonStyle.DANGER)]) + d = await message.reply_text(text=script.CUDNT_FND.format(message.from_user.mention), reply_markup=InlineKeyboardMarkup(buttons), reply_to_message_id=message.id) + await asyncio.sleep(60) + try: + await d.delete() + except Exception: + pass + try: + await message.delete() + except Exception: + pass From e9c6beca9b30c93fc100f8d82dc74dbe7027d5df Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Sun, 13 Sep 2026 16:08:48 +0530 Subject: [PATCH 16/77] Update Script.py --- Script.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Script.py b/Script.py index c5afb93b..c8073e1d 100644 --- a/Script.py +++ b/Script.py @@ -34,7 +34,7 @@ class script(object): 🚀 ꜰᴏʟʟᴏᴡ ᴛʜᴇꜱᴇ ꜱᴛᴇᴘꜱ! """ - ABOUT_TXT = """╭────[ ᴍʏ ᴅᴇᴛᴀɪʟs ]────⍟ + ABOUT_TXT = """╭────[Mʏ Dᴇᴛᴀɪʟs ]────⍟ ├⍟ Mʏ Nᴀᴍᴇ : Bᴏᴜʟᴛғʟɪx Mᴏᴠɪᴇs 🫧🫶🏼 ├⍟ Dᴇᴠᴇʟᴏᴘᴇʀ : Oᴡɴᴇʀ ├⍟ Lɪʙʀᴀʀʏ : Pʏʀᴏɢʀᴀᴍ From d4af2b75a93c6a439c7040659b1e32ff1d518d2d Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Sun, 13 Sep 2026 16:09:13 +0530 Subject: [PATCH 17/77] Update pmfilter.py From 3928aa12d059d4e8482b97f51d1f5519ae515ba7 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Sun, 13 Sep 2026 16:18:12 +0530 Subject: [PATCH 18/77] Refactor about query handling in pmfilter.py Refactor the 'about' query handling to simplify button layout and improve exception handling for message editing. --- plugins/pmfilter.py | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/plugins/pmfilter.py b/plugins/pmfilter.py index acb92f3f..f0f3dce1 100644 --- a/plugins/pmfilter.py +++ b/plugins/pmfilter.py @@ -1224,30 +1224,33 @@ async def cb_handler(client: Client, query: CallbackQuery): ) elif query.data == "about": + # FINAL ABOUT - Only HOME and CLOSE as you asked, same font buttons = [[ - InlineKeyboardButton('‼ ᴅɪꜱᴄʟᴀɪᴍᴇʀ ‼', callback_data='disclaimer'), - InlineKeyboardButton ('🪔 sᴏᴜʀᴄᴇ', callback_data='source'), - ],[ - InlineKeyboardButton('ᴅᴏɴᴀᴛɪᴏɴ 💰', callback_data='donation'), - ],[ - InlineKeyboardButton('⇋ ʙᴀᴄᴋ ᴛᴏ ʜᴏᴍᴇ ⇋', callback_data='start') + InlineKeyboardButton('🏠 Hᴏᴍᴇ', callback_data='start'), + InlineKeyboardButton('🔐 Cʟᴏsᴇ', callback_data='close_data') ]] reply_markup = InlineKeyboardMarkup(buttons) - # FIXED ABOUT with hyperlink font as requested try: about_text = script.ABOUT_TXT.format(temp.U_NAME, temp.B_NAME, OWNER_LNK) except Exception: - # Fallback if ABOUT_TXT has new style {bot_name} etc try: - about_text = script.ABOUT_TXT.format(bot_name=temp.B_NAME, bot_username=temp.U_NAME, owner_link=OWNER_LNK) + about_text = script.ABOUT_TXT.format(temp.U_NAME) except Exception: about_text = script.ABOUT_TXT - await query.message.edit_text( - text=about_text, - reply_markup=reply_markup, - disable_web_page_preview=True, - parse_mode=enums.ParseMode.HTML - ) + try: + await query.message.edit_text( + text=about_text, + reply_markup=reply_markup, + disable_web_page_preview=True, + parse_mode=enums.ParseMode.HTML + ) + except Exception: + # For newer Pyrogram where disable_web_page_preview not allowed in edit_text + await query.message.edit_text( + text=about_text, + reply_markup=reply_markup, + parse_mode=enums.ParseMode.HTML + ) elif query.data == "give_trial": try: From 3c13a04224053973d2b9beeb6e2d648854d7d1f1 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Sun, 13 Sep 2026 21:03:14 +0530 Subject: [PATCH 19/77] Fix reply_to_message_id usage in pmfilter.py --- plugins/pmfilter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/pmfilter.py b/plugins/pmfilter.py index f0f3dce1..5a1f1d13 100644 --- a/plugins/pmfilter.py +++ b/plugins/pmfilter.py @@ -1512,7 +1512,7 @@ async def _schedule_delete(sent_obj, orig_msg, delay): else: message = msg.message.reply_to_message search, files, offset, total_results = spoll - m = await message.reply_text(f'🔎 sᴇᴀʀᴄʜɪɴɢ {search}', reply_to_message_id=message.id) + m = await message.reply_text(f'🔎 sᴇᴀʀᴄʜɪɴɢ {search}') settings = await get_settings(message.chat.id) await msg.message.delete() key = f"{message.chat.id}-{message.id}" @@ -1773,7 +1773,7 @@ async def advantage_spell_chok(client, message): buttons.append([InlineKeyboardButton( text="🚫 ᴄʟᴏsᴇ 🚫", callback_data='close_data', style=enums.ButtonStyle.DANGER)]) - d = await message.reply_text(text=script.CUDNT_FND.format(message.from_user.mention), reply_markup=InlineKeyboardMarkup(buttons), reply_to_message_id=message.id) + d = await message.reply_text(text=script.CUDNT_FND.format(message.from_user.mention), reply_markup=InlineKeyboardMarkup(buttons)) await asyncio.sleep(60) try: await d.delete() From d9693f4f718dfec1173d0b861778cc6a0bd77ae5 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Mon, 14 Sep 2026 08:31:20 +0530 Subject: [PATCH 20/77] Update pmfilter.py --- plugins/pmfilter.py | 54 +++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/plugins/pmfilter.py b/plugins/pmfilter.py index 9673a8e1..5a1f1d13 100644 --- a/plugins/pmfilter.py +++ b/plugins/pmfilter.py @@ -8,7 +8,7 @@ from database.config_db import mdb from pyrogram.errors import MessageIdInvalid, UserIsBlocked, MessageNotModified, PeerIdInvalid, MessageDeleteForbidden from pyrogram import Client, filters, enums -from pyrogram.types import LinkPreviewOptions, InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery, InputMediaPhoto +from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery, InputMediaPhoto from info import ( ADMINS, AUTH_CHANNELS, AUTH_REQ_CHANNELS, BIN_CHANNEL, DELETE_TIME, EMOJI_MODE, GRP_LNK, LANDSCAPE_POSTER, LANGUAGES, LOG_CHANNEL, MAX_B_TN, MSG_ALRT, @@ -327,12 +327,12 @@ async def next_page(bot, query): logger.exception(e) else: try: - await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), link_preview_options=LinkPreviewOptions(is_disabled=True), parse_mode=enums.ParseMode.HTML) + await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) except (MessageNotModified, MessageIdInvalid): pass else: cap = await get_cap(settings, remaining_seconds, files, query, total, dreamx_title, offset+1) - await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), link_preview_options=LinkPreviewOptions(is_disabled=True), parse_mode=enums.ParseMode.HTML) + await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) except (MessageNotModified, MessageIdInvalid): pass except Exception as e: @@ -518,7 +518,7 @@ async def filter_qualities_cb_handler(client: Client, query: CallbackQuery): dreamx_title = clean_search_text(search) cap = await get_cap(settings, remaining_seconds, files, query, total_results, dreamx_title, offset=1) try: - await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), link_preview_options=LinkPreviewOptions(is_disabled=True), parse_mode=enums.ParseMode.HTML) + await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) except (MessageNotModified, MessageIdInvalid): pass else: @@ -669,7 +669,7 @@ async def filter_languages_cb_handler(client: Client, query: CallbackQuery): dreamx_title = clean_search_text(search) cap = await get_cap(settings, remaining_seconds, files, query, total_results, dreamx_title, offset=1) try: - await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), link_preview_options=LinkPreviewOptions(is_disabled=True), parse_mode=enums.ParseMode.HTML) + await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) except (MessageNotModified, MessageIdInvalid): pass else: @@ -806,7 +806,7 @@ async def filter_seasons_cb_handler(client: Client, query: CallbackQuery): await query.message.edit_text( text=cap, reply_markup=InlineKeyboardMarkup(btn), - link_preview_options=LinkPreviewOptions(is_disabled=True), + disable_web_page_preview=True, ) except (MessageNotModified, MessageIdInvalid): pass @@ -950,7 +950,7 @@ async def cb_handler(client: Client, query: CallbackQuery): reply_markup = InlineKeyboardMarkup(btn) await query.message.edit_text( text=await get_settings_text(grp_id, title), - link_preview_options=LinkPreviewOptions(is_disabled=True), + disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML ) await query.message.edit_reply_markup(reply_markup) @@ -982,7 +982,7 @@ async def cb_handler(client: Client, query: CallbackQuery): chat_id=userid, text=await get_settings_text(grp_id, title), reply_markup=reply_markup, - link_preview_options=LinkPreviewOptions(is_disabled=True), + disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML, reply_to_message_id=query.message.id ) @@ -1110,9 +1110,10 @@ async def cb_handler(client: Client, query: CallbackQuery): await asyncio.sleep(1) await log_msg.reply_text( text=f"•• ʟɪɴᴋ ɢᴇɴᴇʀᴀᴛᴇᴅ ꜰᴏʀ ɪᴅ #{user_id} \n•• ᴜꜱᴇʀɴᴀᴍᴇ : {username} \n\n•• ᖴᎥᒪᗴ Nᗩᗰᗴ : {fileName}", - link_preview_options=LinkPreviewOptions(is_disabled=True), - reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ 🚀", url=dreamx_download), # we download Link - InlineKeyboardButton('🖥️ ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥️', url=dreamx_stream)]]) # web stream Link + quote=True, + disable_web_page_preview=True, + reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ 🚀", url=dreamx_download), + InlineKeyboardButton('🖥 ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', url=dreamx_stream)]]) ) dreamcinezone = await query.edit_message_reply_markup( reply_markup=InlineKeyboardMarkup([ @@ -1229,12 +1230,27 @@ async def cb_handler(client: Client, query: CallbackQuery): InlineKeyboardButton('🔐 Cʟᴏsᴇ', callback_data='close_data') ]] reply_markup = InlineKeyboardMarkup(buttons) - await query.message.edit_text( - text=script.ABOUT_TXT.format(temp.U_NAME, temp.B_NAME, OWNER_LNK), - reply_markup=reply_markup, - link_preview_options=LinkPreviewOptions(is_disabled=True), - parse_mode=enums.ParseMode.HTML - ) + try: + about_text = script.ABOUT_TXT.format(temp.U_NAME, temp.B_NAME, OWNER_LNK) + except Exception: + try: + about_text = script.ABOUT_TXT.format(temp.U_NAME) + except Exception: + about_text = script.ABOUT_TXT + try: + await query.message.edit_text( + text=about_text, + reply_markup=reply_markup, + disable_web_page_preview=True, + parse_mode=enums.ParseMode.HTML + ) + except Exception: + # For newer Pyrogram where disable_web_page_preview not allowed in edit_text + await query.message.edit_text( + text=about_text, + reply_markup=reply_markup, + parse_mode=enums.ParseMode.HTML + ) elif query.data == "give_trial": try: @@ -1669,9 +1685,9 @@ async def _schedule_delete(sent_obj, orig_msg, delay): await m.delete() except Exception as e: logger.exception(e) - sent = await message.reply_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), link_preview_options=LinkPreviewOptions(is_disabled=True), parse_mode=enums.ParseMode.HTML) + sent = await message.reply_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) else: - sent = await message.reply_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), link_preview_options=LinkPreviewOptions(is_disabled=True), parse_mode=enums.ParseMode.HTML) + sent = await message.reply_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) if m: await m.delete() except Exception as e: From 32ba0b6a57d23835b4f74149e2462153e90a6bfc Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Mon, 14 Sep 2026 18:06:05 +0530 Subject: [PATCH 21/77] Update pmfilter.py --- plugins/pmfilter.py | 54 ++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/plugins/pmfilter.py b/plugins/pmfilter.py index 5a1f1d13..9673a8e1 100644 --- a/plugins/pmfilter.py +++ b/plugins/pmfilter.py @@ -8,7 +8,7 @@ from database.config_db import mdb from pyrogram.errors import MessageIdInvalid, UserIsBlocked, MessageNotModified, PeerIdInvalid, MessageDeleteForbidden from pyrogram import Client, filters, enums -from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery, InputMediaPhoto +from pyrogram.types import LinkPreviewOptions, InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery, InputMediaPhoto from info import ( ADMINS, AUTH_CHANNELS, AUTH_REQ_CHANNELS, BIN_CHANNEL, DELETE_TIME, EMOJI_MODE, GRP_LNK, LANDSCAPE_POSTER, LANGUAGES, LOG_CHANNEL, MAX_B_TN, MSG_ALRT, @@ -327,12 +327,12 @@ async def next_page(bot, query): logger.exception(e) else: try: - await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) + await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), link_preview_options=LinkPreviewOptions(is_disabled=True), parse_mode=enums.ParseMode.HTML) except (MessageNotModified, MessageIdInvalid): pass else: cap = await get_cap(settings, remaining_seconds, files, query, total, dreamx_title, offset+1) - await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) + await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), link_preview_options=LinkPreviewOptions(is_disabled=True), parse_mode=enums.ParseMode.HTML) except (MessageNotModified, MessageIdInvalid): pass except Exception as e: @@ -518,7 +518,7 @@ async def filter_qualities_cb_handler(client: Client, query: CallbackQuery): dreamx_title = clean_search_text(search) cap = await get_cap(settings, remaining_seconds, files, query, total_results, dreamx_title, offset=1) try: - await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) + await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), link_preview_options=LinkPreviewOptions(is_disabled=True), parse_mode=enums.ParseMode.HTML) except (MessageNotModified, MessageIdInvalid): pass else: @@ -669,7 +669,7 @@ async def filter_languages_cb_handler(client: Client, query: CallbackQuery): dreamx_title = clean_search_text(search) cap = await get_cap(settings, remaining_seconds, files, query, total_results, dreamx_title, offset=1) try: - await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) + await query.message.edit_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), link_preview_options=LinkPreviewOptions(is_disabled=True), parse_mode=enums.ParseMode.HTML) except (MessageNotModified, MessageIdInvalid): pass else: @@ -806,7 +806,7 @@ async def filter_seasons_cb_handler(client: Client, query: CallbackQuery): await query.message.edit_text( text=cap, reply_markup=InlineKeyboardMarkup(btn), - disable_web_page_preview=True, + link_preview_options=LinkPreviewOptions(is_disabled=True), ) except (MessageNotModified, MessageIdInvalid): pass @@ -950,7 +950,7 @@ async def cb_handler(client: Client, query: CallbackQuery): reply_markup = InlineKeyboardMarkup(btn) await query.message.edit_text( text=await get_settings_text(grp_id, title), - disable_web_page_preview=True, + link_preview_options=LinkPreviewOptions(is_disabled=True), parse_mode=enums.ParseMode.HTML ) await query.message.edit_reply_markup(reply_markup) @@ -982,7 +982,7 @@ async def cb_handler(client: Client, query: CallbackQuery): chat_id=userid, text=await get_settings_text(grp_id, title), reply_markup=reply_markup, - disable_web_page_preview=True, + link_preview_options=LinkPreviewOptions(is_disabled=True), parse_mode=enums.ParseMode.HTML, reply_to_message_id=query.message.id ) @@ -1110,10 +1110,9 @@ async def cb_handler(client: Client, query: CallbackQuery): await asyncio.sleep(1) await log_msg.reply_text( text=f"•• ʟɪɴᴋ ɢᴇɴᴇʀᴀᴛᴇᴅ ꜰᴏʀ ɪᴅ #{user_id} \n•• ᴜꜱᴇʀɴᴀᴍᴇ : {username} \n\n•• ᖴᎥᒪᗴ Nᗩᗰᗴ : {fileName}", - quote=True, - disable_web_page_preview=True, - reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ 🚀", url=dreamx_download), - InlineKeyboardButton('🖥 ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', url=dreamx_stream)]]) + link_preview_options=LinkPreviewOptions(is_disabled=True), + reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ 🚀", url=dreamx_download), # we download Link + InlineKeyboardButton('🖥️ ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥️', url=dreamx_stream)]]) # web stream Link ) dreamcinezone = await query.edit_message_reply_markup( reply_markup=InlineKeyboardMarkup([ @@ -1230,27 +1229,12 @@ async def cb_handler(client: Client, query: CallbackQuery): InlineKeyboardButton('🔐 Cʟᴏsᴇ', callback_data='close_data') ]] reply_markup = InlineKeyboardMarkup(buttons) - try: - about_text = script.ABOUT_TXT.format(temp.U_NAME, temp.B_NAME, OWNER_LNK) - except Exception: - try: - about_text = script.ABOUT_TXT.format(temp.U_NAME) - except Exception: - about_text = script.ABOUT_TXT - try: - await query.message.edit_text( - text=about_text, - reply_markup=reply_markup, - disable_web_page_preview=True, - parse_mode=enums.ParseMode.HTML - ) - except Exception: - # For newer Pyrogram where disable_web_page_preview not allowed in edit_text - await query.message.edit_text( - text=about_text, - reply_markup=reply_markup, - parse_mode=enums.ParseMode.HTML - ) + await query.message.edit_text( + text=script.ABOUT_TXT.format(temp.U_NAME, temp.B_NAME, OWNER_LNK), + reply_markup=reply_markup, + link_preview_options=LinkPreviewOptions(is_disabled=True), + parse_mode=enums.ParseMode.HTML + ) elif query.data == "give_trial": try: @@ -1685,9 +1669,9 @@ async def _schedule_delete(sent_obj, orig_msg, delay): await m.delete() except Exception as e: logger.exception(e) - sent = await message.reply_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) + sent = await message.reply_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), link_preview_options=LinkPreviewOptions(is_disabled=True), parse_mode=enums.ParseMode.HTML) else: - sent = await message.reply_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=True, parse_mode=enums.ParseMode.HTML) + sent = await message.reply_text(text=cap, reply_markup=InlineKeyboardMarkup(btn), link_preview_options=LinkPreviewOptions(is_disabled=True), parse_mode=enums.ParseMode.HTML) if m: await m.delete() except Exception as e: From 64a2cc6bba34ebf7c4285ae5cce03682ba94b0b0 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Mon, 14 Sep 2026 19:44:00 +0530 Subject: [PATCH 22/77] Update channel.py --- plugins/channel.py | 54 ++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/plugins/channel.py b/plugins/channel.py index 291f62f5..9bc164ad 100644 --- a/plugins/channel.py +++ b/plugins/channel.py @@ -247,28 +247,44 @@ def _strip_season_episode_tokens(name: str) -> str: "language": language } - -@Client.on_message(filters.chat(CHANNELS) & MEDIA_FILTER) +@Client.on_message(filters.chat(CHANNELS) & (filters.document | filters.video | filters.audio)) async def media_handler(bot, message): - media = next( - (getattr(message, ft) for ft in ("document", "video", "audio") - if getattr(message, ft, None)), - None - ) - if not media: - return + success = False + try: + media = message.document or message.video or message.audio + if not media: + return - media.file_type = next(ft for ft in ("document", "video", "audio") if getattr(message, ft, None)) - media.caption = message.caption or "" - success, info = await save_file(media) - if not success: - return + file_id = media.file_id + file_name = getattr(media, "file_name", "") + file_size = getattr(media, "file_size", 0) - try: - if await db.movie_update_status(bot.me.id): - await process_and_send_update(bot, media.file_name, media.caption) - except Exception: - logger.exception("Error processing media") + logger.info(f"File from {message.chat.id}: {file_name}") + + media.file_type = next((ft for ft in ("document", "video", "audio") if getattr(message, ft, None)), None) + media.caption = message.caption or "" + + lock = locks[file_id] + async with lock: + success, info = await save_file(media) + if success: + print("File saved") + + except DuplicateKeyError: + pass + except FloodWait as e: + await asyncio.sleep(e.value) + except PyMongoError as e: + logger.error(f"MongoDB Error in media_handler: {e}") + except Exception as e: + logger.exception(f"Error processing media: {e}") + + if success: + try: + if await db.movie_update_status(bot.me.id): + await process_and_send_update(bot, file_name, message.caption) + except Exception as e: + logger.exception("Error in movie update") async def process_and_send_update(bot, filename, caption): try: From bc0b76353dc940e5e8fa904cb9f596e9b69b5678 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Mon, 14 Sep 2026 20:32:03 +0530 Subject: [PATCH 23/77] Update Pmfilter.py --- plugins/pmfilter.py | 49 --------------------------------------------- 1 file changed, 49 deletions(-) diff --git a/plugins/pmfilter.py b/plugins/pmfilter.py index 6a583eb2..a2df2f5f 100644 --- a/plugins/pmfilter.py +++ b/plugins/pmfilter.py @@ -1096,55 +1096,6 @@ async def cb_handler(client: Client, query: CallbackQuery): else: await query.answer("Yᴏᴜ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ ᴘᴇʀᴍɪssɪᴏɴ ᴛᴏ sᴇᴇ ᴛʜɪs ❌", show_alert=True) - elif DreamxData.startswith("generate_stream_link"): - _, file_id = DreamxData.split(":") - try: - user_id = query.from_user.id - username = query.from_user.mention - log_msg = await client.send_cached_media(chat_id=BIN_CHANNEL, file_id=file_id,) - fileName = quote_plus(get_name(log_msg)) - dreamx_stream = f"{URL}watch/{str(log_msg.id)}/{quote_plus(get_name(log_msg))}?hash={get_hash(log_msg)}" - dreamx_download = f"{URL}{str(log_msg.id)}/{quote_plus(get_name(log_msg))}?hash={get_hash(log_msg)}" - await query.answer(MSG_ALRT) - await asyncio.sleep(1) - await log_msg.reply_text( - text=f"•• ʟɪɴᴋ ɢᴇɴᴇʀᴀᴛᴇᴅ ꜰᴏʀ ɪᴅ #{user_id} \n•• ᴜꜱᴇʀɴᴀᴍᴇ : {username} \n\n•• ᖴᎥᒪᗴ Nᗩᗰᗴ : {fileName}", - link_preview_options=LinkPreviewOptions(is_disabled=True), - reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ 🚀", url=dreamx_download), # we download Link - InlineKeyboardButton('🖥️ ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥️', url=dreamx_stream)]]) # web stream Link - ) - dreamcinezone = await query.edit_message_reply_markup( - reply_markup=InlineKeyboardMarkup([ - [ - InlineKeyboardButton("🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ 🚀", url=dreamx_download), - InlineKeyboardButton('🖥 ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', url=dreamx_stream) - ], - [ - InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK) - ] - ]) - ) - await asyncio.sleep(DELETE_TIME) - await dreamcinezone.delete() - return - except Exception as e: - logger.error("Callback error: %s", e) - await query.answer(f"⚠ SOMETHING WENT WRONG STREAM LINK \n\n{e}", show_alert=True) - return - - elif query.data == "prestream": - await query.answer(text=script.PRE_STREAM_ALERT, show_alert=True) - dreamcinezone = await client.send_photo( - chat_id=query.message.chat.id, - photo="https://i.ibb.co/whf8xF7j/photo-2025-07-26-10-42-46-7531339305176793100.jpg", - caption=script.PRE_STREAM, - reply_markup=InlineKeyboardMarkup([ - [InlineKeyboardButton("🚀 Buy Premium 🚀", callback_data="premium_info")] - ]) - ) - await asyncio.sleep(DELETE_TIME) - await dreamcinezone.delete() - elif query.data == "start": buttons = [[ InlineKeyboardButton('🔰 ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://telegram.me/{temp.U_NAME}?startgroup=true') From ad7ec358d50551a225dd80b41927ba8165948520 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Mon, 14 Sep 2026 20:39:26 +0530 Subject: [PATCH 24/77] Update Commands.py --- plugins/commands.py | 50 +++++++++++++++------------------------------ 1 file changed, 16 insertions(+), 34 deletions(-) diff --git a/plugins/commands.py b/plugins/commands.py index ae21b9f2..0390712e 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -69,25 +69,28 @@ async def start(client, message): msg = script.THIRDT_VERIFY_COMPLETE_TEXT else: msg = script.SECOND_VERIFY_COMPLETE_TEXT if key == "second_time_verified" else script.VERIFY_COMPLETE_TEXT - if message.command[1].startswith('sendall'): - verifiedfiles = f"https://telegram.me/{temp.U_NAME}?start=allfiles_{grp_id}_{file_id}" - else: - verifiedfiles = f"https://telegram.me/{temp.U_NAME}?start=file_{grp_id}_{file_id}" + await client.send_message(settings['log'], script.VERIFIED_LOG_TEXT.format(m.from_user.mention, user_id, datetime.now(pytz.timezone('Asia/Kolkata')).strftime('%d %B %Y'), num)) - btn = [[ - InlineKeyboardButton("✅ ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ɢᴇᴛ ꜰɪʟᴇ ✅", url=verifiedfiles), - ]] - reply_markup=InlineKeyboardMarkup(btn) + dlt=await m.reply_photo( photo=(VERIFY_IMG), caption=msg.format(message.from_user.mention, get_readable_time(TWO_VERIFY_GAP)), - reply_markup=reply_markup, parse_mode=enums.ParseMode.HTML ) - await asyncio.sleep(300) - await dlt.delete() - return + async def _delete_msg(msg_to_delete, delay): + await asyncio.sleep(delay) + try: + await msg_to_delete.delete() + except Exception: + pass + asyncio.create_task(_delete_msg(dlt, 300)) + + if message.command[1].startswith('sendall'): + message.command[1] = f"allfiles_{grp_id}_{file_id}" + else: + message.command[1] = f"file_{grp_id}_{file_id}" + if message.chat.type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: buttons = [[ InlineKeyboardButton('❤ ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ ❤', url=f'http://t.me/{temp.U_NAME}?startgroup=true') @@ -415,7 +418,6 @@ async def start(client, message): except Exception: return await msg.edit_caption(f_caption, reply_markup=InlineKeyboardMarkup(btn)) - # FIXED: removed k = await msg.reply(script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) await asyncio.sleep(DELETE_TIME) await msg.delete() @@ -464,27 +466,7 @@ async def start(client, message): pass async def stream_buttons(user_id: int, file_id: str): - if STREAM_MODE and not PREMIUM_STREAM_MODE: - return [ - [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], - [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], - [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] - ] - elif STREAM_MODE and PREMIUM_STREAM_MODE: - if not await db.has_premium_access(user_id): - return [ - [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data='prestream')], - [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data='prestream')], - [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] - ] - else: - return [ - [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], - [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], - [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] - ] - else: - return [[InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)]] + return [[InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)]] @Client.on_message(filters.command('logs') & filters.user(ADMINS)) async def log_file(bot, message): From 1906b6c45318035f8ca180acce13cc1ed0ced970 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Mon, 14 Sep 2026 20:56:37 +0530 Subject: [PATCH 25/77] Update Commands.py --- plugins/commands.py | 144 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 133 insertions(+), 11 deletions(-) diff --git a/plugins/commands.py b/plugins/commands.py index 0390712e..0a9139c8 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -61,36 +61,137 @@ async def start(client, message): current_time = datetime.now(tz=ist_timezone) await db.update_notcopy_user(user_id, {key:current_time}) await db.update_verify_id_info(user_id, verify_id, {"verified":True}) + if key == "third_time_verified": num = 3 + msg = script.THIRDT_VERIFY_COMPLETE_TEXT else: num = 2 if key == "second_time_verified" else 1 - if key == "third_time_verified": - msg = script.THIRDT_VERIFY_COMPLETE_TEXT - else: msg = script.SECOND_VERIFY_COMPLETE_TEXT if key == "second_time_verified" else script.VERIFY_COMPLETE_TEXT - await client.send_message(settings['log'], script.VERIFIED_LOG_TEXT.format(m.from_user.mention, user_id, datetime.now(pytz.timezone('Asia/Kolkata')).strftime('%d %B %Y'), num)) + log_channel = settings.get('log') if settings.get('log') else LOG_CHANNEL + try: + await client.send_message(log_channel, script.VERIFIED_LOG_TEXT.format(m.from_user.mention, user_id, datetime.now(pytz.timezone('Asia/Kolkata')).strftime('%d %B %Y'), num)) + except Exception as e: + logger.error(f"Failed to log verification: {e}") - dlt=await m.reply_photo( + # Send Verification Complete message + dlt = await m.reply_photo( photo=(VERIFY_IMG), caption=msg.format(message.from_user.mention, get_readable_time(TWO_VERIFY_GAP)), parse_mode=enums.ParseMode.HTML ) - + async def _delete_msg(msg_to_delete, delay): await asyncio.sleep(delay) try: await msg_to_delete.delete() except Exception: pass + asyncio.create_task(_delete_msg(dlt, 300)) + + # Send files automatically + is_sendall = m.command[1].startswith('sendall') + decoded_file_id = file_id + if not is_sendall: + try: + raw = base64.urlsafe_b64decode(file_id + "=" * (-len(file_id) % 4)) + sep = raw.find(b"_") + if sep != -1: + decoded_file_id = raw[sep + 1:].decode("latin1") + except Exception: + pass + + filesarr = [] - if message.command[1].startswith('sendall'): - message.command[1] = f"allfiles_{grp_id}_{file_id}" + if is_sendall: + files = temp.GETALL.get(file_id) + if not files: + await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ !') + return + for file in files: + file_id_item = file.file_id + files_ = await get_file_details(file_id_item) + if not files_: + continue + files1 = files_[0] + title = clean_filename(files1.file_name) + cover = files1.cover + size = get_size(files1.file_size) + f_caption = files1.caption + + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) + if DREAMX_CAPTION: + try: + f_caption = DREAMX_CAPTION.format(file_name='' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) + except Exception as e: + logger.exception(e) + + if f_caption is None: + f_caption = f"{clean_filename(files1.file_name)}" + + btn = await stream_buttons(message.from_user.id, file_id_item) + sent_msg = await client.send_cached_media( + chat_id=message.from_user.id, + cover=cover, + file_id=file_id_item, + caption=f_caption, + protect_content=settings.get('file_secure', PROTECT_CONTENT), + reply_markup=InlineKeyboardMarkup(btn) + ) + filesarr.append(sent_msg) else: - message.command[1] = f"file_{grp_id}_{file_id}" - + files_ = await get_file_details(decoded_file_id) + if not files_: + await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ !') + return + files1 = files_[0] + title = clean_filename(files1.file_name) + size = get_size(files1.file_size) + cover = files1.cover if files1.cover else None + f_caption = files1.caption + + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) + if DREAMX_CAPTION: + try: + f_caption = DREAMX_CAPTION.format(file_name='' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) + except Exception as e: + logger.exception(e) + + if f_caption is None: + f_caption = clean_filename(files1.file_name) + + btn = await stream_buttons(message.from_user.id, decoded_file_id) + sent_msg = await client.send_cached_media( + chat_id=message.from_user.id, + file_id=decoded_file_id, + cover=cover, + caption=f_caption, + protect_content=settings.get('file_secure', PROTECT_CONTENT), + reply_markup=InlineKeyboardMarkup(btn) + ) + filesarr.append(sent_msg) + + # Auto-Delete Logic + if settings.get('auto_delete', True) and filesarr: + k = await client.send_message(chat_id=message.from_user.id, text=script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) + + async def _delete_files(msgs, notif_msg, delay): + await asyncio.sleep(delay) + for x in msgs: + try: + await x.delete() + except Exception: + pass + try: + await notif_msg.edit_text("ʏᴏᴜʀ ᴠɪᴅᴇᴏꜱ/ꜰɪʟᴇꜱ ᴀʀᴇ ᴅᴇʟᴇᴛᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ !\nᴋɪɴᴅʟʏ ꜱᴇᴀʀᴄʜ ᴀɢᴀɪɴ") + except Exception: + pass + + asyncio.create_task(_delete_files(filesarr, k, DELETE_TIME)) + + return if message.chat.type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: buttons = [[ InlineKeyboardButton('❤ ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ ❤', url=f'http://t.me/{temp.U_NAME}?startgroup=true') @@ -418,6 +519,7 @@ async def _delete_msg(msg_to_delete, delay): except Exception: return await msg.edit_caption(f_caption, reply_markup=InlineKeyboardMarkup(btn)) + # FIXED: removed k = await msg.reply(script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) await asyncio.sleep(DELETE_TIME) await msg.delete() @@ -466,7 +568,27 @@ async def _delete_msg(msg_to_delete, delay): pass async def stream_buttons(user_id: int, file_id: str): - return [[InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)]] + if STREAM_MODE and not PREMIUM_STREAM_MODE: + return [ + [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], + [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], + [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] + ] + elif STREAM_MODE and PREMIUM_STREAM_MODE: + if not await db.has_premium_access(user_id): + return [ + [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data='prestream')], + [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data='prestream')], + [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] + ] + else: + return [ + [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], + [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], + [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] + ] + else: + return [[InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)]] @Client.on_message(filters.command('logs') & filters.user(ADMINS)) async def log_file(bot, message): From 24d085b0fcabeb2bd5a70f3b6b17501f802605a6 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Mon, 14 Sep 2026 21:48:47 +0530 Subject: [PATCH 26/77] Update Script.py --- Script.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Script.py b/Script.py index c8073e1d..1796bd80 100644 --- a/Script.py +++ b/Script.py @@ -424,12 +424,12 @@ class script(object): ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴅɪʀᴇᴄᴛ ꜰɪʟᴇs ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ᴛᴀᴋᴇ ᴘʀᴇᴍɪᴜᴍ sᴇʀᴠɪᴄᴇ (ɴᴏ ɴᴇᴇᴅ ᴛᴏ ᴠᴇʀɪꜰʏ).""" - VERIFY_COMPLETE_TEXT = """👋 ʜᴇʏ {}, - -ʏᴏᴜ ʜᴀᴠᴇ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ᴛʜᴇ 1ꜱᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ ✓ - -ɴᴏᴡ ʏᴏᴜ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ꜰᴏʀ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ.""" + VERIFY_COMPLETE_TEXT = """👋 Hᴇʏ {} ❤, + +Yᴏᴜ ʜᴀᴠᴇ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ᴛʜᴇ 1sᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ ✅ +Nᴏᴡ ʏᴏᴜ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ғᴏʀ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ.""" + SECOND_VERIFICATION_TEXT = """👋 ʜᴇʏ {}, 📌 ʏᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ, ᴛᴀᴘ ᴏɴ ᴛʜᴇ ᴠᴇʀɪꜰʏ ʟɪɴᴋ ᴀɴᴅ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ꜰᴏʀ ᴛɪʟʟ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ. @@ -438,11 +438,11 @@ class script(object): ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴅɪʀᴇᴄᴛ ꜰɪʟᴇs ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ᴛᴀᴋᴇ ᴘʀᴇᴍɪᴜᴍ sᴇʀᴠɪᴄᴇ (ɴᴏ ɴᴇᴇᴅ ᴛᴏ ᴠᴇʀɪꜰʏ).""" - SECOND_VERIFY_COMPLETE_TEXT = """👋 ʜᴇʏ {}, + SECOND_VERIFY_COMPLETE_TEXT = """👋 Hᴇʏ {} ❤, -ʏᴏᴜ ʜᴀᴠᴇ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ᴛʜᴇ 2ɴᴅ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ ✓ +Yᴏᴜ ʜᴀᴠᴇ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ᴛʜᴇ 2ɴᴅ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ ✅ -ɴᴏᴡ ʏᴏᴜ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ꜰᴏʀ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ.""" +Nᴏᴡ ʏᴏᴜ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ғᴏʀ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ.""" THIRDT_VERIFICATION_TEXT = """👋 ʜᴇʏ {}, @@ -452,11 +452,11 @@ class script(object): ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴅɪʀᴇᴄᴛ ꜰɪʟᴇs ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ᴛᴀᴋᴇ ᴘʀᴇᴍɪᴜᴍ sᴇʀᴠɪᴄᴇ (ɴᴏ ɴᴇᴇᴅ ᴛᴏ ᴠᴇʀɪꜰʏ)""" - THIRDT_VERIFY_COMPLETE_TEXT= """👋 ʜᴇʏ {}, + THIRDT_VERIFY_COMPLETE_TEXT = """👋 Hᴇʏ {} ❤, -ʏᴏᴜ ʜᴀᴠᴇ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ᴛʜᴇ 3ʀᴅ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ ✓ +Yᴏᴜ ʜᴀᴠᴇ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ᴛʜᴇ 3ʀᴅ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ ✅ -ɴᴏᴡ ʏᴏᴜ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ꜰᴏʀ ɴᴇxᴛ ꜰᴜʟʟ ᴅᴀʏ.""" +Nᴏᴡ ʏᴏᴜ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ғᴏʀ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ.""" VERIFIED_LOG_TEXT = """ᴜꜱᴇʀ ᴠᴇʀɪꜰɪᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ✓ From 37f4c1aca4b91309d421f0d643f1fdb2d7ab9912 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Mon, 14 Sep 2026 21:52:26 +0530 Subject: [PATCH 27/77] Update commands.py --- plugins/commands.py | 1501 ++----------------------------------------- 1 file changed, 44 insertions(+), 1457 deletions(-) diff --git a/plugins/commands.py b/plugins/commands.py index 0a9139c8..c772e744 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -1,57 +1,11 @@ -import os -import re -import base64 -import logging -import random -import asyncio -import string -import sys -import pytz -from .pmfilter import auto_filter -from Script import script -from datetime import datetime, timedelta -from database.refer import referdb -from database.config_db import mdb -from pyrogram.types import LinkPreviewOptions, InlineKeyboardButton, InlineKeyboardMarkup, Message, ReplyKeyboardMarkup -from pyrogram import Client, filters, enums, StopPropagation -from pyrogram.errors import FloodWait, UserNotParticipant , ChannelInvalid, PeerIdInvalid -from database.ia_filterdb import Media, Media2, get_file_details, unpack_new_file_id, get_bad_files, save_file -from database.users_chats_db import db -from info import ( - LOG_CHANNEL, IMDB_TEMPLATE, IS_VERIFY, TUTORIAL, TUTORIAL_2, TUTORIAL_3, EMOJI_MODE, REACTIONS, - VERIFY_IMG, TWO_VERIFY_GAP, UPDATE_CHNL_LNK, PICS, PICS_URL, ADMINS, SUBSCRIPTION, OWNER_LNK , - OWNER_UPI_ID, QR_CODE, AUTH_CHANNELS, AUTH_REQ_CHANNELS, FSUB_PICS, THREE_VERIFY_GAP, CUSTOM_FILE_CAPTION, - COVERX, PROTECT_CONTENT, DELETE_TIME, PREMIUM_STREAM_MODE, STREAM_MODE, SUPPORT_CHAT_ID, REQST_CHANNEL, - LOG_CHANNEL, SHORTENER_API, SHORTENER_API2, SHORTENER_API3, SHORTENER_WEBSITE, SHORTENER_WEBSITE2, SHORTENER_WEBSITE3, - -) -from utils import get_settings, save_group_settings, is_subscribed, is_req_subscribed, get_size, get_shortlink, is_check_admin, temp, get_readable_time, get_time, generate_settings_text, log_error, clean_filename, get_random_mix_id - -logger = logging.getLogger(__name__) - -TIMEZONE = "Asia/Kolkata" -BATCH_FILES = {} -REQUEST_INVITE_LINK_CACHE: dict[int, str] = {} - - -@Client.on_message(filters.command("start") & filters.incoming) -async def start(client, message): - try: - if EMOJI_MODE: - try: - asyncio.create_task(message.react(emoji=random.choice(REACTIONS), big=True)) - except Exception: - asyncio.create_task(message.react(emoji="⚡")) - pass - m = message if len(m.command) == 2 and m.command[1].startswith(('notcopy', 'sendall')): _, userid, verify_id, file_id = m.command[1].split("_", 3) user_id = int(userid) grp_id = temp.VERIFICATIONS.get(user_id, 0) - settings = await get_settings(grp_id) + settings = await get_settings(grp_id) verify_id_info = await db.get_verify_id_info(user_id, verify_id) if not verify_id_info or verify_id_info["verified"]: - return await message.reply(script.LINK_EXPIRED_TXT) + return await message.reply(script.LINK_EXPIRED_TXT) ist_timezone = pytz.timezone('Asia/Kolkata') if await db.user_verified(user_id): @@ -61,54 +15,63 @@ async def start(client, message): current_time = datetime.now(tz=ist_timezone) await db.update_notcopy_user(user_id, {key:current_time}) await db.update_verify_id_info(user_id, verify_id, {"verified":True}) - - if key == "third_time_verified": - num = 3 + + if key == "third_time_verified": + num = 3 msg = script.THIRDT_VERIFY_COMPLETE_TEXT - else: - num = 2 if key == "second_time_verified" else 1 + else: + num = 2 if key == "second_time_verified" else 1 msg = script.SECOND_VERIFY_COMPLETE_TEXT if key == "second_time_verified" else script.VERIFY_COMPLETE_TEXT - - log_channel = settings.get('log') if settings.get('log') else LOG_CHANNEL + + log_channel = settings.get('log') if settings and settings.get('log') else LOG_CHANNEL try: await client.send_message(log_channel, script.VERIFIED_LOG_TEXT.format(m.from_user.mention, user_id, datetime.now(pytz.timezone('Asia/Kolkata')).strftime('%d %B %Y'), num)) except Exception as e: logger.error(f"Failed to log verification: {e}") - - # Send Verification Complete message + + # Send Verification Complete message with the custom image & button + is_sendall = m.command[1].startswith('sendall') + if is_sendall: + verifiedfiles = f"https://telegram.me/{temp.U_NAME}?start=allfiles_{grp_id}_{file_id}" + else: + verifiedfiles = f"https://telegram.me/{temp.U_NAME}?start=file_{grp_id}_{file_id}" + + btn_complete = [[ + InlineKeyboardButton("🫶🏻 Cʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ɢᴇᴛ ғɪʟᴇ 🕊", url=verifiedfiles), + ]] dlt = await m.reply_photo( - photo=(VERIFY_IMG), - caption=msg.format(message.from_user.mention, get_readable_time(TWO_VERIFY_GAP)), + photo="https://i.ibb.co/1tDXygyb/image.webp", + caption=msg.format(m.from_user.mention), + reply_markup=InlineKeyboardMarkup(btn_complete), parse_mode=enums.ParseMode.HTML ) - + async def _delete_msg(msg_to_delete, delay): await asyncio.sleep(delay) try: await msg_to_delete.delete() except Exception: pass - + asyncio.create_task(_delete_msg(dlt, 300)) - # Send files automatically - is_sendall = m.command[1].startswith('sendall') + # Send files automatically WITHOUT stream buttons decoded_file_id = file_id if not is_sendall: try: raw = base64.urlsafe_b64decode(file_id + "=" * (-len(file_id) % 4)) sep = raw.find(b"_") - if sep != -1: + if sep!= -1: decoded_file_id = raw[sep + 1:].decode("latin1") except Exception: pass filesarr = [] - + if is_sendall: files = temp.GETALL.get(file_id) if not files: - await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ !') + await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ!') return for file in files: file_id_item = file.file_id @@ -120,63 +83,59 @@ async def _delete_msg(msg_to_delete, delay): cover = files1.cover size = get_size(files1.file_size) f_caption = files1.caption - - DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) + + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION if DREAMX_CAPTION: try: f_caption = DREAMX_CAPTION.format(file_name='' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) except Exception as e: logger.exception(e) - + if f_caption is None: f_caption = f"{clean_filename(files1.file_name)}" - - btn = await stream_buttons(message.from_user.id, file_id_item) + sent_msg = await client.send_cached_media( chat_id=message.from_user.id, cover=cover, file_id=file_id_item, caption=f_caption, - protect_content=settings.get('file_secure', PROTECT_CONTENT), - reply_markup=InlineKeyboardMarkup(btn) + protect_content=settings.get('file_secure', PROTECT_CONTENT) if settings else PROTECT_CONTENT ) filesarr.append(sent_msg) else: files_ = await get_file_details(decoded_file_id) if not files_: - await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ !') + await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ!') return files1 = files_[0] title = clean_filename(files1.file_name) size = get_size(files1.file_size) cover = files1.cover if files1.cover else None f_caption = files1.caption - - DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) + + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION if DREAMX_CAPTION: try: f_caption = DREAMX_CAPTION.format(file_name='' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) except Exception as e: logger.exception(e) - + if f_caption is None: f_caption = clean_filename(files1.file_name) - - btn = await stream_buttons(message.from_user.id, decoded_file_id) + sent_msg = await client.send_cached_media( chat_id=message.from_user.id, file_id=decoded_file_id, cover=cover, caption=f_caption, - protect_content=settings.get('file_secure', PROTECT_CONTENT), - reply_markup=InlineKeyboardMarkup(btn) + protect_content=settings.get('file_secure', PROTECT_CONTENT) if settings else PROTECT_CONTENT ) filesarr.append(sent_msg) # Auto-Delete Logic - if settings.get('auto_delete', True) and filesarr: + if settings and settings.get('auto_delete', True) and filesarr: k = await client.send_message(chat_id=message.from_user.id, text=script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) - + async def _delete_files(msgs, notif_msg, delay): await asyncio.sleep(delay) for x in msgs: @@ -185,1382 +144,10 @@ async def _delete_files(msgs, notif_msg, delay): except Exception: pass try: - await notif_msg.edit_text("ʏᴏᴜʀ ᴠɪᴅᴇᴏꜱ/ꜰɪʟᴇꜱ ᴀʀᴇ ᴅᴇʟᴇᴛᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ !\nᴋɪɴᴅʟʏ ꜱᴇᴀʀᴄʜ ᴀɢᴀɪɴ") + await notif_msg.edit_text("ʏᴏᴜʀ ᴠɪᴅᴇᴏꜱ/ꜰɪʟᴇꜱ ᴀʀᴇ ᴅᴇʟᴇᴛᴇᴅ ꜱᴜᴄᴄᴇꜱꜰᴜʟʟʏ!\nᴋɪɴᴅʟʏ ꜱᴇᴀʀᴄʜ ᴀɢᴀɪɴ") except Exception: pass - - asyncio.create_task(_delete_files(filesarr, k, DELETE_TIME)) - - return - if message.chat.type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: - buttons = [[ - InlineKeyboardButton('❤ ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ ❤', url=f'http://t.me/{temp.U_NAME}?startgroup=true') - ],[ - InlineKeyboardButton('🍁 Update Channel 🍁', url=UPDATE_CHNL_LNK) - ]] - reply_markup = InlineKeyboardMarkup(buttons) - await message.reply(script.GSTART_TXT.format(message.from_user.mention if message.from_user else message.chat.title, temp.U_NAME, temp.B_NAME), reply_markup=reply_markup, link_preview_options=LinkPreviewOptions(is_disabled=True)) - - await asyncio.sleep(2) - if not await db.get_chat(message.chat.id): - total=await client.get_chat_members_count(message.chat.id) - await client.send_message(LOG_CHANNEL, script.LOG_TEXT_G.format(message.chat.title, message.chat.id, total, "Unknown")) - await db.add_chat(message.chat.id, message.chat.title) - return - if not await db.is_user_exist(message.from_user.id): - await db.add_user(message.from_user.id, message.from_user.first_name) - await client.send_message(LOG_CHANNEL, script.LOG_TEXT_P.format(message.from_user.id, message.from_user.mention)) - if len(message.command) != 2: - buttons = [[ - InlineKeyboardButton('🔰 ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://t.me/{temp.U_NAME}?startgroup=true') - ],[ - InlineKeyboardButton(' ʜᴇʟᴘ 📢', callback_data='help'), - InlineKeyboardButton(' ᴀʙᴏᴜᴛ 📖', callback_data='about') - ],[ - InlineKeyboardButton('ᴛᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), - InlineKeyboardButton('ᴜᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), - ]] - reply_markup = InlineKeyboardMarkup(buttons) - current_time = datetime.now(pytz.timezone(TIMEZONE)) - curr_time = current_time.hour - if curr_time < 12: - gtxt = "ɢᴏᴏᴅ ᴍᴏʀɴɪɴɢ 🌞" - elif curr_time < 17: - gtxt = "ɢᴏᴏᴅ ᴀғᴛᴇʀɴᴏᴏɴ 🌓" - elif curr_time < 21: - gtxt = "ɢᴏᴏᴅ ᴇᴠᴇɴɪɴɢ 🌘" - else: - gtxt = "ɢᴏᴏᴅ ɴɪɢʜᴛ 🌑" - if len(PICS) == 1: - PIC = PICS[0] - else: - try: - PIC = f"{random.choice(PICS_URL)}?r={get_random_mix_id()}" - except Exception: - PIC = random.choice(PICS) - await message.reply_photo( - photo=PIC, - caption=script.START_TXT.format(message.from_user.mention, gtxt, temp.U_NAME, temp.B_NAME), - reply_markup=reply_markup, - parse_mode=enums.ParseMode.HTML - ) - return - - if len(message.command) == 2 and message.command[1] in ["subscribe", "error", "okay", "help"]: - buttons = [[ - InlineKeyboardButton('🔰 ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://t.me/{temp.U_NAME}?startgroup=true') - ],[ - InlineKeyboardButton(' ʜᴇʟᴘ 📢', callback_data='help'), - InlineKeyboardButton(' ᴀʙᴏᴜᴛ 📖', callback_data='about') - ],[ - InlineKeyboardButton('ᴛᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), - InlineKeyboardButton('ᴜᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), - ]] - reply_markup = InlineKeyboardMarkup(buttons) - current_time = datetime.now(pytz.timezone(TIMEZONE)) - curr_time = current_time.hour - if curr_time < 12: - gtxt = "ɢᴏᴏᴅ ᴍᴏʀɴɪɴɢ 🌞" - elif curr_time < 17: - gtxt = "ɢᴏᴏᴅ ᴀғᴛᴇʀɴᴏᴏɴ 🌓" - elif curr_time < 21: - gtxt = "ɢᴏᴏᴅ ᴇᴠᴇɴɪɴɢ 🌘" - else: - gtxt = "ɢᴏᴏᴅ ɴɪɢʜᴛ 🌑" - if len(PICS) == 1: - PIC = PICS[0] - else: - try: - PIC = f"{random.choice(PICS_URL)}?r={get_random_mix_id()}" - except Exception: - PIC = random.choice(PICS) - await message.reply_photo( - photo=PIC, - caption=script.START_TXT.format(message.from_user.mention, gtxt, temp.U_NAME, temp.B_NAME), - reply_markup=reply_markup, - parse_mode=enums.ParseMode.HTML - ) - return - if message.command[1].startswith("reff_"): - try: - user_id = int(message.command[1].split("_")[1]) - except ValueError: - await message.reply_text("‼ ɪɴᴠᴀʟɪᴅ ʀᴇꜰᴇʀ!") - return - if user_id == message.from_user.id: - await message.reply_text(script.REFER_SELF_ALRT) - return - if referdb.is_user_in_list(message.from_user.id): - await message.reply_text(script.REFER_ALREADY_ALRT) - return - if await db.is_user_exist(message.from_user.id): - await message.reply_text(script.REFER_ALREADY_JOINED_ALRT) - return - try: - uss = await client.get_users(user_id) - except Exception: - return - referdb.add_user(message.from_user.id) - fromuse = referdb.get_refer_points(user_id) + 10 - if fromuse == 100: - referdb.add_refer_points(user_id, 0) - await message.reply_text(script.REFER_INVITED_ALRT.format(uss.mention)) - await client.send_message(chat_id=user_id, text=script.REFER_CONGRATS_ALRT.format(message.from_user.mention)) - seconds = 2592000 - if seconds > 0: - expiry_time = datetime.now() + timedelta(seconds=seconds) - user_data = {"id": user_id, "expiry_time": expiry_time} - await db.update_user(user_data) - await client.send_message( - chat_id=user_id, - text=f"Hᴇʏ {uss.mention}\n\nYᴏᴜ ɢᴏᴛ 1 ᴍᴏɴᴛʜ ᴘʀᴇᴍɪᴜᴍ sᴜʙsᴄʀɪᴘᴛɪᴏɴ ʙʏ ɪɴᴠɪᴛɪɴɢ 10 ᴜsᴇʀs ❗", - link_preview_options=LinkPreviewOptions(is_disabled=True) - ) - for admin in ADMINS: - await client.send_message(chat_id=admin, text=f"Sᴜᴄᴄᴇss ғᴜʟʟʏ ᴛᴀsᴋ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ʙʏ ᴛʜɪs ᴜsᴇʀ:\n\nuser Nᴀᴍᴇ: {uss.mention}\n\nUsᴇʀ ɪᴅ: {uss.id}!") - else: - referdb.add_refer_points(user_id, fromuse) - await message.reply_text(script.REFER_INVITED_ALRT.format(uss.mention)) - await client.send_message(user_id, script.REFER_CONGRATS_ALRT.format(message.from_user.mention)) - return - - if len(message.command) == 2 and message.command[1] in ["premium"]: - buttons = [[ - InlineKeyboardButton('📲 ꜱᴇɴᴅ ᴘᴀʏᴍᴇɴᴛ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ', url=OWNER_LNK) - ],[ - InlineKeyboardButton('UPI ID Copy Karein ??', copy_text=OWNER_UPI_ID) - ],[ - InlineKeyboardButton('❌ ᴄʟᴏꜱᴇ ❌', callback_data='close_data') - ]] - reply_markup = InlineKeyboardMarkup(buttons) - await message.reply_photo( - photo=(SUBSCRIPTION), - caption=script.PREPLANS_TXT.format(message.from_user.mention, OWNER_UPI_ID, QR_CODE), - reply_markup=reply_markup, - parse_mode=enums.ParseMode.HTML - ) - return - - if len(message.command) == 2 and message.command[1].startswith('getfile'): - movies = message.command[1].split("-", 1)[1] - movie = movies.replace('-',' ') - message.text = movie - await auto_filter(client, message) - raise StopPropagation - - data = message.command[1] - try: - _, grp_id, file_id = data.split("_", 2) - grp_id = int(grp_id) - except Exception: - grp_id = 0 - file_id = data - - decoded_file_id = file_id - if not data.startswith("allfiles"): - try: - raw = base64.urlsafe_b64decode(file_id + "=" * (-len(file_id) % 4)) - sep = raw.find(b"_") - if sep != -1: - decoded_file_id = raw[sep + 1:].decode("latin1") - except Exception: - pass - - file_details_task = asyncio.create_task(get_file_details(decoded_file_id)) - if not await db.has_premium_access(message.from_user.id): - try: - btn = [] - chat = grp_id - settings = await get_settings(chat) - fsub_channels = list(dict.fromkeys((settings.get('fsub', []) if settings else [])+ AUTH_CHANNELS)) - - if fsub_channels: - btn += await is_subscribed(client, message.from_user.id, fsub_channels) - if AUTH_REQ_CHANNELS: - btn += await is_req_subscribed(client, message.from_user.id, AUTH_REQ_CHANNELS) - if btn: - if len(message.command) > 1 and "_" in message.command[1]: - kk, file_id = message.command[1].split("_", 1) - btn.append([ - InlineKeyboardButton("♻ ᴛʀʏ ᴀɢᴀɪɴ ♻", callback_data=f"checksub#{kk}#{file_id}") - ]) - reply_markup = InlineKeyboardMarkup(btn) - photo = random.choice(FSUB_PICS) if FSUB_PICS else "https://graph.org/file/7478ff3eac37f4329c3d8.jpg" - caption = script.FORCESUB_TXT.format(message.from_user.mention) - await message.reply_photo( - photo=photo, - caption=caption, - reply_markup=reply_markup, - parse_mode=enums.ParseMode.HTML - ) - return - - except Exception as e: - await log_error(client, f"❗ Force Sub Error:\n\n{repr(e)}") - logger.error(f"❗ Force Sub Error:\n\n{repr(e)}") - - user_id = m.from_user.id - if not await db.has_premium_access(user_id): - try: - grp_id = int(grp_id) - user_verified = await db.is_user_verified(user_id) - settings = await get_settings(grp_id) - is_second_shortener = await db.use_second_shortener(user_id, settings.get('verify_time', TWO_VERIFY_GAP)) - is_third_shortener = await db.use_third_shortener(user_id, settings.get('third_verify_time', THREE_VERIFY_GAP)) - if settings.get("is_verify", IS_VERIFY) and (not user_verified or is_second_shortener or is_third_shortener): - verify_id = ''.join(random.choices(string.ascii_uppercase + string.digits, k=7)) - await db.create_verify_id(user_id, verify_id) - temp.VERIFICATIONS[user_id] = grp_id - if message.command[1].startswith('allfiles'): - verify = await get_shortlink(f"https://telegram.me/{temp.U_NAME}?start=sendall_{user_id}_{verify_id}_{file_id}", grp_id, is_second_shortener, is_third_shortener) - else: - verify = await get_shortlink(f"https://telegram.me/{temp.U_NAME}?start=notcopy_{user_id}_{verify_id}_{file_id}", grp_id, is_second_shortener, is_third_shortener) - if is_third_shortener: - howtodownload = settings.get('tutorial_3', TUTORIAL_3) - else: - howtodownload = settings.get('tutorial_2', TUTORIAL_2) if is_second_shortener else settings.get('tutorial', TUTORIAL) - buttons = [[ - InlineKeyboardButton(text="♻ ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ᴠᴇʀɪꜰʏ ♻", url=verify) - ],[ - InlineKeyboardButton(text="⁉ ʜᴏᴡ ᴛᴏ ᴠᴇʀɪꜰʏ ⁉", url=howtodownload) - ]] - reply_markup=InlineKeyboardMarkup(buttons) - if await db.user_verified(user_id): - msg = script.THIRDT_VERIFICATION_TEXT - else: - msg = script.SECOND_VERIFICATION_TEXT if is_second_shortener else script.VERIFICATION_TEXT - n=await m.reply_text( - text=msg.format(message.from_user.mention), - protect_content = True, - reply_markup=reply_markup, - parse_mode=enums.ParseMode.HTML - ) - await asyncio.sleep(300) - await n.delete() - await m.delete() - return - except Exception as e: - logger.error("Error In Verification: %s", e) - pass - - files_ = await file_details_task - if data.startswith("allfiles"): - try: - files = temp.GETALL.get(file_id) - if not files: - return await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ !') - filesarr = [] - cover = None - for file in files: - file_id = file.file_id - files_ = await get_file_details(file_id) - files1 = files_[0] - title = clean_filename(files1.file_name) - cover = files1.cover - size = get_size(files1.file_size) - f_caption = files1.caption - settings = await get_settings(int(grp_id)) - DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) - if DREAMX_CAPTION: - try: - f_caption=DREAMX_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) - except Exception as e: - logger.exception(e) - f_caption = f_caption - if f_caption is None: - f_caption = f"{clean_filename(files1.file_name)}" - btn = await stream_buttons(message.from_user.id, file_id) - msg = await client.send_cached_media( - chat_id=message.from_user.id, - cover=cover, - file_id=file_id, - caption=f_caption, - protect_content=settings.get('file_secure', PROTECT_CONTENT), - reply_markup=InlineKeyboardMarkup(btn) - ) - filesarr.append(msg) - k = await client.send_message(chat_id=message.from_user.id, text=script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) - - await asyncio.sleep(DELETE_TIME) - for x in filesarr: - await x.delete() - await k.edit_text("ʏᴏᴜʀ ᴀʟʟ ᴠɪᴅᴇᴏꜱ/ꜰɪʟᴇꜱ ᴀʀᴇ ᴅᴇʟᴇᴛᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ !\nᴋɪɴᴅʟʏ ꜱᴇᴀʀᴄʜ ᴀɢᴀɪɴ") - return - except Exception as e: - logger.exception(e) - return - - settings = await get_settings(int(grp_id)) - if not files_: - file_id = decoded_file_id - try: - cover = None - if COVERX: - details = await get_file_details(file_id) - cover = details[0].cover if details and details[0].cover else None - btn = await stream_buttons(message.from_user.id, file_id) - msg = await client.send_cached_media( - chat_id=message.from_user.id, - cover=cover, - file_id=file_id, - protect_content=settings.get('file_secure', PROTECT_CONTENT), - reply_markup=InlineKeyboardMarkup(btn)) - - filetype = msg.media - file = getattr(msg, filetype.value) - title = clean_filename(file.file_name) - size=get_size(file.file_size) - f_caption = f"{title}" - settings = await get_settings(int(grp_id)) - DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) - if DREAMX_CAPTION: - try: - f_caption=DREAMX_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='') - except Exception: - return - await msg.edit_caption(f_caption, reply_markup=InlineKeyboardMarkup(btn)) - # FIXED: removed - k = await msg.reply(script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) - await asyncio.sleep(DELETE_TIME) - await msg.delete() - await k.edit_text("ʏᴏᴜʀ ᴠɪᴅᴇᴏ / ꜰɪʟᴇ ɪꜱ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ !!") - return - except Exception as e: - logger.exception(e) - pass - return await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ !') - - files = files_[0] - title = clean_filename(files.file_name) - size = get_size(files.file_size) - cover = files.cover if files.cover else None - f_caption = files.caption - settings = await get_settings(int(grp_id)) - DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) - if DREAMX_CAPTION: - try: - f_caption=DREAMX_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) - except Exception as e: - logger.exception(e) - f_caption = f_caption - - if f_caption is None: - f_caption = clean_filename(files.file_name) - btn = await stream_buttons(message.from_user.id, file_id) - msg = await client.send_cached_media( - chat_id=message.from_user.id, - file_id=file_id, - cover=cover, - caption=f_caption, - protect_content=settings.get('file_secure', PROTECT_CONTENT), - reply_markup=InlineKeyboardMarkup(btn) - ) - - k = await msg.reply(script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) - await asyncio.sleep(DELETE_TIME) - await msg.delete() - await k.edit_text("ʏᴏᴜʀ ᴠɪᴅᴇᴏ / ꜰɪʟᴇ ɪꜱ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ !!") - return - except StopPropagation: - raise - except Exception as e: - logger.exception(f"Error In /start command - {e}") - pass - -async def stream_buttons(user_id: int, file_id: str): - if STREAM_MODE and not PREMIUM_STREAM_MODE: - return [ - [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], - [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], - [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] - ] - elif STREAM_MODE and PREMIUM_STREAM_MODE: - if not await db.has_premium_access(user_id): - return [ - [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data='prestream')], - [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data='prestream')], - [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] - ] - else: - return [ - [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], - [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], - [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] - ] - else: - return [[InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)]] - -@Client.on_message(filters.command('logs') & filters.user(ADMINS)) -async def log_file(bot, message): - try: - await message.reply_document('DreamXlogs.txt', caption="📑 **ʟᴏɢꜱ**") - except Exception as e: - await message.reply(str(e)) - -@Client.on_message(filters.command('save') & filters.user(ADMINS)) -async def save_file_handler(bot, message): - reply = message.reply_to_message - if reply and reply.media: - msg = await message.reply("Pʀᴏᴄᴇssɪɴɢ...⏳") - else: - await message.reply('Rᴇᴘʟʏ ᴛᴏ ғɪʟᴇ ᴡɪᴛʜ /save ᴡʜɪᴄʜ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ sᴀᴠᴇ') - return - - try: - for file_type in ("document", "video", "audio"): - media = getattr(reply, file_type, None) - if media is not None: - break - else: - await msg.edit('Tʜɪs ɪs ɴᴏᴛ sᴜᴘᴘᴏʀᴛᴇᴅ ғɪʟᴇ ғᴏʀᴍᴀᴛ') - return - - file_id, file_ref = unpack_new_file_id(media.file_id) - media.file_type = file_type - media.caption = reply.caption - success, status = await save_file(media) - if success: - await msg.edit('Fɪʟᴇ ɪs sᴜᴄᴄᴇssғᴜʟʟʏ sᴀᴠᴇᴅ ᴛᴏ ᴅᴀᴛᴀʙᴀsᴇ ✅') - elif status == 0: - await msg.edit('Fɪʟᴇ ᴀʟʀᴇᴀᴅʏ ᴇxɪsᴛs ɪɴ ᴅᴀᴛᴀʙᴀsᴇ ⚠') - elif status == 2: - await msg.edit('Eʀʀᴏʀ: Fɪʟᴇ ᴠᴀʟɪᴅᴀᴛɪᴏɴ ғᴀɪʟᴇᴅ ❌') - else: - await msg.edit('Eʀʀᴏʀ: Fᴀɪʟᴇᴅ ᴛᴏ sᴀᴠᴇ ғɪʟᴇ ❌') - except Exception as e: - logger.exception(e) - await msg.edit(f'Aɴ ᴜɴᴇxᴘᴇᴄᴛᴇᴅ ᴇʀʀᴏʀ ᴏᴄᴄᴜʀʀᴇᴅ: {e} ❌') - - -@Client.on_message(filters.command('delete') & filters.user(ADMINS)) -async def delete(bot, message): - reply = message.reply_to_message - if reply and reply.media: - msg = await message.reply("Pʀᴏᴄᴇssɪɴɢ...⏳") - else: - await message.reply('Rᴇᴘʟʏ ᴛᴏ ғɪʟᴇ ᴡɪᴛʜ /delete ᴡʜɪᴄʜ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴅᴇʟᴇᴛᴇ') - return - - for file_type in ("document", "video", "audio"): - media = getattr(reply, file_type, None) - if media is not None: - break - else: - await msg.edit('Tʜɪs ɪs ɴᴏᴛ sᴜᴘᴘᴏʀᴛᴇᴅ ғɪʟᴇ ғᴏʀᴍᴀᴛ') - return - - file_id, file_ref = unpack_new_file_id(media.file_id) - if await Media.count_documents({'file_id': file_id}): - result = await Media.collection.delete_one({ - '_id': file_id, - }) - else: - result = await Media2.collection.delete_one({ - '_id': file_id, - }) - if result.deleted_count: - await msg.edit('Fɪʟᴇ ɪs sᴜᴄᴄᴇssғᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ғʀᴏᴍ ᴅᴀᴛᴀʙᴀsᴇ ✅') - else: - file_name = re.sub(r"(_|\-|\.|\+)", " ", str(media.file_name)) - result = await Media.collection.delete_many({ - 'file_name': file_name, - 'file_size': media.file_size, - 'mime_type': media.mime_type - }) - if result.deleted_count: - await msg.edit('Fɪʟᴇ ɪs sᴜᴄᴄᴇssғᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ғʀᴏᴍ ᴅᴀᴛᴀʙᴀsᴇ ✅') - else: - result = await Media2.collection.delete_many({ - 'file_name': file_name, - 'file_size': media.file_size, - 'mime_type': media.mime_type - }) - if result.deleted_count: - await msg.edit('Fɪʟᴇ ɪs sᴜᴄᴄᴇssғᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ғʀᴏᴍ ᴅᴀᴛᴀʙᴀsᴇ') - else: - result = await Media.collection.delete_many({ - 'file_name': media.file_name, - 'file_size': media.file_size, - 'mime_type': media.mime_type - }) - if result.deleted_count: - await msg.edit('Fɪʟᴇ ɪs sᴜᴄᴄᴇssғᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ғʀᴏᴍ ᴅᴀᴛᴀʙᴀsᴇ ✅') - else: - result = await Media2.collection.delete_many({ - 'file_name': media.file_name, - 'file_size': media.file_size, - 'mime_type': media.mime_type - }) - if result.deleted_count: - await msg.edit('Fɪʟᴇ ɪs sᴜᴄᴄᴇssғᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ғʀᴏᴍ ᴅᴀᴛᴀʙᴀsᴇ ✅') - else: - await msg.edit('Fɪʟᴇ ɴᴏᴛ ғᴏᴜɴᴅ ɪɴ ᴅᴀᴛᴀʙᴀsᴇ ❌') - - -@Client.on_message(filters.command('deleteall') & filters.user(ADMINS)) -async def delete_all_index(bot, message): - await message.reply_text( - 'ᴛʜɪꜱ ᴡɪʟʟ ᴅᴇʟᴇᴛᴇ ᴀʟʟ ʏᴏᴜʀ ɪɴᴅᴇxᴇᴅ ꜰɪʟᴇꜱ !\nᴅᴏ ʏᴏᴜ ꜱᴛɪʟʟ ᴡᴀɴᴛ ᴛᴏ ᴄᴏɴᴛɪɴᴜᴇ ?', - reply_markup=InlineKeyboardMarkup( - [ - [ - InlineKeyboardButton( - text="⚠ ʏᴇꜱ ⚠", callback_data="autofilter_delete" - ) - ], - [ - InlineKeyboardButton( - text="❌ ɴᴏ ❌", callback_data="close_data" - ) - ], - ] - ), - ) - -@Client.on_message(filters.command('settings')) -async def settings(client, message): - user_id = message.from_user.id if message.from_user else None - if not user_id: - return await message.reply("ʏᴏᴜ'ʀᴇ ᴀɴᴏɴʏᴍᴏᴜꜱ ᴀᴅᴍɪɴ.") - chat_type = message.chat.type - if chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: - grp_id = message.chat.id - if not await is_check_admin(client, grp_id, message.from_user.id): - return await message.reply_text(script.NT_ADMIN_ALRT_TXT) - await db.connect_group(grp_id, user_id) - btn = [[ - InlineKeyboardButton("👤 ᴏᴘᴇɴ ɪɴ ᴘʀɪᴠᴀᴛᴇ ᴄʜᴀᴛ 👤", callback_data=f"opnsetpm#{grp_id}") - ],[ - InlineKeyboardButton("👥 ᴏᴘᴇɴ ʜᴇʀᴇ 👥", callback_data=f"opnsetgrp#{grp_id}") - ]] - await message.reply_text( - text="ᴡʜᴇʀᴇ ᴅᴏ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴏᴘᴇɴ ꜱᴇᴛᴛɪɴɢꜱ ᴍᴇɴᴜ ? ⚙", - reply_markup=InlineKeyboardMarkup(btn), - link_preview_options=LinkPreviewOptions(is_disabled=True), - parse_mode=enums.ParseMode.HTML - ) - elif chat_type == enums.ChatType.PRIVATE: - connected_groups = await db.get_connected_grps(user_id) - if not connected_groups: - return await message.reply_text("Nᴏ Cᴏɴɴᴇᴄᴛᴇᴅ Gʀᴏᴜᴘs Fᴏᴜɴᴅ .") - group_list = [] - for group in connected_groups: - try: - Chat = await client.get_chat(group) - group_list.append([ InlineKeyboardButton(text=Chat.title, callback_data=f"grp_pm#{Chat.id}") ]) - except Exception: - pass - await message.reply_text( - "⚠ ꜱᴇʟᴇᴄᴛ ᴛʜᴇ ɢʀᴏᴜᴘ ᴡʜᴏꜱᴇ ꜱᴇᴛᴛɪɴɢꜱ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʜᴀɴɢᴇ.\n\n" - "ɪꜰ ʏᴏᴜʀ ɢʀᴏᴜᴘ ɪꜱ ɴᴏᴛ ꜱʜᴏᴡɪɴɢ ʜᴇʀᴇ,\n" - "ᴜꜱᴇ /reload ɪɴ ᴛʜᴀᴛ ɢʀᴏᴜᴘ ᴀɴᴅ ɪᴛ ᴡɪʟʟ ᴀᴘᴘᴇᴀʀ ʜᴇʀᴇ.", - reply_markup=InlineKeyboardMarkup(group_list) - ) - -@Client.on_message(filters.command('reload')) -async def connect_group(client, message): - user_id = message.from_user.id - if message.chat.type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: - await db.connect_group(message.chat.id, user_id) - await message.reply_text("Gʀᴏᴜᴘ Rᴇʟᴏᴀᴅᴇᴅ ✅ Nᴏᴡ Yᴏᴜ Cᴀɴ Mᴀɴᴀɢᴇ Tʜɪs Gʀᴏᴜᴘ Fʀᴏᴍ PM.") - elif message.chat.type == enums.ChatType.PRIVATE: - if len(message.command) < 2: - await message.reply_text("Example: /reload 123456789") - return - try: - group_id = int(message.command[1]) - if not await is_check_admin(client, group_id, user_id): - await message.reply_text(script.NT_ADMIN_ALRT_TXT) - return - chat = await client.get_chat(group_id) - await db.connect_group(group_id, user_id) - await message.reply_text(f"Lɪɴᴋᴇᴅ sᴜᴄᴄᴇssғᴜʟʟʏ ✅ {chat.title} ᴛᴏ PM.") - except Exception: - await message.reply_text("Invalid group ID or error occurred.") - -@Client.on_message(filters.command('set_template')) -async def save_template(client, message): - sts = await message.reply("ᴄʜᴇᴄᴋɪɴɢ ᴛᴇᴍᴘʟᴀᴛᴇ...") - user_id = message.from_user.id if message.from_user else None - if not user_id: - return await message.reply("ʏᴏᴜ'ʀᴇ ᴀɴᴏɴʏᴍᴏᴜꜱ ᴀᴅᴍɪɴ.") - if message.chat.type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: - return await sts.edit("⚠ ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ɪɴ ᴀ ɢʀᴏᴜᴘ ᴄʜᴀᴛ.") - - group_id = message.chat.id - title = message.chat.title - if not await is_check_admin(client, group_id, user_id): - await message.reply_text(script.NT_ADMIN_ALRT_TXT) - return - if len(message.command) < 2: - return await sts.edit("⚠ ɴᴏ ᴛᴇᴍᴘʟᴀᴛᴇ ᴘʀᴏᴠɪᴅᴇᴅ!") - - template = message.text.split(" ", 1)[1] - await save_group_settings(group_id, 'template', template) - await sts.edit( - f"✅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴜᴘᴅᴀᴛᴇᴅ ᴛᴇᴍᴘʟᴀᴛᴇ ꜰᴏʀ {title} ᴛᴏ:\n\n{template}" - ) - - -@Client.on_message((filters.command("request") | filters.regex(r"(?i)#request")) & filters.group) -async def requests(bot, message): - if message.chat.id != SUPPORT_CHAT_ID: - return - if not message.from_user: - return await message.reply_text("⚠ ᴜɴᴀʙʟᴇ ᴛᴏ ɪᴅᴇɴᴛɪꜰʏ ʏᴏᴜ.") - - reporter = str(message.from_user.id) - mention = message.from_user.mention - - if message.reply_to_message: - target_msg = message.reply_to_message - content = target_msg.text or target_msg.caption or "" - msg_link = target_msg.link - else: - content = message.text or message.caption or "" - content = re.sub(r"(?i)[#/]?request", "", content).strip() - msg_link = message.link - - content = content.strip() - if len(content) < 3: - return await message.reply_text("ʏᴏᴜ ᴍᴜꜱᴛ ᴛʏᴘᴇ ᴀʙᴏᴜᴛ ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ [ᴍɪɴɪᴍᴜᴍ 3 ᴄʜᴀʀᴀᴄᴛᴇʀꜱ]. ʀᴇǫᴜᴇꜱᴛꜱ ᴄᴀɴ'ᴛ ʙᴇ ᴇᴍᴘᴛʏ.") - - reported_post: Message | None = None - try: - btn = [[ - InlineKeyboardButton('ᴠɪᴇᴡ ʀᴇǫᴜᴇꜱᴛ', url=msg_link), - InlineKeyboardButton('ꜱʜᴏᴡ ᴏᴘᴛɪᴏɴꜱ', callback_data=f'show_option#{reporter}') - ]] - req_text = f"📝 ʀᴇǫᴜᴇꜱᴛ : {content}\n\n📚 ʀᴇᴘᴏʀᴛᴇᴅ ʙʏ : {mention}\n📖 ʀᴇᴘᴏʀᴛᴇʀ ɪᴅ : {reporter}\n\n" - warning_text = "⚠ ʀᴇǫᴜᴇꜱᴛ ᴄʜᴀɴɴᴇʟ ɪꜱ ɴᴏᴛ ꜱᴇᴛ." - if REQST_CHANNEL is not None: - try: - reported_post = await bot.send_message(chat_id=REQST_CHANNEL, text=req_text, reply_markup=InlineKeyboardMarkup(btn)) - except Exception: - for admin in ADMINS: - await bot.send_message(chat_id=admin, text=warning_text) - reported_post = await bot.send_message(chat_id=admin, text=req_text, reply_markup=InlineKeyboardMarkup(btn)) - else: - for admin in ADMINS: - await bot.send_message(chat_id=admin, text=warning_text) - reported_post = await bot.send_message(chat_id=admin, text=req_text, reply_markup=InlineKeyboardMarkup(btn)) - except Exception: - logger.exception("Request failed") - return await message.reply_text( "⚠ ꜱᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ. ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ.") - - if reported_post and REQST_CHANNEL is not None: - try: - invite_link = REQUEST_INVITE_LINK_CACHE.get(REQST_CHANNEL) - if not invite_link: - try: - link = await bot.create_chat_invite_link(int(REQST_CHANNEL)) - invite_link = link.invite_link - REQUEST_INVITE_LINK_CACHE[REQST_CHANNEL] = invite_link - except Exception: - logger.exception("Failed to create invite link") - invite_link = None - if invite_link: - btn = [[ - InlineKeyboardButton('ᴊᴏɪɴ ᴄʜᴀɴɴᴇʟ', url=invite_link), - InlineKeyboardButton('ᴠɪᴇᴡ ʀᴇǫᴜᴇꜱᴛ', url=reported_post.link) - ]] - await message.reply_text("ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ʜᴀꜱ ʙᴇᴇɴ ᴀᴅᴅᴇᴅ! ᴘʟᴇᴀꜱᴇ ᴡᴀɪᴛ ꜰᴏʀ ꜱᴏᴍᴇ ᴛɪᴍᴇ.\n\nᴊᴏɪɴ ᴄʜᴀɴɴᴇʟ ꜰɪʀꜱᴛ & ᴠɪᴇᴡ ʀᴇǫᴜᴇꜱᴛ.", reply_markup=InlineKeyboardMarkup(btn)) - else: - await message.reply_text("ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ʜᴀꜱ ʙᴇᴇɴ ᴀᴅᴅᴇᴅ! ᴘʟᴇᴀꜱᴇ ᴡᴀɪᴛ ꜰᴏʀ ꜱᴏᴍᴇ ᴛɪᴍᴇ.") - except Exception: - logger.exception("Failed to send request confirmation") - await message.reply_text("⚠ ꜱᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ. ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ.") - -@Client.on_message(filters.command("send") & filters.user(ADMINS)) -async def send_msg(bot, message): - if message.reply_to_message: - target_id = message.text.split(" ", 1)[1] - out = "Users Saved In DB Are:\n\n" - success = False - try: - user = await bot.get_users(target_id) - users = await db.get_all_users() - async for usr in users: - out += f"{usr['id']}" - out += '\n' - if str(user.id) in str(out): - await message.reply_to_message.copy(int(user.id)) - success = True - else: - success = False - if success: - await message.reply_text(f"ʏᴏᴜʀ ᴍᴇꜱꜱᴀɢᴇ ʜᴀꜱ ʙᴇᴇɴ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ꜱᴇɴᴛ ᴛᴏ {user.mention}.") - else: - await message.reply_text("ᴛʜɪꜱ ᴜꜱᴇʀ ᴅɪᴅɴ'ᴛ ꜱᴛᴀʀᴛᴇᴅ ᴛʜɪꜱ ʙᴏᴛ ʏᴇᴛ !") - except Exception as e: - await message.reply_text(f"Error: {e}") - else: - await message.reply_text("ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ᴀꜱ ᴀ ʀᴇᴘʟʏ ᴛᴏ ᴀɴʏ ᴍᴇꜱꜱᴀɢᴇ ᴜꜱɪɴɢ ᴛʜᴇ ᴛᴀʀɢᴇᴛ ᴄʜᴀᴛ ɪᴅ. ꜰᴏʀ ᴇɢ: /send ᴜꜱᴇʀɪᴅ") - -@Client.on_message(filters.command("deletefiles") & filters.user(ADMINS)) -async def deletemultiplefiles(bot, message): - chat_type = message.chat.type - if chat_type != enums.ChatType.PRIVATE: - return await message.reply_text(f"Hey {message.from_user.mention}, This command won't work in groups. It only works on my PM !") - - try: - keyword = message.text.split(" ", 1)[1] - except Exception: - return await message.reply_text(f"Hey {message.from_user.mention}, Give me a keyword along with the command to delete files.") - k = await bot.send_message(chat_id=message.chat.id, text=f"Fetching Files for your query {keyword} on DB... Please wait...") - files, total = await get_bad_files(keyword) - total = len(files) - if total == 0: - await k.edit_text(f"No files found for your query {keyword} !") - await asyncio.sleep(DELETE_TIME) - await k.delete() - return - await k.delete() - btn = [[ - InlineKeyboardButton("⚠ Yes, Continue ! ⚠", callback_data=f"killfilesdq#{keyword}") - ],[ - InlineKeyboardButton("❌ No, Abort operation ! ❌", callback_data="close_data") - ]] - await message.reply_text( - text=f"Found {total} files for your query {keyword} !\n\nDo you want to delete?", - reply_markup=InlineKeyboardMarkup(btn), - parse_mode=enums.ParseMode.HTML - ) - - -@Client.on_callback_query(filters.regex("topsearch")) -async def topsearch_callback(client, callback_query): - def is_alphanumeric(string): - return bool(re.match('^[a-zA-Z0-9 ]*$', string)) - - limit = 20 - top_messages = await mdb.get_top_messages(limit) - seen_messages = set() - truncated_messages = [] - for msg in top_messages: - msg_lower = msg.lower() - if msg_lower not in seen_messages and is_alphanumeric(msg): - seen_messages.add(msg_lower) - if len(msg) > 35: - truncated_messages.append(msg[:32] + "...") - else: - truncated_messages.append(msg) - keyboard = [truncated_messages[i:i+2] for i in range(0, len(truncated_messages), 2)] - reply_markup = ReplyKeyboardMarkup( - keyboard, - one_time_keyboard=True, - resize_keyboard=True, - placeholder="Most searches of the day" - ) - await callback_query.message.reply_text( - "Tᴏᴘ Sᴇᴀʀᴄʜᴇs Oғ Tʜᴇ Dᴀʏ 👇", - reply_markup=reply_markup - ) - await callback_query.answer() - -@Client.on_message(filters.command('top_search')) -async def top(_, message): - def is_alphanumeric(string): - return bool(re.match('^[a-zA-Z0-9 ]*$', string)) - try: - limit = int(message.command[1]) - except (IndexError, ValueError): - limit = 20 - top_messages = await mdb.get_top_messages(limit) - seen_messages = set() - truncated_messages = [] - for msg in top_messages: - msg_lower = msg.lower() - if msg_lower not in seen_messages and is_alphanumeric(msg): - seen_messages.add(msg_lower) - if len(msg) > 35: - truncated_messages.append(msg[:32] + "...") - else: - truncated_messages.append(msg) - keyboard = [truncated_messages[i:i+2] for i in range(0, len(truncated_messages), 2)] - reply_markup = ReplyKeyboardMarkup( - keyboard, - one_time_keyboard=True, - resize_keyboard=True, - placeholder="Most searches of the day" - ) - await message.reply_text( - "Tᴏᴘ Sᴇᴀʀᴄʜᴇs Oғ Tʜᴇ Dᴀʏ 👇", - reply_markup=reply_markup - ) + asyncio.create_task(_delete_files(filesarr, k, DELETE_TIME)) -@Client.on_message(filters.command('trendlist')) -async def trendlist(client, message): - def is_alphanumeric(string): - return bool(re.match('^[a-zA-Z0-9 ]*$', string)) - limit = 31 - if len(message.command) > 1: - try: - limit = int(message.command[1]) - except ValueError: - await message.reply_text( - "Invalid number format.\nPlease provide a valid number after the /trendlist command." - ) return - try: - top_messages = await mdb.get_top_messages(limit) - except Exception as e: - await message.reply_text(f"Error retrieving messages: {str(e)}") - return - - if not top_messages: - await message.reply_text("No top messages found.") - return - seen_messages = set() - truncated_messages = [] - - for msg in top_messages: - msg_lower = msg.lower() - if msg_lower not in seen_messages and is_alphanumeric(msg): - seen_messages.add(msg_lower) - truncated_messages.append(msg[:32] + '...' if len(msg) > 35 else msg) - - if not truncated_messages: - await message.reply_text("No valid top messages found.") - return - formatted_list = "\n".join([f"{i+1}. {msg}" for i, msg in enumerate(truncated_messages)]) - additional_message = ( - "⚡ 𝑨𝒍𝒍 𝒕𝒉𝒆 𝒓𝒆𝒔𝒖𝒍𝒕𝒔 𝒂𝒃𝒐𝒗𝒆 𝒄𝒐𝒎𝒆 𝒇𝒓𝒐𝒎 𝒘𝒉𝒂𝒕 𝒖𝒔𝒆𝒓𝒔 𝒉𝒂𝒗𝒆 𝒔𝒆𝒂𝒓𝒄𝒉𝒆𝒅 𝒇𝒐𝒓. " - "𝑻𝒉𝒆𝒚'𝒓𝒆 𝒔𝒉𝒐𝒘𝒏 𝒕𝒐 𝒚𝒐𝒖 𝒆𝒙𝒂𝒄𝒕𝒍𝒚 𝒂𝒔 𝒕𝒉𝒆𝒚 𝒘𝒆𝒓𝒆 𝒔𝒆𝒂𝒓𝒄𝒉𝒆𝒅, " - "𝒘𝒊𝒕𝒉𝒐𝒖𝒕 𝒂𝒏𝒚 𝒄𝒉𝒂𝒏𝒈𝒆𝒔 𝒃𝒚 𝒕𝒉𝒆 𝒐𝒘𝒏𝒆𝒓." - ) - formatted_list += f"\n\n{additional_message}" - reply_text = f"Top {len(truncated_messages)} Tʀᴀɴᴅɪɴɢ ᴏғ ᴛʜᴇ ᴅᴀʏ 👇:\n\n{formatted_list}" - await message.reply_text(reply_text) - -@Client.on_message(filters.private & filters.command("pm_search") & filters.user(ADMINS)) -async def set_pm_search(client, message): - bot_id = client.me.id - try: - option = message.text.split(" ", 1)[1].strip().lower() - enable_status = option in ['on', 'true'] - except (IndexError, ValueError): - await message.reply_text("💔 Invalid option. Please send 'on' or 'off' after the command..") - return - try: - await db.update_pm_search_status(bot_id, enable_status) - response_text = ( - " ᴘᴍ ꜱᴇᴀʀᴄʜ ᴇɴᴀʙʟᴇᴅ ✅" if enable_status - else " ᴘᴍ ꜱᴇᴀʀᴄʜ ᴅɪꜱᴀʙʟᴇᴅ ❌" - ) - await message.reply_text(response_text) - except Exception as e: - logger.error(f"Error in set_pm_search: {e}") - await message.reply_text(f"❗ An error occurred: {e}") - -@Client.on_message(filters.private & filters.command("movie_update") & filters.user(ADMINS)) -async def set_movie_update_notification(client, message): - bot_id = client.me.id - try: - option = message.text.split(" ", 1)[1].strip().lower() - enable_status = option in ['on', 'true'] - except (IndexError, ValueError): - await message.reply_text("💔 Invalid option. Please send 'on' or 'off' after the command.") - return - try: - await db.update_movie_update_status(bot_id, enable_status) - response_text = ( - "ᴍᴏᴠɪᴇ ᴜᴘᴅᴀᴛᴇ ɴᴏᴛɪꜰɪᴄᴀᴛɪᴏɴ ᴇɴᴀʙʟᴇᴅ ✅" if enable_status - else "ᴍᴏᴠɪᴇ ᴜᴘᴅᴀᴛᴇ ɴᴏᴛɪꜰɪᴄᴀᴛɪᴏɴ ᴅɪꜱᴀʙʟᴇᴅ ❌" - ) - await message.reply_text(response_text) - except Exception as e: - logger.error(f"Error in set_movie_update_notification: {e}") - await message.reply_text(f"❗ An error occurred: {e}") - -@Client.on_message(filters.command("restart") & filters.user(ADMINS)) -async def stop_button(bot, message): - msg = await bot.send_message(text="ʙᴏᴛ ɪꜱ ʀᴇꜱᴛᴀʀᴛɪɴɢ", chat_id=message.chat.id) - await asyncio.sleep(3) - await msg.edit("ʙᴏᴛ ɪꜱ ʀᴇꜱᴛᴀʀᴛᴇᴅ ✅") - os.execl(sys.executable, sys.executable, *sys.argv) - -@Client.on_message(filters.command("del_msg") & filters.user(ADMINS)) -async def del_msg(client, message): - confirm_markup = InlineKeyboardMarkup([[ - InlineKeyboardButton("Yes", callback_data="confirm_del_yes"), - InlineKeyboardButton("No", callback_data="confirm_del_no") - ]]) - sent_message = await message.reply_text( - "⚠ Aʀᴇ ʏᴏᴜ sᴜʀᴇ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʟᴇᴀʀ ᴛʜᴇ ᴜᴘᴅᴀᴛᴇs ᴄʜᴀɴɴᴇʟ ʟɪsᴛ ?\n\n ᴅᴏ ʏᴏᴜ ꜱᴛɪʟʟ ᴡᴀɴᴛ ᴛᴏ ᴄᴏɴᴛɪɴᴜᴇ ?", - reply_markup=confirm_markup - ) - await asyncio.sleep(60) - try: - await sent_message.delete() - except Exception as e: - logger.error("Error deleting the message: %s", e) - -@Client.on_callback_query(filters.regex('^confirm_del_')) -async def confirmation_handler(client, callback_query): - action = callback_query.data.split("_")[-1] - if action == "yes": - await db.delete_all_msg() - await callback_query.message.edit_text('🧹 ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ ʟɪsᴛ ʜᴀs ʙᴇᴇɴ ᴄʟᴇᴀʀᴇᴅ sᴜᴄᴄᴇssғᴜʟʟʏ ✅') - elif action == "no": - await callback_query.message.delete() - await callback_query.answer() - -@Client.on_message(filters.command('set_caption')) -async def save_caption(client, message): - grp_id = message.chat.id - title = message.chat.title - invite_link = await client.export_chat_invite_link(grp_id) - if not await is_check_admin(client, grp_id, message.from_user.id): - return await message.reply_text(script.NT_ADMIN_ALRT_TXT) - chat_type = message.chat.type - if chat_type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: - return await message.reply_text("ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ɪɴ ɢʀᴏᴜᴘ...") - try: - caption = message.text.split(" ", 1)[1] - except Exception: - return await message.reply_text("ɢɪᴠᴇ ᴍᴇ ᴀ ᴄᴀᴘᴛɪᴏɴ ᴀʟᴏɴɢ ᴡɪᴛʜ ɪᴛ.\n\nᴇxᴀᴍᴘʟᴇ -\n\nꜰᴏʀ ꜰɪʟᴇ ɴᴀᴍᴇ ꜱᴇɴᴅ {file_name}\nꜰᴏʀ ꜰɪʟᴇ ꜱɪᴢᴇ ꜱᴇɴᴅ {file_size}\n\n/set_caption {file_name}") - await save_group_settings(grp_id, 'caption', caption) - await message.reply_text(f"ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴄʜᴀɴɢᴇᴅ ᴄᴀᴘᴛɪᴏɴ ꜰᴏʀ {title}\n\nᴄᴀᴘᴛɪᴏɴ - {caption}", link_preview_options=LinkPreviewOptions(is_disabled=True)) - await client.send_message(LOG_CHANNEL, f"#Set_Caption\n\nɢʀᴏᴜᴘ ɴᴀᴍᴇ : {title}\n\nɢʀᴏᴜᴘ ɪᴅ: {grp_id}\nɪɴᴠɪᴛᴇ ʟɪɴᴋ : {invite_link}\n\nᴜᴘᴅᴀᴛᴇᴅ ʙʏ : {message.from_user.username}") - - -@Client.on_message(filters.command(["set_tutorial", "set_tutorial_2", "set_tutorial_3"])) -async def set_tutorial(client, message: Message): - grp_id = message.chat.id - title = message.chat.title - chat_type = message.chat.type - if chat_type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: - return await message.reply_text( - f"ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ɪɴ ɢʀᴏᴜᴘ...\n\nGroup Name: {title}\nGroup ID: {grp_id}" - ) - if not await is_check_admin(client, grp_id, message.from_user.id): - return await message.reply_text(script.NT_ADMIN_ALRT_TXT) - - try: - tutorial_link = message.text.split(" ", 1)[1] - except IndexError: - return await message.reply_text( - f"ᴄᴏᴍᴍᴀɴᴅ ɪɴᴄᴏᴍᴘʟᴇᴛᴇ !!\n\nᴜꜱᴇ ʟɪᴋᴇ ᴛʜɪꜱ -\n\n" - f"/{message.command[0]} https://t.me/dreamxbotz" - ) - if message.command[0] == "set_tutorial": - tutorial_key = "tutorial" - else: - tutorial_key = f"tutorial_{message.command[0].split('_', 2)[2]}" - - await save_group_settings(grp_id, tutorial_key, tutorial_link) - invite_link = await client.export_chat_invite_link(grp_id) - await message.reply_text( - f"ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴄʜᴀɴɢᴇᴅ {tutorial_key.replace('_', ' ').title()} ꜰᴏʀ {title}\n\n" - f"ʟɪɴᴋ - {tutorial_link}", - link_preview_options=LinkPreviewOptions(is_disabled=True) - ) - await client.send_message( - LOG_CHANNEL, - f"#Set_{tutorial_key.title()}_Video\n\n" - f"ɢʀᴏᴜᴘ ɴᴀᴍᴇ : {title}\n" - f"ɢʀᴏᴜᴘ ɪᴅ : {grp_id}\n" - f"ɪɴᴠɪᴛᴇ ʟɪɴᴋ : {invite_link}\n" - f"ᴜᴘᴅᴀᴛᴇᴅ ʙʏ : {message.from_user.mention()}" - ) - - -async def handle_shortner_command(c, m, shortner_key, api_key, log_prefix, fallback_url, fallback_api): - grp_id = m.chat.id - if not await is_check_admin(c, grp_id, m.from_user.id): - return await m.reply_text(script.NT_ADMIN_ALRT_TXT) - if len(m.command) != 3: - return await m.reply( - f"ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ʟɪᴋᴇ -\n\n`/{m.command[0]} your-shortener-domain.com your_api_key_here`" - ) - sts = await m.reply("♻ ᴄʜᴇᴄᴋɪɴɢ...") - await asyncio.sleep(1.2) - await sts.delete() - if m.chat.type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: - return await m.reply_text("ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ɪɴ ɢʀᴏᴜᴘ...") - custom_flag = 'custom_shortner' if shortner_key == 'shortner' else f'custom_{shortner_key}' - try: - URL = m.command[1] - API = m.command[2] - await save_group_settings(grp_id, shortner_key, URL) - await save_group_settings(grp_id, api_key, API) - await save_group_settings(grp_id, custom_flag, True) - await m.reply_text(f"✅ sʜᴏʀᴛɴᴇʀ ᴀᴅᴅᴇᴅ\n\nꜱɪᴛᴇ - `{URL}`\nᴀᴘɪ - `{API}`") - user_id = m.from_user.id - user_info = f"@{m.from_user.username}" if m.from_user.username else f"{m.from_user.mention}" - link = (await c.get_chat(m.chat.id)).invite_link - grp_link = f"[{m.chat.title}]({link})" - log_message = ( - f"#{log_prefix}\n\nɴᴀᴍᴇ - {user_info}\n\nɪᴅ - `{user_id}`" - f"\n\nꜱɪᴛᴇ - {URL}\n\nᴀᴘɪ - `{API}`" - f"\n\nɢʀᴏᴜᴘ - {grp_link}\nɢʀᴏᴜᴘ ɪᴅ - `{grp_id}`" - ) - await c.send_message(LOG_CHANNEL, log_message, link_preview_options=LinkPreviewOptions(is_disabled=True)) - except Exception as e: - await save_group_settings(grp_id, shortner_key, fallback_url) - await save_group_settings(grp_id, api_key, fallback_api) - await save_group_settings(grp_id, custom_flag, False) - await m.reply_text( - f"💢 ᴇʀʀᴏʀ ᴏᴄᴄᴜʀᴇᴅ!\n\n" - f"ᴅᴇꜰᴀᴜʟᴛ ꜱʜᴏʀᴛɴᴇʀ ᴀᴘᴘʟɪᴇᴅ\n" - f"ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʜᴀɴɢᴇ ᴛʀʏ ᴀ ᴠᴀʟɪᴅ ꜱɪᴛᴇ ᴀɴᴅ ᴀᴘɪ ᴋᴇʏ.\n\n" - f"ʟɪᴋᴇ:\n\n`/{m.command[0]} your-shortener-domain.com your_api_key_here`\n\n" - f"💔 ᴇʀʀᴏʀ - {e}" - ) - -@Client.on_message(filters.command('set_shortner')) -async def set_shortner(c, m): - await handle_shortner_command(c, m, 'shortner', 'api', 'New_Shortner_Set_For_1st_Verify', SHORTENER_WEBSITE, SHORTENER_API) - -@Client.on_message(filters.command('set_shortner_2')) -async def set_shortner_2(c, m): - await handle_shortner_command(c, m, 'shortner_two', 'api_two', 'New_Shortner_Set_For_2nd_Verify', SHORTENER_WEBSITE2, SHORTENER_API2) - -@Client.on_message(filters.command('set_shortner_3')) -async def set_shortner_3(c, m): - await handle_shortner_command(c, m, 'shortner_three', 'api_three', 'New_Shortner_Set_For_3rd_Verify', SHORTENER_WEBSITE3, SHORTENER_API3) - -@Client.on_message(filters.command('set_log_channel')) -async def set_log(client, message): - grp_id = message.chat.id - title = message.chat.title - if not await is_check_admin(client, grp_id, message.from_user.id): - return await message.reply_text(script.NT_ADMIN_ALRT_TXT) - if len(message.text.split()) == 1: - await message.reply("ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ʟɪᴋᴇ ᴛʜɪꜱ - \n\n`/set_log_channel -100******`") - return - sts = await message.reply("♻ ᴄʜᴇᴄᴋɪɴɢ...") - await asyncio.sleep(1.2) - await sts.delete() - chat_type = message.chat.type - if chat_type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: - return await message.reply_text("ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ɪɴ ɢʀᴏᴜᴘ...") - try: - log = int(message.text.split(" ", 1)[1]) - except IndexError: - return await message.reply_text("ɪɴᴠᴀɪʟᴅ ꜰᴏʀᴍᴀᴛ!!\n\nᴜsᴇ ʟɪᴋᴇ ᴛʜɪs - `/set_log_channel -100xxxxxxxx`") - except ValueError: - return await message.reply_text('ᴍᴀᴋᴇ sᴜʀᴇ ɪᴅ ɪs ɪɴᴛᴇɢᴇʀ...') - try: - t = await client.send_message(chat_id=log, text="ʜᴇʏ ᴡʜᴀᴛ's ᴜᴘ!!") - await asyncio.sleep(3) - await t.delete() - except Exception as e: - return await message.reply_text(f'😐 ᴍᴀᴋᴇ sᴜʀᴇ ᴛʜɪs ʙᴏᴛ ᴀᴅᴍɪɴ ɪɴ ᴛʜᴀᴛ ᴄʜᴀɴɴᴇʟ...\n\n💔 ᴇʀʀᴏʀ - {e}') - await save_group_settings(grp_id, 'log', log) - await message.reply_text(f"✅ sᴜᴄᴄᴇssꜰᴜʟʟʏ sᴇᴛ ʏᴏᴜʀ ʟᴏɢ ᴄʜᴀɴɴᴇʟ ꜰᴏʀ {title}\n\nɪᴅ - `{log}`", link_preview_options=LinkPreviewOptions(is_disabled=True)) - user_id = message.from_user.id - user_info = f"@{message.from_user.username}" if message.from_user.username else f"{message.from_user.mention}" - link = (await client.get_chat(message.chat.id)).invite_link - grp_link = f"[{message.chat.title}]({link})" - log_message = f"#New_Log_Channel_Set\n\nɴᴀᴍᴇ - {user_info}\n\nɪᴅ - `{user_id}`\n\nʟᴏɢ ᴄʜᴀɴɴᴇʟ ɪᴅ - `{log}`\nɢʀᴏᴜᴘ ʟɪɴᴋ - `{grp_link}`\n\nɢʀᴏᴜᴘ ɪᴅ : `{grp_id}`" - await client.send_message(LOG_CHANNEL, log_message, link_preview_options=LinkPreviewOptions(is_disabled=True)) - - -@Client.on_message(filters.command('set_time')) -async def set_time(client, message): - chat_type = message.chat.type - if chat_type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: - return await message.reply_text("ᴜsᴇ ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ ɪɴ ɢʀᴏᴜᴘ...") - grp_id = message.chat.id - title = message.chat.title - invite_link = await client.export_chat_invite_link(grp_id) - if not await is_check_admin(client, grp_id, message.from_user.id): - return await message.reply_text(script.NT_ADMIN_ALRT_TXT) - try: - time = int(message.text.split(" ", 1)[1]) - except Exception: - return await message.reply_text("ᴄᴏᴍᴍᴀɴᴅ ɪɴᴄᴏᴍᴘʟᴇᴛᴇ\n\nᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ʟɪᴋᴇ ᴛʜɪꜱ - /set_time 600 [ ᴛɪᴍᴇ ᴍᴜꜱᴛ ʙᴇ ɪɴ ꜱᴇᴄᴏɴᴅꜱ ]") - await save_group_settings(grp_id, 'verify_time', time) - await message.reply_text(f"✅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ꜱᴇᴛ 2ɴᴅ ᴠᴇʀɪꜰʏ ᴛɪᴍᴇ ꜰᴏʀ {title}\n\nᴛɪᴍᴇ - {time}") - await client.send_message(LOG_CHANNEL, f"#Set_2nd_Verify_Time\n\nɢʀᴏᴜᴘ ɴᴀᴍᴇ : {title}\n\nɢʀᴏᴜᴘ ɪᴅ : {grp_id}\n\nɪɴᴠɪᴛᴇ ʟɪɴᴋ : {invite_link}\n\nᴜᴘᴅᴀᴛᴇᴅ ʙʏ : {message.from_user.username}") -@Client.on_message(filters.command('set_time_2')) -async def set_time_2(client, message): - chat_type = message.chat.type - if chat_type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: - return await message.reply_text("ᴜsᴇ ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ ɪɴ ɢʀᴏᴜᴘ...") - grp_id = message.chat.id - title = message.chat.title - invite_link = await client.export_chat_invite_link(grp_id) - if not await is_check_admin(client, grp_id, message.from_user.id): - return await message.reply_text(script.NT_ADMIN_ALRT_TXT) - try: - time = int(message.text.split(" ", 1)[1]) - except Exception: - return await message.reply_text("ᴄᴏᴍᴍᴀɴᴅ ɪɴᴄᴏᴍᴘʟᴇᴛᴇ\n\nᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ʟɪᴋᴇ ᴛʜɪꜱ - /set_time 3600 [ ᴛɪᴍᴇ ᴍᴜꜱᴛ ʙᴇ ɪɴ ꜱᴇᴄᴏɴᴅꜱ ]") - await save_group_settings(grp_id, 'third_verify_time', time) - await message.reply_text(f"✅ ꜱᴜᴄᴄESꜱꜰᴜʟʟʏ ꜱᴇᴛ 3ʀᴅ ᴠᴇʀɪꜰʏ ᴛɪᴍᴇ ꜰᴏʀ {title}\n\nᴛɪᴍᴇ - {time}") - await client.send_message(LOG_CHANNEL, f"#Set_3rd_Verify_Time\n\nɢʀᴏᴜᴘ ɴᴀᴍᴇ : {title}\n\nɢʀᴏᴜᴘ ɪᴅ : {grp_id}\n\nɪɴᴠɪᴛᴇ ʟɪɴᴋ : {invite_link}\n\nᴜᴘᴅᴀᴛᴇᴅ ʙʏ : {message.from_user.username}") - - -@Client.on_message(filters.command('details')) -async def all_settings(client, message): - if message.chat.type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: - return await message.reply_text("ᴜsᴇ ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ ɪɴ ɢʀᴏᴜᴘ...") - grp_id = message.chat.id - title = message.chat.title - if not await is_check_admin(client, grp_id, message.from_user.id): - return await message.reply_text(script.NT_ADMIN_ALRT_TXT) - try: - settings = await get_settings(grp_id) - except Exception as e: - return await message.reply_text(f"⚠ ᴇʀʀᴏʀ ꜰᴇᴛᴄʜɪɴɢ ꜱᴇᴛᴛɪɴɢꜱ:\n{e}") - text = generate_settings_text(settings, title) - btn = [ - [InlineKeyboardButton("♻ ʀᴇꜱᴇᴛ ꜱᴇᴛᴛɪɴɢꜱ", callback_data=f"reset_group_{grp_id}")], - [InlineKeyboardButton("🚫 ᴄʟᴏꜱᴇ", callback_data="close_data")] - ] - dlt = await message.reply_text(text, reply_markup=InlineKeyboardMarkup(btn), link_preview_options=LinkPreviewOptions(is_disabled=True)) - await asyncio.sleep(300) - await dlt.delete() - -@Client.on_callback_query(filters.regex(r"^reset_group_(\-\d+)$")) -async def reset_group_callback(client, callback_query): - grp_id = int(callback_query.matches[0].group(1)) - user_id = callback_query.from_user.id - if not await is_check_admin(client, grp_id, user_id): - return await callback_query.answer(script.NT_ADMIN_ALRT_TXT, show_alert=True) - await callback_query.answer("♻ ʀᴇꜱᴇᴛᴛɪɴɢ ꜱᴇᴛᴛɪɴɢꜱ...") - defaults = { - 'shortner': SHORTENER_WEBSITE, - 'api': SHORTENER_API, - 'shortner_two': SHORTENER_WEBSITE2, - 'api_two': SHORTENER_API2, - 'shortner_three': SHORTENER_WEBSITE3, - 'api_three': SHORTENER_API3, - 'custom_shortner': False, - 'custom_shortner_two': False, - 'custom_shortner_three': False, - 'verify_time': TWO_VERIFY_GAP, - 'third_verify_time': THREE_VERIFY_GAP, - 'template': IMDB_TEMPLATE, - 'tutorial': TUTORIAL, - 'tutorial_2': TUTORIAL_2, - 'tutorial_3': TUTORIAL_3, - 'caption': CUSTOM_FILE_CAPTION, - 'log': LOG_CHANNEL, - 'is_verify': IS_VERIFY, - 'fsub': AUTH_CHANNELS - } - current = await get_settings(grp_id) - if current == defaults: - return await callback_query.answer("✅ ꜱᴇᴛᴛɪɴɢꜱ ᴀʟʀᴇᴀᴅʏ ᴅᴇꜰᴀᴜʟᴛ.", show_alert=True) - for key, value in defaults.items(): - await save_group_settings(grp_id, key, value) - updated = await get_settings(grp_id) - title = callback_query.message.chat.title - text = generate_settings_text(updated, title, reset_done=True) - buttons = [ - [InlineKeyboardButton("♻ ʀᴇꜱᴇᴛ ꜱᴇᴛᴛɪɴɢꜱ", callback_data=f"reset_group_{grp_id}")], - [InlineKeyboardButton("🚫 ᴄʟᴏꜱᴇ", callback_data="close_data")] - ] - await callback_query.message.edit_text(text, reply_markup=InlineKeyboardMarkup(buttons), link_preview_options=LinkPreviewOptions(is_disabled=True)) - -@Client.on_message(filters.command("verify") & filters.user(ADMINS)) -async def verify(bot, message): - try: - chat_type = message.chat.type - if chat_type == enums.ChatType.PRIVATE: - return await message.reply_text("ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ ᴡᴏʀᴋs ᴏɴʟʏ ɪɴ ɢʀᴏᴜᴘs!") - if chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: - grpid = message.chat.id - command_text = message.text.split(' ')[1] if len(message.text.split(' ')) > 1 else None - if command_text == "off": - await save_group_settings(grpid, 'is_verify', False) - return await message.reply_text("✓ ᴠᴇʀɪꜰʏ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅɪsᴀʙʟᴇᴅ.") - elif command_text == "on": - await save_group_settings(grpid, 'is_verify', True) - return await message.reply_text("✗ ᴠᴇʀɪꜰʏ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴇɴᴀʙʟᴇᴅ.") - else: - return await message.reply_text("ʜɪ, ᴛᴏ ᴇɴᴀʙʟᴇ ᴠᴇʀɪꜰʏ, ᴜsᴇ /verify on ᴀɴᴅ ᴛᴏ ᴅɪsᴀʙʟᴇ ᴠᴇʀɪꜰʏ, ᴜsᴇ /verify off.") - except Exception as e: - logger.error("Error: %s", e) - await message.reply_text(f"Error: {e}") - -@Client.on_message(filters.command('set_fsub')) -async def set_fsub(client, message): - try: - userid = message.from_user.id if message.from_user else None - if not userid: - return await message.reply("You are Anonymous admin you can't use this command !") - if message.chat.type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: - return await message.reply_text("ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ ᴄᴀɴ ᴏɴʟʏ ʙᴇ ᴜsᴇᴅ ɪɴ ɢʀᴏᴜᴘs") - grp_id = message.chat.id - title = message.chat.title - if not await is_check_admin(client, grp_id, userid): - return await message.reply_text(script.NT_ADMIN_ALRT_TXT) - args = message.text.split(maxsplit=1) - if len(args) < 2: - return await message.reply_text( - "ᴄᴏᴍᴍᴀɴᴅ ɪɴᴄᴏᴍᴘʟᴇᴛᴇ!\n\n" - "ᴄᴀɴ ᴀᴅᴅ ᴍᴜʟᴛɪᴘʟᴇ ᴄʜᴀɴɴᴇʟs sᴇᴘᴀʀᴀᴛᴇᴅ ʙʏ sᴘᴀᴄᴇs. ʟɪᴋᴇ: /sᴇᴛ_ғsᴜʙ ɪᴅ1 ɪᴅ2 ɪᴅ3\n" - ) - option = args[1].strip() - try: - fsub_ids = [int(x) for x in option.split()] - except ValueError: - return await message.reply_text('ᴍᴀᴋᴇ sᴜʀᴇ ᴀʟʟ ɪᴅs ᴀʀᴇ ɪɴᴛᴇɢᴇʀs.') - if len(fsub_ids) > 5: - return await message.reply_text("ᴍᴀxɪᴍᴜᴍ 5 ᴄʜᴀɴɴᴇʟs ᴀʟʟᴏᴡᴇᴅ.") - channels = "ᴄʜᴀɴɴᴇʟs:\n" - channel_titles = [] - for id in fsub_ids: - try: - chat = await client.get_chat(id) - except Exception as e: - return await message.reply_text( - f"{id} ɪs ɪɴᴠᴀʟɪᴅ!\nᴍᴀᴋᴇ sᴜʀᴇ ᴛʜɪs ʙᴏᴛ ɪs ᴀᴅᴍɪɴ ɪɴ ᴛʜᴀᴛ ᴄʜᴀɴɴᴇʟ.\n\nError - {e}" - ) - if chat.type != enums.ChatType.CHANNEL: - return await message.reply_text(f"{id} ɪs ɴᴏᴛ ᴀ ᴄʜᴀɴɴᴇʟ.") - channel_titles.append(f"{chat.title} (`{id}`)") - channels += f'{chat.title}\n' - await save_group_settings(grp_id, 'fsub', fsub_ids) - await message.reply_text(f"sᴜᴄᴄᴇssғᴜʟʟʏ sᴇᴛ ꜰꜱᴜʙ ᴄʜᴀɴɴᴇʟ(ꜱ) ғᴏʀ {title} ᴛᴏ\n\n{channels}") - mention = message.from_user.mention if message.from_user else "Unknown" - await client.send_message( - LOG_CHANNEL, - f"#Fsub_Channel_set\n\n" - f"ᴜꜱᴇʀ - {mention} ꜱᴇᴛ ᴛʜᴇ ꜰᴏʀᴄᴇ ᴄʜᴀɴɴᴇʟ(ꜱ) ꜰᴏʀ {title}:\n\n" - f"ꜰꜱᴜʙ ᴄʜᴀɴɴᴇʟ(ꜱ):\n" + '\n'.join(channel_titles) - ) - except Exception as e: - err_text = f"⚠ Error in set_fSub :\n{e}" - logger.error(err_text) - await client.send_message(LOG_CHANNEL, err_text) - -@Client.on_message(filters.private & filters.command("resetallgroup") & filters.user(ADMINS)) -async def reset_all_settings(client, message): - try: - reset_count = await db.dreamx_reset_settings() - await message.reply_text( - f"ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ꜱᴇᴛᴛɪɴɢꜱ ꜰᴏʀ {reset_count} ɢʀᴏᴜᴘꜱ. ᴅᴇꜰᴀᴜʟᴛ ᴠᴀʟᴜᴇꜱ ᴡɪʟʟ ʙᴇ ᴜꜱᴇᴅ ✅" - ) - except Exception as e: - logger.error("reset_all_settings: %s", e) - await message.reply_text( - "🚫 An error occurred while resetting group settings.\nPlease try again later." - ) - -@Client.on_message(filters.command("trial_reset")) -async def reset_trial(client, message): - user_id = message.from_user.id - if user_id not in ADMINS: - await message.reply("ʏᴏᴜ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ ᴀɴʏ ᴘᴇʀᴍɪꜱꜱɪᴏɴ ᴛᴏ ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ.") - return - try: - if len(message.command) > 1: - target_user_id = int(message.command[1]) - updated_count = await db.reset_free_trial(target_user_id) - message_text = f"ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ʀᴇꜱᴇᴛ ꜰʀᴇᴇ ᴛʀᴀɪʟ ꜰᴏʀ ᴜꜱᴇʀꜱ {target_user_id}." if updated_count else f"ᴜꜱᴇʀ {target_user_id} ɴᴏᴛ ꜰᴏᴜɴᴅ ᴏʀ ᴅᴏɴ'ᴛ ᴄʟᴀɪᴍ ꜰʀᴇᴇ ᴛʀᴀɪʟ ʏᴇᴛ." - else: - updated_count = await db.reset_free_trial() - message_text = f"ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ʀᴇꜱᴇᴛ ꜰʀᴇᴇ ᴛʀᴀɪʟ ꜰᴏʀ {updated_count} ᴜꜱᴇʀꜱ." - await message.reply_text(message_text) - except Exception as e: - await message.reply_text(f"An error occurred: {e}") - - -@Client.on_message(filters.command('remove_fsub')) -async def remove_fsub(client, message): - try: - user = message.from_user - if not user: - return await message.reply("ʏᴏᴜ ᴀʀᴇ ᴀɴᴏɴʏᴍᴏᴜs ᴀᴅᴍɪɴ — ʏᴏᴜ ᴄᴀɴ'ᴛ ᴜsᴇ ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ!") - if message.chat.type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: - return await message.reply_text("ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ ᴄᴀɴ ᴏɴʟʏ ʙᴇ ᴜsᴇᴅ ɪɴ ɢʀᴏᴜᴘs.") - grp_id = message.chat.id - title = message.chat.title - if not await is_check_admin(client, grp_id, user.id): - return await message.reply_text(script.NT_ADMIN_ALRT_TXT) - args = message.text.split(maxsplit=1) - if len(args) < 2: - return await message.reply_text( - "ᴜsᴀɢᴇ:\n" - "• /remove_fsub ᴀʟʟ → ʀᴇᴍᴏᴠᴇ ᴀʟʟ ғsᴜʙ ᴄʜᴀɴɴᴇʟs\n" - "• /remove_fsub ɪᴅ1 ɪᴅ2 ... → ʀᴇᴍᴏᴠᴇ sᴘᴇᴄɪғɪᴄ ᴄʜᴀɴɴᴇʟ ɪᴅs" - ) - option = args[1].strip() - settings = await get_settings(grp_id) - cr_fsubs = settings.get("fsub", []) if settings else [] - if not cr_fsubs: - return await message.reply_text("ɴᴏ ғsᴜʙ ᴄʜᴀɴɴᴇʟs ᴀʀᴇ sᴇᴛ ғᴏʀ ᴛʜɪs ɢʀᴏᴜᴘ.") - if option.lower() == "all": - await save_group_settings(grp_id, 'fsub', []) - await message.reply_text(f"✅ ᴀʟʟ ғsᴜʙ ᴄʜᴀɴɴᴇʟs ʀᴇᴍᴏᴠᴇᴅ ғᴏʀ {title}") - return await client.send_message( - LOG_CHANNEL, - f"#ғsᴜʙ_ʀᴇᴍᴏᴠᴇᴅ\n\n👤 {user.mention} ʀᴇᴍᴏᴠᴇᴅ ᴀʟʟ ғsᴜʙ ᴄʜᴀɴɴᴇʟs ғᴏʀ {title}." - ) - try: - remove_ids = [int(x) for x in option.split()] - except ValueError: - return await message.reply_text("ᴍᴀᴋᴇ sᴜʀᴇ ᴀʟʟ ɪᴅs ᴀʀᴇ ᴠᴀʟɪᴅ ɪɴᴛᴇɢᴇʀs.") - - new_fsubs = [cid for cid in cr_fsubs if cid not in remove_ids] - r_id = [cid for cid in cr_fsubs if cid in remove_ids] - if not r_id: - return await message.reply_text("ɴᴏɴᴇ ᴏғ ᴛʜᴇ ɢɪᴠᴇɴ ɪᴅs ᴡᴇʀᴇ ғᴏᴜɴᴅ ɪɴ ᴛʜᴇ ᴄᴜʀʀᴇɴᴛ ғsᴜʙ ʟɪsᴛ.") - await save_group_settings(grp_id, 'fsub', new_fsubs) - r_t = [] - for cid in r_id: - try: - chat = await client.get_chat(cid) - r_t.append(f"• {chat.title} ({cid})") - except Exception: - r_t.append(f"• ᴜɴᴋɴᴏᴡɴ ({cid})") - - await message.reply_text( - f"✅ ʀᴇᴍᴏᴠᴇᴅ {len(r_id)} ғsᴜʙ ᴄʜᴀɴɴᴇʟ(s) ғʀᴏᴍ {title}:\n" + - "\n".join(r_t) - ) - await client.send_message( - LOG_CHANNEL, - f"#ғsᴜʙ_ᴄʜᴀɴɴᴇʟ_ʀᴇᴍᴏᴠᴇᴅ\n\n👤 {user.mention} ʀᴇᴍᴏᴠᴇᴅ ғsᴜʙ ᴄʜᴀɴɴᴇʟ(s) ғʀᴏᴍ {title}:\n" + - "\n".join(r_t) - ) - except Exception as e: - logger.error("remove_fsub: %s", e) - await message.reply_text(f"⚠ ᴀɴ ᴇʀʀᴏʀ ᴏᴄᴄᴜʀʀᴇᴅ: {e}") - -@Client.on_message(filters.command('clean_groups') & filters.user(ADMINS)) -async def clean_groups_handler(client, message): - msg = await message.reply('Cleaning groups... This may take a while.') - deleted_count = 0 - total_groups = await db.total_chat_count() - processed = 0 - batch_size = 100 - chats = await db.get_all_chats() - async for chat in chats: - try: - processed += 1 - chat_id = chat['id'] - try: - await client.get_chat_member(chat_id, client.me.id) - except FloodWait as e: - await asyncio.sleep(e.value) - try: - await client.get_chat_member(chat_id, client.me.id) - except (UserNotParticipant, PeerIdInvalid, ChannelInvalid): - await db.delete_chat(chat_id) - deleted_count += 1 - except Exception: - pass - except (UserNotParticipant, PeerIdInvalid, ChannelInvalid): - await db.delete_chat(chat_id) - deleted_count += 1 - except Exception as e: - logger.error("Error checking chat %s: %s", chat_id, e) - pass - if processed % batch_size == 0: - try: - await msg.edit(f'Progress: {processed}/{total_groups}\nDeleted: {deleted_count}') - await asyncio.sleep(2) - except FloodWait as e: - await asyncio.sleep(e.value) - await msg.edit(f'Progress: {processed}/{total_groups}\nDeleted: {deleted_count}') - except Exception as e: - logger.error("Error in clean_groups loop: %s", e) - await msg.edit(f'**Clean Groups Complete**\n\nTotal Processed: {processed}\nDeleted: {deleted_count}') From 39fca4880ddee6b7fa82ed9db504e3448b7b9327 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Mon, 14 Sep 2026 21:58:58 +0530 Subject: [PATCH 28/77] Update commands.py --- plugins/commands.py | 1477 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1448 insertions(+), 29 deletions(-) diff --git a/plugins/commands.py b/plugins/commands.py index c772e744..e9163d79 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -1,11 +1,57 @@ +import os +import re +import base64 +import logging +import random +import asyncio +import string +import sys +import pytz +from .pmfilter import auto_filter +from Script import script +from datetime import datetime, timedelta +from database.refer import referdb +from database.config_db import mdb +from pyrogram.types import LinkPreviewOptions, InlineKeyboardButton, InlineKeyboardMarkup, Message, ReplyKeyboardMarkup +from pyrogram import Client, filters, enums, StopPropagation +from pyrogram.errors import FloodWait, UserNotParticipant , ChannelInvalid, PeerIdInvalid +from database.ia_filterdb import Media, Media2, get_file_details, unpack_new_file_id, get_bad_files, save_file +from database.users_chats_db import db +from info import ( + LOG_CHANNEL, IMDB_TEMPLATE, IS_VERIFY, TUTORIAL, TUTORIAL_2, TUTORIAL_3, EMOJI_MODE, REACTIONS, + VERIFY_IMG, TWO_VERIFY_GAP, UPDATE_CHNL_LNK, PICS, PICS_URL, ADMINS, SUBSCRIPTION, OWNER_LNK , + OWNER_UPI_ID, QR_CODE, AUTH_CHANNELS, AUTH_REQ_CHANNELS, FSUB_PICS, THREE_VERIFY_GAP, CUSTOM_FILE_CAPTION, + COVERX, PROTECT_CONTENT, DELETE_TIME, PREMIUM_STREAM_MODE, STREAM_MODE, SUPPORT_CHAT_ID, REQST_CHANNEL, + LOG_CHANNEL, SHORTENER_API, SHORTENER_API2, SHORTENER_API3, SHORTENER_WEBSITE, SHORTENER_WEBSITE2, SHORTENER_WEBSITE3, + +) +from utils import get_settings, save_group_settings, is_subscribed, is_req_subscribed, get_size, get_shortlink, is_check_admin, temp, get_readable_time, get_time, generate_settings_text, log_error, clean_filename, get_random_mix_id + +logger = logging.getLogger(__name__) + +TIMEZONE = "Asia/Kolkata" +BATCH_FILES = {} +REQUEST_INVITE_LINK_CACHE: dict[int, str] = {} + + +@Client.on_message(filters.command("start") & filters.incoming) +async def start(client, message): + try: + if EMOJI_MODE: + try: + asyncio.create_task(message.react(emoji=random.choice(REACTIONS), big=True)) + except Exception: + asyncio.create_task(message.react(emoji="⚡")) + pass + m = message if len(m.command) == 2 and m.command[1].startswith(('notcopy', 'sendall')): _, userid, verify_id, file_id = m.command[1].split("_", 3) user_id = int(userid) grp_id = temp.VERIFICATIONS.get(user_id, 0) - settings = await get_settings(grp_id) + settings = await get_settings(grp_id) verify_id_info = await db.get_verify_id_info(user_id, verify_id) if not verify_id_info or verify_id_info["verified"]: - return await message.reply(script.LINK_EXPIRED_TXT) + return await message.reply(script.LINK_EXPIRED_TXT) ist_timezone = pytz.timezone('Asia/Kolkata') if await db.user_verified(user_id): @@ -15,21 +61,20 @@ current_time = datetime.now(tz=ist_timezone) await db.update_notcopy_user(user_id, {key:current_time}) await db.update_verify_id_info(user_id, verify_id, {"verified":True}) - - if key == "third_time_verified": - num = 3 + + if key == "third_time_verified": + num = 3 msg = script.THIRDT_VERIFY_COMPLETE_TEXT - else: - num = 2 if key == "second_time_verified" else 1 + else: + num = 2 if key == "second_time_verified" else 1 msg = script.SECOND_VERIFY_COMPLETE_TEXT if key == "second_time_verified" else script.VERIFY_COMPLETE_TEXT - + log_channel = settings.get('log') if settings and settings.get('log') else LOG_CHANNEL try: await client.send_message(log_channel, script.VERIFIED_LOG_TEXT.format(m.from_user.mention, user_id, datetime.now(pytz.timezone('Asia/Kolkata')).strftime('%d %B %Y'), num)) except Exception as e: logger.error(f"Failed to log verification: {e}") - - # Send Verification Complete message with the custom image & button + is_sendall = m.command[1].startswith('sendall') if is_sendall: verifiedfiles = f"https://telegram.me/{temp.U_NAME}?start=allfiles_{grp_id}_{file_id}" @@ -45,33 +90,34 @@ reply_markup=InlineKeyboardMarkup(btn_complete), parse_mode=enums.ParseMode.HTML ) - + async def _delete_msg(msg_to_delete, delay): await asyncio.sleep(delay) try: await msg_to_delete.delete() except Exception: pass - + asyncio.create_task(_delete_msg(dlt, 300)) - # Send files automatically WITHOUT stream buttons + # Send files automatically + is_sendall = m.command[1].startswith('sendall') decoded_file_id = file_id if not is_sendall: try: raw = base64.urlsafe_b64decode(file_id + "=" * (-len(file_id) % 4)) sep = raw.find(b"_") - if sep!= -1: + if sep != -1: decoded_file_id = raw[sep + 1:].decode("latin1") except Exception: pass filesarr = [] - + if is_sendall: files = temp.GETALL.get(file_id) if not files: - await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ!') + await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ !') return for file in files: file_id_item = file.file_id @@ -83,59 +129,60 @@ async def _delete_msg(msg_to_delete, delay): cover = files1.cover size = get_size(files1.file_size) f_caption = files1.caption - - DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION + + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION if settings else CUSTOM_FILE_CAPTION if DREAMX_CAPTION: try: f_caption = DREAMX_CAPTION.format(file_name='' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) except Exception as e: logger.exception(e) - + if f_caption is None: f_caption = f"{clean_filename(files1.file_name)}" - + sent_msg = await client.send_cached_media( chat_id=message.from_user.id, cover=cover, file_id=file_id_item, caption=f_caption, - protect_content=settings.get('file_secure', PROTECT_CONTENT) if settings else PROTECT_CONTENT + protect_content=settings.get('file_secure', PROTECT_CONTENT) if settings else PROTECT_CONTENT if settings else PROTECT_CONTENT ) filesarr.append(sent_msg) else: files_ = await get_file_details(decoded_file_id) if not files_: - await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ!') + await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ !') return files1 = files_[0] title = clean_filename(files1.file_name) size = get_size(files1.file_size) cover = files1.cover if files1.cover else None f_caption = files1.caption - + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION if DREAMX_CAPTION: try: f_caption = DREAMX_CAPTION.format(file_name='' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) except Exception as e: logger.exception(e) - + if f_caption is None: f_caption = clean_filename(files1.file_name) - + sent_msg = await client.send_cached_media( chat_id=message.from_user.id, file_id=decoded_file_id, cover=cover, caption=f_caption, - protect_content=settings.get('file_secure', PROTECT_CONTENT) if settings else PROTECT_CONTENT + protect_content=settings.get('file_secure', PROTECT_CONTENT), + reply_markup=InlineKeyboardMarkup(btn) ) filesarr.append(sent_msg) # Auto-Delete Logic if settings and settings.get('auto_delete', True) and filesarr: k = await client.send_message(chat_id=message.from_user.id, text=script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) - + async def _delete_files(msgs, notif_msg, delay): await asyncio.sleep(delay) for x in msgs: @@ -144,10 +191,1382 @@ async def _delete_files(msgs, notif_msg, delay): except Exception: pass try: - await notif_msg.edit_text("ʏᴏᴜʀ ᴠɪᴅᴇᴏꜱ/ꜰɪʟᴇꜱ ᴀʀᴇ ᴅᴇʟᴇᴛᴇᴅ ꜱᴜᴄᴄᴇꜱꜰᴜʟʟʏ!\nᴋɪɴᴅʟʏ ꜱᴇᴀʀᴄʜ ᴀɢᴀɪɴ") + await notif_msg.edit_text("ʏᴏᴜʀ ᴠɪᴅᴇᴏꜱ/ꜰɪʟᴇꜱ ᴀʀᴇ ᴅᴇʟᴇᴛᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ !\nᴋɪɴᴅʟʏ ꜱᴇᴀʀᴄʜ ᴀɢᴀɪɴ") except Exception: pass - + asyncio.create_task(_delete_files(filesarr, k, DELETE_TIME)) + + return + if message.chat.type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: + buttons = [[ + InlineKeyboardButton('❤ ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ ❤', url=f'http://t.me/{temp.U_NAME}?startgroup=true') + ],[ + InlineKeyboardButton('🍁 Update Channel 🍁', url=UPDATE_CHNL_LNK) + ]] + reply_markup = InlineKeyboardMarkup(buttons) + await message.reply(script.GSTART_TXT.format(message.from_user.mention if message.from_user else message.chat.title, temp.U_NAME, temp.B_NAME), reply_markup=reply_markup, link_preview_options=LinkPreviewOptions(is_disabled=True)) + await asyncio.sleep(2) + if not await db.get_chat(message.chat.id): + total=await client.get_chat_members_count(message.chat.id) + await client.send_message(LOG_CHANNEL, script.LOG_TEXT_G.format(message.chat.title, message.chat.id, total, "Unknown")) + await db.add_chat(message.chat.id, message.chat.title) + return + if not await db.is_user_exist(message.from_user.id): + await db.add_user(message.from_user.id, message.from_user.first_name) + await client.send_message(LOG_CHANNEL, script.LOG_TEXT_P.format(message.from_user.id, message.from_user.mention)) + if len(message.command) != 2: + buttons = [[ + InlineKeyboardButton('🔰 ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://t.me/{temp.U_NAME}?startgroup=true') + ],[ + InlineKeyboardButton(' ʜᴇʟᴘ 📢', callback_data='help'), + InlineKeyboardButton(' ᴀʙᴏᴜᴛ 📖', callback_data='about') + ],[ + InlineKeyboardButton('ᴛᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), + InlineKeyboardButton('ᴜᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), + ]] + reply_markup = InlineKeyboardMarkup(buttons) + current_time = datetime.now(pytz.timezone(TIMEZONE)) + curr_time = current_time.hour + if curr_time < 12: + gtxt = "ɢᴏᴏᴅ ᴍᴏʀɴɪɴɢ 🌞" + elif curr_time < 17: + gtxt = "ɢᴏᴏᴅ ᴀғᴛᴇʀɴᴏᴏɴ 🌓" + elif curr_time < 21: + gtxt = "ɢᴏᴏᴅ ᴇᴠᴇɴɪɴɢ 🌘" + else: + gtxt = "ɢᴏᴏᴅ ɴɪɢʜᴛ 🌑" + if len(PICS) == 1: + PIC = PICS[0] + else: + try: + PIC = f"{random.choice(PICS_URL)}?r={get_random_mix_id()}" + except Exception: + PIC = random.choice(PICS) + await message.reply_photo( + photo=PIC, + caption=script.START_TXT.format(message.from_user.mention, gtxt, temp.U_NAME, temp.B_NAME), + reply_markup=reply_markup, + parse_mode=enums.ParseMode.HTML + ) + return + + if len(message.command) == 2 and message.command[1] in ["subscribe", "error", "okay", "help"]: + buttons = [[ + InlineKeyboardButton('🔰 ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://t.me/{temp.U_NAME}?startgroup=true') + ],[ + InlineKeyboardButton(' ʜᴇʟᴘ 📢', callback_data='help'), + InlineKeyboardButton(' ᴀʙᴏᴜᴛ 📖', callback_data='about') + ],[ + InlineKeyboardButton('ᴛᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), + InlineKeyboardButton('ᴜᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), + ]] + reply_markup = InlineKeyboardMarkup(buttons) + current_time = datetime.now(pytz.timezone(TIMEZONE)) + curr_time = current_time.hour + if curr_time < 12: + gtxt = "ɢᴏᴏᴅ ᴍᴏʀɴɪɴɢ 🌞" + elif curr_time < 17: + gtxt = "ɢᴏᴏᴅ ᴀғᴛᴇʀɴᴏᴏɴ 🌓" + elif curr_time < 21: + gtxt = "ɢᴏᴏᴅ ᴇᴠᴇɴɪɴɢ 🌘" + else: + gtxt = "ɢᴏᴏᴅ ɴɪɢʜᴛ 🌑" + if len(PICS) == 1: + PIC = PICS[0] + else: + try: + PIC = f"{random.choice(PICS_URL)}?r={get_random_mix_id()}" + except Exception: + PIC = random.choice(PICS) + await message.reply_photo( + photo=PIC, + caption=script.START_TXT.format(message.from_user.mention, gtxt, temp.U_NAME, temp.B_NAME), + reply_markup=reply_markup, + parse_mode=enums.ParseMode.HTML + ) return + if message.command[1].startswith("reff_"): + try: + user_id = int(message.command[1].split("_")[1]) + except ValueError: + await message.reply_text("‼ ɪɴᴠᴀʟɪᴅ ʀᴇꜰᴇʀ!") + return + if user_id == message.from_user.id: + await message.reply_text(script.REFER_SELF_ALRT) + return + if referdb.is_user_in_list(message.from_user.id): + await message.reply_text(script.REFER_ALREADY_ALRT) + return + if await db.is_user_exist(message.from_user.id): + await message.reply_text(script.REFER_ALREADY_JOINED_ALRT) + return + try: + uss = await client.get_users(user_id) + except Exception: + return + referdb.add_user(message.from_user.id) + fromuse = referdb.get_refer_points(user_id) + 10 + if fromuse == 100: + referdb.add_refer_points(user_id, 0) + await message.reply_text(script.REFER_INVITED_ALRT.format(uss.mention)) + await client.send_message(chat_id=user_id, text=script.REFER_CONGRATS_ALRT.format(message.from_user.mention)) + seconds = 2592000 + if seconds > 0: + expiry_time = datetime.now() + timedelta(seconds=seconds) + user_data = {"id": user_id, "expiry_time": expiry_time} + await db.update_user(user_data) + await client.send_message( + chat_id=user_id, + text=f"Hᴇʏ {uss.mention}\n\nYᴏᴜ ɢᴏᴛ 1 ᴍᴏɴᴛʜ ᴘʀᴇᴍɪᴜᴍ sᴜʙsᴄʀɪᴘᴛɪᴏɴ ʙʏ ɪɴᴠɪᴛɪɴɢ 10 ᴜsᴇʀs ❗", + link_preview_options=LinkPreviewOptions(is_disabled=True) + ) + for admin in ADMINS: + await client.send_message(chat_id=admin, text=f"Sᴜᴄᴄᴇss ғᴜʟʟʏ ᴛᴀsᴋ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ʙʏ ᴛʜɪs ᴜsᴇʀ:\n\nuser Nᴀᴍᴇ: {uss.mention}\n\nUsᴇʀ ɪᴅ: {uss.id}!") + else: + referdb.add_refer_points(user_id, fromuse) + await message.reply_text(script.REFER_INVITED_ALRT.format(uss.mention)) + await client.send_message(user_id, script.REFER_CONGRATS_ALRT.format(message.from_user.mention)) + return + + if len(message.command) == 2 and message.command[1] in ["premium"]: + buttons = [[ + InlineKeyboardButton('📲 ꜱᴇɴᴅ ᴘᴀʏᴍᴇɴᴛ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ', url=OWNER_LNK) + ],[ + InlineKeyboardButton('UPI ID Copy Karein ??', copy_text=OWNER_UPI_ID) + ],[ + InlineKeyboardButton('❌ ᴄʟᴏꜱᴇ ❌', callback_data='close_data') + ]] + reply_markup = InlineKeyboardMarkup(buttons) + await message.reply_photo( + photo=(SUBSCRIPTION), + caption=script.PREPLANS_TXT.format(message.from_user.mention, OWNER_UPI_ID, QR_CODE), + reply_markup=reply_markup, + parse_mode=enums.ParseMode.HTML + ) + return + + if len(message.command) == 2 and message.command[1].startswith('getfile'): + movies = message.command[1].split("-", 1)[1] + movie = movies.replace('-',' ') + message.text = movie + await auto_filter(client, message) + raise StopPropagation + + data = message.command[1] + try: + _, grp_id, file_id = data.split("_", 2) + grp_id = int(grp_id) + except Exception: + grp_id = 0 + file_id = data + + decoded_file_id = file_id + if not data.startswith("allfiles"): + try: + raw = base64.urlsafe_b64decode(file_id + "=" * (-len(file_id) % 4)) + sep = raw.find(b"_") + if sep != -1: + decoded_file_id = raw[sep + 1:].decode("latin1") + except Exception: + pass + + file_details_task = asyncio.create_task(get_file_details(decoded_file_id)) + if not await db.has_premium_access(message.from_user.id): + try: + btn = [] + chat = grp_id + settings = await get_settings(chat) + fsub_channels = list(dict.fromkeys((settings.get('fsub', []) if settings else [])+ AUTH_CHANNELS)) + + if fsub_channels: + btn += await is_subscribed(client, message.from_user.id, fsub_channels) + if AUTH_REQ_CHANNELS: + btn += await is_req_subscribed(client, message.from_user.id, AUTH_REQ_CHANNELS) + if btn: + if len(message.command) > 1 and "_" in message.command[1]: + kk, file_id = message.command[1].split("_", 1) + btn.append([ + InlineKeyboardButton("♻ ᴛʀʏ ᴀɢᴀɪɴ ♻", callback_data=f"checksub#{kk}#{file_id}") + ]) + reply_markup = InlineKeyboardMarkup(btn) + photo = random.choice(FSUB_PICS) if FSUB_PICS else "https://graph.org/file/7478ff3eac37f4329c3d8.jpg" + caption = script.FORCESUB_TXT.format(message.from_user.mention) + await message.reply_photo( + photo=photo, + caption=caption, + reply_markup=reply_markup, + parse_mode=enums.ParseMode.HTML + ) + return + + except Exception as e: + await log_error(client, f"❗ Force Sub Error:\n\n{repr(e)}") + logger.error(f"❗ Force Sub Error:\n\n{repr(e)}") + + user_id = m.from_user.id + if not await db.has_premium_access(user_id): + try: + grp_id = int(grp_id) + user_verified = await db.is_user_verified(user_id) + settings = await get_settings(grp_id) + is_second_shortener = await db.use_second_shortener(user_id, settings.get('verify_time', TWO_VERIFY_GAP)) + is_third_shortener = await db.use_third_shortener(user_id, settings.get('third_verify_time', THREE_VERIFY_GAP)) + if settings.get("is_verify", IS_VERIFY) and (not user_verified or is_second_shortener or is_third_shortener): + verify_id = ''.join(random.choices(string.ascii_uppercase + string.digits, k=7)) + await db.create_verify_id(user_id, verify_id) + temp.VERIFICATIONS[user_id] = grp_id + if message.command[1].startswith('allfiles'): + verify = await get_shortlink(f"https://telegram.me/{temp.U_NAME}?start=sendall_{user_id}_{verify_id}_{file_id}", grp_id, is_second_shortener, is_third_shortener) + else: + verify = await get_shortlink(f"https://telegram.me/{temp.U_NAME}?start=notcopy_{user_id}_{verify_id}_{file_id}", grp_id, is_second_shortener, is_third_shortener) + if is_third_shortener: + howtodownload = settings.get('tutorial_3', TUTORIAL_3) + else: + howtodownload = settings.get('tutorial_2', TUTORIAL_2) if is_second_shortener else settings.get('tutorial', TUTORIAL) + buttons = [[ + InlineKeyboardButton(text="♻ ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ᴠᴇʀɪꜰʏ ♻", url=verify) + ],[ + InlineKeyboardButton(text="⁉ ʜᴏᴡ ᴛᴏ ᴠᴇʀɪꜰʏ ⁉", url=howtodownload) + ]] + reply_markup=InlineKeyboardMarkup(buttons) + if await db.user_verified(user_id): + msg = script.THIRDT_VERIFICATION_TEXT + else: + msg = script.SECOND_VERIFICATION_TEXT if is_second_shortener else script.VERIFICATION_TEXT + n=await m.reply_text( + text=msg.format(message.from_user.mention), + protect_content = True, + reply_markup=reply_markup, + parse_mode=enums.ParseMode.HTML + ) + await asyncio.sleep(300) + await n.delete() + await m.delete() + return + except Exception as e: + logger.error("Error In Verification: %s", e) + pass + + files_ = await file_details_task + if data.startswith("allfiles"): + try: + files = temp.GETALL.get(file_id) + if not files: + return await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ !') + filesarr = [] + cover = None + for file in files: + file_id = file.file_id + files_ = await get_file_details(file_id) + files1 = files_[0] + title = clean_filename(files1.file_name) + cover = files1.cover + size = get_size(files1.file_size) + f_caption = files1.caption + settings = await get_settings(int(grp_id)) + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION if settings else CUSTOM_FILE_CAPTION + if DREAMX_CAPTION: + try: + f_caption=DREAMX_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) + except Exception as e: + logger.exception(e) + f_caption = f_caption + if f_caption is None: + f_caption = f"{clean_filename(files1.file_name)}" + btn = await stream_buttons(message.from_user.id, file_id) + msg = await client.send_cached_media( + chat_id=message.from_user.id, + cover=cover, + file_id=file_id, + caption=f_caption, + protect_content=settings.get('file_secure', PROTECT_CONTENT) if settings else PROTECT_CONTENT, + reply_markup=InlineKeyboardMarkup(btn) + ) + filesarr.append(msg) + k = await client.send_message(chat_id=message.from_user.id, text=script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) + + await asyncio.sleep(DELETE_TIME) + for x in filesarr: + await x.delete() + await k.edit_text("ʏᴏᴜʀ ᴀʟʟ ᴠɪᴅᴇᴏꜱ/ꜰɪʟᴇꜱ ᴀʀᴇ ᴅᴇʟᴇᴛᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ !\nᴋɪɴᴅʟʏ ꜱᴇᴀʀᴄʜ ᴀɢᴀɪɴ") + return + except Exception as e: + logger.exception(e) + return + + settings = await get_settings(int(grp_id)) + if not files_: + file_id = decoded_file_id + try: + cover = None + if COVERX: + details = await get_file_details(file_id) + cover = details[0].cover if details and details[0].cover else None + btn = await stream_buttons(message.from_user.id, file_id) + msg = await client.send_cached_media( + chat_id=message.from_user.id, + cover=cover, + file_id=file_id, + protect_content=settings.get('file_secure', PROTECT_CONTENT), + reply_markup=InlineKeyboardMarkup(btn)) + + filetype = msg.media + file = getattr(msg, filetype.value) + title = clean_filename(file.file_name) + size=get_size(file.file_size) + f_caption = f"{title}" + settings = await get_settings(int(grp_id)) + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION + if DREAMX_CAPTION: + try: + f_caption=DREAMX_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='') + except Exception: + return + await msg.edit_caption(f_caption, reply_markup=InlineKeyboardMarkup(btn)) + # FIXED: removed + k = await msg.reply(script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) + await asyncio.sleep(DELETE_TIME) + await msg.delete() + await k.edit_text("ʏᴏᴜʀ ᴠɪᴅᴇᴏ / ꜰɪʟᴇ ɪꜱ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ !!") + return + except Exception as e: + logger.exception(e) + pass + return await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ !') + + files = files_[0] + title = clean_filename(files.file_name) + size = get_size(files.file_size) + cover = files.cover if files.cover else None + f_caption = files.caption + settings = await get_settings(int(grp_id)) + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) + if DREAMX_CAPTION: + try: + f_caption=DREAMX_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) + except Exception as e: + logger.exception(e) + f_caption = f_caption + + if f_caption is None: + f_caption = clean_filename(files.file_name) + btn = await stream_buttons(message.from_user.id, file_id) + msg = await client.send_cached_media( + chat_id=message.from_user.id, + file_id=file_id, + cover=cover, + caption=f_caption, + protect_content=settings.get('file_secure', PROTECT_CONTENT), + reply_markup=InlineKeyboardMarkup(btn) + ) + + k = await msg.reply(script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) + await asyncio.sleep(DELETE_TIME) + await msg.delete() + await k.edit_text("ʏᴏᴜʀ ᴠɪᴅᴇᴏ / ꜰɪʟᴇ ɪꜱ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ !!") + return + except StopPropagation: + raise + except Exception as e: + logger.exception(f"Error In /start command - {e}") + pass + +async def stream_buttons(user_id: int, file_id: str): + if STREAM_MODE and not PREMIUM_STREAM_MODE: + return [ + [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], + [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], + [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] + ] + elif STREAM_MODE and PREMIUM_STREAM_MODE: + if not await db.has_premium_access(user_id): + return [ + [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data='prestream')], + [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data='prestream')], + [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] + ] + else: + return [ + [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], + [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], + [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] + ] + else: + return [[InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)]] + +@Client.on_message(filters.command('logs') & filters.user(ADMINS)) +async def log_file(bot, message): + try: + await message.reply_document('DreamXlogs.txt', caption="📑 **ʟᴏɢꜱ**") + except Exception as e: + await message.reply(str(e)) + +@Client.on_message(filters.command('save') & filters.user(ADMINS)) +async def save_file_handler(bot, message): + reply = message.reply_to_message + if reply and reply.media: + msg = await message.reply("Pʀᴏᴄᴇssɪɴɢ...⏳") + else: + await message.reply('Rᴇᴘʟʏ ᴛᴏ ғɪʟᴇ ᴡɪᴛʜ /save ᴡʜɪᴄʜ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ sᴀᴠᴇ') + return + + try: + for file_type in ("document", "video", "audio"): + media = getattr(reply, file_type, None) + if media is not None: + break + else: + await msg.edit('Tʜɪs ɪs ɴᴏᴛ sᴜᴘᴘᴏʀᴛᴇᴅ ғɪʟᴇ ғᴏʀᴍᴀᴛ') + return + + file_id, file_ref = unpack_new_file_id(media.file_id) + media.file_type = file_type + media.caption = reply.caption + success, status = await save_file(media) + if success: + await msg.edit('Fɪʟᴇ ɪs sᴜᴄᴄᴇssғᴜʟʟʏ sᴀᴠᴇᴅ ᴛᴏ ᴅᴀᴛᴀʙᴀsᴇ ✅') + elif status == 0: + await msg.edit('Fɪʟᴇ ᴀʟʀᴇᴀᴅʏ ᴇxɪsᴛs ɪɴ ᴅᴀᴛᴀʙᴀsᴇ ⚠') + elif status == 2: + await msg.edit('Eʀʀᴏʀ: Fɪʟᴇ ᴠᴀʟɪᴅᴀᴛɪᴏɴ ғᴀɪʟᴇᴅ ❌') + else: + await msg.edit('Eʀʀᴏʀ: Fᴀɪʟᴇᴅ ᴛᴏ sᴀᴠᴇ ғɪʟᴇ ❌') + except Exception as e: + logger.exception(e) + await msg.edit(f'Aɴ ᴜɴᴇxᴘᴇᴄᴛᴇᴅ ᴇʀʀᴏʀ ᴏᴄᴄᴜʀʀᴇᴅ: {e} ❌') + + +@Client.on_message(filters.command('delete') & filters.user(ADMINS)) +async def delete(bot, message): + reply = message.reply_to_message + if reply and reply.media: + msg = await message.reply("Pʀᴏᴄᴇssɪɴɢ...⏳") + else: + await message.reply('Rᴇᴘʟʏ ᴛᴏ ғɪʟᴇ ᴡɪᴛʜ /delete ᴡʜɪᴄʜ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴅᴇʟᴇᴛᴇ') + return + + for file_type in ("document", "video", "audio"): + media = getattr(reply, file_type, None) + if media is not None: + break + else: + await msg.edit('Tʜɪs ɪs ɴᴏᴛ sᴜᴘᴘᴏʀᴛᴇᴅ ғɪʟᴇ ғᴏʀᴍᴀᴛ') + return + + file_id, file_ref = unpack_new_file_id(media.file_id) + if await Media.count_documents({'file_id': file_id}): + result = await Media.collection.delete_one({ + '_id': file_id, + }) + else: + result = await Media2.collection.delete_one({ + '_id': file_id, + }) + if result.deleted_count: + await msg.edit('Fɪʟᴇ ɪs sᴜᴄᴄᴇssғᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ғʀᴏᴍ ᴅᴀᴛᴀʙᴀsᴇ ✅') + else: + file_name = re.sub(r"(_|\-|\.|\+)", " ", str(media.file_name)) + result = await Media.collection.delete_many({ + 'file_name': file_name, + 'file_size': media.file_size, + 'mime_type': media.mime_type + }) + if result.deleted_count: + await msg.edit('Fɪʟᴇ ɪs sᴜᴄᴄᴇssғᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ғʀᴏᴍ ᴅᴀᴛᴀʙᴀsᴇ ✅') + else: + result = await Media2.collection.delete_many({ + 'file_name': file_name, + 'file_size': media.file_size, + 'mime_type': media.mime_type + }) + if result.deleted_count: + await msg.edit('Fɪʟᴇ ɪs sᴜᴄᴄᴇssғᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ғʀᴏᴍ ᴅᴀᴛᴀʙᴀsᴇ') + else: + result = await Media.collection.delete_many({ + 'file_name': media.file_name, + 'file_size': media.file_size, + 'mime_type': media.mime_type + }) + if result.deleted_count: + await msg.edit('Fɪʟᴇ ɪs sᴜᴄᴄᴇssғᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ғʀᴏᴍ ᴅᴀᴛᴀʙᴀsᴇ ✅') + else: + result = await Media2.collection.delete_many({ + 'file_name': media.file_name, + 'file_size': media.file_size, + 'mime_type': media.mime_type + }) + if result.deleted_count: + await msg.edit('Fɪʟᴇ ɪs sᴜᴄᴄᴇssғᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ғʀᴏᴍ ᴅᴀᴛᴀʙᴀsᴇ ✅') + else: + await msg.edit('Fɪʟᴇ ɴᴏᴛ ғᴏᴜɴᴅ ɪɴ ᴅᴀᴛᴀʙᴀsᴇ ❌') + + +@Client.on_message(filters.command('deleteall') & filters.user(ADMINS)) +async def delete_all_index(bot, message): + await message.reply_text( + 'ᴛʜɪꜱ ᴡɪʟʟ ᴅᴇʟᴇᴛᴇ ᴀʟʟ ʏᴏᴜʀ ɪɴᴅᴇxᴇᴅ ꜰɪʟᴇꜱ !\nᴅᴏ ʏᴏᴜ ꜱᴛɪʟʟ ᴡᴀɴᴛ ᴛᴏ ᴄᴏɴᴛɪɴᴜᴇ ?', + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="⚠ ʏᴇꜱ ⚠", callback_data="autofilter_delete" + ) + ], + [ + InlineKeyboardButton( + text="❌ ɴᴏ ❌", callback_data="close_data" + ) + ], + ] + ), + ) + +@Client.on_message(filters.command('settings')) +async def settings(client, message): + user_id = message.from_user.id if message.from_user else None + if not user_id: + return await message.reply("ʏᴏᴜ'ʀᴇ ᴀɴᴏɴʏᴍᴏᴜꜱ ᴀᴅᴍɪɴ.") + chat_type = message.chat.type + if chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: + grp_id = message.chat.id + if not await is_check_admin(client, grp_id, message.from_user.id): + return await message.reply_text(script.NT_ADMIN_ALRT_TXT) + await db.connect_group(grp_id, user_id) + btn = [[ + InlineKeyboardButton("👤 ᴏᴘᴇɴ ɪɴ ᴘʀɪᴠᴀᴛᴇ ᴄʜᴀᴛ 👤", callback_data=f"opnsetpm#{grp_id}") + ],[ + InlineKeyboardButton("👥 ᴏᴘᴇɴ ʜᴇʀᴇ 👥", callback_data=f"opnsetgrp#{grp_id}") + ]] + await message.reply_text( + text="ᴡʜᴇʀᴇ ᴅᴏ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴏᴘᴇɴ ꜱᴇᴛᴛɪɴɢꜱ ᴍᴇɴᴜ ? ⚙", + reply_markup=InlineKeyboardMarkup(btn), + link_preview_options=LinkPreviewOptions(is_disabled=True), + parse_mode=enums.ParseMode.HTML + ) + elif chat_type == enums.ChatType.PRIVATE: + connected_groups = await db.get_connected_grps(user_id) + if not connected_groups: + return await message.reply_text("Nᴏ Cᴏɴɴᴇᴄᴛᴇᴅ Gʀᴏᴜᴘs Fᴏᴜɴᴅ .") + group_list = [] + for group in connected_groups: + try: + Chat = await client.get_chat(group) + group_list.append([ InlineKeyboardButton(text=Chat.title, callback_data=f"grp_pm#{Chat.id}") ]) + except Exception: + pass + await message.reply_text( + "⚠ ꜱᴇʟᴇᴄᴛ ᴛʜᴇ ɢʀᴏᴜᴘ ᴡʜᴏꜱᴇ ꜱᴇᴛᴛɪɴɢꜱ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʜᴀɴɢᴇ.\n\n" + "ɪꜰ ʏᴏᴜʀ ɢʀᴏᴜᴘ ɪꜱ ɴᴏᴛ ꜱʜᴏᴡɪɴɢ ʜᴇʀᴇ,\n" + "ᴜꜱᴇ /reload ɪɴ ᴛʜᴀᴛ ɢʀᴏᴜᴘ ᴀɴᴅ ɪᴛ ᴡɪʟʟ ᴀᴘᴘᴇᴀʀ ʜᴇʀᴇ.", + reply_markup=InlineKeyboardMarkup(group_list) + ) + +@Client.on_message(filters.command('reload')) +async def connect_group(client, message): + user_id = message.from_user.id + if message.chat.type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: + await db.connect_group(message.chat.id, user_id) + await message.reply_text("Gʀᴏᴜᴘ Rᴇʟᴏᴀᴅᴇᴅ ✅ Nᴏᴡ Yᴏᴜ Cᴀɴ Mᴀɴᴀɢᴇ Tʜɪs Gʀᴏᴜᴘ Fʀᴏᴍ PM.") + elif message.chat.type == enums.ChatType.PRIVATE: + if len(message.command) < 2: + await message.reply_text("Example: /reload 123456789") + return + try: + group_id = int(message.command[1]) + if not await is_check_admin(client, group_id, user_id): + await message.reply_text(script.NT_ADMIN_ALRT_TXT) + return + chat = await client.get_chat(group_id) + await db.connect_group(group_id, user_id) + await message.reply_text(f"Lɪɴᴋᴇᴅ sᴜᴄᴄᴇssғᴜʟʟʏ ✅ {chat.title} ᴛᴏ PM.") + except Exception: + await message.reply_text("Invalid group ID or error occurred.") + +@Client.on_message(filters.command('set_template')) +async def save_template(client, message): + sts = await message.reply("ᴄʜᴇᴄᴋɪɴɢ ᴛᴇᴍᴘʟᴀᴛᴇ...") + user_id = message.from_user.id if message.from_user else None + if not user_id: + return await message.reply("ʏᴏᴜ'ʀᴇ ᴀɴᴏɴʏᴍᴏᴜꜱ ᴀᴅᴍɪɴ.") + + if message.chat.type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: + return await sts.edit("⚠ ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ɪɴ ᴀ ɢʀᴏᴜᴘ ᴄʜᴀᴛ.") + + group_id = message.chat.id + title = message.chat.title + if not await is_check_admin(client, group_id, user_id): + await message.reply_text(script.NT_ADMIN_ALRT_TXT) + return + if len(message.command) < 2: + return await sts.edit("⚠ ɴᴏ ᴛᴇᴍᴘʟᴀᴛᴇ ᴘʀᴏᴠɪᴅᴇᴅ!") + + template = message.text.split(" ", 1)[1] + await save_group_settings(group_id, 'template', template) + await sts.edit( + f"✅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴜᴘᴅᴀᴛᴇᴅ ᴛᴇᴍᴘʟᴀᴛᴇ ꜰᴏʀ {title} ᴛᴏ:\n\n{template}" + ) + + +@Client.on_message((filters.command("request") | filters.regex(r"(?i)#request")) & filters.group) +async def requests(bot, message): + if message.chat.id != SUPPORT_CHAT_ID: + return + if not message.from_user: + return await message.reply_text("⚠ ᴜɴᴀʙʟᴇ ᴛᴏ ɪᴅᴇɴᴛɪꜰʏ ʏᴏᴜ.") + + reporter = str(message.from_user.id) + mention = message.from_user.mention + + if message.reply_to_message: + target_msg = message.reply_to_message + content = target_msg.text or target_msg.caption or "" + msg_link = target_msg.link + else: + content = message.text or message.caption or "" + content = re.sub(r"(?i)[#/]?request", "", content).strip() + msg_link = message.link + + content = content.strip() + if len(content) < 3: + return await message.reply_text("ʏᴏᴜ ᴍᴜꜱᴛ ᴛʏᴘᴇ ᴀʙᴏᴜᴛ ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ [ᴍɪɴɪᴍᴜᴍ 3 ᴄʜᴀʀᴀᴄᴛᴇʀꜱ]. ʀᴇǫᴜᴇꜱᴛꜱ ᴄᴀɴ'ᴛ ʙᴇ ᴇᴍᴘᴛʏ.") + + reported_post: Message | None = None + try: + btn = [[ + InlineKeyboardButton('ᴠɪᴇᴡ ʀᴇǫᴜᴇꜱᴛ', url=msg_link), + InlineKeyboardButton('ꜱʜᴏᴡ ᴏᴘᴛɪᴏɴꜱ', callback_data=f'show_option#{reporter}') + ]] + req_text = f"📝 ʀᴇǫᴜᴇꜱᴛ : {content}\n\n📚 ʀᴇᴘᴏʀᴛᴇᴅ ʙʏ : {mention}\n📖 ʀᴇᴘᴏʀᴛᴇʀ ɪᴅ : {reporter}\n\n" + warning_text = "⚠ ʀᴇǫᴜᴇꜱᴛ ᴄʜᴀɴɴᴇʟ ɪꜱ ɴᴏᴛ ꜱᴇᴛ." + if REQST_CHANNEL is not None: + try: + reported_post = await bot.send_message(chat_id=REQST_CHANNEL, text=req_text, reply_markup=InlineKeyboardMarkup(btn)) + except Exception: + for admin in ADMINS: + await bot.send_message(chat_id=admin, text=warning_text) + reported_post = await bot.send_message(chat_id=admin, text=req_text, reply_markup=InlineKeyboardMarkup(btn)) + else: + for admin in ADMINS: + await bot.send_message(chat_id=admin, text=warning_text) + reported_post = await bot.send_message(chat_id=admin, text=req_text, reply_markup=InlineKeyboardMarkup(btn)) + except Exception: + logger.exception("Request failed") + return await message.reply_text( "⚠ ꜱᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ. ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ.") + + if reported_post and REQST_CHANNEL is not None: + try: + invite_link = REQUEST_INVITE_LINK_CACHE.get(REQST_CHANNEL) + if not invite_link: + try: + link = await bot.create_chat_invite_link(int(REQST_CHANNEL)) + invite_link = link.invite_link + REQUEST_INVITE_LINK_CACHE[REQST_CHANNEL] = invite_link + except Exception: + logger.exception("Failed to create invite link") + invite_link = None + if invite_link: + btn = [[ + InlineKeyboardButton('ᴊᴏɪɴ ᴄʜᴀɴɴᴇʟ', url=invite_link), + InlineKeyboardButton('ᴠɪᴇᴡ ʀᴇǫᴜᴇꜱᴛ', url=reported_post.link) + ]] + await message.reply_text("ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ʜᴀꜱ ʙᴇᴇɴ ᴀᴅᴅᴇᴅ! ᴘʟᴇᴀꜱᴇ ᴡᴀɪᴛ ꜰᴏʀ ꜱᴏᴍᴇ ᴛɪᴍᴇ.\n\nᴊᴏɪɴ ᴄʜᴀɴɴᴇʟ ꜰɪʀꜱᴛ & ᴠɪᴇᴡ ʀᴇǫᴜᴇꜱᴛ.", reply_markup=InlineKeyboardMarkup(btn)) + else: + await message.reply_text("ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ʜᴀꜱ ʙᴇᴇɴ ᴀᴅᴅᴇᴅ! ᴘʟᴇᴀꜱᴇ ᴡᴀɪᴛ ꜰᴏʀ ꜱᴏᴍᴇ ᴛɪᴍᴇ.") + except Exception: + logger.exception("Failed to send request confirmation") + await message.reply_text("⚠ ꜱᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ. ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ.") + +@Client.on_message(filters.command("send") & filters.user(ADMINS)) +async def send_msg(bot, message): + if message.reply_to_message: + target_id = message.text.split(" ", 1)[1] + out = "Users Saved In DB Are:\n\n" + success = False + try: + user = await bot.get_users(target_id) + users = await db.get_all_users() + async for usr in users: + out += f"{usr['id']}" + out += '\n' + if str(user.id) in str(out): + await message.reply_to_message.copy(int(user.id)) + success = True + else: + success = False + if success: + await message.reply_text(f"ʏᴏᴜʀ ᴍᴇꜱꜱᴀɢᴇ ʜᴀꜱ ʙᴇᴇɴ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ꜱᴇɴᴛ ᴛᴏ {user.mention}.") + else: + await message.reply_text("ᴛʜɪꜱ ᴜꜱᴇʀ ᴅɪᴅɴ'ᴛ ꜱᴛᴀʀᴛᴇᴅ ᴛʜɪꜱ ʙᴏᴛ ʏᴇᴛ !") + except Exception as e: + await message.reply_text(f"Error: {e}") + else: + await message.reply_text("ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ᴀꜱ ᴀ ʀᴇᴘʟʏ ᴛᴏ ᴀɴʏ ᴍᴇꜱꜱᴀɢᴇ ᴜꜱɪɴɢ ᴛʜᴇ ᴛᴀʀɢᴇᴛ ᴄʜᴀᴛ ɪᴅ. ꜰᴏʀ ᴇɢ: /send ᴜꜱᴇʀɪᴅ") + +@Client.on_message(filters.command("deletefiles") & filters.user(ADMINS)) +async def deletemultiplefiles(bot, message): + chat_type = message.chat.type + if chat_type != enums.ChatType.PRIVATE: + return await message.reply_text(f"Hey {message.from_user.mention}, This command won't work in groups. It only works on my PM !") + + try: + keyword = message.text.split(" ", 1)[1] + except Exception: + return await message.reply_text(f"Hey {message.from_user.mention}, Give me a keyword along with the command to delete files.") + k = await bot.send_message(chat_id=message.chat.id, text=f"Fetching Files for your query {keyword} on DB... Please wait...") + files, total = await get_bad_files(keyword) + total = len(files) + if total == 0: + await k.edit_text(f"No files found for your query {keyword} !") + await asyncio.sleep(DELETE_TIME) + await k.delete() + return + await k.delete() + btn = [[ + InlineKeyboardButton("⚠ Yes, Continue ! ⚠", callback_data=f"killfilesdq#{keyword}") + ],[ + InlineKeyboardButton("❌ No, Abort operation ! ❌", callback_data="close_data") + ]] + await message.reply_text( + text=f"Found {total} files for your query {keyword} !\n\nDo you want to delete?", + reply_markup=InlineKeyboardMarkup(btn), + parse_mode=enums.ParseMode.HTML + ) + + +@Client.on_callback_query(filters.regex("topsearch")) +async def topsearch_callback(client, callback_query): + def is_alphanumeric(string): + return bool(re.match('^[a-zA-Z0-9 ]*$', string)) + + limit = 20 + top_messages = await mdb.get_top_messages(limit) + seen_messages = set() + truncated_messages = [] + for msg in top_messages: + msg_lower = msg.lower() + if msg_lower not in seen_messages and is_alphanumeric(msg): + seen_messages.add(msg_lower) + if len(msg) > 35: + truncated_messages.append(msg[:32] + "...") + else: + truncated_messages.append(msg) + keyboard = [truncated_messages[i:i+2] for i in range(0, len(truncated_messages), 2)] + reply_markup = ReplyKeyboardMarkup( + keyboard, + one_time_keyboard=True, + resize_keyboard=True, + placeholder="Most searches of the day" + ) + await callback_query.message.reply_text( + "Tᴏᴘ Sᴇᴀʀᴄʜᴇs Oғ Tʜᴇ Dᴀʏ 👇", + reply_markup=reply_markup + ) + await callback_query.answer() + +@Client.on_message(filters.command('top_search')) +async def top(_, message): + def is_alphanumeric(string): + return bool(re.match('^[a-zA-Z0-9 ]*$', string)) + try: + limit = int(message.command[1]) + except (IndexError, ValueError): + limit = 20 + top_messages = await mdb.get_top_messages(limit) + seen_messages = set() + truncated_messages = [] + for msg in top_messages: + msg_lower = msg.lower() + if msg_lower not in seen_messages and is_alphanumeric(msg): + seen_messages.add(msg_lower) + if len(msg) > 35: + truncated_messages.append(msg[:32] + "...") + else: + truncated_messages.append(msg) + keyboard = [truncated_messages[i:i+2] for i in range(0, len(truncated_messages), 2)] + reply_markup = ReplyKeyboardMarkup( + keyboard, + one_time_keyboard=True, + resize_keyboard=True, + placeholder="Most searches of the day" + ) + await message.reply_text( + "Tᴏᴘ Sᴇᴀʀᴄʜᴇs Oғ Tʜᴇ Dᴀʏ 👇", + reply_markup=reply_markup + ) + +@Client.on_message(filters.command('trendlist')) +async def trendlist(client, message): + def is_alphanumeric(string): + return bool(re.match('^[a-zA-Z0-9 ]*$', string)) + limit = 31 + if len(message.command) > 1: + try: + limit = int(message.command[1]) + except ValueError: + await message.reply_text( + "Invalid number format.\nPlease provide a valid number after the /trendlist command." + ) + return + try: + top_messages = await mdb.get_top_messages(limit) + except Exception as e: + await message.reply_text(f"Error retrieving messages: {str(e)}") + return + + if not top_messages: + await message.reply_text("No top messages found.") + return + seen_messages = set() + truncated_messages = [] + + for msg in top_messages: + msg_lower = msg.lower() + if msg_lower not in seen_messages and is_alphanumeric(msg): + seen_messages.add(msg_lower) + truncated_messages.append(msg[:32] + '...' if len(msg) > 35 else msg) + + if not truncated_messages: + await message.reply_text("No valid top messages found.") + return + formatted_list = "\n".join([f"{i+1}. {msg}" for i, msg in enumerate(truncated_messages)]) + additional_message = ( + "⚡ 𝑨𝒍𝒍 𝒕𝒉𝒆 𝒓𝒆𝒔𝒖𝒍𝒕𝒔 𝒂𝒃𝒐𝒗𝒆 𝒄𝒐𝒎𝒆 𝒇𝒓𝒐𝒎 𝒘𝒉𝒂𝒕 𝒖𝒔𝒆𝒓𝒔 𝒉𝒂𝒗𝒆 𝒔𝒆𝒂𝒓𝒄𝒉𝒆𝒅 𝒇𝒐𝒓. " + "𝑻𝒉𝒆𝒚'𝒓𝒆 𝒔𝒉𝒐𝒘𝒏 𝒕𝒐 𝒚𝒐𝒖 𝒆𝒙𝒂𝒄𝒕𝒍𝒚 𝒂𝒔 𝒕𝒉𝒆𝒚 𝒘𝒆𝒓𝒆 𝒔𝒆𝒂𝒓𝒄𝒉𝒆𝒅, " + "𝒘𝒊𝒕𝒉𝒐𝒖𝒕 𝒂𝒏𝒚 𝒄𝒉𝒂𝒏𝒈𝒆𝒔 𝒃𝒚 𝒕𝒉𝒆 𝒐𝒘𝒏𝒆𝒓." + ) + formatted_list += f"\n\n{additional_message}" + reply_text = f"Top {len(truncated_messages)} Tʀᴀɴᴅɪɴɢ ᴏғ ᴛʜᴇ ᴅᴀʏ 👇:\n\n{formatted_list}" + await message.reply_text(reply_text) + +@Client.on_message(filters.private & filters.command("pm_search") & filters.user(ADMINS)) +async def set_pm_search(client, message): + bot_id = client.me.id + try: + option = message.text.split(" ", 1)[1].strip().lower() + enable_status = option in ['on', 'true'] + except (IndexError, ValueError): + await message.reply_text("💔 Invalid option. Please send 'on' or 'off' after the command..") + return + try: + await db.update_pm_search_status(bot_id, enable_status) + response_text = ( + " ᴘᴍ ꜱᴇᴀʀᴄʜ ᴇɴᴀʙʟᴇᴅ ✅" if enable_status + else " ᴘᴍ ꜱᴇᴀʀᴄʜ ᴅɪꜱᴀʙʟᴇᴅ ❌" + ) + await message.reply_text(response_text) + except Exception as e: + logger.error(f"Error in set_pm_search: {e}") + await message.reply_text(f"❗ An error occurred: {e}") + +@Client.on_message(filters.private & filters.command("movie_update") & filters.user(ADMINS)) +async def set_movie_update_notification(client, message): + bot_id = client.me.id + try: + option = message.text.split(" ", 1)[1].strip().lower() + enable_status = option in ['on', 'true'] + except (IndexError, ValueError): + await message.reply_text("💔 Invalid option. Please send 'on' or 'off' after the command.") + return + try: + await db.update_movie_update_status(bot_id, enable_status) + response_text = ( + "ᴍᴏᴠɪᴇ ᴜᴘᴅᴀᴛᴇ ɴᴏᴛɪꜰɪᴄᴀᴛɪᴏɴ ᴇɴᴀʙʟᴇᴅ ✅" if enable_status + else "ᴍᴏᴠɪᴇ ᴜᴘᴅᴀᴛᴇ ɴᴏᴛɪꜰɪᴄᴀᴛɪᴏɴ ᴅɪꜱᴀʙʟᴇᴅ ❌" + ) + await message.reply_text(response_text) + except Exception as e: + logger.error(f"Error in set_movie_update_notification: {e}") + await message.reply_text(f"❗ An error occurred: {e}") + +@Client.on_message(filters.command("restart") & filters.user(ADMINS)) +async def stop_button(bot, message): + msg = await bot.send_message(text="ʙᴏᴛ ɪꜱ ʀᴇꜱᴛᴀʀᴛɪɴɢ", chat_id=message.chat.id) + await asyncio.sleep(3) + await msg.edit("ʙᴏᴛ ɪꜱ ʀᴇꜱᴛᴀʀᴛᴇᴅ ✅") + os.execl(sys.executable, sys.executable, *sys.argv) + +@Client.on_message(filters.command("del_msg") & filters.user(ADMINS)) +async def del_msg(client, message): + confirm_markup = InlineKeyboardMarkup([[ + InlineKeyboardButton("Yes", callback_data="confirm_del_yes"), + InlineKeyboardButton("No", callback_data="confirm_del_no") + ]]) + sent_message = await message.reply_text( + "⚠ Aʀᴇ ʏᴏᴜ sᴜʀᴇ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʟᴇᴀʀ ᴛʜᴇ ᴜᴘᴅᴀᴛᴇs ᴄʜᴀɴɴᴇʟ ʟɪsᴛ ?\n\n ᴅᴏ ʏᴏᴜ ꜱᴛɪʟʟ ᴡᴀɴᴛ ᴛᴏ ᴄᴏɴᴛɪɴᴜᴇ ?", + reply_markup=confirm_markup + ) + await asyncio.sleep(60) + try: + await sent_message.delete() + except Exception as e: + logger.error("Error deleting the message: %s", e) + +@Client.on_callback_query(filters.regex('^confirm_del_')) +async def confirmation_handler(client, callback_query): + action = callback_query.data.split("_")[-1] + if action == "yes": + await db.delete_all_msg() + await callback_query.message.edit_text('🧹 ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ ʟɪsᴛ ʜᴀs ʙᴇᴇɴ ᴄʟᴇᴀʀᴇᴅ sᴜᴄᴄᴇssғᴜʟʟʏ ✅') + elif action == "no": + await callback_query.message.delete() + await callback_query.answer() + +@Client.on_message(filters.command('set_caption')) +async def save_caption(client, message): + grp_id = message.chat.id + title = message.chat.title + invite_link = await client.export_chat_invite_link(grp_id) + if not await is_check_admin(client, grp_id, message.from_user.id): + return await message.reply_text(script.NT_ADMIN_ALRT_TXT) + chat_type = message.chat.type + if chat_type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: + return await message.reply_text("ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ɪɴ ɢʀᴏᴜᴘ...") + try: + caption = message.text.split(" ", 1)[1] + except Exception: + return await message.reply_text("ɢɪᴠᴇ ᴍᴇ ᴀ ᴄᴀᴘᴛɪᴏɴ ᴀʟᴏɴɢ ᴡɪᴛʜ ɪᴛ.\n\nᴇxᴀᴍᴘʟᴇ -\n\nꜰᴏʀ ꜰɪʟᴇ ɴᴀᴍᴇ ꜱᴇɴᴅ {file_name}\nꜰᴏʀ ꜰɪʟᴇ ꜱɪᴢᴇ ꜱᴇɴᴅ {file_size}\n\n/set_caption {file_name}") + await save_group_settings(grp_id, 'caption', caption) + await message.reply_text(f"ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴄʜᴀɴɢᴇᴅ ᴄᴀᴘᴛɪᴏɴ ꜰᴏʀ {title}\n\nᴄᴀᴘᴛɪᴏɴ - {caption}", link_preview_options=LinkPreviewOptions(is_disabled=True)) + await client.send_message(LOG_CHANNEL, f"#Set_Caption\n\nɢʀᴏᴜᴘ ɴᴀᴍᴇ : {title}\n\nɢʀᴏᴜᴘ ɪᴅ: {grp_id}\nɪɴᴠɪᴛᴇ ʟɪɴᴋ : {invite_link}\n\nᴜᴘᴅᴀᴛᴇᴅ ʙʏ : {message.from_user.username}") + + +@Client.on_message(filters.command(["set_tutorial", "set_tutorial_2", "set_tutorial_3"])) +async def set_tutorial(client, message: Message): + grp_id = message.chat.id + title = message.chat.title + chat_type = message.chat.type + if chat_type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: + return await message.reply_text( + f"ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ɪɴ ɢʀᴏᴜᴘ...\n\nGroup Name: {title}\nGroup ID: {grp_id}" + ) + if not await is_check_admin(client, grp_id, message.from_user.id): + return await message.reply_text(script.NT_ADMIN_ALRT_TXT) + + try: + tutorial_link = message.text.split(" ", 1)[1] + except IndexError: + return await message.reply_text( + f"ᴄᴏᴍᴍᴀɴᴅ ɪɴᴄᴏᴍᴘʟᴇᴛᴇ !!\n\nᴜꜱᴇ ʟɪᴋᴇ ᴛʜɪꜱ -\n\n" + f"/{message.command[0]} https://t.me/dreamxbotz" + ) + if message.command[0] == "set_tutorial": + tutorial_key = "tutorial" + else: + tutorial_key = f"tutorial_{message.command[0].split('_', 2)[2]}" + + await save_group_settings(grp_id, tutorial_key, tutorial_link) + invite_link = await client.export_chat_invite_link(grp_id) + await message.reply_text( + f"ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴄʜᴀɴɢᴇᴅ {tutorial_key.replace('_', ' ').title()} ꜰᴏʀ {title}\n\n" + f"ʟɪɴᴋ - {tutorial_link}", + link_preview_options=LinkPreviewOptions(is_disabled=True) + ) + await client.send_message( + LOG_CHANNEL, + f"#Set_{tutorial_key.title()}_Video\n\n" + f"ɢʀᴏᴜᴘ ɴᴀᴍᴇ : {title}\n" + f"ɢʀᴏᴜᴘ ɪᴅ : {grp_id}\n" + f"ɪɴᴠɪᴛᴇ ʟɪɴᴋ : {invite_link}\n" + f"ᴜᴘᴅᴀᴛᴇᴅ ʙʏ : {message.from_user.mention()}" + ) + + +async def handle_shortner_command(c, m, shortner_key, api_key, log_prefix, fallback_url, fallback_api): + grp_id = m.chat.id + if not await is_check_admin(c, grp_id, m.from_user.id): + return await m.reply_text(script.NT_ADMIN_ALRT_TXT) + if len(m.command) != 3: + return await m.reply( + f"ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ʟɪᴋᴇ -\n\n`/{m.command[0]} your-shortener-domain.com your_api_key_here`" + ) + sts = await m.reply("♻ ᴄʜᴇᴄᴋɪɴɢ...") + await asyncio.sleep(1.2) + await sts.delete() + if m.chat.type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: + return await m.reply_text("ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ɪɴ ɢʀᴏᴜᴘ...") + custom_flag = 'custom_shortner' if shortner_key == 'shortner' else f'custom_{shortner_key}' + try: + URL = m.command[1] + API = m.command[2] + await save_group_settings(grp_id, shortner_key, URL) + await save_group_settings(grp_id, api_key, API) + await save_group_settings(grp_id, custom_flag, True) + await m.reply_text(f"✅ sʜᴏʀᴛɴᴇʀ ᴀᴅᴅᴇᴅ\n\nꜱɪᴛᴇ - `{URL}`\nᴀᴘɪ - `{API}`") + user_id = m.from_user.id + user_info = f"@{m.from_user.username}" if m.from_user.username else f"{m.from_user.mention}" + link = (await c.get_chat(m.chat.id)).invite_link + grp_link = f"[{m.chat.title}]({link})" + log_message = ( + f"#{log_prefix}\n\nɴᴀᴍᴇ - {user_info}\n\nɪᴅ - `{user_id}`" + f"\n\nꜱɪᴛᴇ - {URL}\n\nᴀᴘɪ - `{API}`" + f"\n\nɢʀᴏᴜᴘ - {grp_link}\nɢʀᴏᴜᴘ ɪᴅ - `{grp_id}`" + ) + await c.send_message(LOG_CHANNEL, log_message, link_preview_options=LinkPreviewOptions(is_disabled=True)) + except Exception as e: + await save_group_settings(grp_id, shortner_key, fallback_url) + await save_group_settings(grp_id, api_key, fallback_api) + await save_group_settings(grp_id, custom_flag, False) + await m.reply_text( + f"💢 ᴇʀʀᴏʀ ᴏᴄᴄᴜʀᴇᴅ!\n\n" + f"ᴅᴇꜰᴀᴜʟᴛ ꜱʜᴏʀᴛɴᴇʀ ᴀᴘᴘʟɪᴇᴅ\n" + f"ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʜᴀɴɢᴇ ᴛʀʏ ᴀ ᴠᴀʟɪᴅ ꜱɪᴛᴇ ᴀɴᴅ ᴀᴘɪ ᴋᴇʏ.\n\n" + f"ʟɪᴋᴇ:\n\n`/{m.command[0]} your-shortener-domain.com your_api_key_here`\n\n" + f"💔 ᴇʀʀᴏʀ - {e}" + ) + +@Client.on_message(filters.command('set_shortner')) +async def set_shortner(c, m): + await handle_shortner_command(c, m, 'shortner', 'api', 'New_Shortner_Set_For_1st_Verify', SHORTENER_WEBSITE, SHORTENER_API) + +@Client.on_message(filters.command('set_shortner_2')) +async def set_shortner_2(c, m): + await handle_shortner_command(c, m, 'shortner_two', 'api_two', 'New_Shortner_Set_For_2nd_Verify', SHORTENER_WEBSITE2, SHORTENER_API2) + +@Client.on_message(filters.command('set_shortner_3')) +async def set_shortner_3(c, m): + await handle_shortner_command(c, m, 'shortner_three', 'api_three', 'New_Shortner_Set_For_3rd_Verify', SHORTENER_WEBSITE3, SHORTENER_API3) + +@Client.on_message(filters.command('set_log_channel')) +async def set_log(client, message): + grp_id = message.chat.id + title = message.chat.title + if not await is_check_admin(client, grp_id, message.from_user.id): + return await message.reply_text(script.NT_ADMIN_ALRT_TXT) + if len(message.text.split()) == 1: + await message.reply("ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ʟɪᴋᴇ ᴛʜɪꜱ - \n\n`/set_log_channel -100******`") + return + sts = await message.reply("♻ ᴄʜᴇᴄᴋɪɴɢ...") + await asyncio.sleep(1.2) + await sts.delete() + chat_type = message.chat.type + if chat_type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: + return await message.reply_text("ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ɪɴ ɢʀᴏᴜᴘ...") + try: + log = int(message.text.split(" ", 1)[1]) + except IndexError: + return await message.reply_text("ɪɴᴠᴀɪʟᴅ ꜰᴏʀᴍᴀᴛ!!\n\nᴜsᴇ ʟɪᴋᴇ ᴛʜɪs - `/set_log_channel -100xxxxxxxx`") + except ValueError: + return await message.reply_text('ᴍᴀᴋᴇ sᴜʀᴇ ɪᴅ ɪs ɪɴᴛᴇɢᴇʀ...') + try: + t = await client.send_message(chat_id=log, text="ʜᴇʏ ᴡʜᴀᴛ's ᴜᴘ!!") + await asyncio.sleep(3) + await t.delete() + except Exception as e: + return await message.reply_text(f'😐 ᴍᴀᴋᴇ sᴜʀᴇ ᴛʜɪs ʙᴏᴛ ᴀᴅᴍɪɴ ɪɴ ᴛʜᴀᴛ ᴄʜᴀɴɴᴇʟ...\n\n💔 ᴇʀʀᴏʀ - {e}') + await save_group_settings(grp_id, 'log', log) + await message.reply_text(f"✅ sᴜᴄᴄᴇssꜰᴜʟʟʏ sᴇᴛ ʏᴏᴜʀ ʟᴏɢ ᴄʜᴀɴɴᴇʟ ꜰᴏʀ {title}\n\nɪᴅ - `{log}`", link_preview_options=LinkPreviewOptions(is_disabled=True)) + user_id = message.from_user.id + user_info = f"@{message.from_user.username}" if message.from_user.username else f"{message.from_user.mention}" + link = (await client.get_chat(message.chat.id)).invite_link + grp_link = f"[{message.chat.title}]({link})" + log_message = f"#New_Log_Channel_Set\n\nɴᴀᴍᴇ - {user_info}\n\nɪᴅ - `{user_id}`\n\nʟᴏɢ ᴄʜᴀɴɴᴇʟ ɪᴅ - `{log}`\nɢʀᴏᴜᴘ ʟɪɴᴋ - `{grp_link}`\n\nɢʀᴏᴜᴘ ɪᴅ : `{grp_id}`" + await client.send_message(LOG_CHANNEL, log_message, link_preview_options=LinkPreviewOptions(is_disabled=True)) + + +@Client.on_message(filters.command('set_time')) +async def set_time(client, message): + chat_type = message.chat.type + if chat_type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: + return await message.reply_text("ᴜsᴇ ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ ɪɴ ɢʀᴏᴜᴘ...") + grp_id = message.chat.id + title = message.chat.title + invite_link = await client.export_chat_invite_link(grp_id) + if not await is_check_admin(client, grp_id, message.from_user.id): + return await message.reply_text(script.NT_ADMIN_ALRT_TXT) + try: + time = int(message.text.split(" ", 1)[1]) + except Exception: + return await message.reply_text("ᴄᴏᴍᴍᴀɴᴅ ɪɴᴄᴏᴍᴘʟᴇᴛᴇ\n\nᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ʟɪᴋᴇ ᴛʜɪꜱ - /set_time 600 [ ᴛɪᴍᴇ ᴍᴜꜱᴛ ʙᴇ ɪɴ ꜱᴇᴄᴏɴᴅꜱ ]") + await save_group_settings(grp_id, 'verify_time', time) + await message.reply_text(f"✅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ꜱᴇᴛ 2ɴᴅ ᴠᴇʀɪꜰʏ ᴛɪᴍᴇ ꜰᴏʀ {title}\n\nᴛɪᴍᴇ - {time}") + await client.send_message(LOG_CHANNEL, f"#Set_2nd_Verify_Time\n\nɢʀᴏᴜᴘ ɴᴀᴍᴇ : {title}\n\nɢʀᴏᴜᴘ ɪᴅ : {grp_id}\n\nɪɴᴠɪᴛᴇ ʟɪɴᴋ : {invite_link}\n\nᴜᴘᴅᴀᴛᴇᴅ ʙʏ : {message.from_user.username}") +@Client.on_message(filters.command('set_time_2')) +async def set_time_2(client, message): + chat_type = message.chat.type + if chat_type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: + return await message.reply_text("ᴜsᴇ ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ ɪɴ ɢʀᴏᴜᴘ...") + grp_id = message.chat.id + title = message.chat.title + invite_link = await client.export_chat_invite_link(grp_id) + if not await is_check_admin(client, grp_id, message.from_user.id): + return await message.reply_text(script.NT_ADMIN_ALRT_TXT) + try: + time = int(message.text.split(" ", 1)[1]) + except Exception: + return await message.reply_text("ᴄᴏᴍᴍᴀɴᴅ ɪɴᴄᴏᴍᴘʟᴇᴛᴇ\n\nᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ʟɪᴋᴇ ᴛʜɪꜱ - /set_time 3600 [ ᴛɪᴍᴇ ᴍᴜꜱᴛ ʙᴇ ɪɴ ꜱᴇᴄᴏɴᴅꜱ ]") + await save_group_settings(grp_id, 'third_verify_time', time) + await message.reply_text(f"✅ ꜱᴜᴄᴄESꜱꜰᴜʟʟʏ ꜱᴇᴛ 3ʀᴅ ᴠᴇʀɪꜰʏ ᴛɪᴍᴇ ꜰᴏʀ {title}\n\nᴛɪᴍᴇ - {time}") + await client.send_message(LOG_CHANNEL, f"#Set_3rd_Verify_Time\n\nɢʀᴏᴜᴘ ɴᴀᴍᴇ : {title}\n\nɢʀᴏᴜᴘ ɪᴅ : {grp_id}\n\nɪɴᴠɪᴛᴇ ʟɪɴᴋ : {invite_link}\n\nᴜᴘᴅᴀᴛᴇᴅ ʙʏ : {message.from_user.username}") + + +@Client.on_message(filters.command('details')) +async def all_settings(client, message): + if message.chat.type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: + return await message.reply_text("ᴜsᴇ ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ ɪɴ ɢʀᴏᴜᴘ...") + grp_id = message.chat.id + title = message.chat.title + if not await is_check_admin(client, grp_id, message.from_user.id): + return await message.reply_text(script.NT_ADMIN_ALRT_TXT) + try: + settings = await get_settings(grp_id) + except Exception as e: + return await message.reply_text(f"⚠ ᴇʀʀᴏʀ ꜰᴇᴛᴄʜɪɴɢ ꜱᴇᴛᴛɪɴɢꜱ:\n{e}") + text = generate_settings_text(settings, title) + btn = [ + [InlineKeyboardButton("♻ ʀᴇꜱᴇᴛ ꜱᴇᴛᴛɪɴɢꜱ", callback_data=f"reset_group_{grp_id}")], + [InlineKeyboardButton("🚫 ᴄʟᴏꜱᴇ", callback_data="close_data")] + ] + dlt = await message.reply_text(text, reply_markup=InlineKeyboardMarkup(btn), link_preview_options=LinkPreviewOptions(is_disabled=True)) + await asyncio.sleep(300) + await dlt.delete() + +@Client.on_callback_query(filters.regex(r"^reset_group_(\-\d+)$")) +async def reset_group_callback(client, callback_query): + grp_id = int(callback_query.matches[0].group(1)) + user_id = callback_query.from_user.id + if not await is_check_admin(client, grp_id, user_id): + return await callback_query.answer(script.NT_ADMIN_ALRT_TXT, show_alert=True) + await callback_query.answer("♻ ʀᴇꜱᴇᴛᴛɪɴɢ ꜱᴇᴛᴛɪɴɢꜱ...") + defaults = { + 'shortner': SHORTENER_WEBSITE, + 'api': SHORTENER_API, + 'shortner_two': SHORTENER_WEBSITE2, + 'api_two': SHORTENER_API2, + 'shortner_three': SHORTENER_WEBSITE3, + 'api_three': SHORTENER_API3, + 'custom_shortner': False, + 'custom_shortner_two': False, + 'custom_shortner_three': False, + 'verify_time': TWO_VERIFY_GAP, + 'third_verify_time': THREE_VERIFY_GAP, + 'template': IMDB_TEMPLATE, + 'tutorial': TUTORIAL, + 'tutorial_2': TUTORIAL_2, + 'tutorial_3': TUTORIAL_3, + 'caption': CUSTOM_FILE_CAPTION, + 'log': LOG_CHANNEL, + 'is_verify': IS_VERIFY, + 'fsub': AUTH_CHANNELS + } + current = await get_settings(grp_id) + if current == defaults: + return await callback_query.answer("✅ ꜱᴇᴛᴛɪɴɢꜱ ᴀʟʀᴇᴀᴅʏ ᴅᴇꜰᴀᴜʟᴛ.", show_alert=True) + for key, value in defaults.items(): + await save_group_settings(grp_id, key, value) + updated = await get_settings(grp_id) + title = callback_query.message.chat.title + text = generate_settings_text(updated, title, reset_done=True) + buttons = [ + [InlineKeyboardButton("♻ ʀᴇꜱᴇᴛ ꜱᴇᴛᴛɪɴɢꜱ", callback_data=f"reset_group_{grp_id}")], + [InlineKeyboardButton("🚫 ᴄʟᴏꜱᴇ", callback_data="close_data")] + ] + await callback_query.message.edit_text(text, reply_markup=InlineKeyboardMarkup(buttons), link_preview_options=LinkPreviewOptions(is_disabled=True)) + +@Client.on_message(filters.command("verify") & filters.user(ADMINS)) +async def verify(bot, message): + try: + chat_type = message.chat.type + if chat_type == enums.ChatType.PRIVATE: + return await message.reply_text("ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ ᴡᴏʀᴋs ᴏɴʟʏ ɪɴ ɢʀᴏᴜᴘs!") + if chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: + grpid = message.chat.id + command_text = message.text.split(' ')[1] if len(message.text.split(' ')) > 1 else None + if command_text == "off": + await save_group_settings(grpid, 'is_verify', False) + return await message.reply_text("✓ ᴠᴇʀɪꜰʏ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅɪsᴀʙʟᴇᴅ.") + elif command_text == "on": + await save_group_settings(grpid, 'is_verify', True) + return await message.reply_text("✗ ᴠᴇʀɪꜰʏ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴇɴᴀʙʟᴇᴅ.") + else: + return await message.reply_text("ʜɪ, ᴛᴏ ᴇɴᴀʙʟᴇ ᴠᴇʀɪꜰʏ, ᴜsᴇ /verify on ᴀɴᴅ ᴛᴏ ᴅɪsᴀʙʟᴇ ᴠᴇʀɪꜰʏ, ᴜsᴇ /verify off.") + except Exception as e: + logger.error("Error: %s", e) + await message.reply_text(f"Error: {e}") + +@Client.on_message(filters.command('set_fsub')) +async def set_fsub(client, message): + try: + userid = message.from_user.id if message.from_user else None + if not userid: + return await message.reply("You are Anonymous admin you can't use this command !") + if message.chat.type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: + return await message.reply_text("ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ ᴄᴀɴ ᴏɴʟʏ ʙᴇ ᴜsᴇᴅ ɪɴ ɢʀᴏᴜᴘs") + grp_id = message.chat.id + title = message.chat.title + if not await is_check_admin(client, grp_id, userid): + return await message.reply_text(script.NT_ADMIN_ALRT_TXT) + args = message.text.split(maxsplit=1) + if len(args) < 2: + return await message.reply_text( + "ᴄᴏᴍᴍᴀɴᴅ ɪɴᴄᴏᴍᴘʟᴇᴛᴇ!\n\n" + "ᴄᴀɴ ᴀᴅᴅ ᴍᴜʟᴛɪᴘʟᴇ ᴄʜᴀɴɴᴇʟs sᴇᴘᴀʀᴀᴛᴇᴅ ʙʏ sᴘᴀᴄᴇs. ʟɪᴋᴇ: /sᴇᴛ_ғsᴜʙ ɪᴅ1 ɪᴅ2 ɪᴅ3\n" + ) + option = args[1].strip() + try: + fsub_ids = [int(x) for x in option.split()] + except ValueError: + return await message.reply_text('ᴍᴀᴋᴇ sᴜʀᴇ ᴀʟʟ ɪᴅs ᴀʀᴇ ɪɴᴛᴇɢᴇʀs.') + if len(fsub_ids) > 5: + return await message.reply_text("ᴍᴀxɪᴍᴜᴍ 5 ᴄʜᴀɴɴᴇʟs ᴀʟʟᴏᴡᴇᴅ.") + channels = "ᴄʜᴀɴɴᴇʟs:\n" + channel_titles = [] + for id in fsub_ids: + try: + chat = await client.get_chat(id) + except Exception as e: + return await message.reply_text( + f"{id} ɪs ɪɴᴠᴀʟɪᴅ!\nᴍᴀᴋᴇ sᴜʀᴇ ᴛʜɪs ʙᴏᴛ ɪs ᴀᴅᴍɪɴ ɪɴ ᴛʜᴀᴛ ᴄʜᴀɴɴᴇʟ.\n\nError - {e}" + ) + if chat.type != enums.ChatType.CHANNEL: + return await message.reply_text(f"{id} ɪs ɴᴏᴛ ᴀ ᴄʜᴀɴɴᴇʟ.") + channel_titles.append(f"{chat.title} (`{id}`)") + channels += f'{chat.title}\n' + await save_group_settings(grp_id, 'fsub', fsub_ids) + await message.reply_text(f"sᴜᴄᴄᴇssғᴜʟʟʏ sᴇᴛ ꜰꜱᴜʙ ᴄʜᴀɴɴᴇʟ(ꜱ) ғᴏʀ {title} ᴛᴏ\n\n{channels}") + mention = message.from_user.mention if message.from_user else "Unknown" + await client.send_message( + LOG_CHANNEL, + f"#Fsub_Channel_set\n\n" + f"ᴜꜱᴇʀ - {mention} ꜱᴇᴛ ᴛʜᴇ ꜰᴏʀᴄᴇ ᴄʜᴀɴɴᴇʟ(ꜱ) ꜰᴏʀ {title}:\n\n" + f"ꜰꜱᴜʙ ᴄʜᴀɴɴᴇʟ(ꜱ):\n" + '\n'.join(channel_titles) + ) + except Exception as e: + err_text = f"⚠ Error in set_fSub :\n{e}" + logger.error(err_text) + await client.send_message(LOG_CHANNEL, err_text) + +@Client.on_message(filters.private & filters.command("resetallgroup") & filters.user(ADMINS)) +async def reset_all_settings(client, message): + try: + reset_count = await db.dreamx_reset_settings() + await message.reply_text( + f"ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ꜱᴇᴛᴛɪɴɢꜱ ꜰᴏʀ {reset_count} ɢʀᴏᴜᴘꜱ. ᴅᴇꜰᴀᴜʟᴛ ᴠᴀʟᴜᴇꜱ ᴡɪʟʟ ʙᴇ ᴜꜱᴇᴅ ✅" + ) + except Exception as e: + logger.error("reset_all_settings: %s", e) + await message.reply_text( + "🚫 An error occurred while resetting group settings.\nPlease try again later." + ) + +@Client.on_message(filters.command("trial_reset")) +async def reset_trial(client, message): + user_id = message.from_user.id + if user_id not in ADMINS: + await message.reply("ʏᴏᴜ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ ᴀɴʏ ᴘᴇʀᴍɪꜱꜱɪᴏɴ ᴛᴏ ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ.") + return + try: + if len(message.command) > 1: + target_user_id = int(message.command[1]) + updated_count = await db.reset_free_trial(target_user_id) + message_text = f"ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ʀᴇꜱᴇᴛ ꜰʀᴇᴇ ᴛʀᴀɪʟ ꜰᴏʀ ᴜꜱᴇʀꜱ {target_user_id}." if updated_count else f"ᴜꜱᴇʀ {target_user_id} ɴᴏᴛ ꜰᴏᴜɴᴅ ᴏʀ ᴅᴏɴ'ᴛ ᴄʟᴀɪᴍ ꜰʀᴇᴇ ᴛʀᴀɪʟ ʏᴇᴛ." + else: + updated_count = await db.reset_free_trial() + message_text = f"ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ʀᴇꜱᴇᴛ ꜰʀᴇᴇ ᴛʀᴀɪʟ ꜰᴏʀ {updated_count} ᴜꜱᴇʀꜱ." + await message.reply_text(message_text) + except Exception as e: + await message.reply_text(f"An error occurred: {e}") + + +@Client.on_message(filters.command('remove_fsub')) +async def remove_fsub(client, message): + try: + user = message.from_user + if not user: + return await message.reply("ʏᴏᴜ ᴀʀᴇ ᴀɴᴏɴʏᴍᴏᴜs ᴀᴅᴍɪɴ — ʏᴏᴜ ᴄᴀɴ'ᴛ ᴜsᴇ ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ!") + if message.chat.type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: + return await message.reply_text("ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ ᴄᴀɴ ᴏɴʟʏ ʙᴇ ᴜsᴇᴅ ɪɴ ɢʀᴏᴜᴘs.") + grp_id = message.chat.id + title = message.chat.title + if not await is_check_admin(client, grp_id, user.id): + return await message.reply_text(script.NT_ADMIN_ALRT_TXT) + args = message.text.split(maxsplit=1) + if len(args) < 2: + return await message.reply_text( + "ᴜsᴀɢᴇ:\n" + "• /remove_fsub ᴀʟʟ → ʀᴇᴍᴏᴠᴇ ᴀʟʟ ғsᴜʙ ᴄʜᴀɴɴᴇʟs\n" + "• /remove_fsub ɪᴅ1 ɪᴅ2 ... → ʀᴇᴍᴏᴠᴇ sᴘᴇᴄɪғɪᴄ ᴄʜᴀɴɴᴇʟ ɪᴅs" + ) + option = args[1].strip() + settings = await get_settings(grp_id) + cr_fsubs = settings.get("fsub", []) if settings else [] + if not cr_fsubs: + return await message.reply_text("ɴᴏ ғsᴜʙ ᴄʜᴀɴɴᴇʟs ᴀʀᴇ sᴇᴛ ғᴏʀ ᴛʜɪs ɢʀᴏᴜᴘ.") + if option.lower() == "all": + await save_group_settings(grp_id, 'fsub', []) + await message.reply_text(f"✅ ᴀʟʟ ғsᴜʙ ᴄʜᴀɴɴᴇʟs ʀᴇᴍᴏᴠᴇᴅ ғᴏʀ {title}") + return await client.send_message( + LOG_CHANNEL, + f"#ғsᴜʙ_ʀᴇᴍᴏᴠᴇᴅ\n\n👤 {user.mention} ʀᴇᴍᴏᴠᴇᴅ ᴀʟʟ ғsᴜʙ ᴄʜᴀɴɴᴇʟs ғᴏʀ {title}." + ) + try: + remove_ids = [int(x) for x in option.split()] + except ValueError: + return await message.reply_text("ᴍᴀᴋᴇ sᴜʀᴇ ᴀʟʟ ɪᴅs ᴀʀᴇ ᴠᴀʟɪᴅ ɪɴᴛᴇɢᴇʀs.") + + new_fsubs = [cid for cid in cr_fsubs if cid not in remove_ids] + r_id = [cid for cid in cr_fsubs if cid in remove_ids] + if not r_id: + return await message.reply_text("ɴᴏɴᴇ ᴏғ ᴛʜᴇ ɢɪᴠᴇɴ ɪᴅs ᴡᴇʀᴇ ғᴏᴜɴᴅ ɪɴ ᴛʜᴇ ᴄᴜʀʀᴇɴᴛ ғsᴜʙ ʟɪsᴛ.") + await save_group_settings(grp_id, 'fsub', new_fsubs) + r_t = [] + for cid in r_id: + try: + chat = await client.get_chat(cid) + r_t.append(f"• {chat.title} ({cid})") + except Exception: + r_t.append(f"• ᴜɴᴋɴᴏᴡɴ ({cid})") + + await message.reply_text( + f"✅ ʀᴇᴍᴏᴠᴇᴅ {len(r_id)} ғsᴜʙ ᴄʜᴀɴɴᴇʟ(s) ғʀᴏᴍ {title}:\n" + + "\n".join(r_t) + ) + await client.send_message( + LOG_CHANNEL, + f"#ғsᴜʙ_ᴄʜᴀɴɴᴇʟ_ʀᴇᴍᴏᴠᴇᴅ\n\n👤 {user.mention} ʀᴇᴍᴏᴠᴇᴅ ғsᴜʙ ᴄʜᴀɴɴᴇʟ(s) ғʀᴏᴍ {title}:\n" + + "\n".join(r_t) + ) + except Exception as e: + logger.error("remove_fsub: %s", e) + await message.reply_text(f"⚠ ᴀɴ ᴇʀʀᴏʀ ᴏᴄᴄᴜʀʀᴇᴅ: {e}") + +@Client.on_message(filters.command('clean_groups') & filters.user(ADMINS)) +async def clean_groups_handler(client, message): + msg = await message.reply('Cleaning groups... This may take a while.') + deleted_count = 0 + total_groups = await db.total_chat_count() + processed = 0 + batch_size = 100 + chats = await db.get_all_chats() + async for chat in chats: + try: + processed += 1 + chat_id = chat['id'] + try: + await client.get_chat_member(chat_id, client.me.id) + except FloodWait as e: + await asyncio.sleep(e.value) + try: + await client.get_chat_member(chat_id, client.me.id) + except (UserNotParticipant, PeerIdInvalid, ChannelInvalid): + await db.delete_chat(chat_id) + deleted_count += 1 + except Exception: + pass + except (UserNotParticipant, PeerIdInvalid, ChannelInvalid): + await db.delete_chat(chat_id) + deleted_count += 1 + except Exception as e: + logger.error("Error checking chat %s: %s", chat_id, e) + pass + if processed % batch_size == 0: + try: + await msg.edit(f'Progress: {processed}/{total_groups}\nDeleted: {deleted_count}') + await asyncio.sleep(2) + except FloodWait as e: + await asyncio.sleep(e.value) + await msg.edit(f'Progress: {processed}/{total_groups}\nDeleted: {deleted_count}') + except Exception as e: + logger.error("Error in clean_groups loop: %s", e) + await msg.edit(f'**Clean Groups Complete**\n\nTotal Processed: {processed}\nDeleted: {deleted_count}') From 1d95b80b2aa230fc4b7b74365667d31b52adbc8c Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Mon, 14 Sep 2026 22:07:15 +0530 Subject: [PATCH 29/77] Update commands.py --- plugins/commands.py | 160 +++++--------------------------------------- 1 file changed, 16 insertions(+), 144 deletions(-) diff --git a/plugins/commands.py b/plugins/commands.py index e9163d79..0390712e 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -61,143 +61,36 @@ async def start(client, message): current_time = datetime.now(tz=ist_timezone) await db.update_notcopy_user(user_id, {key:current_time}) await db.update_verify_id_info(user_id, verify_id, {"verified":True}) - if key == "third_time_verified": num = 3 - msg = script.THIRDT_VERIFY_COMPLETE_TEXT else: num = 2 if key == "second_time_verified" else 1 + if key == "third_time_verified": + msg = script.THIRDT_VERIFY_COMPLETE_TEXT + else: msg = script.SECOND_VERIFY_COMPLETE_TEXT if key == "second_time_verified" else script.VERIFY_COMPLETE_TEXT - log_channel = settings.get('log') if settings and settings.get('log') else LOG_CHANNEL - try: - await client.send_message(log_channel, script.VERIFIED_LOG_TEXT.format(m.from_user.mention, user_id, datetime.now(pytz.timezone('Asia/Kolkata')).strftime('%d %B %Y'), num)) - except Exception as e: - logger.error(f"Failed to log verification: {e}") + await client.send_message(settings['log'], script.VERIFIED_LOG_TEXT.format(m.from_user.mention, user_id, datetime.now(pytz.timezone('Asia/Kolkata')).strftime('%d %B %Y'), num)) - is_sendall = m.command[1].startswith('sendall') - if is_sendall: - verifiedfiles = f"https://telegram.me/{temp.U_NAME}?start=allfiles_{grp_id}_{file_id}" - else: - verifiedfiles = f"https://telegram.me/{temp.U_NAME}?start=file_{grp_id}_{file_id}" - - btn_complete = [[ - InlineKeyboardButton("🫶🏻 Cʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ɢᴇᴛ ғɪʟᴇ 🕊", url=verifiedfiles), - ]] - dlt = await m.reply_photo( - photo="https://i.ibb.co/1tDXygyb/image.webp", - caption=msg.format(m.from_user.mention), - reply_markup=InlineKeyboardMarkup(btn_complete), + dlt=await m.reply_photo( + photo=(VERIFY_IMG), + caption=msg.format(message.from_user.mention, get_readable_time(TWO_VERIFY_GAP)), parse_mode=enums.ParseMode.HTML ) - + async def _delete_msg(msg_to_delete, delay): await asyncio.sleep(delay) try: await msg_to_delete.delete() except Exception: pass - asyncio.create_task(_delete_msg(dlt, 300)) - - # Send files automatically - is_sendall = m.command[1].startswith('sendall') - decoded_file_id = file_id - if not is_sendall: - try: - raw = base64.urlsafe_b64decode(file_id + "=" * (-len(file_id) % 4)) - sep = raw.find(b"_") - if sep != -1: - decoded_file_id = raw[sep + 1:].decode("latin1") - except Exception: - pass - - filesarr = [] - if is_sendall: - files = temp.GETALL.get(file_id) - if not files: - await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ !') - return - for file in files: - file_id_item = file.file_id - files_ = await get_file_details(file_id_item) - if not files_: - continue - files1 = files_[0] - title = clean_filename(files1.file_name) - cover = files1.cover - size = get_size(files1.file_size) - f_caption = files1.caption - - DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION if settings else CUSTOM_FILE_CAPTION - if DREAMX_CAPTION: - try: - f_caption = DREAMX_CAPTION.format(file_name='' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) - except Exception as e: - logger.exception(e) - - if f_caption is None: - f_caption = f"{clean_filename(files1.file_name)}" - - sent_msg = await client.send_cached_media( - chat_id=message.from_user.id, - cover=cover, - file_id=file_id_item, - caption=f_caption, - protect_content=settings.get('file_secure', PROTECT_CONTENT) if settings else PROTECT_CONTENT if settings else PROTECT_CONTENT - ) - filesarr.append(sent_msg) + if message.command[1].startswith('sendall'): + message.command[1] = f"allfiles_{grp_id}_{file_id}" else: - files_ = await get_file_details(decoded_file_id) - if not files_: - await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ !') - return - files1 = files_[0] - title = clean_filename(files1.file_name) - size = get_size(files1.file_size) - cover = files1.cover if files1.cover else None - f_caption = files1.caption - - DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION - if DREAMX_CAPTION: - try: - f_caption = DREAMX_CAPTION.format(file_name='' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) - except Exception as e: - logger.exception(e) - - if f_caption is None: - f_caption = clean_filename(files1.file_name) - - sent_msg = await client.send_cached_media( - chat_id=message.from_user.id, - file_id=decoded_file_id, - cover=cover, - caption=f_caption, - protect_content=settings.get('file_secure', PROTECT_CONTENT), - reply_markup=InlineKeyboardMarkup(btn) - ) - filesarr.append(sent_msg) - - # Auto-Delete Logic - if settings and settings.get('auto_delete', True) and filesarr: - k = await client.send_message(chat_id=message.from_user.id, text=script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) - - async def _delete_files(msgs, notif_msg, delay): - await asyncio.sleep(delay) - for x in msgs: - try: - await x.delete() - except Exception: - pass - try: - await notif_msg.edit_text("ʏᴏᴜʀ ᴠɪᴅᴇᴏꜱ/ꜰɪʟᴇꜱ ᴀʀᴇ ᴅᴇʟᴇᴛᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ !\nᴋɪɴᴅʟʏ ꜱᴇᴀʀᴄʜ ᴀɢᴀɪɴ") - except Exception: - pass - - asyncio.create_task(_delete_files(filesarr, k, DELETE_TIME)) - - return + message.command[1] = f"file_{grp_id}_{file_id}" + if message.chat.type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: buttons = [[ InlineKeyboardButton('❤ ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ ❤', url=f'http://t.me/{temp.U_NAME}?startgroup=true') @@ -466,7 +359,7 @@ async def _delete_files(msgs, notif_msg, delay): size = get_size(files1.file_size) f_caption = files1.caption settings = await get_settings(int(grp_id)) - DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION if settings else CUSTOM_FILE_CAPTION + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if DREAMX_CAPTION: try: f_caption=DREAMX_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) @@ -481,7 +374,7 @@ async def _delete_files(msgs, notif_msg, delay): cover=cover, file_id=file_id, caption=f_caption, - protect_content=settings.get('file_secure', PROTECT_CONTENT) if settings else PROTECT_CONTENT, + protect_content=settings.get('file_secure', PROTECT_CONTENT), reply_markup=InlineKeyboardMarkup(btn) ) filesarr.append(msg) @@ -518,14 +411,13 @@ async def _delete_files(msgs, notif_msg, delay): size=get_size(file.file_size) f_caption = f"{title}" settings = await get_settings(int(grp_id)) - DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if DREAMX_CAPTION: try: f_caption=DREAMX_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='') except Exception: return await msg.edit_caption(f_caption, reply_markup=InlineKeyboardMarkup(btn)) - # FIXED: removed k = await msg.reply(script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) await asyncio.sleep(DELETE_TIME) await msg.delete() @@ -574,27 +466,7 @@ async def _delete_files(msgs, notif_msg, delay): pass async def stream_buttons(user_id: int, file_id: str): - if STREAM_MODE and not PREMIUM_STREAM_MODE: - return [ - [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], - [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], - [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] - ] - elif STREAM_MODE and PREMIUM_STREAM_MODE: - if not await db.has_premium_access(user_id): - return [ - [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data='prestream')], - [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data='prestream')], - [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] - ] - else: - return [ - [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], - [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], - [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] - ] - else: - return [[InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)]] + return [[InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)]] @Client.on_message(filters.command('logs') & filters.user(ADMINS)) async def log_file(bot, message): From 9c7814e38fd6560d2a63dd3aed21ca1f03cb0b52 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Tue, 15 Sep 2026 07:34:28 +0530 Subject: [PATCH 30/77] Update commands.py --- plugins/commands.py | 160 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 144 insertions(+), 16 deletions(-) diff --git a/plugins/commands.py b/plugins/commands.py index 0390712e..e9163d79 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -61,36 +61,143 @@ async def start(client, message): current_time = datetime.now(tz=ist_timezone) await db.update_notcopy_user(user_id, {key:current_time}) await db.update_verify_id_info(user_id, verify_id, {"verified":True}) + if key == "third_time_verified": num = 3 + msg = script.THIRDT_VERIFY_COMPLETE_TEXT else: num = 2 if key == "second_time_verified" else 1 - if key == "third_time_verified": - msg = script.THIRDT_VERIFY_COMPLETE_TEXT - else: msg = script.SECOND_VERIFY_COMPLETE_TEXT if key == "second_time_verified" else script.VERIFY_COMPLETE_TEXT - await client.send_message(settings['log'], script.VERIFIED_LOG_TEXT.format(m.from_user.mention, user_id, datetime.now(pytz.timezone('Asia/Kolkata')).strftime('%d %B %Y'), num)) + log_channel = settings.get('log') if settings and settings.get('log') else LOG_CHANNEL + try: + await client.send_message(log_channel, script.VERIFIED_LOG_TEXT.format(m.from_user.mention, user_id, datetime.now(pytz.timezone('Asia/Kolkata')).strftime('%d %B %Y'), num)) + except Exception as e: + logger.error(f"Failed to log verification: {e}") - dlt=await m.reply_photo( - photo=(VERIFY_IMG), - caption=msg.format(message.from_user.mention, get_readable_time(TWO_VERIFY_GAP)), + is_sendall = m.command[1].startswith('sendall') + if is_sendall: + verifiedfiles = f"https://telegram.me/{temp.U_NAME}?start=allfiles_{grp_id}_{file_id}" + else: + verifiedfiles = f"https://telegram.me/{temp.U_NAME}?start=file_{grp_id}_{file_id}" + + btn_complete = [[ + InlineKeyboardButton("🫶🏻 Cʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ɢᴇᴛ ғɪʟᴇ 🕊", url=verifiedfiles), + ]] + dlt = await m.reply_photo( + photo="https://i.ibb.co/1tDXygyb/image.webp", + caption=msg.format(m.from_user.mention), + reply_markup=InlineKeyboardMarkup(btn_complete), parse_mode=enums.ParseMode.HTML ) - + async def _delete_msg(msg_to_delete, delay): await asyncio.sleep(delay) try: await msg_to_delete.delete() except Exception: pass + asyncio.create_task(_delete_msg(dlt, 300)) + + # Send files automatically + is_sendall = m.command[1].startswith('sendall') + decoded_file_id = file_id + if not is_sendall: + try: + raw = base64.urlsafe_b64decode(file_id + "=" * (-len(file_id) % 4)) + sep = raw.find(b"_") + if sep != -1: + decoded_file_id = raw[sep + 1:].decode("latin1") + except Exception: + pass + + filesarr = [] - if message.command[1].startswith('sendall'): - message.command[1] = f"allfiles_{grp_id}_{file_id}" + if is_sendall: + files = temp.GETALL.get(file_id) + if not files: + await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ !') + return + for file in files: + file_id_item = file.file_id + files_ = await get_file_details(file_id_item) + if not files_: + continue + files1 = files_[0] + title = clean_filename(files1.file_name) + cover = files1.cover + size = get_size(files1.file_size) + f_caption = files1.caption + + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION if settings else CUSTOM_FILE_CAPTION + if DREAMX_CAPTION: + try: + f_caption = DREAMX_CAPTION.format(file_name='' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) + except Exception as e: + logger.exception(e) + + if f_caption is None: + f_caption = f"{clean_filename(files1.file_name)}" + + sent_msg = await client.send_cached_media( + chat_id=message.from_user.id, + cover=cover, + file_id=file_id_item, + caption=f_caption, + protect_content=settings.get('file_secure', PROTECT_CONTENT) if settings else PROTECT_CONTENT if settings else PROTECT_CONTENT + ) + filesarr.append(sent_msg) else: - message.command[1] = f"file_{grp_id}_{file_id}" - + files_ = await get_file_details(decoded_file_id) + if not files_: + await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ !') + return + files1 = files_[0] + title = clean_filename(files1.file_name) + size = get_size(files1.file_size) + cover = files1.cover if files1.cover else None + f_caption = files1.caption + + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION + if DREAMX_CAPTION: + try: + f_caption = DREAMX_CAPTION.format(file_name='' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) + except Exception as e: + logger.exception(e) + + if f_caption is None: + f_caption = clean_filename(files1.file_name) + + sent_msg = await client.send_cached_media( + chat_id=message.from_user.id, + file_id=decoded_file_id, + cover=cover, + caption=f_caption, + protect_content=settings.get('file_secure', PROTECT_CONTENT), + reply_markup=InlineKeyboardMarkup(btn) + ) + filesarr.append(sent_msg) + + # Auto-Delete Logic + if settings and settings.get('auto_delete', True) and filesarr: + k = await client.send_message(chat_id=message.from_user.id, text=script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) + + async def _delete_files(msgs, notif_msg, delay): + await asyncio.sleep(delay) + for x in msgs: + try: + await x.delete() + except Exception: + pass + try: + await notif_msg.edit_text("ʏᴏᴜʀ ᴠɪᴅᴇᴏꜱ/ꜰɪʟᴇꜱ ᴀʀᴇ ᴅᴇʟᴇᴛᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ !\nᴋɪɴᴅʟʏ ꜱᴇᴀʀᴄʜ ᴀɢᴀɪɴ") + except Exception: + pass + + asyncio.create_task(_delete_files(filesarr, k, DELETE_TIME)) + + return if message.chat.type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: buttons = [[ InlineKeyboardButton('❤ ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ ❤', url=f'http://t.me/{temp.U_NAME}?startgroup=true') @@ -359,7 +466,7 @@ async def _delete_msg(msg_to_delete, delay): size = get_size(files1.file_size) f_caption = files1.caption settings = await get_settings(int(grp_id)) - DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION if settings else CUSTOM_FILE_CAPTION if DREAMX_CAPTION: try: f_caption=DREAMX_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) @@ -374,7 +481,7 @@ async def _delete_msg(msg_to_delete, delay): cover=cover, file_id=file_id, caption=f_caption, - protect_content=settings.get('file_secure', PROTECT_CONTENT), + protect_content=settings.get('file_secure', PROTECT_CONTENT) if settings else PROTECT_CONTENT, reply_markup=InlineKeyboardMarkup(btn) ) filesarr.append(msg) @@ -411,13 +518,14 @@ async def _delete_msg(msg_to_delete, delay): size=get_size(file.file_size) f_caption = f"{title}" settings = await get_settings(int(grp_id)) - DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION if DREAMX_CAPTION: try: f_caption=DREAMX_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='') except Exception: return await msg.edit_caption(f_caption, reply_markup=InlineKeyboardMarkup(btn)) + # FIXED: removed k = await msg.reply(script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) await asyncio.sleep(DELETE_TIME) await msg.delete() @@ -466,7 +574,27 @@ async def _delete_msg(msg_to_delete, delay): pass async def stream_buttons(user_id: int, file_id: str): - return [[InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)]] + if STREAM_MODE and not PREMIUM_STREAM_MODE: + return [ + [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], + [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], + [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] + ] + elif STREAM_MODE and PREMIUM_STREAM_MODE: + if not await db.has_premium_access(user_id): + return [ + [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data='prestream')], + [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data='prestream')], + [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] + ] + else: + return [ + [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], + [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], + [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] + ] + else: + return [[InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)]] @Client.on_message(filters.command('logs') & filters.user(ADMINS)) async def log_file(bot, message): From 0646f5439e8651bc495f7f95e0bd1baf6a2d2c31 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Tue, 15 Sep 2026 07:45:04 +0530 Subject: [PATCH 31/77] Update commands.py --- plugins/commands.py | 214 +++++++++----------------------------------- 1 file changed, 43 insertions(+), 171 deletions(-) diff --git a/plugins/commands.py b/plugins/commands.py index e9163d79..9f3e72bd 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -41,7 +41,7 @@ async def start(client, message): try: asyncio.create_task(message.react(emoji=random.choice(REACTIONS), big=True)) except Exception: - asyncio.create_task(message.react(emoji="⚡")) + asyncio.create_task(message.react(emoji="⚡️")) pass m = message if len(m.command) == 2 and m.command[1].startswith(('notcopy', 'sendall')): @@ -61,146 +61,39 @@ async def start(client, message): current_time = datetime.now(tz=ist_timezone) await db.update_notcopy_user(user_id, {key:current_time}) await db.update_verify_id_info(user_id, verify_id, {"verified":True}) - if key == "third_time_verified": num = 3 - msg = script.THIRDT_VERIFY_COMPLETE_TEXT else: num = 2 if key == "second_time_verified" else 1 + if key == "third_time_verified": + msg = script.THIRDT_VERIFY_COMPLETE_TEXT + else: msg = script.SECOND_VERIFY_COMPLETE_TEXT if key == "second_time_verified" else script.VERIFY_COMPLETE_TEXT - log_channel = settings.get('log') if settings and settings.get('log') else LOG_CHANNEL - try: - await client.send_message(log_channel, script.VERIFIED_LOG_TEXT.format(m.from_user.mention, user_id, datetime.now(pytz.timezone('Asia/Kolkata')).strftime('%d %B %Y'), num)) - except Exception as e: - logger.error(f"Failed to log verification: {e}") + await client.send_message(settings['log'], script.VERIFIED_LOG_TEXT.format(m.from_user.mention, user_id, datetime.now(pytz.timezone('Asia/Kolkata')).strftime('%d %B %Y'), num)) - is_sendall = m.command[1].startswith('sendall') - if is_sendall: - verifiedfiles = f"https://telegram.me/{temp.U_NAME}?start=allfiles_{grp_id}_{file_id}" - else: - verifiedfiles = f"https://telegram.me/{temp.U_NAME}?start=file_{grp_id}_{file_id}" - - btn_complete = [[ - InlineKeyboardButton("🫶🏻 Cʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ɢᴇᴛ ғɪʟᴇ 🕊", url=verifiedfiles), - ]] - dlt = await m.reply_photo( - photo="https://i.ibb.co/1tDXygyb/image.webp", - caption=msg.format(m.from_user.mention), - reply_markup=InlineKeyboardMarkup(btn_complete), + dlt=await m.reply_photo( + photo=(VERIFY_IMG), + caption=msg.format(message.from_user.mention, get_readable_time(TWO_VERIFY_GAP)), parse_mode=enums.ParseMode.HTML ) - + async def _delete_msg(msg_to_delete, delay): await asyncio.sleep(delay) try: await msg_to_delete.delete() except Exception: pass - asyncio.create_task(_delete_msg(dlt, 300)) - - # Send files automatically - is_sendall = m.command[1].startswith('sendall') - decoded_file_id = file_id - if not is_sendall: - try: - raw = base64.urlsafe_b64decode(file_id + "=" * (-len(file_id) % 4)) - sep = raw.find(b"_") - if sep != -1: - decoded_file_id = raw[sep + 1:].decode("latin1") - except Exception: - pass - - filesarr = [] - if is_sendall: - files = temp.GETALL.get(file_id) - if not files: - await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ !') - return - for file in files: - file_id_item = file.file_id - files_ = await get_file_details(file_id_item) - if not files_: - continue - files1 = files_[0] - title = clean_filename(files1.file_name) - cover = files1.cover - size = get_size(files1.file_size) - f_caption = files1.caption - - DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION if settings else CUSTOM_FILE_CAPTION - if DREAMX_CAPTION: - try: - f_caption = DREAMX_CAPTION.format(file_name='' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) - except Exception as e: - logger.exception(e) - - if f_caption is None: - f_caption = f"{clean_filename(files1.file_name)}" - - sent_msg = await client.send_cached_media( - chat_id=message.from_user.id, - cover=cover, - file_id=file_id_item, - caption=f_caption, - protect_content=settings.get('file_secure', PROTECT_CONTENT) if settings else PROTECT_CONTENT if settings else PROTECT_CONTENT - ) - filesarr.append(sent_msg) + if message.command[1].startswith('sendall'): + message.command[1] = f"allfiles_{grp_id}_{file_id}" else: - files_ = await get_file_details(decoded_file_id) - if not files_: - await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ !') - return - files1 = files_[0] - title = clean_filename(files1.file_name) - size = get_size(files1.file_size) - cover = files1.cover if files1.cover else None - f_caption = files1.caption - - DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION - if DREAMX_CAPTION: - try: - f_caption = DREAMX_CAPTION.format(file_name='' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) - except Exception as e: - logger.exception(e) - - if f_caption is None: - f_caption = clean_filename(files1.file_name) - - sent_msg = await client.send_cached_media( - chat_id=message.from_user.id, - file_id=decoded_file_id, - cover=cover, - caption=f_caption, - protect_content=settings.get('file_secure', PROTECT_CONTENT), - reply_markup=InlineKeyboardMarkup(btn) - ) - filesarr.append(sent_msg) - - # Auto-Delete Logic - if settings and settings.get('auto_delete', True) and filesarr: - k = await client.send_message(chat_id=message.from_user.id, text=script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) - - async def _delete_files(msgs, notif_msg, delay): - await asyncio.sleep(delay) - for x in msgs: - try: - await x.delete() - except Exception: - pass - try: - await notif_msg.edit_text("ʏᴏᴜʀ ᴠɪᴅᴇᴏꜱ/ꜰɪʟᴇꜱ ᴀʀᴇ ᴅᴇʟᴇᴛᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ !\nᴋɪɴᴅʟʏ ꜱᴇᴀʀᴄʜ ᴀɢᴀɪɴ") - except Exception: - pass - - asyncio.create_task(_delete_files(filesarr, k, DELETE_TIME)) - - return + message.command[1] = f"file_{grp_id}_{file_id}" + if message.chat.type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: buttons = [[ - InlineKeyboardButton('❤ ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ ❤', url=f'http://t.me/{temp.U_NAME}?startgroup=true') + InlineKeyboardButton('❤️ ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ ❤️', url=f'http://t.me/{temp.U_NAME}?startgroup=true') ],[ InlineKeyboardButton('🍁 Update Channel 🍁', url=UPDATE_CHNL_LNK) ]] @@ -291,7 +184,7 @@ async def _delete_files(msgs, notif_msg, delay): try: user_id = int(message.command[1].split("_")[1]) except ValueError: - await message.reply_text("‼ ɪɴᴠᴀʟɪᴅ ʀᴇꜰᴇʀ!") + await message.reply_text("‼️ ɪɴᴠᴀʟɪᴅ ʀᴇꜰᴇʀ!") return if user_id == message.from_user.id: await message.reply_text(script.REFER_SELF_ALRT) @@ -388,7 +281,7 @@ async def _delete_files(msgs, notif_msg, delay): if len(message.command) > 1 and "_" in message.command[1]: kk, file_id = message.command[1].split("_", 1) btn.append([ - InlineKeyboardButton("♻ ᴛʀʏ ᴀɢᴀɪɴ ♻", callback_data=f"checksub#{kk}#{file_id}") + InlineKeyboardButton("♻️ ᴛʀʏ ᴀɢᴀɪɴ ♻️", callback_data=f"checksub#{kk}#{file_id}") ]) reply_markup = InlineKeyboardMarkup(btn) photo = random.choice(FSUB_PICS) if FSUB_PICS else "https://graph.org/file/7478ff3eac37f4329c3d8.jpg" @@ -426,9 +319,9 @@ async def _delete_files(msgs, notif_msg, delay): else: howtodownload = settings.get('tutorial_2', TUTORIAL_2) if is_second_shortener else settings.get('tutorial', TUTORIAL) buttons = [[ - InlineKeyboardButton(text="♻ ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ᴠᴇʀɪꜰʏ ♻", url=verify) + InlineKeyboardButton(text="♻️ ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ᴠᴇʀɪꜰʏ ♻️", url=verify) ],[ - InlineKeyboardButton(text="⁉ ʜᴏᴡ ᴛᴏ ᴠᴇʀɪꜰʏ ⁉", url=howtodownload) + InlineKeyboardButton(text="⁉️ ʜᴏᴡ ᴛᴏ ᴠᴇʀɪꜰʏ ⁉️", url=howtodownload) ]] reply_markup=InlineKeyboardMarkup(buttons) if await db.user_verified(user_id): @@ -466,7 +359,7 @@ async def _delete_files(msgs, notif_msg, delay): size = get_size(files1.file_size) f_caption = files1.caption settings = await get_settings(int(grp_id)) - DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION if settings else CUSTOM_FILE_CAPTION + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if DREAMX_CAPTION: try: f_caption=DREAMX_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) @@ -481,7 +374,7 @@ async def _delete_files(msgs, notif_msg, delay): cover=cover, file_id=file_id, caption=f_caption, - protect_content=settings.get('file_secure', PROTECT_CONTENT) if settings else PROTECT_CONTENT, + protect_content=settings.get('file_secure', PROTECT_CONTENT), reply_markup=InlineKeyboardMarkup(btn) ) filesarr.append(msg) @@ -518,14 +411,13 @@ async def _delete_files(msgs, notif_msg, delay): size=get_size(file.file_size) f_caption = f"{title}" settings = await get_settings(int(grp_id)) - DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if DREAMX_CAPTION: try: f_caption=DREAMX_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='') except Exception: return await msg.edit_caption(f_caption, reply_markup=InlineKeyboardMarkup(btn)) - # FIXED: removed k = await msg.reply(script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) await asyncio.sleep(DELETE_TIME) await msg.delete() @@ -574,27 +466,7 @@ async def _delete_files(msgs, notif_msg, delay): pass async def stream_buttons(user_id: int, file_id: str): - if STREAM_MODE and not PREMIUM_STREAM_MODE: - return [ - [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], - [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], - [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] - ] - elif STREAM_MODE and PREMIUM_STREAM_MODE: - if not await db.has_premium_access(user_id): - return [ - [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data='prestream')], - [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data='prestream')], - [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] - ] - else: - return [ - [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], - [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], - [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] - ] - else: - return [[InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)]] + return [[InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)]] @Client.on_message(filters.command('logs') & filters.user(ADMINS)) async def log_file(bot, message): @@ -628,7 +500,7 @@ async def save_file_handler(bot, message): if success: await msg.edit('Fɪʟᴇ ɪs sᴜᴄᴄᴇssғᴜʟʟʏ sᴀᴠᴇᴅ ᴛᴏ ᴅᴀᴛᴀʙᴀsᴇ ✅') elif status == 0: - await msg.edit('Fɪʟᴇ ᴀʟʀᴇᴀᴅʏ ᴇxɪsᴛs ɪɴ ᴅᴀᴛᴀʙᴀsᴇ ⚠') + await msg.edit('Fɪʟᴇ ᴀʟʀᴇᴀᴅʏ ᴇxɪsᴛs ɪɴ ᴅᴀᴛᴀʙᴀsᴇ ⚠️') elif status == 2: await msg.edit('Eʀʀᴏʀ: Fɪʟᴇ ᴠᴀʟɪᴅᴀᴛɪᴏɴ ғᴀɪʟᴇᴅ ❌') else: @@ -711,7 +583,7 @@ async def delete_all_index(bot, message): [ [ InlineKeyboardButton( - text="⚠ ʏᴇꜱ ⚠", callback_data="autofilter_delete" + text="⚠️ ʏᴇꜱ ⚠️", callback_data="autofilter_delete" ) ], [ @@ -740,7 +612,7 @@ async def settings(client, message): InlineKeyboardButton("👥 ᴏᴘᴇɴ ʜᴇʀᴇ 👥", callback_data=f"opnsetgrp#{grp_id}") ]] await message.reply_text( - text="ᴡʜᴇʀᴇ ᴅᴏ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴏᴘᴇɴ ꜱᴇᴛᴛɪɴɢꜱ ᴍᴇɴᴜ ? ⚙", + text="ᴡʜᴇʀᴇ ᴅᴏ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴏᴘᴇɴ ꜱᴇᴛᴛɪɴɢꜱ ᴍᴇɴᴜ ? ⚙️", reply_markup=InlineKeyboardMarkup(btn), link_preview_options=LinkPreviewOptions(is_disabled=True), parse_mode=enums.ParseMode.HTML @@ -757,7 +629,7 @@ async def settings(client, message): except Exception: pass await message.reply_text( - "⚠ ꜱᴇʟᴇᴄᴛ ᴛʜᴇ ɢʀᴏᴜᴘ ᴡʜᴏꜱᴇ ꜱᴇᴛᴛɪɴɢꜱ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʜᴀɴɢᴇ.\n\n" + "⚠️ ꜱᴇʟᴇᴄᴛ ᴛʜᴇ ɢʀᴏᴜᴘ ᴡʜᴏꜱᴇ ꜱᴇᴛᴛɪɴɢꜱ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʜᴀɴɢᴇ.\n\n" "ɪꜰ ʏᴏᴜʀ ɢʀᴏᴜᴘ ɪꜱ ɴᴏᴛ ꜱʜᴏᴡɪɴɢ ʜᴇʀᴇ,\n" "ᴜꜱᴇ /reload ɪɴ ᴛʜᴀᴛ ɢʀᴏᴜᴘ ᴀɴᴅ ɪᴛ ᴡɪʟʟ ᴀᴘᴘᴇᴀʀ ʜᴇʀᴇ.", reply_markup=InlineKeyboardMarkup(group_list) @@ -792,7 +664,7 @@ async def save_template(client, message): return await message.reply("ʏᴏᴜ'ʀᴇ ᴀɴᴏɴʏᴍᴏᴜꜱ ᴀᴅᴍɪɴ.") if message.chat.type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: - return await sts.edit("⚠ ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ɪɴ ᴀ ɢʀᴏᴜᴘ ᴄʜᴀᴛ.") + return await sts.edit("⚠️ ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ɪɴ ᴀ ɢʀᴏᴜᴘ ᴄʜᴀᴛ.") group_id = message.chat.id title = message.chat.title @@ -800,7 +672,7 @@ async def save_template(client, message): await message.reply_text(script.NT_ADMIN_ALRT_TXT) return if len(message.command) < 2: - return await sts.edit("⚠ ɴᴏ ᴛᴇᴍᴘʟᴀᴛᴇ ᴘʀᴏᴠɪᴅᴇᴅ!") + return await sts.edit("⚠️ ɴᴏ ᴛᴇᴍᴘʟᴀᴛᴇ ᴘʀᴏᴠɪᴅᴇᴅ!") template = message.text.split(" ", 1)[1] await save_group_settings(group_id, 'template', template) @@ -814,7 +686,7 @@ async def requests(bot, message): if message.chat.id != SUPPORT_CHAT_ID: return if not message.from_user: - return await message.reply_text("⚠ ᴜɴᴀʙʟᴇ ᴛᴏ ɪᴅᴇɴᴛɪꜰʏ ʏᴏᴜ.") + return await message.reply_text("⚠️ ᴜɴᴀʙʟᴇ ᴛᴏ ɪᴅᴇɴᴛɪꜰʏ ʏᴏᴜ.") reporter = str(message.from_user.id) mention = message.from_user.mention @@ -839,7 +711,7 @@ async def requests(bot, message): InlineKeyboardButton('ꜱʜᴏᴡ ᴏᴘᴛɪᴏɴꜱ', callback_data=f'show_option#{reporter}') ]] req_text = f"📝 ʀᴇǫᴜᴇꜱᴛ : {content}\n\n📚 ʀᴇᴘᴏʀᴛᴇᴅ ʙʏ : {mention}\n📖 ʀᴇᴘᴏʀᴛᴇʀ ɪᴅ : {reporter}\n\n" - warning_text = "⚠ ʀᴇǫᴜᴇꜱᴛ ᴄʜᴀɴɴᴇʟ ɪꜱ ɴᴏᴛ ꜱᴇᴛ." + warning_text = "⚠️ ʀᴇǫᴜᴇꜱᴛ ᴄʜᴀɴɴᴇʟ ɪꜱ ɴᴏᴛ ꜱᴇᴛ." if REQST_CHANNEL is not None: try: reported_post = await bot.send_message(chat_id=REQST_CHANNEL, text=req_text, reply_markup=InlineKeyboardMarkup(btn)) @@ -853,7 +725,7 @@ async def requests(bot, message): reported_post = await bot.send_message(chat_id=admin, text=req_text, reply_markup=InlineKeyboardMarkup(btn)) except Exception: logger.exception("Request failed") - return await message.reply_text( "⚠ ꜱᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ. ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ.") + return await message.reply_text( "⚠️ ꜱᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ. ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ.") if reported_post and REQST_CHANNEL is not None: try: @@ -876,7 +748,7 @@ async def requests(bot, message): await message.reply_text("ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ʜᴀꜱ ʙᴇᴇɴ ᴀᴅᴅᴇᴅ! ᴘʟᴇᴀꜱᴇ ᴡᴀɪᴛ ꜰᴏʀ ꜱᴏᴍᴇ ᴛɪᴍᴇ.") except Exception: logger.exception("Failed to send request confirmation") - await message.reply_text("⚠ ꜱᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ. ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ.") + await message.reply_text("⚠️ ꜱᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ. ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ.") @Client.on_message(filters.command("send") & filters.user(ADMINS)) async def send_msg(bot, message): @@ -924,7 +796,7 @@ async def deletemultiplefiles(bot, message): return await k.delete() btn = [[ - InlineKeyboardButton("⚠ Yes, Continue ! ⚠", callback_data=f"killfilesdq#{keyword}") + InlineKeyboardButton("⚠️ Yes, Continue ! ⚠️", callback_data=f"killfilesdq#{keyword}") ],[ InlineKeyboardButton("❌ No, Abort operation ! ❌", callback_data="close_data") ]] @@ -1032,7 +904,7 @@ def is_alphanumeric(string): return formatted_list = "\n".join([f"{i+1}. {msg}" for i, msg in enumerate(truncated_messages)]) additional_message = ( - "⚡ 𝑨𝒍𝒍 𝒕𝒉𝒆 𝒓𝒆𝒔𝒖𝒍𝒕𝒔 𝒂𝒃𝒐𝒗𝒆 𝒄𝒐𝒎𝒆 𝒇𝒓𝒐𝒎 𝒘𝒉𝒂𝒕 𝒖𝒔𝒆𝒓𝒔 𝒉𝒂𝒗𝒆 𝒔𝒆𝒂𝒓𝒄𝒉𝒆𝒅 𝒇𝒐𝒓. " + "⚡️ 𝑨𝒍𝒍 𝒕𝒉𝒆 𝒓𝒆𝒔𝒖𝒍𝒕𝒔 𝒂𝒃𝒐𝒗𝒆 𝒄𝒐𝒎𝒆 𝒇𝒓𝒐𝒎 𝒘𝒉𝒂𝒕 𝒖𝒔𝒆𝒓𝒔 𝒉𝒂𝒗𝒆 𝒔𝒆𝒂𝒓𝒄𝒉𝒆𝒅 𝒇𝒐𝒓. " "𝑻𝒉𝒆𝒚'𝒓𝒆 𝒔𝒉𝒐𝒘𝒏 𝒕𝒐 𝒚𝒐𝒖 𝒆𝒙𝒂𝒄𝒕𝒍𝒚 𝒂𝒔 𝒕𝒉𝒆𝒚 𝒘𝒆𝒓𝒆 𝒔𝒆𝒂𝒓𝒄𝒉𝒆𝒅, " "𝒘𝒊𝒕𝒉𝒐𝒖𝒕 𝒂𝒏𝒚 𝒄𝒉𝒂𝒏𝒈𝒆𝒔 𝒃𝒚 𝒕𝒉𝒆 𝒐𝒘𝒏𝒆𝒓." ) @@ -1094,7 +966,7 @@ async def del_msg(client, message): InlineKeyboardButton("No", callback_data="confirm_del_no") ]]) sent_message = await message.reply_text( - "⚠ Aʀᴇ ʏᴏᴜ sᴜʀᴇ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʟᴇᴀʀ ᴛʜᴇ ᴜᴘᴅᴀᴛᴇs ᴄʜᴀɴɴᴇʟ ʟɪsᴛ ?\n\n ᴅᴏ ʏᴏᴜ ꜱᴛɪʟʟ ᴡᴀɴᴛ ᴛᴏ ᴄᴏɴᴛɪɴᴜᴇ ?", + "⚠️ Aʀᴇ ʏᴏᴜ sᴜʀᴇ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʟᴇᴀʀ ᴛʜᴇ ᴜᴘᴅᴀᴛᴇs ᴄʜᴀɴɴᴇʟ ʟɪsᴛ ?\n\n ᴅᴏ ʏᴏᴜ ꜱᴛɪʟʟ ᴡᴀɴᴛ ᴛᴏ ᴄᴏɴᴛɪɴᴜᴇ ?", reply_markup=confirm_markup ) await asyncio.sleep(60) @@ -1181,7 +1053,7 @@ async def handle_shortner_command(c, m, shortner_key, api_key, log_prefix, fallb return await m.reply( f"ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ʟɪᴋᴇ -\n\n`/{m.command[0]} your-shortener-domain.com your_api_key_here`" ) - sts = await m.reply("♻ ᴄʜᴇᴄᴋɪɴɢ...") + sts = await m.reply("♻️ ᴄʜᴇᴄᴋɪɴɢ...") await asyncio.sleep(1.2) await sts.delete() if m.chat.type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: @@ -1237,7 +1109,7 @@ async def set_log(client, message): if len(message.text.split()) == 1: await message.reply("ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ʟɪᴋᴇ ᴛʜɪꜱ - \n\n`/set_log_channel -100******`") return - sts = await message.reply("♻ ᴄʜᴇᴄᴋɪɴɢ...") + sts = await message.reply("♻️ ᴄʜᴇᴄᴋɪɴɢ...") await asyncio.sleep(1.2) await sts.delete() chat_type = message.chat.type @@ -1312,10 +1184,10 @@ async def all_settings(client, message): try: settings = await get_settings(grp_id) except Exception as e: - return await message.reply_text(f"⚠ ᴇʀʀᴏʀ ꜰᴇᴛᴄʜɪɴɢ ꜱᴇᴛᴛɪɴɢꜱ:\n{e}") + return await message.reply_text(f"⚠️ ᴇʀʀᴏʀ ꜰᴇᴛᴄʜɪɴɢ ꜱᴇᴛᴛɪɴɢꜱ:\n{e}") text = generate_settings_text(settings, title) btn = [ - [InlineKeyboardButton("♻ ʀᴇꜱᴇᴛ ꜱᴇᴛᴛɪɴɢꜱ", callback_data=f"reset_group_{grp_id}")], + [InlineKeyboardButton("♻️ ʀᴇꜱᴇᴛ ꜱᴇᴛᴛɪɴɢꜱ", callback_data=f"reset_group_{grp_id}")], [InlineKeyboardButton("🚫 ᴄʟᴏꜱᴇ", callback_data="close_data")] ] dlt = await message.reply_text(text, reply_markup=InlineKeyboardMarkup(btn), link_preview_options=LinkPreviewOptions(is_disabled=True)) @@ -1328,7 +1200,7 @@ async def reset_group_callback(client, callback_query): user_id = callback_query.from_user.id if not await is_check_admin(client, grp_id, user_id): return await callback_query.answer(script.NT_ADMIN_ALRT_TXT, show_alert=True) - await callback_query.answer("♻ ʀᴇꜱᴇᴛᴛɪɴɢ ꜱᴇᴛᴛɪɴɢꜱ...") + await callback_query.answer("♻️ ʀᴇꜱᴇᴛᴛɪɴɢ ꜱᴇᴛᴛɪɴɢꜱ...") defaults = { 'shortner': SHORTENER_WEBSITE, 'api': SHORTENER_API, @@ -1359,7 +1231,7 @@ async def reset_group_callback(client, callback_query): title = callback_query.message.chat.title text = generate_settings_text(updated, title, reset_done=True) buttons = [ - [InlineKeyboardButton("♻ ʀᴇꜱᴇᴛ ꜱᴇᴛᴛɪɴɢꜱ", callback_data=f"reset_group_{grp_id}")], + [InlineKeyboardButton("♻️ ʀᴇꜱᴇᴛ ꜱᴇᴛᴛɪɴɢꜱ", callback_data=f"reset_group_{grp_id}")], [InlineKeyboardButton("🚫 ᴄʟᴏꜱᴇ", callback_data="close_data")] ] await callback_query.message.edit_text(text, reply_markup=InlineKeyboardMarkup(buttons), link_preview_options=LinkPreviewOptions(is_disabled=True)) @@ -1433,7 +1305,7 @@ async def set_fsub(client, message): f"ꜰꜱᴜʙ ᴄʜᴀɴɴᴇʟ(ꜱ):\n" + '\n'.join(channel_titles) ) except Exception as e: - err_text = f"⚠ Error in set_fSub :\n{e}" + err_text = f"⚠️ Error in set_fSub :\n{e}" logger.error(err_text) await client.send_message(LOG_CHANNEL, err_text) @@ -1529,7 +1401,7 @@ async def remove_fsub(client, message): ) except Exception as e: logger.error("remove_fsub: %s", e) - await message.reply_text(f"⚠ ᴀɴ ᴇʀʀᴏʀ ᴏᴄᴄᴜʀʀᴇᴅ: {e}") + await message.reply_text(f"⚠️ ᴀɴ ᴇʀʀᴏʀ ᴏᴄᴄᴜʀʀᴇᴅ: {e}") @Client.on_message(filters.command('clean_groups') & filters.user(ADMINS)) async def clean_groups_handler(client, message): From 74e59d2b2423d14594dda06e9b6ff13fbba0595f Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Tue, 15 Sep 2026 07:58:55 +0530 Subject: [PATCH 32/77] Update commands.py --- plugins/commands.py | 214 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 171 insertions(+), 43 deletions(-) diff --git a/plugins/commands.py b/plugins/commands.py index 9f3e72bd..e9163d79 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -41,7 +41,7 @@ async def start(client, message): try: asyncio.create_task(message.react(emoji=random.choice(REACTIONS), big=True)) except Exception: - asyncio.create_task(message.react(emoji="⚡️")) + asyncio.create_task(message.react(emoji="⚡")) pass m = message if len(m.command) == 2 and m.command[1].startswith(('notcopy', 'sendall')): @@ -61,39 +61,146 @@ async def start(client, message): current_time = datetime.now(tz=ist_timezone) await db.update_notcopy_user(user_id, {key:current_time}) await db.update_verify_id_info(user_id, verify_id, {"verified":True}) + if key == "third_time_verified": num = 3 + msg = script.THIRDT_VERIFY_COMPLETE_TEXT else: num = 2 if key == "second_time_verified" else 1 - if key == "third_time_verified": - msg = script.THIRDT_VERIFY_COMPLETE_TEXT - else: msg = script.SECOND_VERIFY_COMPLETE_TEXT if key == "second_time_verified" else script.VERIFY_COMPLETE_TEXT - await client.send_message(settings['log'], script.VERIFIED_LOG_TEXT.format(m.from_user.mention, user_id, datetime.now(pytz.timezone('Asia/Kolkata')).strftime('%d %B %Y'), num)) + log_channel = settings.get('log') if settings and settings.get('log') else LOG_CHANNEL + try: + await client.send_message(log_channel, script.VERIFIED_LOG_TEXT.format(m.from_user.mention, user_id, datetime.now(pytz.timezone('Asia/Kolkata')).strftime('%d %B %Y'), num)) + except Exception as e: + logger.error(f"Failed to log verification: {e}") - dlt=await m.reply_photo( - photo=(VERIFY_IMG), - caption=msg.format(message.from_user.mention, get_readable_time(TWO_VERIFY_GAP)), + is_sendall = m.command[1].startswith('sendall') + if is_sendall: + verifiedfiles = f"https://telegram.me/{temp.U_NAME}?start=allfiles_{grp_id}_{file_id}" + else: + verifiedfiles = f"https://telegram.me/{temp.U_NAME}?start=file_{grp_id}_{file_id}" + + btn_complete = [[ + InlineKeyboardButton("🫶🏻 Cʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ɢᴇᴛ ғɪʟᴇ 🕊", url=verifiedfiles), + ]] + dlt = await m.reply_photo( + photo="https://i.ibb.co/1tDXygyb/image.webp", + caption=msg.format(m.from_user.mention), + reply_markup=InlineKeyboardMarkup(btn_complete), parse_mode=enums.ParseMode.HTML ) - + async def _delete_msg(msg_to_delete, delay): await asyncio.sleep(delay) try: await msg_to_delete.delete() except Exception: pass + asyncio.create_task(_delete_msg(dlt, 300)) + + # Send files automatically + is_sendall = m.command[1].startswith('sendall') + decoded_file_id = file_id + if not is_sendall: + try: + raw = base64.urlsafe_b64decode(file_id + "=" * (-len(file_id) % 4)) + sep = raw.find(b"_") + if sep != -1: + decoded_file_id = raw[sep + 1:].decode("latin1") + except Exception: + pass + + filesarr = [] - if message.command[1].startswith('sendall'): - message.command[1] = f"allfiles_{grp_id}_{file_id}" + if is_sendall: + files = temp.GETALL.get(file_id) + if not files: + await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ !') + return + for file in files: + file_id_item = file.file_id + files_ = await get_file_details(file_id_item) + if not files_: + continue + files1 = files_[0] + title = clean_filename(files1.file_name) + cover = files1.cover + size = get_size(files1.file_size) + f_caption = files1.caption + + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION if settings else CUSTOM_FILE_CAPTION + if DREAMX_CAPTION: + try: + f_caption = DREAMX_CAPTION.format(file_name='' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) + except Exception as e: + logger.exception(e) + + if f_caption is None: + f_caption = f"{clean_filename(files1.file_name)}" + + sent_msg = await client.send_cached_media( + chat_id=message.from_user.id, + cover=cover, + file_id=file_id_item, + caption=f_caption, + protect_content=settings.get('file_secure', PROTECT_CONTENT) if settings else PROTECT_CONTENT if settings else PROTECT_CONTENT + ) + filesarr.append(sent_msg) else: - message.command[1] = f"file_{grp_id}_{file_id}" - + files_ = await get_file_details(decoded_file_id) + if not files_: + await message.reply('ɴᴏ ꜱᴜᴄʜ ꜰɪʟᴇ ᴇxɪꜱᴛꜱ !') + return + files1 = files_[0] + title = clean_filename(files1.file_name) + size = get_size(files1.file_size) + cover = files1.cover if files1.cover else None + f_caption = files1.caption + + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION + if DREAMX_CAPTION: + try: + f_caption = DREAMX_CAPTION.format(file_name='' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) + except Exception as e: + logger.exception(e) + + if f_caption is None: + f_caption = clean_filename(files1.file_name) + + sent_msg = await client.send_cached_media( + chat_id=message.from_user.id, + file_id=decoded_file_id, + cover=cover, + caption=f_caption, + protect_content=settings.get('file_secure', PROTECT_CONTENT), + reply_markup=InlineKeyboardMarkup(btn) + ) + filesarr.append(sent_msg) + + # Auto-Delete Logic + if settings and settings.get('auto_delete', True) and filesarr: + k = await client.send_message(chat_id=message.from_user.id, text=script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) + + async def _delete_files(msgs, notif_msg, delay): + await asyncio.sleep(delay) + for x in msgs: + try: + await x.delete() + except Exception: + pass + try: + await notif_msg.edit_text("ʏᴏᴜʀ ᴠɪᴅᴇᴏꜱ/ꜰɪʟᴇꜱ ᴀʀᴇ ᴅᴇʟᴇᴛᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ !\nᴋɪɴᴅʟʏ ꜱᴇᴀʀᴄʜ ᴀɢᴀɪɴ") + except Exception: + pass + + asyncio.create_task(_delete_files(filesarr, k, DELETE_TIME)) + + return if message.chat.type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: buttons = [[ - InlineKeyboardButton('❤️ ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ ❤️', url=f'http://t.me/{temp.U_NAME}?startgroup=true') + InlineKeyboardButton('❤ ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ ❤', url=f'http://t.me/{temp.U_NAME}?startgroup=true') ],[ InlineKeyboardButton('🍁 Update Channel 🍁', url=UPDATE_CHNL_LNK) ]] @@ -184,7 +291,7 @@ async def _delete_msg(msg_to_delete, delay): try: user_id = int(message.command[1].split("_")[1]) except ValueError: - await message.reply_text("‼️ ɪɴᴠᴀʟɪᴅ ʀᴇꜰᴇʀ!") + await message.reply_text("‼ ɪɴᴠᴀʟɪᴅ ʀᴇꜰᴇʀ!") return if user_id == message.from_user.id: await message.reply_text(script.REFER_SELF_ALRT) @@ -281,7 +388,7 @@ async def _delete_msg(msg_to_delete, delay): if len(message.command) > 1 and "_" in message.command[1]: kk, file_id = message.command[1].split("_", 1) btn.append([ - InlineKeyboardButton("♻️ ᴛʀʏ ᴀɢᴀɪɴ ♻️", callback_data=f"checksub#{kk}#{file_id}") + InlineKeyboardButton("♻ ᴛʀʏ ᴀɢᴀɪɴ ♻", callback_data=f"checksub#{kk}#{file_id}") ]) reply_markup = InlineKeyboardMarkup(btn) photo = random.choice(FSUB_PICS) if FSUB_PICS else "https://graph.org/file/7478ff3eac37f4329c3d8.jpg" @@ -319,9 +426,9 @@ async def _delete_msg(msg_to_delete, delay): else: howtodownload = settings.get('tutorial_2', TUTORIAL_2) if is_second_shortener else settings.get('tutorial', TUTORIAL) buttons = [[ - InlineKeyboardButton(text="♻️ ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ᴠᴇʀɪꜰʏ ♻️", url=verify) + InlineKeyboardButton(text="♻ ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ᴠᴇʀɪꜰʏ ♻", url=verify) ],[ - InlineKeyboardButton(text="⁉️ ʜᴏᴡ ᴛᴏ ᴠᴇʀɪꜰʏ ⁉️", url=howtodownload) + InlineKeyboardButton(text="⁉ ʜᴏᴡ ᴛᴏ ᴠᴇʀɪꜰʏ ⁉", url=howtodownload) ]] reply_markup=InlineKeyboardMarkup(buttons) if await db.user_verified(user_id): @@ -359,7 +466,7 @@ async def _delete_msg(msg_to_delete, delay): size = get_size(files1.file_size) f_caption = files1.caption settings = await get_settings(int(grp_id)) - DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION if settings else CUSTOM_FILE_CAPTION if DREAMX_CAPTION: try: f_caption=DREAMX_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) @@ -374,7 +481,7 @@ async def _delete_msg(msg_to_delete, delay): cover=cover, file_id=file_id, caption=f_caption, - protect_content=settings.get('file_secure', PROTECT_CONTENT), + protect_content=settings.get('file_secure', PROTECT_CONTENT) if settings else PROTECT_CONTENT, reply_markup=InlineKeyboardMarkup(btn) ) filesarr.append(msg) @@ -411,13 +518,14 @@ async def _delete_msg(msg_to_delete, delay): size=get_size(file.file_size) f_caption = f"{title}" settings = await get_settings(int(grp_id)) - DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) + DREAMX_CAPTION = settings.get('caption', CUSTOM_FILE_CAPTION) if settings else CUSTOM_FILE_CAPTION if DREAMX_CAPTION: try: f_caption=DREAMX_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='') except Exception: return await msg.edit_caption(f_caption, reply_markup=InlineKeyboardMarkup(btn)) + # FIXED: removed k = await msg.reply(script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) await asyncio.sleep(DELETE_TIME) await msg.delete() @@ -466,7 +574,27 @@ async def _delete_msg(msg_to_delete, delay): pass async def stream_buttons(user_id: int, file_id: str): - return [[InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)]] + if STREAM_MODE and not PREMIUM_STREAM_MODE: + return [ + [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], + [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], + [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] + ] + elif STREAM_MODE and PREMIUM_STREAM_MODE: + if not await db.has_premium_access(user_id): + return [ + [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data='prestream')], + [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data='prestream')], + [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] + ] + else: + return [ + [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], + [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], + [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] + ] + else: + return [[InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)]] @Client.on_message(filters.command('logs') & filters.user(ADMINS)) async def log_file(bot, message): @@ -500,7 +628,7 @@ async def save_file_handler(bot, message): if success: await msg.edit('Fɪʟᴇ ɪs sᴜᴄᴄᴇssғᴜʟʟʏ sᴀᴠᴇᴅ ᴛᴏ ᴅᴀᴛᴀʙᴀsᴇ ✅') elif status == 0: - await msg.edit('Fɪʟᴇ ᴀʟʀᴇᴀᴅʏ ᴇxɪsᴛs ɪɴ ᴅᴀᴛᴀʙᴀsᴇ ⚠️') + await msg.edit('Fɪʟᴇ ᴀʟʀᴇᴀᴅʏ ᴇxɪsᴛs ɪɴ ᴅᴀᴛᴀʙᴀsᴇ ⚠') elif status == 2: await msg.edit('Eʀʀᴏʀ: Fɪʟᴇ ᴠᴀʟɪᴅᴀᴛɪᴏɴ ғᴀɪʟᴇᴅ ❌') else: @@ -583,7 +711,7 @@ async def delete_all_index(bot, message): [ [ InlineKeyboardButton( - text="⚠️ ʏᴇꜱ ⚠️", callback_data="autofilter_delete" + text="⚠ ʏᴇꜱ ⚠", callback_data="autofilter_delete" ) ], [ @@ -612,7 +740,7 @@ async def settings(client, message): InlineKeyboardButton("👥 ᴏᴘᴇɴ ʜᴇʀᴇ 👥", callback_data=f"opnsetgrp#{grp_id}") ]] await message.reply_text( - text="ᴡʜᴇʀᴇ ᴅᴏ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴏᴘᴇɴ ꜱᴇᴛᴛɪɴɢꜱ ᴍᴇɴᴜ ? ⚙️", + text="ᴡʜᴇʀᴇ ᴅᴏ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴏᴘᴇɴ ꜱᴇᴛᴛɪɴɢꜱ ᴍᴇɴᴜ ? ⚙", reply_markup=InlineKeyboardMarkup(btn), link_preview_options=LinkPreviewOptions(is_disabled=True), parse_mode=enums.ParseMode.HTML @@ -629,7 +757,7 @@ async def settings(client, message): except Exception: pass await message.reply_text( - "⚠️ ꜱᴇʟᴇᴄᴛ ᴛʜᴇ ɢʀᴏᴜᴘ ᴡʜᴏꜱᴇ ꜱᴇᴛᴛɪɴɢꜱ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʜᴀɴɢᴇ.\n\n" + "⚠ ꜱᴇʟᴇᴄᴛ ᴛʜᴇ ɢʀᴏᴜᴘ ᴡʜᴏꜱᴇ ꜱᴇᴛᴛɪɴɢꜱ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʜᴀɴɢᴇ.\n\n" "ɪꜰ ʏᴏᴜʀ ɢʀᴏᴜᴘ ɪꜱ ɴᴏᴛ ꜱʜᴏᴡɪɴɢ ʜᴇʀᴇ,\n" "ᴜꜱᴇ /reload ɪɴ ᴛʜᴀᴛ ɢʀᴏᴜᴘ ᴀɴᴅ ɪᴛ ᴡɪʟʟ ᴀᴘᴘᴇᴀʀ ʜᴇʀᴇ.", reply_markup=InlineKeyboardMarkup(group_list) @@ -664,7 +792,7 @@ async def save_template(client, message): return await message.reply("ʏᴏᴜ'ʀᴇ ᴀɴᴏɴʏᴍᴏᴜꜱ ᴀᴅᴍɪɴ.") if message.chat.type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: - return await sts.edit("⚠️ ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ɪɴ ᴀ ɢʀᴏᴜᴘ ᴄʜᴀᴛ.") + return await sts.edit("⚠ ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ɪɴ ᴀ ɢʀᴏᴜᴘ ᴄʜᴀᴛ.") group_id = message.chat.id title = message.chat.title @@ -672,7 +800,7 @@ async def save_template(client, message): await message.reply_text(script.NT_ADMIN_ALRT_TXT) return if len(message.command) < 2: - return await sts.edit("⚠️ ɴᴏ ᴛᴇᴍᴘʟᴀᴛᴇ ᴘʀᴏᴠɪᴅᴇᴅ!") + return await sts.edit("⚠ ɴᴏ ᴛᴇᴍᴘʟᴀᴛᴇ ᴘʀᴏᴠɪᴅᴇᴅ!") template = message.text.split(" ", 1)[1] await save_group_settings(group_id, 'template', template) @@ -686,7 +814,7 @@ async def requests(bot, message): if message.chat.id != SUPPORT_CHAT_ID: return if not message.from_user: - return await message.reply_text("⚠️ ᴜɴᴀʙʟᴇ ᴛᴏ ɪᴅᴇɴᴛɪꜰʏ ʏᴏᴜ.") + return await message.reply_text("⚠ ᴜɴᴀʙʟᴇ ᴛᴏ ɪᴅᴇɴᴛɪꜰʏ ʏᴏᴜ.") reporter = str(message.from_user.id) mention = message.from_user.mention @@ -711,7 +839,7 @@ async def requests(bot, message): InlineKeyboardButton('ꜱʜᴏᴡ ᴏᴘᴛɪᴏɴꜱ', callback_data=f'show_option#{reporter}') ]] req_text = f"📝 ʀᴇǫᴜᴇꜱᴛ : {content}\n\n📚 ʀᴇᴘᴏʀᴛᴇᴅ ʙʏ : {mention}\n📖 ʀᴇᴘᴏʀᴛᴇʀ ɪᴅ : {reporter}\n\n" - warning_text = "⚠️ ʀᴇǫᴜᴇꜱᴛ ᴄʜᴀɴɴᴇʟ ɪꜱ ɴᴏᴛ ꜱᴇᴛ." + warning_text = "⚠ ʀᴇǫᴜᴇꜱᴛ ᴄʜᴀɴɴᴇʟ ɪꜱ ɴᴏᴛ ꜱᴇᴛ." if REQST_CHANNEL is not None: try: reported_post = await bot.send_message(chat_id=REQST_CHANNEL, text=req_text, reply_markup=InlineKeyboardMarkup(btn)) @@ -725,7 +853,7 @@ async def requests(bot, message): reported_post = await bot.send_message(chat_id=admin, text=req_text, reply_markup=InlineKeyboardMarkup(btn)) except Exception: logger.exception("Request failed") - return await message.reply_text( "⚠️ ꜱᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ. ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ.") + return await message.reply_text( "⚠ ꜱᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ. ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ.") if reported_post and REQST_CHANNEL is not None: try: @@ -748,7 +876,7 @@ async def requests(bot, message): await message.reply_text("ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ʜᴀꜱ ʙᴇᴇɴ ᴀᴅᴅᴇᴅ! ᴘʟᴇᴀꜱᴇ ᴡᴀɪᴛ ꜰᴏʀ ꜱᴏᴍᴇ ᴛɪᴍᴇ.") except Exception: logger.exception("Failed to send request confirmation") - await message.reply_text("⚠️ ꜱᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ. ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ.") + await message.reply_text("⚠ ꜱᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ. ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ.") @Client.on_message(filters.command("send") & filters.user(ADMINS)) async def send_msg(bot, message): @@ -796,7 +924,7 @@ async def deletemultiplefiles(bot, message): return await k.delete() btn = [[ - InlineKeyboardButton("⚠️ Yes, Continue ! ⚠️", callback_data=f"killfilesdq#{keyword}") + InlineKeyboardButton("⚠ Yes, Continue ! ⚠", callback_data=f"killfilesdq#{keyword}") ],[ InlineKeyboardButton("❌ No, Abort operation ! ❌", callback_data="close_data") ]] @@ -904,7 +1032,7 @@ def is_alphanumeric(string): return formatted_list = "\n".join([f"{i+1}. {msg}" for i, msg in enumerate(truncated_messages)]) additional_message = ( - "⚡️ 𝑨𝒍𝒍 𝒕𝒉𝒆 𝒓𝒆𝒔𝒖𝒍𝒕𝒔 𝒂𝒃𝒐𝒗𝒆 𝒄𝒐𝒎𝒆 𝒇𝒓𝒐𝒎 𝒘𝒉𝒂𝒕 𝒖𝒔𝒆𝒓𝒔 𝒉𝒂𝒗𝒆 𝒔𝒆𝒂𝒓𝒄𝒉𝒆𝒅 𝒇𝒐𝒓. " + "⚡ 𝑨𝒍𝒍 𝒕𝒉𝒆 𝒓𝒆𝒔𝒖𝒍𝒕𝒔 𝒂𝒃𝒐𝒗𝒆 𝒄𝒐𝒎𝒆 𝒇𝒓𝒐𝒎 𝒘𝒉𝒂𝒕 𝒖𝒔𝒆𝒓𝒔 𝒉𝒂𝒗𝒆 𝒔𝒆𝒂𝒓𝒄𝒉𝒆𝒅 𝒇𝒐𝒓. " "𝑻𝒉𝒆𝒚'𝒓𝒆 𝒔𝒉𝒐𝒘𝒏 𝒕𝒐 𝒚𝒐𝒖 𝒆𝒙𝒂𝒄𝒕𝒍𝒚 𝒂𝒔 𝒕𝒉𝒆𝒚 𝒘𝒆𝒓𝒆 𝒔𝒆𝒂𝒓𝒄𝒉𝒆𝒅, " "𝒘𝒊𝒕𝒉𝒐𝒖𝒕 𝒂𝒏𝒚 𝒄𝒉𝒂𝒏𝒈𝒆𝒔 𝒃𝒚 𝒕𝒉𝒆 𝒐𝒘𝒏𝒆𝒓." ) @@ -966,7 +1094,7 @@ async def del_msg(client, message): InlineKeyboardButton("No", callback_data="confirm_del_no") ]]) sent_message = await message.reply_text( - "⚠️ Aʀᴇ ʏᴏᴜ sᴜʀᴇ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʟᴇᴀʀ ᴛʜᴇ ᴜᴘᴅᴀᴛᴇs ᴄʜᴀɴɴᴇʟ ʟɪsᴛ ?\n\n ᴅᴏ ʏᴏᴜ ꜱᴛɪʟʟ ᴡᴀɴᴛ ᴛᴏ ᴄᴏɴᴛɪɴᴜᴇ ?", + "⚠ Aʀᴇ ʏᴏᴜ sᴜʀᴇ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴄʟᴇᴀʀ ᴛʜᴇ ᴜᴘᴅᴀᴛᴇs ᴄʜᴀɴɴᴇʟ ʟɪsᴛ ?\n\n ᴅᴏ ʏᴏᴜ ꜱᴛɪʟʟ ᴡᴀɴᴛ ᴛᴏ ᴄᴏɴᴛɪɴᴜᴇ ?", reply_markup=confirm_markup ) await asyncio.sleep(60) @@ -1053,7 +1181,7 @@ async def handle_shortner_command(c, m, shortner_key, api_key, log_prefix, fallb return await m.reply( f"ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ʟɪᴋᴇ -\n\n`/{m.command[0]} your-shortener-domain.com your_api_key_here`" ) - sts = await m.reply("♻️ ᴄʜᴇᴄᴋɪɴɢ...") + sts = await m.reply("♻ ᴄʜᴇᴄᴋɪɴɢ...") await asyncio.sleep(1.2) await sts.delete() if m.chat.type not in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: @@ -1109,7 +1237,7 @@ async def set_log(client, message): if len(message.text.split()) == 1: await message.reply("ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ʟɪᴋᴇ ᴛʜɪꜱ - \n\n`/set_log_channel -100******`") return - sts = await message.reply("♻️ ᴄʜᴇᴄᴋɪɴɢ...") + sts = await message.reply("♻ ᴄʜᴇᴄᴋɪɴɢ...") await asyncio.sleep(1.2) await sts.delete() chat_type = message.chat.type @@ -1184,10 +1312,10 @@ async def all_settings(client, message): try: settings = await get_settings(grp_id) except Exception as e: - return await message.reply_text(f"⚠️ ᴇʀʀᴏʀ ꜰᴇᴛᴄʜɪɴɢ ꜱᴇᴛᴛɪɴɢꜱ:\n{e}") + return await message.reply_text(f"⚠ ᴇʀʀᴏʀ ꜰᴇᴛᴄʜɪɴɢ ꜱᴇᴛᴛɪɴɢꜱ:\n{e}") text = generate_settings_text(settings, title) btn = [ - [InlineKeyboardButton("♻️ ʀᴇꜱᴇᴛ ꜱᴇᴛᴛɪɴɢꜱ", callback_data=f"reset_group_{grp_id}")], + [InlineKeyboardButton("♻ ʀᴇꜱᴇᴛ ꜱᴇᴛᴛɪɴɢꜱ", callback_data=f"reset_group_{grp_id}")], [InlineKeyboardButton("🚫 ᴄʟᴏꜱᴇ", callback_data="close_data")] ] dlt = await message.reply_text(text, reply_markup=InlineKeyboardMarkup(btn), link_preview_options=LinkPreviewOptions(is_disabled=True)) @@ -1200,7 +1328,7 @@ async def reset_group_callback(client, callback_query): user_id = callback_query.from_user.id if not await is_check_admin(client, grp_id, user_id): return await callback_query.answer(script.NT_ADMIN_ALRT_TXT, show_alert=True) - await callback_query.answer("♻️ ʀᴇꜱᴇᴛᴛɪɴɢ ꜱᴇᴛᴛɪɴɢꜱ...") + await callback_query.answer("♻ ʀᴇꜱᴇᴛᴛɪɴɢ ꜱᴇᴛᴛɪɴɢꜱ...") defaults = { 'shortner': SHORTENER_WEBSITE, 'api': SHORTENER_API, @@ -1231,7 +1359,7 @@ async def reset_group_callback(client, callback_query): title = callback_query.message.chat.title text = generate_settings_text(updated, title, reset_done=True) buttons = [ - [InlineKeyboardButton("♻️ ʀᴇꜱᴇᴛ ꜱᴇᴛᴛɪɴɢꜱ", callback_data=f"reset_group_{grp_id}")], + [InlineKeyboardButton("♻ ʀᴇꜱᴇᴛ ꜱᴇᴛᴛɪɴɢꜱ", callback_data=f"reset_group_{grp_id}")], [InlineKeyboardButton("🚫 ᴄʟᴏꜱᴇ", callback_data="close_data")] ] await callback_query.message.edit_text(text, reply_markup=InlineKeyboardMarkup(buttons), link_preview_options=LinkPreviewOptions(is_disabled=True)) @@ -1305,7 +1433,7 @@ async def set_fsub(client, message): f"ꜰꜱᴜʙ ᴄʜᴀɴɴᴇʟ(ꜱ):\n" + '\n'.join(channel_titles) ) except Exception as e: - err_text = f"⚠️ Error in set_fSub :\n{e}" + err_text = f"⚠ Error in set_fSub :\n{e}" logger.error(err_text) await client.send_message(LOG_CHANNEL, err_text) @@ -1401,7 +1529,7 @@ async def remove_fsub(client, message): ) except Exception as e: logger.error("remove_fsub: %s", e) - await message.reply_text(f"⚠️ ᴀɴ ᴇʀʀᴏʀ ᴏᴄᴄᴜʀʀᴇᴅ: {e}") + await message.reply_text(f"⚠ ᴀɴ ᴇʀʀᴏʀ ᴏᴄᴄᴜʀʀᴇᴅ: {e}") @Client.on_message(filters.command('clean_groups') & filters.user(ADMINS)) async def clean_groups_handler(client, message): From b22084293897b35d7581e77630f7d3e99bb3f7bd Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Tue, 15 Sep 2026 08:06:40 +0530 Subject: [PATCH 33/77] Refactor stream_buttons function to simplify logic --- plugins/commands.py | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/plugins/commands.py b/plugins/commands.py index e9163d79..ae911812 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -574,27 +574,7 @@ async def _delete_files(msgs, notif_msg, delay): pass async def stream_buttons(user_id: int, file_id: str): - if STREAM_MODE and not PREMIUM_STREAM_MODE: - return [ - [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], - [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], - [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] - ] - elif STREAM_MODE and PREMIUM_STREAM_MODE: - if not await db.has_premium_access(user_id): - return [ - [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data='prestream')], - [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data='prestream')], - [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] - ] - else: - return [ - [InlineKeyboardButton('🚀 ꜰᴀꜱᴛ ᴅᴏᴡɴʟᴏᴀᴅ / ᴡᴀᴛᴄʜ ᴏɴʟɪɴᴇ 🖥', callback_data=f'generate_stream_link:{file_id}')], - [InlineKeyboardButton('ℹ ᴠɪᴇᴡ ᴀᴜᴅɪᴏ & ꜱᴜʙꜱ ɪɴꜰᴏ ℹ', callback_data=f'extract_data:{file_id}')], - [InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)] - ] - else: - return [[InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)]] + return [[InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)]] @Client.on_message(filters.command('logs') & filters.user(ADMINS)) async def log_file(bot, message): From 18f444be0c68e2a7ba01fb81cce28fe1a34582a6 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Tue, 15 Sep 2026 08:29:17 +0530 Subject: [PATCH 34/77] Update commands.py --- plugins/commands.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/commands.py b/plugins/commands.py index ae911812..f449b056 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -85,7 +85,7 @@ async def start(client, message): InlineKeyboardButton("🫶🏻 Cʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ɢᴇᴛ ғɪʟᴇ 🕊", url=verifiedfiles), ]] dlt = await m.reply_photo( - photo="https://i.ibb.co/1tDXygyb/image.webp", + photo="https://i.ibb.co/wrB2JMjG/movie-poster-verification-banner.jpg", caption=msg.format(m.from_user.mention), reply_markup=InlineKeyboardMarkup(btn_complete), parse_mode=enums.ParseMode.HTML @@ -1550,3 +1550,6 @@ async def clean_groups_handler(client, message): except Exception as e: logger.error("Error in clean_groups loop: %s", e) await msg.edit(f'**Clean Groups Complete**\n\nTotal Processed: {processed}\nDeleted: {deleted_count}') + + + From 4ea9baea4aad518c74490e439b706ba8375534d4 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Tue, 15 Sep 2026 10:15:22 +0530 Subject: [PATCH 35/77] Update photo URL in reply_photo method --- plugins/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/commands.py b/plugins/commands.py index f449b056..848e1552 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -85,7 +85,7 @@ async def start(client, message): InlineKeyboardButton("🫶🏻 Cʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ɢᴇᴛ ғɪʟᴇ 🕊", url=verifiedfiles), ]] dlt = await m.reply_photo( - photo="https://i.ibb.co/wrB2JMjG/movie-poster-verification-banner.jpg", + photo="https://i.ibb.co/RkXnCM07/Chat-GPT-Image-Sep-15-2026-10-11-43-AM.jpg", caption=msg.format(m.from_user.mention), reply_markup=InlineKeyboardMarkup(btn_complete), parse_mode=enums.ParseMode.HTML From e5240558d0db6c4f4afc2a1aba0a67ffe128a6c4 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Tue, 15 Sep 2026 11:09:48 +0530 Subject: [PATCH 36/77] Update Script.py --- Script.py | 55 ++++++++++++++++++++++++------------------------------- 1 file changed, 24 insertions(+), 31 deletions(-) diff --git a/Script.py b/Script.py index 1796bd80..881138f7 100644 --- a/Script.py +++ b/Script.py @@ -299,12 +299,13 @@ class script(object): ʀᴇǫ ʙʏ : {message.from_user.mention}""" LOGO = r""" - ██████╗░██████╗░███████╗░█████╗░███╗░░░███╗██╗░░██╗██████╗░░█████╗░████████╗███████╗ - ██╔══██╗██╔══██╗██╔════╝██╔══██╗████╗░████║╚██╗██╔╝██╔══██╗██╔══██╗╚══██╔══╝╚════██║ - ██║░░██║██████╔╝█████╗░░███████║██╔████╔██║░╚███╔╝░██████╦╝██║░░██║░░░██║░░░░░███╔═╝ - ██║░░██║██╔══██╗██╔══╝░░██╔══██║██║╚██╔╝██║░██╔██╗░██╔══██╗██║░░██║░░░██║░░░██╔══╝░░ - ██████╔╝██║░░██║███████╗██║░░██║██║░╚═╝░██║██╔╝╚██╗██████╦╝╚█████╔╝░░░██║░░░███████╗ - ╚═════╝░╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░░░░╚═╝╚═╝░░╚═╝╚═════╝░░╚════╝░░░░╚═╝░░░╚══════╝ +.______ ______ __ __ __ .___________. _______ __ __ ___ ___ +| _ \ / __ \ | | | | | | | | | ____|| | | | \ \ / / +| |_) | | | | | | | | | | | `---| |----` | |__ | | | | \ V / +| _ < | | | | | | | | | | | | | __| | | | | > < +| |_) | | `--' | | `--' | | `----. | | | | | `----.| | / . \ +|______/ \______/ \______/ |_______| |__| |__| |_______||__| /__/ \__\ + 𝙱𝙾𝚃 𝚆𝙾𝚁𝙺𝙸𝙽𝙶 𝙿𝚁𝙾𝙿𝙴𝚁𝙻𝚈.... """ @@ -324,7 +325,6 @@ class script(object): ◉ 60 ᴅᴀʏꜱ - 75 ₹ / 75 ꜱᴛᴀʀ •─────•─────────•─────• -🏷️ ꜱᴜʙꜱᴄʀɪᴘᴛɪᴏɴ ᴘʀᴏᴏꜰ ‼️ ᴍᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. ‼️ ᴀꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇꜱ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" @@ -333,7 +333,7 @@ class script(object): ɴᴏᴡ ʏᴏᴜ ᴄᴀɴ ʙᴜʏ ᴏᴜʀ ᴘʀᴇᴍɪᴜᴍ ꜱᴇʀᴠɪᴄᴇ ᴜꜱɪɴɢ ᴛᴇʟᴇɢʀᴀᴍ ꜱᴛᴀʀꜱ. -ɪꜰ ʏᴏᴜ ꜰᴀᴄᴇ ᴀɴʏ ᴘʀᴏʙʟᴇᴍ, ᴛᴀᴋᴇ ᴀ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀɴᴅ ꜱᴇɴᴅ ɪᴛ ᴛᴏ - @deendayal_Support_group +ɪꜰ ʏᴏᴜ ꜰᴀᴄᴇ ᴀɴʏ ᴘʀᴏʙʟᴇᴍ, ᴛᴀᴋᴇ ᴀ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀɴᴅ ꜱᴇɴᴅ ɪᴛ ᴛᴏ - @BoultflixSupportBot ꜱᴇʟᴇᴄᴛ ʏᴏᴜʀ ᴅᴇꜱɪʀᴇᴅ ᴀᴍᴏᴜɴᴛ ᴀɴᴅ ᴘᴜʀᴄʜᴀꜱᴇ ᴀ ꜱᴜʙꜱᴄʀɪᴘᴛɪᴏɴ 👇. """ @@ -342,7 +342,7 @@ class script(object): ʏᴏᴜ ᴄᴀɴ ᴘᴜʀᴄʜᴀꜱᴇ ᴘʀᴇᴍɪᴜᴍ ᴛʜʀᴏᴜɢʜ ᴜᴘɪ , ɴᴇᴛ ʙᴀɴᴋɪɴɢ. -💳 ᴜᴘɪ ɪᴅ - {} +💳 ᴜᴘɪ ɪᴅ - {myself.anish@fam} 💢 ᴍᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. @@ -395,7 +395,7 @@ class script(object): 🏷️ ᴘᴀʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅꜱ -💸 ᴜᴘɪ ɪᴅ → {} +💸 ᴜᴘɪ ɪᴅ → {myself.anish@fam} 📷 ǫʀ ᴄᴏᴅᴇ → ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ꜱᴄᴀɴ 🧾 ᴘᴀʏ ᴀᴄᴄᴏʀᴅɪɴɢ ᴛᴏ ʏᴏᴜʀ ᴘʟᴀɴ ᴀɴᴅ ᴇɴᴊᴏʏ ᴘʀᴇᴍɪᴜᴍ! @@ -407,56 +407,49 @@ class script(object): - - SOURCE_TXT ="""ՏOᑌᖇᑕᗴ ᑕOᗪᗴ : 👇 - -This Is An Open-Source Project. You Can Use It Freely, But Selling The Source Code Is Strictly Prohibited.\n -ꜱᴏᴜʀᴄᴇ ᴄᴏᴅᴇ ʜᴇʀᴇ ◉› :𝓓𝓻𝓮𝓪𝓶𝔁𝓑𝓸𝓽𝔃\n """ - - - VERIFICATION_TEXT = """👋 ʜᴇʏ {}, + VERIFICATION_TEXT = """👋 Hᴇʏ {}, -📌 ʏᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ᴛᴏᴅᴀʏ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ꜰᴏʀ ᴛɪʟʟ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. +📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ꜰᴏʀ ᴛɪʟʟ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. -#ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 1/3 ✓ +#Vᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 1/3 ✓ -ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴅɪʀᴇᴄᴛ ꜰɪʟᴇs ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ᴛᴀᴋᴇ ᴘʀᴇᴍɪᴜᴍ sᴇʀᴠɪᴄᴇ (ɴᴏ ɴᴇᴇᴅ ᴛᴏ ᴠᴇʀɪꜰʏ).""" +Iꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴅɪʀᴇᴄᴛ ꜰɪʟᴇs ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ᴛᴀᴋᴇ ᴘʀᴇᴍɪᴜᴍ sᴇʀᴠɪᴄᴇ (ɴᴏ ɴᴇᴇᴅ ᴛᴏ ᴠᴇʀɪꜰʏ).""" VERIFY_COMPLETE_TEXT = """👋 Hᴇʏ {} ❤, Yᴏᴜ ʜᴀᴠᴇ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ᴛʜᴇ 1sᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ ✅ -Nᴏᴡ ʏᴏᴜ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ғᴏʀ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ.""" +Nᴏᴡ ʏᴏᴜ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ᴛɪʟʟ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ.""" - SECOND_VERIFICATION_TEXT = """👋 ʜᴇʏ {}, + SECOND_VERIFICATION_TEXT = """👋 ʜᴇʏ {}, -📌 ʏᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ, ᴛᴀᴘ ᴏɴ ᴛʜᴇ ᴠᴇʀɪꜰʏ ʟɪɴᴋ ᴀɴᴅ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ꜰᴏʀ ᴛɪʟʟ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ. +📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ꜰᴏʀ ᴛɪʟʟ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. -#ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 2/3 ✓ +#Vᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 2/3 ✓ -ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴅɪʀᴇᴄᴛ ꜰɪʟᴇs ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ᴛᴀᴋᴇ ᴘʀᴇᴍɪᴜᴍ sᴇʀᴠɪᴄᴇ (ɴᴏ ɴᴇᴇᴅ ᴛᴏ ᴠᴇʀɪꜰʏ).""" +Iꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴅɪʀᴇᴄᴛ ꜰɪʟᴇs ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ᴛᴀᴋᴇ ᴘʀᴇᴍɪᴜᴍ sᴇʀᴠɪᴄᴇ (ɴᴏ ɴᴇᴇᴅ ᴛᴏ ᴠᴇʀɪꜰʏ).""" SECOND_VERIFY_COMPLETE_TEXT = """👋 Hᴇʏ {} ❤, Yᴏᴜ ʜᴀᴠᴇ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ᴛʜᴇ 2ɴᴅ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ ✅ -Nᴏᴡ ʏᴏᴜ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ғᴏʀ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ.""" +Nᴏᴡ ʏᴏᴜ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ᴛɪʟʟ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ.""" THIRDT_VERIFICATION_TEXT = """👋 ʜᴇʏ {}, -📌 ʏᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ, ᴛᴀᴘ ᴏɴ ᴛʜᴇ ᴠᴇʀɪꜰʏ ʟɪɴᴋ & ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ꜰᴏʀ ɴᴇxᴛ ꜰᴜʟʟ ᴅᴀʏ. +📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ꜰᴏʀ ᴛɪʟʟ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. -#ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 3/3 ✓ +#Vᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 3/3 ✓ -ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴅɪʀᴇᴄᴛ ꜰɪʟᴇs ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ᴛᴀᴋᴇ ᴘʀᴇᴍɪᴜᴍ sᴇʀᴠɪᴄᴇ (ɴᴏ ɴᴇᴇᴅ ᴛᴏ ᴠᴇʀɪꜰʏ)""" +Iꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴅɪʀᴇᴄᴛ ꜰɪʟᴇs ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ᴛᴀᴋᴇ ᴘʀᴇᴍɪᴜᴍ sᴇʀᴠɪᴄᴇ (ɴᴏ ɴᴇᴇᴅ ᴛᴏ ᴠᴇʀɪꜰʏ)""" THIRDT_VERIFY_COMPLETE_TEXT = """👋 Hᴇʏ {} ❤, Yᴏᴜ ʜᴀᴠᴇ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ᴛʜᴇ 3ʀᴅ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ ✅ -Nᴏᴡ ʏᴏᴜ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ғᴏʀ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ.""" +Nᴏᴡ ʏᴏᴜ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ᴛɪʟʟ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ.""" VERIFIED_LOG_TEXT = """ᴜꜱᴇʀ ᴠᴇʀɪꜰɪᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ✓ From b167d780b42e1a766c563607e8cd95adb660aad8 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Tue, 15 Sep 2026 11:16:52 +0530 Subject: [PATCH 37/77] Update Script.py --- Script.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Script.py b/Script.py index 881138f7..d6eb1d33 100644 --- a/Script.py +++ b/Script.py @@ -342,7 +342,7 @@ class script(object): ʏᴏᴜ ᴄᴀɴ ᴘᴜʀᴄʜᴀꜱᴇ ᴘʀᴇᴍɪᴜᴍ ᴛʜʀᴏᴜɢʜ ᴜᴘɪ , ɴᴇᴛ ʙᴀɴᴋɪɴɢ. -💳 ᴜᴘɪ ɪᴅ - {myself.anish@fam} +💳 ᴜᴘɪ ɪᴅ - {} 💢 ᴍᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. @@ -395,7 +395,7 @@ class script(object): 🏷️ ᴘᴀʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅꜱ -💸 ᴜᴘɪ ɪᴅ → {myself.anish@fam} +💸 ᴜᴘɪ ɪᴅ → {} 📷 ǫʀ ᴄᴏᴅᴇ → ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ꜱᴄᴀɴ 🧾 ᴘᴀʏ ᴀᴄᴄᴏʀᴅɪɴɢ ᴛᴏ ʏᴏᴜʀ ᴘʟᴀɴ ᴀɴᴅ ᴇɴᴊᴏʏ ᴘʀᴇᴍɪᴜᴍ! From b47cedbb278d97feed3644075ee40915117837bd Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Tue, 15 Sep 2026 20:23:17 +0530 Subject: [PATCH 38/77] Fix button labels and improve formatting --- plugins/commands.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/plugins/commands.py b/plugins/commands.py index 848e1552..c20db736 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -218,13 +218,13 @@ async def _delete_files(msgs, notif_msg, delay): await client.send_message(LOG_CHANNEL, script.LOG_TEXT_P.format(message.from_user.id, message.from_user.mention)) if len(message.command) != 2: buttons = [[ - InlineKeyboardButton('🔰 ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://t.me/{temp.U_NAME}?startgroup=true') + InlineKeyboardButton('🔰 Aᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://t.me/{temp.U_NAME}?startgroup=true') ],[ - InlineKeyboardButton(' ʜᴇʟᴘ 📢', callback_data='help'), - InlineKeyboardButton(' ᴀʙᴏᴜᴛ 📖', callback_data='about') + InlineKeyboardButton(' Hᴇʟᴘ 📢', callback_data='help'), + InlineKeyboardButton(' Aʙᴏᴜᴛ 📖', callback_data='about') ],[ - InlineKeyboardButton('ᴛᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), - InlineKeyboardButton('ᴜᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), + InlineKeyboardButton('Tᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), + InlineKeyboardButton('Uᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), ]] reply_markup = InlineKeyboardMarkup(buttons) current_time = datetime.now(pytz.timezone(TIMEZONE)) @@ -254,13 +254,13 @@ async def _delete_files(msgs, notif_msg, delay): if len(message.command) == 2 and message.command[1] in ["subscribe", "error", "okay", "help"]: buttons = [[ - InlineKeyboardButton('🔰 ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://t.me/{temp.U_NAME}?startgroup=true') + InlineKeyboardButton('🔰 Aᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://t.me/{temp.U_NAME}?startgroup=true') ],[ - InlineKeyboardButton(' ʜᴇʟᴘ 📢', callback_data='help'), - InlineKeyboardButton(' ᴀʙᴏᴜᴛ 📖', callback_data='about') + InlineKeyboardButton(' Hᴇʟᴘ 📢', callback_data='help'), + InlineKeyboardButton(' Aʙᴏᴜᴛ 📖', callback_data='about') ],[ - InlineKeyboardButton('ᴛᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), - InlineKeyboardButton('ᴜᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), + InlineKeyboardButton('Tᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), + InlineKeyboardButton('Uᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), ]] reply_markup = InlineKeyboardMarkup(buttons) current_time = datetime.now(pytz.timezone(TIMEZONE)) @@ -334,8 +334,9 @@ async def _delete_files(msgs, notif_msg, delay): buttons = [[ InlineKeyboardButton('📲 ꜱᴇɴᴅ ᴘᴀʏᴍᴇɴᴛ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ', url=OWNER_LNK) ],[ - InlineKeyboardButton('UPI ID Copy Karein ??', copy_text=OWNER_UPI_ID) + InlineKeyboardButton('📷 Qʀ Cᴏᴅᴇ', url=QR_CODE) ],[ + InlineKeyboardButton('⇋ ʙᴀᴄᴋ ⇋', callback_data='start'), InlineKeyboardButton('❌ ᴄʟᴏꜱᴇ ❌', callback_data='close_data') ]] reply_markup = InlineKeyboardMarkup(buttons) @@ -1553,3 +1554,7 @@ async def clean_groups_handler(client, message): + + + +================================================ From 8c68c03db7af6d5f947bfef564d55452ed6a8817 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Tue, 15 Sep 2026 20:55:44 +0530 Subject: [PATCH 39/77] Update commands.py --- plugins/commands.py | 51 +++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/plugins/commands.py b/plugins/commands.py index c20db736..946b9fd4 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -221,7 +221,7 @@ async def _delete_files(msgs, notif_msg, delay): InlineKeyboardButton('🔰 Aᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://t.me/{temp.U_NAME}?startgroup=true') ],[ InlineKeyboardButton(' Hᴇʟᴘ 📢', callback_data='help'), - InlineKeyboardButton(' Aʙᴏᴜᴛ 📖', callback_data='about') + InlineKeyboardButton(' ᴀʙᴏᴜᴛ 📖', callback_data='about') ],[ InlineKeyboardButton('Tᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), InlineKeyboardButton('Uᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), @@ -230,13 +230,13 @@ async def _delete_files(msgs, notif_msg, delay): current_time = datetime.now(pytz.timezone(TIMEZONE)) curr_time = current_time.hour if curr_time < 12: - gtxt = "ɢᴏᴏᴅ ᴍᴏʀɴɪɴɢ 🌞" + gtxt = "Gᴏᴏᴅ ᴍᴏʀɴɪɴɢ 🌞" elif curr_time < 17: - gtxt = "ɢᴏᴏᴅ ᴀғᴛᴇʀɴᴏᴏɴ 🌓" + gtxt = "Gᴏᴏᴅ ᴀғᴛᴇʀɴᴏᴏɴ 🌓" elif curr_time < 21: - gtxt = "ɢᴏᴏᴅ ᴇᴠᴇɴɪɴɢ 🌘" + gtxt = "Gᴏᴏᴅ ᴇᴠᴇɴɪɴɢ 🌘" else: - gtxt = "ɢᴏᴏᴅ ɴɪɢʜᴛ 🌑" + gtxt = "Gᴏᴏᴅ ɴɪɢʜᴛ 🌑" if len(PICS) == 1: PIC = PICS[0] else: @@ -266,13 +266,13 @@ async def _delete_files(msgs, notif_msg, delay): current_time = datetime.now(pytz.timezone(TIMEZONE)) curr_time = current_time.hour if curr_time < 12: - gtxt = "ɢᴏᴏᴅ ᴍᴏʀɴɪɴɢ 🌞" + gtxt = "Gᴏᴏᴅ ᴍᴏʀɴɪɴɢ 🌞" elif curr_time < 17: - gtxt = "ɢᴏᴏᴅ ᴀғᴛᴇʀɴᴏᴏɴ 🌓" + gtxt = "Gᴏᴏᴅ ᴀғᴛᴇʀɴᴏᴏɴ 🌓" elif curr_time < 21: - gtxt = "ɢᴏᴏᴅ ᴇᴠᴇɴɪɴɢ 🌘" + gtxt = "Gᴏᴏᴅ ᴇᴠᴇɴɪɴɢ 🌘" else: - gtxt = "ɢᴏᴏᴅ ɴɪɢʜᴛ 🌑" + gtxt = "Gᴏᴏᴅ ɴɪɢʜᴛ 🌑" if len(PICS) == 1: PIC = PICS[0] else: @@ -332,12 +332,12 @@ async def _delete_files(msgs, notif_msg, delay): if len(message.command) == 2 and message.command[1] in ["premium"]: buttons = [[ - InlineKeyboardButton('📲 ꜱᴇɴᴅ ᴘᴀʏᴍᴇɴᴛ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ', url=OWNER_LNK) + InlineKeyboardButton('📲 Sᴇɴᴅ ᴘᴀʏᴍᴇɴᴛ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ', url=OWNER_LNK) ],[ InlineKeyboardButton('📷 Qʀ Cᴏᴅᴇ', url=QR_CODE) ],[ - InlineKeyboardButton('⇋ ʙᴀᴄᴋ ⇋', callback_data='start'), - InlineKeyboardButton('❌ ᴄʟᴏꜱᴇ ❌', callback_data='close_data') + InlineKeyboardButton('⇋ Bᴀᴄᴋ ⇋', callback_data='start'), + InlineKeyboardButton('❌ Cʟᴏꜱᴇ ❌', callback_data='close_data') ]] reply_markup = InlineKeyboardMarkup(buttons) await message.reply_photo( @@ -530,7 +530,11 @@ async def _delete_files(msgs, notif_msg, delay): k = await msg.reply(script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) await asyncio.sleep(DELETE_TIME) await msg.delete() - await k.edit_text("ʏᴏᴜʀ ᴠɪᴅᴇᴏ / ꜰɪʟᴇ ɪꜱ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ !!") + await k.edit_text( + "Yᴏᴜʀ ᴠɪᴅᴇᴏ / ꜰɪʟᴇ ɪꜱ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ !!\n" + "Tᴏ ᴘʀᴏᴛᴇᴄᴛ ᴏᴜʀ ʙᴏᴛ ғʀᴏᴍ ᴄᴏᴘʏʀɪɢʜᴛ 🥀\n" + "Iғ ʏᴏᴜ ᴅɪᴅɴ'ᴛ ғᴏʀᴡᴀʀᴅ ɪᴛ ᴀɴʏᴡʜᴇʀᴇ ᴇʟsᴇ, ᴋɪɴᴅʟʏ ʀᴇǫᴜᴇsᴛ ᴛʜᴇ ғɪʟᴇ ᴏɴᴄᴇ ᴀɢᴀɪɴ 🫶🏻🩵" + ) return except Exception as e: logger.exception(e) @@ -566,7 +570,11 @@ async def _delete_files(msgs, notif_msg, delay): k = await msg.reply(script.DEL_MSG.format(get_time(DELETE_TIME)), parse_mode=enums.ParseMode.HTML) await asyncio.sleep(DELETE_TIME) await msg.delete() - await k.edit_text("ʏᴏᴜʀ ᴠɪᴅᴇᴏ / ꜰɪʟᴇ ɪꜱ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ !!") + await k.edit_text( + "Yᴏᴜʀ ᴠɪᴅᴇᴏ / ꜰɪʟᴇ ɪꜱ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ !!\n" + "Tᴏ ᴘʀᴏᴛᴇᴄᴛ ᴏᴜʀ ʙᴏᴛ ғʀᴏᴍ ᴄᴏᴘʏʀɪɢʜᴛ 🥀\n" + "Iғ ʏᴏᴜ ᴅɪᴅɴ'ᴛ ғᴏʀᴡᴀʀᴅ ɪᴛ ᴀɴʏᴡʜᴇʀᴇ ᴇʟsᴇ, ᴋɪɴᴅʟʏ ʀᴇǫᴜᴇsᴛ ᴛʜᴇ ғɪʟᴇ ᴏɴᴄᴇ ᴀɢᴀɪɴ 🫶🏻🩵" + ) return except StopPropagation: raise @@ -575,7 +583,7 @@ async def _delete_files(msgs, notif_msg, delay): pass async def stream_buttons(user_id: int, file_id: str): - return [[InlineKeyboardButton('📌 ᴊᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)]] + return [[InlineKeyboardButton('📌 Jᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)]] @Client.on_message(filters.command('logs') & filters.user(ADMINS)) async def log_file(bot, message): @@ -819,7 +827,7 @@ async def requests(bot, message): InlineKeyboardButton('ᴠɪᴇᴡ ʀᴇǫᴜᴇꜱᴛ', url=msg_link), InlineKeyboardButton('ꜱʜᴏᴡ ᴏᴘᴛɪᴏɴꜱ', callback_data=f'show_option#{reporter}') ]] - req_text = f"📝 ʀᴇǫᴜᴇꜱᴛ : {content}\n\n📚 ʀᴇᴘᴏʀᴛᴇᴅ ʙʏ : {mention}\n📖 ʀᴇᴘᴏʀᴛᴇʀ ɪᴅ : {reporter}\n\n" + req_text = f"📝 ʀᴇǫᴜᴇꜱᴛ : {content}\n\n📚 Rᴇᴘᴏʀᴛᴇᴅ ʙʏ : {mention}\n📖 Rᴇᴘᴏʀᴛᴇʀ ɪᴅ : {reporter}\n\n" warning_text = "⚠ ʀᴇǫᴜᴇꜱᴛ ᴄʜᴀɴɴᴇʟ ɪꜱ ɴᴏᴛ ꜱᴇᴛ." if REQST_CHANNEL is not None: try: @@ -834,7 +842,7 @@ async def requests(bot, message): reported_post = await bot.send_message(chat_id=admin, text=req_text, reply_markup=InlineKeyboardMarkup(btn)) except Exception: logger.exception("Request failed") - return await message.reply_text( "⚠ ꜱᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ. ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ.") + return await message.reply_text( "⚠ Sᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ. ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ.") if reported_post and REQST_CHANNEL is not None: try: @@ -1065,7 +1073,7 @@ async def set_movie_update_notification(client, message): async def stop_button(bot, message): msg = await bot.send_message(text="ʙᴏᴛ ɪꜱ ʀᴇꜱᴛᴀʀᴛɪɴɢ", chat_id=message.chat.id) await asyncio.sleep(3) - await msg.edit("ʙᴏᴛ ɪꜱ ʀᴇꜱᴛᴀʀᴛᴇᴅ ✅") + await msg.edit("Bᴏᴛ ɪꜱ ʀᴇꜱᴛᴀʀᴛᴇᴅ ✅") os.execl(sys.executable, sys.executable, *sys.argv) @Client.on_message(filters.command("del_msg") & filters.user(ADMINS)) @@ -1551,10 +1559,3 @@ async def clean_groups_handler(client, message): except Exception as e: logger.error("Error in clean_groups loop: %s", e) await msg.edit(f'**Clean Groups Complete**\n\nTotal Processed: {processed}\nDeleted: {deleted_count}') - - - - - - -================================================ From 516649e7107070a644ba5bdcaeb8288ce7c5c460 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Tue, 15 Sep 2026 21:27:23 +0530 Subject: [PATCH 40/77] Update info.py --- info.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/info.py b/info.py index e6a5be8f..810b3016 100644 --- a/info.py +++ b/info.py @@ -64,8 +64,8 @@ def is_enabled(value, default): # ============================ # Payment Configuration # ============================ -QR_CODE = environ.get('QR_CODE', 'https://graph.org/file/e419f801841c2ee3db0fc.jpg') # QR code image for payments -OWNER_UPI_ID = environ.get('OWNER_UPI_ID', 'ɴᴏ ᴀᴠᴀɪʟᴀʙʟᴇ ʀɪɢʜᴛ ɴᴏᴡ') # Owner UPI ID for payments +QR_CODE = environ.get('QR_CODE', 'https://i.ibb.co/k2DsfKQs/photo-2026-09-15-16-42-13.jpg') # QR code image for payments +OWNER_UPI_ID = environ.get('OWNER_UPI_ID', 'myself.anish@fam') # Owner UPI ID for payments STAR_PREMIUM_PLANS = { 10: "7day", @@ -102,7 +102,7 @@ def is_enabled(value, default): # ============================ IS_VERIFY = is_enabled(environ.get('IS_VERIFY', 'False'), False) # Verification On (True) / Off (False) LOG_VR_CHANNEL = int(environ.get('LOG_VR_CHANNEL', '-100')) #Verification Channel Id -VERIFY_IMG = environ.get("VERIFY_IMG", "https://telegra.ph/file/9ecc5d6e4df5b83424896.jpg") +VERIFY_IMG = environ.get("VERIFY_IMG", "https://i.ibb.co/RkXnCM07/Chat-GPT-Image-Sep-15-2026-10-11-43-AM.jpg") TUTORIAL = environ.get("TUTORIAL", "https://t.me/dreamxbotz") # Tutorial link for verification TUTORIAL_2 = environ.get("TUTORIAL_2", "https://t.me/dreamxbotz") # Second tutorial link for verification @@ -125,7 +125,7 @@ def is_enabled(value, default): # Channel & Group Links Configuration # ============================ GRP_LNK = environ.get('GRP_LNK', 'https://t.me/dreamxbotz') # Group link for the bot -OWNER_LNK = environ.get('OWNER_LNK', 'https://t.me/dreamxbotz') # Owner link for the bot +OWNER_LNK = environ.get('OWNER_LNK', 'https://t.me/BoultFlixSupportBot') # Owner link for the bot UPDATE_CHNL_LNK = environ.get('UPDATE_CHNL_LNK', 'https://t.me/dreamxbotz') # Update channel link for the bot # ============================ @@ -142,7 +142,7 @@ def is_enabled(value, default): MAX_B_TN = environ.get("MAX_B_TN", "5") # Maximum number of buttons in a row (default: 5) PORT = int(environ.get("PORT", "8080")) # Port for the web server (default: 8080) -MSG_ALRT = environ.get('MSG_ALRT', 'Share & Support Us ♥️') # Alert message for users +MSG_ALRT = environ.get('MSG_ALRT', 'Share & Support Us ♥') # Alert message for users DELETE_TIME = int(environ.get("DELETE_TIME", "300")) # deletion time in seconds (default: 5 minutes). Adjust as per your needs. CUSTOM_FILE_CAPTION = environ.get("CUSTOM_FILE_CAPTION", f"{script.CAPTION}") # Custom caption for files BATCH_FILE_CAPTION = environ.get("BATCH_FILE_CAPTION", CUSTOM_FILE_CAPTION) # Custom caption for batch files @@ -232,7 +232,7 @@ def is_enabled(value, default): name = str(environ.get('name', 'DREAMXBOTZ')) PING_INTERVAL = int(environ.get("PING_INTERVAL", "298")) # 5 minutes # ============================ -REACTIONS = ["🤝", "😇", "🤗", "😍", "👍", "🎅", "😐", "🥰", "🤩", "😱", "🤣", "😘", "👏", "😛", "😈", "🎉", "⚡️", "🫡", "🤓", "😎", "🏆", "🔥", "🤭", "🌚", "🆒", "👻", "😁"] +REACTIONS = ["🤝", "😇", "🤗", "😍", "👍", "🎅", "😐", "🥰", "🤩", "😱", "🤣", "😘", "👏", "😛", "😈", "🎉", "⚡", "🫡", "🤓", "😎", "🏆", "🔥", "🤭", "🌚", "🆒", "👻", "😁"] # ============================ # Commands Bot From 3914c9dbce83bd64c5bda8b7eecfaecf8b3e3b9e Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Tue, 15 Sep 2026 22:09:55 +0530 Subject: [PATCH 41/77] Update commands.py --- plugins/commands.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/commands.py b/plugins/commands.py index 946b9fd4..1a6ce597 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -139,7 +139,6 @@ async def _delete_msg(msg_to_delete, delay): if f_caption is None: f_caption = f"{clean_filename(files1.file_name)}" - sent_msg = await client.send_cached_media( chat_id=message.from_user.id, cover=cover, @@ -175,7 +174,6 @@ async def _delete_msg(msg_to_delete, delay): cover=cover, caption=f_caption, protect_content=settings.get('file_secure', PROTECT_CONTENT), - reply_markup=InlineKeyboardMarkup(btn) ) filesarr.append(sent_msg) From 858e606a5190f2cfd887bfc29361cadda35bf244 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Tue, 15 Sep 2026 22:17:19 +0530 Subject: [PATCH 42/77] Fix formatting and improve message editing --- plugins/commands.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/commands.py b/plugins/commands.py index 1a6ce597..946b9fd4 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -139,6 +139,7 @@ async def _delete_msg(msg_to_delete, delay): if f_caption is None: f_caption = f"{clean_filename(files1.file_name)}" + sent_msg = await client.send_cached_media( chat_id=message.from_user.id, cover=cover, @@ -174,6 +175,7 @@ async def _delete_msg(msg_to_delete, delay): cover=cover, caption=f_caption, protect_content=settings.get('file_secure', PROTECT_CONTENT), + reply_markup=InlineKeyboardMarkup(btn) ) filesarr.append(sent_msg) From 6c02353b37c608630a1cb55b2e2be908b6a3a351 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Wed, 16 Sep 2026 07:30:36 +0530 Subject: [PATCH 43/77] Update commands.py --- plugins/commands.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/plugins/commands.py b/plugins/commands.py index 946b9fd4..608ab4ef 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -414,6 +414,16 @@ async def _delete_files(msgs, notif_msg, delay): settings = await get_settings(grp_id) is_second_shortener = await db.use_second_shortener(user_id, settings.get('verify_time', TWO_VERIFY_GAP)) is_third_shortener = await db.use_third_shortener(user_id, settings.get('third_verify_time', THREE_VERIFY_GAP)) + # reset after 3rd expires -> back to 1st + if is_third_shortener: + try: + await db.update_notcopy_user(user_id, {"last_verified": None, "second_time_verified": None, "third_time_verified": None}) + user_verified = False + is_second_shortener = False + is_third_shortener = False + except Exception: + pass + if settings.get("is_verify", IS_VERIFY) and (not user_verified or is_second_shortener or is_third_shortener): verify_id = ''.join(random.choices(string.ascii_uppercase + string.digits, k=7)) await db.create_verify_id(user_id, verify_id) @@ -1245,7 +1255,7 @@ async def set_log(client, message): except Exception as e: return await message.reply_text(f'😐 ᴍᴀᴋᴇ sᴜʀᴇ ᴛʜɪs ʙᴏᴛ ᴀᴅᴍɪɴ ɪɴ ᴛʜᴀᴛ ᴄʜᴀɴɴᴇʟ...\n\n💔 ᴇʀʀᴏʀ - {e}') await save_group_settings(grp_id, 'log', log) - await message.reply_text(f"✅ sᴜᴄᴄᴇssꜰᴜʟʟʏ sᴇᴛ ʏᴏᴜʀ ʟᴏɢ ᴄʜᴀɴɴᴇʟ ꜰᴏʀ {title}\n\nɪᴅ - `{log}`", link_preview_options=LinkPreviewOptions(is_disabled=True)) + await message.reply_text(f"✅ sᴜᴄᴄᴇssғᴜʟʟʏ sᴇᴛ ʏᴏᴜʀ ʟᴏɢ ᴄʜᴀɴɴᴇʟ ꜰᴏʀ {title}\n\nɪᴅ - `{log}`", link_preview_options=LinkPreviewOptions(is_disabled=True)) user_id = message.from_user.id user_info = f"@{message.from_user.username}" if message.from_user.username else f"{message.from_user.mention}" link = (await client.get_chat(message.chat.id)).invite_link From b0be3b24597b89b252044d9093fbc3d4d8280ad5 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Wed, 16 Sep 2026 08:10:06 +0530 Subject: [PATCH 44/77] Update commands.py --- plugins/commands.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/commands.py b/plugins/commands.py index 608ab4ef..1c25c55e 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -200,9 +200,9 @@ async def _delete_files(msgs, notif_msg, delay): return if message.chat.type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]: buttons = [[ - InlineKeyboardButton('❤ ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ ❤', url=f'http://t.me/{temp.U_NAME}?startgroup=true') + InlineKeyboardButton('🫶🏻 Aᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🫶🏻', url=f'http://t.me/{temp.U_NAME}?startgroup=true') ],[ - InlineKeyboardButton('🍁 Update Channel 🍁', url=UPDATE_CHNL_LNK) + InlineKeyboardButton('🍁 Uᴘᴅᴀᴛᴇ ᴄʜᴀɴɴᴇʟ 🍁', url=UPDATE_CHNL_LNK) ]] reply_markup = InlineKeyboardMarkup(buttons) await message.reply(script.GSTART_TXT.format(message.from_user.mention if message.from_user else message.chat.title, temp.U_NAME, temp.B_NAME), reply_markup=reply_markup, link_preview_options=LinkPreviewOptions(is_disabled=True)) From 58aefac584bc4a326f050f476408d0216b5a35a4 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Wed, 16 Sep 2026 08:21:05 +0530 Subject: [PATCH 45/77] Update button text for support contact --- plugins/p_ttishow.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/p_ttishow.py b/plugins/p_ttishow.py index 03eec56c..59c5a387 100644 --- a/plugins/p_ttishow.py +++ b/plugins/p_ttishow.py @@ -38,7 +38,7 @@ async def save_group(bot, message): await bot.leave_chat(message.chat.id) return buttons = [[ - InlineKeyboardButton("👩‍🌾 Bot Owner 👩‍🌾", url=OWNER_LNK) + InlineKeyboardButton("👩‍🌾 Bᴏᴛ ᴏɴᴡᴇʀ 👩‍🌾", url=OWNER_LNK) ]] reply_markup=InlineKeyboardMarkup(buttons) await message.reply_text( @@ -64,7 +64,7 @@ async def save_group(bot, message): caption=script.MELCOW_ENG.format(u.mention, message.chat.title), reply_markup=InlineKeyboardMarkup([ [ - InlineKeyboardButton("📌 ᴄᴏɴᴛᴀᴄᴛ ꜱᴜᴘᴘᴏʀᴛ 📌", url=OWNER_LNK) + InlineKeyboardButton("📌 Cᴏɴᴛᴀᴄᴛ ꜱᴜᴘᴘᴏʀᴛ 📌", url=OWNER_LNK) ]]),parse_mode=enums.ParseMode.HTML) except Exception as e: logger.error("Welcome photo send failed: %s", e) @@ -88,7 +88,7 @@ async def leave_a_chat(bot, message): chat = chat try: buttons = [[ - InlineKeyboardButton("📌 ᴄᴏɴᴛᴀᴄᴛ ꜱᴜᴘᴘᴏʀᴛ 📌", url=OWNER_LNK) + InlineKeyboardButton("📌 Cᴏɴᴛᴀᴄᴛ ꜱᴜᴘᴘᴏʀᴛ 📌", url=OWNER_LNK) ]] reply_markup=InlineKeyboardMarkup(buttons) await bot.send_message( @@ -127,7 +127,7 @@ async def disable_chat(bot, message): await message.reply('Chat Successfully Disabled') try: buttons = [[ - InlineKeyboardButton('📌 ᴄᴏɴᴛᴀᴄᴛ ꜱᴜᴘᴘᴏʀᴛ 📌', url=OWNER_LNK) + InlineKeyboardButton('📌 Cᴏɴᴛᴀᴄᴛ ꜱᴜᴘᴘᴏʀᴛ 📌', url=OWNER_LNK) ]] reply_markup=InlineKeyboardMarkup(buttons) await bot.send_message( From 07b4bef2226e1c2a1e467bab310177c23d8c339f Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Wed, 16 Sep 2026 08:53:24 +0530 Subject: [PATCH 46/77] Update pmfilter.py --- plugins/pmfilter.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/plugins/pmfilter.py b/plugins/pmfilter.py index a2df2f5f..297746b5 100644 --- a/plugins/pmfilter.py +++ b/plugins/pmfilter.py @@ -185,7 +185,7 @@ async def next_page(bot, query): btn.insert(0, [ InlineKeyboardButton( - "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), + "Rᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) @@ -206,7 +206,7 @@ async def next_page(bot, query): ) btn.insert(0, [ InlineKeyboardButton( - "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), + "Rᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton("Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) ]) if ULTRA_FAST_MODE: @@ -1285,15 +1285,18 @@ async def cb_handler(client: Client, query: CallbackQuery): elif query.data == "upi_info": try: btn = [[ - InlineKeyboardButton('• ꜱᴇɴᴅ ᴘᴀʏᴍᴇɴᴛ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ •', url=OWNER_LNK), + InlineKeyboardButton('📲 Sᴇɴᴅ Pᴀʏᴍᴇɴᴛ Sᴄʀᴇᴇɴsʜᴏᴛ', url=OWNER_LNK) + ],[ + InlineKeyboardButton('📷 Qʀ Cᴏᴅᴇ', url=QR_CODE) ],[ - InlineKeyboardButton('⇋ ʙᴀᴄᴋ ⇋', callback_data='buy_info') + InlineKeyboardButton('⇋ Bᴀᴄᴋ ⇋', callback_data='buy_info'), + InlineKeyboardButton('❌ Cʟᴏsᴇ ❌', callback_data='close_data') ]] reply_markup = InlineKeyboardMarkup(btn) await client.edit_message_media( chat_id=query.message.chat.id, message_id=query.message.id, - media=InputMediaPhoto(media=SUBSCRIPTION, caption=script.PREMIUM_UPI_TEXT.format(OWNER_UPI_ID), parse_mode=enums.ParseMode.HTML), + media=InputMediaPhoto(media=SUBSCRIPTION, caption=script.PREPLANS_TXT.format(query.from_user.mention, OWNER_UPI_ID, QR_CODE), parse_mode=enums.ParseMode.HTML), reply_markup=reply_markup ) except Exception: @@ -1717,3 +1720,6 @@ async def advantage_spell_chok(client, message): await message.delete() except Exception: pass + + + From 3db58c15aa418207fb7d453a212842cb428bb25f Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Wed, 16 Sep 2026 09:01:52 +0530 Subject: [PATCH 47/77] Update pmfilter.py --- plugins/pmfilter.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/plugins/pmfilter.py b/plugins/pmfilter.py index 297746b5..63500471 100644 --- a/plugins/pmfilter.py +++ b/plugins/pmfilter.py @@ -458,7 +458,7 @@ async def filter_qualities_cb_handler(client: Client, query: CallbackQuery): btn.insert(0, [ InlineKeyboardButton( - "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), + "Rᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) ]) @@ -477,7 +477,7 @@ async def filter_qualities_cb_handler(client: Client, query: CallbackQuery): btn.insert(0, [ InlineKeyboardButton( - "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), + "Rᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) @@ -613,7 +613,7 @@ async def filter_languages_cb_handler(client: Client, query: CallbackQuery): btn.insert(0, [ InlineKeyboardButton( - "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), + "Rᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) ] @@ -632,7 +632,7 @@ async def filter_languages_cb_handler(client: Client, query: CallbackQuery): btn.insert(0, [ InlineKeyboardButton( - "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), + "Rᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) ]) @@ -763,7 +763,7 @@ async def filter_seasons_cb_handler(client: Client, query: CallbackQuery): 0, [ InlineKeyboardButton( - "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), + "Rᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton("Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS), ], ) @@ -1210,7 +1210,7 @@ async def cb_handler(client: Client, query: CallbackQuery): ), parse_mode=enums.ParseMode.HTML, reply_markup=InlineKeyboardMarkup([[ - InlineKeyboardButton("🚀 Buy Premium 🚀", callback_data="premium_info") + InlineKeyboardButton("🚀 Bᴜʏ ᴘʀᴇᴍɪᴜᴍ 🚀", callback_data="premium_info") ]]) ) await asyncio.sleep(DELETE_TIME) @@ -1247,10 +1247,10 @@ async def cb_handler(client: Client, query: CallbackQuery): elif query.data == "premium_info": try: btn = [[ - InlineKeyboardButton('• ʙᴜʏ ᴘʀᴇᴍɪᴜᴍ •', callback_data='buy_info'), + InlineKeyboardButton('• Bᴜʏ ᴘʀᴇᴍɪᴜᴍ •', callback_data='buy_info'), ],[ - InlineKeyboardButton('• ʀᴇꜰᴇʀ ꜰʀɪᴇɴᴅꜱ', callback_data='reffff'), - InlineKeyboardButton('ꜰʀᴇᴇ ᴛʀɪᴀʟ •', callback_data='give_trial') + InlineKeyboardButton('• Rᴇꜰᴇʀ ꜰʀɪᴇɴᴅꜱ •', callback_data='reffff'), + InlineKeyboardButton('• Fʀᴇᴇ ᴛʀɪᴀʟ •', callback_data='give_trial') ],[ InlineKeyboardButton('⇋ ʙᴀᴄᴋ ᴛᴏ ʜᴏᴍᴇ ⇋', callback_data='start') ]] From ba54003fa7edb4b8544e80b179809b60a7baac66 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Wed, 16 Sep 2026 09:52:29 +0530 Subject: [PATCH 48/77] Update pmfilter.py --- plugins/pmfilter.py | 89 ++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 49 deletions(-) diff --git a/plugins/pmfilter.py b/plugins/pmfilter.py index 63500471..6295f6e1 100644 --- a/plugins/pmfilter.py +++ b/plugins/pmfilter.py @@ -184,8 +184,7 @@ async def next_page(bot, query): ) btn.insert(0, [ - InlineKeyboardButton( - "Rᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium_info", style=enums.ButtonStyle.PRIMARY), + InlineKeyboardButton("ʀᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info"), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) @@ -205,8 +204,7 @@ async def next_page(bot, query): ] ) btn.insert(0, [ - InlineKeyboardButton( - "Rᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium_info", style=enums.ButtonStyle.PRIMARY), + InlineKeyboardButton("ʀᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info"), InlineKeyboardButton("Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) ]) if ULTRA_FAST_MODE: @@ -379,8 +377,8 @@ async def qualities_cb_handler(client: Client, query: CallbackQuery): try: if int(req) not in [query.from_user.id, 0]: return await query.answer( - f"⚠ ʜᴇʟʟᴏ {query.from_user.first_name},\n" - f"ᴛʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ,\nʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀ'ꜱ...", + f"⚠ Hʟʟᴏ {query.from_user.first_name},\n" + f"Tʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ,\nYᴏᴜ ᴍᴀʏ ʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀꜱ...", show_alert=True, ) except Exception: @@ -457,8 +455,7 @@ async def filter_qualities_cb_handler(client: Client, query: CallbackQuery): ) btn.insert(0, [ - InlineKeyboardButton( - "Rᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium_info", style=enums.ButtonStyle.PRIMARY), + InlineKeyboardButton("ʀᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info"), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) ]) @@ -476,8 +473,7 @@ async def filter_qualities_cb_handler(client: Client, query: CallbackQuery): ) btn.insert(0, [ - InlineKeyboardButton( - "Rᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium_info", style=enums.ButtonStyle.PRIMARY), + InlineKeyboardButton("ʀᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info"), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) @@ -507,7 +503,7 @@ async def filter_qualities_cb_handler(client: Client, query: CallbackQuery): btn.append( [InlineKeyboardButton( - text="↭ ɴᴏ ᴍᴏʀᴇ ᴘᴀɢᴇꜱ ᴀᴠᴀɪʟᴀʙʟᴇ ↭", callback_data="pages")] + text="↭ Nᴏ ᴍᴏʀᴇ ᴘᴀɢᴇꜱ ᴀᴠᴀɪʟᴀʙʟᴇ ↭", callback_data="pages")] ) if not settings["button"]: cur_time = datetime.now(pytz.timezone('Asia/Kolkata')).time() @@ -535,8 +531,8 @@ async def languages_cb_handler(client: Client, query: CallbackQuery): try: if int(req) not in [query.from_user.id, 0]: return await query.answer( - f"⚠ ʜᴇʟʟᴏ {query.from_user.first_name},\n" - f"ᴛʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ,\nʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀ'ꜱ...", + f"⚠ Hᴇʟʟᴏ {query.from_user.first_name},\n" + f"Tʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ,\nYᴏᴜ ᴍᴀʏ ʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀꜱ...", show_alert=True, ) except Exception: @@ -588,7 +584,7 @@ async def filter_languages_cb_handler(client: Client, query: CallbackQuery): BUTTONS[key] = search files, offset, total_results = await get_search_results(chat_id, search, offset=0, filter=True) if not files: - await query.answer("🚫 ɴᴏ ꜰɪʟᴇꜱ ᴡᴇʀᴇ ꜰᴏᴜɴᴅ 🚫", show_alert=1) + await query.answer("🚫 Nᴏ ꜰɪʟᴇꜱ ᴡᴇʀᴇ ꜰᴏᴜɴᴅ 🚫", show_alert=1) return temp.GETALL[key] = files settings = await get_settings(message.chat.id) @@ -612,8 +608,7 @@ async def filter_languages_cb_handler(client: Client, query: CallbackQuery): ) btn.insert(0, [ - InlineKeyboardButton( - "Rᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium_info", style=enums.ButtonStyle.PRIMARY), + InlineKeyboardButton("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info"), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) ] @@ -631,8 +626,7 @@ async def filter_languages_cb_handler(client: Client, query: CallbackQuery): ]) btn.insert(0, [ - InlineKeyboardButton( - "Rᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium_info", style=enums.ButtonStyle.PRIMARY), + InlineKeyboardButton("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info"), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) ]) @@ -647,19 +641,19 @@ async def filter_languages_cb_handler(client: Client, query: CallbackQuery): else: btn.append( [ - InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( + InlineKeyboardButton("Pᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( text=f"1/{math.ceil(int(total_results)/int(MAX_B_TN))}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}") ]) except KeyError: await save_group_settings(query.message.chat.id, 'max_btn', True) btn.append( [ - InlineKeyboardButton("ᴘᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( + InlineKeyboardButton("Pᴀɢᴇ", callback_data="pages"), InlineKeyboardButton( text=f"1/{math.ceil(int(total_results)/10)}", callback_data="pages"), InlineKeyboardButton(text="ɴᴇxᴛ ⋟", callback_data=f"next_{req}_{key}_{offset}") ]) else: btn.append([InlineKeyboardButton( - text="↭ ɴᴏ ᴍᴏʀᴇ ᴘᴀɢᴇꜱ ᴀᴠᴀɪʟᴀʙʟᴇ ↭", callback_data="pages")]) + text="↭ Nᴏ ᴍᴏʀᴇ ᴘᴀɢᴇꜱ ᴀᴠᴀɪʟᴀʙʟᴇ ↭", callback_data="pages")]) if not settings["button"]: cur_time = datetime.now(pytz.timezone('Asia/Kolkata')).time() time_difference = timedelta(hours=cur_time.hour, minutes=cur_time.minute, seconds=(cur_time.second+(cur_time.microsecond/1000000))) - \ @@ -733,7 +727,7 @@ async def filter_seasons_cb_handler(client: Client, query: CallbackQuery): files, n_offset, total_results = await get_search_results(chat_id, query_input, offset=0, filter=True) if not files: BUTTONS[key] = None - return await query.answer("🚫 ɴᴏ ꜰɪʟᴇꜱ ꜰᴏᴜɴᴅ 🚫", show_alert=True) + return await query.answer("🚫 Nᴏ ꜰɪʟᴇꜱ ꜰᴏᴜɴᴅ 🚫", show_alert=True) temp.GETALL[key] = files settings = await get_settings(chat_id) @@ -762,8 +756,7 @@ async def filter_seasons_cb_handler(client: Client, query: CallbackQuery): btn.insert( 0, [ - InlineKeyboardButton( - "Rᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium_info", style=enums.ButtonStyle.PRIMARY), + InlineKeyboardButton("ʀᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info"), InlineKeyboardButton("Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS), ], ) @@ -790,7 +783,7 @@ async def filter_seasons_cb_handler(client: Client, query: CallbackQuery): n_offset = 0 btn.append( [InlineKeyboardButton( - "↭ ɴᴏ ᴍᴏʀᴇ ᴘᴀɢᴇꜱ ᴀᴠᴀɪʟᴀʙʟᴇ ↭", callback_data="pages")] + "↭ Nᴏ ᴍᴏʀᴇ ᴘᴀɢᴇꜱ ᴀᴠᴀɪʟᴀʙʟᴇ ↭", callback_data="pages")] ) if not settings.get("button"): curr_time = datetime.now(pytz.timezone("Asia/Kolkata")).time() @@ -831,7 +824,7 @@ async def cb_handler(client: Client, query: CallbackQuery): user = query.from_user.id if int(user) != 0 and query.from_user.id != int(user): return await query.answer(script.NT_ALRT_TXT, show_alert=True) - await query.answer("ᴛʜᴀɴᴋs ꜰᴏʀ ᴄʟᴏsᴇ 🙈") + await query.answer("Tʜᴀɴᴋs ꜰᴏʀ ᴄʟᴏsᴇ 🙈") await query.message.delete() try: await query.message.reply_to_message.delete() @@ -839,7 +832,7 @@ async def cb_handler(client: Client, query: CallbackQuery): pass elif query.data == "pages": - await query.answer("ᴛʜɪs ɪs ᴘᴀɢᴇs ʙᴜᴛᴛᴏɴ 😅") + await query.answer("Tʜɪs ɪs ᴘᴀɢᴇs ʙᴜᴛᴛᴏɴ 😅") if query.data.startswith("file"): ident, file_id = query.data.split("#") @@ -867,7 +860,7 @@ async def cb_handler(client: Client, query: CallbackQuery): if MULTIPLE_DB: await Media2.collection.drop() await query.answer("Eᴠᴇʀʏᴛʜɪɴɢ's Gᴏɴᴇ") - await query.message.edit('ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ᴀʟʟ ɪɴᴅᴇxᴇᴅ ꜰɪʟᴇꜱ ✅') + await query.message.edit('Sᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ᴀʟʟ ɪɴᴅᴇxᴇᴅ ꜰɪʟᴇꜱ ✅') elif query.data.startswith("checksub"): try: @@ -885,8 +878,8 @@ async def cb_handler(client: Client, query: CallbackQuery): except (MessageNotModified, MessageIdInvalid): pass await query.answer( - f"👋 Hello {query.from_user.first_name},\n\n" - "🛑 Yᴏᴜ ʜᴀᴠᴇ ɴᴏᴛ ᴊᴏɪɴᴇᴅ ᴀʟʟ ʀᴇǫᴜɪʀᴇᴅ ᴜᴘᴅᴀᴛᴇ Cʜᴀɴɴᴇʟs.\n" + f"👋 Hᴇʟʟᴏ {query.from_user.first_name},\n\n" + "🛑 Yᴏᴜ ʜᴀᴠᴇ ɴᴏᴛ ᴊᴏɪɴᴇᴅ ᴀʟʟ ʀᴇǫᴜɪʀᴇᴅ ᴜᴘᴅᴀᴛᴇ ᴄʜᴀɴɴᴇʟs.\n" "👉 Pʟᴇᴀsᴇ ᴊᴏɪɴ ᴇᴀᴄʜ ᴏɴᴇ ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ.\n", show_alert=True ) @@ -1098,25 +1091,25 @@ async def cb_handler(client: Client, query: CallbackQuery): elif query.data == "start": buttons = [[ - InlineKeyboardButton('🔰 ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://telegram.me/{temp.U_NAME}?startgroup=true') + InlineKeyboardButton('🔰 Aᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://telegram.me/{temp.U_NAME}?startgroup=true') ],[ - InlineKeyboardButton(' ʜᴇʟᴘ 📢', callback_data='help'), + InlineKeyboardButton(' Hᴇʟᴘ 📢', callback_data='help'), InlineKeyboardButton(' ᴀʙᴏᴜᴛ 📖', callback_data='about') ],[ - InlineKeyboardButton('ᴛᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), - InlineKeyboardButton('ᴜᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), + InlineKeyboardButton('Tᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), + InlineKeyboardButton('Uᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), ]] reply_markup = InlineKeyboardMarkup(buttons) current_time = datetime.now(pytz.timezone(TIMEZONE)) curr_time = current_time.hour if curr_time < 12: - gtxt = "ɢᴏᴏᴅ ᴍᴏʀɴɪɴɢ 🌞" + gtxt = "Gᴏᴏᴅ ᴍᴏʀɴɪɴɢ 🌞" elif curr_time < 17: - gtxt = "ɢᴏᴏᴅ ᴀғᴛᴇʀɴᴏᴏɴ 🌓" + gtxt = "Gᴏᴏᴅ ᴀғᴛᴇʀɴᴏᴏɴ 🌓" elif curr_time < 21: - gtxt = "ɢᴏᴏᴅ ᴇᴠᴇɴɪɴɢ 🌘" + gtxt = "Gᴏᴏᴅ ᴇᴠᴇɴɪɴɢ 🌘" else: - gtxt = "ɢᴏᴏᴅ ɴɪɢʜᴛ 🌑" + gtxt = "Gᴏᴏᴅ ɴɪɢʜᴛ 🌑" try: if len(PICS) == 1: PIC = PICS[0] @@ -1192,7 +1185,7 @@ async def cb_handler(client: Client, query: CallbackQuery): has_free_trial = await db.check_trial_status(user_id) if has_free_trial: await query.answer( - "🚸 ʏᴏᴜ'ᴠᴇ ᴀʟʀᴇᴀᴅʏ ᴄʟᴀɪᴍᴇᴅ ʏᴏᴜʀ ꜰʀᴇᴇ ᴛʀɪᴀʟ ᴏɴᴄᴇ !\n\n📌 ᴄʜᴇᴄᴋᴏᴜᴛ ᴏᴜʀ ᴘʟᴀɴꜱ ʙʏ : /plan", + "🚸 Yᴏᴜ'ᴠᴇ ᴀʟʀᴇᴀᴅʏ ᴄʟᴀɪᴍᴇᴅ ʏᴏᴜʀ ꜰʀᴇᴇ ᴛʀɪᴀʟ ᴏɴᴄᴇ !\n\n📌 ᴄʜᴇᴄᴋᴏᴜᴛ ᴏᴜʀ ᴘʟᴀɴꜱ ʙʏ : /plan", show_alert=True ) return @@ -1210,7 +1203,7 @@ async def cb_handler(client: Client, query: CallbackQuery): ), parse_mode=enums.ParseMode.HTML, reply_markup=InlineKeyboardMarkup([[ - InlineKeyboardButton("🚀 Bᴜʏ ᴘʀᴇᴍɪᴜᴍ 🚀", callback_data="premium_info") + InlineKeyboardButton("🚀 Buy Premium 🚀", callback_data="premium_info") ]]) ) await asyncio.sleep(DELETE_TIME) @@ -1252,7 +1245,7 @@ async def cb_handler(client: Client, query: CallbackQuery): InlineKeyboardButton('• Rᴇꜰᴇʀ ꜰʀɪᴇɴᴅꜱ •', callback_data='reffff'), InlineKeyboardButton('• Fʀᴇᴇ ᴛʀɪᴀʟ •', callback_data='give_trial') ],[ - InlineKeyboardButton('⇋ ʙᴀᴄᴋ ᴛᴏ ʜᴏᴍᴇ ⇋', callback_data='start') + InlineKeyboardButton('⇋ Bᴀᴄᴋ ᴛᴏ ʜᴏᴍᴇ ⇋', callback_data='start') ]] reply_markup = InlineKeyboardMarkup(btn) await client.edit_message_media( @@ -1267,8 +1260,8 @@ async def cb_handler(client: Client, query: CallbackQuery): elif query.data == "buy_info": try: btn = [[ - InlineKeyboardButton('ꜱᴛᴀʀ', callback_data='star_info'), - InlineKeyboardButton('ᴜᴘɪ', callback_data='upi_info') + InlineKeyboardButton('Sᴛᴀʀ', callback_data='star_info'), + InlineKeyboardButton('Uᴘɪ', callback_data='upi_info') ],[ InlineKeyboardButton('⇋ ʙᴀᴄᴋ ᴛᴏ ᴘʀᴇᴍɪᴜᴍ ⇋', callback_data='premium_info') ]] @@ -1290,7 +1283,7 @@ async def cb_handler(client: Client, query: CallbackQuery): InlineKeyboardButton('📷 Qʀ Cᴏᴅᴇ', url=QR_CODE) ],[ InlineKeyboardButton('⇋ Bᴀᴄᴋ ⇋', callback_data='buy_info'), - InlineKeyboardButton('❌ Cʟᴏsᴇ ❌', callback_data='close_data') + InlineKeyboardButton('🚫 Cʟᴏsᴇ 🚫', callback_data='close_data') ]] reply_markup = InlineKeyboardMarkup(btn) await client.edit_message_media( @@ -1426,7 +1419,7 @@ async def _schedule_delete(sent_obj, orig_msg, delay): settings = await get_settings(message.chat.id) if not files: if settings.get("spell_check"): - ai_sts = await m.edit('🤖 ᴘʟᴇᴀꜱᴇ ᴡᴀɪᴛ, ᴀɪ ɪꜱ ᴄʜᴇᴄᴋɪɴɢ ʏᴏᴜʀ ꜱᴘᴇʟʟɪɴɢ...') + ai_sts = await m.edit('🤖 Pʟᴇᴀꜱᴇ ᴡᴀɪᴛ, Aɪ ɪꜱ ᴄʜᴇᴄᴋɪɴɢ ʏᴏᴜʀ ꜱᴘᴇʟʟɪɴɢ...') is_misspelled = await ai_spell_check(chat_id=message.chat.id, wrong_name=search) if is_misspelled: await ai_sts.edit(f'✅ Aɪ Sᴜɢɢᴇsᴛᴇᴅ: {is_misspelled}\n🔍 Searching for it...') @@ -1481,8 +1474,7 @@ async def _schedule_delete(sent_obj, orig_msg, delay): ) btn.insert(0, [ - InlineKeyboardButton( - "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), + InlineKeyboardButton("ʀᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info"), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) @@ -1501,8 +1493,7 @@ async def _schedule_delete(sent_obj, orig_msg, delay): ) btn.insert(0, [ - InlineKeyboardButton( - "ʀᴇᴍᴏᴠᴇ ᴀᴅs", url=f"https://t.me/{temp.U_NAME}?start=premium", style=enums.ButtonStyle.PRIMARY), + InlineKeyboardButton("ʀᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info"), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) ]) From 95d49eb97a49ee8f02cbdbef836436f4940e790d Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Wed, 16 Sep 2026 10:04:03 +0530 Subject: [PATCH 49/77] Update Script.py --- Script.py | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/Script.py b/Script.py index d6eb1d33..5d981071 100644 --- a/Script.py +++ b/Script.py @@ -1,5 +1,5 @@ class script(object): - START_TXT = """🚩 ᴊᴀɪ ꜱʜʀɪ ʀᴀᴍ 🚩 + START_TXT = """🧸 Sʏsᴛᴇᴍ ɪɴɪᴛɪᴀʟɪᴢᴇᴅ 🎧 ʜᴇʏ {}, {} @@ -7,7 +7,7 @@ class script(object): """ - GSTART_TXT = """🚩 ᴊᴀɪ ꜱʜʀɪ ʀᴀᴍ 🚩 + GSTART_TXT = """🧸 Sʏsᴛᴇᴍ ɪɴɪᴛɪᴀʟɪᴢᴇᴅ 🎧 ʜᴇʏ {}, @@ -31,7 +31,7 @@ class script(object): 📌 ꜰᴏʀ ᴍᴏᴠɪᴇꜱ: ➤ ᴍᴏᴠɪᴇ ɴᴀᴍᴇ + ʏᴇᴀʀ (ᴇx: ᴊᴏᴋᴇʀ 2019) -🚀 ꜰᴏʟʟᴏᴡ ᴛʜᴇꜱᴇ ꜱᴛᴇᴘꜱ! +🚀 ꜰᴏʟʟᴏᴡ ᴛʜᴇꜱᴇ ꜱᴛᴇᴘꜱ !! """ ABOUT_TXT = """╭────[Mʏ Dᴇᴛᴀɪʟs ]────⍟ @@ -112,13 +112,13 @@ class script(object): Iᴅ - {} Nᴀᴍᴇ - {} """ - NT_ADMIN_ALRT_TXT = """‼️ ʏᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴀᴅᴍɪɴ ɪɴ ᴛʜɪꜱ ɢʀᴏᴜᴘ ‼️""" + NT_ADMIN_ALRT_TXT = """‼️ Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴀᴅᴍɪɴ ɪɴ ᴛʜɪꜱ ɢʀᴏᴜᴘ ‼️""" NT_ALRT_TXT = """Not Yours!""" ALRT_TXT = """ʜᴇʟʟᴏ {}, ᴛʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ, -ʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀ'ꜱ...""" +ʏᴏᴜ ᴍᴀʏ ʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀꜱ...""" OLD_ALRT_TXT = """ʜᴇʏ {}, ʏᴏᴜ ᴀʀᴇ ᴜꜱɪɴɢ ᴏɴᴇ ᴏꜰ ᴍʏ ᴏʟᴅ ᴍᴇꜱꜱᴀɢᴇꜱ, @@ -163,7 +163,7 @@ class script(object): ALREADY_AVAILABLE_TXT = """ʜᴇʏ {}, -ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ɪꜱ ᴀʟʀᴇᴀᴅʏ ᴀᴠᴀɪʟᴀʙʟᴇ ✅ +Yᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ɪꜱ ᴀʟʀᴇᴀᴅʏ ᴀᴠᴀɪʟᴀʙʟᴇ ✅
📂 ꜰɪʟᴇꜱ ꜰᴏᴜɴᴅ : {} 🔍 ꜱᴇᴀʀᴄʜ : {}
@@ -315,7 +315,7 @@ class script(object): - PREMIUM_TEXT = """
🎖️ ᴀᴠᴀɪʟᴀʙʟᴇ ᴘʟᴀɴs
+ PREMIUM_TEXT = """
🎖️ Aᴠᴀɪʟᴀʙʟᴇ ᴘʟᴀɴs
◉ 07 ᴅᴀʏꜱ - 10 ₹ / 10 ꜱᴛᴀʀ @@ -326,10 +326,10 @@ class script(object): •─────•─────────•─────• -‼️ ᴍᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. -‼️ ᴀꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇꜱ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" +‼️ Mᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. +‼️ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇꜱ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" - PREMIUM_STAR_TEXT = """
ᴘᴀʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅ: ᴛᴇʟᴇɢʀᴀᴍ ꜱᴛᴀʀꜱ ⭐
+ PREMIUM_STAR_TEXT = """
Pᴀʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅ: Tᴇʟᴇɢʀᴀᴍ ꜱᴛᴀʀꜱ ⭐
ɴᴏᴡ ʏᴏᴜ ᴄᴀɴ ʙᴜʏ ᴏᴜʀ ᴘʀᴇᴍɪᴜᴍ ꜱᴇʀᴠɪᴄᴇ ᴜꜱɪɴɢ ᴛᴇʟᴇɢʀᴀᴍ ꜱᴛᴀʀꜱ. @@ -356,8 +356,8 @@ class script(object): ᴄʟɪᴄᴋ ᴏɴ /plan ᴛᴏ ᴄʜᴇᴄᴋ ᴏᴜʀ ᴏᴛʜᴇʀ ᴘʟᴀɴs.
ᴀᴀᴘᴋᴀ ᴘʀᴇᴍɪᴜᴍ ᴀᴄᴄᴇss ʜᴀᴛᴀ ᴅɪʏᴀ ɢᴀʏᴀ ʜᴀɪ। -ʜᴀᴍᴀʀɪ sᴇᴠᴀ ᴋᴀ ᴜᴘʏᴏɢ ᴋᴀʀɴᴇ ᴋᴇ ʟɪʏᴇ ᴅʜᴀɴʏᴀᴠᴀᴀᴅ 🥳 -ʜᴀᴍᴀʀɪ ᴀɴʏᴀ ʏᴏᴊɴᴀᴏɴ ᴋɪ ᴊᴀᴀɴᴄʜ ᴋᴀʀɴᴇ ᴋᴇ ʟɪʏᴇ /plan ᴘᴀʀ ᴋʟɪᴄᴋ ᴋᴀʀᴇɪɴ।
+Hᴀᴍᴀʀɪ sᴇᴠᴀ ᴋᴀ ᴜᴘʏᴏɢ ᴋᴀʀɴᴇ ᴋᴇ ʟɪʏᴇ ᴅʜᴀɴʏᴀᴠᴀᴀᴅ 🥳 +Hᴀᴍᴀʀɪ ᴀɴʏᴀ ʏᴏᴊɴᴀᴏɴ ᴋɪ ᴊᴀᴀɴᴄʜ ᴋᴀʀɴᴇ ᴋᴇ ʟɪʏᴇ /plan ᴘᴀʀ ᴋʟɪᴄᴋ ᴋᴀʀᴇɪɴ। """ @@ -378,7 +378,7 @@ class script(object): •─────•─────────•─────• ◉ ᴄʜᴇᴄᴋ ʏᴏᴜʀ ᴀᴄᴛɪᴠᴇ ᴘʟᴀɴ : /myplan -‼️ ᴀꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇꜱ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" +‼️ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇꜱ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" PREPLANS_TXT = PREMIUM_TXT = """👋 ʜᴇʏ {}, @@ -393,17 +393,17 @@ class script(object): •─────•─────────•─────• -🏷️ ᴘᴀʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅꜱ +🏷️ Pᴀʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅꜱ - Uᴘɪ -💸 ᴜᴘɪ ɪᴅ → {} -📷 ǫʀ ᴄᴏᴅᴇ → ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ꜱᴄᴀɴ +💸 Uᴘɪ ɪᴅ → {} +📷 Qʀ ᴄᴏᴅᴇ → ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ꜱᴄᴀɴ -🧾 ᴘᴀʏ ᴀᴄᴄᴏʀᴅɪɴɢ ᴛᴏ ʏᴏᴜʀ ᴘʟᴀɴ ᴀɴᴅ ᴇɴᴊᴏʏ ᴘʀᴇᴍɪᴜᴍ! +🧾 Pᴀʏ ᴀᴄᴄᴏʀᴅɪɴɢ ᴛᴏ ʏᴏᴜʀ ᴘʟᴀɴ ᴀɴᴅ ᴇɴᴊᴏʏ ᴘʀᴇᴍɪᴜᴍ! -‼️ ᴍᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. -‼️ ᴀꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ᴀ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ, ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇ ᴛɪᴍᴇ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴛʜᴇ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ. +‼️ Mᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. +‼️ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ᴀ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ, ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇ ᴛɪᴍᴇ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴛʜᴇ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ. -💎 ᴄʜᴇᴄᴋ ʏᴏᴜʀ ᴘʟᴀɴ → /myplan""" +💎 Cʜᴇᴄᴋ ʏᴏᴜʀ ᴘʟᴀɴ → /myplan
""" From 25da10df3c726531febdaf6b8eb370e6287c0773 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Wed, 16 Sep 2026 10:06:21 +0530 Subject: [PATCH 50/77] Update START_TXT to remove underline formatting --- Script.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Script.py b/Script.py index 5d981071..9c9acba5 100644 --- a/Script.py +++ b/Script.py @@ -1,5 +1,5 @@ class script(object): - START_TXT = """🧸 Sʏsᴛᴇᴍ ɪɴɪᴛɪᴀʟɪᴢᴇᴅ 🎧 + START_TXT = """🧸 Sʏsᴛᴇᴍ ɪɴɪᴛɪᴀʟɪᴢᴇᴅ 🎧 ʜᴇʏ {}, {} From 79a12a38e89fcb2b5351ce2b44de6f3b5ec1c4f0 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Wed, 16 Sep 2026 10:11:31 +0530 Subject: [PATCH 51/77] Update pmfilter.py --- plugins/pmfilter.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/pmfilter.py b/plugins/pmfilter.py index 6295f6e1..3e6425cb 100644 --- a/plugins/pmfilter.py +++ b/plugins/pmfilter.py @@ -184,7 +184,7 @@ async def next_page(bot, query): ) btn.insert(0, [ - InlineKeyboardButton("ʀᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info"), + InlineKeyboardButton("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) @@ -204,7 +204,7 @@ async def next_page(bot, query): ] ) btn.insert(0, [ - InlineKeyboardButton("ʀᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info"), + InlineKeyboardButton("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton("Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) ]) if ULTRA_FAST_MODE: @@ -455,7 +455,7 @@ async def filter_qualities_cb_handler(client: Client, query: CallbackQuery): ) btn.insert(0, [ - InlineKeyboardButton("ʀᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info"), + InlineKeyboardButton("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) ]) @@ -473,7 +473,7 @@ async def filter_qualities_cb_handler(client: Client, query: CallbackQuery): ) btn.insert(0, [ - InlineKeyboardButton("ʀᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info"), + InlineKeyboardButton("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) @@ -608,7 +608,7 @@ async def filter_languages_cb_handler(client: Client, query: CallbackQuery): ) btn.insert(0, [ - InlineKeyboardButton("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info"), + InlineKeyboardButton("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) ] @@ -626,7 +626,7 @@ async def filter_languages_cb_handler(client: Client, query: CallbackQuery): ]) btn.insert(0, [ - InlineKeyboardButton("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info"), + InlineKeyboardButton("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) ]) @@ -756,7 +756,7 @@ async def filter_seasons_cb_handler(client: Client, query: CallbackQuery): btn.insert( 0, [ - InlineKeyboardButton("ʀᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info"), + InlineKeyboardButton("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton("Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS), ], ) @@ -1203,7 +1203,7 @@ async def cb_handler(client: Client, query: CallbackQuery): ), parse_mode=enums.ParseMode.HTML, reply_markup=InlineKeyboardMarkup([[ - InlineKeyboardButton("🚀 Buy Premium 🚀", callback_data="premium_info") + InlineKeyboardButton("🚀 Bᴜʏ ᴘʀᴇᴍɪᴜᴍ 🚀", callback_data="premium_info") ]]) ) await asyncio.sleep(DELETE_TIME) @@ -1474,7 +1474,7 @@ async def _schedule_delete(sent_obj, orig_msg, delay): ) btn.insert(0, [ - InlineKeyboardButton("ʀᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info"), + InlineKeyboardButton("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) @@ -1493,7 +1493,7 @@ async def _schedule_delete(sent_obj, orig_msg, delay): ) btn.insert(0, [ - InlineKeyboardButton("ʀᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info"), + InlineKeyboardButton("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) ]) From d9f7fb72d7a4db18a28dc1f7c75e6ce8b66572f2 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Wed, 16 Sep 2026 12:34:49 +0530 Subject: [PATCH 52/77] Fix typo in button label for 'About' section --- plugins/pmfilter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/pmfilter.py b/plugins/pmfilter.py index 3e6425cb..6a3c6ea8 100644 --- a/plugins/pmfilter.py +++ b/plugins/pmfilter.py @@ -1094,7 +1094,7 @@ async def cb_handler(client: Client, query: CallbackQuery): InlineKeyboardButton('🔰 Aᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://telegram.me/{temp.U_NAME}?startgroup=true') ],[ InlineKeyboardButton(' Hᴇʟᴘ 📢', callback_data='help'), - InlineKeyboardButton(' ᴀʙᴏᴜᴛ 📖', callback_data='about') + InlineKeyboardButton(' Aʙᴏᴜᴛ 📖', callback_data='about') ],[ InlineKeyboardButton('Tᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), InlineKeyboardButton('Uᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), From 58de205ef1d6044b2e3ef54e40a226233bbd9a9a Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Thu, 17 Sep 2026 12:17:29 +0530 Subject: [PATCH 53/77] Fix typo in button label for 'About' --- plugins/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/commands.py b/plugins/commands.py index 1c25c55e..3bfe2ec2 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -221,7 +221,7 @@ async def _delete_files(msgs, notif_msg, delay): InlineKeyboardButton('🔰 Aᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://t.me/{temp.U_NAME}?startgroup=true') ],[ InlineKeyboardButton(' Hᴇʟᴘ 📢', callback_data='help'), - InlineKeyboardButton(' ᴀʙᴏᴜᴛ 📖', callback_data='about') + InlineKeyboardButton(' Aʙᴏᴜᴛ 📖', callback_data='about') ],[ InlineKeyboardButton('Tᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), InlineKeyboardButton('Uᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), From 96f3ad0ec19eb47e42b57e16a8727e54d81affa3 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Mon, 21 Sep 2026 18:52:06 +0530 Subject: [PATCH 54/77] Update commands.py From 934f8d1e137dca8ac2a98bdbc4ac182d54b6b380 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Mon, 21 Sep 2026 18:58:57 +0530 Subject: [PATCH 55/77] Fix duplicate message edit in clean_groups function From 8df78fc426d4f2a98fbd53aaf9e46cac360aa876 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Mon, 21 Sep 2026 19:27:14 +0530 Subject: [PATCH 56/77] Update commands.py --- plugins/commands.py | 47 ++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/plugins/commands.py b/plugins/commands.py index 579d783b..c2db9b41 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -12,7 +12,7 @@ from datetime import datetime, timedelta from database.refer import referdb from database.config_db import mdb -from pyrogram.types import LinkPreviewOptions, InlineKeyboardButton, InlineKeyboardMarkup, Message, ReplyKeyboardMarkup, CopyTextButton +from pyrogram.types import LinkPreviewOptions, InlineKeyboardButton, InlineKeyboardMarkup, Message, ReplyKeyboardMarkup from pyrogram import Client, filters, enums, StopPropagation from pyrogram.errors import FloodWait, UserNotParticipant , ChannelInvalid, PeerIdInvalid from database.ia_filterdb import Media, Media2, get_file_details, unpack_new_file_id, get_bad_files, save_file @@ -84,11 +84,10 @@ async def start(client, message): btn_complete = [[ InlineKeyboardButton("🫶🏻 Cʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ɢᴇᴛ ғɪʟᴇ 🕊", url=verifiedfiles), ]] - reply_markup = InlineKeyboardMarkup(btn) - dlt=await m.reply_photo( - photo=(VERIFY_IMG), - caption=msg.format(message.from_user.mention, get_readable_time(TWO_VERIFY_GAP)), - reply_markup=reply_markup, + dlt = await m.reply_photo( + photo="https://i.ibb.co/RkXnCM07/Chat-GPT-Image-Sep-15-2026-10-11-43-AM.jpg", + caption=msg.format(m.from_user.mention), + reply_markup=InlineKeyboardMarkup(btn_complete), parse_mode=enums.ParseMode.HTML ) @@ -222,7 +221,7 @@ async def _delete_files(msgs, notif_msg, delay): InlineKeyboardButton('🔰 Aᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ 🔰', url=f'http://t.me/{temp.U_NAME}?startgroup=true') ],[ InlineKeyboardButton(' Hᴇʟᴘ 📢', callback_data='help'), - InlineKeyboardButton(' Aʙᴏᴜᴛ 📖', callback_data='about') + InlineKeyboardButton(' ᴀʙᴏᴜᴛ 📖', callback_data='about') ],[ InlineKeyboardButton('Tᴏᴘ sᴇᴀʀᴄʜɪɴɢ ⭐', callback_data="topsearch"), InlineKeyboardButton('Uᴘɢʀᴀᴅᴇ 🎟', callback_data="premium_info"), @@ -490,8 +489,8 @@ async def _delete_files(msgs, notif_msg, delay): btn = await stream_buttons(message.from_user.id, file_id) msg = await client.send_cached_media( chat_id=message.from_user.id, - file_id=file_id, cover=cover, + file_id=file_id, caption=f_caption, protect_content=settings.get('file_secure', PROTECT_CONTENT) if settings else PROTECT_CONTENT, reply_markup=InlineKeyboardMarkup(btn) @@ -564,7 +563,8 @@ async def _delete_files(msgs, notif_msg, delay): f_caption=DREAMX_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption) except Exception as e: logger.exception(e) - pass + f_caption = f_caption + if f_caption is None: f_caption = clean_filename(files.file_name) btn = await stream_buttons(message.from_user.id, file_id) @@ -866,9 +866,10 @@ async def requests(bot, message): logger.exception("Failed to create invite link") invite_link = None if invite_link: - btn = [[InlineKeyboardButton('ᴊᴏɪɴ ᴄʜᴀɴɴᴇʟ', url=invite_link)]] - if getattr(reported_post, "link", None): - btn[0].append(InlineKeyboardButton('ᴠɪᴇᴡ ʀᴇǫᴜᴇꜱᴛ', url=reported_post.link)) + btn = [[ + InlineKeyboardButton('ᴊᴏɪɴ ᴄʜᴀɴɴᴇʟ', url=invite_link), + InlineKeyboardButton('ᴠɪᴇᴡ ʀᴇǫᴜᴇꜱᴛ', url=reported_post.link) + ]] await message.reply_text("ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ʜᴀꜱ ʙᴇᴇɴ ᴀᴅᴅᴇᴅ! ᴘʟᴇᴀꜱᴇ ᴡᴀɪᴛ ꜰᴏʀ ꜱᴏᴍᴇ ᴛɪᴍᴇ.\n\nᴊᴏɪɴ ᴄʜᴀɴɴᴇʟ ꜰɪʀꜱᴛ & ᴠɪᴇᴡ ʀᴇǫᴜᴇꜱᴛ.", reply_markup=InlineKeyboardMarkup(btn)) else: await message.reply_text("ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ʜᴀꜱ ʙᴇᴇɴ ᴀᴅᴅᴇᴅ! ᴘʟᴇᴀꜱᴇ ᴡᴀɪᴛ ꜰᴏʀ ꜱᴏᴍᴇ ᴛɪᴍᴇ.") @@ -879,17 +880,24 @@ async def requests(bot, message): @Client.on_message(filters.command("send") & filters.user(ADMINS)) async def send_msg(bot, message): if message.reply_to_message: - parts = message.text.split(" ", 1) - if len(parts) < 2: - return await message.reply_text("ᴜꜱᴇ ᴛʜɪꜱ ᴄᴏᴍᴍᴀɴᴅ ᴀꜱ ᴀ ʀᴇᴘʟʏ ᴛᴏ ᴀɴʏ ᴍᴇꜱꜱᴀɢᴇ ᴜꜱɪɴɢ ᴛʜᴇ ᴛᴀʀɢᴇᴛ ᴄʜᴀᴛ ɪᴅ. ꜰᴏʀ ᴇɢ: /send ᴜꜱᴇʀɪᴅ") - target_id = parts[1] + target_id = message.text.split(" ", 1)[1] + out = "Users Saved In DB Are:\n\n" + success = False try: user = await bot.get_users(target_id) - if await db.is_user_exist(user.id): + users = await db.get_all_users() + async for usr in users: + out += f"{usr['id']}" + out += '\n' + if str(user.id) in str(out): await message.reply_to_message.copy(int(user.id)) + success = True + else: + success = False + if success: await message.reply_text(f"ʏᴏᴜʀ ᴍᴇꜱꜱᴀɢᴇ ʜᴀꜱ ʙᴇᴇɴ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ꜱᴇɴᴛ ᴛᴏ {user.mention}.") else: - await message.reply_text("ᴛʜɪꜱ ᴜꜱᴇʀ ʜᴀꜱɴ'ᴛ ꜱᴛᴀʀᴛᴇᴅ ᴛʜɪꜱ ʙᴏᴛ ʏᴇᴛ !") + await message.reply_text("ᴛʜɪꜱ ᴜꜱᴇʀ ᴅɪᴅɴ'ᴛ ꜱᴛᴀʀᴛᴇᴅ ᴛʜɪꜱ ʙᴏᴛ ʏᴇᴛ !") except Exception as e: await message.reply_text(f"Error: {e}") else: @@ -1561,3 +1569,6 @@ async def clean_groups_handler(client, message): except Exception as e: logger.error("Error in clean_groups loop: %s", e) await msg.edit(f'**Clean Groups Complete**\n\nTotal Processed: {processed}\nDeleted: {deleted_count}') + + + From 685c77f27933542a2018d64a0e7b90e660811bb4 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Mon, 21 Sep 2026 19:51:39 +0530 Subject: [PATCH 57/77] Fix formatting and improve exception handling --- plugins/commands.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/commands.py b/plugins/commands.py index c2db9b41..4acd41ec 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -168,7 +168,7 @@ async def _delete_msg(msg_to_delete, delay): if f_caption is None: f_caption = clean_filename(files1.file_name) - + btn = await stream_buttons(message.from_user.id, decoded_file_id) sent_msg = await client.send_cached_media( chat_id=message.from_user.id, file_id=decoded_file_id, @@ -305,13 +305,13 @@ async def _delete_files(msgs, notif_msg, delay): try: uss = await client.get_users(user_id) except Exception: - return + return referdb.add_user(message.from_user.id) fromuse = referdb.get_refer_points(user_id) + 10 if fromuse == 100: referdb.add_refer_points(user_id, 0) - await message.reply_text(script.REFER_INVITED_ALRT.format(uss.mention)) - await client.send_message(chat_id=user_id, text=script.REFER_CONGRATS_ALRT.format(message.from_user.mention)) + await message.reply_text(script.REFER_INVITED_ALRT.format(uss.mention)) + await client.send_message(chat_id=user_id, text=script.REFER_CONGRATS_ALRT.format(message.from_user.mention)) seconds = 2592000 if seconds > 0: expiry_time = datetime.now() + timedelta(seconds=seconds) @@ -323,7 +323,7 @@ async def _delete_files(msgs, notif_msg, delay): link_preview_options=LinkPreviewOptions(is_disabled=True) ) for admin in ADMINS: - await client.send_message(chat_id=admin, text=f"Sᴜᴄᴄᴇss ғᴜʟʟʏ ᴛᴀsᴋ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ʙʏ ᴛʜɪs ᴜsᴇʀ:\n\nuser Nᴀᴍᴇ: {uss.mention}\n\nUsᴇʀ ɪᴅ: {uss.id}!") + await client.send_message(chat_id=admin, text=f"Sᴜᴄᴄᴇss ғᴜʟʟʏ ᴛᴀsᴋ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ʙʏ ᴛʜɪs ᴜsᴇʀ:\n\nuser Nᴀᴍᴇ: {uss.mention}\n\nUsᴇʀ ɪᴅ: {uss.id}!") else: referdb.add_refer_points(user_id, fromuse) await message.reply_text(script.REFER_INVITED_ALRT.format(uss.mention)) From b312950c9e1b64ef111fd2927ddf67db02986df4 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Mon, 21 Sep 2026 20:19:35 +0530 Subject: [PATCH 58/77] Update commands.py From 550982d238841a0dfbbb97407f64189a0ce68aef Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Mon, 21 Sep 2026 20:43:14 +0530 Subject: [PATCH 59/77] Update commands.py --- plugins/commands.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/commands.py b/plugins/commands.py index 4acd41ec..e38d0adf 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -99,8 +99,9 @@ async def _delete_msg(msg_to_delete, delay): pass asyncio.create_task(_delete_msg(dlt, 300)) + return - # Send files automatically + # Send files automatically - DISABLED, file will be sent only after button click is_sendall = m.command[1].startswith('sendall') decoded_file_id = file_id if not is_sendall: From c63bffa36f7c10006028149e3408d2ca1e0a7b31 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Tue, 22 Sep 2026 09:38:27 +0530 Subject: [PATCH 60/77] Update Script.py --- Script.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Script.py b/Script.py index e1ee1ae4..c76c1f70 100644 --- a/Script.py +++ b/Script.py @@ -410,7 +410,7 @@ class script(object): VERIFICATION_TEXT = """👋 Hᴇʏ {}, -📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ꜰᴏʀ ᴛɪʟʟ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. +📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. #Vᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 1/3 ✓ @@ -425,7 +425,7 @@ class script(object): SECOND_VERIFICATION_TEXT = """👋 ʜᴇʏ {}, -📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ꜰᴏʀ ᴛɪʟʟ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. +📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. #Vᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 2/3 ✓ From 1996f3c3c9729d8daf8cc8d2c41b6aac35132f2a Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Tue, 22 Sep 2026 09:45:57 +0530 Subject: [PATCH 61/77] Update Script.py --- Script.py | 86 +++++++++++++++++++++++++++---------------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/Script.py b/Script.py index c76c1f70..ff313e9e 100644 --- a/Script.py +++ b/Script.py @@ -3,7 +3,7 @@ class script(object): ʜᴇʏ {}, {} -🤖 ɪ ᴀᴍ {}, ᴛʜᴇ ᴍᴏꜱᴛ ᴘᴏᴡᴇʀꜰᴜʟ ᴀᴜᴛᴏ ꜰɪʟᴛᴇʀ ʙᴏᴛ ᴡɪᴛʜ ᴘʀᴇᴍɪᴜᴍ ꜰᴇᴀᴛᴜʀᴇꜱ. +🤖 I ᴀᴍ {}, ᴛʜᴇ ᴍᴏꜱᴛ ᴘᴏᴡᴇʀꜰᴜʟ ᴀᴜᴛᴏ ꜰɪʟᴛᴇʀ ʙᴏᴛ ᴡɪᴛʜ ᴘʀᴇᴍɪᴜᴍ ꜰᴇᴀᴛᴜʀᴇꜱ. """ @@ -11,27 +11,27 @@ class script(object): ʜᴇʏ {}, -🤖 ɪ ᴀᴍ {}, ᴛʜᴇ ᴍᴏꜱᴛ ᴘᴏᴡᴇʀꜰᴜʟ ᴀᴜᴛᴏ ꜰɪʟᴛᴇʀ ʙᴏᴛ ᴡɪᴛʜ ᴘʀᴇᴍɪᴜᴍ ꜰᴇᴀᴛᴜʀᴇꜱ.""" +🤖 I ᴀᴍ {}, ᴛʜᴇ ᴍᴏꜱᴛ ᴘᴏᴡᴇʀꜰᴜʟ ᴀᴜᴛᴏ ꜰɪʟᴛᴇʀ ʙᴏᴛ ᴡɪᴛʜ ᴘʀᴇᴍɪᴜᴍ ꜰᴇᴀᴛᴜʀᴇꜱ.""" HELP_TXT = """ -✨ ʜᴏᴡ ᴛᴏ ʀᴇǫᴜᴇꜱᴛ ᴅʀᴀᴍᴀꜱ & ᴍᴏᴠɪᴇꜱ ✨ +✨ Hᴏᴡ ᴛᴏ ʀᴇǫᴜᴇꜱᴛ ᴅʀᴀᴍᴀꜱ & ᴍᴏᴠɪᴇꜱ ✨ -1️⃣ ꜱᴇᴀʀᴄʜ ᴛʜᴇ ᴄᴏʀʀᴇᴄᴛ ɴᴀᴍᴇ ᴏɴ ɢᴏᴏɢʟᴇ. -2️⃣ ꜱᴇɴᴅ ᴛʜᴇ ɴᴀᴍᴇ ɪɴ ᴛʜᴇ ɢʀᴏᴜᴘ. -3️⃣ ᴜꜱᴇ ᴛʜɪꜱ ꜰᴏʀᴍᴀᴛ: +1️⃣ Sᴇᴀʀᴄʜ ᴛʜᴇ ᴄᴏʀʀᴇᴄᴛ ɴᴀᴍᴇ ᴏɴ ɢᴏᴏɢʟᴇ. +2️⃣ Sᴇɴᴅ ᴛʜᴇ ɴᴀᴍᴇ ɪɴ ᴛʜᴇ ɢʀᴏᴜᴘ. +3️⃣ Uꜱᴇ ᴛʜɪꜱ ꜰᴏʀᴍᴀᴛ: -📌 ꜰᴏʀ ꜱᴇʀɪᴇꜱ: +📌 Fᴏʀ ꜱᴇʀɪᴇꜱ: ➤ ᴅʀᴀᴍᴀ ɴᴀᴍᴇ + S01 (ꜰᴏʀ ꜱᴇᴀꜱᴏɴ 1, ᴄʜᴀɴɢᴇ ꜰᴏʀ ᴏᴛʜᴇʀꜱ) -📌 ꜰᴏʀ ʜɪɴᴅɪ ᴅʀᴀᴍᴀꜱ: +📌 Fᴏʀ ʜɪɴᴅɪ ᴅʀᴀᴍᴀꜱ: ➤ ᴅʀᴀᴍᴀ ɴᴀᴍᴇ + ʜɪɴᴅɪ -📌 ꜰᴏʀ ᴍᴏᴠɪᴇꜱ: +📌 Fᴏʀ ᴍᴏᴠɪᴇꜱ: ➤ ᴍᴏᴠɪᴇ ɴᴀᴍᴇ + ʏᴇᴀʀ (ᴇx: ᴊᴏᴋᴇʀ 2019) -🚀 ꜰᴏʟʟᴏᴡ ᴛʜᴇꜱᴇ ꜱᴛᴇᴘꜱ !! +🚀 Fᴏʟʟᴏᴡ ᴛʜᴇꜱᴇ ꜱᴛᴇᴘꜱ ᴛᴏ ɢᴇᴛ ʙᴇsᴛ ʀᴇsᴜʟᴛ !! """ ABOUT_TXT = """╭────[Mʏ Dᴇᴛᴀɪʟs ]────⍟ @@ -143,40 +143,40 @@ class script(object):
ᴘʟᴇᴀꜱᴇ ꜰᴏʀᴡᴀʀᴅ ᴛʜɪꜱ ꜰɪʟᴇ ᴛᴏ ꜱᴏᴍᴇᴡʜᴇʀᴇ ᴇʟꜱᴇ & ꜱᴛᴀʀᴛ ᴅᴏᴡɴʟᴏᴀᴅɪɴɢ ᴛʜᴇʀᴇ
""" - I_CUDNT = """sᴏʀʀʏ ɴᴏ ꜰɪʟᴇs ᴡᴇʀᴇ ꜰᴏᴜɴᴅ ꜰᴏʀ ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ {} 😕 + I_CUDNT = """Sᴏʀʀʏ ɴᴏ ꜰɪʟᴇs ᴡᴇʀᴇ ꜰᴏᴜɴᴅ ꜰᴏʀ ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ {} 😕 -ᴄʜᴇᴄᴋ ʏᴏᴜʀ sᴘᴇʟʟɪɴɢ ɪɴ ɢᴏᴏɢʟᴇ ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ 😃 +Cʜᴇᴄᴋ ʏᴏᴜʀ sᴘᴇʟʟɪɴɢ ɪɴ ɢᴏᴏɢʟᴇ ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ 😃 -📝 ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ ꜰᴏʀᴍᴀᴛ 👇 +📝 Mᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ ꜰᴏʀᴍᴀᴛ 👇 -⚜️ ᴇxᴀᴍᴘʟᴇ : Jawan or Jawan 2023 +⚜️ Exᴀᴍᴘʟᴇ : Jawan or Jawan 2023 -📝 ꜱᴇʀɪᴇꜱ ʀᴇǫᴜᴇꜱᴛ ꜰᴏʀᴍᴀᴛ 👇 +📝 Sᴇʀɪᴇꜱ ʀᴇǫᴜᴇꜱᴛ ꜰᴏʀᴍᴀᴛ 👇 -⚜️ ᴇxᴀᴍᴘʟᴇ : Loki S01 or Loki S01E04 or Lucifer S03E24 +⚜️ Exᴀᴍᴘʟᴇ : Loki S01 or Loki S01E04 or Lucifer S03E24 -🚯 ᴅᴏɴᴛ ᴜꜱᴇ ➠ ':(!,./)""" +🚯 Dᴏɴᴛ ᴜꜱᴇ ➠ ':(!,./)""" - MVE_NT_FND = NOT_FOUND_TXT = """😌 ᴛʜɪꜱ ᴍᴏᴠɪᴇ ɪꜱ ɴᴏᴛ ᴀᴠᴀɪʟᴀʙʟᴇ ɪɴ ᴍʏ ᴅᴀᴛᴀʙᴀꜱᴇ. + MVE_NT_FND = NOT_FOUND_TXT = """😌 Tʜɪꜱ ᴍᴏᴠɪᴇ ɪꜱ ɴᴏᴛ ᴀᴠᴀɪʟᴀʙʟᴇ ɪɴ ᴍʏ ᴅᴀᴛᴀʙᴀꜱᴇ.
😌 यह ᴍᴏᴠɪᴇ मुझे ᴍᴇʀᴇ ᴅᴀᴛᴀʙᴀꜱᴇ में नहीं मिली।
""" - ALREADY_AVAILABLE_TXT = """ʜᴇʏ {}, + ALREADY_AVAILABLE_TXT = """Hᴇʏ {}, Yᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ɪꜱ ᴀʟʀᴇᴀᴅʏ ᴀᴠᴀɪʟᴀʙʟᴇ ✅
📂 ꜰɪʟᴇꜱ ꜰᴏᴜɴᴅ : {} 🔍 ꜱᴇᴀʀᴄʜ : {}
-‼️ ᴛʜɪs ɪs ᴀ sᴜᴘᴘᴏʀᴛ ɢʀᴏᴜᴘ sᴏ ᴛʜᴀᴛ ʏᴏᴜ ᴄᴀɴ'ᴛ ɢᴇᴛ ғɪʟᴇs ғʀᴏᴍ ʜᴇʀᴇ... +‼️ Tʜɪs ɪs ᴀ sᴜᴘᴘᴏʀᴛ ɢʀᴏᴜᴘ sᴏ ᴛʜᴀᴛ ʏᴏᴜ ᴄᴀɴ'ᴛ ɢᴇᴛ ғɪʟᴇs ғʀᴏᴍ ʜᴇʀᴇ... -📝 ꜱᴇᴀʀᴄʜ ʜᴇʀᴇ : 👇
""" +📝 Sᴇᴀʀᴄʜ ʜᴇʀᴇ : 👇
""" - MAINTENANCE_TXT = """🛑 ꜱᴇʀᴠɪᴄᴇ ᴜɴᴅᴇʀ ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ 🛑 + MAINTENANCE_TXT = """🛑 Sᴇʀᴠɪᴄᴇ ᴜɴᴅᴇʀ ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ 🛑 -ʜᴇʏ {}, ᴡᴇ ᴀʀᴇ ᴄᴜʀʀᴇɴᴛʟʏ ᴜᴘᴅᴀᴛɪɴɢ ᴏᴜʀ ꜱʏꜱᴛᴇᴍꜱ ᴛᴏ ꜱᴇʀᴠᴇ ʏᴏᴜ ʙᴇᴛᴛᴇʀ. ᴛʜᴇ ꜱᴇʀᴠɪᴄᴇ ɪꜱ ᴛᴇᴍᴘᴏʀᴀʀɪʟʏ ᴅɪꜱᴀʙʟᴇᴅ. +Hᴇʏ {}, ᴡᴇ ᴀʀᴇ ᴄᴜʀʀᴇɴᴛʟʏ ᴜᴘᴅᴀᴛɪɴɢ ᴏᴜʀ ꜱʏꜱᴛᴇᴍꜱ ᴛᴏ ꜱᴇʀᴠᴇ ʏᴏᴜ ʙᴇᴛᴛᴇʀ. ᴛʜᴇ ꜱᴇʀᴠɪᴄᴇ ɪꜱ ᴛᴇᴍᴘᴏʀᴀʀɪʟʏ ᴅɪꜱᴀʙʟᴇᴅ. -
ᴛʜᴇ ꜱᴇʀᴠɪᴄᴇ ɪꜱ ᴄᴜʀʀᴇɴᴛʟʏ ᴜɴᴅᴇʀ ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ. ᴘʟᴇᴀꜱᴇ ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ. 😊
""" +
Tʜᴇ ꜱᴇʀᴠɪᴄᴇ ɪꜱ ᴄᴜʀʀᴇɴᴛʟʏ ᴜɴᴅᴇʀ ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ. ᴘʟᴇᴀꜱᴇ ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ. 😊
""" PM_SEARCH_DISABLED_TXT = """🙋 ʜᴇʏ {} 😍, @@ -192,49 +192,49 @@ class script(object): 🆔 ɪᴅ : {} 💬 ᴍᴇssᴀɢᴇ : {}""" - LINK_EXPIRED_TXT = """‼️ ʟɪɴᴋ ᴇxᴘɪʀᴇᴅ, ᴘʟᴇᴀꜱᴇ ᴛʀʏ ᴀɢᴀɪɴ...""" + LINK_EXPIRED_TXT = """‼️ Lɪɴᴋ ᴇxᴘɪʀᴇᴅ, ᴘʟᴇᴀꜱᴇ ᴛʀʏ ᴀɢᴀɪɴ...""" - REFER_TXT = """ʜᴀʏ, ʏᴏᴜʀ ʀᴇꜰᴇʀ ʟɪɴᴋ: + REFER_TXT = """Hᴇʏ, ʏᴏᴜʀ ʀᴇꜰᴇʀ ʟɪɴᴋ: https://t.me/{}?start=reff_{} -
sʜᴀʀᴇ ᴛʜɪs ʟɪɴᴋ ᴡɪᴛʜ ʏᴏᴜʀ ғʀɪᴇɴᴅs. ᴇᴀᴄʜ ᴛɪᴍᴇ ᴛʜᴇʏ ᴊᴏɪɴ, ʏᴏᴜ ᴡɪʟʟ ɢᴇᴛ 10 ʀᴇꜰꜰᴇʀᴀʟ ᴘᴏɪɴᴛs ᴀɴᴅ ᴀꜰᴛᴇʀ 100 ᴘᴏɪɴᴛs ʏᴏᴜ ᴡɪʟʟ ɢᴇᴛ 1 ᴍᴏɴᴛʜ ᴘʀᴇᴍɪᴜᴍ sᴜʙsᴄʀɪᴘᴛɪᴏɴ.
""" +
Sʜᴀʀᴇ ᴛʜɪs ʟɪɴᴋ ᴡɪᴛʜ ʏᴏᴜʀ ғʀɪᴇɴᴅs. ᴇᴀᴄʜ ᴛɪᴍᴇ ᴛʜᴇʏ ᴊᴏɪɴ, ʏᴏᴜ ᴡɪʟʟ ɢᴇᴛ 10 ʀᴇꜰꜰᴇʀᴀʟ ᴘᴏɪɴᴛs ᴀɴᴅ ᴀꜰᴛᴇʀ 100 ᴘᴏɪɴᴛs ʏᴏᴜ ᴡɪʟʟ ɢᴇᴛ 1 ᴍᴏɴᴛʜ ᴘʀᴇᴍɪᴜᴍ sᴜʙsᴄʀɪᴘᴛɪᴏɴ.
""" REFER_SELF_ALRT = """Hᴇʏ Dᴜᴅᴇ, Yᴏᴜ Cᴀɴ'ᴛ Rᴇғᴇʀ Yᴏᴜʀsᴇʟғ 🤣! -
sʜᴀʀᴇ ʟɪɴᴋ ʏᴏᴜʀ ғʀɪᴇɴᴅ ᴀɴᴅ ɢᴇᴛ 10 ʀᴇғᴇʀʀᴀʟ ᴘᴏɪɴᴛ ɪғ ʏᴏᴜ ᴀʀᴇ ᴄᴏʟʟᴇᴄᴛɪɴɢ 100 ʀᴇғᴇʀʀᴀʟ ᴘᴏɪɴᴛs ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ɢᴇᴛ 1 ᴍᴏɴᴛʜ ғʀᴇᴇ ᴘʀᴇᴍɪᴜᴍ ᴍᴇᴍʙᴇʀsʜɪᴘ.
""" +
Sʜᴀʀᴇ ʟɪɴᴋ ʏᴏᴜʀ ғʀɪᴇɴᴅ ᴀɴᴅ ɢᴇᴛ 10 ʀᴇғᴇʀʀᴀʟ ᴘᴏɪɴᴛ ɪғ ʏᴏᴜ ᴀʀᴇ ᴄᴏʟʟᴇᴄᴛɪɴɢ 100 ʀᴇғᴇʀʀᴀʟ ᴘᴏɪɴᴛs ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ɢᴇᴛ 1 ᴍᴏɴᴛʜ ғʀᴇᴇ ᴘʀᴇᴍɪᴜᴍ ᴍᴇᴍʙᴇʀsʜɪᴘ.
""" - REFER_ALREADY_ALRT = """ʏᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ ᴀʟʀᴇᴀᴅʏ ɪɴᴠɪᴛᴇᴅ ❗""" + REFER_ALREADY_ALRT = """Yᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ ᴀʟʀᴇᴀᴅʏ ɪɴᴠɪᴛᴇᴅ ❗""" - REFER_ALREADY_JOINED_ALRT = """‼️ ʏᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ ᴀʟʀᴇᴀᴅʏ ɪɴᴠɪᴛᴇᴅ ᴏʀ ᴊᴏɪɴᴇᴅ""" + REFER_ALREADY_JOINED_ALRT = """‼️ Yᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ ᴀʟʀᴇᴀᴅʏ ɪɴᴠɪᴛᴇᴅ ᴏʀ ᴊᴏɪɴᴇᴅ""" - REFER_CONGRATS_ALRT = """🎉 ᴄᴏɴɢʀᴀᴛᴜʟᴀᴛɪᴏɴs! ʏᴏᴜ ᴡᴏɴ 10 ʀᴇꜰᴇʀʀᴀʟ ᴘᴏɪɴᴛ ʙᴇᴄᴀᴜsᴇ ʏᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ sᴜᴄᴄᴇssꜰᴜʟʟʏ ɪɴᴠɪᴛᴇᴅ ☞ {}!""" + REFER_CONGRATS_ALRT = """🎉 Cᴏɴɢʀᴀᴛᴜʟᴀᴛɪᴏɴs! ʏᴏᴜ ᴡᴏɴ 10 ʀᴇꜰᴇʀʀᴀʟ ᴘᴏɪɴᴛ ʙᴇᴄᴀᴜsᴇ ʏᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ sᴜᴄᴄᴇssꜰᴜʟʟʏ ɪɴᴠɪᴛᴇᴅ ☞ {}!""" - REFER_INVITED_ALRT = """ʏᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ sᴜᴄᴄᴇssꜰᴜʟʟʏ ɪɴᴠɪᴛᴇᴅ ʙʏ {}!""" + REFER_INVITED_ALRT = """Yᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ sᴜᴄᴄᴇssꜰᴜʟʟʏ ɪɴᴠɪᴛᴇᴅ ʙʏ {}!""" - FORCESUB_TXT = """👋 ʜᴇʟʟᴏ {} + FORCESUB_TXT = """👋 Hᴇʟʟᴏ {} -🛑 ʏᴏᴜ ᴍᴜsᴛ ᴊᴏɪɴ ᴛʜᴇ ʀᴇǫᴜɪʀᴇᴅ ᴄʜᴀɴɴᴇʟs ᴛᴏ ᴄᴏɴᴛɪɴᴜᴇ. +🛑 Yᴏᴜ ᴍᴜsᴛ ᴊᴏɪɴ ᴛʜᴇ ʀᴇǫᴜɪʀᴇᴅ ᴄʜᴀɴɴᴇʟs ᴛᴏ ᴄᴏɴᴛɪɴᴜᴇ. -
👉 ᴊᴏɪɴ ᴀʟʟ ᴛʜᴇ ʙᴇʟᴏᴡ ᴄʜᴀɴɴᴇʟs ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ.
""" +
👉 Jᴏɪɴ ᴀʟʟ ᴛʜᴇ ʙᴇʟᴏᴡ ᴄʜᴀɴɴᴇʟs ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ.
""" - BOT_ADD_TXT = """ᴛʜᴀɴᴋ ʏᴏᴜ ғᴏʀ ᴀᴅᴅɪɴɢ ᴍᴇ ᴛᴏ {} ❣️ + BOT_ADD_TXT = """Tʜᴀɴᴋ ʏᴏᴜ ғᴏʀ ᴀᴅᴅɪɴɢ ᴍᴇ ᴛᴏ {} ❣️
ɪғ ʏᴏᴜ ʜᴀᴠᴇ ᴀɴʏ ǫᴜᴇsᴛɪᴏɴs & ᴅᴏᴜʙᴛs ᴀʙᴏᴜᴛ ᴜsɪɴɢ ᴍᴇ ᴄᴏɴᴛᴀᴄᴛ sᴜᴘᴘᴏʀᴛ.
""" - CHAT_RESTRICTED_TXT = """ᴄʜᴀᴛ ɴᴏᴛ ᴀʟʟᴏᴡᴇᴅ 🐞 + CHAT_RESTRICTED_TXT = """Cʜᴀᴛ ɴᴏᴛ ᴀʟʟᴏᴡᴇᴅ 🐞 -
ᴍʏ ᴀᴅᴍɪɴꜱ ʜᴀᴠᴇ ʀᴇꜱᴛʀɪᴄᴛᴇᴅ ᴍᴇ ꜰʀᴏᴍ ᴡᴏʀᴋɪɴɢ ʜᴇʀᴇ ! ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴋɴᴏᴡ ᴍᴏʀᴇ ᴀʙᴏᴜᴛ ɪᴛ ᴄᴏɴᴛᴀᴄᴛ ꜱᴜᴘᴘᴏʀᴛ.
""" +
Mʏ ᴀᴅᴍɪɴꜱ ʜᴀᴠᴇ ʀᴇꜱᴛʀɪᴄᴛᴇᴅ ᴍᴇ ꜰʀᴏᴍ ᴡᴏʀᴋɪɴɢ ʜᴇʀᴇ ! ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴋɴᴏᴡ ᴍᴏʀᴇ ᴀʙᴏᴜᴛ ɪᴛ ᴄᴏɴᴛᴀᴄᴛ ꜱᴜᴘᴘᴏʀᴛ.
""" - LEAVE_CHAT_TXT = """ʜᴇʟʟᴏ ꜰʀɪᴇɴᴅꜱ, + LEAVE_CHAT_TXT = """Hᴇʟʟᴏ ꜰʀɪᴇɴᴅꜱ, -
ᴍʏ ᴀᴅᴍɪɴ ʜᴀꜱ ᴛᴏʟᴅ ᴍᴇ ᴛᴏ ʟᴇᴀᴠᴇ ᴛʜɪꜱ ɢʀᴏᴜᴘ, ꜱᴏ ɪ ʜᴀᴠᴇ ᴛᴏ ɢᴏ ! ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴀᴅᴅ ᴍᴇ ᴀɢᴀɪɴ ᴄᴏɴᴛᴀᴄᴛ ꜱᴜᴘᴘᴏʀᴛ.
""" +
Mʏ ᴀᴅᴍɪɴ ʜᴀꜱ ᴛᴏʟᴅ ᴍᴇ ᴛᴏ ʟᴇᴀᴠᴇ ᴛʜɪꜱ ɢʀᴏᴜᴘ, ꜱᴏ ɪ ʜᴀᴠᴇ ᴛᴏ ɢᴏ ! ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴀᴅᴅ ᴍᴇ ᴀɢᴀɪɴ ᴄᴏɴᴛᴀᴄᴛ ꜱᴜᴘᴘᴏʀᴛ.
""" - SEARCHING_TXT = """ 𝖲𝖾𝖺𝗋𝖼𝗁𝗂𝗇𝗀 𝖿ᴏʀ '{}' 🔎""" + SEARCHING_TXT = """Sᴇᴀʀᴄʜɪɴɢ ғᴏʀ '{}' 🔎""" - TOP_ALRT_MSG = """ꜱᴇᴀʀᴄʜɪɴɢ ꜰᴏʀ ǫᴜᴇʀʏ ɪɴ ᴍʏ ᴅᴀᴛᴀʙᴀꜱᴇ...""" + TOP_ALRT_MSG = """Sᴇᴀʀᴄʜɪɴɢ ꜰᴏʀ ǫᴜᴇʀʏ ɪɴ ᴍʏ ᴅᴀᴛᴀʙᴀꜱᴇ...""" - MELCOW_ENG = """👋 ʜᴇʏ {},\n\n🍁 ᴡᴇʟᴄᴏᴍᴇ ᴛᴏ\n🌟 {} \n\n🔍 ʜᴇʀᴇ ʏᴏᴜ ᴄᴀɴ ꜱᴇᴀʀᴄʜ ʏᴏᴜʀ ꜰᴀᴠᴏᴜʀɪᴛᴇ ᴍᴏᴠɪᴇꜱ ᴏʀ ꜱᴇʀɪᴇꜱ ʙʏ ᴊᴜꜱᴛ ᴛʏᴘɪɴɢ ɪᴛ'ꜱ ɴᴀᴍᴇ 🔎\n\n⚠️ ɪꜰ ʏᴏᴜ'ʀᴇ ʜᴀᴠɪɴɢ ᴀɴʏ ᴘʀᴏʙʟᴇᴍ ʀᴇɢᴀʀᴅɪɴɢ ᴅᴏᴡɴʟᴏᴀᴅɪɴɢ ᴏʀ ꜱᴏᴍᴇᴛʜɪɴɢ ᴇʟꜱᴇ ᴛʜᴇɴ ᴍᴇꜱꜱᴀɢᴇ ʜᴇʀᴇ 👇""" + MELCOW_ENG = """👋 Hᴇʏ {},\n\n🍁 ᴡᴇʟᴄᴏᴍᴇ ᴛᴏ\n🌟 {} \n\n🔍 ʜᴇʀᴇ ʏᴏᴜ ᴄᴀɴ ꜱᴇᴀʀᴄʜ ʏᴏᴜʀ ꜰᴀᴠᴏᴜʀɪᴛᴇ ᴍᴏᴠɪᴇꜱ ᴏʀ ꜱᴇʀɪᴇꜱ ʙʏ ᴊᴜꜱᴛ ᴛʏᴘɪɴɢ ɪᴛ'ꜱ ɴᴀᴍᴇ 🔎\n\n⚠️ ɪꜰ ʏᴏᴜ'ʀᴇ ʜᴀᴠɪɴɢ ᴀɴʏ ᴘʀᴏʙʟᴇᴍ ʀᴇɢᴀʀᴅɪɴɢ ᴅᴏᴡɴʟᴏᴀᴅɪɴɢ ᴏʀ ꜱᴏᴍᴇᴛʜɪɴɢ ᴇʟꜱᴇ ᴛʜᴇɴ ᴍᴇꜱꜱᴀɢᴇ ʜᴇʀᴇ 👇""" DISCLAIMER_TXT = """ ᴛʜɪꜱ ɪꜱ ᴀɴ ᴏᴘᴇɴ ꜱᴏᴜʀᴄᴇ ᴘʀᴏᴊᴇᴄᴛ. From f1f3a5c40b776236c46b175e84b41e764033b64e Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Tue, 22 Sep 2026 10:04:13 +0530 Subject: [PATCH 62/77] Update Script.py --- Script.py | 104 ++++++++++++++++++++++-------------------------------- 1 file changed, 43 insertions(+), 61 deletions(-) diff --git a/Script.py b/Script.py index ff313e9e..9cd95389 100644 --- a/Script.py +++ b/Script.py @@ -6,21 +6,19 @@ class script(object): 🤖 I ᴀᴍ {}, ᴛʜᴇ ᴍᴏꜱᴛ ᴘᴏᴡᴇʀꜰᴜʟ ᴀᴜᴛᴏ ꜰɪʟᴛᴇʀ ʙᴏᴛ ᴡɪᴛʜ ᴘʀᴇᴍɪᴜᴍ ꜰᴇᴀᴛᴜʀᴇꜱ. """ - GSTART_TXT = """🧸 Sʏsᴛᴇᴍ ɪɴɪᴛɪᴀʟɪᴢᴇᴅ 🎧 ʜᴇʏ {}, 🤖 I ᴀᴍ {}, ᴛʜᴇ ᴍᴏꜱᴛ ᴘᴏᴡᴇʀꜰᴜʟ ᴀᴜᴛᴏ ꜰɪʟᴛᴇʀ ʙᴏᴛ ᴡɪᴛʜ ᴘʀᴇᴍɪᴜᴍ ꜰᴇᴀᴛᴜʀᴇꜱ.""" - HELP_TXT = """ ✨ Hᴏᴡ ᴛᴏ ʀᴇǫᴜᴇꜱᴛ ᴅʀᴀᴍᴀꜱ & ᴍᴏᴠɪᴇꜱ ✨ -1️⃣ Sᴇᴀʀᴄʜ ᴛʜᴇ ᴄᴏʀʀᴇᴄᴛ ɴᴀᴍᴇ ᴏɴ ɢᴏᴏɢʟᴇ. -2️⃣ Sᴇɴᴅ ᴛʜᴇ ɴᴀᴍᴇ ɪɴ ᴛʜᴇ ɢʀᴏᴜᴘ. -3️⃣ Uꜱᴇ ᴛʜɪꜱ ꜰᴏʀᴍᴀᴛ: +1⃣ Sᴇᴀʀᴄʜ ᴛʜᴇ ᴄᴏʀʀᴇᴄᴛ ɴᴀᴍᴇ ᴏɴ ɢᴏᴏɢʟᴇ. +2⃣ Sᴇɴᴅ ᴛʜᴇ ɴᴀᴍᴇ ɪɴ ᴛʜᴇ ɢʀᴏᴜᴘ. +3⃣ Uꜱᴇ ᴛʜɪꜱ ꜰᴏʀᴍᴀᴛ: 📌 Fᴏʀ ꜱᴇʀɪᴇꜱ: ➤ ᴅʀᴀᴍᴀ ɴᴀᴍᴇ + S01 (ꜰᴏʀ ꜱᴇᴀꜱᴏɴ 1, ᴄʜᴀɴɢᴇ ꜰᴏʀ ᴏᴛʜᴇʀꜱ) @@ -43,13 +41,14 @@ class script(object): ├⍟ Bᴏᴛ Sᴇʀᴠᴇʀ : Rᴇɴᴅᴇʀ ├⍟ Bᴜɪʟᴅ Sᴛᴀᴛᴜs : ᴠ1.4 [ Sᴛᴀʙʟᴇ ] ╰───────────────⍟""" + RESTART_TXT = """ {} Bᴏᴛ Rᴇsᴛᴀʀᴛᴇᴅ ! 📅 Dᴀᴛᴇ : {} ⏰ Tɪᴍᴇ : {} 🌐 Tɪᴍᴇᴢᴏɴᴇ : Asia/Kolkata -🛠️ Bᴜɪʟᴅ Sᴛᴀᴛᴜs: v1.4 [ Sᴛᴀʙʟᴇ ] +🛠 Bᴜɪʟᴅ Sᴛᴀᴛᴜs: v1.4 [ Sᴛᴀʙʟᴇ ] """ MULTI_STATUS_TXT = """🗃ᴜsᴇʀs ᴅᴀᴛᴀʙᴀsᴇ 🗃 @@ -112,7 +111,7 @@ class script(object): Iᴅ - {} Nᴀᴍᴇ - {} """ - NT_ADMIN_ALRT_TXT = """‼️ Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴀᴅᴍɪɴ ɪɴ ᴛʜɪꜱ ɢʀᴏᴜᴘ ‼️""" + NT_ADMIN_ALRT_TXT = """‼ Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴀᴅᴍɪɴ ɪɴ ᴛʜɪꜱ ɢʀᴏᴜᴘ ‼""" NT_ALRT_TXT = """Not Yours!""" @@ -129,31 +128,29 @@ class script(object): ✨ ᴜɴʟᴏᴄᴋ ᴇxᴄʟᴜsɪᴠᴇ ᴄᴏɴᴛᴇɴᴛ ᴀɴᴅ ꜰᴇᴀᴛᴜʀᴇs 💳 ʙᴜʏ ᴘʀᴇᴍɪᴜᴍ ᴛᴏ ɢᴇᴛ sᴛᴀʀᴛᴇᴅ""" - PRE_STREAM_ALERT = """⚠️ ᴘʀᴇᴍɪᴜᴍ ᴄᴏɴᴛᴇɴᴛ ❗ + PRE_STREAM_ALERT = """⚠ ᴘʀᴇᴍɪᴜᴍ ᴄᴏɴᴛᴇɴᴛ ❗ 🔓 ᴜɴʟᴏᴄᴋ ɪᴛ ʙʏ ᴜᴘɢʀᴀᴅɪɴɢ ᴛᴏ ᴘʀᴇᴍɪᴜᴍ""" - CUDNT_FND = SPELLING_ERROR_TXT = """‼️ ꜱᴘᴇʟʟɪɴɢ ᴍɪꜱᴛᴀᴋᴇ ʙʀᴏ! + CUDNT_FND = SPELLING_ERROR_TXT = """‼ ꜱᴘᴇʟʟɪɴɢ ᴍɪꜱᴛᴀᴋᴇ ʙʀᴏ! 😊 ɴᴏ ᴡᴏʀʀɪᴇꜱ — ᴄʜᴏᴏꜱᴇ ᴛʜᴇ ᴄᴏʀʀᴇᴄᴛ ᴏɴᴇ ʙᴇʟᴏᴡ 👇
👇 नीचे दिए गए विकल्पों में से movie के नाम की सही spelling चुनें
""" - - DEL_MSG = """⚠️ ᴛʜɪꜱ ᴍᴏᴠɪᴇ ꜰɪʟᴇ/ᴠɪᴅᴇᴏ ᴡɪʟʟ ʙᴇ ᴅᴇʟᴇᴛᴇᴅ ɪɴ {} + DEL_MSG = """⚠ ᴛʜɪꜱ ᴍᴏᴠɪᴇ ꜰɪʟᴇ/ᴠɪᴅᴇᴏ ᴡɪʟʟ ʙᴇ ᴅᴇʟᴇᴛᴇᴅ ɪɴ {}
ᴘʟᴇᴀꜱᴇ ꜰᴏʀᴡᴀʀᴅ ᴛʜɪꜱ ꜰɪʟᴇ ᴛᴏ ꜱᴏᴍᴇᴡʜᴇʀᴇ ᴇʟꜱᴇ & ꜱᴛᴀʀᴛ ᴅᴏᴡɴʟᴏᴀᴅɪɴɢ ᴛʜᴇʀᴇ
""" - I_CUDNT = """Sᴏʀʀʏ ɴᴏ ꜰɪʟᴇs ᴡᴇʀᴇ ꜰᴏᴜɴᴅ ꜰᴏʀ ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ {} 😕 Cʜᴇᴄᴋ ʏᴏᴜʀ sᴘᴇʟʟɪɴɢ ɪɴ ɢᴏᴏɢʟᴇ ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ 😃 📝 Mᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ ꜰᴏʀᴍᴀᴛ 👇 -⚜️ Exᴀᴍᴘʟᴇ : Jawan or Jawan 2023 +⚜ Exᴀᴍᴘʟᴇ : Jawan or Jawan 2023 📝 Sᴇʀɪᴇꜱ ʀᴇǫᴜᴇꜱᴛ ꜰᴏʀᴍᴀᴛ 👇 -⚜️ Exᴀᴍᴘʟᴇ : Loki S01 or Loki S01E04 or Lucifer S03E24 +⚜ Exᴀᴍᴘʟᴇ : Loki S01 or Loki S01E04 or Lucifer S03E24 🚯 Dᴏɴᴛ ᴜꜱᴇ ➠ ':(!,./)""" @@ -168,7 +165,7 @@ class script(object):
📂 ꜰɪʟᴇꜱ ꜰᴏᴜɴᴅ : {} 🔍 ꜱᴇᴀʀᴄʜ : {}
-‼️ Tʜɪs ɪs ᴀ sᴜᴘᴘᴏʀᴛ ɢʀᴏᴜᴘ sᴏ ᴛʜᴀᴛ ʏᴏᴜ ᴄᴀɴ'ᴛ ɢᴇᴛ ғɪʟᴇs ғʀᴏᴍ ʜᴇʀᴇ... +‼ Tʜɪs ɪs ᴀ sᴜᴘᴘᴏʀᴛ ɢʀᴏᴜᴘ sᴏ ᴛʜᴀᴛ ʏᴏᴜ ᴄᴀɴ'ᴛ ɢᴇᴛ ғɪʟᴇs ғʀᴏᴍ ʜᴇʀᴇ... 📝 Sᴇᴀʀᴄʜ ʜᴇʀᴇ : 👇
""" @@ -176,7 +173,7 @@ class script(object): Hᴇʏ {}, ᴡᴇ ᴀʀᴇ ᴄᴜʀʀᴇɴᴛʟʏ ᴜᴘᴅᴀᴛɪɴɢ ᴏᴜʀ ꜱʏꜱᴛᴇᴍꜱ ᴛᴏ ꜱᴇʀᴠᴇ ʏᴏᴜ ʙᴇᴛᴛᴇʀ. ᴛʜᴇ ꜱᴇʀᴠɪᴄᴇ ɪꜱ ᴛᴇᴍᴘᴏʀᴀʀɪʟʏ ᴅɪꜱᴀʙʟᴇᴅ. -
Tʜᴇ ꜱᴇʀᴠɪᴄᴇ ɪꜱ ᴄᴜʀʀᴇɴᴛʟʏ ᴜɴᴅᴇʀ ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ. ᴘʟᴇᴀꜱᴇ ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ. 😊
""" +
Tʜᴇ ꜱᴇʀᴠɪᴄᴇ ɪꜱ ᴄᴜʀʀᴇɴᴛʟʏ ᴜɴᴅᴇʀ ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ. ᴘʟᴇᴀsᴇ ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ. 😊
""" PM_SEARCH_DISABLED_TXT = """🙋 ʜᴇʏ {} 😍, @@ -192,13 +189,13 @@ class script(object): 🆔 ɪᴅ : {} 💬 ᴍᴇssᴀɢᴇ : {}""" - LINK_EXPIRED_TXT = """‼️ Lɪɴᴋ ᴇxᴘɪʀᴇᴅ, ᴘʟᴇᴀꜱᴇ ᴛʀʏ ᴀɢᴀɪɴ...""" + LINK_EXPIRED_TXT = """‼ Lɪɴᴋ ᴇxᴘɪʀᴇᴅ, ᴘʟᴇᴀꜱᴇ ᴛʀʏ ᴀɢᴀɪɴ...""" REFER_TXT = """Hᴇʏ, ʏᴏᴜʀ ʀᴇꜰᴇʀ ʟɪɴᴋ: https://t.me/{}?start=reff_{} -
Sʜᴀʀᴇ ᴛʜɪs ʟɪɴᴋ ᴡɪᴛʜ ʏᴏᴜʀ ғʀɪᴇɴᴅs. ᴇᴀᴄʜ ᴛɪᴍᴇ ᴛʜᴇʏ ᴊᴏɪɴ, ʏᴏᴜ ᴡɪʟʟ ɢᴇᴛ 10 ʀᴇꜰꜰᴇʀᴀʟ ᴘᴏɪɴᴛs ᴀɴᴅ ᴀꜰᴛᴇʀ 100 ᴘᴏɪɴᴛs ʏᴏᴜ ᴡɪʟʟ ɢᴇᴛ 1 ᴍᴏɴᴛʜ ᴘʀᴇᴍɪᴜᴍ sᴜʙsᴄʀɪᴘᴛɪᴏɴ.
""" +
Sʜᴀʀᴇ ᴛʜɪs ʟɪɴᴋ ᴡɪᴛʜ ʏᴏᴜʀ ғʀɪᴇɴᴅs. ᴇᴀᴄʜ ᴛɪᴍᴇ ᴛʜᴇʏ ᴊᴏɪɴ, ʏᴏᴜ ᴡɪʟʟ ɢᴇᴛ 10 ʀᴇғғᴇʀᴀʟ ᴘᴏɪɴᴛs ᴀɴᴅ ᴀꜰᴛᴇʀ 100 ᴘᴏɪɴᴛs ʏᴏᴜ ᴡɪʟʟ ɢᴇᴛ 1 ᴍᴏɴᴛʜ ᴘʀᴇᴍɪᴜᴍ sᴜʙsᴄʀɪᴘᴛɪᴏɴ.
""" REFER_SELF_ALRT = """Hᴇʏ Dᴜᴅᴇ, Yᴏᴜ Cᴀɴ'ᴛ Rᴇғᴇʀ Yᴏᴜʀsᴇʟғ 🤣! @@ -206,9 +203,9 @@ class script(object): REFER_ALREADY_ALRT = """Yᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ ᴀʟʀᴇᴀᴅʏ ɪɴᴠɪᴛᴇᴅ ❗""" - REFER_ALREADY_JOINED_ALRT = """‼️ Yᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ ᴀʟʀᴇᴀᴅʏ ɪɴᴠɪᴛᴇᴅ ᴏʀ ᴊᴏɪɴᴇᴅ""" + REFER_ALREADY_JOINED_ALRT = """‼ Yᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ ᴀʟʀᴇᴀᴅʏ ɪɴᴠɪᴛᴇᴅ ᴏʀ ᴊᴏɪɴᴇᴅ""" - REFER_CONGRATS_ALRT = """🎉 Cᴏɴɢʀᴀᴛᴜʟᴀᴛɪᴏɴs! ʏᴏᴜ ᴡᴏɴ 10 ʀᴇꜰᴇʀʀᴀʟ ᴘᴏɪɴᴛ ʙᴇᴄᴀᴜsᴇ ʏᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ sᴜᴄᴄᴇssꜰᴜʟʟʏ ɪɴᴠɪᴛᴇᴅ ☞ {}!""" + REFER_CONGRATS_ALRT = """🎉 Cᴏɴɢʀᴀᴛᴜʟᴀᴛɪᴏɴs! ʏᴏᴜ ᴡᴏɴ 10 ʀᴇғᴇʀʀᴀʟ ᴘᴏɪɴᴛ ʙᴇᴄᴀᴜsᴇ ʏᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ sᴜᴄᴄᴇssꜰᴜʟʟʏ ɪɴᴠɪᴛᴇᴅ ☞ {}!""" REFER_INVITED_ALRT = """Yᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ sᴜᴄᴄᴇssꜰᴜʟʟʏ ɪɴᴠɪᴛᴇᴅ ʙʏ {}!""" @@ -218,7 +215,7 @@ class script(object):
👉 Jᴏɪɴ ᴀʟʟ ᴛʜᴇ ʙᴇʟᴏᴡ ᴄʜᴀɴɴᴇʟs ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ.
""" - BOT_ADD_TXT = """Tʜᴀɴᴋ ʏᴏᴜ ғᴏʀ ᴀᴅᴅɪɴɢ ᴍᴇ ᴛᴏ {} ❣️ + BOT_ADD_TXT = """Tʜᴀɴᴋ ʏᴏᴜ ғᴏʀ ᴀᴅᴅɪɴɢ ᴍᴇ ᴛᴏ {} ❣
ɪғ ʏᴏᴜ ʜᴀᴠᴇ ᴀɴʏ ǫᴜᴇsᴛɪᴏɴs & ᴅᴏᴜʙᴛs ᴀʙᴏᴜᴛ ᴜsɪɴɢ ᴍᴇ ᴄᴏɴᴛᴀᴄᴛ sᴜᴘᴘᴏʀᴛ.
""" @@ -228,18 +225,18 @@ class script(object): LEAVE_CHAT_TXT = """Hᴇʟʟᴏ ꜰʀɪᴇɴᴅꜱ, -
Mʏ ᴀᴅᴍɪɴ ʜᴀꜱ ᴛᴏʟᴅ ᴍᴇ ᴛᴏ ʟᴇᴀᴠᴇ ᴛʜɪꜱ ɢʀᴏᴜᴘ, ꜱᴏ ɪ ʜᴀᴠᴇ ᴛᴏ ɢᴏ ! ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴀᴅᴅ ᴍᴇ ᴀɢᴀɪɴ ᴄᴏɴᴛᴀᴄᴛ ꜱᴜᴘᴘᴏʀᴛ.
""" +
Mʏ ᴀᴅᴍɪɴ ʜᴀꜱ ᴛᴏʟᴅ ᴍᴇ ᴛᴏ ʟᴇᴀᴠᴇ ᴛʜɪs ɢʀᴏᴜᴘ, ꜱᴏ ɪ ʜᴀᴠᴇ ᴛᴏ ɢᴏ ! ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴀᴅᴅ ᴍᴇ ᴀɢᴀɪɴ ᴄᴏɴᴛᴀᴄᴛ ꜱᴜᴘᴘᴏʀᴛ.
""" SEARCHING_TXT = """Sᴇᴀʀᴄʜɪɴɢ ғᴏʀ '{}' 🔎""" TOP_ALRT_MSG = """Sᴇᴀʀᴄʜɪɴɢ ꜰᴏʀ ǫᴜᴇʀʏ ɪɴ ᴍʏ ᴅᴀᴛᴀʙᴀꜱᴇ...""" - MELCOW_ENG = """👋 Hᴇʏ {},\n\n🍁 ᴡᴇʟᴄᴏᴍᴇ ᴛᴏ\n🌟 {} \n\n🔍 ʜᴇʀᴇ ʏᴏᴜ ᴄᴀɴ ꜱᴇᴀʀᴄʜ ʏᴏᴜʀ ꜰᴀᴠᴏᴜʀɪᴛᴇ ᴍᴏᴠɪᴇꜱ ᴏʀ ꜱᴇʀɪᴇꜱ ʙʏ ᴊᴜꜱᴛ ᴛʏᴘɪɴɢ ɪᴛ'ꜱ ɴᴀᴍᴇ 🔎\n\n⚠️ ɪꜰ ʏᴏᴜ'ʀᴇ ʜᴀᴠɪɴɢ ᴀɴʏ ᴘʀᴏʙʟᴇᴍ ʀᴇɢᴀʀᴅɪɴɢ ᴅᴏᴡɴʟᴏᴀᴅɪɴɢ ᴏʀ ꜱᴏᴍᴇᴛʜɪɴɢ ᴇʟꜱᴇ ᴛʜᴇɴ ᴍᴇꜱꜱᴀɢᴇ ʜᴇʀᴇ 👇""" + MELCOW_ENG = """👋 Hᴇʏ {},\n\n🍁 ᴡᴇʟᴄᴏᴍᴇ ᴛᴏ\n🌟 {} \n\n🔍 ʜᴇʀᴇ ʏᴏᴜ ᴄᴀɴ ꜱᴇᴀʀᴄʜ ʏᴏᴜʀ ꜰᴀᴠᴏᴜʀɪᴛᴇ ᴍᴏᴠɪᴇꜱ ᴏʀ ꜱᴇʀɪᴇꜱ ʙʏ ᴊᴜꜱᴛ ᴛʏᴘɪɴɢ ɪᴛ'ꜱ ɴᴀᴍᴇ 🔎\n\n⚠ ɪꜰ ʏᴏᴜ'ʀᴇ ʜᴀᴠɪɴɢ ᴀɴʏ ᴘʀᴏʙʟᴇᴍ ʀᴇɢᴀʀᴅɪɴɢ ᴅᴏᴡɴʟᴏᴀᴅɪɴɢ ᴏʀ ꜱᴏᴍᴇᴛʜɪɴɢ ᴇʟꜱᴇ ᴛʜᴇɴ ᴍᴇꜱꜱᴀɢᴇ ʜᴇʀᴇ 👇""" DISCLAIMER_TXT = """ ᴛʜɪꜱ ɪꜱ ᴀɴ ᴏᴘᴇɴ ꜱᴏᴜʀᴄᴇ ᴘʀᴏᴊᴇᴄᴛ. -ᴀʟʟ ᴛʜᴇ ꜰɪʟᴇꜱ ɪɴ ᴛʜɪꜱ ʙᴏᴛ ᴀʀᴇ ꜰʀᴇᴇʟʏ ᴀᴠᴀɪʟᴀʙʟᴇ ᴏɴ ᴛʜᴇ ɪɴᴛᴇʀɴᴇᴛ ᴏʀ ᴘᴏꜱᴛᴇᴅ ʙʏ ꜱᴏᴍᴇʙᴏᴅʏ ᴇʟꜱᴇ. ᴊᴜꜱᴛ ꜰᴏʀ ᴇᴀꜱʏ ꜱᴇᴀʀᴄʜɪɴɢ ᴛʜɪꜱ ʙᴏᴛ ɪꜱ ɪɴᴅᴇxɪɴɢ ꜰɪʟᴇꜱ ᴡʜɪᴄʜ ᴀʀᴇ ᴀʟʀᴇᴀᴅʏ ᴜᴘʟᴏᴀᴅᴇᴅ ᴏɴ ᴛᴇʟᴇɢʀᴀᴍ. ᴡᴇ ʀᴇꜱᴘᴇᴄᴛ ᴀʟʟ ᴛʜᴇ ᴄᴏᴘʏʀɪɢʜᴛ ʟᴀᴡꜱ ᴀɴᴅ ᴡᴏʀᴋꜱ ɪɴ ᴄᴏᴍᴘʟɪᴀɴᴄᴇ ᴡɪᴛʜ ᴅᴍᴄᴀ ᴀɴᴅ ᴇᴜᴄᴅ. ɪꜰ ᴀɴʏᴛʜɪɴɢ ɪꜱ ᴀɢᴀɪɴꜱᴛ ʟᴀᴡ ᴘʟᴇᴀꜱᴇ ᴄᴏɴᴛᴀᴄᴛ ᴍᴇ ꜱᴏ ᴛʜᴀᴛ ɪᴛ ᴄᴀɴ ʙᴇ ʀᴇᴍᴏᴠᴇᴅ ᴀꜱᴀᴘ. ɪᴛ ɪꜱ ꜰᴏʀʙɪᴅᴅᴇɴ ᴛᴏ ᴅᴏᴡɴʟᴏᴀᴅ, ꜱᴛʀᴇᴀᴍ, ʀᴇᴘʀᴏᴅᴜᴄᴇ, ꜱʜᴀʀᴇ ᴏʀ ᴄᴏɴꜱᴜᴍᴇ ᴄᴏɴᴛᴇɴᴛ ᴡɪᴛʜᴏᴜᴛ ᴇxᴘʟɪᴄɪᴛ ᴘᴇʀᴍɪꜱꜱɪᴏɴ ꜰʀᴏᴍ ᴛʜᴇ ᴄᴏɴᴛᴇɴᴛ ᴄʀᴇᴀᴛᴏʀ ᴏʀ ʟᴇɢᴀʟ ᴄᴏᴘʏʀɪɢʜᴛ ʜᴏʟᴅᴇʀ. ɪꜰ ʏᴏᴜ ʙᴇʟɪᴇᴠᴇ ᴛʜɪꜱ ʙᴏᴛ ɪꜱ ᴠɪᴏʟᴀᴛɪɴɢ ʏᴏᴜʀ ɪɴᴛᴇʟʟᴇᴄᴛᴜᴀʟ ᴘʀᴏᴘᴇʀᴛʏ, ᴄᴏɴᴛᴀᴄᴛ ᴛʜᴇ ʀᴇꜱᴘᴇᴄᴛɪᴠᴇ ᴄʜᴀɴɴᴇʟꜱ ꜰᴏʀ ʀᴇᴍᴏᴠᴀʟ. ᴛʜᴇ ʙᴏᴛ ᴅᴏᴇꜱ ɴᴏᴛ ᴏᴡɴ ᴀɴʏ ᴏꜰ ᴛʜᴇꜱᴇ ᴄᴏɴᴛᴇɴᴛꜱ, ɪᴛ ᴏɴʟʏ ɪɴᴅᴇxᴇꜱ ᴛʜᴇ ꜰɪʟᴇꜱ ꜰʀᴏᴍ ᴛᴇʟᴇɢʀᴀᴍ. +ᴀʟʟ ᴛʜᴇ ꜰɪʟᴇꜱ ɪɴ ᴛʜɪꜱ ʙᴏᴛ ᴀʀᴇ ꜰʀᴇᴇʟʏ ᴀᴠᴀɪʟᴀʙʟᴇ ᴏɴ ᴛʜᴇ ɪɴᴛᴇʀɴᴇᴛ ᴏʀ ᴘᴏꜱᴛᴇᴅ ʙʏ ꜱᴏᴍᴇʙᴏᴅʏ ᴇʟꜱᴇ. ᴊᴜꜱᴛ ꜰᴏʀ ᴇᴀꜱʏ ꜱᴇᴀʀᴄʜɪɴɢ ᴛʜɪꜱ ʙᴏᴛ ɪꜱ ɪɴᴅᴇxɪɴɢ ꜰɪʟᴇꜱ ᴡʜɪᴄʜ ᴀʀᴇ ᴀʟʀᴇᴀᴅʏ ᴜᴘʟᴏᴀᴅᴇᴅ ᴏɴ ᴛᴇʟᴇɢʀᴀᴍ. ᴡᴇ ʀᴇꜱᴘᴇᴄᴛ ᴀʟʟ ᴛʜᴇ ᴄᴏᴘʏʀɪɢʜᴛ ʟᴀᴡꜱ ᴀɴᴅ ᴡᴏʀᴋꜱ ɪɴ ᴄᴏᴍᴘʟɪᴀɴᴄᴇ ᴡɪᴛʜ ᴅᴍᴄᴀ ᴀɴᴅ ᴇᴜᴄᴅ. ɪꜰ ᴀɴʏᴛʜɪɴɢ ɪꜱ ᴀɢᴀɪɴꜱᴛ ʟᴀᴡ ᴘʟᴇᴀꜱᴇ ᴄᴏɴᴛᴀᴄᴛ ᴍᴇ ꜱᴏ ᴛʜᴀᴛ ɪᴛ ᴄᴀɴ ʙᴇ ʀᴇᴍᴏᴠᴇᴅ ᴀꜱᴀᴘ. ɪᴛ ɪꜱ ꜰᴏʀʙɪᴅᴅᴇɴ ᴛᴏ ᴅᴏᴡɴʟᴏᴀᴅ, ꜱᴛʀᴇᴀᴍ, ʀᴇᴘʀᴏᴅᴜᴄᴇ, ꜱʜᴀʀᴇ ᴏʀ ᴄᴏɴꜱᴜᴍᴇ ᴄᴏɴᴛᴇɴᴛ ᴡɪᴛʜᴏᴜᴛ ᴇxᴘʟɪᴄɪᴛ ᴘᴇʀᴍɪꜱꜱɪᴏɴ ꜰʀᴏᴍ ᴛʜᴇ ᴄᴏɴᴛᴇɴᴛ ᴄʀᴇᴀᴛᴏʀ ᴏʀ ʟᴇɢᴀʟ ᴄᴏᴘʏʀɪɢʜᴛ ʜᴏʟᴅᴇʀ. ɪꜰ ʏᴏᴜ ʙᴇʟɪᴇᴠᴇ ᴛʜɪꜱ ʙᴏᴛ ɪꜱ ᴠɪᴏʟᴀᴛɪɴɢ ʏᴏᴜʀ ɪɴᴛᴇʟʟᴇᴄᴛᴜᴀʟ ᴘʀᴏᴘᴇʀᴛʏ, ᴄᴏɴᴛᴀᴄᴛ ᴛʜᴇ ʀᴇꜱᴘᴇᴄᴛɪᴠᴇ ᴄʜᴀɴɴᴇʟꜱ ꜰᴏʀ ʀᴇᴍᴏᴠᴀʟ. ᴛʜᴇ ʙᴏᴛ ᴅᴏᴇꜱ ɴᴏᴛ ᴏᴡɴ ᴀɴʏ ᴏꜰ ᴛʜᴇꜱᴇ ᴄᴏɴᴛᴇɴᴛꜱ, ɪᴛ ᴏɴʟʏ ɪɴᴅᴇxᴇs ᴛʜᴇ ꜰɪʟᴇꜱ ꜰʀᴏᴍ ᴛᴇʟᴇɢʀᴀᴍ. """ DREAMXBOTZ_DONATION = DONATE_TXT = """👋 ʜᴇʏ {}, @@ -256,10 +253,7 @@ class script(object): ➤ 📷 Qʀ ᴄᴏᴅᴇ → ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ꜱᴄᴀɴ ➤ 💸 ᴜᴘɪ ɪᴅ → {} -‼️ ᴍᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴅᴏɴᴀᴛɪɴɢ.""" - - - +‼ ᴍᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴅᴏɴᴀᴛɪɴɢ.""" NORSLTS = """ #NoResults @@ -269,33 +263,34 @@ class script(object): Mᴇꜱꜱᴀɢᴇ : {}""" - CAPTION = """{file_name}\n\n⚜️ Powered By : [ ᴅʀᴇᴀᴍxʙᴏᴛᴢ ]""" + CAPTION = """{file_name}\n\n⚜ Powered By : [ ᴅʀᴇᴀᴍxʙᴏᴛᴢ ]""" - + # === UPDATED WITH DIVIDER AND RUNTIME - HD PRO STYLE === MOVIE_UPDATE_NOTIFY_TXT = """ 📥New {tag} Added
✨ ᴛɪᴛʟᴇ : {filename} {year} - +⚬────────✧────────⚬ 🎭 ɢᴇɴʀᴇs : {genres} 📺 ᴏᴛᴛ : {ott} -🎞️ ǫᴜᴀʟɪᴛʏ : {quality} +⏰ ʀᴜɴᴛɪᴍᴇ : {runtime} +🎞 ǫᴜᴀʟɪᴛʏ : {quality} 🎧 ᴀᴜᴅɪᴏ : {language} -🔥 ʀᴀᴛɪɴɢ : {rating} +🔥 ʀᴀᴛɪɴɢ : {rating}/10 {episodes}
+⚬────────✧────────⚬ 🔍 Sᴇᴀʀᴄʜ → {search_link} """ - IMDB_TEMPLATE_TXT = """{title} ({year}) ʀᴀᴛɪɴɢ : {rating} ɢᴇɴʀᴇ : {genres} ᴀᴜᴅɪᴏ : {languages} -sʜᴏᴡɴ ɪɴ : {remaining_seconds} sᴇᴄ⚡️ +sʜᴏᴡɴ ɪɴ : {remaining_seconds} sᴇᴄ⚡ ʀᴇǫ ʙʏ : {message.from_user.mention}""" LOGO = r""" @@ -310,12 +305,7 @@ class script(object): 𝙱𝙾𝚃 𝚆𝙾𝚁𝙺𝙸𝙽𝙶 𝙿𝚁𝙾𝙿𝙴𝚁𝙻𝚈.... """ - - #PLANS - - - - PREMIUM_TEXT = """
🎖️ Aᴠᴀɪʟᴀʙʟᴇ ᴘʟᴀɴs
+ PREMIUM_TEXT = """
🎖 Aᴠᴀɪʟᴀʙʟᴇ ᴘʟᴀɴs
◉ 07 ᴅᴀʏꜱ - 10 ₹ / 10 ꜱᴛᴀʀ @@ -326,8 +316,8 @@ class script(object): •─────•─────────•─────• -‼️ Mᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. -‼️ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇꜱ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" +‼ Mᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. +‼ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇꜱ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" PREMIUM_STAR_TEXT = """
Pᴀʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅ: Tᴇʟᴇɢʀᴀᴍ ꜱᴛᴀʀꜱ ⭐
@@ -346,8 +336,7 @@ class script(object): 💢 ᴍᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. -‼️ ᴀꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴘʟᴇᴀꜱᴇ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.
""" - +‼ ᴀꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴘʟᴇᴀꜱᴇ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.
""" PREMIUM_END_TEXT = """ʜᴇʏ {}, @@ -360,7 +349,6 @@ class script(object): Hᴀᴍᴀʀɪ ᴀɴʏᴀ ʏᴏᴊɴᴀᴏɴ ᴋɪ ᴊᴀᴀɴᴄʜ ᴋᴀʀɴᴇ ᴋᴇ ʟɪʏᴇ /plan ᴘᴀʀ ᴋʟɪᴄᴋ ᴋᴀʀᴇɪɴ। """ - BPREMIUM_TXT = """
🎁 ᴘʀᴇᴍɪᴜᴍ ꜰᴇᴀᴛᴜʀᴇꜱ :
○ ɴᴏ ɴᴇᴇᴅ ᴛᴏ ᴠᴇʀɪꜰʏ @@ -378,12 +366,11 @@ class script(object): •─────•─────────•─────• ◉ ᴄʜᴇᴄᴋ ʏᴏᴜʀ ᴀᴄᴛɪᴠᴇ ᴘʟᴀɴ : /myplan -‼️ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇꜱ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" - +‼ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇꜱ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" PREPLANS_TXT = PREMIUM_TXT = """👋 ʜᴇʏ {}, -
🎖️ ᴀᴠᴀɪʟᴀʙʟᴇ ᴘʟᴀɴꜱ
+
🎖 ᴀᴠᴀɪʟᴀʙʟᴇ ᴘʟᴀɴꜱ
◉ 07 ᴅᴀʏꜱ - 10 ₹ ◉ 15 ᴅᴀʏꜱ - 20 ₹ @@ -393,29 +380,25 @@ class script(object): •─────•─────────•─────• -🏷️ Pᴀʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅꜱ - Uᴘɪ +🏷 Pᴀʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅꜱ - Uᴘɪ 💸 Uᴘɪ ɪᴅ → {} 📷 Qʀ ᴄᴏᴅᴇ → ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ꜱᴄᴀɴ 🧾 Pᴀʏ ᴀᴄᴄᴏʀᴅɪɴɢ ᴛᴏ ʏᴏᴜʀ ᴘʟᴀɴ ᴀɴᴅ ᴇɴᴊᴏʏ ᴘʀᴇᴍɪᴜᴍ! -‼️ Mᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. -‼️ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ᴀ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ, ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇ ᴛɪᴍᴇ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴛʜᴇ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ. +‼ Mᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. +‼ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ᴀ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ, ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇ ᴛɪᴍᴇ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴛʜᴇ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ. 💎 Cʜᴇᴄᴋ ʏᴏᴜʀ ᴘʟᴀɴ → /myplan
""" - - - VERIFICATION_TEXT = """👋 Hᴇʏ {}, -📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. +📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ. #Vᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 1/3 ✓ Iꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴅɪʀᴇᴄᴛ ꜰɪʟᴇs ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ᴛᴀᴋᴇ ᴘʀᴇᴍɪᴜᴍ sᴇʀᴠɪᴄᴇ (ɴᴏ ɴᴇᴇᴅ ᴛᴏ ᴠᴇʀɪꜰʏ).""" - VERIFY_COMPLETE_TEXT = """👋 Hᴇʏ {} ❤, @@ -425,7 +408,7 @@ class script(object): SECOND_VERIFICATION_TEXT = """👋 ʜᴇʏ {}, -📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. +📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ. #Vᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 2/3 ✓ @@ -439,7 +422,7 @@ class script(object): THIRDT_VERIFICATION_TEXT = """👋 ʜᴇʏ {}, -📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. +📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ. #Vᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 3/3 ✓ @@ -459,7 +442,6 @@ class script(object): #Verification_{}_Completed""" - ADMIN_CMD = """ʜᴇʏ 👋, 📚 ʜᴇʀᴇ ᴀʀᴇ ᴍʏ ᴄᴏᴍᴍᴀɴᴅꜱ ʟɪꜱᴛ ꜰᴏʀ ᴀʟʟ ʙᴏᴛ ᴀᴅᴍɪɴꜱ ⇊ @@ -478,7 +460,7 @@ class script(object): • /disable - ᴅɪꜱᴀʙʟᴇ ᴀ ᴄʜᴀᴛ. • /ban - ʙᴀɴ ᴀ ᴜꜱᴇʀ. • /unban - ᴜɴʙᴀɴ ᴀ ᴜꜱᴇʀ. -• /broadcast - ʙʀᴏᴀᴅᴄᴀꜱᴛ ᴀ ᴍᴇꜱꜱᴀɢᴇ ᴛᴏ ᴀʟʟ ᴜꜱᴇʀꜱ. +• /broadcast - ʙʀᴏᴀᴅᴄᴀsᴛ ᴀ ᴍᴇꜱꜱᴀɢᴇ ᴛᴏ ᴀʟʟ ᴜꜱᴇʀꜱ. • /grp_broadcast - ʙʀᴏᴀᴅᴄᴀsᴛ ᴀ ᴍᴇssᴀɢᴇ ᴛᴏ ᴀʟʟ ᴄᴏɴɴᴇᴄᴛᴇᴅ ɢʀᴏᴜᴘs. • /deletefiles - ᴅᴇʟᴇᴛᴇ CᴀᴍRɪᴘ ᴀɴᴅ PʀᴇDVD ғɪʟᴇs ғʀᴏᴍ ᴛʜᴇ ʙᴏᴛ's ᴅᴀᴛᴀʙᴀsᴇ. • /send - ꜱᴇɴᴅ ᴍᴇꜱꜱᴀɢᴇ ᴛᴏ ᴀ ᴘᴀʀᴛɪᴄᴜʟᴀʀ ᴜꜱᴇʀ. From 50385d98512c5f50a588fa94c6e3291b887b2ef1 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Tue, 22 Sep 2026 10:04:35 +0530 Subject: [PATCH 63/77] Update utils.py --- utils.py | 253 ++++++++++++++++--------------------------------------- 1 file changed, 74 insertions(+), 179 deletions(-) diff --git a/utils.py b/utils.py index 57b0f92c..f2a94a0a 100644 --- a/utils.py +++ b/utils.py @@ -4,7 +4,7 @@ import random import string from info import ULTRA_FAST_MODE, MAX_LIST_ELM, BAD_WORDS, LONG_IMDB_DESCRIPTION, IS_VERIFY, MAX_B_TN, TUTORIAL, TUTORIAL_2, TUTORIAL_3, LOG_CHANNEL, TMDB_ON_SEARCH -from imdbkit import IMDBKit # pyrefly: ignore +from imdbkit import IMDBKit import asyncio from pyrogram.types import Message, InlineKeyboardButton from pyrogram.errors import InputUserDeactivated, UserNotParticipant, FloodWait, UserIsBlocked, PeerIdInvalid, ChatAdminRequired @@ -18,7 +18,6 @@ from shortzy import Shortzy from plugins.Dreamxfutures.Imdbposter import get_movie_detailsx - logger = logging.getLogger(__name__) def get_random_mix_id(): @@ -31,12 +30,14 @@ def get_random_mix_id(): imdb = IMDBKit() +# OMDB API KEY - from env, fallback to your key ab767d2b +OMDB_API_KEY = os.environ.get("OMDB_API_KEY", "ab767d2b") + BANNED = {} SMART_OPEN = '“' SMART_CLOSE = '”' START_CHAR = ('\'', '"', SMART_OPEN) - class temp(object): BANNED_USERS = [] BANNED_CHATS = [] @@ -57,10 +58,26 @@ class temp(object): TEMP_INVITE_LINKS = {} REQ_LINKS = {} +async def fetch_omdb_details(imdb_id): + """Fetch OMDB details for best result - IMDB + OMDB + TMDB combined""" + if not imdb_id or not OMDB_API_KEY: + return {} + try: + if not imdb_id.startswith("tt"): + imdb_id = f"tt{imdb_id}" + url = f"http://www.omdbapi.com/?i={imdb_id}&apikey={OMDB_API_KEY}" + async with aiohttp.ClientSession() as session: + async with session.get(url, timeout=10) as resp: + if resp.status == 200: + data = await resp.json() + if data.get("Response") == "True": + return data + except Exception as e: + logger.warning(f"OMDB fetch failed for {imdb_id}: {e}") + return {} async def is_req_subscribed(bot, user_id, rqfsub_channels): btn = [] - async def check_req_channel(ch_id): if await db.has_joined_channel(user_id, ch_id): return None @@ -73,41 +90,31 @@ async def check_req_channel(ch_id): pass except Exception as e: logger.error(f"Error checking membership in {ch_id}: {e}") - try: chat = await bot.get_chat(ch_id) if ch_id in temp.REQ_LINKS: invite_link = temp.REQ_LINKS[ch_id] else: - invite = await bot.create_chat_invite_link( - ch_id, - creates_join_request=True - ) + invite = await bot.create_chat_invite_link(ch_id, creates_join_request=True) invite_link = invite.invite_link temp.REQ_LINKS[ch_id] = invite_link - - return [InlineKeyboardButton(f"⛔️ Join {chat.title}", url=invite_link)] + return [InlineKeyboardButton(f"⛔ Join {chat.title}", url=invite_link)] except ChatAdminRequired: logger.warning(f"Bot not admin in {ch_id}") except Exception as e: logger.warning(f"Invite link error for {ch_id}: {e}") return None - tasks = [check_req_channel(ch_id) for ch_id in rqfsub_channels] results = await asyncio.gather(*tasks) - for res in results: if res: btn.append(res) - return btn async def is_subscribed(bot, user_id, fsub_channels): btn = [] - async def check_channel(channel_id): try: - # No need to get chat object separately await bot.get_chat_member(channel_id, user_id) except UserNotParticipant: try: @@ -119,14 +126,11 @@ async def check_channel(channel_id): except Exception as e: logger.exception(f"is_subscribed error for {channel_id}: {e}") return None - tasks = [check_channel(channel_id) for channel_id in fsub_channels] results = await asyncio.gather(*tasks) - for button in results: if button: btn.append([button]) - return btn async def is_check_admin(bot, chat_id, user_id): @@ -160,7 +164,6 @@ async def users_broadcast(user_id, message, is_pin): logger.error(f"[BROADCAST FAIL] user={user_id} | {type(e).__name__}: {e}") return False, "Error" - async def groups_broadcast(chat_id, message, is_pin): try: m = await message.copy(chat_id=chat_id) @@ -189,7 +192,6 @@ async def junk_group(chat_id, message): await db.delete_chat(int(chat_id)) logger.info(f"{chat_id} - PeerIdInvalid") return False, "deleted", f'{e}\n\n' - async def clear_junk(user_id, message): try: @@ -221,29 +223,19 @@ async def get_status(bot_id): return False async def add_name_to_db(filename): - """ - Helper function to add a filename to the database. - """ - return await db.add_name(filename) - def listx_to_str(k): if k is None or k == "": return "N/A" - - # Handle non-iterable types first if not hasattr(k, '__iter__') or isinstance(k, (str, int, float)): return str(k) - result = [] for elem in k: if elem and str(elem).strip(): result.append(str(elem).strip()) - if MAX_LIST_ELM and len(result) > MAX_LIST_ELM: result = result[:int(MAX_LIST_ELM)] - return ', '.join(result) if result else "N/A" async def get_poster(query, bulk=False, id=False, file=None): @@ -251,7 +243,6 @@ async def get_poster(query, bulk=False, id=False, file=None): query = (query.strip()).lower() title = query year_val = None - year_list = re.findall(r'[1-2]\d{3}$', query, re.IGNORECASE) if year_list: year_val = year_list[0] @@ -260,26 +251,20 @@ async def get_poster(query, bulk=False, id=False, file=None): year_list = re.findall(r'[1-2]\d{3}', file, re.IGNORECASE) if year_list: year_val = year_list[0] - search_result = await asyncio.to_thread(imdb.search_movie, title.lower()) if not search_result or not search_result.titles: return None - movie_list = search_result.titles[:MAX_LIST_ELM] - if year_val: filtered = [m for m in movie_list if m.year and str(m.year) == str(year_val)] if not filtered: filtered = movie_list else: filtered = movie_list - kind_filter = ['movie', 'tv series', 'tvSeries', 'tvMiniSeries', 'tvMovie'] filtered_kind = [m for m in filtered if m.kind and m.kind in kind_filter] - if not filtered_kind: filtered_kind = filtered - if bulk: return filtered_kind[:MAX_LIST_ELM] if not filtered_kind: @@ -306,6 +291,13 @@ async def get_poster(query, bulk=False, id=False, file=None): imdb_id = movie.imdb_id if not imdb_id.startswith("tt"): imdb_id = f"tt{imdb_id}" + + # Fetch OMDB for better rating/runtime + omdb_data = await fetch_omdb_details(imdb_id) + rating = omdb_data.get("imdbRating") if omdb_data.get("imdbRating") and omdb_data.get("imdbRating") != "N/A" else str(movie.rating) + runtime = omdb_data.get("Runtime") if omdb_data.get("Runtime") and omdb_data.get("Runtime") != "N/A" else listx_to_str(movie.duration) + genres = omdb_data.get("Genre") if omdb_data.get("Genre") and omdb_data.get("Genre") != "N/A" else listx_to_str(movie.genres) + return { 'title': movie.title, 'votes': movie.votes, @@ -321,7 +313,7 @@ async def get_poster(query, bulk=False, id=False, file=None): 'kind': movie.kind, "imdb_id": imdb_id, "cast": listx_to_str(movie.stars), - "runtime": listx_to_str(movie.duration), + "runtime": runtime, "countries": listx_to_str(movie.countries), "certificates": listx_to_str(movie.certificates), "languages": listx_to_str(movie.languages), @@ -334,115 +326,20 @@ async def get_poster(query, bulk=False, id=False, file=None): "distributors": listx_to_str([c.name for c in movie.distributors]), 'release_date': date, 'year': movie.year, - 'genres': listx_to_str(movie.genres), + 'genres': genres, 'poster': movie.cover_url, 'plot': plot, - 'rating': str(movie.rating), + 'rating': rating, "url": movie.url or f"https://www.imdb.com/title/{imdb_id}" } -#Remove Nahi Kiya Hu.....Agar Tujha Remove Karna Hai To Kar Dena -async def old_get_poster(query, bulk=False, id=False, file=None): - if not id: - query = (query.strip()).lower() - title = query - year = re.findall(r'[1-2]\d{3}$', query, re.IGNORECASE) - imdb - if year: - year = list_to_str(year[:1]) - title = (query.replace(year, "")).strip() - elif file is not None: - year = re.findall(r'[1-2]\d{3}', file, re.IGNORECASE) - if year: - year = list_to_str(year[:1]) - else: - year = None - movieid = imdb.search_movie(title.lower(), results=10) - if not movieid: - return None - if year: - filtered=list(filter(lambda k: str(k.get('year')) == str(year), movieid)) - if not filtered: - filtered = movieid - else: - filtered = movieid - movieid=list(filter(lambda k: k.get('kind') in ['movie', 'tv series'], filtered)) - if not movieid: - movieid = filtered - if bulk: - return movieid - movieid = movieid[0].movieID - else: - movieid = query - movie = imdb.get_movie(movieid) - imdb.update(movie, info=['main', 'vote details']) - if movie.get("original air date"): - date = movie["original air date"] - elif movie.get("year"): - date = movie.get("year") - else: - date = "N/A" - plot = "" - if not LONG_IMDB_DESCRIPTION: - plot = movie.get('plot') - if plot and len(plot) > 0: - plot = plot[0] - else: - plot = movie.get('plot outline') - if plot and len(plot) > 800: - plot = plot[0:800] + "..." - STANDARD_GENRES = { - 'Action', 'Adventure', 'Animation', 'Biography', 'Comedy', 'Crime', 'Documentary', - 'Drama', 'Family', 'Fantasy', 'Film-Noir', 'History', 'Horror', 'Music', - 'Musical', 'Mystery', 'Romance', 'Sci-Fi', 'Sport', 'Thriller', 'War', 'Western' - } - raw_genres = movie.get("genres", "N/A") - if isinstance(raw_genres, str): - genre_list = [g.strip() for g in raw_genres.split(",")] - genres = ", ".join(g for g in genre_list if g in STANDARD_GENRES) or "N/A" - else: - genres = ", ".join(g for g in raw_genres if g in STANDARD_GENRES) or "N/A" - - return { - 'title': movie.get('title'), - 'votes': movie.get('votes'), - "aka": list_to_str(movie.get("akas")), - "seasons": movie.get("number of seasons"), - "box_office": movie.get('box office'), - 'localized_title': movie.get('localized title'), - 'kind': movie.get("kind"), - "imdb_id": f"tt{movie.get('imdbID')}", - "cast": list_to_str(movie.get("cast")), - "runtime": list_to_str(movie.get("runtimes")), - "countries": list_to_str(movie.get("countries")), - "certificates": list_to_str(movie.get("certificates")), - "languages": list_to_str(movie.get("languages")), - "director": list_to_str(movie.get("director")), - "writer":list_to_str(movie.get("writer")), - "producer":list_to_str(movie.get("producer")), - "composer":list_to_str(movie.get("composer")) , - "cinematographer":list_to_str(movie.get("cinematographer")), - "music_team": list_to_str(movie.get("music department")), - "distributors": list_to_str(movie.get("distributors")), - 'release_date': date, - 'year': movie.get('year'), - 'genres': genres, - 'poster': movie.get('full-size cover url'), - 'plot': plot, - 'rating': str(movie.get("rating")), - 'url':f'https://www.imdb.com/title/tt{movieid}' - } - async def get_posterx(query, bulk=False, id=False, file=None): """ - Fetches movie details from TMDB using the get_movie_detailsx helper - and formats the output to be compatible with the original get_poster function. + Fetches movie details from TMDB + OMDB + IMDB combined for best result """ if not id: - # The get_movie_detailsx function handles searching by query string. details = await get_movie_detailsx(query, file=file) else: - # Assumes the 'id' is a TMDB ID or IMDb ID that get_movie_detailsx can handle. details = await get_movie_detailsx(query, id=True) if not details or details.get("error"): @@ -458,24 +355,41 @@ async def get_posterx(query, bulk=False, id=False, file=None): if plot and len(plot) > 800: plot = plot[0:800] + "..." - # --- Mapping TMDB keys to the original IMDb key format --- - def list_to_str(val): if isinstance(val, list): return ", ".join(str(x) for x in val if x) return str(val) if val else "" + imdb_id = details.get('imdb_id') + omdb_data = {} + if imdb_id: + omdb_data = await fetch_omdb_details(imdb_id) + + # Best rating: OMDB > TMDB > N/A + rating = omdb_data.get("imdbRating") if omdb_data.get("imdbRating") and omdb_data.get("imdbRating") != "N/A" else details.get("rating", "N/A") + runtime = omdb_data.get("Runtime") if omdb_data.get("Runtime") and omdb_data.get("Runtime") != "N/A" else list_to_str(details.get("runtime")) + genres = omdb_data.get("Genre") if omdb_data.get("Genre") and omdb_data.get("Genre") != "N/A" else list_to_str(details.get("genres")) + # Runtime convert if needed - keep as "1h 51m" format + if runtime and "min" in str(runtime).lower() and "h" not in str(runtime).lower(): + try: + mins = int(re.search(r'\d+', str(runtime)).group()) + h = mins // 60 + m = mins % 60 + runtime = f"{h}h {m}m" if h else f"{m}m" + except: + pass + return { 'title': details.get('title'), 'votes': details.get('votes'), - "aka": None, # Not typically provided by TMDB in this format + "aka": None, "seasons": details.get('seasons'), "box_office": details.get('box_office'), 'localized_title': details.get('localized_title'), 'kind': 'movie' if 'movie' in details.get('tmdb_url', '') else 'tv series', - "imdb_id": details.get('imdb_id'), + "imdb_id": imdb_id, "cast": list_to_str(details.get("cast")), - "runtime": list_to_str(details.get("runtime")), + "runtime": runtime or list_to_str(details.get("runtime")), "countries": list_to_str(details.get("countries")), "certificates": list_to_str(details.get("certificates")), "languages": list_to_str(details.get("languages")), @@ -484,15 +398,17 @@ def list_to_str(val): "producer": list_to_str(details.get("producer")), "composer": list_to_str(details.get("composer")), "cinematographer": list_to_str(details.get("cinematographer")), - "music_team": None, # Not provided by the TMDB API wrapper + "music_team": None, "distributors": list_to_str(details.get("distributors")), 'release_date': details.get('release_date'), 'year': details.get('year'), - 'genres': list_to_str(details.get("genres")), + 'genres': genres, 'poster': details.get('poster_url'), 'backdrop' : details.get('backdrop_url'), + 'poster_url': details.get('poster_url'), + 'backdrop_url': details.get('backdrop_url'), 'plot': plot, - 'rating': str(details.get("rating", "N/A")), + 'rating': str(rating) if rating else "N/A", 'url': details.get('tmdb_url') } @@ -503,12 +419,10 @@ async def search_gagala(text): } text = text.replace(" ", "+") url = f"https://www.google.com/search?q={text}" - async with aiohttp.ClientSession() as session: async with session.get(url, headers=usr_agent, timeout=30) as response: response.raise_for_status() html = await response.text() - soup = await asyncio.to_thread(BeautifulSoup, html, 'html.parser') titles = soup.find_all('h3') return [title.get_text() for title in titles if title.get_text().strip()] @@ -557,7 +471,6 @@ async def delete_group_setting(group_id, key): def clean_filename(file_name): prefixes = ('[', '@', 'www.') unwanted = {word.lower() for word in BAD_WORDS} - file_name = ' '.join( word for word in file_name.split() if not (word.startswith(prefixes) or word.lower() in unwanted) @@ -587,27 +500,27 @@ def extract_request_content(message_text): return message_text.strip() def generate_settings_text(settings, title, reset_done=False): - note = "\n📌 ɴᴏᴛᴇ :- ʀᴇꜱᴇᴛ ꜱᴜᴄᴄᴇꜱꜱғᴜʟʟʏ ✅" if reset_done else "" - return f"""⚙️ ʏᴏᴜʀ sᴇᴛᴛɪɴɢs ꜰᴏʀ - {title} + note = "\n📌 ɴᴏᴛᴇ :- ʀᴇꜱᴇᴛ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ✅" if reset_done else "" + return f"""⚙ ʏᴏᴜʀ sᴇᴛᴛɪɴɢs ꜰᴏʀ - {title} -✅️ 1sᴛ ᴠᴇʀɪꜰʏ sʜᴏʀᴛɴᴇʀ +✅ 1sᴛ ᴠᴇʀɪꜰʏ sʜᴏʀᴛɴᴇʀ ɴᴀᴍᴇ - {settings.get("shortner", "N/A")} ᴀᴘɪ - {settings.get("api", "N/A")} -✅️ 2ɴᴅ ᴠᴇʀɪꜰʏ sʜᴏʀᴛɴᴇʀ +✅ 2ɴᴅ ᴠᴇʀɪꜰʏ sʜᴏʀᴛɴᴇʀ ɴᴀᴍᴇ - {settings.get("shortner_two", "N/A")} ᴀᴘɪ - {settings.get("api_two", "N/A")} -✅️ 𝟹ʀᴅ ᴠᴇʀɪꜰʏ sʜᴏʀᴛɴᴇʀ +✅ 𝟹ʀᴅ ᴠᴇʀɪꜰʏ sʜᴏʀᴛɴᴇʀ ɴᴀᴍᴇ - {settings.get("shortner_three", "N/A")} ᴀᴘɪ - {settings.get("api_three", "N/A")} ⏰ 2ɴᴅ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ ᴛɪᴍᴇ - {settings.get("verify_time", "N/A")} ⏰ 𝟹ʀᴅ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ ᴛɪᴍᴇ - {settings.get("third_verify_time", "N/A")} -1️⃣ ᴛᴜᴛᴏʀɪᴀʟ ʟɪɴᴋ 1 - {settings.get("tutorial", TUTORIAL)} -2️⃣ ᴛᴜᴛᴏʀɪᴀʟ ʟɪɴᴋ 2 - {settings.get("tutorial_2", TUTORIAL_2)} -3️⃣ ᴛᴜᴛᴏʀɪᴀʟ ʟɪɴᴋ 3 - {settings.get("tutorial_3", TUTORIAL_3)} +1⃣ ᴛᴜᴛᴏʀɪᴀʟ ʟɪɴᴋ 1 - {settings.get("tutorial", TUTORIAL)} +2⃣ ᴛᴜᴛᴏʀɪᴀʟ ʟɪɴᴋ 2 - {settings.get("tutorial_2", TUTORIAL_2)} +3⃣ ᴛᴜᴛᴏʀɪᴀʟ ʟɪɴᴋ 3 - {settings.get("tutorial_3", TUTORIAL_3)} 📝 ʟᴏɢ ᴄʜᴀɴɴᴇʟ ɪᴅ - {settings.get("log", "N/A")} 🚫 ꜰꜱᴜʙ ᴄʜᴀɴɴᴇʟ ɪᴅ - {settings.get("fsub", "N/A")} @@ -703,19 +616,16 @@ def extract_user(message: Message) -> Union[int, str]: if message.reply_to_message: user_id = message.reply_to_message.from_user.id user_first_name = message.reply_to_message.from_user.first_name - elif len(message.command) > 1: if ( len(message.entities) > 1 and message.entities[1].type == enums.MessageEntityType.TEXT_MENTION ): - required_entity = message.entities[1] user_id = required_entity.user.id user_first_name = required_entity.user.first_name else: user_id = message.command[1] - # don't want to make a request -_- user_first_name = user_id try: user_id = int(user_id) @@ -755,7 +665,6 @@ def last_online(from_user): time += from_user.last_online_date.strftime("%a, %d %b %Y, %H:%M:%S") return time - def split_quotes(text: str) -> List: if not any(text.startswith(char) for char in START_CHAR): return text.split(None, 1) @@ -814,13 +723,11 @@ def gfilterparser(text, keyword): text=match.group(2), url=match.group(4).replace(" ", "") )]) - else: note_data += text[prev:to_check] prev = match.start(1) - 1 else: note_data += text[prev:] - try: return note_data, buttons, alerts except Exception: @@ -866,13 +773,11 @@ def parser(text, keyword): text=match.group(2), url=match.group(4).replace(" ", "") )]) - else: note_data += text[prev:to_check] prev = match.start(1) - 1 else: note_data += text[prev:] - try: return note_data, buttons, alerts except Exception: @@ -893,14 +798,10 @@ def remove_escapes(text: str) -> str: async def log_error(client, error_message): try: - await client.send_message( - chat_id=LOG_CHANNEL, - text=f"⚠️ Error Log:\n{error_message}" - ) + await client.send_message(chat_id=LOG_CHANNEL, text=f"⚠ Error Log:\n{error_message}") except Exception as e: logger.error("Failed to log error: %s", e) - def get_time(seconds): periods = [(' ᴅᴀʏs', 86400), (' ʜᴏᴜʀ', 3600), (' ᴍɪɴᴜᴛᴇ', 60), (' sᴇᴄᴏɴᴅ', 1)] result = '' @@ -937,8 +838,6 @@ def generate_season_variations(search_raw: str, season_number: int): f"{search_raw} season {season_number:02}", ] - - async def get_seconds(time_string): def extract_value_and_unit(ts): value = "" @@ -966,7 +865,6 @@ def extract_value_and_unit(ts): return value * 86400 * 365 else: return 0 - def clean_search_text(search_raw: str) -> str: search_lower = search_raw.lower() @@ -1047,7 +945,6 @@ async def get_cap(settings, remaining_seconds, files, query, total_results, sear url=imdb['url'], **locals() ) - for idx, file in enumerate(files, start=offset+1): cap += ( f"{idx}. " @@ -1063,7 +960,7 @@ async def get_cap(settings, remaining_seconds, files, query, total_results, sear f"🏷 ᴛɪᴛʟᴇ : {search}\n" f"⏰ ʀᴇsᴜʟᴛ ɪɴ : {remaining_seconds} Sᴇᴄᴏɴᴅs\n\n" f"📝 ʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {query.from_user.mention}\n" - f"⚜️ ᴘᴏᴡᴇʀᴇᴅ ʙʏ :⚡ {query.message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'}\n" + f"⚜ ᴘᴏᴡᴇʀᴇᴅ ʙʏ :⚡ {query.message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'}\n" ) else: cap = ( @@ -1071,7 +968,7 @@ async def get_cap(settings, remaining_seconds, files, query, total_results, sear f"🧱 ᴛᴏᴛᴀʟ ꜰɪʟᴇꜱ : {total_results}\n" f"⏰ ʀᴇsᴜʟᴛ ɪɴ : {remaining_seconds} Sᴇᴄᴏɴᴅs\n\n" f"📝 ʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {query.from_user.mention}\n" - f"⚜️ ᴘᴏᴡᴇʀᴇᴅ ʙʏ :⚡ {query.message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'}\n" + f"⚜ ᴘᴏᴡᴇʀᴇᴅ ʙʏ :⚡ {query.message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'}\n" ) cap += "\n\nYour Requested Files Are Here \n\n" for idx, file in enumerate(files, start=offset + 1): @@ -1083,13 +980,12 @@ async def get_cap(settings, remaining_seconds, files, query, total_results, sear f"{clean_filename(file.file_name)}\n\n" f"" ) - else: if ULTRA_FAST_MODE: cap = ( f"🏷 ᴛɪᴛʟᴇ : {search}\n" f"⏰ ʀᴇsᴜʟᴛ ɪɴ : {remaining_seconds} Sᴇᴄᴏɴᴅs\n\n" - f"⚜️ ᴘᴏᴡᴇʀᴇᴅ ʙʏ : ⚡ {query.message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'}\n" + f"⚜ ᴘᴏᴡᴇʀᴇᴅ ʙʏ : ⚡ {query.message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'}\n" ) else: cap = ( @@ -1097,9 +993,8 @@ async def get_cap(settings, remaining_seconds, files, query, total_results, sear f"🧱 ᴛᴏᴛᴀʟ ꜰɪʟᴇꜱ : {total_results}\n" f"⏰ ʀᴇsᴜʟᴛ ɪɴ : {remaining_seconds} Sᴇᴄᴏɴᴅs\n\n" f"📝 ʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {query.from_user.mention}\n" - f"⚜️ ᴘᴏᴡᴇʀᴇᴅ ʙʏ : ⚡ {query.message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'}\n" + f"⚜ ᴘᴏᴡᴇʀᴇᴅ ʙʏ : ⚡ {query.message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'}\n" ) - cap += "\n\nYour Requested Files Are Here\n\n" for idx, file in enumerate(files, start=offset + 1): cap += ( From 69751a7c7824a17675b4f5f086c159c30c50a65e Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Tue, 22 Sep 2026 10:33:00 +0530 Subject: [PATCH 64/77] Update utils.py From 17e367dfbd16cf3a47c5550db9fa3d7867a49ca7 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Tue, 22 Sep 2026 10:33:36 +0530 Subject: [PATCH 65/77] Update channel.py --- plugins/channel.py | 363 +++++++++++++++------------------------------ 1 file changed, 123 insertions(+), 240 deletions(-) diff --git a/plugins/channel.py b/plugins/channel.py index d2fca5ae..3770c048 100644 --- a/plugins/channel.py +++ b/plugins/channel.py @@ -17,7 +17,6 @@ logger = logging.getLogger(__name__) -# Precomputed sets for faster lookups IGNORE_WORDS = { "rarbg", "dub", "sub", "sample", "mkv", "aac", "combined", "action", "adventure", "animation", "biography", "comedy", "crime", @@ -35,7 +34,6 @@ "apple", "hoichoi", "sunnxt", "viki" }|BAD_WORDS -# Constants CAPTION_LANGUAGES = { "hin": "Hindi", "hindi": "Hindi", "tam": "Tamil", "tamil": "Tamil", @@ -51,7 +49,6 @@ "kor": "Korean", "korean": "Korean", "jpn": "Japanese", "japanese": "Japanese", } - OTT_PLATFORMS = { "nf": "Netflix", "netflix": "Netflix", "sonyliv": "SonyLiv", "sony": "SonyLiv", "sliv": "SonyLiv", @@ -61,14 +58,11 @@ "aha": "Aha", "hbo": "HBO Max", "paramount": "Paramount+", "apple": "Apple TV+", "hoichoi": "Hoichoi", "sunnxt": "Sun NXT", "viki": "Viki" } - STANDARD_GENRES = { 'Action', 'Adventure', 'Animation', 'Biography', 'Comedy', 'Crime', 'Documentary', 'Drama', 'Family', 'Fantasy', 'Film-Noir', 'History', 'Horror', 'Music', 'Musical', 'Mystery', 'Romance', 'Sci-Fi', 'Sport', 'Thriller', 'War', 'Western' } - -# Precompiled regex patterns CLEAN_PATTERN = re.compile(r'@[^ \n\r\t\.,:;!?()\[\]{}<>\\/"\'=_%]+|\bwww\.[^\s\]\)]+|\([\@^]+\)|\[[\@^]+\]') NORMALIZE_PATTERN = re.compile(r"[._]+|[()\[\]{}:;'–!,.?_]") QUALITY_PATTERN = re.compile( @@ -83,33 +77,25 @@ NAMED_REGEX = re.compile(r'Season\s*0*(\d{1,2})[\s\-,:]*Ep(?:isode)?\s*0*(\d{1,3})', re.IGNORECASE) EP_ONLY_RANGE = re.compile(r'\b(?:EP|Episode)0*(\d{1,3})\s*-\s*0*(\d{1,3})\b',re.IGNORECASE) - -MEDIA_FILTER = filters.document | filters.video | filters.audio locks = defaultdict(asyncio.Lock) pending_updates = {} error_tmdb = False def clean_mentions_links(text: str) -> str: return CLEAN_PATTERN.sub("", text or "").strip() - def normalize(s: str) -> str: s = NORMALIZE_PATTERN.sub(" ", s) return re.sub(r"\s+", " ", s).strip() - -IGNORE_WORDS_LOWER = {w.lower() for w in IGNORE_WORDS} - def remove_ignored_words(text: str) -> str: + IGNORE_WORDS_LOWER = {w.lower() for w in IGNORE_WORDS} return " ".join(word for word in text.split() if word.lower() not in IGNORE_WORDS_LOWER) - def get_qualities(text: str) -> str: qualities = QUALITY_PATTERN.findall(text) return ", ".join(qualities) if qualities else "N/A" - def extract_ott_platform(text: str) -> str: text = text.lower() platforms = {plat for key, plat in OTT_PLATFORMS.items() if key in text} return " | ".join(platforms) if platforms else "N/A" - def extract_season_episode(filename: str) -> Tuple[Optional[int], Optional[str]]: if m := EP_ONLY_RANGE.search(filename): return 1, f"{int(m.group(1))}-{int(m.group(2))}" @@ -122,120 +108,42 @@ def extract_season_episode(filename: str) -> Tuple[Optional[int], Optional[str]] ep = m.group(2) return season, ep return None, None - def schedule_update(bot, base_name, delay=5): if handle := pending_updates.get(base_name): if not handle.cancelled(): handle.cancel() - loop = asyncio.get_event_loop() pending_updates[base_name] = loop.call_later( delay, lambda: asyncio.create_task(update_movie_message(bot, base_name)) ) + def extract_media_info(filename: str, caption: str): filename = normalize(clean_mentions_links(filename).title()) caption_clean = clean_mentions_links(caption).lower() if caption else "" unified = f"{caption_clean} {filename.lower()}".strip() - season = episode = year = None tag = "#MOVIE" processed_raw = base_raw = filename quality = get_qualities(caption_clean) or get_qualities(filename.lower()) or "N/A" ott_platform = extract_ott_platform(f"{filename} {caption_clean}") - lang_keys = {k for k in CAPTION_LANGUAGES if k in caption_clean or k in filename.lower()} - language = ", ".join(sorted({CAPTION_LANGUAGES[k] for k in lang_keys})) if lang_keys else "N/A" - - season, episode = extract_season_episode(filename) - if season is not None: - tag = "#SERIES" - if m := (RANGE_REGEX.search(filename) or SINGLE_REGEX.search(filename) or NAMED_REGEX.search(filename) or EP_ONLY_RANGE.search(filename)): - match_str = m.group(0) - start_idx = filename.lower().find(match_str.lower()) - end_idx = start_idx + len(match_str) - processed_raw = filename[:end_idx] - base_raw = filename[:start_idx] - if year_match := YEAR_PATTERN.search(filename.lower()[end_idx:]): - y = year_match.group(0) - yi = filename.lower().find(y, end_idx) - if yi != -1: - processed_raw = filename[:yi+4] - base_raw += f" {y}" + language = ", ".join(CAPTION_LANGUAGES[k] for k in lang_keys) if lang_keys else "N/A" + year_match = YEAR_PATTERN.search(filename) + if year_match: + year = year_match.group(0) + base_raw = filename.replace(year, "").strip() else: - if year_match := YEAR_PATTERN.search(unified): - year = year_match.group(0) - year_idx = filename.lower().find(year.lower()) - if year_idx != -1: - processed_raw = filename[:year_idx + 4] - base_raw = processed_raw - else: - if qual_match := QUALITY_PATTERN.search(unified): - qual_str = qual_match.group(0) - qual_idx = filename.lower().find(qual_str.lower()) - if qual_idx != -1: - processed_raw = filename[:qual_idx] - base_raw = processed_raw - - base_name = normalize(remove_ignored_words(normalize(base_raw))) - if year and year not in base_name: - base_name += f" {year}" - - if base_name.endswith(")"): - base_name = re.sub(r"\s+\(\d{4}\)$", "", base_name) - if year: - base_name += f" {year}" - - # ------------------------- - # NEW: strip season/episode tokens from final base_name - # ------------------------- - def _strip_season_episode_tokens(name: str) -> str: - """ - Remove common season/episode markers from a title while preserving a trailing year. - Examples removed: S01, s01e02, 1x02, season 1, ep 02, episode 2, part 1 - """ - if not name: - return name - - # Preserve trailing year (e.g. "Title (2020)" or "Title 2020") - year_match = re.search(r'\(?\b(19|20)\d{2}\b\)?\s*$', name) - year_part = "" + year_match = YEAR_PATTERN.search(caption_clean) if year_match: - year_part = year_match.group(0) - name = name[:year_match.start()].strip() - - # Common patterns to remove - patterns = [ - r'\bS\d{1,2}E\d{1,2}\b', # S01E02 - r'\bS\d{1,2}\b', # S01 - r'\bE\d{1,2}\b', # E02 - r'\b\d{1,2}x\d{1,2}\b', # 1x02 - r'\bSeason\s*\d{1,2}\b', # Season 1 - r'\bEp(?:isode)?\.?\s*\d{1,3}\b', # Ep02, Episode 2 - r'\bEpisode\s*\d{1,3}\b', - r'\bPart\s*\d{1,2}\b' - ] - - for p in patterns: - name = re.sub(p, ' ', name, flags=re.IGNORECASE) - - # Remove leftover separators and extra whitespace - name = re.sub(r'[_\.\-]+', ' ', name) # underscores/dots/hyphens - name = re.sub(r'\s+', ' ', name).strip() - - # Reattach year in canonical form if we removed it earlier - if year_part: - y = re.search(r'(19|20)\d{2}', year_part) - if y: - name = f"{name} {y.group(0)}" - - return name.strip() - - base_name = _strip_season_episode_tokens(base_name) - # If stripping accidentally removed everything, fall back to a safer value + year = year_match.group(0) + season, episode = extract_season_episode(filename) + if season: + tag = "#SERIES" + base_name = remove_ignored_words(base_raw) + base_name = re.sub(r'\s+', ' ', base_name).strip() if not base_name: - base_name = normalize(remove_ignored_words(normalize(processed_raw))) or filename - + base_name = filename return { "processed": normalize(processed_raw), "base_name": base_name, @@ -250,61 +158,66 @@ def _strip_season_episode_tokens(name: str) -> str: @Client.on_message(filters.chat(CHANNELS) & (filters.document | filters.video | filters.audio)) async def media_handler(bot, message): - success = False - try: - media = message.document or message.video or message.audio - if not media: - return - - file_id = media.file_id - file_name = getattr(media, "file_name", "") - file_size = getattr(media, "file_size", 0) - - logger.info(f"File from {message.chat.id}: {file_name}") - - media.file_type = next((ft for ft in ("document", "video", "audio") if getattr(message, ft, None)), None) - media.caption = message.caption or "" - - lock = locks[file_id] - async with lock: - success, info = await save_file(media) - if success: - print("File saved") - - except DuplicateKeyError: - pass - except FloodWait as e: - await asyncio.sleep(e.value) - except PyMongoError as e: - logger.error(f"MongoDB Error in media_handler: {e}") - except Exception as e: - logger.exception(f"Error processing media: {e}") - - if success: + logger.info(f"media_handler triggered from chat {message.chat.id} | CHANNELS env = {CHANNELS}") + print(f"[AUTO INDEX] Triggered from {message.chat.id} | CHANNELS={CHANNELS}") + if not CHANNELS or CHANNELS == [-100]: + logger.error("CHANNELS env is empty or default -100. Set CHANNELS in Render env to -100xxxxxxxxx") + return + media = message.document or message.video or message.audio + if not media: + logger.warning("No media found in message") + return + file_name = getattr(media, "file_name", "unknown") + file_id = getattr(media, "file_id", "") + lock = locks[file_id] + async with lock: try: - if await db.movie_update_status(temp.ME): - await process_and_send_update(bot, file_name, message.caption) + media.file_type = next((ft for ft in ("document", "video", "audio") if getattr(message, ft, None)), None) + media.caption = message.caption or "" + success, _ = await save_file(media) + if success: + print(f"File saved to DB: {file_name}") + logger.info(f"File saved to DB: {file_name}") + else: + print(f"File already exists or failed: {file_name}") + success = True + if success: + try: + if await db.movie_update_status(bot.me.id): + await process_and_send_update(bot, file_name, message.caption or "") + except Exception as e: + logger.exception(f"Error in movie_update_status: {e}") + except DuplicateKeyError: + logger.info(f"Duplicate file skipped: {file_name}") + try: + if await db.movie_update_status(bot.me.id): + await process_and_send_update(bot, file_name, message.caption or "") + except: + pass + except FloodWait as e: + logger.warning(f"FloodWait {e.value}s for {file_name}") + await asyncio.sleep(e.value) + except PyMongoError as e: + logger.error(f"MongoDB Error: {e} for {file_name}") except Exception as e: - logger.exception("Error in movie update") + logger.exception(f"Unexpected error in media_handler for {file_name}: {e}") async def process_and_send_update(bot, filename, caption): try: media_info = extract_media_info(filename, caption) base_name = media_info["base_name"] processed = media_info["processed"] - lock = locks[base_name] async with lock: await _process_with_lock(bot, filename, caption, media_info, base_name, processed) except PyMongoError as e: - logger.error(f"Database error in process_and_send_update: {e}") + logger.error(f"DB error in process_and_send_update: {e}") except Exception as e: - logger.exception(f"Processing failed in process_and_send_update: {e}") + logger.exception(f"Processing failed: {e}") async def _process_with_lock(bot, filename, caption, media_info, base_name, processed): if not hasattr(db, 'movie_updates'): db.movie_updates = db.db.movie_updates - movie_doc = await db.movie_updates.find_one({"_id": base_name}) error_tmdb=False file_data = { @@ -318,7 +231,6 @@ async def _process_with_lock(bot, filename, caption, media_info, base_name, proc "season": media_info["season"], "episode": media_info["episode"] } - if not movie_doc: if TMDB_POSTER: details = await get_movie_detailsx(base_name) @@ -328,19 +240,27 @@ async def _process_with_lock(bot, filename, caption, media_info, base_name, proc details = await get_movie_details(base_name) or {} else: details = await get_movie_details(base_name) or {} - raw_genres = details.get("genres", "N/A") if isinstance(raw_genres, str): genre_list = [g.strip() for g in raw_genres.split(",")] genres = ", ".join(g for g in genre_list if g in STANDARD_GENRES) or "N/A" else: genres = ", ".join(g for g in raw_genres if g in STANDARD_GENRES) or "N/A" + + # FIX: Get runtime from TMDB/IMDB/OMDB + runtime_raw = details.get("runtime", "N/A") + if isinstance(runtime_raw, list): + runtime_raw = ", ".join(str(x) for x in runtime_raw) + # Format runtime to 1h 51m style + runtime_formatted = format_runtime(runtime_raw) + movie_doc = { "_id": base_name, "files": [file_data], "poster_url": details.get("backdrop_url") if LANDSCAPE_POSTER and TMDB_POSTER and details.get("backdrop_url") and not error_tmdb else details.get("poster_url"), "genres": genres, "rating": details.get("rating", "N/A"), + "runtime": runtime_formatted, "imdb_url": details.get("url", "")if not TMDB_POSTER or error_tmdb else details.get("tmdb_url"), "year": details.get("year") or media_info["year"], "tag": media_info["tag"], @@ -353,28 +273,51 @@ async def _process_with_lock(bot, filename, caption, media_info, base_name, proc try: await db.movie_updates.insert_one(movie_doc) await send_movie_update(bot, base_name) - movie_doc = await db.movie_updates.find_one({"_id": base_name}) except DuplicateKeyError: movie_doc = await db.movie_updates.find_one({"_id": base_name}) - if movie_doc: - if any(f["filename"] == filename for f in movie_doc["files"]): - return - await db.movie_updates.update_one( - {"_id": base_name}, - {"$push": {"files": file_data}} - ) - movie_doc["files"].append(file_data) + if movie_doc and not any(f["filename"] == filename for f in movie_doc["files"]): + await db.movie_updates.update_one({"_id": base_name},{"$push": {"files": file_data}}) schedule_update(bot, base_name) else: if any(f["filename"] == filename for f in movie_doc["files"]): return - await db.movie_updates.update_one( - {"_id": base_name}, - {"$push": {"files": file_data}} - ) - movie_doc["files"].append(file_data) + await db.movie_updates.update_one({"_id": base_name},{"$push": {"files": file_data}}) schedule_update(bot, base_name) +def format_runtime(runtime_input): + """Convert runtime to HD PRO style: 1h 51m""" + if not runtime_input or runtime_input == "N/A": + return "N/A" + runtime_str = str(runtime_input).strip() + # If already in 1h 51m format, return as is + if "h" in runtime_str.lower() and "m" in runtime_str.lower(): + return runtime_str + # If format like "111 min" or "111" + try: + # Extract numbers + if "min" in runtime_str.lower(): + mins = int(re.search(r'\d+', runtime_str).group()) + else: + # Could be list like "120" or "120 min" + nums = re.findall(r'\d+', runtime_str) + if nums: + mins = int(nums[0]) + # If runtime is like "2h 30m" already handled above, so mins is total minutes + # But if input is "120" it might be minutes + if mins < 10: # likely hours? + return runtime_str + else: + return runtime_str + + h = mins // 60 + m = mins % 60 + if h > 0: + return f"{h}h {m}m" if m else f"{h}h" + else: + return f"{m}m" + except: + return runtime_str + async def send_movie_update(bot, base_name): max_retries = 3 for attempt in range(max_retries): @@ -382,57 +325,31 @@ async def send_movie_update(bot, base_name): movie_doc = await db.movie_updates.find_one({"_id": base_name}) if not movie_doc: return None - text = generate_movie_message(movie_doc, base_name) buttons = InlineKeyboardMarkup([[ - InlineKeyboardButton( - 'ɢᴇᴛ ғɪʟᴇs', - url=f"https://t.me/{temp.U_NAME}?start=getfile-{base_name.replace(' ', '-')}" - ) + InlineKeyboardButton('ɢᴇᴛ ғɪʟᴇs',url=f"https://t.me/{temp.U_NAME}?start=getfile-{base_name.replace(' ', '-')}") ]]) size=(2560, 1440) if LANDSCAPE_POSTER and TMDB_POSTER and movie_doc.get("is_backdrop") and not movie_doc.get("error_tmdb") else (853, 1280) if movie_doc.get("poster_url") and not LINK_PREVIEW: resized_poster = await fetch_image(movie_doc["poster_url"], size) if resized_poster: - msg = await bot.send_photo( - chat_id=MOVIE_UPDATE_CHANNEL, - photo=resized_poster, - caption=text, - reply_markup=buttons, - parse_mode=enums.ParseMode.HTML - ) + msg = await bot.send_photo(chat_id=MOVIE_UPDATE_CHANNEL,photo=resized_poster,caption=text,reply_markup=buttons,parse_mode=enums.ParseMode.HTML) is_photo = True else: - send_params = { - "chat_id": MOVIE_UPDATE_CHANNEL, - "text": text, - "reply_markup": buttons, - "parse_mode": enums.ParseMode.HTML - } - msg = await bot.send_message(**send_params) + msg = await bot.send_message(chat_id=MOVIE_UPDATE_CHANNEL,text=text,reply_markup=buttons,parse_mode=enums.ParseMode.HTML) is_photo = False else: - send_params = { - "chat_id": MOVIE_UPDATE_CHANNEL, - "text": text, - "reply_markup": buttons, - "parse_mode": enums.ParseMode.HTML - } + send_params = {"chat_id": MOVIE_UPDATE_CHANNEL,"text": text,"reply_markup": buttons,"parse_mode": enums.ParseMode.HTML} if movie_doc.get("poster_url") and LINK_PREVIEW: send_params["link_preview_options"] = LinkPreviewOptions(is_disabled=False, show_above_text=ABOVE_PREVIEW) else: send_params["link_preview_options"] = LinkPreviewOptions(is_disabled=not LINK_PREVIEW) msg = await bot.send_message(**send_params) is_photo = False - - await db.movie_updates.update_one( - {"_id": base_name}, - {"$set": {"message_id": msg.id, "is_photo": is_photo}} - ) + await db.movie_updates.update_one({"_id": base_name},{"$set": {"message_id": msg.id, "is_photo": is_photo}}) return msg except FloodWait as e: - wait_time = e.value + 2 - await asyncio.sleep(wait_time) + await asyncio.sleep(e.value+2) except Exception as e: logger.error(f"Failed to send movie update: {e}") break @@ -443,70 +360,42 @@ async def update_movie_message(bot, base_name): movie_doc = await db.movie_updates.find_one({"_id": base_name}) if not movie_doc: return - text = generate_movie_message(movie_doc, base_name) buttons = InlineKeyboardMarkup([[ - InlineKeyboardButton( - 'ɢᴇᴛ ғɪʟᴇs', - url=f"https://t.me/{temp.U_NAME}?start=getfile-{base_name.replace(' ', '-')}" - ) + InlineKeyboardButton('ɢᴇᴛ ғɪʟᴇs',url=f"https://t.me/{temp.U_NAME}?start=getfile-{base_name.replace(' ', '-')}") ]]) - message_id = movie_doc.get("message_id") is_photo = movie_doc.get("is_photo", False) - if not message_id: await send_movie_update(bot, base_name) return - try: if is_photo: - await bot.edit_message_caption( - chat_id=MOVIE_UPDATE_CHANNEL, - message_id=message_id, - caption=text, - reply_markup=buttons, - parse_mode=enums.ParseMode.HTML - ) + await bot.edit_message_caption(chat_id=MOVIE_UPDATE_CHANNEL,message_id=message_id,caption=text,reply_markup=buttons,parse_mode=enums.ParseMode.HTML) else: - await bot.edit_message_text( - chat_id=MOVIE_UPDATE_CHANNEL, - message_id=message_id, - text=text, - reply_markup=buttons, - parse_mode=enums.ParseMode.HTML, - link_preview_options=LinkPreviewOptions(is_disabled=not LINK_PREVIEW, show_above_text=ABOVE_PREVIEW) - ) + await bot.edit_message_text(chat_id=MOVIE_UPDATE_CHANNEL,message_id=message_id,text=text,reply_markup=buttons,parse_mode=enums.ParseMode.HTML,link_preview_options=LinkPreviewOptions(is_disabled=not LINK_PREVIEW, show_above_text=ABOVE_PREVIEW)) return except MessageNotModified: pass - except MessageIdInvalid as e: - logger.warning(f"Message update skipped due to error: {e}") + except MessageIdInvalid: pass except Exception: try: - await bot.delete_messages( - chat_id=MOVIE_UPDATE_CHANNEL, - message_ids=message_id - ) - await db.movie_updates.update_one( - {"_id": base_name}, - {"$set": {"message_id": None, "is_photo": False}} - ) - except Exception as e: - logger.error(f"Error during message deletion/update in recovery: {e}") + await bot.delete_messages(chat_id=MOVIE_UPDATE_CHANNEL,message_ids=message_id) + await db.movie_updates.update_one({"_id": base_name},{"$set": {"message_id": None, "is_photo": False}}) + except: pass await send_movie_update(bot, base_name) except Exception as e: logger.error(f"Failed to update movie message for {base_name}: {e}") def generate_movie_message(movie_doc, base_name): + from collections import defaultdict all_qualities = set() all_languages = set() all_ott_platforms = set() all_tags = set() episodes_by_season = defaultdict(set) - for file in movie_doc["files"]: if file["quality"] != "N/A": all_qualities.update(q.strip() for q in file["quality"].split(",") if q.strip()) @@ -518,10 +407,7 @@ def generate_movie_message(movie_doc, base_name): if file["tag"]: all_tags.add(file["tag"]) if file.get("season") and file.get("episode"): - season = file["season"] - episode = file["episode"] - episodes_by_season[season].add(episode) - + episodes_by_season[file["season"]].add(file["episode"]) primary_tag = "#SERIES" if "#SERIES" in all_tags else "#MOVIE" epi_block = "" if episodes_by_season: @@ -529,7 +415,6 @@ def generate_movie_message(movie_doc, base_name): for season, episodes in sorted(episodes_by_season.items(), key=lambda x: int(x[0])): singles = [] ranges = [] - for ep in episodes: if "-" in ep: ranges.append(ep) @@ -538,7 +423,6 @@ def generate_movie_message(movie_doc, base_name): singles.append(int(ep)) except ValueError: ranges.append(ep) - singles.sort() collapsed = [] start = end = None @@ -552,14 +436,11 @@ def generate_movie_message(movie_doc, base_name): start = end = num if start is not None: collapsed.append(str(start) if start == end else f"{start}-{end}") - all_ep_parts = collapsed + sorted(ranges, key=lambda s: int(s.split("-")[0])) episode_lines.append(f"S{int(season)}: {', '.join(all_ep_parts)}") - epi_str = "\n".join(episode_lines) if epi_str: epi_block = f"📺 ᴇᴘɪsᴏᴅᴇs : \n{epi_str}" - genres = movie_doc.get("genres", "N/A") quality_str = ", ".join(sorted(all_qualities)) if all_qualities else "N/A" language_str = ", ".join(sorted(all_languages)) if all_languages else "N/A" @@ -569,12 +450,13 @@ def generate_movie_message(movie_doc, base_name): r = float(rating) except (TypeError, ValueError): r = 0.0 - rating_text = "-" if r == 0.0 else str(rating) + runtime = movie_doc.get("runtime", "N/A") year_val = str(movie_doc.get("year") or "") filename_display = base_name if year_val and filename_display.strip().endswith(year_val): filename_display = filename_display.strip()[:-len(year_val)].strip() + # FIXED: Added runtime parameter return script.MOVIE_UPDATE_NOTIFY_TXT.format( poster_url=movie_doc.get("poster_url", ""), imdb_url=movie_doc.get("imdb_url", ""), @@ -583,9 +465,10 @@ def generate_movie_message(movie_doc, base_name): year=year_val, genres=genres, ott=ott_str, + runtime=runtime, quality=quality_str, language=language_str, episodes=epi_block, rating=rating_text, search_link=temp.B_LINK -) + ) From 6ddfece9e68bb79579d9c5a890005610c4104dc0 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Wed, 23 Sep 2026 19:30:28 +0530 Subject: [PATCH 66/77] Update message formatting and final version notes --- Script.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Script.py b/Script.py index 9cd95389..55521dd3 100644 --- a/Script.py +++ b/Script.py @@ -265,18 +265,19 @@ class script(object): CAPTION = """{file_name}\n\n⚜ Powered By : [ ᴅʀᴇᴀᴍxʙᴏᴛᴢ ]""" - # === UPDATED WITH DIVIDER AND RUNTIME - HD PRO STYLE === + # === FINAL V3 - TITLE OUTSIDE QUOTE, DIVIDER LOGIC, RUNTIME FIX === MOVIE_UPDATE_NOTIFY_TXT = """ 📥New {tag} Added -
✨ ᴛɪᴛʟᴇ : {filename} {year} +✨ ᴛɪᴛʟᴇ : {filename} {year} ⚬────────✧────────⚬ -🎭 ɢᴇɴʀᴇs : {genres} -📺 ᴏᴛᴛ : {ott} + +
🎭 ɢᴇɴʀᴇs : {genres} +📺 ᴏᴛᴛ : {ott} ⏰ ʀᴜɴᴛɪᴍᴇ : {runtime} 🎞 ǫᴜᴀʟɪᴛʏ : {quality} -🎧 ᴀᴜᴅɪᴏ : {language} -🔥 ʀᴀᴛɪɴɢ : {rating}/10 +🎧 ᴀᴜᴅɪᴏ : {language} +🔥 ʀᴀᴛɪɴɢ : {rating}/10 {episodes}
⚬────────✧────────⚬ From 4caad86c12fef88c775592f39eae2cef0cac328b Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Wed, 23 Sep 2026 19:32:19 +0530 Subject: [PATCH 67/77] Enhance ignore words and quality pattern Added extra ignore words for base_name grouping and updated quality pattern to include codec and bluray terms. --- plugins/channel.py | 55 ++++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/plugins/channel.py b/plugins/channel.py index 3770c048..9dcc24aa 100644 --- a/plugins/channel.py +++ b/plugins/channel.py @@ -17,6 +17,15 @@ logger = logging.getLogger(__name__) +# FIXED: Added all quality/codec words to IGNORE for base_name grouping +EXTRA_IGNORE = { + "x264", "x265", "h264", "h265", "hevc", "10bit", "8bit", "10-bit", "8-bit", + "10Bit", "8Bit", "x264", "x265", "X264", "X265", "HEVC", "10BIT", + "bluray", "blu-ray", "brrip", "bdrip", "webrip", "web-dl", "webdl", "hdrip", + "esub", "esubs", "subs", "sub", "aac", "ac3", "dts", "mp3", "flac", + "remux", "proper", "repack", "extended", "unrated", "directors", "cut" +} + IGNORE_WORDS = { "rarbg", "dub", "sub", "sample", "mkv", "aac", "combined", "action", "adventure", "animation", "biography", "comedy", "crime", @@ -32,7 +41,7 @@ "japanese", "nf", "netflix", "sonyliv", "sony", "sliv", "amzn", "prime", "primevideo", "hotstar", "zee5", "jio", "jhs", "aha", "hbo", "paramount", "apple", "hoichoi", "sunnxt", "viki" -}|BAD_WORDS +}|BAD_WORDS|EXTRA_IGNORE|{w.lower() for w in EXTRA_IGNORE} CAPTION_LANGUAGES = { "hin": "Hindi", "hindi": "Hindi", @@ -65,10 +74,12 @@ } CLEAN_PATTERN = re.compile(r'@[^ \n\r\t\.,:;!?()\[\]{}<>\\/"\'=_%]+|\bwww\.[^\s\]\)]+|\([\@^]+\)|\[[\@^]+\]') NORMALIZE_PATTERN = re.compile(r"[._]+|[()\[\]{}:;'–!,.?_]") +# FIXED: Quality pattern now includes codec and bluray etc QUALITY_PATTERN = re.compile( r"\b(?:HDCam|HDTC|CamRip|TS|TC|TeleSync|DVDScr|DVDRip|PreDVD|" r"WEBRip|WEB-DL|TVRip|HDTV|WEB DL|WebDl|BluRay|BRRip|BDRip|" - r"360p|480p|720p|1080p|2160p|4K|1440p|540p|240p|140p|HEVC|HDRip)\b", + r"360p|480p|720p|1080p|2160p|4K|1440p|540p|240p|140p|HEVC|HDRip|" + r"x264|x265|h264|h265|10bit|8bit|10-bit|HEVC|BluRay|Bluray)\b", re.IGNORECASE ) YEAR_PATTERN = re.compile(r"(? str: return CLEAN_PATTERN.sub("", text or "").strip() @@ -88,9 +98,12 @@ def normalize(s: str) -> str: return re.sub(r"\s+", " ", s).strip() def remove_ignored_words(text: str) -> str: IGNORE_WORDS_LOWER = {w.lower() for w in IGNORE_WORDS} - return " ".join(word for word in text.split() if word.lower() not in IGNORE_WORDS_LOWER) + # Also remove words like 10Bit, X265 case insensitive + return " ".join(word for word in text.split() if word.lower() not in IGNORE_WORDS_LOWER and word.lower() not in {w.lower() for w in EXTRA_IGNORE}) def get_qualities(text: str) -> str: qualities = QUALITY_PATTERN.findall(text) + # Normalize to uppercase for final display but keep original case for detection + # Return as found, uppercasing will be done later return ", ".join(qualities) if qualities else "N/A" def extract_ott_platform(text: str) -> str: text = text.lower() @@ -246,14 +259,10 @@ async def _process_with_lock(bot, filename, caption, media_info, base_name, proc genres = ", ".join(g for g in genre_list if g in STANDARD_GENRES) or "N/A" else: genres = ", ".join(g for g in raw_genres if g in STANDARD_GENRES) or "N/A" - - # FIX: Get runtime from TMDB/IMDB/OMDB runtime_raw = details.get("runtime", "N/A") if isinstance(runtime_raw, list): runtime_raw = ", ".join(str(x) for x in runtime_raw) - # Format runtime to 1h 51m style runtime_formatted = format_runtime(runtime_raw) - movie_doc = { "_id": base_name, "files": [file_data], @@ -285,30 +294,22 @@ async def _process_with_lock(bot, filename, caption, media_info, base_name, proc schedule_update(bot, base_name) def format_runtime(runtime_input): - """Convert runtime to HD PRO style: 1h 51m""" if not runtime_input or runtime_input == "N/A": return "N/A" runtime_str = str(runtime_input).strip() - # If already in 1h 51m format, return as is if "h" in runtime_str.lower() and "m" in runtime_str.lower(): return runtime_str - # If format like "111 min" or "111" try: - # Extract numbers if "min" in runtime_str.lower(): mins = int(re.search(r'\d+', runtime_str).group()) else: - # Could be list like "120" or "120 min" nums = re.findall(r'\d+', runtime_str) if nums: mins = int(nums[0]) - # If runtime is like "2h 30m" already handled above, so mins is total minutes - # But if input is "120" it might be minutes - if mins < 10: # likely hours? + if mins < 10: return runtime_str else: return runtime_str - h = mins // 60 m = mins % 60 if h > 0: @@ -326,8 +327,14 @@ async def send_movie_update(bot, base_name): if not movie_doc: return None text = generate_movie_message(movie_doc, base_name) + # BUTTON COLOR LOGIC: Movie = Green, Series = Blue + is_series = "#SERIES" in str(movie_doc.get("tag", "")) or any(f.get("season") for f in movie_doc.get("files", [])) + if is_series: + btn_text = "🔵 ɢᴇᴛ ғɪʟᴇs" # Blue for Series + else: + btn_text = "🟢 ɢᴇᴛ ғɪʟᴇs" # Green for Movie buttons = InlineKeyboardMarkup([[ - InlineKeyboardButton('ɢᴇᴛ ғɪʟᴇs',url=f"https://t.me/{temp.U_NAME}?start=getfile-{base_name.replace(' ', '-')}") + InlineKeyboardButton(btn_text, url=f"https://t.me/{temp.U_NAME}?start=getfile-{base_name.replace(' ', '-')}") ]]) size=(2560, 1440) if LANDSCAPE_POSTER and TMDB_POSTER and movie_doc.get("is_backdrop") and not movie_doc.get("error_tmdb") else (853, 1280) if movie_doc.get("poster_url") and not LINK_PREVIEW: @@ -361,8 +368,13 @@ async def update_movie_message(bot, base_name): if not movie_doc: return text = generate_movie_message(movie_doc, base_name) + is_series = "#SERIES" in str(movie_doc.get("tag", "")) or any(f.get("season") for f in movie_doc.get("files", [])) + if is_series: + btn_text = "🔵 ɢᴇᴛ ғɪʟᴇs" + else: + btn_text = "🟢 ɢᴇᴛ ғɪʟᴇs" buttons = InlineKeyboardMarkup([[ - InlineKeyboardButton('ɢᴇᴛ ғɪʟᴇs',url=f"https://t.me/{temp.U_NAME}?start=getfile-{base_name.replace(' ', '-')}") + InlineKeyboardButton(btn_text, url=f"https://t.me/{temp.U_NAME}?start=getfile-{base_name.replace(' ', '-')}") ]]) message_id = movie_doc.get("message_id") is_photo = movie_doc.get("is_photo", False) @@ -398,7 +410,9 @@ def generate_movie_message(movie_doc, base_name): episodes_by_season = defaultdict(set) for file in movie_doc["files"]: if file["quality"] != "N/A": - all_qualities.update(q.strip() for q in file["quality"].split(",") if q.strip()) + # Split and uppercase for final display + quals = [q.strip().upper() for q in file["quality"].split(",") if q.strip()] + all_qualities.update(quals) if file["language"] != "N/A": all_languages.update(lang.strip() for lang in file["language"].split(",") if lang.strip()) if file["ott_platform"] != "N/A": @@ -456,7 +470,6 @@ def generate_movie_message(movie_doc, base_name): filename_display = base_name if year_val and filename_display.strip().endswith(year_val): filename_display = filename_display.strip()[:-len(year_val)].strip() - # FIXED: Added runtime parameter return script.MOVIE_UPDATE_NOTIFY_TXT.format( poster_url=movie_doc.get("poster_url", ""), imdb_url=movie_doc.get("imdb_url", ""), From a933af157196ba62b14fa081e305b18dac5ac4bd Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Wed, 23 Sep 2026 19:46:12 +0530 Subject: [PATCH 68/77] Update channel.py --- plugins/channel.py | 386 ++++++++++++++++++++++++++++----------------- 1 file changed, 245 insertions(+), 141 deletions(-) diff --git a/plugins/channel.py b/plugins/channel.py index 9dcc24aa..d2fca5ae 100644 --- a/plugins/channel.py +++ b/plugins/channel.py @@ -17,15 +17,7 @@ logger = logging.getLogger(__name__) -# FIXED: Added all quality/codec words to IGNORE for base_name grouping -EXTRA_IGNORE = { - "x264", "x265", "h264", "h265", "hevc", "10bit", "8bit", "10-bit", "8-bit", - "10Bit", "8Bit", "x264", "x265", "X264", "X265", "HEVC", "10BIT", - "bluray", "blu-ray", "brrip", "bdrip", "webrip", "web-dl", "webdl", "hdrip", - "esub", "esubs", "subs", "sub", "aac", "ac3", "dts", "mp3", "flac", - "remux", "proper", "repack", "extended", "unrated", "directors", "cut" -} - +# Precomputed sets for faster lookups IGNORE_WORDS = { "rarbg", "dub", "sub", "sample", "mkv", "aac", "combined", "action", "adventure", "animation", "biography", "comedy", "crime", @@ -41,8 +33,9 @@ "japanese", "nf", "netflix", "sonyliv", "sony", "sliv", "amzn", "prime", "primevideo", "hotstar", "zee5", "jio", "jhs", "aha", "hbo", "paramount", "apple", "hoichoi", "sunnxt", "viki" -}|BAD_WORDS|EXTRA_IGNORE|{w.lower() for w in EXTRA_IGNORE} +}|BAD_WORDS +# Constants CAPTION_LANGUAGES = { "hin": "Hindi", "hindi": "Hindi", "tam": "Tamil", "tamil": "Tamil", @@ -58,6 +51,7 @@ "kor": "Korean", "korean": "Korean", "jpn": "Japanese", "japanese": "Japanese", } + OTT_PLATFORMS = { "nf": "Netflix", "netflix": "Netflix", "sonyliv": "SonyLiv", "sony": "SonyLiv", "sliv": "SonyLiv", @@ -67,19 +61,20 @@ "aha": "Aha", "hbo": "HBO Max", "paramount": "Paramount+", "apple": "Apple TV+", "hoichoi": "Hoichoi", "sunnxt": "Sun NXT", "viki": "Viki" } + STANDARD_GENRES = { 'Action', 'Adventure', 'Animation', 'Biography', 'Comedy', 'Crime', 'Documentary', 'Drama', 'Family', 'Fantasy', 'Film-Noir', 'History', 'Horror', 'Music', 'Musical', 'Mystery', 'Romance', 'Sci-Fi', 'Sport', 'Thriller', 'War', 'Western' } + +# Precompiled regex patterns CLEAN_PATTERN = re.compile(r'@[^ \n\r\t\.,:;!?()\[\]{}<>\\/"\'=_%]+|\bwww\.[^\s\]\)]+|\([\@^]+\)|\[[\@^]+\]') NORMALIZE_PATTERN = re.compile(r"[._]+|[()\[\]{}:;'–!,.?_]") -# FIXED: Quality pattern now includes codec and bluray etc QUALITY_PATTERN = re.compile( r"\b(?:HDCam|HDTC|CamRip|TS|TC|TeleSync|DVDScr|DVDRip|PreDVD|" r"WEBRip|WEB-DL|TVRip|HDTV|WEB DL|WebDl|BluRay|BRRip|BDRip|" - r"360p|480p|720p|1080p|2160p|4K|1440p|540p|240p|140p|HEVC|HDRip|" - r"x264|x265|h264|h265|10bit|8bit|10-bit|HEVC|BluRay|Bluray)\b", + r"360p|480p|720p|1080p|2160p|4K|1440p|540p|240p|140p|HEVC|HDRip)\b", re.IGNORECASE ) YEAR_PATTERN = re.compile(r"(? str: return CLEAN_PATTERN.sub("", text or "").strip() + def normalize(s: str) -> str: s = NORMALIZE_PATTERN.sub(" ", s) return re.sub(r"\s+", " ", s).strip() + +IGNORE_WORDS_LOWER = {w.lower() for w in IGNORE_WORDS} + def remove_ignored_words(text: str) -> str: - IGNORE_WORDS_LOWER = {w.lower() for w in IGNORE_WORDS} - # Also remove words like 10Bit, X265 case insensitive - return " ".join(word for word in text.split() if word.lower() not in IGNORE_WORDS_LOWER and word.lower() not in {w.lower() for w in EXTRA_IGNORE}) + return " ".join(word for word in text.split() if word.lower() not in IGNORE_WORDS_LOWER) + def get_qualities(text: str) -> str: qualities = QUALITY_PATTERN.findall(text) - # Normalize to uppercase for final display but keep original case for detection - # Return as found, uppercasing will be done later return ", ".join(qualities) if qualities else "N/A" + def extract_ott_platform(text: str) -> str: text = text.lower() platforms = {plat for key, plat in OTT_PLATFORMS.items() if key in text} return " | ".join(platforms) if platforms else "N/A" + def extract_season_episode(filename: str) -> Tuple[Optional[int], Optional[str]]: if m := EP_ONLY_RANGE.search(filename): return 1, f"{int(m.group(1))}-{int(m.group(2))}" @@ -121,42 +122,120 @@ def extract_season_episode(filename: str) -> Tuple[Optional[int], Optional[str]] ep = m.group(2) return season, ep return None, None + def schedule_update(bot, base_name, delay=5): if handle := pending_updates.get(base_name): if not handle.cancelled(): handle.cancel() + loop = asyncio.get_event_loop() pending_updates[base_name] = loop.call_later( delay, lambda: asyncio.create_task(update_movie_message(bot, base_name)) ) - def extract_media_info(filename: str, caption: str): filename = normalize(clean_mentions_links(filename).title()) caption_clean = clean_mentions_links(caption).lower() if caption else "" unified = f"{caption_clean} {filename.lower()}".strip() + season = episode = year = None tag = "#MOVIE" processed_raw = base_raw = filename quality = get_qualities(caption_clean) or get_qualities(filename.lower()) or "N/A" ott_platform = extract_ott_platform(f"{filename} {caption_clean}") + lang_keys = {k for k in CAPTION_LANGUAGES if k in caption_clean or k in filename.lower()} - language = ", ".join(CAPTION_LANGUAGES[k] for k in lang_keys) if lang_keys else "N/A" - year_match = YEAR_PATTERN.search(filename) - if year_match: - year = year_match.group(0) - base_raw = filename.replace(year, "").strip() - else: - year_match = YEAR_PATTERN.search(caption_clean) - if year_match: - year = year_match.group(0) + language = ", ".join(sorted({CAPTION_LANGUAGES[k] for k in lang_keys})) if lang_keys else "N/A" + season, episode = extract_season_episode(filename) - if season: + if season is not None: tag = "#SERIES" - base_name = remove_ignored_words(base_raw) - base_name = re.sub(r'\s+', ' ', base_name).strip() + if m := (RANGE_REGEX.search(filename) or SINGLE_REGEX.search(filename) or NAMED_REGEX.search(filename) or EP_ONLY_RANGE.search(filename)): + match_str = m.group(0) + start_idx = filename.lower().find(match_str.lower()) + end_idx = start_idx + len(match_str) + processed_raw = filename[:end_idx] + base_raw = filename[:start_idx] + if year_match := YEAR_PATTERN.search(filename.lower()[end_idx:]): + y = year_match.group(0) + yi = filename.lower().find(y, end_idx) + if yi != -1: + processed_raw = filename[:yi+4] + base_raw += f" {y}" + else: + if year_match := YEAR_PATTERN.search(unified): + year = year_match.group(0) + year_idx = filename.lower().find(year.lower()) + if year_idx != -1: + processed_raw = filename[:year_idx + 4] + base_raw = processed_raw + else: + if qual_match := QUALITY_PATTERN.search(unified): + qual_str = qual_match.group(0) + qual_idx = filename.lower().find(qual_str.lower()) + if qual_idx != -1: + processed_raw = filename[:qual_idx] + base_raw = processed_raw + + base_name = normalize(remove_ignored_words(normalize(base_raw))) + if year and year not in base_name: + base_name += f" {year}" + + if base_name.endswith(")"): + base_name = re.sub(r"\s+\(\d{4}\)$", "", base_name) + if year: + base_name += f" {year}" + + # ------------------------- + # NEW: strip season/episode tokens from final base_name + # ------------------------- + def _strip_season_episode_tokens(name: str) -> str: + """ + Remove common season/episode markers from a title while preserving a trailing year. + Examples removed: S01, s01e02, 1x02, season 1, ep 02, episode 2, part 1 + """ + if not name: + return name + + # Preserve trailing year (e.g. "Title (2020)" or "Title 2020") + year_match = re.search(r'\(?\b(19|20)\d{2}\b\)?\s*$', name) + year_part = "" + if year_match: + year_part = year_match.group(0) + name = name[:year_match.start()].strip() + + # Common patterns to remove + patterns = [ + r'\bS\d{1,2}E\d{1,2}\b', # S01E02 + r'\bS\d{1,2}\b', # S01 + r'\bE\d{1,2}\b', # E02 + r'\b\d{1,2}x\d{1,2}\b', # 1x02 + r'\bSeason\s*\d{1,2}\b', # Season 1 + r'\bEp(?:isode)?\.?\s*\d{1,3}\b', # Ep02, Episode 2 + r'\bEpisode\s*\d{1,3}\b', + r'\bPart\s*\d{1,2}\b' + ] + + for p in patterns: + name = re.sub(p, ' ', name, flags=re.IGNORECASE) + + # Remove leftover separators and extra whitespace + name = re.sub(r'[_\.\-]+', ' ', name) # underscores/dots/hyphens + name = re.sub(r'\s+', ' ', name).strip() + + # Reattach year in canonical form if we removed it earlier + if year_part: + y = re.search(r'(19|20)\d{2}', year_part) + if y: + name = f"{name} {y.group(0)}" + + return name.strip() + + base_name = _strip_season_episode_tokens(base_name) + # If stripping accidentally removed everything, fall back to a safer value if not base_name: - base_name = filename + base_name = normalize(remove_ignored_words(normalize(processed_raw))) or filename + return { "processed": normalize(processed_raw), "base_name": base_name, @@ -171,66 +250,61 @@ def extract_media_info(filename: str, caption: str): @Client.on_message(filters.chat(CHANNELS) & (filters.document | filters.video | filters.audio)) async def media_handler(bot, message): - logger.info(f"media_handler triggered from chat {message.chat.id} | CHANNELS env = {CHANNELS}") - print(f"[AUTO INDEX] Triggered from {message.chat.id} | CHANNELS={CHANNELS}") - if not CHANNELS or CHANNELS == [-100]: - logger.error("CHANNELS env is empty or default -100. Set CHANNELS in Render env to -100xxxxxxxxx") - return - media = message.document or message.video or message.audio - if not media: - logger.warning("No media found in message") - return - file_name = getattr(media, "file_name", "unknown") - file_id = getattr(media, "file_id", "") - lock = locks[file_id] - async with lock: - try: - media.file_type = next((ft for ft in ("document", "video", "audio") if getattr(message, ft, None)), None) - media.caption = message.caption or "" - success, _ = await save_file(media) - if success: - print(f"File saved to DB: {file_name}") - logger.info(f"File saved to DB: {file_name}") - else: - print(f"File already exists or failed: {file_name}") - success = True + success = False + try: + media = message.document or message.video or message.audio + if not media: + return + + file_id = media.file_id + file_name = getattr(media, "file_name", "") + file_size = getattr(media, "file_size", 0) + + logger.info(f"File from {message.chat.id}: {file_name}") + + media.file_type = next((ft for ft in ("document", "video", "audio") if getattr(message, ft, None)), None) + media.caption = message.caption or "" + + lock = locks[file_id] + async with lock: + success, info = await save_file(media) if success: - try: - if await db.movie_update_status(bot.me.id): - await process_and_send_update(bot, file_name, message.caption or "") - except Exception as e: - logger.exception(f"Error in movie_update_status: {e}") - except DuplicateKeyError: - logger.info(f"Duplicate file skipped: {file_name}") - try: - if await db.movie_update_status(bot.me.id): - await process_and_send_update(bot, file_name, message.caption or "") - except: - pass - except FloodWait as e: - logger.warning(f"FloodWait {e.value}s for {file_name}") - await asyncio.sleep(e.value) - except PyMongoError as e: - logger.error(f"MongoDB Error: {e} for {file_name}") + print("File saved") + + except DuplicateKeyError: + pass + except FloodWait as e: + await asyncio.sleep(e.value) + except PyMongoError as e: + logger.error(f"MongoDB Error in media_handler: {e}") + except Exception as e: + logger.exception(f"Error processing media: {e}") + + if success: + try: + if await db.movie_update_status(temp.ME): + await process_and_send_update(bot, file_name, message.caption) except Exception as e: - logger.exception(f"Unexpected error in media_handler for {file_name}: {e}") + logger.exception("Error in movie update") async def process_and_send_update(bot, filename, caption): try: media_info = extract_media_info(filename, caption) base_name = media_info["base_name"] processed = media_info["processed"] + lock = locks[base_name] async with lock: await _process_with_lock(bot, filename, caption, media_info, base_name, processed) except PyMongoError as e: - logger.error(f"DB error in process_and_send_update: {e}") + logger.error(f"Database error in process_and_send_update: {e}") except Exception as e: - logger.exception(f"Processing failed: {e}") + logger.exception(f"Processing failed in process_and_send_update: {e}") async def _process_with_lock(bot, filename, caption, media_info, base_name, processed): if not hasattr(db, 'movie_updates'): db.movie_updates = db.db.movie_updates + movie_doc = await db.movie_updates.find_one({"_id": base_name}) error_tmdb=False file_data = { @@ -244,6 +318,7 @@ async def _process_with_lock(bot, filename, caption, media_info, base_name, proc "season": media_info["season"], "episode": media_info["episode"] } + if not movie_doc: if TMDB_POSTER: details = await get_movie_detailsx(base_name) @@ -253,23 +328,19 @@ async def _process_with_lock(bot, filename, caption, media_info, base_name, proc details = await get_movie_details(base_name) or {} else: details = await get_movie_details(base_name) or {} + raw_genres = details.get("genres", "N/A") if isinstance(raw_genres, str): genre_list = [g.strip() for g in raw_genres.split(",")] genres = ", ".join(g for g in genre_list if g in STANDARD_GENRES) or "N/A" else: genres = ", ".join(g for g in raw_genres if g in STANDARD_GENRES) or "N/A" - runtime_raw = details.get("runtime", "N/A") - if isinstance(runtime_raw, list): - runtime_raw = ", ".join(str(x) for x in runtime_raw) - runtime_formatted = format_runtime(runtime_raw) movie_doc = { "_id": base_name, "files": [file_data], "poster_url": details.get("backdrop_url") if LANDSCAPE_POSTER and TMDB_POSTER and details.get("backdrop_url") and not error_tmdb else details.get("poster_url"), "genres": genres, "rating": details.get("rating", "N/A"), - "runtime": runtime_formatted, "imdb_url": details.get("url", "")if not TMDB_POSTER or error_tmdb else details.get("tmdb_url"), "year": details.get("year") or media_info["year"], "tag": media_info["tag"], @@ -282,43 +353,28 @@ async def _process_with_lock(bot, filename, caption, media_info, base_name, proc try: await db.movie_updates.insert_one(movie_doc) await send_movie_update(bot, base_name) + movie_doc = await db.movie_updates.find_one({"_id": base_name}) except DuplicateKeyError: movie_doc = await db.movie_updates.find_one({"_id": base_name}) - if movie_doc and not any(f["filename"] == filename for f in movie_doc["files"]): - await db.movie_updates.update_one({"_id": base_name},{"$push": {"files": file_data}}) + if movie_doc: + if any(f["filename"] == filename for f in movie_doc["files"]): + return + await db.movie_updates.update_one( + {"_id": base_name}, + {"$push": {"files": file_data}} + ) + movie_doc["files"].append(file_data) schedule_update(bot, base_name) else: if any(f["filename"] == filename for f in movie_doc["files"]): return - await db.movie_updates.update_one({"_id": base_name},{"$push": {"files": file_data}}) + await db.movie_updates.update_one( + {"_id": base_name}, + {"$push": {"files": file_data}} + ) + movie_doc["files"].append(file_data) schedule_update(bot, base_name) -def format_runtime(runtime_input): - if not runtime_input or runtime_input == "N/A": - return "N/A" - runtime_str = str(runtime_input).strip() - if "h" in runtime_str.lower() and "m" in runtime_str.lower(): - return runtime_str - try: - if "min" in runtime_str.lower(): - mins = int(re.search(r'\d+', runtime_str).group()) - else: - nums = re.findall(r'\d+', runtime_str) - if nums: - mins = int(nums[0]) - if mins < 10: - return runtime_str - else: - return runtime_str - h = mins // 60 - m = mins % 60 - if h > 0: - return f"{h}h {m}m" if m else f"{h}h" - else: - return f"{m}m" - except: - return runtime_str - async def send_movie_update(bot, base_name): max_retries = 3 for attempt in range(max_retries): @@ -326,37 +382,57 @@ async def send_movie_update(bot, base_name): movie_doc = await db.movie_updates.find_one({"_id": base_name}) if not movie_doc: return None + text = generate_movie_message(movie_doc, base_name) - # BUTTON COLOR LOGIC: Movie = Green, Series = Blue - is_series = "#SERIES" in str(movie_doc.get("tag", "")) or any(f.get("season") for f in movie_doc.get("files", [])) - if is_series: - btn_text = "🔵 ɢᴇᴛ ғɪʟᴇs" # Blue for Series - else: - btn_text = "🟢 ɢᴇᴛ ғɪʟᴇs" # Green for Movie buttons = InlineKeyboardMarkup([[ - InlineKeyboardButton(btn_text, url=f"https://t.me/{temp.U_NAME}?start=getfile-{base_name.replace(' ', '-')}") + InlineKeyboardButton( + 'ɢᴇᴛ ғɪʟᴇs', + url=f"https://t.me/{temp.U_NAME}?start=getfile-{base_name.replace(' ', '-')}" + ) ]]) size=(2560, 1440) if LANDSCAPE_POSTER and TMDB_POSTER and movie_doc.get("is_backdrop") and not movie_doc.get("error_tmdb") else (853, 1280) if movie_doc.get("poster_url") and not LINK_PREVIEW: resized_poster = await fetch_image(movie_doc["poster_url"], size) if resized_poster: - msg = await bot.send_photo(chat_id=MOVIE_UPDATE_CHANNEL,photo=resized_poster,caption=text,reply_markup=buttons,parse_mode=enums.ParseMode.HTML) + msg = await bot.send_photo( + chat_id=MOVIE_UPDATE_CHANNEL, + photo=resized_poster, + caption=text, + reply_markup=buttons, + parse_mode=enums.ParseMode.HTML + ) is_photo = True else: - msg = await bot.send_message(chat_id=MOVIE_UPDATE_CHANNEL,text=text,reply_markup=buttons,parse_mode=enums.ParseMode.HTML) + send_params = { + "chat_id": MOVIE_UPDATE_CHANNEL, + "text": text, + "reply_markup": buttons, + "parse_mode": enums.ParseMode.HTML + } + msg = await bot.send_message(**send_params) is_photo = False else: - send_params = {"chat_id": MOVIE_UPDATE_CHANNEL,"text": text,"reply_markup": buttons,"parse_mode": enums.ParseMode.HTML} + send_params = { + "chat_id": MOVIE_UPDATE_CHANNEL, + "text": text, + "reply_markup": buttons, + "parse_mode": enums.ParseMode.HTML + } if movie_doc.get("poster_url") and LINK_PREVIEW: send_params["link_preview_options"] = LinkPreviewOptions(is_disabled=False, show_above_text=ABOVE_PREVIEW) else: send_params["link_preview_options"] = LinkPreviewOptions(is_disabled=not LINK_PREVIEW) msg = await bot.send_message(**send_params) is_photo = False - await db.movie_updates.update_one({"_id": base_name},{"$set": {"message_id": msg.id, "is_photo": is_photo}}) + + await db.movie_updates.update_one( + {"_id": base_name}, + {"$set": {"message_id": msg.id, "is_photo": is_photo}} + ) return msg except FloodWait as e: - await asyncio.sleep(e.value+2) + wait_time = e.value + 2 + await asyncio.sleep(wait_time) except Exception as e: logger.error(f"Failed to send movie update: {e}") break @@ -367,52 +443,73 @@ async def update_movie_message(bot, base_name): movie_doc = await db.movie_updates.find_one({"_id": base_name}) if not movie_doc: return + text = generate_movie_message(movie_doc, base_name) - is_series = "#SERIES" in str(movie_doc.get("tag", "")) or any(f.get("season") for f in movie_doc.get("files", [])) - if is_series: - btn_text = "🔵 ɢᴇᴛ ғɪʟᴇs" - else: - btn_text = "🟢 ɢᴇᴛ ғɪʟᴇs" buttons = InlineKeyboardMarkup([[ - InlineKeyboardButton(btn_text, url=f"https://t.me/{temp.U_NAME}?start=getfile-{base_name.replace(' ', '-')}") + InlineKeyboardButton( + 'ɢᴇᴛ ғɪʟᴇs', + url=f"https://t.me/{temp.U_NAME}?start=getfile-{base_name.replace(' ', '-')}" + ) ]]) + message_id = movie_doc.get("message_id") is_photo = movie_doc.get("is_photo", False) + if not message_id: await send_movie_update(bot, base_name) return + try: if is_photo: - await bot.edit_message_caption(chat_id=MOVIE_UPDATE_CHANNEL,message_id=message_id,caption=text,reply_markup=buttons,parse_mode=enums.ParseMode.HTML) + await bot.edit_message_caption( + chat_id=MOVIE_UPDATE_CHANNEL, + message_id=message_id, + caption=text, + reply_markup=buttons, + parse_mode=enums.ParseMode.HTML + ) else: - await bot.edit_message_text(chat_id=MOVIE_UPDATE_CHANNEL,message_id=message_id,text=text,reply_markup=buttons,parse_mode=enums.ParseMode.HTML,link_preview_options=LinkPreviewOptions(is_disabled=not LINK_PREVIEW, show_above_text=ABOVE_PREVIEW)) + await bot.edit_message_text( + chat_id=MOVIE_UPDATE_CHANNEL, + message_id=message_id, + text=text, + reply_markup=buttons, + parse_mode=enums.ParseMode.HTML, + link_preview_options=LinkPreviewOptions(is_disabled=not LINK_PREVIEW, show_above_text=ABOVE_PREVIEW) + ) return except MessageNotModified: pass - except MessageIdInvalid: + except MessageIdInvalid as e: + logger.warning(f"Message update skipped due to error: {e}") pass except Exception: try: - await bot.delete_messages(chat_id=MOVIE_UPDATE_CHANNEL,message_ids=message_id) - await db.movie_updates.update_one({"_id": base_name},{"$set": {"message_id": None, "is_photo": False}}) - except: + await bot.delete_messages( + chat_id=MOVIE_UPDATE_CHANNEL, + message_ids=message_id + ) + await db.movie_updates.update_one( + {"_id": base_name}, + {"$set": {"message_id": None, "is_photo": False}} + ) + except Exception as e: + logger.error(f"Error during message deletion/update in recovery: {e}") pass await send_movie_update(bot, base_name) except Exception as e: logger.error(f"Failed to update movie message for {base_name}: {e}") def generate_movie_message(movie_doc, base_name): - from collections import defaultdict all_qualities = set() all_languages = set() all_ott_platforms = set() all_tags = set() episodes_by_season = defaultdict(set) + for file in movie_doc["files"]: if file["quality"] != "N/A": - # Split and uppercase for final display - quals = [q.strip().upper() for q in file["quality"].split(",") if q.strip()] - all_qualities.update(quals) + all_qualities.update(q.strip() for q in file["quality"].split(",") if q.strip()) if file["language"] != "N/A": all_languages.update(lang.strip() for lang in file["language"].split(",") if lang.strip()) if file["ott_platform"] != "N/A": @@ -421,7 +518,10 @@ def generate_movie_message(movie_doc, base_name): if file["tag"]: all_tags.add(file["tag"]) if file.get("season") and file.get("episode"): - episodes_by_season[file["season"]].add(file["episode"]) + season = file["season"] + episode = file["episode"] + episodes_by_season[season].add(episode) + primary_tag = "#SERIES" if "#SERIES" in all_tags else "#MOVIE" epi_block = "" if episodes_by_season: @@ -429,6 +529,7 @@ def generate_movie_message(movie_doc, base_name): for season, episodes in sorted(episodes_by_season.items(), key=lambda x: int(x[0])): singles = [] ranges = [] + for ep in episodes: if "-" in ep: ranges.append(ep) @@ -437,6 +538,7 @@ def generate_movie_message(movie_doc, base_name): singles.append(int(ep)) except ValueError: ranges.append(ep) + singles.sort() collapsed = [] start = end = None @@ -450,11 +552,14 @@ def generate_movie_message(movie_doc, base_name): start = end = num if start is not None: collapsed.append(str(start) if start == end else f"{start}-{end}") + all_ep_parts = collapsed + sorted(ranges, key=lambda s: int(s.split("-")[0])) episode_lines.append(f"S{int(season)}: {', '.join(all_ep_parts)}") + epi_str = "\n".join(episode_lines) if epi_str: epi_block = f"📺 ᴇᴘɪsᴏᴅᴇs : \n{epi_str}" + genres = movie_doc.get("genres", "N/A") quality_str = ", ".join(sorted(all_qualities)) if all_qualities else "N/A" language_str = ", ".join(sorted(all_languages)) if all_languages else "N/A" @@ -464,8 +569,8 @@ def generate_movie_message(movie_doc, base_name): r = float(rating) except (TypeError, ValueError): r = 0.0 + rating_text = "-" if r == 0.0 else str(rating) - runtime = movie_doc.get("runtime", "N/A") year_val = str(movie_doc.get("year") or "") filename_display = base_name if year_val and filename_display.strip().endswith(year_val): @@ -478,10 +583,9 @@ def generate_movie_message(movie_doc, base_name): year=year_val, genres=genres, ott=ott_str, - runtime=runtime, quality=quality_str, language=language_str, episodes=epi_block, rating=rating_text, search_link=temp.B_LINK - ) +) From e83570672ec57cf80452f53bcecbd48be85efa31 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Wed, 23 Sep 2026 19:59:34 +0530 Subject: [PATCH 69/77] Update Script.py --- Script.py | 153 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 85 insertions(+), 68 deletions(-) diff --git a/Script.py b/Script.py index 55521dd3..e7eda801 100644 --- a/Script.py +++ b/Script.py @@ -3,33 +3,35 @@ class script(object): ʜᴇʏ {}, {} -🤖 I ᴀᴍ {}, ᴛʜᴇ ᴍᴏꜱᴛ ᴘᴏᴡᴇʀꜰᴜʟ ᴀᴜᴛᴏ ꜰɪʟᴛᴇʀ ʙᴏᴛ ᴡɪᴛʜ ᴘʀᴇᴍɪᴜᴍ ꜰᴇᴀᴛᴜʀᴇꜱ. +🤖 ɪ ᴀᴍ {}, ᴛʜᴇ ᴍᴏꜱᴛ ᴘᴏᴡᴇʀꜰᴜʟ ᴀᴜᴛᴏ ꜰɪʟᴛᴇʀ ʙᴏᴛ ᴡɪᴛʜ ᴘʀᴇᴍɪᴜᴍ ꜰᴇᴀᴛᴜʀᴇꜱ. """ + GSTART_TXT = """🧸 Sʏsᴛᴇᴍ ɪɴɪᴛɪᴀʟɪᴢᴇᴅ 🎧 ʜᴇʏ {}, -🤖 I ᴀᴍ {}, ᴛʜᴇ ᴍᴏꜱᴛ ᴘᴏᴡᴇʀꜰᴜʟ ᴀᴜᴛᴏ ꜰɪʟᴛᴇʀ ʙᴏᴛ ᴡɪᴛʜ ᴘʀᴇᴍɪᴜᴍ ꜰᴇᴀᴛᴜʀᴇꜱ.""" +🤖 ɪ ᴀᴍ {}, ᴛʜᴇ ᴍᴏꜱᴛ ᴘᴏᴡᴇʀꜰᴜʟ ᴀᴜᴛᴏ ꜰɪʟᴛᴇʀ ʙᴏᴛ ᴡɪᴛʜ ᴘʀᴇᴍɪᴜᴍ ꜰᴇᴀᴛᴜʀᴇꜱ.""" + HELP_TXT = """ ✨ Hᴏᴡ ᴛᴏ ʀᴇǫᴜᴇꜱᴛ ᴅʀᴀᴍᴀꜱ & ᴍᴏᴠɪᴇꜱ ✨ -1⃣ Sᴇᴀʀᴄʜ ᴛʜᴇ ᴄᴏʀʀᴇᴄᴛ ɴᴀᴍᴇ ᴏɴ ɢᴏᴏɢʟᴇ. -2⃣ Sᴇɴᴅ ᴛʜᴇ ɴᴀᴍᴇ ɪɴ ᴛʜᴇ ɢʀᴏᴜᴘ. -3⃣ Uꜱᴇ ᴛʜɪꜱ ꜰᴏʀᴍᴀᴛ: +1️⃣ Sᴇᴀʀᴄʜ ᴛʜᴇ ᴄᴏʀʀᴇᴄᴛ ɴᴀᴍᴇ ᴏɴ ɢᴏᴏɢʟᴇ. +2️⃣ Sᴇɴᴅ ᴛʜᴇ ɴᴀᴍᴇ ɪɴ ᴛʜᴇ ɢʀᴏᴜᴘ. +3️⃣ Uꜱᴇ ᴛʜɪꜱ ꜰᴏʀᴍᴀᴛ: 📌 Fᴏʀ ꜱᴇʀɪᴇꜱ: -➤ ᴅʀᴀᴍᴀ ɴᴀᴍᴇ + S01 (ꜰᴏʀ ꜱᴇᴀꜱᴏɴ 1, ᴄʜᴀɴɢᴇ ꜰᴏʀ ᴏᴛʜᴇʀꜱ) +➤ Sᴇʀɪᴇs ɴᴀᴍᴇ + S01 (ꜰᴏʀ ꜱᴇᴀꜱᴏɴ 1, ᴄʜᴀɴɢᴇ ꜰᴏʀ ᴏᴛʜᴇʀꜱ) -📌 Fᴏʀ ʜɪɴᴅɪ ᴅʀᴀᴍᴀꜱ: -➤ ᴅʀᴀᴍᴀ ɴᴀᴍᴇ + ʜɪɴᴅɪ +📌 Fᴏʀ ᴅʀᴀᴍᴀꜱ: +➤ Dʀᴀᴍᴀ ɴᴀᴍᴇ + S01 (ꜰᴏʀ ꜱᴇᴀꜱᴏɴ 1, ᴄʜᴀɴɢᴇ ꜰᴏʀ ᴏᴛʜᴇʀꜱ) 📌 Fᴏʀ ᴍᴏᴠɪᴇꜱ: -➤ ᴍᴏᴠɪᴇ ɴᴀᴍᴇ + ʏᴇᴀʀ (ᴇx: ᴊᴏᴋᴇʀ 2019) +➤ Mᴏᴠɪᴇ ɴᴀᴍᴇ + ʏᴇᴀʀ (ᴇx: ᴊᴏᴋᴇʀ 2019) -🚀 Fᴏʟʟᴏᴡ ᴛʜᴇꜱᴇ ꜱᴛᴇᴘꜱ ᴛᴏ ɢᴇᴛ ʙᴇsᴛ ʀᴇsᴜʟᴛ !! +🚀 ꜰᴏʟʟᴏᴡ ᴛʜᴇꜱᴇ ꜱᴛᴇᴘꜱ !! """ ABOUT_TXT = """╭────[Mʏ Dᴇᴛᴀɪʟs ]────⍟ @@ -41,14 +43,13 @@ class script(object): ├⍟ Bᴏᴛ Sᴇʀᴠᴇʀ : Rᴇɴᴅᴇʀ ├⍟ Bᴜɪʟᴅ Sᴛᴀᴛᴜs : ᴠ1.4 [ Sᴛᴀʙʟᴇ ] ╰───────────────⍟""" - RESTART_TXT = """ {} Bᴏᴛ Rᴇsᴛᴀʀᴛᴇᴅ ! 📅 Dᴀᴛᴇ : {} ⏰ Tɪᴍᴇ : {} 🌐 Tɪᴍᴇᴢᴏɴᴇ : Asia/Kolkata -🛠 Bᴜɪʟᴅ Sᴛᴀᴛᴜs: v1.4 [ Sᴛᴀʙʟᴇ ] +🛠️ Bᴜɪʟᴅ Sᴛᴀᴛᴜs: v1.4 [ Sᴛᴀʙʟᴇ ] """ MULTI_STATUS_TXT = """🗃ᴜsᴇʀs ᴅᴀᴛᴀʙᴀsᴇ 🗃 @@ -111,7 +112,7 @@ class script(object): Iᴅ - {} Nᴀᴍᴇ - {} """ - NT_ADMIN_ALRT_TXT = """‼ Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴀᴅᴍɪɴ ɪɴ ᴛʜɪꜱ ɢʀᴏᴜᴘ ‼""" + NT_ADMIN_ALRT_TXT = """‼️ Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴀᴅᴍɪɴ ɪɴ ᴛʜɪꜱ ɢʀᴏᴜᴘ ‼️""" NT_ALRT_TXT = """Not Yours!""" @@ -128,52 +129,54 @@ class script(object): ✨ ᴜɴʟᴏᴄᴋ ᴇxᴄʟᴜsɪᴠᴇ ᴄᴏɴᴛᴇɴᴛ ᴀɴᴅ ꜰᴇᴀᴛᴜʀᴇs 💳 ʙᴜʏ ᴘʀᴇᴍɪᴜᴍ ᴛᴏ ɢᴇᴛ sᴛᴀʀᴛᴇᴅ""" - PRE_STREAM_ALERT = """⚠ ᴘʀᴇᴍɪᴜᴍ ᴄᴏɴᴛᴇɴᴛ ❗ + PRE_STREAM_ALERT = """⚠️ ᴘʀᴇᴍɪᴜᴍ ᴄᴏɴᴛᴇɴᴛ ❗ 🔓 ᴜɴʟᴏᴄᴋ ɪᴛ ʙʏ ᴜᴘɢʀᴀᴅɪɴɢ ᴛᴏ ᴘʀᴇᴍɪᴜᴍ""" - CUDNT_FND = SPELLING_ERROR_TXT = """‼ ꜱᴘᴇʟʟɪɴɢ ᴍɪꜱᴛᴀᴋᴇ ʙʀᴏ! + CUDNT_FND = SPELLING_ERROR_TXT = """‼️ ꜱᴘᴇʟʟɪɴɢ ᴍɪꜱᴛᴀᴋᴇ ʙʀᴏ! 😊 ɴᴏ ᴡᴏʀʀɪᴇꜱ — ᴄʜᴏᴏꜱᴇ ᴛʜᴇ ᴄᴏʀʀᴇᴄᴛ ᴏɴᴇ ʙᴇʟᴏᴡ 👇
👇 नीचे दिए गए विकल्पों में से movie के नाम की सही spelling चुनें
""" - DEL_MSG = """⚠ ᴛʜɪꜱ ᴍᴏᴠɪᴇ ꜰɪʟᴇ/ᴠɪᴅᴇᴏ ᴡɪʟʟ ʙᴇ ᴅᴇʟᴇᴛᴇᴅ ɪɴ {} + + DEL_MSG = """⚠️ ᴛʜɪꜱ ᴍᴏᴠɪᴇ ꜰɪʟᴇ/ᴠɪᴅᴇᴏ ᴡɪʟʟ ʙᴇ ᴅᴇʟᴇᴛᴇᴅ ɪɴ {}
ᴘʟᴇᴀꜱᴇ ꜰᴏʀᴡᴀʀᴅ ᴛʜɪꜱ ꜰɪʟᴇ ᴛᴏ ꜱᴏᴍᴇᴡʜᴇʀᴇ ᴇʟꜱᴇ & ꜱᴛᴀʀᴛ ᴅᴏᴡɴʟᴏᴀᴅɪɴɢ ᴛʜᴇʀᴇ
""" - I_CUDNT = """Sᴏʀʀʏ ɴᴏ ꜰɪʟᴇs ᴡᴇʀᴇ ꜰᴏᴜɴᴅ ꜰᴏʀ ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ {} 😕 -Cʜᴇᴄᴋ ʏᴏᴜʀ sᴘᴇʟʟɪɴɢ ɪɴ ɢᴏᴏɢʟᴇ ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ 😃 + I_CUDNT = """sᴏʀʀʏ ɴᴏ ꜰɪʟᴇs ᴡᴇʀᴇ ꜰᴏᴜɴᴅ ꜰᴏʀ ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ {} 😕 + +ᴄʜᴇᴄᴋ ʏᴏᴜʀ sᴘᴇʟʟɪɴɢ ɪɴ ɢᴏᴏɢʟᴇ ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ 😃 -📝 Mᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ ꜰᴏʀᴍᴀᴛ 👇 +📝 ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ ꜰᴏʀᴍᴀᴛ 👇 -⚜ Exᴀᴍᴘʟᴇ : Jawan or Jawan 2023 +⚜️ ᴇxᴀᴍᴘʟᴇ : Jawan or Jawan 2023 -📝 Sᴇʀɪᴇꜱ ʀᴇǫᴜᴇꜱᴛ ꜰᴏʀᴍᴀᴛ 👇 +📝 ꜱᴇʀɪᴇꜱ ʀᴇǫᴜᴇꜱᴛ ꜰᴏʀᴍᴀᴛ 👇 -⚜ Exᴀᴍᴘʟᴇ : Loki S01 or Loki S01E04 or Lucifer S03E24 +⚜️ ᴇxᴀᴍᴘʟᴇ : Loki S01 or Loki S01E04 or Lucifer S03E24 -🚯 Dᴏɴᴛ ᴜꜱᴇ ➠ ':(!,./)""" +🚯 ᴅᴏɴᴛ ᴜꜱᴇ ➠ ':(!,./)""" - MVE_NT_FND = NOT_FOUND_TXT = """😌 Tʜɪꜱ ᴍᴏᴠɪᴇ ɪꜱ ɴᴏᴛ ᴀᴠᴀɪʟᴀʙʟᴇ ɪɴ ᴍʏ ᴅᴀᴛᴀʙᴀꜱᴇ. + MVE_NT_FND = NOT_FOUND_TXT = """😌 ᴛʜɪꜱ ᴍᴏᴠɪᴇ ɪꜱ ɴᴏᴛ ᴀᴠᴀɪʟᴀʙʟᴇ ɪɴ ᴍʏ ᴅᴀᴛᴀʙᴀꜱᴇ.
😌 यह ᴍᴏᴠɪᴇ मुझे ᴍᴇʀᴇ ᴅᴀᴛᴀʙᴀꜱᴇ में नहीं मिली।
""" - ALREADY_AVAILABLE_TXT = """Hᴇʏ {}, + ALREADY_AVAILABLE_TXT = """ʜᴇʏ {}, Yᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ɪꜱ ᴀʟʀᴇᴀᴅʏ ᴀᴠᴀɪʟᴀʙʟᴇ ✅
📂 ꜰɪʟᴇꜱ ꜰᴏᴜɴᴅ : {} 🔍 ꜱᴇᴀʀᴄʜ : {}
-‼ Tʜɪs ɪs ᴀ sᴜᴘᴘᴏʀᴛ ɢʀᴏᴜᴘ sᴏ ᴛʜᴀᴛ ʏᴏᴜ ᴄᴀɴ'ᴛ ɢᴇᴛ ғɪʟᴇs ғʀᴏᴍ ʜᴇʀᴇ... +‼️ ᴛʜɪs ɪs ᴀ sᴜᴘᴘᴏʀᴛ ɢʀᴏᴜᴘ sᴏ ᴛʜᴀᴛ ʏᴏᴜ ᴄᴀɴ'ᴛ ɢᴇᴛ ғɪʟᴇs ғʀᴏᴍ ʜᴇʀᴇ... -📝 Sᴇᴀʀᴄʜ ʜᴇʀᴇ : 👇
""" +📝 ꜱᴇᴀʀᴄʜ ʜᴇʀᴇ : 👇
""" - MAINTENANCE_TXT = """🛑 Sᴇʀᴠɪᴄᴇ ᴜɴᴅᴇʀ ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ 🛑 + MAINTENANCE_TXT = """🛑 ꜱᴇʀᴠɪᴄᴇ ᴜɴᴅᴇʀ ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ 🛑 -Hᴇʏ {}, ᴡᴇ ᴀʀᴇ ᴄᴜʀʀᴇɴᴛʟʏ ᴜᴘᴅᴀᴛɪɴɢ ᴏᴜʀ ꜱʏꜱᴛᴇᴍꜱ ᴛᴏ ꜱᴇʀᴠᴇ ʏᴏᴜ ʙᴇᴛᴛᴇʀ. ᴛʜᴇ ꜱᴇʀᴠɪᴄᴇ ɪꜱ ᴛᴇᴍᴘᴏʀᴀʀɪʟʏ ᴅɪꜱᴀʙʟᴇᴅ. +ʜᴇʏ {}, ᴡᴇ ᴀʀᴇ ᴄᴜʀʀᴇɴᴛʟʏ ᴜᴘᴅᴀᴛɪɴɢ ᴏᴜʀ ꜱʏꜱᴛᴇᴍꜱ ᴛᴏ ꜱᴇʀᴠᴇ ʏᴏᴜ ʙᴇᴛᴛᴇʀ. ᴛʜᴇ ꜱᴇʀᴠɪᴄᴇ ɪꜱ ᴛᴇᴍᴘᴏʀᴀʀɪʟʏ ᴅɪꜱᴀʙʟᴇᴅ. -
Tʜᴇ ꜱᴇʀᴠɪᴄᴇ ɪꜱ ᴄᴜʀʀᴇɴᴛʟʏ ᴜɴᴅᴇʀ ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ. ᴘʟᴇᴀsᴇ ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ. 😊
""" +
ᴛʜᴇ ꜱᴇʀᴠɪᴄᴇ ɪꜱ ᴄᴜʀʀᴇɴᴛʟʏ ᴜɴᴅᴇʀ ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ. ᴘʟᴇᴀꜱᴇ ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ. 😊
""" PM_SEARCH_DISABLED_TXT = """🙋 ʜᴇʏ {} 😍, @@ -189,13 +192,13 @@ class script(object): 🆔 ɪᴅ : {} 💬 ᴍᴇssᴀɢᴇ : {}""" - LINK_EXPIRED_TXT = """‼ Lɪɴᴋ ᴇxᴘɪʀᴇᴅ, ᴘʟᴇᴀꜱᴇ ᴛʀʏ ᴀɢᴀɪɴ...""" + LINK_EXPIRED_TXT = """‼️ Lɪɴᴋ ᴇxᴘɪʀᴇᴅ, ᴘʟᴇᴀꜱᴇ ᴛʀʏ ᴀɢᴀɪɴ...""" REFER_TXT = """Hᴇʏ, ʏᴏᴜʀ ʀᴇꜰᴇʀ ʟɪɴᴋ: https://t.me/{}?start=reff_{} -
Sʜᴀʀᴇ ᴛʜɪs ʟɪɴᴋ ᴡɪᴛʜ ʏᴏᴜʀ ғʀɪᴇɴᴅs. ᴇᴀᴄʜ ᴛɪᴍᴇ ᴛʜᴇʏ ᴊᴏɪɴ, ʏᴏᴜ ᴡɪʟʟ ɢᴇᴛ 10 ʀᴇғғᴇʀᴀʟ ᴘᴏɪɴᴛs ᴀɴᴅ ᴀꜰᴛᴇʀ 100 ᴘᴏɪɴᴛs ʏᴏᴜ ᴡɪʟʟ ɢᴇᴛ 1 ᴍᴏɴᴛʜ ᴘʀᴇᴍɪᴜᴍ sᴜʙsᴄʀɪᴘᴛɪᴏɴ.
""" +
Sʜᴀʀᴇ ᴛʜɪs ʟɪɴᴋ ᴡɪᴛʜ ʏᴏᴜʀ ғʀɪᴇɴᴅs. ᴇᴀᴄʜ ᴛɪᴍᴇ ᴛʜᴇʏ ᴊᴏɪɴ, ʏᴏᴜ ᴡɪʟʟ ɢᴇᴛ 10 ʀᴇꜰꜰᴇʀᴀʟ ᴘᴏɪɴᴛs ᴀɴᴅ ᴀꜰᴛᴇʀ 100 ᴘᴏɪɴᴛs ʏᴏᴜ ᴡɪʟʟ ɢᴇᴛ 1 ᴍᴏɴᴛʜ ᴘʀᴇᴍɪᴜᴍ sᴜʙsᴄʀɪᴘᴛɪᴏɴ.
""" REFER_SELF_ALRT = """Hᴇʏ Dᴜᴅᴇ, Yᴏᴜ Cᴀɴ'ᴛ Rᴇғᴇʀ Yᴏᴜʀsᴇʟғ 🤣! @@ -203,40 +206,40 @@ class script(object): REFER_ALREADY_ALRT = """Yᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ ᴀʟʀᴇᴀᴅʏ ɪɴᴠɪᴛᴇᴅ ❗""" - REFER_ALREADY_JOINED_ALRT = """‼ Yᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ ᴀʟʀᴇᴀᴅʏ ɪɴᴠɪᴛᴇᴅ ᴏʀ ᴊᴏɪɴᴇᴅ""" + REFER_ALREADY_JOINED_ALRT = """‼️ Yᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ ᴀʟʀᴇᴀᴅʏ ɪɴᴠɪᴛᴇᴅ ᴏʀ ᴊᴏɪɴᴇᴅ""" - REFER_CONGRATS_ALRT = """🎉 Cᴏɴɢʀᴀᴛᴜʟᴀᴛɪᴏɴs! ʏᴏᴜ ᴡᴏɴ 10 ʀᴇғᴇʀʀᴀʟ ᴘᴏɪɴᴛ ʙᴇᴄᴀᴜsᴇ ʏᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ sᴜᴄᴄᴇssꜰᴜʟʟʏ ɪɴᴠɪᴛᴇᴅ ☞ {}!""" + REFER_CONGRATS_ALRT = """🎉 Cᴏɴɢʀᴀᴛᴜʟᴀᴛɪᴏɴs! ʏᴏᴜ ᴡᴏɴ 10 ʀᴇꜰᴇʀʀᴀʟ ᴘᴏɪɴᴛ ʙᴇᴄᴀᴜsᴇ ʏᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ sᴜᴄᴄᴇssꜰᴜʟʟʏ ɪɴᴠɪᴛᴇᴅ ☞ {}!""" REFER_INVITED_ALRT = """Yᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ sᴜᴄᴄᴇssꜰᴜʟʟʏ ɪɴᴠɪᴛᴇᴅ ʙʏ {}!""" FORCESUB_TXT = """👋 Hᴇʟʟᴏ {} -🛑 Yᴏᴜ ᴍᴜsᴛ ᴊᴏɪɴ ᴛʜᴇ ʀᴇǫᴜɪʀᴇᴅ ᴄʜᴀɴɴᴇʟs ᴛᴏ ᴄᴏɴᴛɪɴᴜᴇ. +🛑 yᴏᴜ ᴍᴜsᴛ ᴊᴏɪɴ ᴛʜᴇ ʀᴇǫᴜɪʀᴇᴅ ᴄʜᴀɴɴᴇʟs ᴛᴏ ᴄᴏɴᴛɪɴᴜᴇ.
👉 Jᴏɪɴ ᴀʟʟ ᴛʜᴇ ʙᴇʟᴏᴡ ᴄʜᴀɴɴᴇʟs ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ.
""" - BOT_ADD_TXT = """Tʜᴀɴᴋ ʏᴏᴜ ғᴏʀ ᴀᴅᴅɪɴɢ ᴍᴇ ᴛᴏ {} ❣ + BOT_ADD_TXT = """Tʜᴀɴᴋ ʏᴏᴜ ғᴏʀ ᴀᴅᴅɪɴɢ ᴍᴇ ᴛᴏ {} ❣️ -
ɪғ ʏᴏᴜ ʜᴀᴠᴇ ᴀɴʏ ǫᴜᴇsᴛɪᴏɴs & ᴅᴏᴜʙᴛs ᴀʙᴏᴜᴛ ᴜsɪɴɢ ᴍᴇ ᴄᴏɴᴛᴀᴄᴛ sᴜᴘᴘᴏʀᴛ.
""" +
Iғ ʏᴏᴜ ʜᴀᴠᴇ ᴀɴʏ ǫᴜᴇsᴛɪᴏɴs & ᴅᴏᴜʙᴛs ᴀʙᴏᴜᴛ ᴜsɪɴɢ ᴍᴇ ᴄᴏɴᴛᴀᴄᴛ sᴜᴘᴘᴏʀᴛ.
""" CHAT_RESTRICTED_TXT = """Cʜᴀᴛ ɴᴏᴛ ᴀʟʟᴏᴡᴇᴅ 🐞 -
Mʏ ᴀᴅᴍɪɴꜱ ʜᴀᴠᴇ ʀᴇꜱᴛʀɪᴄᴛᴇᴅ ᴍᴇ ꜰʀᴏᴍ ᴡᴏʀᴋɪɴɢ ʜᴇʀᴇ ! ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴋɴᴏᴡ ᴍᴏʀᴇ ᴀʙᴏᴜᴛ ɪᴛ ᴄᴏɴᴛᴀᴄᴛ ꜱᴜᴘᴘᴏʀᴛ.
""" +
mʏ ᴀᴅᴍɪɴꜱ ʜᴀᴠᴇ ʀᴇꜱᴛʀɪᴄᴛᴇᴅ ᴍᴇ ꜰʀᴏᴍ ᴡᴏʀᴋɪɴɢ ʜᴇʀᴇ ! ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴋɴᴏᴡ ᴍᴏʀᴇ ᴀʙᴏᴜᴛ ɪᴛ ᴄᴏɴᴛᴀᴄᴛ ꜱᴜᴘᴘᴏʀᴛ.
""" LEAVE_CHAT_TXT = """Hᴇʟʟᴏ ꜰʀɪᴇɴᴅꜱ, -
Mʏ ᴀᴅᴍɪɴ ʜᴀꜱ ᴛᴏʟᴅ ᴍᴇ ᴛᴏ ʟᴇᴀᴠᴇ ᴛʜɪs ɢʀᴏᴜᴘ, ꜱᴏ ɪ ʜᴀᴠᴇ ᴛᴏ ɢᴏ ! ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴀᴅᴅ ᴍᴇ ᴀɢᴀɪɴ ᴄᴏɴᴛᴀᴄᴛ ꜱᴜᴘᴘᴏʀᴛ.
""" +
Mʏ ᴀᴅᴍɪɴ ʜᴀꜱ ᴛᴏʟᴅ ᴍᴇ ᴛᴏ ʟᴇᴀᴠᴇ ᴛʜɪꜱ ɢʀᴏᴜᴘ, ꜱᴏ ɪ ʜᴀᴠᴇ ᴛᴏ ɢᴏ ! ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴀᴅᴅ ᴍᴇ ᴀɢᴀɪɴ ᴄᴏɴᴛᴀᴄᴛ ꜱᴜᴘᴘᴏʀᴛ.
""" - SEARCHING_TXT = """Sᴇᴀʀᴄʜɪɴɢ ғᴏʀ '{}' 🔎""" + SEARCHING_TXT = """ Sᴇᴀʀᴄʜɪɴɢ ғᴏʀ '{}' 🔎""" TOP_ALRT_MSG = """Sᴇᴀʀᴄʜɪɴɢ ꜰᴏʀ ǫᴜᴇʀʏ ɪɴ ᴍʏ ᴅᴀᴛᴀʙᴀꜱᴇ...""" - MELCOW_ENG = """👋 Hᴇʏ {},\n\n🍁 ᴡᴇʟᴄᴏᴍᴇ ᴛᴏ\n🌟 {} \n\n🔍 ʜᴇʀᴇ ʏᴏᴜ ᴄᴀɴ ꜱᴇᴀʀᴄʜ ʏᴏᴜʀ ꜰᴀᴠᴏᴜʀɪᴛᴇ ᴍᴏᴠɪᴇꜱ ᴏʀ ꜱᴇʀɪᴇꜱ ʙʏ ᴊᴜꜱᴛ ᴛʏᴘɪɴɢ ɪᴛ'ꜱ ɴᴀᴍᴇ 🔎\n\n⚠ ɪꜰ ʏᴏᴜ'ʀᴇ ʜᴀᴠɪɴɢ ᴀɴʏ ᴘʀᴏʙʟᴇᴍ ʀᴇɢᴀʀᴅɪɴɢ ᴅᴏᴡɴʟᴏᴀᴅɪɴɢ ᴏʀ ꜱᴏᴍᴇᴛʜɪɴɢ ᴇʟꜱᴇ ᴛʜᴇɴ ᴍᴇꜱꜱᴀɢᴇ ʜᴇʀᴇ 👇""" + MELCOW_ENG = """👋 Hᴇʏ {},\n\n🍁 ᴡᴇʟᴄᴏᴍᴇ ᴛᴏ\n🌟 {} \n\n🔍 ʜᴇʀᴇ ʏᴏᴜ ᴄᴀɴ ꜱᴇᴀʀᴄʜ ʏᴏᴜʀ ꜰᴀᴠᴏᴜʀɪᴛᴇ ᴍᴏᴠɪᴇꜱ ᴏʀ ꜱᴇʀɪᴇꜱ ʙʏ ᴊᴜꜱᴛ ᴛʏᴘɪɴɢ ɪᴛ'ꜱ ɴᴀᴍᴇ 🔎\n\n⚠️ ɪꜰ ʏᴏᴜ'ʀᴇ ʜᴀᴠɪɴɢ ᴀɴʏ ᴘʀᴏʙʟᴇᴍ ʀᴇɢᴀʀᴅɪɴɢ ᴅᴏᴡɴʟᴏᴀᴅɪɴɢ ᴏʀ ꜱᴏᴍᴇᴛʜɪɴɢ ᴇʟꜱᴇ ᴛʜᴇɴ ᴍᴇꜱꜱᴀɢᴇ ʜᴇʀᴇ 👇""" DISCLAIMER_TXT = """ ᴛʜɪꜱ ɪꜱ ᴀɴ ᴏᴘᴇɴ ꜱᴏᴜʀᴄᴇ ᴘʀᴏᴊᴇᴄᴛ. -ᴀʟʟ ᴛʜᴇ ꜰɪʟᴇꜱ ɪɴ ᴛʜɪꜱ ʙᴏᴛ ᴀʀᴇ ꜰʀᴇᴇʟʏ ᴀᴠᴀɪʟᴀʙʟᴇ ᴏɴ ᴛʜᴇ ɪɴᴛᴇʀɴᴇᴛ ᴏʀ ᴘᴏꜱᴛᴇᴅ ʙʏ ꜱᴏᴍᴇʙᴏᴅʏ ᴇʟꜱᴇ. ᴊᴜꜱᴛ ꜰᴏʀ ᴇᴀꜱʏ ꜱᴇᴀʀᴄʜɪɴɢ ᴛʜɪꜱ ʙᴏᴛ ɪꜱ ɪɴᴅᴇxɪɴɢ ꜰɪʟᴇꜱ ᴡʜɪᴄʜ ᴀʀᴇ ᴀʟʀᴇᴀᴅʏ ᴜᴘʟᴏᴀᴅᴇᴅ ᴏɴ ᴛᴇʟᴇɢʀᴀᴍ. ᴡᴇ ʀᴇꜱᴘᴇᴄᴛ ᴀʟʟ ᴛʜᴇ ᴄᴏᴘʏʀɪɢʜᴛ ʟᴀᴡꜱ ᴀɴᴅ ᴡᴏʀᴋꜱ ɪɴ ᴄᴏᴍᴘʟɪᴀɴᴄᴇ ᴡɪᴛʜ ᴅᴍᴄᴀ ᴀɴᴅ ᴇᴜᴄᴅ. ɪꜰ ᴀɴʏᴛʜɪɴɢ ɪꜱ ᴀɢᴀɪɴꜱᴛ ʟᴀᴡ ᴘʟᴇᴀꜱᴇ ᴄᴏɴᴛᴀᴄᴛ ᴍᴇ ꜱᴏ ᴛʜᴀᴛ ɪᴛ ᴄᴀɴ ʙᴇ ʀᴇᴍᴏᴠᴇᴅ ᴀꜱᴀᴘ. ɪᴛ ɪꜱ ꜰᴏʀʙɪᴅᴅᴇɴ ᴛᴏ ᴅᴏᴡɴʟᴏᴀᴅ, ꜱᴛʀᴇᴀᴍ, ʀᴇᴘʀᴏᴅᴜᴄᴇ, ꜱʜᴀʀᴇ ᴏʀ ᴄᴏɴꜱᴜᴍᴇ ᴄᴏɴᴛᴇɴᴛ ᴡɪᴛʜᴏᴜᴛ ᴇxᴘʟɪᴄɪᴛ ᴘᴇʀᴍɪꜱꜱɪᴏɴ ꜰʀᴏᴍ ᴛʜᴇ ᴄᴏɴᴛᴇɴᴛ ᴄʀᴇᴀᴛᴏʀ ᴏʀ ʟᴇɢᴀʟ ᴄᴏᴘʏʀɪɢʜᴛ ʜᴏʟᴅᴇʀ. ɪꜰ ʏᴏᴜ ʙᴇʟɪᴇᴠᴇ ᴛʜɪꜱ ʙᴏᴛ ɪꜱ ᴠɪᴏʟᴀᴛɪɴɢ ʏᴏᴜʀ ɪɴᴛᴇʟʟᴇᴄᴛᴜᴀʟ ᴘʀᴏᴘᴇʀᴛʏ, ᴄᴏɴᴛᴀᴄᴛ ᴛʜᴇ ʀᴇꜱᴘᴇᴄᴛɪᴠᴇ ᴄʜᴀɴɴᴇʟꜱ ꜰᴏʀ ʀᴇᴍᴏᴠᴀʟ. ᴛʜᴇ ʙᴏᴛ ᴅᴏᴇꜱ ɴᴏᴛ ᴏᴡɴ ᴀɴʏ ᴏꜰ ᴛʜᴇꜱᴇ ᴄᴏɴᴛᴇɴᴛꜱ, ɪᴛ ᴏɴʟʏ ɪɴᴅᴇxᴇs ᴛʜᴇ ꜰɪʟᴇꜱ ꜰʀᴏᴍ ᴛᴇʟᴇɢʀᴀᴍ. +ᴀʟʟ ᴛʜᴇ ꜰɪʟᴇꜱ ɪɴ ᴛʜɪꜱ ʙᴏᴛ ᴀʀᴇ ꜰʀᴇᴇʟʏ ᴀᴠᴀɪʟᴀʙʟᴇ ᴏɴ ᴛʜᴇ ɪɴᴛᴇʀɴᴇᴛ ᴏʀ ᴘᴏꜱᴛᴇᴅ ʙʏ ꜱᴏᴍᴇʙᴏᴅʏ ᴇʟꜱᴇ. ᴊᴜꜱᴛ ꜰᴏʀ ᴇᴀꜱʏ ꜱᴇᴀʀᴄʜɪɴɢ ᴛʜɪꜱ ʙᴏᴛ ɪꜱ ɪɴᴅᴇxɪɴɢ ꜰɪʟᴇꜱ ᴡʜɪᴄʜ ᴀʀᴇ ᴀʟʀᴇᴀᴅʏ ᴜᴘʟᴏᴀᴅᴇᴅ ᴏɴ ᴛᴇʟᴇɢʀᴀᴍ. ᴡᴇ ʀᴇꜱᴘᴇᴄᴛ ᴀʟʟ ᴛʜᴇ ᴄᴏᴘʏʀɪɢʜᴛ ʟᴀᴡꜱ ᴀɴᴅ ᴡᴏʀᴋꜱ ɪɴ ᴄᴏᴍᴘʟɪᴀɴᴄᴇ ᴡɪᴛʜ ᴅᴍᴄᴀ ᴀɴᴅ ᴇᴜᴄᴅ. ɪꜰ ᴀɴʏᴛʜɪɴɢ ɪꜱ ᴀɢᴀɪɴꜱᴛ ʟᴀᴡ ᴘʟᴇᴀꜱᴇ ᴄᴏɴᴛᴀᴄᴛ ᴍᴇ ꜱᴏ ᴛʜᴀᴛ ɪᴛ ᴄᴀɴ ʙᴇ ʀᴇᴍᴏᴠᴇᴅ ᴀꜱᴀᴘ. ɪᴛ ɪꜱ ꜰᴏʀʙɪᴅᴅᴇɴ ᴛᴏ ᴅᴏᴡɴʟᴏᴀᴅ, ꜱᴛʀᴇᴀᴍ, ʀᴇᴘʀᴏᴅᴜᴄᴇ, ꜱʜᴀʀᴇ ᴏʀ ᴄᴏɴꜱᴜᴍᴇ ᴄᴏɴᴛᴇɴᴛ ᴡɪᴛʜᴏᴜᴛ ᴇxᴘʟɪᴄɪᴛ ᴘᴇʀᴍɪꜱꜱɪᴏɴ ꜰʀᴏᴍ ᴛʜᴇ ᴄᴏɴᴛᴇɴᴛ ᴄʀᴇᴀᴛᴏʀ ᴏʀ ʟᴇɢᴀʟ ᴄᴏᴘʏʀɪɢʜᴛ ʜᴏʟᴅᴇʀ. ɪꜰ ʏᴏᴜ ʙᴇʟɪᴇᴠᴇ ᴛʜɪꜱ ʙᴏᴛ ɪꜱ ᴠɪᴏʟᴀᴛɪɴɢ ʏᴏᴜʀ ɪɴᴛᴇʟʟᴇᴄᴛᴜᴀʟ ᴘʀᴏᴘᴇʀᴛʏ, ᴄᴏɴᴛᴀᴄᴛ ᴛʜᴇ ʀᴇꜱᴘᴇᴄᴛɪᴠᴇ ᴄʜᴀɴɴᴇʟꜱ ꜰᴏʀ ʀᴇᴍᴏᴠᴀʟ. ᴛʜᴇ ʙᴏᴛ ᴅᴏᴇꜱ ɴᴏᴛ ᴏᴡɴ ᴀɴʏ ᴏꜰ ᴛʜᴇꜱᴇ ᴄᴏɴᴛᴇɴᴛꜱ, ɪᴛ ᴏɴʟʏ ɪɴᴅᴇxᴇꜱ ᴛʜᴇ ꜰɪʟᴇꜱ ꜰʀᴏᴍ ᴛᴇʟᴇɢʀᴀᴍ. """ DREAMXBOTZ_DONATION = DONATE_TXT = """👋 ʜᴇʏ {}, @@ -253,7 +256,10 @@ class script(object): ➤ 📷 Qʀ ᴄᴏᴅᴇ → ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ꜱᴄᴀɴ ➤ 💸 ᴜᴘɪ ɪᴅ → {} -‼ ᴍᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴅᴏɴᴀᴛɪɴɢ.""" +‼️ ᴍᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴅᴏɴᴀᴛɪɴɢ.""" + + + NORSLTS = """ #NoResults @@ -263,35 +269,33 @@ class script(object): Mᴇꜱꜱᴀɢᴇ : {}""" - CAPTION = """{file_name}\n\n⚜ Powered By : [ ᴅʀᴇᴀᴍxʙᴏᴛᴢ ]""" + CAPTION = """{file_name}\n\n⚜️ Powered By : [ ᴅʀᴇᴀᴍxʙᴏᴛᴢ ]""" - # === FINAL V3 - TITLE OUTSIDE QUOTE, DIVIDER LOGIC, RUNTIME FIX === + MOVIE_UPDATE_NOTIFY_TXT = """ 📥New {tag} Added -✨ ᴛɪᴛʟᴇ : {filename} {year} -⚬────────✧────────⚬ +
✨ ᴛɪᴛʟᴇ : {filename} {year} -
🎭 ɢᴇɴʀᴇs : {genres} -📺 ᴏᴛᴛ : {ott} -⏰ ʀᴜɴᴛɪᴍᴇ : {runtime} -🎞 ǫᴜᴀʟɪᴛʏ : {quality} -🎧 ᴀᴜᴅɪᴏ : {language} -🔥 ʀᴀᴛɪɴɢ : {rating}/10 +🎭 ɢᴇɴʀᴇs : {genres} +📺 ᴏᴛᴛ : {ott} +🎞️ ǫᴜᴀʟɪᴛʏ : {quality} +🎧 ᴀᴜᴅɪᴏ : {language} +🔥 ʀᴀᴛɪɴɢ : {rating} {episodes}
-⚬────────✧────────⚬ 🔍 Sᴇᴀʀᴄʜ → {search_link} """ + IMDB_TEMPLATE_TXT = """{title} ({year}) ʀᴀᴛɪɴɢ : {rating} ɢᴇɴʀᴇ : {genres} ᴀᴜᴅɪᴏ : {languages} -sʜᴏᴡɴ ɪɴ : {remaining_seconds} sᴇᴄ⚡ +sʜᴏᴡɴ ɪɴ : {remaining_seconds} sᴇᴄ⚡️ ʀᴇǫ ʙʏ : {message.from_user.mention}""" LOGO = r""" @@ -306,7 +310,12 @@ class script(object): 𝙱𝙾𝚃 𝚆𝙾𝚁𝙺𝙸𝙽𝙶 𝙿𝚁𝙾𝙿𝙴𝚁𝙻𝚈.... """ - PREMIUM_TEXT = """
🎖 Aᴠᴀɪʟᴀʙʟᴇ ᴘʟᴀɴs
+ + #PLANS + + + + PREMIUM_TEXT = """
🎖️ Aᴠᴀɪʟᴀʙʟᴇ ᴘʟᴀɴs
◉ 07 ᴅᴀʏꜱ - 10 ₹ / 10 ꜱᴛᴀʀ @@ -317,8 +326,8 @@ class script(object): •─────•─────────•─────• -‼ Mᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. -‼ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇꜱ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" +‼️ Mᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. +‼️ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇꜱ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" PREMIUM_STAR_TEXT = """
Pᴀʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅ: Tᴇʟᴇɢʀᴀᴍ ꜱᴛᴀʀꜱ ⭐
@@ -337,7 +346,8 @@ class script(object): 💢 ᴍᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. -‼ ᴀꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴘʟᴇᴀꜱᴇ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.
""" +‼️ ᴀꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴘʟᴇᴀꜱᴇ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" + PREMIUM_END_TEXT = """ʜᴇʏ {}, @@ -350,6 +360,7 @@ class script(object): Hᴀᴍᴀʀɪ ᴀɴʏᴀ ʏᴏᴊɴᴀᴏɴ ᴋɪ ᴊᴀᴀɴᴄʜ ᴋᴀʀɴᴇ ᴋᴇ ʟɪʏᴇ /plan ᴘᴀʀ ᴋʟɪᴄᴋ ᴋᴀʀᴇɪɴ।
""" + BPREMIUM_TXT = """
🎁 ᴘʀᴇᴍɪᴜᴍ ꜰᴇᴀᴛᴜʀᴇꜱ :
○ ɴᴏ ɴᴇᴇᴅ ᴛᴏ ᴠᴇʀɪꜰʏ @@ -367,11 +378,12 @@ class script(object): •─────•─────────•─────• ◉ ᴄʜᴇᴄᴋ ʏᴏᴜʀ ᴀᴄᴛɪᴠᴇ ᴘʟᴀɴ : /myplan -‼ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇꜱ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" +‼️ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇꜱ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" + PREPLANS_TXT = PREMIUM_TXT = """👋 ʜᴇʏ {}, -
🎖 ᴀᴠᴀɪʟᴀʙʟᴇ ᴘʟᴀɴꜱ
+
🎖️ ᴀᴠᴀɪʟᴀʙʟᴇ ᴘʟᴀɴꜱ
◉ 07 ᴅᴀʏꜱ - 10 ₹ ◉ 15 ᴅᴀʏꜱ - 20 ₹ @@ -381,25 +393,29 @@ class script(object): •─────•─────────•─────• -🏷 Pᴀʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅꜱ - Uᴘɪ +🏷️ Pᴀʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅꜱ - Uᴘɪ 💸 Uᴘɪ ɪᴅ → {} 📷 Qʀ ᴄᴏᴅᴇ → ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ꜱᴄᴀɴ 🧾 Pᴀʏ ᴀᴄᴄᴏʀᴅɪɴɢ ᴛᴏ ʏᴏᴜʀ ᴘʟᴀɴ ᴀɴᴅ ᴇɴᴊᴏʏ ᴘʀᴇᴍɪᴜᴍ! -‼ Mᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. -‼ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ᴀ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ, ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇ ᴛɪᴍᴇ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴛʜᴇ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ. +‼️ Mᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. +‼️ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ᴀ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ, ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇ ᴛɪᴍᴇ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴛʜᴇ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ. 💎 Cʜᴇᴄᴋ ʏᴏᴜʀ ᴘʟᴀɴ → /myplan
""" + + + VERIFICATION_TEXT = """👋 Hᴇʏ {}, -📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ. +📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. #Vᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 1/3 ✓ Iꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴅɪʀᴇᴄᴛ ꜰɪʟᴇs ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ᴛᴀᴋᴇ ᴘʀᴇᴍɪᴜᴍ sᴇʀᴠɪᴄᴇ (ɴᴏ ɴᴇᴇᴅ ᴛᴏ ᴠᴇʀɪꜰʏ).""" + VERIFY_COMPLETE_TEXT = """👋 Hᴇʏ {} ❤, @@ -409,7 +425,7 @@ class script(object): SECOND_VERIFICATION_TEXT = """👋 ʜᴇʏ {}, -📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ. +📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. #Vᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 2/3 ✓ @@ -423,7 +439,7 @@ class script(object): THIRDT_VERIFICATION_TEXT = """👋 ʜᴇʏ {}, -📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ. +📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. #Vᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 3/3 ✓ @@ -443,6 +459,7 @@ class script(object): #Verification_{}_Completed""" + ADMIN_CMD = """ʜᴇʏ 👋, 📚 ʜᴇʀᴇ ᴀʀᴇ ᴍʏ ᴄᴏᴍᴍᴀɴᴅꜱ ʟɪꜱᴛ ꜰᴏʀ ᴀʟʟ ʙᴏᴛ ᴀᴅᴍɪɴꜱ ⇊ @@ -461,7 +478,7 @@ class script(object): • /disable - ᴅɪꜱᴀʙʟᴇ ᴀ ᴄʜᴀᴛ. • /ban - ʙᴀɴ ᴀ ᴜꜱᴇʀ. • /unban - ᴜɴʙᴀɴ ᴀ ᴜꜱᴇʀ. -• /broadcast - ʙʀᴏᴀᴅᴄᴀsᴛ ᴀ ᴍᴇꜱꜱᴀɢᴇ ᴛᴏ ᴀʟʟ ᴜꜱᴇʀꜱ. +• /broadcast - ʙʀᴏᴀᴅᴄᴀꜱᴛ ᴀ ᴍᴇꜱꜱᴀɢᴇ ᴛᴏ ᴀʟʟ ᴜꜱᴇʀꜱ. • /grp_broadcast - ʙʀᴏᴀᴅᴄᴀsᴛ ᴀ ᴍᴇssᴀɢᴇ ᴛᴏ ᴀʟʟ ᴄᴏɴɴᴇᴄᴛᴇᴅ ɢʀᴏᴜᴘs. • /deletefiles - ᴅᴇʟᴇᴛᴇ CᴀᴍRɪᴘ ᴀɴᴅ PʀᴇDVD ғɪʟᴇs ғʀᴏᴍ ᴛʜᴇ ʙᴏᴛ's ᴅᴀᴛᴀʙᴀsᴇ. • /send - ꜱᴇɴᴅ ᴍᴇꜱꜱᴀɢᴇ ᴛᴏ ᴀ ᴘᴀʀᴛɪᴄᴜʟᴀʀ ᴜꜱᴇʀ. From 4cecc52ae5b3c574a47857cdd8fd3b5bd6f8a798 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Wed, 23 Sep 2026 20:00:11 +0530 Subject: [PATCH 70/77] Update utils.py --- utils.py | 253 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 179 insertions(+), 74 deletions(-) diff --git a/utils.py b/utils.py index f2a94a0a..57b0f92c 100644 --- a/utils.py +++ b/utils.py @@ -4,7 +4,7 @@ import random import string from info import ULTRA_FAST_MODE, MAX_LIST_ELM, BAD_WORDS, LONG_IMDB_DESCRIPTION, IS_VERIFY, MAX_B_TN, TUTORIAL, TUTORIAL_2, TUTORIAL_3, LOG_CHANNEL, TMDB_ON_SEARCH -from imdbkit import IMDBKit +from imdbkit import IMDBKit # pyrefly: ignore import asyncio from pyrogram.types import Message, InlineKeyboardButton from pyrogram.errors import InputUserDeactivated, UserNotParticipant, FloodWait, UserIsBlocked, PeerIdInvalid, ChatAdminRequired @@ -18,6 +18,7 @@ from shortzy import Shortzy from plugins.Dreamxfutures.Imdbposter import get_movie_detailsx + logger = logging.getLogger(__name__) def get_random_mix_id(): @@ -30,14 +31,12 @@ def get_random_mix_id(): imdb = IMDBKit() -# OMDB API KEY - from env, fallback to your key ab767d2b -OMDB_API_KEY = os.environ.get("OMDB_API_KEY", "ab767d2b") - BANNED = {} SMART_OPEN = '“' SMART_CLOSE = '”' START_CHAR = ('\'', '"', SMART_OPEN) + class temp(object): BANNED_USERS = [] BANNED_CHATS = [] @@ -58,26 +57,10 @@ class temp(object): TEMP_INVITE_LINKS = {} REQ_LINKS = {} -async def fetch_omdb_details(imdb_id): - """Fetch OMDB details for best result - IMDB + OMDB + TMDB combined""" - if not imdb_id or not OMDB_API_KEY: - return {} - try: - if not imdb_id.startswith("tt"): - imdb_id = f"tt{imdb_id}" - url = f"http://www.omdbapi.com/?i={imdb_id}&apikey={OMDB_API_KEY}" - async with aiohttp.ClientSession() as session: - async with session.get(url, timeout=10) as resp: - if resp.status == 200: - data = await resp.json() - if data.get("Response") == "True": - return data - except Exception as e: - logger.warning(f"OMDB fetch failed for {imdb_id}: {e}") - return {} async def is_req_subscribed(bot, user_id, rqfsub_channels): btn = [] + async def check_req_channel(ch_id): if await db.has_joined_channel(user_id, ch_id): return None @@ -90,31 +73,41 @@ async def check_req_channel(ch_id): pass except Exception as e: logger.error(f"Error checking membership in {ch_id}: {e}") + try: chat = await bot.get_chat(ch_id) if ch_id in temp.REQ_LINKS: invite_link = temp.REQ_LINKS[ch_id] else: - invite = await bot.create_chat_invite_link(ch_id, creates_join_request=True) + invite = await bot.create_chat_invite_link( + ch_id, + creates_join_request=True + ) invite_link = invite.invite_link temp.REQ_LINKS[ch_id] = invite_link - return [InlineKeyboardButton(f"⛔ Join {chat.title}", url=invite_link)] + + return [InlineKeyboardButton(f"⛔️ Join {chat.title}", url=invite_link)] except ChatAdminRequired: logger.warning(f"Bot not admin in {ch_id}") except Exception as e: logger.warning(f"Invite link error for {ch_id}: {e}") return None + tasks = [check_req_channel(ch_id) for ch_id in rqfsub_channels] results = await asyncio.gather(*tasks) + for res in results: if res: btn.append(res) + return btn async def is_subscribed(bot, user_id, fsub_channels): btn = [] + async def check_channel(channel_id): try: + # No need to get chat object separately await bot.get_chat_member(channel_id, user_id) except UserNotParticipant: try: @@ -126,11 +119,14 @@ async def check_channel(channel_id): except Exception as e: logger.exception(f"is_subscribed error for {channel_id}: {e}") return None + tasks = [check_channel(channel_id) for channel_id in fsub_channels] results = await asyncio.gather(*tasks) + for button in results: if button: btn.append([button]) + return btn async def is_check_admin(bot, chat_id, user_id): @@ -164,6 +160,7 @@ async def users_broadcast(user_id, message, is_pin): logger.error(f"[BROADCAST FAIL] user={user_id} | {type(e).__name__}: {e}") return False, "Error" + async def groups_broadcast(chat_id, message, is_pin): try: m = await message.copy(chat_id=chat_id) @@ -192,6 +189,7 @@ async def junk_group(chat_id, message): await db.delete_chat(int(chat_id)) logger.info(f"{chat_id} - PeerIdInvalid") return False, "deleted", f'{e}\n\n' + async def clear_junk(user_id, message): try: @@ -223,19 +221,29 @@ async def get_status(bot_id): return False async def add_name_to_db(filename): + """ + Helper function to add a filename to the database. + """ + return await db.add_name(filename) + def listx_to_str(k): if k is None or k == "": return "N/A" + + # Handle non-iterable types first if not hasattr(k, '__iter__') or isinstance(k, (str, int, float)): return str(k) + result = [] for elem in k: if elem and str(elem).strip(): result.append(str(elem).strip()) + if MAX_LIST_ELM and len(result) > MAX_LIST_ELM: result = result[:int(MAX_LIST_ELM)] + return ', '.join(result) if result else "N/A" async def get_poster(query, bulk=False, id=False, file=None): @@ -243,6 +251,7 @@ async def get_poster(query, bulk=False, id=False, file=None): query = (query.strip()).lower() title = query year_val = None + year_list = re.findall(r'[1-2]\d{3}$', query, re.IGNORECASE) if year_list: year_val = year_list[0] @@ -251,20 +260,26 @@ async def get_poster(query, bulk=False, id=False, file=None): year_list = re.findall(r'[1-2]\d{3}', file, re.IGNORECASE) if year_list: year_val = year_list[0] + search_result = await asyncio.to_thread(imdb.search_movie, title.lower()) if not search_result or not search_result.titles: return None + movie_list = search_result.titles[:MAX_LIST_ELM] + if year_val: filtered = [m for m in movie_list if m.year and str(m.year) == str(year_val)] if not filtered: filtered = movie_list else: filtered = movie_list + kind_filter = ['movie', 'tv series', 'tvSeries', 'tvMiniSeries', 'tvMovie'] filtered_kind = [m for m in filtered if m.kind and m.kind in kind_filter] + if not filtered_kind: filtered_kind = filtered + if bulk: return filtered_kind[:MAX_LIST_ELM] if not filtered_kind: @@ -291,13 +306,6 @@ async def get_poster(query, bulk=False, id=False, file=None): imdb_id = movie.imdb_id if not imdb_id.startswith("tt"): imdb_id = f"tt{imdb_id}" - - # Fetch OMDB for better rating/runtime - omdb_data = await fetch_omdb_details(imdb_id) - rating = omdb_data.get("imdbRating") if omdb_data.get("imdbRating") and omdb_data.get("imdbRating") != "N/A" else str(movie.rating) - runtime = omdb_data.get("Runtime") if omdb_data.get("Runtime") and omdb_data.get("Runtime") != "N/A" else listx_to_str(movie.duration) - genres = omdb_data.get("Genre") if omdb_data.get("Genre") and omdb_data.get("Genre") != "N/A" else listx_to_str(movie.genres) - return { 'title': movie.title, 'votes': movie.votes, @@ -313,7 +321,7 @@ async def get_poster(query, bulk=False, id=False, file=None): 'kind': movie.kind, "imdb_id": imdb_id, "cast": listx_to_str(movie.stars), - "runtime": runtime, + "runtime": listx_to_str(movie.duration), "countries": listx_to_str(movie.countries), "certificates": listx_to_str(movie.certificates), "languages": listx_to_str(movie.languages), @@ -326,20 +334,115 @@ async def get_poster(query, bulk=False, id=False, file=None): "distributors": listx_to_str([c.name for c in movie.distributors]), 'release_date': date, 'year': movie.year, - 'genres': genres, + 'genres': listx_to_str(movie.genres), 'poster': movie.cover_url, 'plot': plot, - 'rating': rating, + 'rating': str(movie.rating), "url": movie.url or f"https://www.imdb.com/title/{imdb_id}" } +#Remove Nahi Kiya Hu.....Agar Tujha Remove Karna Hai To Kar Dena +async def old_get_poster(query, bulk=False, id=False, file=None): + if not id: + query = (query.strip()).lower() + title = query + year = re.findall(r'[1-2]\d{3}$', query, re.IGNORECASE) + imdb + if year: + year = list_to_str(year[:1]) + title = (query.replace(year, "")).strip() + elif file is not None: + year = re.findall(r'[1-2]\d{3}', file, re.IGNORECASE) + if year: + year = list_to_str(year[:1]) + else: + year = None + movieid = imdb.search_movie(title.lower(), results=10) + if not movieid: + return None + if year: + filtered=list(filter(lambda k: str(k.get('year')) == str(year), movieid)) + if not filtered: + filtered = movieid + else: + filtered = movieid + movieid=list(filter(lambda k: k.get('kind') in ['movie', 'tv series'], filtered)) + if not movieid: + movieid = filtered + if bulk: + return movieid + movieid = movieid[0].movieID + else: + movieid = query + movie = imdb.get_movie(movieid) + imdb.update(movie, info=['main', 'vote details']) + if movie.get("original air date"): + date = movie["original air date"] + elif movie.get("year"): + date = movie.get("year") + else: + date = "N/A" + plot = "" + if not LONG_IMDB_DESCRIPTION: + plot = movie.get('plot') + if plot and len(plot) > 0: + plot = plot[0] + else: + plot = movie.get('plot outline') + if plot and len(plot) > 800: + plot = plot[0:800] + "..." + STANDARD_GENRES = { + 'Action', 'Adventure', 'Animation', 'Biography', 'Comedy', 'Crime', 'Documentary', + 'Drama', 'Family', 'Fantasy', 'Film-Noir', 'History', 'Horror', 'Music', + 'Musical', 'Mystery', 'Romance', 'Sci-Fi', 'Sport', 'Thriller', 'War', 'Western' + } + raw_genres = movie.get("genres", "N/A") + if isinstance(raw_genres, str): + genre_list = [g.strip() for g in raw_genres.split(",")] + genres = ", ".join(g for g in genre_list if g in STANDARD_GENRES) or "N/A" + else: + genres = ", ".join(g for g in raw_genres if g in STANDARD_GENRES) or "N/A" + + return { + 'title': movie.get('title'), + 'votes': movie.get('votes'), + "aka": list_to_str(movie.get("akas")), + "seasons": movie.get("number of seasons"), + "box_office": movie.get('box office'), + 'localized_title': movie.get('localized title'), + 'kind': movie.get("kind"), + "imdb_id": f"tt{movie.get('imdbID')}", + "cast": list_to_str(movie.get("cast")), + "runtime": list_to_str(movie.get("runtimes")), + "countries": list_to_str(movie.get("countries")), + "certificates": list_to_str(movie.get("certificates")), + "languages": list_to_str(movie.get("languages")), + "director": list_to_str(movie.get("director")), + "writer":list_to_str(movie.get("writer")), + "producer":list_to_str(movie.get("producer")), + "composer":list_to_str(movie.get("composer")) , + "cinematographer":list_to_str(movie.get("cinematographer")), + "music_team": list_to_str(movie.get("music department")), + "distributors": list_to_str(movie.get("distributors")), + 'release_date': date, + 'year': movie.get('year'), + 'genres': genres, + 'poster': movie.get('full-size cover url'), + 'plot': plot, + 'rating': str(movie.get("rating")), + 'url':f'https://www.imdb.com/title/tt{movieid}' + } + async def get_posterx(query, bulk=False, id=False, file=None): """ - Fetches movie details from TMDB + OMDB + IMDB combined for best result + Fetches movie details from TMDB using the get_movie_detailsx helper + and formats the output to be compatible with the original get_poster function. """ if not id: + # The get_movie_detailsx function handles searching by query string. details = await get_movie_detailsx(query, file=file) else: + # Assumes the 'id' is a TMDB ID or IMDb ID that get_movie_detailsx can handle. details = await get_movie_detailsx(query, id=True) if not details or details.get("error"): @@ -355,41 +458,24 @@ async def get_posterx(query, bulk=False, id=False, file=None): if plot and len(plot) > 800: plot = plot[0:800] + "..." + # --- Mapping TMDB keys to the original IMDb key format --- + def list_to_str(val): if isinstance(val, list): return ", ".join(str(x) for x in val if x) return str(val) if val else "" - imdb_id = details.get('imdb_id') - omdb_data = {} - if imdb_id: - omdb_data = await fetch_omdb_details(imdb_id) - - # Best rating: OMDB > TMDB > N/A - rating = omdb_data.get("imdbRating") if omdb_data.get("imdbRating") and omdb_data.get("imdbRating") != "N/A" else details.get("rating", "N/A") - runtime = omdb_data.get("Runtime") if omdb_data.get("Runtime") and omdb_data.get("Runtime") != "N/A" else list_to_str(details.get("runtime")) - genres = omdb_data.get("Genre") if omdb_data.get("Genre") and omdb_data.get("Genre") != "N/A" else list_to_str(details.get("genres")) - # Runtime convert if needed - keep as "1h 51m" format - if runtime and "min" in str(runtime).lower() and "h" not in str(runtime).lower(): - try: - mins = int(re.search(r'\d+', str(runtime)).group()) - h = mins // 60 - m = mins % 60 - runtime = f"{h}h {m}m" if h else f"{m}m" - except: - pass - return { 'title': details.get('title'), 'votes': details.get('votes'), - "aka": None, + "aka": None, # Not typically provided by TMDB in this format "seasons": details.get('seasons'), "box_office": details.get('box_office'), 'localized_title': details.get('localized_title'), 'kind': 'movie' if 'movie' in details.get('tmdb_url', '') else 'tv series', - "imdb_id": imdb_id, + "imdb_id": details.get('imdb_id'), "cast": list_to_str(details.get("cast")), - "runtime": runtime or list_to_str(details.get("runtime")), + "runtime": list_to_str(details.get("runtime")), "countries": list_to_str(details.get("countries")), "certificates": list_to_str(details.get("certificates")), "languages": list_to_str(details.get("languages")), @@ -398,17 +484,15 @@ def list_to_str(val): "producer": list_to_str(details.get("producer")), "composer": list_to_str(details.get("composer")), "cinematographer": list_to_str(details.get("cinematographer")), - "music_team": None, + "music_team": None, # Not provided by the TMDB API wrapper "distributors": list_to_str(details.get("distributors")), 'release_date': details.get('release_date'), 'year': details.get('year'), - 'genres': genres, + 'genres': list_to_str(details.get("genres")), 'poster': details.get('poster_url'), 'backdrop' : details.get('backdrop_url'), - 'poster_url': details.get('poster_url'), - 'backdrop_url': details.get('backdrop_url'), 'plot': plot, - 'rating': str(rating) if rating else "N/A", + 'rating': str(details.get("rating", "N/A")), 'url': details.get('tmdb_url') } @@ -419,10 +503,12 @@ async def search_gagala(text): } text = text.replace(" ", "+") url = f"https://www.google.com/search?q={text}" + async with aiohttp.ClientSession() as session: async with session.get(url, headers=usr_agent, timeout=30) as response: response.raise_for_status() html = await response.text() + soup = await asyncio.to_thread(BeautifulSoup, html, 'html.parser') titles = soup.find_all('h3') return [title.get_text() for title in titles if title.get_text().strip()] @@ -471,6 +557,7 @@ async def delete_group_setting(group_id, key): def clean_filename(file_name): prefixes = ('[', '@', 'www.') unwanted = {word.lower() for word in BAD_WORDS} + file_name = ' '.join( word for word in file_name.split() if not (word.startswith(prefixes) or word.lower() in unwanted) @@ -500,27 +587,27 @@ def extract_request_content(message_text): return message_text.strip() def generate_settings_text(settings, title, reset_done=False): - note = "\n📌 ɴᴏᴛᴇ :- ʀᴇꜱᴇᴛ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ✅" if reset_done else "" - return f"""⚙ ʏᴏᴜʀ sᴇᴛᴛɪɴɢs ꜰᴏʀ - {title} + note = "\n📌 ɴᴏᴛᴇ :- ʀᴇꜱᴇᴛ ꜱᴜᴄᴄᴇꜱꜱғᴜʟʟʏ ✅" if reset_done else "" + return f"""⚙️ ʏᴏᴜʀ sᴇᴛᴛɪɴɢs ꜰᴏʀ - {title} -✅ 1sᴛ ᴠᴇʀɪꜰʏ sʜᴏʀᴛɴᴇʀ +✅️ 1sᴛ ᴠᴇʀɪꜰʏ sʜᴏʀᴛɴᴇʀ ɴᴀᴍᴇ - {settings.get("shortner", "N/A")} ᴀᴘɪ - {settings.get("api", "N/A")} -✅ 2ɴᴅ ᴠᴇʀɪꜰʏ sʜᴏʀᴛɴᴇʀ +✅️ 2ɴᴅ ᴠᴇʀɪꜰʏ sʜᴏʀᴛɴᴇʀ ɴᴀᴍᴇ - {settings.get("shortner_two", "N/A")} ᴀᴘɪ - {settings.get("api_two", "N/A")} -✅ 𝟹ʀᴅ ᴠᴇʀɪꜰʏ sʜᴏʀᴛɴᴇʀ +✅️ 𝟹ʀᴅ ᴠᴇʀɪꜰʏ sʜᴏʀᴛɴᴇʀ ɴᴀᴍᴇ - {settings.get("shortner_three", "N/A")} ᴀᴘɪ - {settings.get("api_three", "N/A")} ⏰ 2ɴᴅ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ ᴛɪᴍᴇ - {settings.get("verify_time", "N/A")} ⏰ 𝟹ʀᴅ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ ᴛɪᴍᴇ - {settings.get("third_verify_time", "N/A")} -1⃣ ᴛᴜᴛᴏʀɪᴀʟ ʟɪɴᴋ 1 - {settings.get("tutorial", TUTORIAL)} -2⃣ ᴛᴜᴛᴏʀɪᴀʟ ʟɪɴᴋ 2 - {settings.get("tutorial_2", TUTORIAL_2)} -3⃣ ᴛᴜᴛᴏʀɪᴀʟ ʟɪɴᴋ 3 - {settings.get("tutorial_3", TUTORIAL_3)} +1️⃣ ᴛᴜᴛᴏʀɪᴀʟ ʟɪɴᴋ 1 - {settings.get("tutorial", TUTORIAL)} +2️⃣ ᴛᴜᴛᴏʀɪᴀʟ ʟɪɴᴋ 2 - {settings.get("tutorial_2", TUTORIAL_2)} +3️⃣ ᴛᴜᴛᴏʀɪᴀʟ ʟɪɴᴋ 3 - {settings.get("tutorial_3", TUTORIAL_3)} 📝 ʟᴏɢ ᴄʜᴀɴɴᴇʟ ɪᴅ - {settings.get("log", "N/A")} 🚫 ꜰꜱᴜʙ ᴄʜᴀɴɴᴇʟ ɪᴅ - {settings.get("fsub", "N/A")} @@ -616,16 +703,19 @@ def extract_user(message: Message) -> Union[int, str]: if message.reply_to_message: user_id = message.reply_to_message.from_user.id user_first_name = message.reply_to_message.from_user.first_name + elif len(message.command) > 1: if ( len(message.entities) > 1 and message.entities[1].type == enums.MessageEntityType.TEXT_MENTION ): + required_entity = message.entities[1] user_id = required_entity.user.id user_first_name = required_entity.user.first_name else: user_id = message.command[1] + # don't want to make a request -_- user_first_name = user_id try: user_id = int(user_id) @@ -665,6 +755,7 @@ def last_online(from_user): time += from_user.last_online_date.strftime("%a, %d %b %Y, %H:%M:%S") return time + def split_quotes(text: str) -> List: if not any(text.startswith(char) for char in START_CHAR): return text.split(None, 1) @@ -723,11 +814,13 @@ def gfilterparser(text, keyword): text=match.group(2), url=match.group(4).replace(" ", "") )]) + else: note_data += text[prev:to_check] prev = match.start(1) - 1 else: note_data += text[prev:] + try: return note_data, buttons, alerts except Exception: @@ -773,11 +866,13 @@ def parser(text, keyword): text=match.group(2), url=match.group(4).replace(" ", "") )]) + else: note_data += text[prev:to_check] prev = match.start(1) - 1 else: note_data += text[prev:] + try: return note_data, buttons, alerts except Exception: @@ -798,10 +893,14 @@ def remove_escapes(text: str) -> str: async def log_error(client, error_message): try: - await client.send_message(chat_id=LOG_CHANNEL, text=f"⚠ Error Log:\n{error_message}") + await client.send_message( + chat_id=LOG_CHANNEL, + text=f"⚠️ Error Log:\n{error_message}" + ) except Exception as e: logger.error("Failed to log error: %s", e) + def get_time(seconds): periods = [(' ᴅᴀʏs', 86400), (' ʜᴏᴜʀ', 3600), (' ᴍɪɴᴜᴛᴇ', 60), (' sᴇᴄᴏɴᴅ', 1)] result = '' @@ -838,6 +937,8 @@ def generate_season_variations(search_raw: str, season_number: int): f"{search_raw} season {season_number:02}", ] + + async def get_seconds(time_string): def extract_value_and_unit(ts): value = "" @@ -865,6 +966,7 @@ def extract_value_and_unit(ts): return value * 86400 * 365 else: return 0 + def clean_search_text(search_raw: str) -> str: search_lower = search_raw.lower() @@ -945,6 +1047,7 @@ async def get_cap(settings, remaining_seconds, files, query, total_results, sear url=imdb['url'], **locals() ) + for idx, file in enumerate(files, start=offset+1): cap += ( f"{idx}. " @@ -960,7 +1063,7 @@ async def get_cap(settings, remaining_seconds, files, query, total_results, sear f"🏷 ᴛɪᴛʟᴇ : {search}\n" f"⏰ ʀᴇsᴜʟᴛ ɪɴ : {remaining_seconds} Sᴇᴄᴏɴᴅs\n\n" f"📝 ʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {query.from_user.mention}\n" - f"⚜ ᴘᴏᴡᴇʀᴇᴅ ʙʏ :⚡ {query.message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'}\n" + f"⚜️ ᴘᴏᴡᴇʀᴇᴅ ʙʏ :⚡ {query.message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'}\n" ) else: cap = ( @@ -968,7 +1071,7 @@ async def get_cap(settings, remaining_seconds, files, query, total_results, sear f"🧱 ᴛᴏᴛᴀʟ ꜰɪʟᴇꜱ : {total_results}\n" f"⏰ ʀᴇsᴜʟᴛ ɪɴ : {remaining_seconds} Sᴇᴄᴏɴᴅs\n\n" f"📝 ʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {query.from_user.mention}\n" - f"⚜ ᴘᴏᴡᴇʀᴇᴅ ʙʏ :⚡ {query.message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'}\n" + f"⚜️ ᴘᴏᴡᴇʀᴇᴅ ʙʏ :⚡ {query.message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'}\n" ) cap += "\n\nYour Requested Files Are Here \n\n" for idx, file in enumerate(files, start=offset + 1): @@ -980,12 +1083,13 @@ async def get_cap(settings, remaining_seconds, files, query, total_results, sear f"{clean_filename(file.file_name)}\n\n" f"" ) + else: if ULTRA_FAST_MODE: cap = ( f"🏷 ᴛɪᴛʟᴇ : {search}\n" f"⏰ ʀᴇsᴜʟᴛ ɪɴ : {remaining_seconds} Sᴇᴄᴏɴᴅs\n\n" - f"⚜ ᴘᴏᴡᴇʀᴇᴅ ʙʏ : ⚡ {query.message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'}\n" + f"⚜️ ᴘᴏᴡᴇʀᴇᴅ ʙʏ : ⚡ {query.message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'}\n" ) else: cap = ( @@ -993,8 +1097,9 @@ async def get_cap(settings, remaining_seconds, files, query, total_results, sear f"🧱 ᴛᴏᴛᴀʟ ꜰɪʟᴇꜱ : {total_results}\n" f"⏰ ʀᴇsᴜʟᴛ ɪɴ : {remaining_seconds} Sᴇᴄᴏɴᴅs\n\n" f"📝 ʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {query.from_user.mention}\n" - f"⚜ ᴘᴏᴡᴇʀᴇᴅ ʙʏ : ⚡ {query.message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'}\n" + f"⚜️ ᴘᴏᴡᴇʀᴇᴅ ʙʏ : ⚡ {query.message.chat.title or temp.B_LINK or 'ᴅʀᴇᴀᴍxʙᴏᴛᴢ'}\n" ) + cap += "\n\nYour Requested Files Are Here\n\n" for idx, file in enumerate(files, start=offset + 1): cap += ( From 48f00eebb1f3f3aa934f7173aceb3de3ad8567c5 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Thu, 24 Sep 2026 18:53:25 +0530 Subject: [PATCH 71/77] Update channel.py --- plugins/channel.py | 367 ++++++++++++++++++++++++++++++--------------- 1 file changed, 243 insertions(+), 124 deletions(-) diff --git a/plugins/channel.py b/plugins/channel.py index d2fca5ae..aa736b85 100644 --- a/plugins/channel.py +++ b/plugins/channel.py @@ -1,9 +1,11 @@ import re import logging import asyncio +import aiohttp from datetime import datetime from collections import defaultdict -from plugins.Dreamxfutures.Imdbposter import get_movie_detailsx, fetch_image, get_movie_details +from bs4 import BeautifulSoup +from plugins.Dreamxfutures.Imdbposter import get_movie_detailsx, fetch_image, get_movie_details, get_blogger_poster_url, get_posterflix_poster, get_hdhub4u_data from database.users_chats_db import db from pyrogram import Client, filters, enums from info import CHANNELS, MOVIE_UPDATE_CHANNEL, LINK_PREVIEW, ABOVE_PREVIEW, BAD_WORDS, LANDSCAPE_POSTER, TMDB_POSTER @@ -17,8 +19,8 @@ logger = logging.getLogger(__name__) -# Precomputed sets for faster lookups -IGNORE_WORDS = { +# === ORIGINAL IGNORE WORDS (kept exactly) === +IGNORE_WORDS_ORIG = { "rarbg", "dub", "sub", "sample", "mkv", "aac", "combined", "action", "adventure", "animation", "biography", "comedy", "crime", "documentary", "drama", "fantasy", "film-noir", "history", @@ -35,7 +37,25 @@ "apple", "hoichoi", "sunnxt", "viki" }|BAD_WORDS -# Constants +# === EXTRA IGNORE WORDS FROM RPEDITZ (added, no font change) === +EXTRA_IGNORE = { + "x264", "x265", "h264", "h265", "10bit", "8bit", "10-bit", "8-bit", + "hdhub4u", "hdhub", "hub4u", "hdhub4", "4uhd", "hdhubforu", "hdhubforu", + "esub", "msub", "esubs", "msubs", "subs", "sub", "aac", "ac3", "dts", "mp3", + "remux", "proper", "repack", "extended", "unrated", "directors", "cut", + "brrip", "bdrip", "webrip", "web-dl", "webdl", "hdrip", "hdcam", "hdtc", "camrip", + "cam", "hdts", "hq", "hq-hdrip", "hq-hdtc", "hq-cam", "hq-ts", "hq-predvd", + "dual", "multi", "audio", "v1", "v2", "v3", "v4", "v5", "version", "ver", "cleaned", "clean", + "atv", "atvp", "appletv", "cr", "crunchyroll", "hulu", "disney", "dnp", "lionsgate", "peacock", "max", "alt", "altt", + "shemaroo", "chaupal", "stage", "planetmarathi", "manorama", "tubi", + "5.1", "7.1", "2.0", "dd5.1", "ddp5.1", "dd", "ddp", "rs", "m", "ms", "mp4", "avi" +} + +IGNORE_WORDS = IGNORE_WORDS_ORIG | EXTRA_IGNORE +IGNORE_WORDS_LOWER = {w.lower() for w in IGNORE_WORDS} + +DEFAULT_HDHUB_DOMAIN = "https://new6.hdhub4u.cl" + CAPTION_LANGUAGES = { "hin": "Hindi", "hindi": "Hindi", "tam": "Tamil", "tamil": "Tamil", @@ -68,13 +88,12 @@ 'Musical', 'Mystery', 'Romance', 'Sci-Fi', 'Sport', 'Thriller', 'War', 'Western' } -# Precompiled regex patterns CLEAN_PATTERN = re.compile(r'@[^ \n\r\t\.,:;!?()\[\]{}<>\\/"\'=_%]+|\bwww\.[^\s\]\)]+|\([\@^]+\)|\[[\@^]+\]') NORMALIZE_PATTERN = re.compile(r"[._]+|[()\[\]{}:;'–!,.?_]") QUALITY_PATTERN = re.compile( r"\b(?:HDCam|HDTC|CamRip|TS|TC|TeleSync|DVDScr|DVDRip|PreDVD|" r"WEBRip|WEB-DL|TVRip|HDTV|WEB DL|WebDl|BluRay|BRRip|BDRip|" - r"360p|480p|720p|1080p|2160p|4K|1440p|540p|240p|140p|HEVC|HDRip)\b", + r"360p|480p|720p|1080p|2160p|4K|1440p|540p|240p|140p|HEVC|HDRip|x264|x265|h264|h265|10bit|8bit|10-bit|BluRay|Bluray|HEVC)\b", re.IGNORECASE ) YEAR_PATTERN = re.compile(r"(? str: @@ -96,14 +116,46 @@ def normalize(s: str) -> str: s = NORMALIZE_PATTERN.sub(" ", s) return re.sub(r"\s+", " ", s).strip() -IGNORE_WORDS_LOWER = {w.lower() for w in IGNORE_WORDS} - def remove_ignored_words(text: str) -> str: return " ".join(word for word in text.split() if word.lower() not in IGNORE_WORDS_LOWER) +def is_good_title_match(query: str, found_title: str) -> bool: + if not query or not found_title: + return False + q_raw = YEAR_PATTERN.sub('', query).strip() + f_raw = YEAR_PATTERN.sub('', found_title).strip() + def clean_words(s: str): + s = re.sub(r'\(?\b(?:full\s*movie|full\s*series|full\s*film|hd|rip|dubbed)\b\)?', '', s, flags=re.IGNORECASE) + s = re.sub(r'^(the|a|an)\s+', '', s, flags=re.IGNORECASE) + s = re.sub(r"['’]", "", s) + s = normalize(s).lower() + return [w for w in s.split() if w] + q_words = clean_words(q_raw) + f_words = clean_words(f_raw) + if not q_words or not f_words: + return False + if q_words == f_words: + return True + if all(qw in f_words for qw in q_words): + return True + return False + def get_qualities(text: str) -> str: - qualities = QUALITY_PATTERN.findall(text) - return ", ".join(qualities) if qualities else "N/A" + # Enhanced: keep original but uppercase and include x264/x265 + if not text: + return "N/A" + quals = QUALITY_PATTERN.findall(text) + extra = re.findall(r'\b(?:x264|x265|hevc|10bit|bluray|blu-ray)\b', text, re.IGNORECASE) + all_q = quals + extra + # Uppercase and dedup + seen = set() + result = [] + for q in all_q: + q_up = q.upper() + if q_up.lower() not in seen: + seen.add(q_up.lower()) + result.append(q_up) + return ", ".join(result) if result else "N/A" def extract_ott_platform(text: str) -> str: text = text.lower() @@ -121,19 +173,24 @@ def extract_season_episode(filename: str) -> Tuple[Optional[int], Optional[str]] else: ep = m.group(2) return season, ep + if m := LOOSE_SEASON_EP.search(filename): + s, e = int(m.group(1)), int(m.group(2)) + if 1 <= s <= 30 and 1 <= e <= 100: + return s, str(e) return None, None def schedule_update(bot, base_name, delay=5): if handle := pending_updates.get(base_name): if not handle.cancelled(): handle.cancel() - loop = asyncio.get_event_loop() pending_updates[base_name] = loop.call_later( delay, lambda: asyncio.create_task(update_movie_message(bot, base_name)) ) + def extract_media_info(filename: str, caption: str): + filename_orig = filename filename = normalize(clean_mentions_links(filename).title()) caption_clean = clean_mentions_links(caption).lower() if caption else "" unified = f"{caption_clean} {filename.lower()}".strip() @@ -147,21 +204,22 @@ def extract_media_info(filename: str, caption: str): lang_keys = {k for k in CAPTION_LANGUAGES if k in caption_clean or k in filename.lower()} language = ", ".join(sorted({CAPTION_LANGUAGES[k] for k in lang_keys})) if lang_keys else "N/A" - season, episode = extract_season_episode(filename) + season, episode = extract_season_episode(filename_orig) if season is not None: tag = "#SERIES" - if m := (RANGE_REGEX.search(filename) or SINGLE_REGEX.search(filename) or NAMED_REGEX.search(filename) or EP_ONLY_RANGE.search(filename)): + if m := (RANGE_REGEX.search(filename) or SINGLE_REGEX.search(filename) or NAMED_REGEX.search(filename) or EP_ONLY_RANGE.search(filename) or LOOSE_SEASON_EP.search(filename)): match_str = m.group(0) start_idx = filename.lower().find(match_str.lower()) end_idx = start_idx + len(match_str) - processed_raw = filename[:end_idx] - base_raw = filename[:start_idx] - if year_match := YEAR_PATTERN.search(filename.lower()[end_idx:]): - y = year_match.group(0) - yi = filename.lower().find(y, end_idx) - if yi != -1: - processed_raw = filename[:yi+4] - base_raw += f" {y}" + if start_idx != -1: + processed_raw = filename[:end_idx] + base_raw = filename[:start_idx] + if year_match := YEAR_PATTERN.search(filename.lower()[end_idx:]): + y = year_match.group(0) + yi = filename.lower().find(y, end_idx) + if yi != -1: + processed_raw = filename[:yi+4] + base_raw += f" {y}" else: if year_match := YEAR_PATTERN.search(unified): year = year_match.group(0) @@ -177,68 +235,63 @@ def extract_media_info(filename: str, caption: str): processed_raw = filename[:qual_idx] base_raw = processed_raw - base_name = normalize(remove_ignored_words(normalize(base_raw))) - if year and year not in base_name: - base_name += f" {year}" - - if base_name.endswith(")"): - base_name = re.sub(r"\s+\(\d{4}\)$", "", base_name) - if year: - base_name += f" {year}" + # Enhanced cleaning for HdHub4U type files + base_raw = re.sub(r'\b(?:HdHub4U|Hub4U|Hdhub|hdhub4u|x264-hdhub4u|x265-hdhub4u|HdHubForU|Rs|M|Ms)\b', ' ', base_raw, flags=re.IGNORECASE) + base_raw = re.sub(r'\b[A-Z0-9]+-HdHub4U\b', ' ', base_raw, flags=re.IGNORECASE) + base_raw = re.sub(r'\b\d+Bit\b', ' ', base_raw, flags=re.IGNORECASE) + base_raw = re.sub(r'\bX\d{3,4}\b', ' ', base_raw, flags=re.IGNORECASE) - # ------------------------- - # NEW: strip season/episode tokens from final base_name - # ------------------------- + base_name = normalize(remove_ignored_words(normalize(base_raw))) + + # Strip season/episode tokens from final base_name def _strip_season_episode_tokens(name: str) -> str: - """ - Remove common season/episode markers from a title while preserving a trailing year. - Examples removed: S01, s01e02, 1x02, season 1, ep 02, episode 2, part 1 - """ if not name: return name - - # Preserve trailing year (e.g. "Title (2020)" or "Title 2020") year_match = re.search(r'\(?\b(19|20)\d{2}\b\)?\s*$', name) year_part = "" if year_match: year_part = year_match.group(0) name = name[:year_match.start()].strip() - - # Common patterns to remove patterns = [ - r'\bS\d{1,2}E\d{1,2}\b', # S01E02 - r'\bS\d{1,2}\b', # S01 - r'\bE\d{1,2}\b', # E02 - r'\b\d{1,2}x\d{1,2}\b', # 1x02 - r'\bSeason\s*\d{1,2}\b', # Season 1 - r'\bEp(?:isode)?\.?\s*\d{1,3}\b', # Ep02, Episode 2 + r'\bS\d{1,2}E\d{1,2}\b', + r'\bS\d{1,2}\b', + r'\bE\d{1,2}\b', + r'\b\d{1,2}x\d{1,2}\b', + r'\bSeason\s*\d{1,2}\b', + r'\bEp(?:isode)?\.?\s*\d{1,3}\b', r'\bEpisode\s*\d{1,3}\b', r'\bPart\s*\d{1,2}\b' ] - for p in patterns: name = re.sub(p, ' ', name, flags=re.IGNORECASE) - - # Remove leftover separators and extra whitespace - name = re.sub(r'[_\.\-]+', ' ', name) # underscores/dots/hyphens + name = re.sub(r'[_\.\-]+', ' ', name) name = re.sub(r'\s+', ' ', name).strip() - - # Reattach year in canonical form if we removed it earlier if year_part: y = re.search(r'(19|20)\d{2}', year_part) if y: name = f"{name} {y.group(0)}" - return name.strip() base_name = _strip_season_episode_tokens(base_name) - # If stripping accidentally removed everything, fall back to a safer value if not base_name: base_name = normalize(remove_ignored_words(normalize(processed_raw))) or filename + # Grouping ID: same movie different quality = same ID, different episode = different ID + grouping_id = base_name + if season: + if episode and "-" not in str(episode): + try: + ep_num = int(episode) + grouping_id = f"{base_name} S{season:02d}E{ep_num:02d}" + except: + grouping_id = f"{base_name} S{season:02d}E{episode}" + else: + grouping_id = f"{base_name} S{season:02d}" + return { "processed": normalize(processed_raw), "base_name": base_name, + "grouping_id": grouping_id, "tag": tag, "season": season, "episode": episode, @@ -251,26 +304,20 @@ def _strip_season_episode_tokens(name: str) -> str: @Client.on_message(filters.chat(CHANNELS) & (filters.document | filters.video | filters.audio)) async def media_handler(bot, message): success = False + file_name = "" try: media = message.document or message.video or message.audio if not media: return - file_id = media.file_id file_name = getattr(media, "file_name", "") - file_size = getattr(media, "file_size", 0) - - logger.info(f"File from {message.chat.id}: {file_name}") - media.file_type = next((ft for ft in ("document", "video", "audio") if getattr(message, ft, None)), None) media.caption = message.caption or "" - lock = locks[file_id] async with lock: success, info = await save_file(media) if success: print("File saved") - except DuplicateKeyError: pass except FloodWait as e: @@ -291,21 +338,20 @@ async def process_and_send_update(bot, filename, caption): try: media_info = extract_media_info(filename, caption) base_name = media_info["base_name"] + grouping_id = media_info["grouping_id"] processed = media_info["processed"] - - lock = locks[base_name] + lock = locks[grouping_id] async with lock: - await _process_with_lock(bot, filename, caption, media_info, base_name, processed) + await _process_with_lock(bot, filename, caption, media_info, base_name, grouping_id, processed) except PyMongoError as e: logger.error(f"Database error in process_and_send_update: {e}") except Exception as e: logger.exception(f"Processing failed in process_and_send_update: {e}") -async def _process_with_lock(bot, filename, caption, media_info, base_name, processed): +async def _process_with_lock(bot, filename, caption, media_info, base_name, grouping_id, processed): if not hasattr(db, 'movie_updates'): db.movie_updates = db.db.movie_updates - - movie_doc = await db.movie_updates.find_one({"_id": base_name}) + movie_doc = await db.movie_updates.find_one({"_id": grouping_id}) error_tmdb=False file_data = { "filename": filename, @@ -318,16 +364,32 @@ async def _process_with_lock(bot, filename, caption, media_info, base_name, proc "season": media_info["season"], "episode": media_info["episode"] } - if not movie_doc: if TMDB_POSTER: details = await get_movie_detailsx(base_name) if not details or details.get("error") or (not details.get("poster_url") and not details.get("backdrop_url")): error_tmdb=True - logger.info("TMDB error switching to IMDB") + logger.info("TMDB error switching to IMDB + Blogger + PosterFlix") details = await get_movie_details(base_name) or {} + # Fallback chain for poster + if not details.get("poster_url"): + blog_poster = await get_blogger_poster_url(base_name, year=media_info.get("year")) + if blog_poster: + details["poster_url"] = blog_poster + else: + pf_poster = await get_posterflix_poster(base_name, year=media_info.get("year")) + if pf_poster: + details["poster_url"] = pf_poster else: details = await get_movie_details(base_name) or {} + if not details.get("poster_url"): + blog_poster = await get_blogger_poster_url(base_name) + if blog_poster: + details["poster_url"] = blog_poster + else: + pf_poster = await get_posterflix_poster(base_name) + if pf_poster: + details["poster_url"] = pf_poster raw_genres = details.get("genres", "N/A") if isinstance(raw_genres, str): @@ -335,12 +397,18 @@ async def _process_with_lock(bot, filename, caption, media_info, base_name, proc genres = ", ".join(g for g in genre_list if g in STANDARD_GENRES) or "N/A" else: genres = ", ".join(g for g in raw_genres if g in STANDARD_GENRES) or "N/A" + runtime_raw = details.get("runtime", "N/A") + if isinstance(runtime_raw, list): + runtime_raw = ", ".join(str(x) for x in runtime_raw) + runtime_formatted = format_runtime(runtime_raw) movie_doc = { - "_id": base_name, + "_id": grouping_id, + "base_name": base_name, "files": [file_data], "poster_url": details.get("backdrop_url") if LANDSCAPE_POSTER and TMDB_POSTER and details.get("backdrop_url") and not error_tmdb else details.get("poster_url"), "genres": genres, "rating": details.get("rating", "N/A"), + "runtime": runtime_formatted, "imdb_url": details.get("url", "")if not TMDB_POSTER or error_tmdb else details.get("tmdb_url"), "year": details.get("year") or media_info["year"], "tag": media_info["tag"], @@ -352,42 +420,74 @@ async def _process_with_lock(bot, filename, caption, media_info, base_name, proc } try: await db.movie_updates.insert_one(movie_doc) - await send_movie_update(bot, base_name) - movie_doc = await db.movie_updates.find_one({"_id": base_name}) + await send_movie_update(bot, grouping_id) + movie_doc = await db.movie_updates.find_one({"_id": grouping_id}) except DuplicateKeyError: - movie_doc = await db.movie_updates.find_one({"_id": base_name}) + movie_doc = await db.movie_updates.find_one({"_id": grouping_id}) if movie_doc: if any(f["filename"] == filename for f in movie_doc["files"]): return await db.movie_updates.update_one( - {"_id": base_name}, + {"_id": grouping_id}, {"$push": {"files": file_data}} ) movie_doc["files"].append(file_data) - schedule_update(bot, base_name) + schedule_update(bot, grouping_id) else: if any(f["filename"] == filename for f in movie_doc["files"]): return await db.movie_updates.update_one( - {"_id": base_name}, + {"_id": grouping_id}, {"$push": {"files": file_data}} ) movie_doc["files"].append(file_data) - schedule_update(bot, base_name) - -async def send_movie_update(bot, base_name): + schedule_update(bot, grouping_id) + +def format_runtime(runtime_input): + if not runtime_input or runtime_input == "N/A": + return "N/A" + runtime_str = str(runtime_input).strip() + if "h" in runtime_str.lower() and "m" in runtime_str.lower(): + return runtime_str + try: + if "min" in runtime_str.lower(): + mins = int(re.search(r'\d+', runtime_str).group()) + else: + nums = re.findall(r'\d+', runtime_str) + if nums: + mins = int(nums[0]) + if mins < 10: + return runtime_str + else: + return runtime_str + h = mins // 60 + m = mins % 60 + if h > 0: + return f"{h}h {m}m" if m else f"{h}h" + else: + return f"{m}m" + except: + return runtime_str + +async def send_movie_update(bot, grouping_id): + if grouping_id in sending_updates: + logger.warning(f"Duplicate send prevented: {grouping_id}") + return None + sending_updates.add(grouping_id) max_retries = 3 for attempt in range(max_retries): try: - movie_doc = await db.movie_updates.find_one({"_id": base_name}) + movie_doc = await db.movie_updates.find_one({"_id": grouping_id}) if not movie_doc: + sending_updates.discard(grouping_id) return None - - text = generate_movie_message(movie_doc, base_name) + text = generate_movie_message(movie_doc, grouping_id) + is_series = movie_doc.get("tag") == "#SERIES" or any(f.get("season") for f in movie_doc.get("files", [])) + btn_text = "🔵 ɢᴇᴛ ғɪʟᴇs" if is_series else "🟢 ɢᴇᴛ ғɪʟᴇs" buttons = InlineKeyboardMarkup([[ InlineKeyboardButton( - 'ɢᴇᴛ ғɪʟᴇs', - url=f"https://t.me/{temp.U_NAME}?start=getfile-{base_name.replace(' ', '-')}" + btn_text, + url=f"https://t.me/{temp.U_NAME}?start=getfile-{grouping_id.replace(' ', '-')}" ) ]]) size=(2560, 1440) if LANDSCAPE_POSTER and TMDB_POSTER and movie_doc.get("is_backdrop") and not movie_doc.get("error_tmdb") else (853, 1280) @@ -403,13 +503,12 @@ async def send_movie_update(bot, base_name): ) is_photo = True else: - send_params = { - "chat_id": MOVIE_UPDATE_CHANNEL, - "text": text, - "reply_markup": buttons, - "parse_mode": enums.ParseMode.HTML - } - msg = await bot.send_message(**send_params) + msg = await bot.send_message( + chat_id=MOVIE_UPDATE_CHANNEL, + text=text, + reply_markup=buttons, + parse_mode=enums.ParseMode.HTML + ) is_photo = False else: send_params = { @@ -424,41 +523,39 @@ async def send_movie_update(bot, base_name): send_params["link_preview_options"] = LinkPreviewOptions(is_disabled=not LINK_PREVIEW) msg = await bot.send_message(**send_params) is_photo = False - await db.movie_updates.update_one( - {"_id": base_name}, + {"_id": grouping_id}, {"$set": {"message_id": msg.id, "is_photo": is_photo}} ) + sending_updates.discard(grouping_id) return msg except FloodWait as e: - wait_time = e.value + 2 - await asyncio.sleep(wait_time) + await asyncio.sleep(e.value + 2) except Exception as e: logger.error(f"Failed to send movie update: {e}") break + sending_updates.discard(grouping_id) return None -async def update_movie_message(bot, base_name): +async def update_movie_message(bot, grouping_id): try: - movie_doc = await db.movie_updates.find_one({"_id": base_name}) + movie_doc = await db.movie_updates.find_one({"_id": grouping_id}) if not movie_doc: return - - text = generate_movie_message(movie_doc, base_name) + text = generate_movie_message(movie_doc, grouping_id) + is_series = movie_doc.get("tag") == "#SERIES" or any(f.get("season") for f in movie_doc.get("files", [])) + btn_text = "🔵 ɢᴇᴛ ғɪʟᴇs" if is_series else "🟢 ɢᴇᴛ ғɪʟᴇs" buttons = InlineKeyboardMarkup([[ InlineKeyboardButton( - 'ɢᴇᴛ ғɪʟᴇs', - url=f"https://t.me/{temp.U_NAME}?start=getfile-{base_name.replace(' ', '-')}" + btn_text, + url=f"https://t.me/{temp.U_NAME}?start=getfile-{grouping_id.replace(' ', '-')}" ) ]]) - message_id = movie_doc.get("message_id") is_photo = movie_doc.get("is_photo", False) - if not message_id: - await send_movie_update(bot, base_name) + await send_movie_update(bot, grouping_id) return - try: if is_photo: await bot.edit_message_caption( @@ -490,26 +587,27 @@ async def update_movie_message(bot, base_name): message_ids=message_id ) await db.movie_updates.update_one( - {"_id": base_name}, + {"_id": grouping_id}, {"$set": {"message_id": None, "is_photo": False}} ) except Exception as e: logger.error(f"Error during message deletion/update in recovery: {e}") pass - await send_movie_update(bot, base_name) + await send_movie_update(bot, grouping_id) except Exception as e: - logger.error(f"Failed to update movie message for {base_name}: {e}") + logger.error(f"Failed to update movie message for {grouping_id}: {e}") -def generate_movie_message(movie_doc, base_name): +def generate_movie_message(movie_doc, grouping_id): + from collections import defaultdict all_qualities = set() all_languages = set() all_ott_platforms = set() all_tags = set() episodes_by_season = defaultdict(set) - for file in movie_doc["files"]: if file["quality"] != "N/A": - all_qualities.update(q.strip() for q in file["quality"].split(",") if q.strip()) + quals = [q.strip().upper() for q in file["quality"].split(",") if q.strip()] + all_qualities.update(quals) if file["language"] != "N/A": all_languages.update(lang.strip() for lang in file["language"].split(",") if lang.strip()) if file["ott_platform"] != "N/A": @@ -518,10 +616,7 @@ def generate_movie_message(movie_doc, base_name): if file["tag"]: all_tags.add(file["tag"]) if file.get("season") and file.get("episode"): - season = file["season"] - episode = file["episode"] - episodes_by_season[season].add(episode) - + episodes_by_season[file["season"]].add(file["episode"]) primary_tag = "#SERIES" if "#SERIES" in all_tags else "#MOVIE" epi_block = "" if episodes_by_season: @@ -529,7 +624,6 @@ def generate_movie_message(movie_doc, base_name): for season, episodes in sorted(episodes_by_season.items(), key=lambda x: int(x[0])): singles = [] ranges = [] - for ep in episodes: if "-" in ep: ranges.append(ep) @@ -538,7 +632,6 @@ def generate_movie_message(movie_doc, base_name): singles.append(int(ep)) except ValueError: ranges.append(ep) - singles.sort() collapsed = [] start = end = None @@ -552,14 +645,11 @@ def generate_movie_message(movie_doc, base_name): start = end = num if start is not None: collapsed.append(str(start) if start == end else f"{start}-{end}") - all_ep_parts = collapsed + sorted(ranges, key=lambda s: int(s.split("-")[0])) episode_lines.append(f"S{int(season)}: {', '.join(all_ep_parts)}") - epi_str = "\n".join(episode_lines) if epi_str: epi_block = f"📺 ᴇᴘɪsᴏᴅᴇs : \n{epi_str}" - genres = movie_doc.get("genres", "N/A") quality_str = ", ".join(sorted(all_qualities)) if all_qualities else "N/A" language_str = ", ".join(sorted(all_languages)) if all_languages else "N/A" @@ -569,10 +659,10 @@ def generate_movie_message(movie_doc, base_name): r = float(rating) except (TypeError, ValueError): r = 0.0 - rating_text = "-" if r == 0.0 else str(rating) + runtime = movie_doc.get("runtime", "N/A") year_val = str(movie_doc.get("year") or "") - filename_display = base_name + filename_display = movie_doc.get("base_name", grouping_id) if year_val and filename_display.strip().endswith(year_val): filename_display = filename_display.strip()[:-len(year_val)].strip() return script.MOVIE_UPDATE_NOTIFY_TXT.format( @@ -583,9 +673,38 @@ def generate_movie_message(movie_doc, base_name): year=year_val, genres=genres, ott=ott_str, + runtime=runtime, quality=quality_str, language=language_str, episodes=epi_block, rating=rating_text, search_link=temp.B_LINK -) + ) + +# --- Domain setter (from Rpeditz) --- +@Client.on_message(filters.command("setdomain")) +async def set_domain_handler(bot, message): + if len(message.command) < 2: + try: + from database.users_chats_db import db + setting = await db.db.settings.find_one({"_id": "hdhub_base_url"}) + current_url = setting.get("url") if setting else DEFAULT_HDHUB_DOMAIN + except: + current_url = DEFAULT_HDHUB_DOMAIN + return await message.reply_text( + f"🌐 Current HDHub4u URL: {current_url}\n\n" + f"💡 Usage: /setdomain https://newdomain.com" + ) + new_url = message.command[1].strip() + if not new_url.startswith("http"): + return await message.reply_text("❌ Invalid URL. Must start with http:// or https://") + try: + from database.users_chats_db import db + await db.db.settings.update_one( + {"_id": "hdhub_base_url"}, + {"$set": {"url": new_url}}, + upsert=True + ) + await message.reply_text(f"✅ HDHub4u base URL updated to:\n{new_url}") + except Exception as e: + await message.reply_text(f"❌ Failed to update domain: {e}") From 39322ef3ee6ed9d4ddfe16332e17709d8a3901f5 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Thu, 24 Sep 2026 18:55:07 +0530 Subject: [PATCH 72/77] Update Imdbposter.py --- plugins/Dreamxfutures/Imdbposter.py | 401 ++++++++++++++++++++-------- 1 file changed, 292 insertions(+), 109 deletions(-) diff --git a/plugins/Dreamxfutures/Imdbposter.py b/plugins/Dreamxfutures/Imdbposter.py index e478b1ce..ee13a68a 100644 --- a/plugins/Dreamxfutures/Imdbposter.py +++ b/plugins/Dreamxfutures/Imdbposter.py @@ -8,6 +8,8 @@ from difflib import SequenceMatcher from PIL import Image from info import DREAMXBOTZ_IMAGE_FETCH, TMDB_API_KEY, MAX_LIST_ELM +from bs4 import BeautifulSoup +from typing import Optional, Tuple logger = logging.getLogger(__name__) @@ -16,13 +18,12 @@ Image.MAX_IMAGE_PIXELS = None warnings.simplefilter("ignore", Image.DecompressionBombWarning) -#TMDB API ADDED BY @Bharath_boy - # --- TMDB Configuration --- TMDB_BEARER_TOKEN = 'eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI2ZGU3YTIyZGU1YjE5YTFjNmUyZGU5ZWEyMzE2ZmQxMCIsIm5iZiI6MTc0NTMyMjQ2Mi41MzMsInN1YiI6IjY4MDc4MWRlYzVjODAzNWZiMDhhNjExNCIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.rMMJ2-PBIv8Y7ybxPIEpIlzTEXzuwrm9ruKxAUCAsbw' TMDB_BASE_URL = 'https://api.themoviedb.org/3' TMDB_IMAGE_BASE_URL = 'https://image.tmdb.org/t/p/original' MIN_RUNTIME = 40 +DEFAULT_HDHUB_DOMAIN = "https://new6.hdhub4u.cl" _session: aiohttp.ClientSession | None = None @@ -38,34 +39,27 @@ async def fetch_image(url, size=(860, 1200)): if not DREAMXBOTZ_IMAGE_FETCH: logger.info("Image fetching is disabled.") return url - try: session = await get_session() - async with session.get(url) as response: if response.status != 200: logger.error(f"Failed to fetch image: {response.status} for {url}") return None - data = await response.read() img = Image.open(BytesIO(data)) img = img.resize(size, Image.LANCZOS) - out = BytesIO() img.save(out, format="JPEG") out.seek(0) return out - except aiohttp.ClientError as e: logger.error(f"HTTP request error in fetch_image: {e}") except IOError as e: logger.error(f"I/O error in fetch_image: {e}") except Exception as e: logger.error(f"Unexpected error in fetch_image: {e}") - return None - async def close_session(): if _session and not _session.closed: await _session.close() @@ -75,9 +69,7 @@ def list_to_str(lst): return ", ".join(map(str, lst)) return "" - def _list_to_str_tmdb(data_list, limit=10, key=None): - """Helper for formatting TMDB response lists to comma-separated strings.""" if not data_list or not isinstance(data_list, list): return None items = data_list[:limit] @@ -85,9 +77,7 @@ def _list_to_str_tmdb(data_list, limit=10, key=None): return ", ".join(str(item.get(key, '')) for item in items if item) return ", ".join(str(item) for item in items if item) - def _extract_title_and_year(query: str): - """Extract title and optional year from a search query string.""" match = re.search(r'^(.*?)(?:\s+(\d{4}))?$', query.strip()) if match: title, year_str = match.groups() @@ -95,13 +85,19 @@ def _extract_title_and_year(query: str): return title.strip(), year return query.strip(), None +def _extract_title_year_and_season(query: str): + match = re.search(r'^(.*?)(?:\s+(?:season|s)\s*(\d+))?(?:\s+(\d{4}))?$', query.strip(), re.IGNORECASE) + if match: + title, season_str, year_str = match.groups() + season = int(season_str) if season_str and season_str.isdigit() else None + year = int(year_str) if year_str and year_str.isdigit() else None + return title.strip(), season, year + return query.strip(), None, None async def _tmdb_get(path, params=None, api_key=None): - """Async GET request to TMDB API using aiohttp.""" url = f"{TMDB_BASE_URL}/{path.lstrip('/')}" _params = params.copy() if params else {} _headers = {} - if api_key: _params['api_key'] = api_key elif TMDB_BEARER_TOKEN: @@ -109,45 +105,63 @@ async def _tmdb_get(path, params=None, api_key=None): 'Authorization': f'Bearer {TMDB_BEARER_TOKEN}', 'Content-Type': 'application/json;charset=utf-8' } - session = await get_session() async with session.get(url, params=_params, headers=_headers, ssl=False) as resp: resp.raise_for_status() return await resp.json() - async def _fetch_media_details(media_type: str, media_id: int, api_key=None): - """Fetch full details for a movie or TV show from TMDB.""" - params = {'append_to_response': 'credits,external_ids,alternative_titles,release_dates,images'} + params = {'append_to_response': 'credits,external_ids,alternative_titles,release_dates,images', 'include_image_language': 'en,hi,null'} return await _tmdb_get(f"{media_type}/{media_id}", params=params, api_key=api_key) +async def _fetch_season_poster(tv_id: int, season_number: int, api_key=None): + try: + data = await _tmdb_get( + f"tv/{tv_id}/season/{season_number}", + params={'append_to_response': 'images', 'include_image_language': 'en,hi,null'}, + api_key=api_key + ) + posters = data.get('images', {}).get('posters', []) + if posters: + return f"{TMDB_IMAGE_BASE_URL}{posters[0]['file_path']}" + except Exception: + pass + return None -async def _search_media_id(query: str, api_key=None): - """Search TMDB for the best matching movie/TV show and return (media_type, media_id).""" - title, year = _extract_title_and_year(query) - +async def _search_media_id(query: str, api_key=None, is_series: bool = None): + # IMDb ID direct lookup + if re.match(r'^tt\d+$', query.strip(), re.IGNORECASE): + try: + find_res = await _tmdb_get(f"find/{query.strip()}", params={'external_source': 'imdb_id'}, api_key=api_key) + order = ('tv', 'movie') if is_series else ('movie', 'tv') + for mtype in order: + res_list = find_res.get(f"{mtype}_results", []) + if res_list: + return mtype, res_list[0]['id'] + except Exception: + pass + + title, season, year = _extract_title_year_and_season(query) + clean_title_for_match = re.sub(r'\b(season|part|vol|volume)\b.*', '', title, flags=re.IGNORECASE).strip() + if not clean_title_for_match: + clean_title_for_match = title + + queries_to_try = list(dict.fromkeys([title, clean_title_for_match]))[:3] multi_results = [] - words = title.split() - - # Generate up to 3 fallback queries to minimize API rate limit usage - queries_to_try = [title] - if len(words) > 2: - queries_to_try.append(" ".join(words[:-1])) # Drop the last word - queries_to_try.append(words[0]) # Keep just the first word - elif len(words) == 2: - queries_to_try.append(words[0]) - - # Remove any duplicates but preserve order, capping at 3 attempts - queries_to_try = list(dict.fromkeys(queries_to_try))[:3] - for target_query in queries_to_try: if not target_query: continue params = {'query': target_query, 'language': 'en-US', 'page': 1, 'include_adult': 'false'} - result = await _tmdb_get('search/multi', params=params, api_key=api_key) - multi_results = result.get('results', []) - if multi_results: - break + try: + result = await _tmdb_get('search/multi', params=params, api_key=api_key) + multi_results = result.get('results', []) + if multi_results: + break + except Exception: + continue + + if not multi_results: + return None, None def get_ratio(s1, s2): if not s1 or not s2: @@ -155,53 +169,64 @@ def get_ratio(s1, s2): return SequenceMatcher(None, s1.lower(), s2.lower()).ratio() scored_results = [] + query_words = set(clean_title_for_match.lower().split()) + target_type = 'tv' if is_series is True else ('movie' if is_series is False else None) + for r in multi_results: - # Score the string matched against the ORIGINAL title, not the shortened target_query - ratio = get_ratio(r.get('title') or r.get('name'), title) - if ratio >= 0.5: # Lowered from 0.6 to 0.5 to allow for dropped/modified words - scored_results.append((r, ratio)) + mtype = r.get('media_type') + if mtype not in ['movie', 'tv']: + continue + type_bonus = 0.0 + if target_type: + if mtype == target_type: + type_bonus = 0.35 + else: + type_bonus = -0.35 + media_name = r.get('title') or r.get('name') or '' + orig_name = r.get('original_title') or r.get('original_name') or '' + ratio = max(get_ratio(media_name, clean_title_for_match), get_ratio(orig_name, clean_title_for_match)) + media_words = set(media_name.lower().split()) | set(orig_name.lower().split()) + overlap = len(query_words.intersection(media_words)) + lang_bonus = 0.15 if r.get('original_language') == 'hi' else 0.0 + final_ratio = ratio + type_bonus + lang_bonus + if ratio >= 0.35 or (query_words and overlap >= len(query_words) * 0.5): + scored_results.append((r, final_ratio, overlap)) if not scored_results: - scored_results = [(r, get_ratio(r.get('title') or r.get('name'), title)) for r in multi_results[:10]] + valid_res = [r for r in multi_results if r.get('media_type') in ['movie', 'tv']] + if valid_res: + scored_results = [(valid_res[0], 1.0, 1)] + candidates_past, candidates_upcoming, candidates_nodate = [], [], [] today = datetime.utcnow().date() - candidates_past, candidates_upcoming = [], [] - for r, ratio in scored_results: + for item in scored_results: + r = item[0] + ratio = item[1] mtype = r.get('media_type') rd_str = r.get('release_date') or r.get('first_air_date') - if not (rd_str and mtype in ['movie', 'tv']): + candidate = {'type': mtype, 'id': r['id'], 'date': None, 'score': r.get('popularity', 0), 'ratio': ratio} + if not rd_str: + candidates_nodate.append(candidate) continue try: rd_date = datetime.strptime(rd_str, '%Y-%m-%d').date() + candidate['date'] = rd_date except ValueError: + candidates_nodate.append(candidate) + continue + if year and abs(rd_date.year - year) > 1: continue - if year: - if abs(rd_date.year - year) > 1: - continue - if mtype == 'movie': - try: - details = await _fetch_media_details(mtype, r['id'], api_key=api_key) - runtime = details.get('runtime') - is_video = details.get('video', False) - - if is_video or (runtime and runtime < MIN_RUNTIME): - continue - except Exception: - continue - candidate = {'type': mtype, 'id': r['id'], 'date': rd_date, 'score': r.get('popularity', 0), 'ratio': ratio} (candidates_upcoming if rd_date > today else candidates_past).append(candidate) - candidates_past.sort(key=lambda x: (x['ratio'], x['date'], x['score']), reverse=True) - candidates_upcoming.sort(key=lambda x: (x['ratio'], x['date'], x['score']), reverse=True) - final = candidates_past or candidates_upcoming + candidates_past.sort(key=lambda x: (round(x['ratio'], 1), x['score'], x['date'] or today), reverse=True) + candidates_upcoming.sort(key=lambda x: (round(x['ratio'], 1), x['score']), reverse=True) + candidates_nodate.sort(key=lambda x: (round(x['ratio'], 1), x['score']), reverse=True) + final = candidates_past or candidates_upcoming or candidates_nodate if not final: return None, None - top = final[0] - return top['type'], top['id'] - + return final[0]['type'], final[0]['id'] def _process_images(images_data): - """Organize poster and backdrop images by language.""" posters_by_lang, backdrops_by_lang = {}, {} for img in images_data.get('posters', []): lang = img.get('iso_639_1') or 'no_lang' @@ -214,36 +239,28 @@ def _process_images(images_data): languages = sorted(set(posters_by_lang) | set(backdrops_by_lang)) return {'posters': posters_by_lang, 'backdrops': backdrops_by_lang, 'available_languages': languages} - -async def _fetch_tmdb_data(query: str, api_key=None): - """ - Core TMDB lookup: search → fetch details → build response dict. - This replaces the external tmdb.blazeposters.workers.dev API call. - """ - media_type, media_id = await _search_media_id(query, api_key=api_key) +async def _fetch_tmdb_data(query: str, api_key=None, is_series: bool = None): + title, season, year_extracted = _extract_title_year_and_season(query) + media_type, media_id = await _search_media_id(query, api_key=api_key, is_series=is_series) if not media_id: return None - details = await _fetch_media_details(media_type, media_id, api_key=api_key) crew = details.get('credits', {}).get('crew', []) - certificates = None if media_type == 'movie' and 'release_dates' in details: us = [r for r in details['release_dates']['results'] if r['iso_3166_1'] == 'US'] if us and us[0]['release_dates']: certificates = us[0]['release_dates'][0].get('certification') - runtime_display = None + er_raw = details.get('episode_run_time', []) + er_val = er_raw[0] if isinstance(er_raw, list) and er_raw else None if media_type == 'movie': runtime = details.get('runtime') runtime_display = f"{runtime} min" if runtime else None else: - er = _list_to_str_tmdb(details.get('episode_run_time', [])) - runtime_display = f"{er} min" if er else None - + runtime_display = f"{er_val} min" if er_val else None images_structured = _process_images(details.get('images', {})) images_structured['original_language'] = details.get('original_language') - output_data = { 'query': query, 'media_type': media_type, 'media_id': media_id, 'title': details.get('title') or details.get('name'), @@ -275,15 +292,162 @@ async def _fetch_tmdb_data(query: str, api_key=None): 'url': f"https://www.themoviedb.org/{media_type}/{details.get('id')}", 'images': images_structured, } - if media_type == 'tv': output_data.update({ 'seasons': details.get('number_of_seasons'), 'episodes': details.get('number_of_episodes'), }) - + # Season poster if season provided + if season: + season_poster = await _fetch_season_poster(media_id, season, api_key=api_key) + if season_poster: + output_data['season_poster'] = season_poster return output_data +# --- Poster Fallback Chain --- + +async def get_hdhub_base_url() -> str: + try: + from database.users_chats_db import db + if hasattr(db, 'db'): + setting = await db.db.settings.find_one({"_id": "hdhub_base_url"}) + if setting and setting.get("url"): + return setting["url"].rstrip("/") + except Exception: + pass + return DEFAULT_HDHUB_DOMAIN + +async def get_blogger_poster_url(base_name: str, year: Optional[str] = None) -> Optional[str]: + try: + blog_url = "https://tmdbimdbhdhub4u.blogspot.com" + try: + from database.users_chats_db import db + if hasattr(db, 'db'): + setting = await db.db.settings.find_one({"_id": "blogger_base_url"}) + if setting and setting.get("url"): + blog_url = setting["url"].rstrip("/") + except: + pass + feed_url = f"{blog_url}/feeds/posts/default?alt=json&max-results=50" + timeout = aiohttp.ClientTimeout(total=8) + async with aiohttp.ClientSession(timeout=timeout) as session: + async with session.get(feed_url) as resp: + if resp.status != 200: + return None + data = await resp.json() + entries = data.get("feed", {}).get("entry", []) + clean_query = re.sub(r'\b(19|20)\d{2}\b', '', base_name).strip().lower() + for entry in entries: + post_title = entry.get("title", {}).get("$t", "") + if clean_query in post_title.lower() or base_name.lower() in post_title.lower(): + content_html = entry.get("content", {}).get("$t", "") + soup = BeautifulSoup(content_html, "html.parser") + img_tag = soup.find("img") + if img_tag and img_tag.get("src"): + img_url = img_tag["src"] + img_url = re.sub(r'/s\d+(-c)?/', '/s1600/', img_url) + img_url = re.sub(r'/w\d+-[h\d]+/', '/', img_url) + return img_url + except Exception as e: + logger.error(f"Error fetching Blogger poster: {e}") + return None + +async def get_posterflix_poster(base_name: str, year: Optional[str] = None) -> Optional[str]: + try: + query = f"{base_name} {year}" if year else base_name + query_enc = query.replace(" ", "+") + url = f"https://posterflix.vercel.app/api/movie-posters?query={query_enc}" + timeout = aiohttp.ClientTimeout(total=8) + async with aiohttp.ClientSession(timeout=timeout) as session: + async with session.get(url) as resp: + if resp.status != 200: + return None + data = await resp.json() + # API returns JSON with poster collection + posters = data.get('posters') or data.get('data') or data.get('results') or [] + if isinstance(posters, dict): + posters = posters.get('posters') or [] + if posters and isinstance(posters, list): + first = posters[0] + if isinstance(first, dict): + return first.get('url') or first.get('poster_url') or first.get('image') or first.get('path') + elif isinstance(first, str) and first.startswith('http'): + return first + # Sometimes direct url field + if data.get('poster_url'): + return data['poster_url'] + except Exception as e: + logger.error(f"PosterFlix error: {e}") + return None + +async def get_hdhub4u_data(base_name: str) -> Tuple[str, str, str, bool]: + genres = "N/A" + rating = "N/A" + info_url = "" + is_series = False + try: + base_url = await get_hdhub_base_url() + clean_search_query = re.sub(r'\b(?:season|s)\s*\d+\b', '', base_name, flags=re.IGNORECASE) + clean_search_query = re.sub(r'\b(?:19|20)\d{2}\b', '', clean_search_query).strip() + search_words = [w for w in clean_search_query.split() if len(w) >= 2][:3] + effective_query = "+".join(search_words) if search_words else clean_search_query.replace(" ", "+") + search_url = f"{base_url.rstrip('/')}/?s={effective_query}" + headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" + } + timeout = aiohttp.ClientTimeout(total=10) + async with aiohttp.ClientSession(timeout=timeout) as session: + async with session.get(search_url, headers=headers, allow_redirects=True) as resp: + if resp.status != 200: + return genres, rating, info_url, is_series + html = await resp.text() + soup = BeautifulSoup(html, "html.parser") + for tag in soup(["header", "nav", "footer", "aside", "script", "style", "form"]): + tag.decompose() + candidate_items = [] + for art in soup.select("article, .post-item, .recent-movies li, .entry-title, .thumb"): + a_tag = art.find("a", href=True) + if not a_tag: + continue + href = a_tag["href"].strip() + if not href or href == "#" or any(x in href for x in ["/category/", "/tag/", "/author/", "/page/", "/wp-content/"]): + continue + title_text = f"{a_tag.get('title', '')} {a_tag.get_text()}".strip() + candidate_items.append((title_text, href)) + if not candidate_items: + return genres, rating, info_url, is_series + # Simple best match + best_href = candidate_items[0][1] + # Fetch movie page + async with aiohttp.ClientSession(timeout=timeout) as session: + async with session.get(best_href, headers=headers, allow_redirects=True) as resp: + if resp.status != 200: + return genres, rating, info_url, is_series + movie_html = await resp.text() + movie_soup = BeautifulSoup(movie_html, "html.parser") + search_area = movie_soup.select_one(".entry-content, .post-content, article") or movie_soup.body or movie_soup + for a_tag in search_area.find_all("a", href=True): + href = a_tag["href"].strip() + m_imdb = re.search(r'imdb\.com/title/(tt\d+)', href, re.IGNORECASE) + if m_imdb: + info_url = f"https://www.imdb.com/title/{m_imdb.group(1)}/" + break + # Try to find rating/genres in text + text_content = search_area.get_text(" ", strip=True) + m_rating = re.search(r'(\d\.\d)/10', text_content) + if m_rating: + rating = m_rating.group(1) + # Genre detection simple + known_genres = ['Action','Adventure','Drama','Comedy','Thriller','Horror','Romance','Sci-Fi','Crime','Mystery'] + found = [g for g in known_genres if g.lower() in text_content.lower()] + if found: + genres = ", ".join(found[:3]) + if 'series' in text_content.lower() or 'season' in text_content.lower(): + is_series = True + except Exception as e: + logger.error(f"get_hdhub4u_data error: {e}") + return genres, rating, info_url, is_series async def get_movie_details(query, bulk=False, id=False, file=None): if not id: @@ -291,7 +455,6 @@ async def get_movie_details(query, bulk=False, id=False, file=None): query = (query.strip()).lower() title = query year_val = None - year_list = re.findall(r'[1-2]\d{3}$', query, re.IGNORECASE) if year_list: year_val = year_list[0] @@ -300,26 +463,20 @@ async def get_movie_details(query, bulk=False, id=False, file=None): year_list = re.findall(r'[1-2]\d{3}', file, re.IGNORECASE) if year_list: year_val = year_list[0] - search_result = await asyncio.to_thread(imdb.search_movie, title.lower()) if not search_result or not search_result.titles: return None - movie_list = search_result.titles[:MAX_LIST_ELM] - if year_val: filtered = [m for m in movie_list if m.year and str(m.year) == str(year_val)] if not filtered: filtered = movie_list else: filtered = movie_list - kind_filter = ['movie', 'tv series', 'tvSeries', 'tvMiniSeries', 'tvMovie'] filtered_kind = [m for m in filtered if m.kind and m.kind in kind_filter] - if not filtered_kind: filtered_kind = filtered - if bulk: return filtered_kind[:MAX_LIST_ELM] if not filtered_kind: @@ -328,18 +485,15 @@ async def get_movie_details(query, bulk=False, id=False, file=None): movieid_str = movie_brief.imdb_id else: movieid_str = query - movie = await asyncio.to_thread(imdb.get_movie, movieid_str) if not movie: return None - if movie.release_date: date = movie.release_date elif movie.year: date = str(movie.year) else: date = "N/A" - plot = movie.plot[0] if isinstance(movie.plot, list) else movie.plot or "" if len(plot) > 800: plot = plot[:800] + "..." @@ -382,23 +536,44 @@ async def get_movie_details(query, bulk=False, id=False, file=None): "url": movie.url or f"https://www.imdb.com/title/{imdb_id}" } - async def get_movie_detailsx(query, id=False, file=None): - """ - Primary movie details fetcher using direct TMDB API calls. - Falls back to IMDb-based get_movie_details() on failure. - """ q = str(query).strip() + # Detect if query looks like series + is_series_hint = bool(re.search(r'\bS\d{1,2}E\d{1,3}\b|\bSeason\b', q, re.IGNORECASE)) try: - data = await _fetch_tmdb_data(q, api_key=TMDB_API_KEY or None) + data = await _fetch_tmdb_data(q, api_key=TMDB_API_KEY or None, is_series=is_series_hint if is_series_hint else None) if not data: logger.info(f"TMDB returned no results for '{q}' → switching to IMDb fallback") - return await get_movie_details(q) + imdb_data = await get_movie_details(q) + # Try poster fallbacks + if imdb_data: + poster = imdb_data.get('poster_url') or imdb_data.get('poster') + if not poster or 'nopicture' in str(poster).lower(): + # Try Blogger + blog_poster = await get_blogger_poster_url(q) + if blog_poster: + imdb_data['poster_url'] = blog_poster + else: + # Try PosterFlix API + pf_poster = await get_posterflix_poster(q) + if pf_poster: + imdb_data['poster_url'] = pf_poster + return imdb_data except Exception as e: logger.info(f"TMDB direct call failed → fallback IMDb: {e}") - return await get_movie_details(q) + imdb_data = await get_movie_details(q) + if imdb_data: + poster = imdb_data.get('poster_url') + if not poster: + blog_poster = await get_blogger_poster_url(q) + if blog_poster: + imdb_data['poster_url'] = blog_poster + else: + pf_poster = await get_posterflix_poster(q) + if pf_poster: + imdb_data['poster_url'] = pf_poster + return imdb_data - # Normalize fields details = {} details['title'] = data.get('title') or data.get('localized_title') details['year'] = (data.get('year', 0)) if data.get('year') else None @@ -408,14 +583,12 @@ async def get_movie_detailsx(query, id=False, file=None): details['runtime'] = data.get('runtime') details['certificates'] = data.get('certificates') details['tmdb_url'] = data.get('url') - for key in ('genres', 'languages', 'countries'): raw = data.get(key) details[key] = [s.strip() for s in raw.split(',')] if raw else [] for role in ('director', 'writer', 'producer', 'composer', 'cinematographer', 'cast'): raw = data.get(role) details[role] = [s.strip() for s in raw.split(',')] if raw else [] - details['plot'] = data.get('plot') details['tagline'] = data.get('tagline') details['box_office'] = (data.get('box_office', 0)) if data.get('box_office') else None @@ -423,7 +596,6 @@ async def get_movie_detailsx(query, id=False, file=None): details['distributors'] = [d.strip() for d in raw_dist.split(',')] if raw_dist else [] details['imdb_id'] = data.get('imdb_id') details['tmdb_id'] = data.get('tmdb_id') - posters = data.get('images', {}).get('posters', {}) original_language = data.get('images', {}).get('original_language') poster_url = data.get('poster_url') @@ -432,8 +604,21 @@ async def get_movie_detailsx(query, id=False, file=None): if key and posters.get(key): poster_url = posters[key][0] break + # Season poster priority + if data.get('season_poster'): + poster_url = data.get('season_poster') details['poster_url'] = poster_url.replace("/original/", "/w1280/") if poster_url else None + # If still no poster, try Blogger then PosterFlix + if not details['poster_url']: + blog_poster = await get_blogger_poster_url(q, year=details.get('year')) + if blog_poster: + details['poster_url'] = blog_poster + else: + pf_poster = await get_posterflix_poster(q, year=details.get('year')) + if pf_poster: + details['poster_url'] = pf_poster + backdrops = data.get('images', {}).get('backdrops', {}) original_language = data.get('images', {}).get('original_language') backdrop_url = None @@ -442,6 +627,4 @@ async def get_movie_detailsx(query, id=False, file=None): backdrop_url = backdrops[key][0] break details['backdrop_url'] = backdrop_url.replace("/original/", "/w1280/") if backdrop_url else None - return details - From 8385435a9902fc795c7f1b090bd06eab7560eabc Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Thu, 24 Sep 2026 18:55:35 +0530 Subject: [PATCH 73/77] Update Script.py --- Script.py | 87 +++++++++++++++++++++++++++---------------------------- 1 file changed, 43 insertions(+), 44 deletions(-) diff --git a/Script.py b/Script.py index e7eda801..a5a36def 100644 --- a/Script.py +++ b/Script.py @@ -18,9 +18,9 @@ class script(object): ✨ Hᴏᴡ ᴛᴏ ʀᴇǫᴜᴇꜱᴛ ᴅʀᴀᴍᴀꜱ & ᴍᴏᴠɪᴇꜱ ✨ -1️⃣ Sᴇᴀʀᴄʜ ᴛʜᴇ ᴄᴏʀʀᴇᴄᴛ ɴᴀᴍᴇ ᴏɴ ɢᴏᴏɢʟᴇ. -2️⃣ Sᴇɴᴅ ᴛʜᴇ ɴᴀᴍᴇ ɪɴ ᴛʜᴇ ɢʀᴏᴜᴘ. -3️⃣ Uꜱᴇ ᴛʜɪꜱ ꜰᴏʀᴍᴀᴛ: +1⃣ Sᴇᴀʀᴄʜ ᴛʜᴇ ᴄᴏʀʀᴇᴄᴛ ɴᴀᴍᴇ ᴏɴ ɢᴏᴏɢʟᴇ. +2⃣ Sᴇɴᴅ ᴛʜᴇ ɴᴀᴍᴇ ɪɴ ᴛʜᴇ ɢʀᴏᴜᴘ. +3⃣ Uꜱᴇ ᴛʜɪꜱ ꜰᴏʀᴍᴀᴛ: 📌 Fᴏʀ ꜱᴇʀɪᴇꜱ: ➤ Sᴇʀɪᴇs ɴᴀᴍᴇ + S01 (ꜰᴏʀ ꜱᴇᴀꜱᴏɴ 1, ᴄʜᴀɴɢᴇ ꜰᴏʀ ᴏᴛʜᴇʀꜱ) @@ -49,7 +49,7 @@ class script(object): 📅 Dᴀᴛᴇ : {} ⏰ Tɪᴍᴇ : {} 🌐 Tɪᴍᴇᴢᴏɴᴇ : Asia/Kolkata -🛠️ Bᴜɪʟᴅ Sᴛᴀᴛᴜs: v1.4 [ Sᴛᴀʙʟᴇ ] +🛠 Bᴜɪʟᴅ Sᴛᴀᴛᴜs: v1.4 [ Sᴛᴀʙʟᴇ ] """ MULTI_STATUS_TXT = """🗃ᴜsᴇʀs ᴅᴀᴛᴀʙᴀsᴇ 🗃 @@ -112,7 +112,7 @@ class script(object): Iᴅ - {} Nᴀᴍᴇ - {} """ - NT_ADMIN_ALRT_TXT = """‼️ Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴀᴅᴍɪɴ ɪɴ ᴛʜɪꜱ ɢʀᴏᴜᴘ ‼️""" + NT_ADMIN_ALRT_TXT = """‼ Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴀᴅᴍɪɴ ɪɴ ᴛʜɪꜱ ɢʀᴏᴜᴘ ‼""" NT_ALRT_TXT = """Not Yours!""" @@ -129,31 +129,31 @@ class script(object): ✨ ᴜɴʟᴏᴄᴋ ᴇxᴄʟᴜsɪᴠᴇ ᴄᴏɴᴛᴇɴᴛ ᴀɴᴅ ꜰᴇᴀᴛᴜʀᴇs 💳 ʙᴜʏ ᴘʀᴇᴍɪᴜᴍ ᴛᴏ ɢᴇᴛ sᴛᴀʀᴛᴇᴅ""" - PRE_STREAM_ALERT = """⚠️ ᴘʀᴇᴍɪᴜᴍ ᴄᴏɴᴛᴇɴᴛ ❗ + PRE_STREAM_ALERT = """⚠ ᴘʀᴇᴍɪᴜᴍ ᴄᴏɴᴛᴇɴᴛ ❗ 🔓 ᴜɴʟᴏᴄᴋ ɪᴛ ʙʏ ᴜᴘɢʀᴀᴅɪɴɢ ᴛᴏ ᴘʀᴇᴍɪᴜᴍ""" - CUDNT_FND = SPELLING_ERROR_TXT = """‼️ ꜱᴘᴇʟʟɪɴɢ ᴍɪꜱᴛᴀᴋᴇ ʙʀᴏ! + CUDNT_FND = SPELLING_ERROR_TXT = """‼ ꜱᴘᴇʟʟɪɴɢ ᴍɪꜱᴛᴀᴋᴇ ʙʀᴏ! 😊 ɴᴏ ᴡᴏʀʀɪᴇꜱ — ᴄʜᴏᴏꜱᴇ ᴛʜᴇ ᴄᴏʀʀᴇᴄᴛ ᴏɴᴇ ʙᴇʟᴏᴡ 👇
👇 नीचे दिए गए विकल्पों में से movie के नाम की सही spelling चुनें
""" - DEL_MSG = """⚠️ ᴛʜɪꜱ ᴍᴏᴠɪᴇ ꜰɪʟᴇ/ᴠɪᴅᴇᴏ ᴡɪʟʟ ʙᴇ ᴅᴇʟᴇᴛᴇᴅ ɪɴ {} + DEL_MSG = """⚠ ᴛʜɪꜱ ᴍᴏᴠɪᴇ ꜰɪʟᴇ/ᴠɪᴅᴇᴏ ᴡɪʟʟ ʙᴇ ᴅᴇʟᴇᴛᴇᴅ ɪɴ {}
ᴘʟᴇᴀꜱᴇ ꜰᴏʀᴡᴀʀᴅ ᴛʜɪꜱ ꜰɪʟᴇ ᴛᴏ ꜱᴏᴍᴇᴡʜᴇʀᴇ ᴇʟꜱᴇ & ꜱᴛᴀʀᴛ ᴅᴏᴡɴʟᴏᴀᴅɪɴɢ ᴛʜᴇʀᴇ
""" - I_CUDNT = """sᴏʀʀʏ ɴᴏ ꜰɪʟᴇs ᴡᴇʀᴇ ꜰᴏᴜɴᴅ ꜰᴏʀ ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ {} 😕 + I_CUDNT = """sᴏʀʀʏ ɴᴏ ꜰɪʟᴇs ᴡᴇʀᴇ ꜰᴏᴜɴᴅ ꜰᴏʀ ʏᴏᴜʀ ʀᴇǫᴜᴇsᴛ {} 😕 ᴄʜᴇᴄᴋ ʏᴏᴜʀ sᴘᴇʟʟɪɴɢ ɪɴ ɢᴏᴏɢʟᴇ ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ 😃 📝 ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ ꜰᴏʀᴍᴀᴛ 👇 -⚜️ ᴇxᴀᴍᴘʟᴇ : Jawan or Jawan 2023 +⚜ ᴇxᴀᴍᴘʟᴇ : Jawan or Jawan 2023 📝 ꜱᴇʀɪᴇꜱ ʀᴇǫᴜᴇꜱᴛ ꜰᴏʀᴍᴀᴛ 👇 -⚜️ ᴇxᴀᴍᴘʟᴇ : Loki S01 or Loki S01E04 or Lucifer S03E24 +⚜ ᴇxᴀᴍᴘʟᴇ : Loki S01 or Loki S01E04 or Lucifer S03E24 🚯 ᴅᴏɴᴛ ᴜꜱᴇ ➠ ':(!,./)""" @@ -168,7 +168,7 @@ class script(object):
📂 ꜰɪʟᴇꜱ ꜰᴏᴜɴᴅ : {} 🔍 ꜱᴇᴀʀᴄʜ : {}
-‼️ ᴛʜɪs ɪs ᴀ sᴜᴘᴘᴏʀᴛ ɢʀᴏᴜᴘ sᴏ ᴛʜᴀᴛ ʏᴏᴜ ᴄᴀɴ'ᴛ ɢᴇᴛ ғɪʟᴇs ғʀᴏᴍ ʜᴇʀᴇ... +‼ ᴛʜɪs ɪs ᴀ sᴜᴘᴘᴏʀᴛ ɢʀᴏᴜᴘ sᴏ ᴛʜᴀᴛ ʏᴏᴜ ᴄᴀɴ'ᴛ ɢᴇᴛ ғɪʟᴇs ғʀᴏᴍ ʜᴇʀᴇ... 📝 ꜱᴇᴀʀᴄʜ ʜᴇʀᴇ : 👇
""" @@ -180,7 +180,7 @@ class script(object): PM_SEARCH_DISABLED_TXT = """🙋 ʜᴇʏ {} 😍, -ʏᴏᴜ ᴄᴀɴ sᴇᴀʀᴄʜ ғᴏʀ ᴍᴏᴠɪᴇs ᴏɴʟʏ ᴏɴ ᴏᴜʀ ᴍᴏᴠɪᴇ ɢʀᴏᴜᴘ. ʏᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴀʟʟᴏᴡᴇᴅ ᴛᴏ sᴇᴀʀᴄʜ ғᴏʀ ᴍᴏᴠɪᴇs ᴏɴ ᴅɪʀᴇᴄᴛ ʙᴏᴛ. ᴘʟᴇᴀsᴇ ᴊᴏɪɴ ᴏᴜʀ ᴍᴏᴠɪᴇ ɢʀᴏᴜᴘ ʙʏ ᴄʟɪᴄᴋɪɴɢ ᴏɴ ᴛʜᴇ ʀᴇǫᴜᴇsᴛ ʜᴇʀᴇ ʙᴜᴛᴛᴏɴ ɢɪᴠᴇɴ ʙᴇʟᴏᴡ ᴀɴᴅ sᴇᴀʀᴄʜ ʏᴏᴜʀ ғᴀᴠᴏʀɪᴛᴇ ᴍᴏᴠɪᴇ ᴛʜᴇʀᴇ 👇 +ʏᴏᴜ ᴄᴀɴ sᴇᴀʀᴄʜ ғᴏʀ ᴍᴏᴠɪᴇs ᴏɴʟʏ ᴏɴ ᴏᴜʀ ᴍᴏᴠɪᴇ ɢʀᴏᴜᴘ. ʏᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴀʟʟᴏᴡᴇᴅ ᴛᴏ sᴇᴀʀᴄʜ ғᴏʀ ᴍᴏᴠɪᴇs ᴏɴ ᴅɪʀᴇᴄᴛ ʙᴏᴛ. ᴘʟᴇᴀsᴇ ᴊᴏɪɴ ᴏᴜʀ ᴍᴏᴠɪᴇ ɢʀᴏᴜᴘ ʙʏ ᴄʟɪᴄᴋɪɴɢ ᴏɴ ᴛʜᴇ ʀᴇǫᴜᴇsᴛ ʜᴇʀᴇ ʙᴜᴛᴛᴏɴ ɢɪᴠᴇɴ ʙᴇʟᴏᴡ ᴀɴᴅ sᴇᴀʀᴄʜ ʏᴏᴜʀ ғᴀᴠᴏᴜʀɪᴛᴇ ᴍᴏᴠɪᴇ ᴛʜᴇʀᴇ 👇
आप केवल हमारे ᴍᴏᴠɪᴇ ɢʀᴏᴜᴘ पर ही ᴍᴏᴠɪᴇ sᴇᴀʀᴄʜ कर सकते हो । @@ -192,7 +192,7 @@ class script(object): 🆔 ɪᴅ : {} 💬 ᴍᴇssᴀɢᴇ : {}""" - LINK_EXPIRED_TXT = """‼️ Lɪɴᴋ ᴇxᴘɪʀᴇᴅ, ᴘʟᴇᴀꜱᴇ ᴛʀʏ ᴀɢᴀɪɴ...""" + LINK_EXPIRED_TXT = """‼ Lɪɴᴋ ᴇxᴘɪʀᴇᴅ, ᴘʟᴇᴀꜱᴇ ᴛʀʏ ᴀɢᴀɪɴ...""" REFER_TXT = """Hᴇʏ, ʏᴏᴜʀ ʀᴇꜰᴇʀ ʟɪɴᴋ: @@ -206,7 +206,7 @@ class script(object): REFER_ALREADY_ALRT = """Yᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ ᴀʟʀᴇᴀᴅʏ ɪɴᴠɪᴛᴇᴅ ❗""" - REFER_ALREADY_JOINED_ALRT = """‼️ Yᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ ᴀʟʀᴇᴀᴅʏ ɪɴᴠɪᴛᴇᴅ ᴏʀ ᴊᴏɪɴᴇᴅ""" + REFER_ALREADY_JOINED_ALRT = """‼ Yᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ ᴀʟʀᴇᴀᴅʏ ɪɴᴠɪᴛᴇᴅ ᴏʀ ᴊᴏɪɴᴇᴅ""" REFER_CONGRATS_ALRT = """🎉 Cᴏɴɢʀᴀᴛᴜʟᴀᴛɪᴏɴs! ʏᴏᴜ ᴡᴏɴ 10 ʀᴇꜰᴇʀʀᴀʟ ᴘᴏɪɴᴛ ʙᴇᴄᴀᴜsᴇ ʏᴏᴜ ʜᴀᴠᴇ ʙᴇᴇɴ sᴜᴄᴄᴇssꜰᴜʟʟʏ ɪɴᴠɪᴛᴇᴅ ☞ {}!""" @@ -218,7 +218,7 @@ class script(object):
👉 Jᴏɪɴ ᴀʟʟ ᴛʜᴇ ʙᴇʟᴏᴡ ᴄʜᴀɴɴᴇʟs ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ.
""" - BOT_ADD_TXT = """Tʜᴀɴᴋ ʏᴏᴜ ғᴏʀ ᴀᴅᴅɪɴɢ ᴍᴇ ᴛᴏ {} ❣️ + BOT_ADD_TXT = """Tʜᴀɴᴋ ʏᴏᴜ ғᴏʀ ᴀᴅᴅɪɴɢ ᴍᴇ ᴛᴏ {} ❣
Iғ ʏᴏᴜ ʜᴀᴠᴇ ᴀɴʏ ǫᴜᴇsᴛɪᴏɴs & ᴅᴏᴜʙᴛs ᴀʙᴏᴜᴛ ᴜsɪɴɢ ᴍᴇ ᴄᴏɴᴛᴀᴄᴛ sᴜᴘᴘᴏʀᴛ.
""" @@ -234,7 +234,7 @@ class script(object): TOP_ALRT_MSG = """Sᴇᴀʀᴄʜɪɴɢ ꜰᴏʀ ǫᴜᴇʀʏ ɪɴ ᴍʏ ᴅᴀᴛᴀʙᴀꜱᴇ...""" - MELCOW_ENG = """👋 Hᴇʏ {},\n\n🍁 ᴡᴇʟᴄᴏᴍᴇ ᴛᴏ\n🌟 {} \n\n🔍 ʜᴇʀᴇ ʏᴏᴜ ᴄᴀɴ ꜱᴇᴀʀᴄʜ ʏᴏᴜʀ ꜰᴀᴠᴏᴜʀɪᴛᴇ ᴍᴏᴠɪᴇꜱ ᴏʀ ꜱᴇʀɪᴇꜱ ʙʏ ᴊᴜꜱᴛ ᴛʏᴘɪɴɢ ɪᴛ'ꜱ ɴᴀᴍᴇ 🔎\n\n⚠️ ɪꜰ ʏᴏᴜ'ʀᴇ ʜᴀᴠɪɴɢ ᴀɴʏ ᴘʀᴏʙʟᴇᴍ ʀᴇɢᴀʀᴅɪɴɢ ᴅᴏᴡɴʟᴏᴀᴅɪɴɢ ᴏʀ ꜱᴏᴍᴇᴛʜɪɴɢ ᴇʟꜱᴇ ᴛʜᴇɴ ᴍᴇꜱꜱᴀɢᴇ ʜᴇʀᴇ 👇""" + MELCOW_ENG = """👋 Hᴇʏ {},\n\n🍁 ᴡᴇʟᴄᴏᴍᴇ ᴛᴏ\n🌟 {} \n\n🔍 ʜᴇʀᴇ ʏᴏᴜ ᴄᴀɴ ꜱᴇᴀʀᴄʜ ʏᴏᴜʀ ꜰᴀᴠᴏᴜʀɪᴛᴇ ᴍᴏᴠɪᴇꜱ ᴏʀ ꜱᴇʀɪᴇꜱ ʙʏ ᴊᴜꜱᴛ ᴛʏᴘɪɴɢ ɪᴛ'ꜱ ɴᴀᴍᴇ 🔎\n\n⚠ ɪꜰ ʏᴏᴜ'ʀᴇ ʜᴀᴠɪɴɢ ᴀɴʏ ᴘʀᴏʙʟᴇᴍ ʀᴇɢᴀʀᴅɪɴɢ ᴅᴏᴡɴʟᴏᴀᴅɪɴɢ ᴏʀ ꜱᴏᴍᴇᴛʜɪɴɢ ᴇʟꜱᴇ ᴛʜᴇɴ ᴍᴇꜱꜱᴀɢᴇ ʜᴇʀᴇ 👇""" DISCLAIMER_TXT = """ ᴛʜɪꜱ ɪꜱ ᴀɴ ᴏᴘᴇɴ ꜱᴏᴜʀᴄᴇ ᴘʀᴏᴊᴇᴄᴛ. @@ -256,7 +256,7 @@ class script(object): ➤ 📷 Qʀ ᴄᴏᴅᴇ → ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ꜱᴄᴀɴ ➤ 💸 ᴜᴘɪ ɪᴅ → {} -‼️ ᴍᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴅᴏɴᴀᴛɪɴɢ.""" +‼ ᴍᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴅᴏɴᴀᴛɪɴɢ.""" @@ -269,21 +269,24 @@ class script(object): Mᴇꜱꜱᴀɢᴇ : {}""" - CAPTION = """{file_name}\n\n⚜️ Powered By : [ ᴅʀᴇᴀᴍxʙᴏᴛᴢ ]""" + CAPTION = """{file_name}\n\n⚜ Powered By : [ ᴅʀᴇᴀᴍxʙᴏᴛᴢ ]""" - + # === UPDATED WITH YOUR DIVIDER AND TITLE OUTSIDE + RUNTIME === MOVIE_UPDATE_NOTIFY_TXT = """ 📥New {tag} Added -
✨ ᴛɪᴛʟᴇ : {filename} {year} +✨ ᴛɪᴛʟᴇ : {filename} {year} +⚬────────✧────────⚬ -🎭 ɢᴇɴʀᴇs : {genres} -📺 ᴏᴛᴛ : {ott} -🎞️ ǫᴜᴀʟɪᴛʏ : {quality} -🎧 ᴀᴜᴅɪᴏ : {language} -🔥 ʀᴀᴛɪɴɢ : {rating} +
🎭 ɢᴇɴʀᴇs : {genres} +📺 ᴏᴛᴛ : {ott} +⏰ ʀᴜɴᴛɪᴍᴇ : {runtime} +🎞 ǫᴜᴀʟɪᴛʏ : {quality} +🎧 ᴀᴜᴅɪᴏ : {language} +🔥 ʀᴀᴛɪɴɢ : {rating}/10 {episodes}
+⚬────────✧────────⚬ 🔍 Sᴇᴀʀᴄʜ → {search_link} """ @@ -295,7 +298,7 @@ class script(object): ɢᴇɴʀᴇ : {genres} ᴀᴜᴅɪᴏ : {languages} -sʜᴏᴡɴ ɪɴ : {remaining_seconds} sᴇᴄ⚡️ +sʜᴏᴡɴ ɪɴ : {remaining_seconds} sᴇᴄ⚡ ʀᴇǫ ʙʏ : {message.from_user.mention}""" LOGO = r""" @@ -313,9 +316,7 @@ class script(object): #PLANS - - - PREMIUM_TEXT = """
🎖️ Aᴠᴀɪʟᴀʙʟᴇ ᴘʟᴀɴs
+ PREMIUM_TEXT = """
🎖 Aᴠᴀɪʟᴀʙʟᴇ ᴘʟᴀɴs
◉ 07 ᴅᴀʏꜱ - 10 ₹ / 10 ꜱᴛᴀʀ @@ -326,8 +327,8 @@ class script(object): •─────•─────────•─────• -‼️ Mᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. -‼️ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇꜱ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" +‼ Mᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. +‼ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇꜱ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" PREMIUM_STAR_TEXT = """
Pᴀʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅ: Tᴇʟᴇɢʀᴀᴍ ꜱᴛᴀʀꜱ ⭐
@@ -346,7 +347,7 @@ class script(object): 💢 ᴍᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. -‼️ ᴀꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴘʟᴇᴀꜱᴇ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.
""" +‼ ᴀꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴘʟᴇᴀꜱᴇ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.
""" PREMIUM_END_TEXT = """ʜᴇʏ {}, @@ -378,12 +379,12 @@ class script(object): •─────•─────────•─────• ◉ ᴄʜᴇᴄᴋ ʏᴏᴜʀ ᴀᴄᴛɪᴠᴇ ᴘʟᴀɴ : /myplan -‼️ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇꜱ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" +‼ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇꜱ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" PREPLANS_TXT = PREMIUM_TXT = """👋 ʜᴇʏ {}, -
🎖️ ᴀᴠᴀɪʟᴀʙʟᴇ ᴘʟᴀɴꜱ
+
🎖 ᴀᴠᴀɪʟᴀʙʟᴇ ᴘʟᴀɴꜱ
◉ 07 ᴅᴀʏꜱ - 10 ₹ ◉ 15 ᴅᴀʏꜱ - 20 ₹ @@ -393,24 +394,22 @@ class script(object): •─────•─────────•─────• -🏷️ Pᴀʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅꜱ - Uᴘɪ +🏷 Pᴀʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅꜱ - Uᴘɪ 💸 Uᴘɪ ɪᴅ → {} 📷 Qʀ ᴄᴏᴅᴇ → ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ꜱᴄᴀɴ 🧾 Pᴀʏ ᴀᴄᴄᴏʀᴅɪɴɢ ᴛᴏ ʏᴏᴜʀ ᴘʟᴀɴ ᴀɴᴅ ᴇɴᴊᴏʏ ᴘʀᴇᴍɪᴜᴍ! -‼️ Mᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. -‼️ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ᴀ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ, ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇ ᴛɪᴍᴇ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴛʜᴇ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ. +‼ Mᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. +‼ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ᴀ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ, ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇ ᴛɪᴍᴇ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴛʜᴇ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ. 💎 Cʜᴇᴄᴋ ʏᴏᴜʀ ᴘʟᴀɴ → /myplan
""" - - VERIFICATION_TEXT = """👋 Hᴇʏ {}, -📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. +📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. #Vᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 1/3 ✓ @@ -425,7 +424,7 @@ class script(object): SECOND_VERIFICATION_TEXT = """👋 ʜᴇʏ {}, -📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. +📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. #Vᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 2/3 ✓ @@ -439,7 +438,7 @@ class script(object): THIRDT_VERIFICATION_TEXT = """👋 ʜᴇʏ {}, -📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. +📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. #Vᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 3/3 ✓ @@ -469,7 +468,7 @@ class script(object): • /del_msg - ʀᴇᴍᴏᴠᴇ ғɪʟᴇ ɴᴀᴍᴇ ᴄᴏʟʟᴇᴄᴛɪᴏɴ ɴᴏтɪғɪᴄᴀᴛɪᴏɴ... • /movie_update - ᴏɴ / ᴏғғ ᴀᴄᴄᴏʀᴅɪɴɢ ᴛᴏ ʏᴏᴜʀ ɴᴇᴇᴅꜱ... • /pm_search - ᴘᴍ sᴇᴀʀᴄʜ ᴏɴ / ᴏғғ ᴀᴄᴄᴏʀᴅɪɴɢ ᴛᴏ ʏᴏᴜʀ ɴᴇᴇᴅꜱ... -• /verify - ᴛᴜʀɴ ᴏɴ / ᴏꜰꜰ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ (ᴏɴʟʏ ᴡᴏʀᴋ ɪɴ ɢʀᴏᴜᴘ) +• /verify - ᴛᴜʀɴ ᴏɴ / ᴏғғ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ (ᴏɴʟʏ ᴡᴏʀᴋ ɪɴ ɢʀᴏᴜᴘ) • /logs - ɢᴇᴛ ᴛʜᴇ ʀᴇᴄᴇɴᴛ ᴇʀʀᴏʀꜱ. • /delete - ᴅᴇʟᴇᴛᴇ ᴀ ꜱᴘᴇᴄɪꜰɪᴄ ꜰɪʟᴇ ꜰʀᴏᴍ ᴅʙ. • /users - ɢᴇᴛ ʟɪꜱᴛ ᴏꜰ ᴍʏ ᴜꜱᴇʀꜱ ᴀɴᴅ ɪᴅꜱ. From f4e9edf3486dec471145482164701eab08598a95 Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Thu, 24 Sep 2026 20:13:25 +0530 Subject: [PATCH 74/77] Refine quality extraction in get_qualities function Updated the get_qualities function to refine quality extraction, including new patterns and sorting logic. --- plugins/channel.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/plugins/channel.py b/plugins/channel.py index aa736b85..9ed4a0fd 100644 --- a/plugins/channel.py +++ b/plugins/channel.py @@ -141,20 +141,23 @@ def clean_words(s: str): return False def get_qualities(text: str) -> str: - # Enhanced: keep original but uppercase and include x264/x265 if not text: return "N/A" - quals = QUALITY_PATTERN.findall(text) - extra = re.findall(r'\b(?:x264|x265|hevc|10bit|bluray|blu-ray)\b', text, re.IGNORECASE) - all_q = quals + extra - # Uppercase and dedup + quals = re.findall(r'(?:480p|720p|1080p|2160p|4K|WEB-DL|WEBRip|BluRay|HDRip)', text, re.IGNORECASE) seen = set() result = [] - for q in all_q: + for q in quals: q_up = q.upper() + # Normalize + if q_up == "WEBRIP": + q_up = "WEBRip" + if q_up == "WEB-DL": + q_up = "WEB-DL" if q_up.lower() not in seen: seen.add(q_up.lower()) result.append(q_up) + order = {"480P":0, "720P":1, "1080P":2, "2160P":3, "4K":4, "WEB-DL":5, "WEBRIP":6, "BLURAY":7, "HDRIP":8} + result.sort(key=lambda x: order.get(x.upper(), 99)) return ", ".join(result) if result else "N/A" def extract_ott_platform(text: str) -> str: @@ -649,7 +652,7 @@ def generate_movie_message(movie_doc, grouping_id): episode_lines.append(f"S{int(season)}: {', '.join(all_ep_parts)}") epi_str = "\n".join(episode_lines) if epi_str: - epi_block = f"📺 ᴇᴘɪsᴏᴅᴇs : \n{epi_str}" + epi_block = f"📺 ᴇᴘɪsᴏᴅᴇs : {epi_str}" genres = movie_doc.get("genres", "N/A") quality_str = ", ".join(sorted(all_qualities)) if all_qualities else "N/A" language_str = ", ".join(sorted(all_languages)) if all_languages else "N/A" From f2d40db46e7b72f3306da844e80c9c51ca46226d Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Thu, 24 Sep 2026 20:13:53 +0530 Subject: [PATCH 75/77] Preserve original HD quality for poster and backdrop URLs --- plugins/Dreamxfutures/Imdbposter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Dreamxfutures/Imdbposter.py b/plugins/Dreamxfutures/Imdbposter.py index ee13a68a..af3e3825 100644 --- a/plugins/Dreamxfutures/Imdbposter.py +++ b/plugins/Dreamxfutures/Imdbposter.py @@ -607,7 +607,7 @@ async def get_movie_detailsx(query, id=False, file=None): # Season poster priority if data.get('season_poster'): poster_url = data.get('season_poster') - details['poster_url'] = poster_url.replace("/original/", "/w1280/") if poster_url else None + details['poster_url'] = poster_url # keep original HD # If still no poster, try Blogger then PosterFlix if not details['poster_url']: @@ -626,5 +626,5 @@ async def get_movie_detailsx(query, id=False, file=None): if key and backdrops.get(key): backdrop_url = backdrops[key][0] break - details['backdrop_url'] = backdrop_url.replace("/original/", "/w1280/") if backdrop_url else None + details['backdrop_url'] = backdrop_url # keep original HD return details From fc3cca5b7d8c2463d07acf73dd63a34355bd085c Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Thu, 24 Sep 2026 20:14:32 +0530 Subject: [PATCH 76/77] Update Script.py --- Script.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Script.py b/Script.py index a5a36def..7503d40d 100644 --- a/Script.py +++ b/Script.py @@ -277,7 +277,6 @@ class script(object): ✨ ᴛɪᴛʟᴇ : {filename} {year} ⚬────────✧────────⚬ -
🎭 ɢᴇɴʀᴇs : {genres} 📺 ᴏᴛᴛ : {ott} ⏰ ʀᴜɴᴛɪᴍᴇ : {runtime} @@ -287,7 +286,6 @@ class script(object): {episodes}
⚬────────✧────────⚬ - 🔍 Sᴇᴀʀᴄʜ → {search_link} """ From 794a06b38b2ac68cf9bc71960b3282fb4d9dd8ef Mon Sep 17 00:00:00 2001 From: ab9816892-dot Date: Thu, 24 Sep 2026 21:06:08 +0530 Subject: [PATCH 77/77] Update channel.py --- plugins/channel.py | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/plugins/channel.py b/plugins/channel.py index 9ed4a0fd..55bce057 100644 --- a/plugins/channel.py +++ b/plugins/channel.py @@ -12,6 +12,12 @@ from Script import script from database.ia_filterdb import save_file from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, LinkPreviewOptions +try: + from pyrogram.types import KeyboardButtonStyle + HAS_STYLED = True +except ImportError: + KeyboardButtonStyle = None + HAS_STYLED = False from utils import temp from pymongo.errors import PyMongoError, DuplicateKeyError from pyrogram.errors import MessageIdInvalid, MessageNotModified, FloodWait @@ -486,14 +492,13 @@ async def send_movie_update(bot, grouping_id): return None text = generate_movie_message(movie_doc, grouping_id) is_series = movie_doc.get("tag") == "#SERIES" or any(f.get("season") for f in movie_doc.get("files", [])) - btn_text = "🔵 ɢᴇᴛ ғɪʟᴇs" if is_series else "🟢 ɢᴇᴛ ғɪʟᴇs" - buttons = InlineKeyboardMarkup([[ - InlineKeyboardButton( - btn_text, - url=f"https://t.me/{temp.U_NAME}?start=getfile-{grouping_id.replace(' ', '-')}" - ) - ]]) - size=(2560, 1440) if LANDSCAPE_POSTER and TMDB_POSTER and movie_doc.get("is_backdrop") and not movie_doc.get("error_tmdb") else (853, 1280) + btn_text = "ɢᴇᴛ ғɪʟᴇs" + if HAS_STYLED and KeyboardButtonStyle: + bstyle = KeyboardButtonStyle(bg_primary=True) if is_series else KeyboardButtonStyle(bg_success=True) + buttons = InlineKeyboardMarkup([[InlineKeyboardButton(btn_text, url=f"https://t.me/{temp.U_NAME}?start=getfile-{grouping_id.replace(' ', '-')}", style=bstyle)]]) + else: + buttons = InlineKeyboardMarkup([[InlineKeyboardButton(btn_text, url=f"https://t.me/{temp.U_NAME}?start=getfile-{grouping_id.replace(' ', '-')}")]]) + size=(2560, 1440) if LANDSCAPE_POSTER else (1280, 1920) if movie_doc.get("poster_url") and not LINK_PREVIEW: resized_poster = await fetch_image(movie_doc["poster_url"], size) if resized_poster: @@ -547,13 +552,12 @@ async def update_movie_message(bot, grouping_id): return text = generate_movie_message(movie_doc, grouping_id) is_series = movie_doc.get("tag") == "#SERIES" or any(f.get("season") for f in movie_doc.get("files", [])) - btn_text = "🔵 ɢᴇᴛ ғɪʟᴇs" if is_series else "🟢 ɢᴇᴛ ғɪʟᴇs" - buttons = InlineKeyboardMarkup([[ - InlineKeyboardButton( - btn_text, - url=f"https://t.me/{temp.U_NAME}?start=getfile-{grouping_id.replace(' ', '-')}" - ) - ]]) + btn_text = "ɢᴇᴛ ғɪʟᴇs" + if HAS_STYLED and KeyboardButtonStyle: + bstyle = KeyboardButtonStyle(bg_primary=True) if is_series else KeyboardButtonStyle(bg_success=True) + buttons = InlineKeyboardMarkup([[InlineKeyboardButton(btn_text, url=f"https://t.me/{temp.U_NAME}?start=getfile-{grouping_id.replace(' ', '-')}", style=bstyle)]]) + else: + buttons = InlineKeyboardMarkup([[InlineKeyboardButton(btn_text, url=f"https://t.me/{temp.U_NAME}?start=getfile-{grouping_id.replace(' ', '-')}")]]) message_id = movie_doc.get("message_id") is_photo = movie_doc.get("is_photo", False) if not message_id: