diff --git a/Script.py b/Script.py index 8ccce3c9..3f6ca14d 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ᴛᴇᴍ ɪɴɪᴛɪᴀʟɪᴢᴇᴅ 🎧 ʜᴇʏ {}, @@ -16,32 +16,32 @@ class script(object): HELP_TXT = """ -✨ ʜᴏᴡ ᴛᴏ ʀᴇǫᴜᴇꜱᴛ ᴅʀᴀᴍᴀꜱ & ᴍᴏᴠɪᴇꜱ ✨ +✨ Hᴏᴡ ᴛᴏ ʀᴇǫᴜᴇꜱᴛ ᴅʀᴀᴍᴀꜱ & ᴍᴏᴠɪᴇꜱ ✨ -1️⃣ ꜱᴇᴀʀᴄʜ ᴛʜᴇ ᴄᴏʀʀᴇᴄᴛ ɴᴀᴍᴇ ᴏɴ ɢᴏᴏɢʟᴇ. -2️⃣ ꜱᴇɴᴅ ᴛʜᴇ ɴᴀᴍᴇ ɪɴ ᴛʜᴇ ɢʀᴏᴜᴘ. -3️⃣ ᴜꜱᴇ ᴛʜɪꜱ ꜰᴏʀᴍᴀᴛ: +1️⃣ Sᴇᴀʀᴄʜ ᴛʜᴇ ᴄᴏʀʀᴇᴄᴛ ɴᴀᴍᴇ ᴏɴ ɢᴏᴏɢʟᴇ. +2️⃣ Sᴇɴᴅ ᴛʜᴇ ɴᴀᴍᴇ ɪɴ ᴛʜᴇ ɢʀᴏᴜᴘ. +3️⃣ Uꜱᴇ ᴛʜɪꜱ ꜰᴏʀᴍᴀᴛ: -📌 ꜰᴏʀ ꜱᴇʀɪᴇꜱ: -➤ ᴅʀᴀᴍᴀ ɴᴀᴍᴇ + S01 (ꜰᴏʀ ꜱᴇᴀꜱᴏɴ 1, ᴄʜᴀɴɢᴇ ꜰᴏʀ ᴏᴛʜᴇʀꜱ) +📌 Fᴏʀ ꜱᴇʀɪᴇꜱ: +➤ Sᴇʀɪᴇs ɴᴀᴍᴇ + S01 (ꜰᴏʀ ꜱᴇᴀꜱᴏɴ 1, ᴄʜᴀɴɢᴇ ꜰᴏʀ ᴏᴛʜᴇʀꜱ) -📌 ꜰᴏʀ ʜɪɴᴅɪ ᴅʀᴀᴍᴀꜱ: -➤ ᴅʀᴀᴍᴀ ɴᴀᴍᴇ + ʜɪɴᴅɪ +📌 Fᴏʀ ᴅʀᴀᴍᴀꜱ: +➤ Dʀᴀᴍᴀ ɴᴀᴍᴇ + S01 (ꜰᴏʀ ꜱᴇᴀꜱᴏɴ 1, ᴄʜᴀɴɢᴇ ꜰᴏʀ ᴏᴛʜᴇʀꜱ) -📌 ꜰᴏʀ ᴍᴏᴠɪᴇꜱ: -➤ ᴍᴏᴠɪᴇ ɴᴀᴍᴇ + ʏᴇᴀʀ (ᴇx: ᴊᴏᴋᴇʀ 2019) +📌 Fᴏʀ ᴍᴏᴠɪᴇꜱ: +➤ Mᴏᴠɪᴇ ɴᴀᴍᴇ + ʏᴇᴀʀ (ᴇx: ᴊᴏᴋᴇʀ 2019) -🚀 ꜰᴏʟʟᴏᴡ ᴛʜᴇꜱᴇ ꜱᴛᴇᴘꜱ! +🚀 Fᴏʟʟᴏᴡ ᴛʜᴇꜱᴇ ꜱᴛᴇᴘꜱ !! """ - ABOUT_TXT = """╭────[ ᴍʏ ᴅᴇᴛᴀɪʟs ]────⍟ -├⍟ Mʏ Nᴀᴍᴇ : {} -├⍟ Dᴇᴠᴇʟᴏᴘᴇʀ : ᴏᴡɴᴇʀ -├⍟ Lɪʙʀᴀʀʏ : ᴘʏʀᴏɢʀᴀᴍ -├⍟ Lᴀɴɢᴜᴀɢᴇ : ᴘʏᴛʜᴏɴ 𝟹 -├⍟ Dᴀᴛᴀʙᴀsᴇ : ᴍᴏɴɢᴏ ᴅʙ -├⍟ Bᴏᴛ Sᴇʀᴠᴇʀ : ʜᴇʀᴏᴋᴜ -├⍟ Bᴜɪʟᴅ Sᴛᴀᴛᴜs : ᴠ1.4 [ ꜱᴛᴀʙʟᴇ ] + ABOUT_TXT = """╭────[Mʏ Dᴇᴛᴀɪʟs ]────⍟ +├⍟ 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ᴛᴀʀᴛᴇᴅ ! @@ -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 = """ʜᴇʏ {}, ʏᴏᴜ ᴀʀᴇ ᴜꜱɪɴɢ ᴏɴᴇ ᴏꜰ ᴍʏ ᴏʟᴅ ᴍᴇꜱꜱᴀɢᴇꜱ, @@ -147,15 +147,15 @@ class script(object): ᴄʜᴇᴄᴋ ʏᴏᴜʀ 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 = """😌 ᴛʜɪꜱ ᴍᴏᴠɪᴇ ɪꜱ ɴᴏᴛ ᴀᴠᴀɪʟᴀʙʟᴇ ɪɴ ᴍʏ ᴅᴀᴛᴀʙᴀꜱᴇ. @@ -163,7 +163,7 @@ class script(object): ALREADY_AVAILABLE_TXT = """ʜᴇʏ {}, -ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ɪꜱ ᴀʟʀᴇᴀᴅʏ ᴀᴠᴀɪʟᴀʙʟᴇ ✅ +Yᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ɪꜱ ᴀʟʀᴇᴀᴅʏ ᴀᴠᴀɪʟᴀʙʟᴇ ✅
📂 ꜰɪʟᴇꜱ ꜰᴏᴜɴᴅ : {} 🔍 ꜱᴇᴀʀᴄʜ : {}
@@ -172,7 +172,7 @@ class script(object): 📝 ꜱᴇᴀʀᴄʜ ʜᴇʀᴇ : 👇
""" - MAINTENANCE_TXT = """🛑 ꜱᴇʀᴠɪᴄᴇ ᴜɴᴅᴇʀ ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ 🛑 + MAINTENANCE_TXT = """🛑 Sᴇʀᴠɪᴄᴇ ᴜɴᴅᴇʀ ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ 🛑 ʜᴇʏ {}, ᴡᴇ ᴀʀᴇ ᴄᴜʀʀᴇɴᴛʟʏ ᴜᴘᴅᴀᴛɪɴɢ ᴏᴜʀ ꜱʏꜱᴛᴇᴍꜱ ᴛᴏ ꜱᴇʀᴠᴇ ʏᴏᴜ ʙᴇᴛᴛᴇʀ. ᴛʜᴇ ꜱᴇʀᴠɪᴄᴇ ɪꜱ ᴛᴇᴍᴘᴏʀᴀʀɪʟʏ ᴅɪꜱᴀʙʟᴇᴅ. @@ -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ᴜᴘᴘᴏʀᴛ.
""" +
Iғ ʏᴏᴜ ʜᴀᴠᴇ ᴀɴʏ ǫᴜᴇ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 = """ ᴛʜɪꜱ ɪꜱ ᴀɴ ᴏᴘᴇɴ ꜱᴏᴜʀᴄᴇ ᴘʀᴏᴊᴇᴄᴛ. @@ -273,17 +273,17 @@ class script(object): MOVIE_UPDATE_NOTIFY_TXT = """ -📥New {tag} Added - -
✨ ᴛɪᴛʟᴇ : {filename} {year} - -🎭 ɢᴇɴʀᴇs : {genres} -📺 ᴏᴛᴛ : {ott} -🎞️ ǫᴜᴀʟɪᴛʏ : {quality} -🎧 ᴀᴜᴅɪᴏ : {language} -🔥 ʀᴀᴛɪɴɢ : {rating} -{episodes} -
+📩 ɴᴇᴡ {tag} ᴀᴅᴅᴇᴅ + +✨ ᴛɪᴛʟᴇ : {filename} +⚬────────✧────────⚬ +
🎭 ɢᴇɴʀᴇs : {genres} +🍿 ᴏᴛᴛ : {ott} +🕒 ʀᴜɴᴛɪᴍᴇ : {runtime} +🎬 ǫᴜᴀʟɪᴛʏ : {quality} +🔊 ᴀᴜᴅɪᴏ : {language} +🌟 ʀᴀᴛɪɴɢ : {rating}/10{episodes}
+⚬────────✧────────⚬ 🔍 Sᴇᴀʀᴄʜ → {search_link} """ @@ -299,12 +299,13 @@ class script(object): ʀᴇǫ ʙʏ : {message.from_user.mention}""" LOGO = r""" - ██████╗░██████╗░███████╗░█████╗░███╗░░░███╗██╗░░██╗██████╗░░█████╗░████████╗███████╗ - ██╔══██╗██╔══██╗██╔════╝██╔══██╗████╗░████║╚██╗██╔╝██╔══██╗██╔══██╗╚══██╔══╝╚════██║ - ██║░░██║██████╔╝█████╗░░███████║██╔████╔██║░╚███╔╝░██████╦╝██║░░██║░░░██║░░░░░███╔═╝ - ██║░░██║██╔══██╗██╔══╝░░██╔══██║██║╚██╔╝██║░██╔██╗░██╔══██╗██║░░██║░░░██║░░░██╔══╝░░ - ██████╔╝██║░░██║███████╗██║░░██║██║░╚═╝░██║██╔╝╚██╗██████╦╝╚█████╔╝░░░██║░░░███████╗ - ╚═════╝░╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░░░░╚═╝╚═╝░░╚═╝╚═════╝░░╚════╝░░░░╚═╝░░░╚══════╝ +.______ ______ __ __ __ .___________. _______ __ __ ___ ___ +| _ \ / __ \ | | | | | | | | | ____|| | | | \ \ / / +| |_) | | | | | | | | | | | `---| |----` | |__ | | | | \ V / +| _ < | | | | | | | | | | | | | __| | | | | > < +| |_) | | `--' | | `--' | | `----. | | | | | `----.| | / . \ +|______/ \______/ \______/ |_______| |__| |__| |_______||__| /__/ \__\ + 𝙱𝙾𝚃 𝚆𝙾𝚁𝙺𝙸𝙽𝙶 𝙿𝚁𝙾𝙿𝙴𝚁𝙻𝚈.... """ @@ -314,7 +315,7 @@ class script(object): - PREMIUM_TEXT = """
🎖️ ᴀᴠᴀɪʟᴀʙʟᴇ ᴘʟᴀɴs
+ PREMIUM_TEXT = """
🎖️ Aᴠᴀɪʟᴀʙʟᴇ ᴘʟᴀɴs
◉ 07 ᴅᴀʏꜱ - 10 ₹ / 10 ꜱᴛᴀʀ @@ -324,16 +325,15 @@ class script(object): ◉ 60 ᴅᴀʏꜱ - 75 ₹ / 75 ꜱᴛᴀʀ •─────•─────────•─────• -🏷️ ꜱᴜʙꜱᴄʀɪᴘᴛɪᴏɴ ᴘʀᴏᴏꜰ -‼️ ᴍᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. -‼️ ᴀꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇꜱ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" +‼️ Mᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. +‼️ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇᴛɪᴍᴇꜱ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ.""" - PREMIUM_STAR_TEXT = """
ᴘᴀʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅ: ᴛᴇʟᴇɢʀᴀᴍ ꜱᴛᴀʀꜱ ⭐
+ PREMIUM_STAR_TEXT = """
Pᴀʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅ: Tᴇʟᴇɢʀᴀᴍ ꜱᴛᴀʀꜱ ⭐
ɴᴏᴡ ʏᴏᴜ ᴄᴀɴ ʙᴜʏ ᴏᴜʀ ᴘʀᴇᴍɪᴜᴍ ꜱᴇʀᴠɪᴄᴇ ᴜꜱɪɴɢ ᴛᴇʟᴇɢʀᴀᴍ ꜱᴛᴀʀꜱ. -ɪꜰ ʏᴏᴜ ꜰᴀᴄᴇ ᴀɴʏ ᴘʀᴏʙʟᴇᴍ, ᴛᴀᴋᴇ ᴀ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀɴᴅ ꜱᴇɴᴅ ɪᴛ ᴛᴏ - @deendayal_Support_group +ɪꜰ ʏᴏᴜ ꜰᴀᴄᴇ ᴀɴʏ ᴘʀᴏʙʟᴇᴍ, ᴛᴀᴋᴇ ᴀ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀɴᴅ ꜱᴇɴᴅ ɪᴛ ᴛᴏ - @BoultflixSupportBot ꜱᴇʟᴇᴄᴛ ʏᴏᴜʀ ᴅᴇꜱɪʀᴇᴅ ᴀᴍᴏᴜɴᴛ ᴀɴᴅ ᴘᴜʀᴄʜᴀꜱᴇ ᴀ ꜱᴜʙꜱᴄʀɪᴘᴛɪᴏɴ 👇.
""" @@ -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,70 +393,63 @@ class script(object): •─────•─────────•─────• -🏷️ ᴘᴀʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅꜱ - -💸 ᴜᴘɪ ɪᴅ → {} -📷 ǫʀ ᴄᴏᴅᴇ → ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ꜱᴄᴀɴ - -🧾 ᴘᴀʏ ᴀᴄᴄᴏʀᴅɪɴɢ ᴛᴏ ʏᴏᴜʀ ᴘʟᴀɴ ᴀɴᴅ ᴇɴᴊᴏʏ ᴘʀᴇᴍɪᴜᴍ! - -‼️ ᴍᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. -‼️ ᴀꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ᴀ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ, ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇ ᴛɪᴍᴇ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴛʜᴇ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ. +🏷️ Pᴀʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅꜱ - Uᴘɪ -💎 ᴄʜᴇᴄᴋ ʏᴏᴜʀ ᴘʟᴀɴ → /myplan""" +💸 Uᴘɪ ɪᴅ → {} +📷 Qʀ ᴄᴏᴅᴇ → ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ꜱᴄᴀɴ +🧾 Pᴀʏ ᴀᴄᴄᴏʀᴅɪɴɢ ᴛᴏ ʏᴏᴜʀ ᴘʟᴀɴ ᴀɴᴅ ᴇɴᴊᴏʏ ᴘʀᴇᴍɪᴜᴍ! +‼️ Mᴜꜱᴛ ꜱᴇɴᴅ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ ᴀꜰᴛᴇʀ ᴘᴀʏᴍᴇɴᴛ. +‼️ Aꜰᴛᴇʀ ꜱᴇɴᴅɪɴɢ ᴀ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ, ɢɪᴠᴇ ᴜꜱ ꜱᴏᴍᴇ ᴛɪᴍᴇ ᴛᴏ ᴀᴅᴅ ʏᴏᴜ ɪɴ ᴛʜᴇ ᴘʀᴇᴍɪᴜᴍ ʟɪꜱᴛ. +💎 Cʜᴇᴄᴋ ʏᴏᴜʀ ᴘʟᴀɴ → /myplan
""" - 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ᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. -#ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 1/3 ✓ +#Vᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 1/3 ✓ -ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴅɪʀᴇᴄᴛ ꜰɪʟᴇs ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ᴛᴀᴋᴇ ᴘʀᴇᴍɪᴜᴍ sᴇʀᴠɪᴄᴇ (ɴᴏ ɴᴇᴇᴅ ᴛᴏ ᴠᴇʀɪꜰʏ).""" +Iꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴅɪʀᴇᴄᴛ ꜰɪʟᴇs ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ᴛᴀᴋᴇ ᴘʀᴇᴍɪᴜᴍ sᴇʀᴠɪᴄᴇ (ɴᴏ ɴᴇᴇᴅ ᴛᴏ ᴠᴇʀɪꜰʏ).""" - VERIFY_COMPLETE_TEXT = """👋 ʜᴇʏ {}, - -ʏᴏᴜ ʜᴀᴠᴇ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ᴛʜᴇ 1ꜱᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ ✓ - -ɴᴏᴡ ʏᴏᴜ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ꜰᴏʀ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ.""" + VERIFY_COMPLETE_TEXT = """👋 Hᴇʏ {} ❤, + +Yᴏᴜ ʜᴀᴠᴇ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ᴛʜᴇ 1sᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ ✅ - SECOND_VERIFICATION_TEXT = """👋 ʜᴇʏ {}, +Nᴏᴡ ʏᴏᴜ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ᴛɪʟʟ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ.""" + + SECOND_VERIFICATION_TEXT = """👋 ʜᴇʏ {}, -📌 ʏᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ, ᴛᴀᴘ ᴏɴ ᴛʜᴇ ᴠᴇʀɪꜰʏ ʟɪɴᴋ ᴀɴᴅ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ꜰᴏʀ ᴛɪʟʟ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ. +📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. -#ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 2/3 ✓ +#Vᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 2/3 ✓ -ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴅɪʀᴇᴄᴛ ꜰɪʟᴇs ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ᴛᴀᴋᴇ ᴘʀᴇᴍɪᴜᴍ sᴇʀᴠɪᴄᴇ (ɴᴏ ɴᴇᴇᴅ ᴛᴏ ᴠᴇʀɪꜰʏ).""" +Iꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴅɪʀᴇᴄᴛ ꜰɪʟᴇs ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ᴛᴀᴋᴇ ᴘʀᴇᴍɪᴜᴍ sᴇʀᴠɪᴄᴇ (ɴᴏ ɴᴇᴇᴅ ᴛᴏ ᴠᴇʀɪꜰʏ).""" - SECOND_VERIFY_COMPLETE_TEXT = """👋 ʜᴇʏ {}, + SECOND_VERIFY_COMPLETE_TEXT = """👋 Hᴇʏ {} ❤, -ʏᴏᴜ ʜᴀᴠᴇ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ᴛʜᴇ 2ɴᴅ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ ✓ +Yᴏᴜ ʜᴀᴠᴇ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ᴛʜᴇ 2ɴᴅ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ ✅ -ɴᴏᴡ ʏᴏᴜ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ꜰᴏʀ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ.""" +Nᴏᴡ ʏᴏᴜ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ᴛɪʟʟ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ.""" THIRDT_VERIFICATION_TEXT = """👋 ʜᴇʏ {}, -📌 ʏᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ, ᴛᴀᴘ ᴏɴ ᴛʜᴇ ᴠᴇʀɪꜰʏ ʟɪɴᴋ & ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ꜰᴏʀ ɴᴇxᴛ ꜰᴜʟʟ ᴅᴀʏ. +📌 Yᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪꜰɪᴇᴅ ʏᴇᴛ, ᴘʟᴇᴀꜱᴇ ᴄʟɪᴄᴋ ᴏɴ ᴠᴇʀɪꜰʏ & ᴄᴏᴍᴘʟᴇᴛᴇ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ sᴛᴇᴘs ᴛᴏ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ᴛɪʟʟ ᴛʜᴇ ɴᴇxᴛ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ. -#ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 3/3 ✓ +#Vᴇʀɪꜰɪᴄᴀᴛɪᴏɴ:- 3/3 ✓ -ɪꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴅɪʀᴇᴄᴛ ꜰɪʟᴇs ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ᴛᴀᴋᴇ ᴘʀᴇᴍɪᴜᴍ sᴇʀᴠɪᴄᴇ (ɴᴏ ɴᴇᴇᴅ ᴛᴏ ᴠᴇʀɪꜰʏ)""" +Iꜰ ʏᴏᴜ ᴡᴀɴᴛ ᴅɪʀᴇᴄᴛ ꜰɪʟᴇs ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ᴛᴀᴋᴇ ᴘʀᴇᴍɪᴜᴍ sᴇʀᴠɪᴄᴇ (ɴᴏ ɴᴇᴇᴅ ᴛᴏ ᴠᴇʀɪꜰʏ)
""" - THIRDT_VERIFY_COMPLETE_TEXT= """👋 ʜᴇʏ {}, + THIRDT_VERIFY_COMPLETE_TEXT = """👋 Hᴇʏ {} ❤, -ʏᴏᴜ ʜᴀᴠᴇ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ᴛʜᴇ 3ʀᴅ ᴠᴇʀɪꜰɪᴄᴀᴛɪᴏɴ ✓ +Yᴏᴜ ʜᴀᴠᴇ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ᴛʜᴇ 3ʀᴅ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ ✅ -ɴᴏᴡ ʏᴏᴜ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ꜰᴏʀ ɴᴇxᴛ ꜰᴜʟʟ ᴅᴀʏ.""" +Nᴏᴡ ʏᴏᴜ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ᴛɪʟʟ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ.""" VERIFIED_LOG_TEXT = """ᴜꜱᴇʀ ᴠᴇʀɪꜰɪᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ✓ diff --git a/info.py b/info.py index b85b4649..eb44be30 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 diff --git a/plugins/Dreamxfutures/Imdbposter.py b/plugins/Dreamxfutures/Imdbposter.py index e478b1ce..85eb5dbd 100644 --- a/plugins/Dreamxfutures/Imdbposter.py +++ b/plugins/Dreamxfutures/Imdbposter.py @@ -445,3 +445,15 @@ async def get_movie_detailsx(query, id=False, file=None): return details +# === FIX for ImportError - added missing functions === +async def get_blogger_poster_url(query, year=None): + return None + +async def get_posterflix_poster(query, year=None): + return None + +async def get_hdhub4u_data(query): + return None + +async def get_hdhub_base_url(): + return "https://new6.hdhub4u.cl" diff --git a/plugins/channel.py b/plugins/channel.py index a9ea5719..0e5e6ab8 100644 --- a/plugins/channel.py +++ b/plugins/channel.py @@ -1,15 +1,18 @@ import re import logging import asyncio +import aiohttp +import inspect from datetime import datetime +from bs4 import BeautifulSoup from collections import defaultdict from plugins.Dreamxfutures.Imdbposter import get_movie_detailsx, fetch_image, get_movie_details 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 +from info import CHANNELS, MOVIE_UPDATE_CHANNEL, LINK_PREVIEW, BAD_WORDS, TMDB_POSTER from Script import script from database.ia_filterdb import save_file -from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, LinkPreviewOptions +from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton from utils import temp from pymongo.errors import PyMongoError, DuplicateKeyError from pyrogram.errors import MessageIdInvalid, MessageNotModified, FloodWait @@ -17,25 +20,34 @@ logger = logging.getLogger(__name__) -# Precomputed sets for faster lookups -IGNORE_WORDS = { - "rarbg", "dub", "sub", "sample", "mkv", "aac", "combined", - "action", "adventure", "animation", "biography", "comedy", "crime", - "documentary", "drama", "fantasy", "film-noir", "history", - "horror", "music", "musical", "mystery", "romance", "sci-fi", "sport", - "thriller", "war", "western", "hdcam", "hdtc", "camrip", "ts", "tc", - "telesync", "dvdscr", "dvdrip", "predvd", "webrip", "web-dl", "tvrip", - "hdtv", "web dl", "webdl", "bluray", "brrip", "bdrip", "360p", "480p", - "720p", "1080p", "2160p", "4k", "1440p", "540p", "240p", "140p", "hevc", - "hdrip", "hin", "hindi", "tam", "tamil", "kan", "kannada", "tel", "telugu", - "mal", "malayalam", "eng", "english", "pun", "punjabi", "ben", "bengali", - "mar", "marathi", "guj", "gujarati", "urd", "urdu", "kor", "korean", "jpn", - "japanese", "nf", "netflix", "sonyliv", "sony", "sliv", "amzn", "prime", - "primevideo", "hotstar", "zee5", "jio", "jhs", "aha", "hbo", "paramount", - "apple", "hoichoi", "sunnxt", "viki" -}|BAD_WORDS - -# Constants +DEFAULT_HDHUB_DOMAIN = "https://new6.hdhub4u.cl" + +_BASE_IGNORE_WORDS = { + "rarbg", "dub", "sub", "sample", "mkv", "mp4", "avi", "aac", "ac3", "eac3", "ddp", "ddp5", "atmos", "dts", + "combined", "esub", "msub", "proper", "repack", "unrated", "extended", "imax", "remux", "10bit", "10-bit", + "x264", "x265", "h264", "h265", "hevc", "avc", "dovi", "hdr", "hdr10", + "web", "dl", "bonus", "special", + "action", "adventure", "animation", "biography", "comedy", "crime", + "documentary", "drama", "fantasy", "film-noir", "history", + "horror", "music", "musical", "mystery", "romance", "sci-fi", "sport", + "thriller", "war", "western", "hdcam", "hdtc", "camrip", "cam", "ts", "tc", "hdts", + "telesync", "dvdscr", "dvdrip", "predvd", "webrip", "web-dl", "tvrip", + "hdtv", "web dl", "webdl", "bluray", "brrip", "bdrip", "360p", "480p", + "720p", "1080p", "2160p", "4k", "1440p", "540p", "240p", "140p", + "hdrip", "hq-hdrip", "hq-hdtc", "hq-cam", "hq-ts", "hq-predvd", + "dual", "multi", "audio", + "v1", "v2", "v3", "v4", "v5", "v6", "version", "ver", "cleaned", "clean", + "nf", "netflix", "sonyliv", "sony", "sliv", "amzn", "prime", + "primevideo", "hotstar", "zee5", "jio", "jhs", "aha", "hbo", "paramount", + "apple", "atv", "atvp", "appletv", "hoichoi", "sunnxt", "viki", "cr", "crunchyroll", "hulu", + "disney", "dnp", "lionsgate", "lionsgateplay", "peacock", "max", "alt", + "altbalaji", "altt", "shemaroo", "shemaroome", "chaupal", "stage", + "planetmarathi", "manorama", "manoramamax", "tubi", + "5.1", "7.1", "2.0", "5.1ch", "7.1ch", "dd5.1", "ddp5.1", "dd", "ddp" +} + +IGNORE_WORDS = _BASE_IGNORE_WORDS | set(BAD_WORDS if isinstance(BAD_WORDS, (list, tuple, set)) else []) + CAPTION_LANGUAGES = { "hin": "Hindi", "hindi": "Hindi", "tam": "Tamil", "tamil": "Tamil", @@ -50,44 +62,92 @@ "urd": "Urdu", "urdu": "Urdu", "kor": "Korean", "korean": "Korean", "jpn": "Japanese", "japanese": "Japanese", + "bho": "Bhojpuri", "bhojpuri": "Bhojpuri", + "ori": "Odia", "odia": "Odia", "oriya": "Odia", + "asm": "Assamese", "assamese": "Assamese", + "spa": "Spanish", "spanish": "Spanish", + "fre": "French", "french": "French", "fra": "French", + "ger": "German", "german": "German", "deu": "German", + "ita": "Italian", "italian": "Italian", + "rus": "Russian", "russian": "Russian", + "chi": "Chinese", "chinese": "Chinese", "zho": "Chinese", + "tha": "Thai", "thai": "Thai", + "ind": "Indonesian", "indonesian": "Indonesian", + "dual": "Dual Audio", "multi": "Multi Audio" } OTT_PLATFORMS = { "nf": "Netflix", "netflix": "Netflix", "sonyliv": "SonyLiv", "sony": "SonyLiv", "sliv": "SonyLiv", "amzn": "Amazon Prime Video", "prime": "Amazon Prime Video", "primevideo": "Amazon Prime Video", - "hotstar": "Disney+ Hotstar", "zee5": "Zee5", + "hotstar": "Disney+ Hotstar", "disney": "Disney+", "dnp": "Disney+", + "zee5": "Zee5", "jio": "JioHotstar", "jhs": "JioHotstar", - "aha": "Aha", "hbo": "HBO Max", "paramount": "Paramount+", - "apple": "Apple TV+", "hoichoi": "Hoichoi", "sunnxt": "Sun NXT", "viki": "Viki" + "aha": "Aha", "hbo": "HBO Max", "max": "Max", + "paramount": "Paramount+", + "apple": "Apple TV+", "atv": "Apple TV+", "atvp": "Apple TV+", "appletv": "Apple TV+", + "hoichoi": "Hoichoi", "sunnxt": "Sun NXT", "viki": "Viki", + "cr": "Crunchyroll", "crunchyroll": "Crunchyroll", + "hulu": "Hulu", "peacock": "Peacock", + "lionsgate": "Lionsgate Play", "lionsgateplay": "Lionsgate Play" } -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' +STANDARD_FORMATS = { + "hdtc": "HDTC", "hd-tc": "HDTC", "hq-hdtc": "HQ-HDTC", + "hdcam": "HDCam", "hd-cam": "HDCam", "hq-hdcam": "HQ-HDCam", + "cam": "CAM", "camrip": "CamRip", "hq-cam": "HQ-CAM", + "ts": "TS", "hdts": "HDTS", "hq-ts": "HQ-TS", "tc": "TC", + "telesync": "TeleSync", "predvd": "PreDVD", "hq-predvd": "HQ-PreDVD", + "dvdrip": "DVDRip", "dvdscr": "DVDScr", + "webrip": "WEBRip", "web-dl": "WEB-DL", "webdl": "WEB-DL", "web dl": "WEB-DL", + "bluray": "BluRay", "brrip": "BRRip", "bdrip": "BDRip", + "remux": "Remux", "imax": "IMAX", + "hdrip": "HDRip", "hq-hdrip": "HQ-HDRip", + "hdtv": "HDTV", "tvrip": "TVRip", + "hevc": "HEVC", "10bit": "10-Bit", "10-bit": "10-Bit", + "hdr": "HDR", "hdr10": "HDR10", "hdr10+": "HDR10+", + "dv": "Dolby Vision", "dovi": "Dolby Vision" +} + +RES_ORDER = { + "140p": 140, "240p": 240, "360p": 360, "480p": 480, + "540p": 540, "720p": 720, "1080p": 1080, "1440p": 1440, + "2160p": 2160, "4k": 2160 } -# 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", + +RESOLUTION_PATTERN = re.compile(r"\b(?:2160p|4K|1440p|1080p|720p|540p|480p|360p|240p|140p)\b", re.IGNORECASE) +SOURCE_PATTERN = re.compile( + r"\b(?:HDCam|HD-Cam|HQ-HDCam|HDTC|HD-TC|HQ-HDTC|CamRip|CAM|HQ-CAM|TS|HDTS|HQ-TS|TC|TeleSync|DVDScr|DVDRip|PreDVD|HQ-PreDVD|" + r"WEBRip|WEB-DL|TVRip|HDTV|WEB DL|WebDl|BluRay|BRRip|BDRip|Remux|IMAX|" + r"HEVC|10Bit|10-Bit|HDRip|HQ-HDRip|HDR10\+|HDR10|HDR|DV|DoVi)\b", re.IGNORECASE ) +VERSION_STANDALONE = re.compile(r"\b(?:[vV]\d+|ver\.?\s*\d+|version\s*\d+)\b", re.IGNORECASE) YEAR_PATTERN = re.compile(r"(? str: return CLEAN_PATTERN.sub("", text or "").strip() @@ -96,143 +156,644 @@ 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) + 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 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 or all(qw in f_words for qw in q_words): + return True + + for sep in [':', '-', '–', '—', '|']: + if sep in f_raw: + main_part = f_raw.split(sep)[0].strip() + if q_words == clean_words(main_part): + return True + return False def get_qualities(text: str) -> str: - qualities = QUALITY_PATTERN.findall(text) - return ", ".join(qualities) if qualities else "N/A" + if not text: + return "N/A" + v_match = VERSION_STANDALONE.search(text) + version_str = None + if v_match: + raw_v = v_match.group(0).upper() + raw_v = re.sub(r'^(?:VER\.?|VERSION)\s*', 'V', raw_v) + if not raw_v.startswith("V"): + raw_v = f"V{raw_v}" + version_str = raw_v + + resolutions = [] + for r in RESOLUTION_PATTERN.findall(text): + norm_r = r.lower() if r.lower() != "4k" else "4K" + if norm_r not in resolutions: + resolutions.append(norm_r) + + sources = [] + for s in SOURCE_PATTERN.findall(text): + s_norm = re.sub(r"[._]+", "-", s).strip().lower() + formatted = STANDARD_FORMATS.get(s_norm, s.upper()) + if formatted not in sources: + sources.append(formatted) + + if version_str: + attached = False + for idx, s in enumerate(sources): + if any(k in s.upper() for k in ["HDTC", "CAM", "TS", "PREDVD", "WEBRIP", "WEB-DL", "RIP", "BLURAY"]): + sources[idx] = f"{s} {version_str}" + attached = True + break + if not attached: + sources.append(version_str) + + all_items = resolutions + sources + return ", ".join(all_items) if all_items else "N/A" + +def format_movie_qualities(quality_list: list) -> str: + if not quality_list: + return "N/A" + resolutions = set() + sources = set() + versions = set() + + for item in quality_list: + if not item or item == "N/A": + continue + v_matches = VERSION_STANDALONE.findall(item) + for vm in v_matches: + v_num = re.sub(r"\D", "", vm) + if v_num: + versions.add(int(v_num)) + for r in RESOLUTION_PATTERN.findall(item): + norm_r = r.lower() if r.lower() != "4k" else "4K" + resolutions.add(norm_r) + for s in SOURCE_PATTERN.findall(item): + s_norm = re.sub(r"[._]+", "-", s).strip().lower() + formatted = STANDARD_FORMATS.get(s_norm, s.upper()) + sources.add(formatted) + + if "HQ-HDTC" in sources and "HDTC" in sources: + sources.remove("HDTC") + if "HQ-CAM" in sources: + sources.discard("CAM") + sources.discard("HDCam") + if "HDCam" in sources and "CAM" in sources: + sources.remove("CAM") + if "HQ-TS" in sources: + sources.discard("TS") + sources.discard("HDTS") + if "HDTS" in sources and "TS" in sources: + sources.remove("TS") + if "HQ-PreDVD" in sources and "PreDVD" in sources: + sources.remove("PreDVD") + if "HDR10+" in sources: + sources.discard("HDR10") + sources.discard("HDR") + elif "HDR10" in sources: + sources.discard("HDR") + + sorted_res = sorted(resolutions, key=lambda x: RES_ORDER.get(x.lower(), 9999)) + version_str = f"V{max(versions)}" if versions else "" + + source_list = [] + for s in sorted(sources): + if s and s not in source_list: + source_list.append(s) + + if version_str: + attached = False + for idx, s in enumerate(source_list): + if any(k in s.upper() for k in ["HDTC", "CAM", "TS", "PREDVD", "WEBRIP", "WEB-DL", "RIP", "BLURAY"]): + source_list[idx] = f"{s} {version_str}" + attached = True + break + if not attached: + sources.append(version_str) + + final_parts = sorted_res + source_list + return ", ".join(final_parts) if final_parts 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" + platforms = {plat for key, plat in OTT_PLATFORMS.items() if re.search(rf"\b{re.escape(key)}\b", text)} + return " | ".join(sorted(platforms)) if platforms else "N/A" + +def get_clean_title(name: str) -> str: + t = re.sub(r'\b(19|20)\d{2}\b', '', name) + return normalize(t).lower() + +def format_runtime(runtime_val, is_series: bool = False) -> str: + if not runtime_val or str(runtime_val).strip().upper() in ("N/A", "NONE", "0", "-", ""): + return "N/A" + if isinstance(runtime_val, (list, tuple)): + if not runtime_val: + return "N/A" + runtime_val = runtime_val[0] + + runtime_str = str(runtime_val).strip() + runtime_str = re.sub(r'[\s/]*(?:ep|episode)\b', '', runtime_str, flags=re.IGNORECASE).strip() + total_mins = 0 + try: + try: + total_mins = int(float(runtime_str)) + except ValueError: + colon_match = re.match(r"^(\d{1,2}):(\d{2})(?::(\d{2}))?$", runtime_str) + if colon_match: + hours = int(colon_match.group(1)) + mins = int(colon_match.group(2)) + total_mins = (hours * 60) + mins + else: + hours_match = re.search(r"(\d+)\s*(?:h|hr|hour)s?", runtime_str, re.IGNORECASE) + mins_match = re.search(r"(\d+)\s*(?:m|min|minute)s?", runtime_str, re.IGNORECASE) + if hours_match or mins_match: + hours = int(hours_match.group(1)) if hours_match else 0 + mins = int(mins_match.group(1)) if mins_match else 0 + total_mins = (hours * 60) + mins + else: + numbers = re.findall(r"\d+", runtime_str) + if numbers: + total_mins = int(numbers[0]) + except Exception: + return "N/A" + + if total_mins <= 0: + return "N/A" + if total_mins >= 60: + hours = total_mins // 60 + mins = total_mins % 60 + return f"{hours}h {mins}m" if mins > 0 else f"{hours}h" + else: + return f"{total_mins}m" + +async def fetch_imdb_safely(base_name: str, is_series: bool, year: Optional[str] = None) -> dict: + sig = inspect.signature(get_movie_details) + kwargs = {} + if "is_series" in sig.parameters: + kwargs["is_series"] = is_series + elif "media_type" in sig.parameters: + kwargs["media_type"] = "tv" if is_series else "movie" + + search_name = re.sub(r'\s+Season\s*\d+', '', base_name, flags=re.IGNORECASE).strip() if is_series else base_name + queries = [] + if is_series: + if year: + queries.append(f"{search_name} {year}") + queries.append(f"{search_name} Series") + queries.append(f"{search_name} TV") + queries.append(search_name) + else: + if year: + queries.append(f"{base_name} {year}") + queries.append(base_name) + + best_fallback = {} + for q in queries: + try: + res = await get_movie_details(q, **kwargs) if kwargs else await get_movie_details(q) + if res and isinstance(res, dict): + title = res.get("title") + if title and is_good_title_match(search_name if is_series else base_name, title): + return res + if not best_fallback and res: + best_fallback = res + except Exception as e: + logger.warning(f"Error fetching IMDb details for '{q}': {e}") + return best_fallback + +async def fetch_tmdb_safely(tmdb_query: str, base_name: str, is_series: bool) -> dict: + if not TMDB_POSTER: + return {} + sig = inspect.signature(get_movie_detailsx) + kwargs = {} + if "is_series" in sig.parameters: + kwargs["is_series"] = is_series + elif "media_type" in sig.parameters: + kwargs["media_type"] = "tv" if is_series else "movie" + + if tmdb_query and tmdb_query.startswith("tt"): + try: + res = await get_movie_detailsx(tmdb_query, **kwargs) if kwargs else await get_movie_detailsx(tmdb_query) + if res and not res.get("error"): + return res + except Exception: + pass + + queries = [] + if is_series: + queries.append(f"{base_name} Series") + queries.append(base_name) + else: + queries.append(tmdb_query or base_name) + + best_fallback = {} + for q in queries: + try: + res = await get_movie_detailsx(q, **kwargs) if kwargs else await get_movie_detailsx(q) + if res and not res.get("error"): + title = res.get("title") or res.get("name") + if title and is_good_title_match(base_name, title): + return res + if not best_fallback: + best_fallback = res + except Exception: + pass + return best_fallback + +async def get_hdhub_base_url() -> str: + try: + 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" + 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", []) + if not entries: + return None + + clean_query = f"{base_name} {year}".strip() if year else base_name + for entry in entries: + post_title = entry.get("title", {}).get("$t", "") + if is_good_title_match(clean_query, post_title) or is_good_title_match(base_name, post_title): + 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_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() or DEFAULT_HDHUB_DOMAIN + 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() + clean_query = normalize(clean_search_query).strip() + + search_words = [w for w in clean_query.split() if len(w) >= 2][:3] + effective_query = "+".join(search_words) if search_words else clean_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", + "Referer": base_url + } + + 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 "N/A", "N/A", "", False + 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 + img_alt = art.find("img").get("alt", "") if art.find("img") else "" + title_text = f"{a_tag.get('title', '')} {a_tag.get_text()} {img_alt}".strip() + candidate_items.append((title_text, href)) + + if not candidate_items: + for a in soup.select("h2 a, h3 a, .entry-title a, .recent-movies a, a[rel='bookmark']"): + href = a.get("href", "") + if href and not any(x in href for x in ["/category/", "/tag/", "/author/", "/page/"]): + candidate_items.append((a.get_text().strip(), href)) + + movie_page_url = None + matched_title = "" + core_tokens = [re.sub(r'[^a-zA-Z0-9]', '', w).lower() for w in clean_query.split() if len(w) >= 2] + + for title_text, href in candidate_items: + clean_cand = normalize(title_text).lower() + if is_good_title_match(clean_query, title_text) or is_good_title_match(base_name, title_text): + movie_page_url = href + matched_title = title_text + break + if core_tokens and all(tok in clean_cand for tok in core_tokens): + movie_page_url = href + matched_title = title_text + break + + if not movie_page_url: + return "N/A", "N/A", "", False + + if re.search(r'\b(?:Season\s*\d+|S\d{1,2}|Series|Episodes?|Complete)\b', matched_title, re.IGNORECASE): + is_series = True + + async with aiohttp.ClientSession(timeout=timeout) as session: + async with session.get(movie_page_url, headers=headers, allow_redirects=True) as resp: + if resp.status != 200: + return "N/A", "N/A", "", 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, .k-post-content") + 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'https?://(?:www\.)?(?:m\.)?imdb\.com/title/(tt\d+)/?', href, re.IGNORECASE) or 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 + m_tmdb = re.search(r'https?://(?:www\.)?themoviedb\.org/(?:movie|tv)/\d+', href, re.IGNORECASE) or re.search(r'themoviedb\.org/(?:movie|tv)/\d+', href, re.IGNORECASE) + if m_tmdb: + info_url = m_tmdb.group(0) + if not info_url.startswith("http"): + info_url = f"https://{info_url}" + break + + raw_content_str = str(search_area) + if not info_url: + m_imdb = re.search(r'https?://(?:www\.)?(?:m\.)?imdb\.com/title/(tt\d+)/?', raw_content_str, re.IGNORECASE) + if m_imdb: + info_url = f"https://www.imdb.com/title/{m_imdb.group(1)}/" + else: + m_tmdb = re.search(r'https?://(?:www\.)?themoviedb\.org/(?:movie|tv)/\d+', raw_content_str, re.IGNORECASE) + if m_tmdb: + info_url = m_tmdb.group(0) + + for br in movie_soup.find_all(["br", "hr"]): + br.replace_with("\n") + for block_elem in movie_soup.find_all(["p", "div", "h1", "h2", "h3", "h4", "li", "tr"]): + block_elem.append("\n") + for tag in movie_soup(["header", "nav", "footer", "aside", "script", "style", "iframe"]): + tag.decompose() + + cat_links = search_area.select(".cat-links a, a[rel='category tag'], .entry-category a, .genres a") + extracted_categories = [] + for c in cat_links: + cat_name = c.get_text().strip() + cat_lower = cat_name.lower() + if any(term in cat_lower for term in ["web series", "tv shows", "tv series", "series", "k-drama", "anime"]): + is_series = True + elif len(cat_name) >= 3 and not any(bad in cat_lower for bad in ["movies", "bollywood", "hollywood", "dual", "hindi", "720p", "480p", "1080p", "hevc"]): + extracted_categories.append(cat_name.title()) + + lines = [re.sub(r'\s+', ' ', line).strip() for line in search_area.get_text().splitlines() if line.strip()] + for line in lines: + if not is_series and re.search(r'\b(?:Season|Episodes?|Complete Pack)\b\s*[:\-–]', line, re.IGNORECASE): + is_series = True + if rating == "N/A" and re.search(r'\b(?:IMDb|IMDB|Rating|Ratings)\b', line, re.IGNORECASE): + r_match = re.search( + r'(?:IMDb|IMDB|Rating|Ratings)\s*(?:Rating|Ratings)?\s*[:\-•.\s]*\s*([0-9]+(?:\.[0-9]+)?|[xX]|N/?A)', + line, + re.IGNORECASE + ) + if r_match: + raw_val = r_match.group(1).strip() + if raw_val.lower() in ("x", "n/a", "na"): + rating = "x/10" + else: + try: + val = float(raw_val) + if 0.0 < val <= 10.0: + rating = f"{val:.1f}" + except ValueError: + rating = "x/10" + + if genres == "N/A" and re.search(r'\b(?:Genre|Genres)\b', line, re.IGNORECASE): + g_match = re.search(r'\b(?:Genre|Genres)\s*[:\-–]\s*([^\n\r]+)', line, re.IGNORECASE) + if g_match: + candidate = g_match.group(1).strip() + candidate = re.split( + r'\b(?:Release|IMDb|Rating|Language|Audio|Stars|Cast|Director|Quality|Size|Source|Format|Storyline|Info|Trailer|Screenshots?|Plot)\b', + candidate, + flags=re.IGNORECASE + )[0] + candidate = re.sub(r'["\'<>{}[\]\\]', '', candidate) + parts = re.split(r'[,|/•]', candidate) + cleaned_genres = [] + for p in parts: + p_clean = re.sub(r'\b(?:info|trailer)\b', '', p, flags=re.IGNORECASE).strip().title() + if p_clean and 2 <= len(p_clean) <= 25 and not any( + bad in p_clean.lower() for bad in ["dropdown", "menu", "select", "category", "home", "search", "click", "download"] + ): + cleaned_genres.append(p_clean) + if cleaned_genres: + genres = ", ".join(cleaned_genres) + + if genres == "N/A" and extracted_categories: + genres = ", ".join(extracted_categories[:4]) + + except Exception as e: + logger.error(f"Error scraping HDHub4u data: {e}") + return genres, rating, info_url, is_series def extract_season_episode(filename: str) -> Tuple[Optional[int], Optional[str]]: + filename = AUDIO_CHANNELS_PATTERN.sub(" ", filename) + if m := BONUS_RANGE_REGEX.search(filename): + return int(m.group(1)), f"Bonus {int(m.group(2))}-{int(m.group(3))}" + if m := BONUS_REGEX.search(filename): + return int(m.group(1)), f"Bonus {int(m.group(2))}" + if m := RANGE_REGEX.search(filename): + return int(m.group(1)), f"{int(m.group(2))}-{int(m.group(3))}" + if m := SINGLE_REGEX.search(filename): + return int(m.group(1)), str(int(m.group(2))) + if m := NAMED_REGEX.search(filename): + return int(m.group(1)), str(int(m.group(2))) + if m := X_REGEX.search(filename): + s_val = int(m.group(1)) + ep_val = int(m.group(2)) + if ep_val not in (264, 265, 720, 1080, 480) and s_val not in (264, 265, 720, 1080): + return s_val, str(ep_val) + if m := DAY_REGEX.search(filename): + season = int(m.group(1)) if m.group(1) else 1 + ep_val = m.group(2) or m.group(3) + if ep_val: + return season, str(int(ep_val)) + if m := NO_S_REGEX.search(filename): + return int(m.group(1)), str(int(m.group(2))) if m := EP_ONLY_RANGE.search(filename): return 1, f"{int(m.group(1))}-{int(m.group(2))}" - for pattern in (RANGE_REGEX, SINGLE_REGEX, NAMED_REGEX): - if m := pattern.search(filename): - season = int(m.group(1)) - if pattern == RANGE_REGEX: - ep = f"{m.group(2)}-{m.group(3)}" - else: - ep = m.group(2) - return season, ep + if m := EP_ONLY_SINGLE.search(filename): + ep_val = int(m.group(1)) + if ep_val not in (264, 265): + return 1, str(ep_val) return None, None -def schedule_update(bot, base_name, delay=5): +def schedule_update(bot, base_name, delay=8): if handle := pending_updates.get(base_name): if not handle.cancelled(): handle.cancel() - - loop = asyncio.get_event_loop() + + try: + loop = asyncio.get_running_loop() + except RuntimeError: + loop = asyncio.get_event_loop() + + async def wrapper(): + try: + await update_movie_message(bot, base_name) + finally: + pending_updates.pop(base_name, None) + pending_updates[base_name] = loop.call_later( delay, - lambda: asyncio.create_task(update_movie_message(bot, base_name)) + lambda: asyncio.create_task(wrapper()) ) + def extract_media_info(filename: str, caption: str): - filename = normalize(clean_mentions_links(filename).title()) + filename_clean = clean_mentions_links(filename) + filename = normalize(filename_clean.title()) caption_clean = clean_mentions_links(caption).lower() if caption else "" unified = f"{caption_clean} {filename.lower()}".strip() - season = episode = year = None + season = None + episode = None + year = None tag = "#MOVIE" - processed_raw = base_raw = filename - quality = get_qualities(caption_clean) or get_qualities(filename.lower()) or "N/A" + + processed_raw = filename + base_raw = filename + + quality = get_qualities(caption) or get_qualities(filename) 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()} + lang_keys = {k for k in CAPTION_LANGUAGES if re.search(rf"\b{re.escape(k)}\b", unified)} 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)): + clean_fn = AUDIO_CHANNELS_PATTERN.sub(" ", filename) + m = ( + BONUS_RANGE_REGEX.search(clean_fn) + or BONUS_REGEX.search(clean_fn) + or RANGE_REGEX.search(clean_fn) + or SINGLE_REGEX.search(clean_fn) + or NAMED_REGEX.search(clean_fn) + or X_REGEX.search(clean_fn) + or DAY_REGEX.search(clean_fn) + or NO_S_REGEX.search(clean_fn) + or EP_ONLY_RANGE.search(clean_fn) + or EP_ONLY_SINGLE.search(clean_fn) + ) + if m: match_str = m.group(0) - start_idx = filename.lower().find(match_str.lower()) + start_idx = clean_fn.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:]): + year_match = YEAR_PATTERN.search(filename.lower()[end_idx:]) + if year_match: y = year_match.group(0) yi = filename.lower().find(y, end_idx) if yi != -1: - processed_raw = filename[:yi+4] + processed_raw = filename[:yi + 4] base_raw += f" {y}" else: - if year_match := YEAR_PATTERN.search(unified): + year_match = YEAR_PATTERN.search(unified) + if year_match: 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_match = SOURCE_PATTERN.search(unified) or RESOLUTION_PATTERN.search(unified) + if qual_match: 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_raw = AUDIO_CHANNELS_PATTERN.sub(" ", base_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_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' + r"\bS\d{1,2}[\s._-]*(?:Bonus|Special)[\s._-]*E(?:p(?:isode)?)?0*\d{1,3}\b", + r"\b(?:Bonus|Special)[\s._-]*Ep(?:isode)?\.?\s*\d{1,3}\b", + r"\bS\d{1,2}E\d{1,3}\b", r"\bS\d{1,2}\b", r"\bE\d{1,3}\b", r"\b\d{1,2}x\d{1,3}\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", r"\bDay\s*\d{1,3}\b", r"\bBonus\b", r"\bSpecial\b", + r"\b[vV]\d+\b", r"\b(?:version|ver)\.?\s*\d+\b", + r"\b(?:dd|ddp|ac3|eac3|aac)?\s*[257]\s*[._]\s*[01]\b", r"\b(?:dd|ddp)\s*[257]\b" ] - for p in patterns: - name = re.sub(p, ' ', name, flags=re.IGNORECASE) + 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 + name = re.sub(r"[_\.\-]+", " ", name) + name = re.sub(r"\s+", " ", name).strip() if year_part: - y = re.search(r'(19|20)\d{2}', 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 + base_name = re.sub(r'(\b(?:19|20)\d{2}\b)(?:\s+\1)+', r'\1', base_name).strip() + + if season is not None: + base_name = f"{base_name} Season {season}" + if not base_name: base_name = normalize(remove_ignored_words(normalize(processed_raw))) or filename @@ -248,49 +809,76 @@ def _strip_season_episode_tokens(name: str) -> str: "language": language } - @Client.on_message(filters.chat(CHANNELS) & MEDIA_FILTER) async def media_handler(bot, message): - media = next( - (getattr(message, ft) for ft in ("document", "video", "audio") - if getattr(message, ft, None)), - None - ) + media = next((getattr(message, ft) for ft in ("document", "video", "audio") if getattr(message, ft, None)), None) if not media: return + duration_secs = getattr(media, "duration", None) or (message.video.duration if message.video else (message.audio.duration if message.audio else None)) + file_runtime_mins = round(duration_secs / 60) if duration_secs else None + 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 try: - if await db.movie_update_status(temp.ME): - await process_and_send_update(bot, media.file_name, media.caption) + if await db.movie_update_status(bot.me.id): + await process_and_send_update( + bot, + media.file_name or message.caption or "Unknown", + media.caption, + file_runtime_mins + ) except Exception: logger.exception("Error processing media") -async def process_and_send_update(bot, filename, caption): +async def process_and_send_update(bot, filename, caption, file_runtime_mins=None): try: media_info = extract_media_info(filename, caption) base_name = media_info["base_name"] processed = media_info["processed"] + if not hasattr(db, "movie_updates"): + db.movie_updates = db.db.movie_updates + + clean_title = get_clean_title(base_name) + existing_doc = await db.movie_updates.find_one({ + "$or": [{"_id": base_name}, {"clean_title": clean_title}] + }) + if existing_doc: + base_name = existing_doc["_id"] + lock = locks[base_name] 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, processed, file_runtime_mins) 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): - if not hasattr(db, 'movie_updates'): +async def _process_with_lock(bot, filename, caption, media_info, base_name, processed, file_runtime_mins=None): + if not hasattr(db, "movie_updates"): db.movie_updates = db.db.movie_updates + clean_title = get_clean_title(base_name) movie_doc = await db.movie_updates.find_one({"_id": base_name}) - error_tmdb=False + if not movie_doc: + movie_doc = await db.movie_updates.find_one({"clean_title": clean_title}) + if movie_doc: + base_name = movie_doc["_id"] + + is_series = media_info["tag"] == "#SERIES" + is_mismatched = False + if movie_doc: + stored_title = movie_doc.get("title", "") + if stored_title and not is_good_title_match(base_name, stored_title): + is_mismatched = True + + final_file_runtime = f"{file_runtime_mins}" if file_runtime_mins else "N/A" file_data = { "filename": filename, "processed": processed, @@ -300,127 +888,252 @@ async def _process_with_lock(bot, filename, caption, media_info, base_name, proc "timestamp": datetime.now(), "tag": media_info["tag"], "season": media_info["season"], - "episode": media_info["episode"] + "episode": media_info["episode"], + "runtime": final_file_runtime } - 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") - details = await get_movie_details(base_name) or {} + if not movie_doc or is_mismatched: + hdhub_genres, hdhub_rating, hdhub_info_url, hdhub_is_series = await get_hdhub4u_data(base_name) + if not is_series and hdhub_is_series: + is_series = True + media_info["tag"] = "#SERIES" + file_data["tag"] = "#SERIES" + + tt_match = re.search(r'tt\d+', hdhub_info_url) if hdhub_info_url else None + hdhub_imdb_id = tt_match.group(0) if tt_match else None + + imdb_details = await fetch_imdb_safely(base_name, is_series=is_series, year=media_info.get("year")) or {} + if not imdb_details or not is_good_title_match(base_name, imdb_details.get("title", "")): + imdb_id = hdhub_imdb_id + official_search_title = base_name else: - details = await get_movie_details(base_name) or {} + official_search_title = imdb_details.get("title", base_name) + imdb_id = hdhub_imdb_id or imdb_details.get("imdb_id") - 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" + tmdb_query = imdb_id if (imdb_id and imdb_id.startswith("tt")) else official_search_title + tmdb_details = await fetch_tmdb_safely(tmdb_query, base_name, is_series) + + # ----------------------------------------------------------------- + # POSTER LOGIC (BOTH MOVIE & SERIES ALWAYS LANDSCAPE BANNER): + # 1. Blogger Banner Feed + # 2. TMDB Backdrop Banner (Landscape 16:9) + # 3. IMDB Backdrop + # ----------------------------------------------------------------- + poster_url = "" + is_backdrop = True + + blogger_poster = await get_blogger_poster_url(base_name, media_info.get("year")) + if blogger_poster: + poster_url = blogger_poster + elif TMDB_POSTER and tmdb_details.get("backdrop_url"): + poster_url = tmdb_details.get("backdrop_url") + elif imdb_details.get("backdrop_url"): + poster_url = imdb_details.get("backdrop_url") + elif tmdb_details.get("poster_url"): + poster_url = tmdb_details.get("poster_url") + is_backdrop = False else: - genres = ", ".join(g for g in raw_genres if g in STANDARD_GENRES) or "N/A" - movie_doc = { + poster_url = imdb_details.get("poster_url", "") + is_backdrop = False + + imdb_rate = imdb_details.get("rating") + tmdb_rate = tmdb_details.get("rating") + if hdhub_rating and hdhub_rating != "N/A" and hdhub_rating != "x/10": + rating = hdhub_rating + elif imdb_rate and str(imdb_rate).strip().upper() not in ("N/A", "NONE", "0", "0.0", "-", ""): + rating = str(imdb_rate).strip() + elif tmdb_rate and str(tmdb_rate).strip().upper() not in ("N/A", "NONE", "0", "0.0", "-", ""): + rating = str(tmdb_rate).strip() + else: + rating = "6.5" + + imdb_url = hdhub_info_url.strip() if hdhub_info_url else "" + if not imdb_url: + final_imdb_id = imdb_details.get("imdb_id") or (tmdb_details.get("imdb_id") if isinstance(tmdb_details, dict) else None) or imdb_id + if final_imdb_id and str(final_imdb_id).startswith("tt"): + imdb_url = f"https://www.imdb.com/title/{final_imdb_id}/" + elif is_series and tmdb_details.get("id"): + imdb_url = f"https://www.themoviedb.org/tv/{tmdb_details.get('id')}" + elif tmdb_details.get("id"): + imdb_url = f"https://www.themoviedb.org/movie/{tmdb_details.get('id')}" + + imdb_r = imdb_details.get("runtime") + tmdb_r = tmdb_details.get("episode_run_time") if is_series and tmdb_details.get("episode_run_time") else tmdb_details.get("runtime") + if isinstance(imdb_r, (list, tuple)) and imdb_r: + imdb_r = imdb_r[0] + if isinstance(tmdb_r, (list, tuple)) and tmdb_r: + tmdb_r = tmdb_r[0] + + if is_series: + runtime = str(tmdb_r).strip() if (tmdb_r and str(tmdb_r).strip().upper() not in ("N/A", "NONE", "0", "")) else (final_file_runtime if final_file_runtime != "N/A" else (str(imdb_r).strip() if imdb_r else "N/A")) + else: + runtime = str(imdb_r).strip() if (imdb_r and str(imdb_r).strip().upper() not in ("N/A", "NONE", "0", "")) else (str(tmdb_r).strip() if tmdb_r else (final_file_runtime if final_file_runtime != "N/A" else "N/A")) + + certificates = tmdb_details.get("certificates") if tmdb_details.get("certificates") and tmdb_details.get("certificates") != "N/A" else imdb_details.get("certificates", "N/A") + + genre_list = [] + if hdhub_genres and hdhub_genres != "N/A": + raw_parts = re.split(r'[,|/•]', hdhub_genres) + for p in raw_parts: + p_clean = re.sub(r'\b(?:info|trailer)\b', '', p, flags=re.IGNORECASE).strip() + if p_clean and p_clean != "N/A" and not any(bad in p_clean.lower() for bad in ["dropdown", "menu", "select", "category"]): + genre_list.append(p_clean.title()) + if not genre_list: + raw_genres = imdb_details.get("genres") or tmdb_details.get("genres", "N/A") + if isinstance(raw_genres, str) and raw_genres != "N/A": + genre_list = [g.strip().title() for g in raw_genres.split(",") if g.strip()] + + genres = ", ".join(genre_list[:4]) if genre_list else "N/A" + movie_year = media_info.get("year") or imdb_details.get("year") or tmdb_details.get("year") + + if is_mismatched: + update_data = { + "title": official_search_title, + "clean_title": clean_title, + "poster_url": poster_url, + "genres": genres, + "rating": rating, + "runtime": runtime, + "certificates": certificates, + "imdb_url": imdb_url, + "year": movie_year, + "tag": media_info["tag"], + "ott_platform": media_info["ott_platform"], + "is_backdrop": is_backdrop + } + await db.movie_updates.update_one({"_id": base_name}, {"$set": update_data, "$push": {"files": file_data}}) + schedule_update(bot, base_name) + return + + new_doc = { "_id": base_name, + "clean_title": clean_title, + "title": official_search_title, "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"), + "poster_url": poster_url, "genres": genres, - "rating": details.get("rating", "N/A"), - "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"], + "rating": rating, + "runtime": runtime, + "certificates": certificates, + "imdb_url": imdb_url, + "year": movie_year, "tag": media_info["tag"], "ott_platform": media_info["ott_platform"], "message_id": None, "is_photo": False, - "error_tmdb": error_tmdb, - "is_backdrop": details.get("backdrop_url") + "is_backdrop": is_backdrop } + 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 db.movie_updates.insert_one(new_doc) 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) - schedule_update(bot, base_name) + if not movie_doc or any(f.get("filename") == filename for f in movie_doc.get("files", [])): + return + await db.movie_updates.update_one({"_id": base_name}, {"$push": {"files": file_data}}) + schedule_update(bot, base_name) + return + + await send_movie_update(bot, base_name) else: - if any(f["filename"] == filename for f in movie_doc["files"]): + if any(f.get("filename") == filename for f in movie_doc.get("files", [])): return - await db.movie_updates.update_one( - {"_id": base_name}, - {"$push": {"files": file_data}} - ) - movie_doc["files"].append(file_data) + + update_fields = {"$push": {"files": file_data}} + current_db_runtime = movie_doc.get("runtime") + if (not current_db_runtime or str(current_db_runtime).strip().upper() in ("N/A", "NONE", "0", "")) and final_file_runtime != "N/A": + update_fields.setdefault("$set", {})["runtime"] = final_file_runtime + + await db.movie_updates.update_one({"_id": base_name}, update_fields) schedule_update(bot, base_name) async def send_movie_update(bot, base_name): - max_retries = 3 - for attempt in range(max_retries): - try: - 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(' ', '-')}" - ) - ]]) - 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( + if base_name in sending_updates: + return None + sending_updates.add(base_name) + + try: + for attempt in range(3): + try: + movie_doc = await db.movie_updates.find_one({"_id": base_name}) + if not movie_doc: + return None + + if movie_doc.get("message_id"): + await update_movie_message(bot, base_name) + return None + + text = generate_movie_message(movie_doc, base_name) + all_tags = {f.get("tag") for f in movie_doc.get("files", []) if f.get("tag")} + primary_tag = "#SERIES" if "#SERIES" in all_tags else "#MOVIE" + + # Series -> Green (SUCCESS), Movie -> Red (DANGER) + btn_style = enums.ButtonStyle.SUCCESS if primary_tag == "#SERIES" else enums.ButtonStyle.PRIMARY + + match = re.search(r'(.+?)\s+Season\s+(\d+)', base_name, re.IGNORECASE) + if match: + button_query = f"{match.group(1).strip()}-S{int(match.group(2)):02d}" + else: + button_query = base_name + + buttons = InlineKeyboardMarkup([[ + InlineKeyboardButton( + "ɢᴇᴛ ғɪʟᴇs", + url=f"https://t.me/{temp.U_NAME}?start=getfile-{button_query.replace(' ', '-')}", + style=btn_style + ) + ]]) + + # Movie and Series both get 2560x1440 Landscape resolution + size = (2560, 1440) + + poster_url = movie_doc.get("poster_url") + is_photo = False + msg = None + + if poster_url and not LINK_PREVIEW: + try: + resized_poster = await fetch_image(poster_url, size) + photo_to_send = resized_poster or poster_url + msg = await bot.send_photo( + chat_id=MOVIE_UPDATE_CHANNEL, + photo=photo_to_send, + caption=text, + reply_markup=buttons, + parse_mode=enums.ParseMode.HTML + ) + is_photo = True + except Exception: + msg = await bot.send_message( + chat_id=MOVIE_UPDATE_CHANNEL, + text=text, + reply_markup=buttons, + parse_mode=enums.ParseMode.HTML + ) + is_photo = False + else: + msg = await bot.send_message( chat_id=MOVIE_UPDATE_CHANNEL, - photo=resized_poster, - caption=text, + text=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) is_photo = False - else: - 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}} - ) - return msg - except FloodWait as e: - wait_time = e.value + 2 - await asyncio.sleep(wait_time) - except Exception as e: - logger.error(f"Failed to send movie update: {e}") - break - return None + await db.movie_updates.update_one( + {"_id": base_name, "message_id": None}, + {"$set": {"message_id": msg.id, "is_photo": is_photo}} + ) + return msg + + except FloodWait as e: + await asyncio.sleep(e.value + 2) + except Exception as e: + logger.error(f"Failed to send movie update: {e}") + break + return None + finally: + sending_updates.discard(base_name) async def update_movie_message(bot, base_name): try: @@ -429,10 +1142,21 @@ async def update_movie_message(bot, base_name): return text = generate_movie_message(movie_doc, base_name) + all_tags = {f.get("tag") for f in movie_doc.get("files", []) if f.get("tag")} + primary_tag = "#SERIES" if "#SERIES" in all_tags else "#MOVIE" + btn_style = enums.ButtonStyle.SUCCESS if primary_tag == "#SERIES" else enums.ButtonStyle.PRIMARY + + match = re.search(r'(.+?)\s+Season\s+(\d+)', base_name, re.IGNORECASE) + if match: + button_query = f"{match.group(1).strip()}-S{int(match.group(2)):02d}" + else: + button_query = base_name + buttons = InlineKeyboardMarkup([[ InlineKeyboardButton( - 'ɢᴇᴛ ғɪʟᴇs', - url=f"https://t.me/{temp.U_NAME}?start=getfile-{base_name.replace(' ', '-')}" + "ɢᴇᴛ ғɪʟᴇs", + url=f"https://t.me/{temp.U_NAME}?start=getfile-{button_query.replace(' ', '-')}", + style=btn_style ) ]]) @@ -459,117 +1183,124 @@ async def update_movie_message(bot, base_name): text=text, reply_markup=buttons, parse_mode=enums.ParseMode.HTML, - link_preview_options=LinkPreviewOptions(is_disabled=not LINK_PREVIEW, show_above_text=ABOVE_PREVIEW) + disable_web_page_preview=not LINK_PREVIEW ) - return except MessageNotModified: pass - 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 Exception as e: - logger.error(f"Error during message deletion/update in recovery: {e}") - pass + except MessageIdInvalid: + await db.movie_updates.update_one({"_id": base_name}, {"$set": {"message_id": None}}) await send_movie_update(bot, base_name) + except Exception as e: + logger.error(f"Error updating movie message: {e}") except Exception as e: logger.error(f"Failed to update movie message for {base_name}: {e}") def generate_movie_message(movie_doc, base_name): - all_qualities = set() + all_raw_qualities = [] 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()) - 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": - platforms = [p.strip() for p in file["ott_platform"].split("|") if p.strip()] - all_ott_platforms.update(platforms) - if file["tag"]: - all_tags.add(file["tag"]) - if file.get("season") and file.get("episode"): - season = file["season"] - episode = file["episode"] + for file in movie_doc.get("files", []): + if file.get("quality") and file.get("quality") != "N/A": + all_raw_qualities.append(file.get("quality")) + + lang_val = file.get("language") + if lang_val and lang_val != "N/A": + for lang in lang_val.split(","): + clean_l = lang.strip() + if clean_l and clean_l != "N/A": + all_languages.add(CAPTION_LANGUAGES.get(clean_l.lower(), clean_l.title())) + + ott_val = file.get("ott_platform") + if ott_val and ott_val != "N/A": + for plat in ott_val.split("|"): + clean_p = plat.strip() + if clean_p and clean_p != "N/A": + all_ott_platforms.add(OTT_PLATFORMS.get(clean_p.lower(), clean_p)) + + if file.get("tag"): + all_tags.add(file.get("tag")) + + if file.get("season") is not None and file.get("episode"): + season = file.get("season") + episode = str(file.get("episode")) episodes_by_season[season].add(episode) primary_tag = "#SERIES" if "#SERIES" in all_tags else "#MOVIE" + is_series = (primary_tag == "#SERIES") + epi_block = "" if episodes_by_season: episode_lines = [] for season, episodes in sorted(episodes_by_season.items(), key=lambda x: int(x[0])): - singles = [] - ranges = [] - + regular_eps = set() for ep in episodes: - if "-" in ep: - ranges.append(ep) - else: + ep_str = str(ep).strip() + if "-" in ep_str: try: - singles.append(int(ep)) + p1, p2 = ep_str.split("-") + regular_eps.update(range(int(p1), int(p2) + 1)) except ValueError: - ranges.append(ep) - - singles.sort() - collapsed = [] - start = end = None - for num in singles: - if start is None: - start = end = num - elif num == end + 1: - end = num - else: - collapsed.append(str(start) if start == end else f"{start}-{end}") - start = end = num - if start is not None: - collapsed.append(str(start) if start == end else f"{start}-{end}") + pass + elif ep_str.isdigit(): + regular_eps.add(int(ep_str)) - all_ep_parts = collapsed + sorted(ranges, key=lambda s: int(s.split("-")[0])) - episode_lines.append(f"S{int(season)}: {', '.join(all_ep_parts)}") + sorted_nums = sorted(regular_eps) + if sorted_nums: + collapsed = [] + start = end = sorted_nums[0] + for num in sorted_nums[1:]: + if num == end + 1: + end = num + else: + collapsed.append(str(start) if start == end else f"{start}-{end}") + start = end = num + collapsed.append(str(start) if start == end else f"{start}-{end}") + episode_lines.append(f"S{int(season)}: {', '.join(collapsed)}") epi_str = "\n".join(episode_lines) if epi_str: - epi_block = f"📺 ᴇᴘɪsᴏᴅᴇs : \n{epi_str}" + epi_block = f"\n📺 ᴇᴘɪsᴏᴅᴇs : {epi_str}" + + genres = movie_doc.get("genres", "Drama") + quality_str = format_movie_qualities(all_raw_qualities) + language_str = ", ".join(sorted(all_languages)) if all_languages else "Hindi" + ott_str = " | ".join(sorted(all_ott_platforms)) if all_ott_platforms else "N/A" + + raw_rating = str(movie_doc.get("rating", "6.5")).strip() + if "/" in raw_rating: + clean_rating = raw_rating.split("/")[0].strip() + else: + clean_rating = raw_rating if raw_rating not in ("x/10", "x", "N/A", "0") else "6.5" + + raw_runtime = movie_doc.get("runtime", "N/A") + runtime = format_runtime(raw_runtime, is_series=is_series) + + stored_title = movie_doc.get("title", base_name) + stored_title = re.sub(r'[:,]?\s*(?:Episode|Ep)\s*\d+.*', '', stored_title, flags=re.IGNORECASE).strip() + display_title = re.sub(r'\s+Season\s*\d+', '', stored_title, flags=re.IGNORECASE).strip() + display_title = re.sub(r'\s+S\d+', '', display_title, flags=re.IGNORECASE).strip(" :,-\"'") + + movie_year = movie_doc.get("year") + if movie_year and str(movie_year) not in str(display_title) and primary_tag != "#SERIES": + filename_display = f"{display_title} {movie_year}" + else: + filename_display = display_title + + imdb_url = movie_doc.get("imdb_url") or "https://www.imdb.com" - 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" - ott_str = ", ".join(sorted(all_ott_platforms)) if all_ott_platforms else "N/A" - rating=movie_doc.get("rating", "-") - try: - r = float(rating) - except (TypeError, ValueError): - r = 0.0 - - rating_text = "-" if r == 0.0 else str(rating) - 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() return script.MOVIE_UPDATE_NOTIFY_TXT.format( - poster_url=movie_doc.get("poster_url", ""), - imdb_url=movie_doc.get("imdb_url", ""), + imdb_url=imdb_url, filename=filename_display, - tag=primary_tag, - year=year_val, + tag=f"{primary_tag}", genres=genres, ott=ott_str, + runtime=runtime, quality=quality_str, language=language_str, episodes=epi_block, - rating=rating_text, + rating=clean_rating, search_link=temp.B_LINK -) + ).strip() diff --git a/plugins/commands.py b/plugins/commands.py index f80dfffa..4ae96dfc 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, UserIsBlocked, InputUserDeactivated from database.ia_filterdb import Media, Media2, get_file_details, unpack_new_file_id, get_bad_files, save_file @@ -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,38 +61,149 @@ 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 - if message.command[1].startswith('sendall'): + + 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}") + + 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}" - 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), + + 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 ) + + 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)) + return + + # 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: + 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 - await asyncio.sleep(300) - await dlt.delete() + 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) + 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) + 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 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('🫶🏻 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)) @@ -108,25 +219,25 @@ async def start(client, message): 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)) 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: @@ -144,25 +255,25 @@ async def start(client, message): 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)) 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: @@ -181,7 +292,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) @@ -195,25 +306,25 @@ async def start(client, message): 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) - 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 ❗", 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)) @@ -222,11 +333,12 @@ async def start(client, message): if len(message.command) == 2 and message.command[1] in ["premium"]: buttons = [[ - InlineKeyboardButton('📲 ꜱᴇɴᴅ ᴘᴀʏᴍᴇɴᴛ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ', url=OWNER_LNK) + InlineKeyboardButton('📲 Sᴇɴᴅ ᴘᴀʏᴍᴇɴᴛ ꜱᴄʀᴇᴇɴꜱʜᴏᴛ', url=OWNER_LNK) ],[ - InlineKeyboardButton('UPI ID Copy Karein ??', copy_text=CopyTextButton(text=OWNER_UPI_ID), style=enums.ButtonStyle.PRIMARY) + InlineKeyboardButton('📷 Qʀ Cᴏᴅᴇ', url=QR_CODE) ],[ - InlineKeyboardButton('❌ ᴄʟᴏꜱᴇ ❌', callback_data='close_data', style=enums.ButtonStyle.DANGER) + InlineKeyboardButton('⇋ Bᴀᴄᴋ ⇋', callback_data='start'), + InlineKeyboardButton('❌ Cʟᴏꜱᴇ ❌', callback_data='close_data') ]] reply_markup = InlineKeyboardMarkup(buttons) await message.reply_photo( @@ -278,7 +390,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 +404,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): @@ -303,6 +415,16 @@ async def start(client, message): 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) @@ -316,9 +438,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): @@ -356,7 +478,7 @@ async def start(client, message): 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) @@ -368,10 +490,10 @@ async def start(client, message): 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), + protect_content=settings.get('file_secure', PROTECT_CONTENT) if settings else PROTECT_CONTENT, reply_markup=InlineKeyboardMarkup(btn) ) filesarr.append(msg) @@ -408,17 +530,22 @@ async def start(client, message): 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() - await k.edit_text("ʏᴏᴜʀ ᴠɪᴅᴇᴏ / ꜰɪʟᴇ ɪꜱ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ !!") + await k.edit_text( + "Yᴏᴜʀ ᴠɪᴅᴇᴏ / ꜰɪʟᴇ ɪꜱ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ !!\n" + "Tᴏ ᴘʀᴏᴛᴇᴄᴛ ᴏᴜʀ ʙᴏᴛ ғʀᴏᴍ ᴄᴏᴘʏʀɪɢʜᴛ 🥀\n" + "Iғ ʏᴏᴜ ᴅɪᴅɴ'ᴛ ғᴏʀᴡᴀʀᴅ ɪᴛ ᴀɴʏᴡʜᴇʀᴇ ᴇʟsᴇ, ᴋɪɴᴅʟʏ ʀᴇǫᴜᴇsᴛ ᴛʜᴇ ғɪʟᴇ ᴏɴᴄᴇ ᴀɢᴀɪɴ 🫶🏻🩵" + ) return except Exception as e: logger.exception(e) @@ -437,7 +564,8 @@ async def start(client, message): 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) @@ -453,7 +581,11 @@ async def start(client, message): 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 @@ -462,31 +594,10 @@ 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('📌 Jᴏɪɴ ᴜᴘᴅᴀᴛᴇꜱ ᴄʜᴀɴɴᴇʟ 📌', url=UPDATE_CHNL_LNK)]] @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: @@ -494,7 +605,6 @@ 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ɪɴɢ...⏳") @@ -518,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: @@ -530,7 +640,6 @@ 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ɪɴɢ...⏳") @@ -602,7 +711,7 @@ async def delete_all_index(bot, message): [ [ InlineKeyboardButton( - text="⚠️ ʏᴇꜱ ⚠️", callback_data="autofilter_delete", style=enums.ButtonStyle.DANGER + text="⚠ ʏᴇꜱ ⚠", callback_data="autofilter_delete" ) ], [ @@ -631,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 @@ -648,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) @@ -683,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 @@ -691,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) @@ -700,13 +809,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 @@ -730,8 +838,8 @@ 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" - warning_text = "⚠️ ʀᴇǫᴜᴇꜱᴛ ᴄʜᴀɴɴᴇʟ ɪꜱ ɴᴏᴛ ꜱᴇᴛ." + req_text = f"📝 ʀᴇǫᴜᴇꜱᴛ : {content}\n\n📚 Rᴇᴘᴏʀᴛᴇᴅ ʙʏ : {mention}\n📖 Rᴇᴘᴏʀᴛᴇʀ ɪᴅ : {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)) @@ -745,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( "⚠ Sᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ. ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ.") if reported_post and REQST_CHANNEL is not None: try: @@ -759,15 +867,16 @@ 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("ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ʜᴀꜱ ʙᴇᴇɴ ᴀᴅᴅᴇᴅ! ᴘʟᴇᴀꜱᴇ ᴡᴀɪᴛ ꜰᴏʀ ꜱᴏᴍᴇ ᴛɪᴍᴇ.") 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): @@ -781,17 +890,25 @@ async def send_msg(bot, message): target_id = parts[1] 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("Tʜɪꜱ ᴜꜱᴇʀ ʜᴀꜱɴ'ᴛ ꜱᴛᴀʀᴛᴇᴅ ᴛʜɪꜱ ʙᴏᴛ ʏᴇᴛ !") except UserIsBlocked: - await message.reply_text("ᴛʜɪꜱ ᴜꜱᴇʀ ʜᴀꜱ ʙʟᴏᴄᴋᴇᴅ ᴛʜᴇ ʙᴏᴛ !") + await message.reply_text("Tʜɪꜱ ᴜꜱᴇʀ ʜᴀꜱ ʙʟᴏᴄᴋᴇᴅ ᴛʜᴇ ʙᴏᴛ !") except PeerIdInvalid: - await message.reply_text("ɪɴᴠᴀʟɪᴅ ᴜꜱᴇʀ ɪᴅ, ᴏʀ ᴛʜᴇ ʙᴏᴛ ʜᴀꜱɴ'ᴛ ᴍᴇᴛ ᴛʜɪꜱ ᴜꜱᴇʀ ʏᴇᴛ !") + await message.reply_text("Iɴᴠᴀʟɪᴅ ᴜꜱᴇʀ ɪᴅ, ᴏʀ ᴛʜᴇ ʙᴏᴛ ʜᴀꜱɴ'ᴛ ᴍᴇᴛ ᴛʜɪꜱ ᴜꜱᴇʀ ʏᴇᴛ !") except InputUserDeactivated: - await message.reply_text("ᴛʜɪꜱ ᴜꜱᴇʀ ᴀᴄᴄᴏᴜɴᴛ ɪꜱ ᴅᴇʟᴇᴛᴇᴅ / ᴅᴇᴀᴄᴛɪᴠᴀᴛᴇᴅ !") + await message.reply_text("Tʜɪꜱ ᴜꜱᴇʀ ᴀᴄᴄᴏᴜɴᴛ ɪꜱ ᴅᴇʟᴇᴛᴇᴅ / ᴅᴇᴀᴄᴛɪᴠᴀᴛᴇᴅ !") except Exception as e: await message.reply_text(f"Error: {e}") else: @@ -817,9 +934,9 @@ 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) + 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?", @@ -925,7 +1042,7 @@ def is_alphanumeric(string): return formatted_list = "\n".join([f"{i+1}. {msg}" for i, msg in enumerate(truncated_messages)]) additional_message = ( - "⚡️ 𝑨𝒍𝒍 𝒕𝒉𝒆 𝒓𝒆𝒔𝒖𝒍𝒕𝒔 𝒂𝒃𝒐𝒗𝒆 𝒄𝒐𝒎𝒆 𝒇𝒓𝒐𝒎 𝒘𝒉𝒂𝒕 𝒖𝒔𝒆𝒓𝒔 𝒉𝒂𝒗𝒆 𝒔𝒆𝒂𝒓𝒄𝒉𝒆𝒅 𝒇𝒐𝒓. " + "⚡ 𝑨𝒍𝒍 𝒕𝒉𝒆 𝒓𝒆𝒔𝒖𝒍𝒕𝒔 𝒂𝒃𝒐𝒗𝒆 𝒄𝒐𝒎𝒆 𝒇𝒓𝒐𝒎 𝒘𝒉𝒂𝒕 𝒖𝒔𝒆𝒓𝒔 𝒉𝒂𝒗𝒆 𝒔𝒆𝒂𝒓𝒄𝒉𝒆𝒅 𝒇𝒐𝒓. " "𝑻𝒉𝒆𝒚'𝒓𝒆 𝒔𝒉𝒐𝒘𝒏 𝒕𝒐 𝒚𝒐𝒖 𝒆𝒙𝒂𝒄𝒕𝒍𝒚 𝒂𝒔 𝒕𝒉𝒆𝒚 𝒘𝒆𝒓𝒆 𝒔𝒆𝒂𝒓𝒄𝒉𝒆𝒅, " "𝒘𝒊𝒕𝒉𝒐𝒖𝒕 𝒂𝒏𝒚 𝒄𝒉𝒂𝒏𝒈𝒆𝒔 𝒃𝒚 𝒕𝒉𝒆 𝒐𝒘𝒏𝒆𝒓." ) @@ -977,7 +1094,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)) @@ -987,7 +1104,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) @@ -1074,7 +1191,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]: @@ -1130,7 +1247,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 @@ -1149,7 +1266,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 @@ -1173,7 +1290,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): @@ -1190,7 +1307,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}") @@ -1205,11 +1322,11 @@ 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="close_data", style=enums.ButtonStyle.DANGER)] + [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) @@ -1221,7 +1338,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, @@ -1252,8 +1369,8 @@ 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="close_data", style=enums.ButtonStyle.DANGER)] + [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)) @@ -1326,7 +1443,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) @@ -1422,7 +1539,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): @@ -1463,3 +1580,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}') + + + diff --git a/plugins/p_ttishow.py b/plugins/p_ttishow.py index e5caa70e..ed10904d 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( @@ -65,7 +65,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) @@ -89,7 +89,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( @@ -129,7 +129,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( diff --git a/plugins/pmfilter.py b/plugins/pmfilter.py index a30ca87d..b0ce9007 100644 --- a/plugins/pmfilter.py +++ b/plugins/pmfilter.py @@ -30,8 +30,6 @@ logger = logging.getLogger(__name__) - - TIMEZONE = "Asia/Kolkata" BUTTON = {} BUTTONS = {} @@ -41,7 +39,6 @@ BUTTONS2 = {} SPELL_CHECK = {} - @Client.on_message(filters.group & filters.text & filters.incoming & ~filters.regex(r"^/") ) async def give_filter(client, message): if not message.from_user: @@ -50,7 +47,7 @@ async def give_filter(client, message): try: await message.react(emoji=random.choice(REACTIONS), big=True) except Exception: - await message.react(emoji="⚡️") + await message.react(emoji="⚡") pass await mdb.update_top_messages(message.from_user.id, message.text) if message.chat.id != SUPPORT_CHAT_ID: @@ -81,7 +78,6 @@ async def give_filter(client, message): [[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 = temp.ME @@ -92,7 +88,7 @@ async def pm_text(bot, message): try: await message.react(emoji=random.choice(REACTIONS), big=True) except Exception: - await message.react(emoji="⚡️") + await message.react(emoji="⚡") pass if content.startswith(("#")): return @@ -113,7 +109,6 @@ async def pm_text(bot, message): except Exception: pass - @Client.on_callback_query(filters.regex(r"^reffff")) async def refercall(bot, query): btn = [[ @@ -191,8 +186,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), + InlineKeyboardButton("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) @@ -212,8 +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), + 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: @@ -351,7 +344,6 @@ async def next_page(bot, query): pass await query.answer() - @Client.on_callback_query(filters.regex(r"^spol")) async def advantage_spoll_choker(bot, query): _, id, user = query.data.split('#') @@ -387,8 +379,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: @@ -418,7 +410,6 @@ async def qualities_cb_handler(client: Client, query: CallbackQuery): 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("#") @@ -434,7 +425,7 @@ async def filter_qualities_cb_handler(client: Client, query: CallbackQuery): message = query.message 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,) + return await query.answer(f"⚠ ʜᴇʟʟᴏ {query.from_user.first_name},\nᴛʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ,\nʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀ'ꜱ...", show_alert=True,) except Exception: pass if qual != "homepage": @@ -466,8 +457,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), + InlineKeyboardButton("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) ]) @@ -485,8 +475,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), + InlineKeyboardButton("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) @@ -516,7 +505,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() @@ -538,16 +527,14 @@ async def filter_qualities_cb_handler(client: Client, query: CallbackQuery): 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: 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: @@ -576,7 +563,6 @@ async def languages_cb_handler(client: Client, query: CallbackQuery): await query.edit_message_reply_markup(InlineKeyboardMarkup(btn)) - @Client.on_callback_query(filters.regex(r"^fl#")) async def filter_languages_cb_handler(client: Client, query: CallbackQuery): _, lang, req, key = query.data.split("#") @@ -592,7 +578,7 @@ async def filter_languages_cb_handler(client: Client, query: CallbackQuery): message = query.message 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,) + return await query.answer(f"⚠ ʜᴇʟʟᴏ {query.from_user.first_name},\nᴛʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ,\nʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀ'ꜱ...", show_alert=True,) except Exception: pass if lang != "homepage": @@ -600,7 +586,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) @@ -624,8 +610,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), + InlineKeyboardButton("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) ] @@ -643,8 +628,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), + InlineKeyboardButton("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) ]) @@ -659,23 +643,23 @@ 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))) - \ - timedelta(hours=curr_time.hour, minutes=curr_time.minute, seconds=( + 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) @@ -691,14 +675,13 @@ async def filter_languages_cb_handler(client: Client, query: CallbackQuery): pass await query.answer() - @Client.on_callback_query(filters.regex(r"^seasons#")) async def seasons_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ᴛʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ,\nʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀ'ꜱ…", + f"⚠ ʜᴇʟʟᴏ {query.from_user.first_name},\nᴛʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ,\nʀᴇǫᴜᴇꜱᴛ ʏᴏᴜʀ'ꜱ...", show_alert=True, ) except Exception: @@ -715,14 +698,13 @@ async def seasons_cb_handler(client: Client, query: CallbackQuery): btn.insert( 0, - [InlineKeyboardButton("⇊ ꜱᴇʟᴇᴄᴛ ꜱᴇᴀꜱᴏɴ ⇊", callback_data="ident")], + [InlineKeyboardButton("⇊ ꜱᴇʟᴇᴄᴛ ꜱᴇᴀꜱᴏɴ ⇊", callback_data="ident")], ) - btn.append([InlineKeyboardButton(text="↭ ʙᴀᴄᴋ ᴛᴏ ꜰɪʟᴇs ​↭", + 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): start_t = datetime.now(pytz.timezone("Asia/Kolkata")) @@ -740,7 +722,7 @@ async def filter_seasons_cb_handler(client: Client, query: CallbackQuery): 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) + return await query.answer("⚠ Not your request", show_alert=True) except Exception: pass @@ -748,7 +730,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) @@ -771,14 +753,13 @@ async def filter_seasons_cb_handler(client: Client, query: CallbackQuery): [ InlineKeyboardButton("Qᴜᴀʟɪᴛʏ", callback_data=f"qualities#{req}#{key}"), InlineKeyboardButton("Lᴀɴɢᴜᴀɢᴇ", callback_data=f"languages#{req}#{key}"), - InlineKeyboardButton("Sᴇᴀꜱᴏɴ", callback_data=f"seasons#{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("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton("Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS), ], ) @@ -805,7 +786,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"): time_difference = datetime.now(pytz.timezone("Asia/Kolkata")) - start_t @@ -827,7 +808,6 @@ async def filter_seasons_cb_handler(client: Client, query: CallbackQuery): pass await query.answer() - @Client.on_callback_query(group=10) async def cb_handler(client: Client, query: CallbackQuery): DreamxData = query.data @@ -842,17 +822,11 @@ 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() - except Exception: - 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("#") @@ -875,14 +849,12 @@ async def cb_handler(client: Client, query: CallbackQuery): 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ᴇᴅ ꜰɪʟᴇꜱ ✅') + await query.message.edit('Sᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ᴀʟʟ ɪɴᴅᴇxᴇᴅ ꜰɪʟᴇꜱ ✅') elif query.data.startswith("checksub"): try: @@ -894,14 +866,14 @@ async def cb_handler(client: Client, query: CallbackQuery): 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}")]) + 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" + f"👋 Hᴇʟʟᴏ {query.from_user.first_name},\n\n" + "🛑 Yᴏᴜ ʜᴀᴠᴇ ɴᴏᴛ ᴊᴏɪɴᴇᴅ ᴀʟʟ ʀᴇǫᴜɪʀᴇᴅ ᴜᴘᴅᴀᴛᴇ ᴄʜᴀɴɴᴇʟs.\n" "👉 Pʟᴇᴀsᴇ ᴊᴏɪɴ ᴇᴀᴄʜ ᴏɴᴇ ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ.\n", show_alert=True ) @@ -916,7 +888,6 @@ async def cb_handler(client: Client, query: CallbackQuery): 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...") @@ -957,7 +928,7 @@ async def cb_handler(client: Client, query: CallbackQuery): and st.status != enums.ChatMemberStatus.OWNER and str(userid) not in ADMINS ): - await query.answer("ʏᴏᴜ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ ʀɪɢʜᴛꜱ ᴛᴏ ᴅᴏ ᴛʜɪꜱ !", show_alert=True) + await query.answer("ʏᴏᴜ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ ʀɪɢʜᴛꜱ ᴛᴏ ᴅᴏ ᴛʜɪs !", show_alert=True) return title = query.message.chat.title settings = await get_settings(grp_id) @@ -986,7 +957,7 @@ async def cb_handler(client: Client, query: CallbackQuery): settings = await get_settings(grp_id) btn2 = [[ InlineKeyboardButton( - "ᴄʜᴇᴄᴋ ᴍʏ ᴅᴍ 🗳️", url=f"telegram.me/{temp.U_NAME}") + "ᴄʜᴇᴄᴋ ᴍʏ ᴅᴍ 🗳", url=f"telegram.me/{temp.U_NAME}") ]] reply_markup = InlineKeyboardMarkup(btn2) await query.message.edit_text(f"ʏᴏᴜʀ sᴇᴛᴛɪɴɢs ᴍᴇɴᴜ ғᴏʀ {title} ʜᴀs ʙᴇᴇɴ sᴇɴᴛ ᴛᴏ ʏᴏᴜ ʙʏ ᴅᴍ.") @@ -1005,15 +976,15 @@ async def cb_handler(client: Client, query: CallbackQuery): elif query.data.startswith("show_option"): ident, from_user = query.data.split("#") btn = [[ - InlineKeyboardButton("⚠️ ᴜɴᴀᴠᴀɪʟᴀʙʟᴇ ⚠️", callback_data=f"unavailable#{from_user}"), + InlineKeyboardButton("⚠ ᴜɴᴀᴠᴀɪʟᴀʙʟᴇ ⚠", callback_data=f"unavailable#{from_user}"), InlineKeyboardButton("🟢 ᴜᴘʟᴏᴀᴅᴇᴅ 🟢", callback_data=f"uploaded#{from_user}") ], [ - InlineKeyboardButton("♻️ ᴀʟʀᴇᴀᴅʏ ᴀᴠᴀɪʟᴀʙʟᴇ ♻️", callback_data=f"already_available#{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("♨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}") + 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) @@ -1030,25 +1001,25 @@ async def cb_handler(client: Client, query: CallbackQuery): 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ɴʙʟᴏᴄᴋ ᴛʜᴇ ʙᴏᴛ ᴛᴏ ʀᴇᴄᴇɪᴠᴇ ᴍᴇꜱꜱᴀɢᴇꜱ.", + "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ɴʙʟᴏᴄᴋ ᴛʜᴇ ʙᴏᴛ ᴛᴏ ʀᴇᴄᴇɪᴠᴇ ᴍᴇꜱꜱᴀɢᴇꜱ.", + "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ᴘᴇʟʟɪɴɢ !", + "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ɪɴᴅɪ !", + "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 @@ -1060,7 +1031,7 @@ async def cb_handler(client: Client, query: CallbackQuery): "search": True }, "already_available": { - "btn_text": "♻️ ᴀʟʀᴇᴀᴅʏ ᴀᴠᴀɪʟᴀʙʟᴇ ♻️", "alert_key": "alalert", "answer": "Sᴇᴛ ᴛᴏ Aʟʀᴇᴀᴅʏ Aᴠᴀɪʟᴀʙʟᴇ !", + "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 @@ -1100,7 +1071,7 @@ async def cb_handler(client: Client, query: CallbackQuery): alerts = { "alalert": "Hᴇʏ {name}, Yᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ɪꜱ Aʟʀᴇᴀᴅʏ Aᴠᴀɪʟᴀʙʟᴇ ✅", "upalert": "Hᴇʏ {name}, Yᴏᴜʀ ʀᴇǫᴜESꜱᴛ ɪꜱ Uᴘʟᴏᴀᴅᴇᴅ 🔼", - "unalert": "Hᴇʏ {name}, Yᴏᴜʀ ʀᴇǫᴜᴇꜱᴛ ɪꜱ 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ᴘᴇʟʟɪɴɢ ❗" @@ -1110,82 +1081,29 @@ async def cb_handler(client: Client, query: CallbackQuery): 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}", - 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() - - - + await query.answer("Yᴏᴜ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ ᴘᴇʀᴍɪssɪᴏɴ ᴛᴏ sᴇᴇ ᴛʜɪs ❌", show_alert=True) 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(' ᴀʙᴏᴜᴛ 📖', 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)) 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] @@ -1242,13 +1160,10 @@ 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) await query.message.edit_text( @@ -1264,7 +1179,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 @@ -1282,7 +1197,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) @@ -1290,8 +1205,6 @@ async def cb_handler(client: Client, query: CallbackQuery): 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'), @@ -1321,12 +1234,12 @@ 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') + InlineKeyboardButton('⇋ Bᴀᴄᴋ ᴛᴏ ʜᴏᴍᴇ ⇋', callback_data='start') ]] reply_markup = InlineKeyboardMarkup(btn) await client.edit_message_media( @@ -1338,12 +1251,11 @@ async def cb_handler(client: Client, query: CallbackQuery): 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('Sᴛᴀʀ', callback_data='star_info'), + InlineKeyboardButton('Uᴘɪ', callback_data='upi_info') ],[ InlineKeyboardButton('⇋ ʙᴀᴄᴋ ᴛᴏ ᴘʀᴇᴍɪᴜᴍ ⇋', callback_data='premium_info') ]] @@ -1360,15 +1272,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: @@ -1392,7 +1307,6 @@ async def cb_handler(client: Client, query: CallbackQuery): 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 @@ -1403,6 +1317,34 @@ async def cb_handler(client: Client, query: CallbackQuery): 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("#") @@ -1423,7 +1365,6 @@ async def cb_handler(client: Client, query: CallbackQuery): 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. @@ -1442,7 +1383,6 @@ async def _schedule_delete(sent_obj, orig_msg, delay): except Exception: pass except Exception: - # ignore scheduling errors pass m = None try: @@ -1473,7 +1413,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...') @@ -1528,8 +1468,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("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) @@ -1548,8 +1487,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("Rᴇᴍᴏᴠᴇ ᴀᴅs", callback_data="premium_info", style=enums.ButtonStyle.PRIMARY), InlineKeyboardButton( "Sᴇɴᴅ Aʟʟ", callback_data=f"sendfiles#{key}", style=enums.ButtonStyle.SUCCESS) ]) @@ -1637,16 +1575,16 @@ async def _schedule_delete(sent_obj, orig_msg, delay): 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" + 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" + 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" + 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" + 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" @@ -1767,4 +1705,6 @@ async def advantage_spell_chok(client, message): await message.delete() except Exception: pass - + + +